Skip to main content
AnthropicAgent and OpenAIAgent are thin wrappers around the AI SDK ToolLoopAgent with class-style ergonomics matching the CLI agents.

Import

import {
  AnthropicAgent,
  OpenAIAgent,
  tools,
} from "smithers-orchestrator";
import { stepCountIs } from "ai";

Quick Start

const claude = new AnthropicAgent({
  model: "claude-opus-4-6",
  tools,
  instructions: "You are a careful planner.",
  stopWhen: stepCountIs(40),
});

const codex = new OpenAIAgent({
  model: "gpt-5.3-codex",
  tools,
  instructions: "You are a precise implementation agent.",
  stopWhen: stepCountIs(40),
});
{/* outputs comes from createSmithers() */}
<Task id="plan" output={outputs.plan} agent={claude}>
  Analyze the repository and propose a migration plan.
</Task>

Model Input

Both classes accept a model ID string ("claude-opus-4-6", "gpt-5.3-codex") or a prebuilt AI SDK language model instance.

Options

Constructors forward standard AI SDK ToolLoopAgent settings:
  • instructions
  • tools
  • stopWhen
  • maxOutputTokens
  • temperature
  • providerOptions
  • prepareCall
The only addition is model: the wrapper resolves model-ID strings automatically.

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 smithers hijack <runId>. Live-run behavior:
  • Smithers captures response history after each step via onStepFinish.
  • smithers hijack waits until history is durable, cancels the live run, and opens the REPL.
  • On clean REPL exit, Smithers writes updated message history back and resumes the workflow automatically.
Limits:
  • Conversation hijack stays on the same agent implementation. Cross-engine hijack is not supported.
  • Smithers reconstructs the original task agent from the workflow source.

CLI vs SDK

CLI AgentsSDK Agents
BillingProvider subscription / local CLIAPI billing
ToolsProvider CLI tool ecosystemSmithers tools sandbox
FlexibilityNative CLI flagsAI SDK providerOptions
Pass a raw ToolLoopAgent directly if you prefer. The wrappers are convenience, not a separate runtime.

Example: Dual Setup

const useCli = process.env.USE_CLI_AGENTS === "1";

export const claude = useCli
  ? new ClaudeCodeAgent({
      model: "claude-opus-4-6",
      dangerouslySkipPermissions: true,
    })
  : new AnthropicAgent({
      model: "claude-opus-4-6",
      tools,
      instructions: "You are a careful planner.",
      stopWhen: stepCountIs(40),
    });
See Model Selection for a broader comparison.