Skip to main content
The shortest answer is a backend object: wai.OpenAI("gpt-4.1-mini", api_key="sk-..."), wai.Anthropic(...), wai.Endpoint(model, url=), wai.Ollama(...), wai.Hosted(). Its repr says where the call goes and which key it uses, wai.configure(agent=, judge=, api_key=) sets it once for the process, and print(wai.settings) shows what each role resolves to. That page is Connect your agent. This page is the string form underneath, for configs and command lines. The agent is the first argument of simulate(). Pass the model as a string, and the key comes from that provider’s usual environment variable. Every request goes straight to that provider. The situation writer runs on the same model, so no While key is involved.
Set the key the way you already do for that provider:

Tools are functions

@wai.tool turns a typed function into the tool: the signature is the schema, the docstring is the description, Annotated[str, "note"] or a Google-style Args: block gives a parameter its note, and a parameter with a default is optional. The mock world answers the calls, faults first. To have the bodies answer instead, pass execute=wai.Tool.dispatch([get_order, ...]). Raw OpenAI schema dicts still work in the same list.

No tools at all yet

draft_tools writes plausible schemas from one sentence about the agent, on the same key:
Each drafted schema is marked drafted, so you can tell it from a declared tool. Replace them with your real schemas when you have them.

The judge

Same shape as the agent: a callable over a row, a verifier (wai.verify.MathEqual(), wai.verify.CodeExec(tests=...)), or a model string on its own key. The judge is never the model it is judging; the evals guide shows how to check it against people before you trust it.

Three models, three arguments

Three models can take part in a run. A model string can name each one, and each goes in a different place. Set them once for a machine with WHILEAI_AGENT, WHILEAI_SURROGATE (the writer) and WHILEAI_JUDGE instead. If agent and judge end up the same model, data.degraded carries same_model and the warning says so.

The While key

Only the hosted parts need it. The SDK looks in this order and stops at the first it finds: Keys start with zp_. Every WHILEAI_* variable also reads its old ZEROPROOF_* name.

What reaches While

Three things, and only when you ask for them: Everything else runs on your machine. whileai status prints which key the SDK will use and where it came from; whileai login or whileai signup --email you@example.com gets one when you want the hosted parts. The platform reference covers that side.
Last modified on September 19, 2026