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=Falsethe 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), andper_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.