TestModel auto-generates plausible tool calls and a final response on every run; FunctionModel gives you full per-turn control so you can simulate exact model behavior. Both integrate with agent.override({ model }) to drop in a test model without changing your agent definition.
Preventing accidental API calls
CallsetAllowModelRequests(false) once at the top of your test file to raise an error if any agent accidentally reaches the real model API. This guards against tests that forget to use a test model.
TestModel
TestModel is the simplest option. It auto-generates schema-valid tool calls for any tools the agent has, then returns a final result.
TestModel accepts an optional options object:
| Option | Type | Default | Description |
|---|---|---|---|
callTools | boolean | true | Auto-generate tool calls on the first turn before returning final result |
text | string | "test response" | Text returned when there is no output schema |
outputSchema | Zod schema | - | When provided, generates schema-valid structured output |
createTestModel({ outputSchema }) is a convenience factory equivalent to new TestModel({ outputSchema }).
FunctionModel - per-turn control
When you need precise control over what the model returns on each turn, useFunctionModel. Its constructor takes a function that receives { messages, tools, turn } and returns a DoGenerateResult.
messages array and tools definition on every turn, so you can assert on what the agent sent before deciding what to return.
captureRunMessages
captureRunMessages wraps an agent run and captures the ModelMessage[] arrays that were passed to the model on each turn, letting you assert on exact message content:
agent.override()
agent.override({ model }) returns a runner object - it is not an Agent instance. The runner exposes the same three execution methods:
agent.override() returns { run, stream, runStreamEvents } - not an Agent. You cannot pass the override result where an Agent is expected, and it cannot be stored in a variable typed as Agent.override call bypasses the setAllowModelRequests(false) guard automatically, so your test models always work even when real API calls are blocked.
API reference
| Symbol | Signature | Description |
|---|---|---|
setAllowModelRequests | (allow: boolean) => void | Module-level guard - throws if a real model call is attempted when false |
TestModel | new TestModel(options?) | Auto-generates tool calls and final result; use for most agent tests |
createTestModel | ({ outputSchema }) => TestModel | Convenience factory for typed output tests |
FunctionModel | new FunctionModel(fn) | Per-turn model control; fn receives { messages, tools, turn } |
captureRunMessages | (fn) => Promise<{ result, messages }> | Captures ModelMessage[][] for all turns; sequential only |
agent.override | (options) => { run, stream, runStreamEvents } | Swap model for a test; bypasses setAllowModelRequests guard |
Hello World
Build your first agent and run it end-to-end
Agents
Agent configuration, output schemas, and run options