Skip to main content
AnthropicAgent, OpenAIAgent, and HermesAgent are provider-backed AI SDK agents with class-style ergonomics matching the CLI agents. AnthropicAgent and OpenAIAgent wrap ToolLoopAgent directly; HermesAgent extends the OpenAI-compatible path with Hermes defaults. ElizaAgent adapts an Eliza runtime/character into the same Smithers agent interface.
API reference: Agents lists every agent class, its options, and links to source and tests.

Import

Quick Start

In workflow JSX, the schema lives on the Smithers task (output={outputs.plan}), not the agent constructor. At execution time the engine infers the task’s Zod schema and calls the SDK agent with agent.generate({ outputSchema }), passing both the prompt and the schema. ctx is the normal smithers((ctx) => ...) parameter, typed from the input schema above. You can also call an SDK agent directly, without a workflow: pass outputSchema to generate() for typed structured output:
For AnthropicAgent, outputSchema is forwarded as AI SDK Output.object({ schema }), which uses Anthropic’s native structured-output request path for Claude models. OpenAIAgent does the same unless nativeStructuredOutput: false; HermesAgent defaults that option to false (see Hermes below).

Model Input

AnthropicAgent and OpenAIAgent accept a model ID string ("claude-fable-5", "gpt-5.6-luna") or a prebuilt provider model instance; HermesAgent’s model is optional and defaults to "hermes".

Options

Constructors forward standard AI SDK ToolLoopAgent settings (instructions, tools, stopWhen, maxOutputTokens, temperature, providerOptions, prepareCall) and add provider model resolution on top.
  • AnthropicAgentOptions is ToolLoopAgentSettings with model required as string | LanguageModel.
  • OpenAIAgentOptions adds nativeStructuredOutput?: boolean and two model forms: a string model may include baseURL, apiKey, and api; a prebuilt OpenAI provider model must not include baseURL or apiKey.
  • HermesAgentOptions makes model optional, allows baseURL/apiKey, and defaults nativeStructuredOutput to false. A runtime baseURL or HERMES_BASE_URL is required.
For the string model form of OpenAIAgent, pass baseURL and apiKey directly to target an OpenAI-compatible endpoint instead of the default OpenAI API, the simplest path for local servers like llama.cpp. Use apiKey: "none" when the server accepts OpenAI-compatible requests but doesn’t require a real key:
String models default to OpenAI’s Responses API (/responses), which most OpenAI-compatible servers (Gemini’s OpenAI-compat layer, llama.cpp, vLLM) don’t implement: every call 404s though /chat/completions works fine. Set api: "chat" to route the agent through /chat/completions on those endpoints:
Some OpenAI-compatible local servers accept chat requests but don’t reliably implement JSON schema structured output: keep the output schema on the Smithers task and disable native structured output on the agent so Smithers falls back to prompt-based JSON extraction:
For advanced provider setup, create the AI SDK OpenAI provider and pass the prebuilt model into OpenAIAgent:
Use this path for provider-level config beyond baseURL/apiKey; in that form baseURL and apiKey belong in the createOpenAI config, not the OpenAIAgent constructor.

Generic HTTP Tool

createHttpTool() returns an AI SDK tool that calls any REST endpoint without an OpenAPI spec: the universal escape hatch when no curated connector or MCP server exists yet.
The tool input accepts method, url, headers, query, body, optional auth (bearer, basic, or custom header), and timeoutMs. Results include ok, status, statusText, response headers, and a parsed JSON or text body.

Hermes

Hermes (Nous Research) exposes an OpenAI-compatible HTTP API; HermesAgent is a convenience OpenAIAgent subclass that points at your Hermes server and disables native structured output by default (a local Hermes server may not honor JSON-schema response formats).
baseURL falls back to the HERMES_BASE_URL env var and must be set in either place; apiKey falls back to HERMES_API_KEY (then "hermes"). Pass nativeStructuredOutput: true if your server honors JSON-schema output. To use Smithers from Hermes instead of running Hermes as a worker, see Agent Support → Hermes.

Eliza

ElizaAgent wraps an in-process elizaOS AgentRuntime so an Eliza character and its plugins (Slack, Discord, Telegram, model providers) run as a first-class Smithers agent. Unlike the other agents here, it ships in a separate opt-in package owning the @elizaos/core dependency: install and import it from @smthrs/agent-eliza:
The harness lazily initializes the runtime on the first generate (or preflight) call and reuses it across calls. settings and env merge onto the character’s settings, with precedence env > settings > character.settings. Pass an outputSchema on the Smithers task (or to generate directly) for structured output; ElizaAgent extracts JSON from the model’s text since it doesn’t set supportsNativeStructuredOutput.

Hijack Support

SDK agents do not reopen a provider-native CLI; Smithers persists the agent conversation and reopens it through a Smithers-managed REPL via bunx smthrs hijack RUN_ID. Live-run behavior:
  • Smithers captures response history after each step via onStepEnd.
  • bunx smthrs hijack waits until history is durable, aborts the current agent task (handing it off to the REPL), and opens the REPL.
  • On clean REPL exit, Smithers writes updated message history back and resumes the workflow automatically.
Limits:
  • Smithers reconstructs the agent from the workflow source on hijack, so cross-engine hijack isn’t supported: the REPL uses the same agent class that ran originally.

CLI vs SDK

Choosing an agent for typed/JSON-output tasks. Only AnthropicAgent and OpenAIAgent declare supportsNativeStructuredOutput = true: when a <Task> has an output schema, they pass it through the AI SDK’s native structured-output API (Output.object({ schema })) for a schema-constrained result. CLI agents (ClaudeCodeAgent, CodexAgent, etc.) do not set this flag: the engine falls back to injecting JSON instructions into the prompt and extracting the object from the model’s text, and emits a console.warn (“engine … does not support native structured output. Falling back to prompt-injection + text JSON extraction”). Schema-validation retries still run, but valid JSON shape doesn’t guarantee meaningful values. For typed/JSON-output tasks, prefer AnthropicAgent/OpenAIAgent (or an OpenAI-compatible endpoint that honors JSON schema, via OpenAIAgent with nativeStructuredOutput left enabled). CodexAgent additionally forwards the task schema to the CLI via --output-schema for constrained decoding, but the engine still wraps it with the prompt-injection fallback because the flag is unset. Pass a raw ToolLoopAgent directly if preferred; the wrappers are convenience, not a separate runtime.

Transcription Tool

Use createTranscriptionTool when an SDK agent needs to transcribe audio in its tool loop. It accepts audioUrl or audioBase64 input and normalizes Whisper/Deepgram responses to { text, provider, language?, durationSeconds? }. For Whisper, remote audio downloads are capped at 25 MiB by default; set maxResponseBodyBytes for a different cap (the deprecated maxResponseBytes is a fallback when it’s omitted). The generic createHttpTool has its own independent 1 MiB default.

Example: Dual Setup

Next Steps