> ## Documentation Index > Fetch the complete documentation index at: https://openrouter.ai/docs/llms.txt > Use this file to discover all available pages before exploring further. # Agent SDK API Reference > Type signatures and exports for the Agent SDK, covering callModel, ModelResult, tool types, conversation state helpers, stop conditions, and format utilities. ## callModel ```typescript lines theme={null} function callModel(request: CallModelInput, options?: RequestOptions): ModelResult ``` Creates a response using the OpenResponses API with multiple consumption patterns. ### CallModelInput | Parameter | Type | Required | Description | | --------------------- | ------------------------------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `model` | `string \| ((ctx: TurnContext) => string)` | Yes\* | Model ID (e.g., "openai/gpt-5-nano") | | `models` | `string[]` | Yes\* | Model fallback array | | `input` | `OpenResponsesInput` | Yes | Input messages or string | | `instructions` | `string \| ((ctx: TurnContext) => string)` | No | System instructions | | `tools` | `Tool[]` | No | Tools available to the model | | `maxToolRounds` | `MaxToolRounds` | No | Tool execution limit (deprecated) | | `stopWhen` | `StopWhen` | No | Stop conditions | | `allowFinalResponse` | `boolean \| string` | No | Final text turn when `stopWhen` halts mid-tool-call. Default on: makes one more turn with `toolChoice: 'none'` and a built-in final-answer directive (`DEFAULT_FINAL_RESPONSE_DIRECTIVE`). A string overrides the directive wording; `''` appends no message; `false` disables the final turn | | `strictFinalResponse` | `boolean` | No | Throw if the final response has empty `output` even after completed tool rounds (pre-0.8.0 behavior). Default `false`: retry the follow-up once, then resolve successfully with empty text so tool-terminal runs aren't reported as failures. Runs with no completed tool work still throw on empty output | | `temperature` | `number \| ((ctx: TurnContext) => number)` | No | Sampling temperature (0-2) | | `maxOutputTokens` | `number \| ((ctx: TurnContext) => number)` | No | Maximum tokens to generate | | `topP` | `number` | No | Top-p sampling | | `text` | `ResponseTextConfig` | No | Text format configuration | | `provider` | `ProviderPreferences` | No | Provider routing and configuration | | `topK` | `number` | No | Top-k sampling | | `metadata` | `Record` | No | Request metadata | | `toolChoice` | `ToolChoice` | No | Tool choice configuration | | `parallelToolCalls` | `boolean` | No | Enable parallel tool calling | | `reasoning` | `ReasoningConfig` | No | Reasoning configuration | | `promptCacheKey` | `string` | No | Cache key for prompt caching | | `previousResponseId` | `string` | No | Context from previous response | | `include` | `string[]` | No | Include extra fields in response | | `background` | `boolean` | No | Run request in background | | `safetyIdentifier` | `string` | No | User safety identifier | | `serviceTier` | `string` | No | Service tier preference | | `truncation` | `string` | No | Truncation mode | | `plugins` | `Plugin[]` | No | Enabled plugins | | `user` | `string` | No | End-user identifier | | `sessionId` | `string` | No | Session identifier | | `store` | `boolean` | No | Store request data | | `context` | `ContextInput` | No | Tool context keyed by tool name | | `hooks` | `InlineHookConfig \| HooksManager` | No | Agent lifecycle hooks | See [Lifecycle Hooks](/docs/agent-sdk/call-model/lifecycle-hooks) for hook payloads, results, and manager APIs. \*Either `model` or `models` is required. ### ProviderPreferences Configuration for routing and provider selection. | Parameter | Type | Description | | ------------------------ | ------------------- | ------------------------------------------------------------------ | | `allowFallbacks` | `boolean` | Allow backup providers when primary is unavailable (default: true) | | `requireParameters` | `boolean` | Only use providers that support all requested parameters | | `dataCollection` | `"allow" \| "deny"` | Data collection policy (allow/deny) | | `order` | `string[]` | Custom provider routing order | | `only` | `string[]` | Restrict to specific providers | | `ignore` | `string[]` | Exclude specific providers | | `quantizations` | `string[]` | Filter by quantization levels | | `sort` | `string` | Load balancing strategy (e.g., "throughput") | | `maxPrice` | `object` | Maximum price limits | | `preferredMinThroughput` | `number` | Minimum tokens per second preference | | `preferredMaxLatency` | `number` | Maximum latency preference | ### RequestOptions | Parameter | Type | Description | | --------- | ------------- | ------------------------------- | | `timeout` | `number` | Request timeout in milliseconds | | `signal` | `AbortSignal` | Abort signal for cancellation | *** ## ModelResult Wrapper providing multiple consumption patterns for a response. ### Methods #### getText() ```typescript lines theme={null} getText(): Promise ``` Get text content after tool execution completes. #### getResponse() ```typescript lines theme={null} getResponse(): Promise ``` Get full response with usage data (inputTokens, outputTokens, cachedTokens). #### getTextStream() ```typescript lines theme={null} getTextStream(): AsyncIterableIterator ``` Stream text deltas. #### getReasoningStream() ```typescript lines theme={null} getReasoningStream(): AsyncIterableIterator ``` Stream reasoning deltas (for reasoning models). #### getNewMessagesStream() ```typescript lines theme={null} getNewMessagesStream(): AsyncIterableIterator ``` Stream cumulative message snapshots in OpenResponses format. #### getFullResponsesStream() ```typescript lines theme={null} getFullResponsesStream(): AsyncIterableIterator ``` Stream all events including tool preliminary results. #### getToolCalls() ```typescript lines theme={null} getToolCalls(): Promise ``` Get all tool calls from initial response. #### getToolCallsStream() ```typescript lines theme={null} getToolCallsStream(): AsyncIterableIterator ``` Stream tool calls as they complete. #### getToolStream() ```typescript lines theme={null} getToolStream(): AsyncIterableIterator ``` Stream tool deltas and preliminary results. #### getContextUpdates() ```typescript lines theme={null} getContextUpdates(): AsyncGenerator> ``` Stream context snapshots whenever a tool calls `setContext()`. Completes when tool execution finishes. #### cancel() ```typescript lines theme={null} cancel(): Promise ``` Cancel the stream and all consumers. *** ## Tool Types ### tool() ```typescript lines theme={null} function tool(config: ToolConfig): Tool ``` Create a typed tool with Zod schema validation. ### ToolConfig | Parameter | Type | Required | Description | | -------------------- | ------------------------- | -------- | ----------------------------------------------------------- | | `name` | `string` | Yes | Tool name | | `description` | `string` | No | Tool description | | `inputSchema` | `ZodObject` | Yes | Input parameter schema | | `outputSchema` | `ZodType` | No | Output schema | | `eventSchema` | `ZodType` | No | Event schema (triggers generator mode) | | `contextSchema` | `ZodObject` | No | Context data this tool needs | | `execute` | `function \| false` | Yes\* | Execute function, or `false` for manual | | `onToolCalled` | `function` | Yes\* | HITL hook — return value to auto-respond, `null` to pause | | `onResponseReceived` | `function` | No | HITL hook — post-process caller-supplied result (HITL only) | | `nextTurnParams` | `NextTurnParamsFunctions` | No | Parameters to modify next turn | \* Provide exactly one of `execute` or `onToolCalled`. Omitting both (with `execute: false`) makes the tool a manual tool. ### Tool Union type of all tool types: ```typescript lines theme={null} type Tool = | ToolWithExecute | ToolWithGenerator | ManualTool | HITLTool; ``` ### ToolWithExecute Regular tool with execute function: ```typescript lines theme={null} interface ToolWithExecute< TInput, TOutput, TContext, TName > { type: ToolType.Function; function: { name: TName; description?: string; inputSchema: TInput; outputSchema?: TOutput; contextSchema?: ZodObject; execute: ( params: z.infer, context: ToolExecuteContext, ) => Promise>; }; } ``` ### ToolWithGenerator Generator tool with eventSchema: ```typescript lines theme={null} interface ToolWithGenerator< TInput, TEvent, TOutput, TContext, TName > { type: ToolType.Function; function: { name: TName; description?: string; inputSchema: TInput; eventSchema: TEvent; outputSchema: TOutput; contextSchema?: ZodObject; execute: ( params: z.infer, context: ToolExecuteContext, ) => AsyncGenerator>; }; } ``` ### ManualTool Tool without execute function: ```typescript lines theme={null} interface ManualTool { type: ToolType.Function; function: { name: string; description?: string; inputSchema: TInput; outputSchema?: TOutput; }; } ``` ### HITLTool Human-in-the-loop tool with `onToolCalled` and optional `onResponseReceived` hooks. `outputSchema` is required — it validates both the hook's non-null return value and the caller-supplied response delivered via `function_call_output`. ```typescript expandable lines theme={null} interface HITLToolFunction< TInput, TOutput, TContext, TName > { name: TName; description?: string; inputSchema: TInput; outputSchema: TOutput; contextSchema?: ZodObject; onToolCalled: ( params: z.infer, context?: ToolExecuteContext, ) => Promise | null> | z.infer | null; onResponseReceived?: ( rawResult: unknown, context?: ToolExecuteContext, ) => Promise> | z.infer; toModelOutput?: ToModelOutputFunction< z.infer, z.infer >; } type HITLTool = { type: ToolType.Function; function: HITLToolFunction; }; ``` Returning `null` from `onToolCalled` pauses the loop and sets the conversation status to `'awaiting_hitl'`. Throwing from `onToolCalled` is surfaced as a tool error of the form `{ error: ... }`. Throwing from `onResponseReceived` is surfaced as an error payload that includes the caller's original output of the form `{ error: ..., originalOutput: ... }`. *** ## Tool Type Guards ```typescript lines theme={null} function isManualTool(tool: Tool): tool is ManualTool; function isHITLTool(tool: Tool): tool is HITLTool; function isAutoResolvableTool( tool: Tool, ): tool is ToolWithExecute | ToolWithGenerator | HITLTool; ``` * `isManualTool` — no `execute` and no `onToolCalled`. Always pauses the loop. * `isHITLTool` — has an `onToolCalled` function. * `isAutoResolvableTool` — either has an `execute` function (regular/generator) or is a HITL tool. Returns `false` for manual and server tools. *** ## Context Types ### TurnContext ```typescript lines theme={null} interface TurnContext { toolCall?: OpenResponsesFunctionToolCall; numberOfTurns: number; turnRequest?: OpenResponsesRequest; } ``` ### ToolExecuteContext Flat context passed to tool execute functions. Merges `TurnContext` fields with tool-specific context: ```typescript lines theme={null} type ToolExecuteContext = TurnContext & { tools: { readonly [K in TName]: Readonly; }; setContext(partial: Partial): void; }; ``` ### ToolContextMap Context map for `callModel`'s `context` option, keyed by tool name: ```typescript lines theme={null} type ToolContextMap = { [K in T[number] as K['function']['name']]: InferToolContext; }; ``` ### ContextInput Context can be static, a sync function, or an async function: ```typescript lines theme={null} type ContextInput = | T | ((turn: TurnContext) => T) | ((turn: TurnContext) => Promise); ``` ### NextTurnParamsContext ```typescript lines theme={null} interface NextTurnParamsContext { input: OpenResponsesInput; model: string; models: string[]; temperature: number | null; maxOutputTokens: number | null; topP: number | null; topK?: number | undefined; instructions: string | null; } ``` *** ## Stream Event Types ### EnhancedResponseStreamEvent ```typescript lines theme={null} type EnhancedResponseStreamEvent = | OpenResponsesStreamEvent | ToolPreliminaryResultEvent; ``` ### ToolStreamEvent ```typescript lines theme={null} type ToolStreamEvent = | { type: 'delta'; content: string } | { type: 'preliminary_result'; toolCallId: string; result: unknown }; ``` ### ParsedToolCall ```typescript lines theme={null} interface ParsedToolCall { id: string; name: string; arguments: unknown; } ``` ### ToolExecutionResult ```typescript lines theme={null} interface ToolExecutionResult { toolCallId: string; toolName: string; /** * `'client'` for locally-defined tools: `result` is precisely typed from * the tool's `outputSchema`. `'mcp'` for tools wrapped from a remote MCP * server: `result` is `unknown`. * * Consumers narrow on `source` to keep MCP's `unknown` from collapsing the * result union of typed client tools. Also present on `ToolResultEvent` * (streaming). See [Tools › ToolResultEvent](/agent-sdk/call-model/tools#toolresultevent-type). */ source: 'client' | 'mcp'; result: unknown; preliminaryResults?: unknown[]; error?: Error; } ``` The `source` field was added in `@openrouter/agent` 0.8.0. This is an additive breaking change for consumers that exhaustively matched or constructed `ToolExecutionResult` (or `ToolResultEvent`) payloads. ### MCP branding ```typescript lines theme={null} // Guard: returns true for tools branded as originating from an MCP server. function isMcpTool(tool: Tool): tool is McpBranded; // Helper: brand a tool as MCP. `@openrouter/mcp` brands its wrapped tools // automatically; most callers never call this directly. function markMcp(tool: T): McpBranded; // Type-level brand that isolates MCP results in ToolExecutionResult / // ToolResultEvent unions. type McpBranded = T & { readonly _mcp: true }; ``` *** ## Conversation State See [Tool Approval & State](/docs/agent-sdk/call-model/tool-approval-state) for a walkthrough of the state accessor pattern, resumption, and status values. ### ConversationState ```typescript lines theme={null} interface ConversationState { /** * Serialization-contract version. Optional so legacy blobs remain * assignable; absence means `1`. `createInitialState` stamps `1`. */ version?: number; id: string; messages: OpenResponsesInputUnion; previousResponseId?: string; pendingToolCalls?: ParsedToolCall[]; unsentToolResults?: UnsentToolResult[]; partialResponse?: PartialResponse; interruptedBy?: string; status: ConversationStatus; createdAt: number; updatedAt: number; } ``` ### ConversationStatus ```typescript lines theme={null} type ConversationStatus = | 'in_progress' | 'awaiting_approval' | 'awaiting_hitl' | 'awaiting_client_tools' | 'awaiting_async_tools' | 'complete' | 'interrupted'; ``` `'awaiting_client_tools'` was added in `@openrouter/agent` 0.8.0 for unresolved manual (`execute: false`) tool calls. See [Status Values](/docs/agent-sdk/call-model/tool-approval-state#status-values). ### StateAccessor ```typescript lines theme={null} interface StateAccessor { load: () => Promise | null>; save: (state: ConversationState) => Promise; } ``` ### Serialization helpers Opt-in wrappers over `JSON.stringify` / `JSON.parse` that manage the state version and surface typed errors on load. Available at the package root and via the `@openrouter/agent/conversation-state` subpath. ```typescript lines theme={null} const CONVERSATION_STATE_VERSION = 1; function serializeConversationState( state: ConversationState, ): string; function deserializeConversationState( json: string, ): ConversationState; // Thrown when the blob's `version` is not supported by this SDK build. class UnsupportedStateVersionError extends Error { readonly found: number; readonly supported: readonly number[]; } // Thrown for malformed JSON or missing required fields. class InvalidStateError extends Error {} ``` Treat the serialized JSON as opaque. Additive changes stay within a major version; migrations run inside `deserializeConversationState` on version bumps. `StateAccessor.load` / `save` are unchanged, so these helpers are opt-in. *** ## Stop Conditions ### StopWhen ```typescript lines theme={null} type StopWhen = | StopCondition | StopCondition[]; ``` ### StopCondition ```typescript lines theme={null} type StopCondition = (context: StopConditionContext) => boolean | Promise; ``` ### StopConditionContext ```typescript lines theme={null} interface StopConditionContext { steps: StepResult[]; } ``` ### StepResult ```typescript lines theme={null} interface StepResult { stepType: 'initial' | 'continue'; text: string; toolCalls: TypedToolCallUnion[]; toolResults: ToolExecutionResultUnion[]; response: OpenResponsesNonStreamingResponse; usage?: OpenResponsesUsage; finishReason?: string; warnings?: Warning[]; experimental_providerMetadata?: Record; } ``` ### Warning ```typescript lines theme={null} interface Warning { type: string; message: string; } ``` ### Built-in Helpers | Function | Signature | Description | | ---------------- | ----------------------------------- | ------------------------ | | `stepCountIs` | `(n: number) => StopCondition` | Stop after n steps | | `hasToolCall` | `(name: string) => StopCondition` | Stop when tool is called | | `maxTokensUsed` | `(n: number) => StopCondition` | Stop after n tokens | | `maxCost` | `(amount: number) => StopCondition` | Stop after cost limit | | `finishReasonIs` | `(reason: string) => StopCondition` | Stop on finish reason | *** ## Format Helpers ### fromChatMessages ```typescript lines theme={null} function fromChatMessages(messages: Message[]): OpenResponsesInput ``` Convert OpenAI chat format to OpenResponses input. ### toChatMessage ```typescript lines theme={null} function toChatMessage(response: OpenResponsesNonStreamingResponse): AssistantMessage ``` Convert response to chat message format. ### fromClaudeMessages ```typescript lines theme={null} function fromClaudeMessages(messages: ClaudeMessageParam[]): OpenResponsesInput ``` Convert Anthropic Claude format to OpenResponses input. ### toClaudeMessage ```typescript lines theme={null} function toClaudeMessage(response: OpenResponsesNonStreamingResponse): ClaudeMessage ``` Convert response to Claude message format. *** ## Type Utilities ### InferToolInput ```typescript lines theme={null} type InferToolInput = T extends { function: { inputSchema: infer S } } ? S extends ZodType ? z.infer : unknown : unknown; ``` ### InferToolOutput ```typescript lines theme={null} type InferToolOutput = T extends { function: { outputSchema: infer S } } ? S extends ZodType ? z.infer : unknown : unknown; ``` ### InferToolEvent ```typescript lines theme={null} type InferToolEvent = T extends { function: { eventSchema: infer S } } ? S extends ZodType ? z.infer : never : never; ``` ### TypedToolCall ```typescript lines theme={null} type TypedToolCall = { id: string; name: T extends { function: { name: infer N } } ? N : string; arguments: InferToolInput; }; ``` *** ## Exports ```typescript expandable lines theme={null} // Agent client export { OpenRouter } from '@openrouter/agent'; // Tool helpers export { tool, ToolType, isManualTool, isHITLTool, isAutoResolvableTool, isMcpTool, markMcp, } from '@openrouter/agent'; // Conversation state helpers export { createInitialState, serializeConversationState, deserializeConversationState, CONVERSATION_STATE_VERSION, UnsupportedStateVersionError, InvalidStateError, } from '@openrouter/agent'; // Also available at the subpath: '@openrouter/agent/conversation-state' // Format helpers export { fromChatMessages, toChatMessage, fromClaudeMessages, toClaudeMessage } from '@openrouter/agent'; // Stop condition helpers export { stepCountIs, hasToolCall, maxTokensUsed, maxCost, finishReasonIs } from '@openrouter/agent'; // Final-turn directive appended when allowFinalResponse is on (the default) export { DEFAULT_FINAL_RESPONSE_DIRECTIVE } from '@openrouter/agent'; // Context helpers export { buildToolExecuteContext, ToolContextStore, } from '@openrouter/agent'; // Lifecycle hooks export { HooksManager, HookName, isAsyncOutput, } from '@openrouter/agent'; // Types export type { CallModelInput, ContextInput, Tool, ToolWithExecute, ToolWithGenerator, ManualTool, HITLTool, HITLToolFunction, McpBranded, ToolExecuteContext, ToolContextMap, TurnContext, ParsedToolCall, ToolExecutionResult, ToolResultEvent, ConversationState, ConversationStatus, StateAccessor, StopCondition, StopWhen, InferToolInput, InferToolOutput, InferToolEvent, InlineHookConfig, HookEntry, HookHandler, HookReturn, HooksManagerOptions, HookDefinition, HookRegistry, ToolMatcher, EmitResult, BuiltInHookDefinitions, LifecycleHookContext, AsyncOutput, PreToolUsePayload, PreToolUseResult, PostToolUsePayload, PostToolUseFailurePayload, UserPromptSubmitPayload, UserPromptSubmitResult, PermissionRequestPayload, PermissionRequestResult, StopPayload, StopResult, SessionStartPayload, SessionEndPayload, PostModelCallPayload, ModelCallUsage, SessionUsageTotals, } from '@openrouter/agent'; ```