Skip to content

Models

A model in Shio only proposes: propose(request) -> text. Parsing, checking and deciding happen in Shio. Any object with that method is a model.

from shio import models

models.ollama("qwen3:8b", digest="sha256:...")            # a local model; refused unless the weights match the pin
models.openai_compat("gpt-x", "https://api.example.com/v1", key_env="EXAMPLE_API_KEY")   # vLLM, LM Studio, OpenAI...
models.anthropic("claude-opus-5-5", effort="medium")      # Claude, pip install 'shio-lang[anthropic]'
models.replay(lambda request: {"value": 42})              # saved answers, for tests and demos
  • Structured output. Every backend asks for JSON matching the reading's schema. With structured=False the schema goes in the prompt instead, for a provider without structured outputs.
  • Failures are null readings. A timeout, an error, a refusal or a reply that doesn't fit the schema gives a null reading, which fails its checks. A model failure never crashes an agent and never passes a check.
  • Retries and pacing. Every backend retries timeouts, 429 and 5xx with backoff, honouring Retry-After (retries=2), and per_minute= paces calls across threads.
  • Keys come from the environment and are never written to a trace.

Images and PDFs

read total: Receipt from image("receipt.png") by claude:       # in .shio: image(...) and pdf(...)
    What does this receipt say?

Source.image(path) and Source.from_pdf(path) reach models that read files as the files themselves: Claude (anthropic(...)) gets images and PDFs as image and document blocks, and an OpenAI-compatible vision model (openai_compat(..., vision=True), including Ollama's llava or qwen2.5-vl) gets images as data URLs. A PDF also keeps its extracted text, for text-only models. A model that can't read a source (an image, for a text-only model) fails the read: the reading is null and its checks fail, instead of the model guessing. The trace records each file's SHA-256, so the exact image a decision was made from is auditable.