std.llm
The provider layer with the language machinery taken off.
import std.llm
llm.chat({ user: "Say hello" })
llm.chat({ system: "Answer in one word.", user: "Capital of France?" })
llm.chat({ user: "Summarize this", model: "gpt-4o-mini" })
One prompt in, a string out. No typed coercion, no contracts, no retry loop, no tool calls.
Fields
user is required. system sets the system prompt. model overrides the configured model for that call only - passed through rather than written to the process environment, so concurrent workers under pmap cannot clobber each other's choice.
Offline
With no provider configured it returns a deterministic mock string rather than failing, on the same principle as ai - the program still runs. A failing live call raises a catchable error.
Use ai instead, nearly always
ai is the same provider underneath, plus everything that makes model output usable:
ai | llm.chat | |
|---|---|---|
| Typed output | yes | no |
| Contracts | yes | no |
| Coercion retry | yes | no |
| Tools | yes | no |
| Sessions | yes | no |
| Streaming | yes | no |
| Caching | yes | no |
| Voting | yes | no |
ai "..." is shorter and does more. The reason llm.chat exists is for the few cases where you want the provider and nothing else: a one-off probe, a wrapper of your own, or code that needs the raw string with no machinery in the way.
If you find yourself rebuilding retry and parsing around llm.chat, that is what ai already is.