Documentation Index
Fetch the complete documentation index at: https://smithers.sh/llms.txt
Use this file to discover all available pages before exploring further.
CLI-backed agent classes wrap external AI command-line tools and implement the AI SDK Agent interface. Use them anywhere Smithers accepts an agent, including <Task>. Reach for these for a vendor’s full CLI surface (sessions, sandboxes, slash commands, MCP). For API-billed provider wrappers, see SDK Agents.
Quick Start
import { ClaudeCodeAgent, Task, Workflow, createSmithers } from "smithers-orchestrator";
import { z } from "zod";
const { smithers, outputs } = createSmithers({
analysis: z.object({ summary: z.string() }),
});
const claude = new ClaudeCodeAgent({
model: "claude-sonnet-4-20250514",
systemPrompt: "You are a careful code reviewer.",
timeoutMs: 30 * 60 * 1000,
});
export default smithers((ctx) => (
<Workflow name="review">
<Task id="analysis" output={outputs.analysis} agent={claude}>
{`Analyze the codebase and identify potential improvements.`}
</Task>
</Workflow>
));
Available agents
agents[8]{class,cli,defaultModel,hijack,notes}:
ClaudeCodeAgent,claude,claude-sonnet-4-20250514,native session id,Anthropic Claude Code CLI
CodexAgent,codex,gpt-5.3-codex,native thread id,OpenAI Codex CLI (codex exec via stdin + JSON stream)
GeminiAgent,gemini,gemini-2.5-pro,native session id,Google Gemini CLI (falls back to gcloud auth)
PiAgent,pi,gpt-5.2-codex,native session id,Pi CLI (text/json/rpc modes + extension UI hooks)
KimiAgent,kimi,kimi-latest,native session id,Moonshot Kimi CLI (auto-isolates KIMI_SHARE_DIR)
ForgeAgent,forge,anthropic/claude-sonnet-4-20250514,conversation id,Forge CLI (300+ models)
AmpAgent,amp,claude-sonnet-4-20250514,thread id,Amp CLI (--execute headless mode)
OpenCodeAgent,opencode,provider/model string,not yet,OpenCode CLI (opencode run --format json)
CLI binaries must be on PATH: claude, codex, gemini, pi, kimi, forge, amp, opencode.
Codex CLI Agent
CodexAgent is the Smithers wrapper for OpenAI’s codex CLI. It runs codex exec in non-interactive mode, sends the task prompt over stdin, forces --json so Smithers can stream structured progress, and captures the final assistant message via --output-last-message.
import { CodexAgent, Task, Workflow, createSmithers } from "smithers-orchestrator";
import { z } from "zod";
const { smithers, outputs } = createSmithers({
patch: z.object({ summary: z.string(), files: z.array(z.string()) }),
});
const codex = new CodexAgent({
model: "gpt-5.3-codex",
sandbox: "workspace-write",
skipGitRepoCheck: true,
yolo: true,
});
export default smithers(() => (
<Workflow name="codex-implementation">
<Task id="implement" output={outputs.patch} agent={codex}>
Implement the requested change and summarize the edited files.
</Task>
</Workflow>
));
Authentication options:
- Subscription login: run
codex login once. For isolated accounts, pass configDir; Smithers sets CODEX_HOME for that invocation.
- API billing: pass
apiKey or set OPENAI_API_KEY; Smithers forwards it to the spawned codex process.
- Account registry:
bunx smithers-orchestrator agents add --provider codex ... registers a subscription config directory, while --provider openai-api registers API-key billing for Codex-compatible providers.
Structured output:
- If the Smithers task has an output schema and
outputSchema is not set, Smithers writes a temporary OpenAI-compatible JSON Schema file and passes it as --output-schema.
- Resume attempts use
codex exec resume <thread-id> and skip --output-schema, matching the Codex CLI’s resume command surface.
- Hijack opens native Codex with
codex resume <thread-id> -C <cwd>.
Common options
All CLI agents accept the same base option surface:
type BaseCliAgentOptions = {
id?: string; // Agent instance id (default: random UUID)
model?: string; // Model name passed to --model
systemPrompt?: string; // Prepended to the user prompt
instructions?: string; // Alias for systemPrompt
cwd?: string; // Working directory (default: tool ctx rootDir or process.cwd())
env?: Record<string, string>; // Extra env vars merged with process.env
yolo?: boolean; // Skip permission prompts (default: true)
timeoutMs?: number; // Hard wall-clock cap
idleTimeoutMs?: number; // Inactivity cap; resets on any stdout/stderr
maxOutputBytes?: number; // Truncate captured output
extraArgs?: string[]; // Additional CLI flags appended to the command
};
Per-call timeout override:
await agent.generate({
prompt: "do the thing",
timeout: { totalMs: 15 * 60 * 1000, idleMs: 2 * 60 * 1000 },
});
import { ClaudeCodeAgent } from "smithers-orchestrator";
new ClaudeCodeAgent({
permissionMode?: "acceptEdits" | "bypassPermissions" | "default" | "delegate" | "dontAsk" | "plan";
allowedTools?: string[]; disallowedTools?: string[]; disableSlashCommands?: boolean;
addDir?: string[]; file?: string[]; fromPr?: string; fallbackModel?: string;
appendSystemPrompt?: string; agents?: Record<string, { description?: string; prompt?: string }> | string;
agent?: string; tools?: string[] | "default" | "";
betas?: string[]; pluginDir?: string[]; resume?: string; sessionId?: string;
mcpConfig?: string[]; mcpDebug?: boolean; maxBudgetUsd?: number; jsonSchema?: string;
configDir?: string; apiKey?: string;
dangerouslySkipPermissions?: boolean; allowDangerouslySkipPermissions?: boolean; chrome?: boolean; noChrome?: boolean;
continue?: boolean; forkSession?: boolean; noSessionPersistence?: boolean; replayUserMessages?: boolean;
debug?: boolean | string; debugFile?: string; ide?: boolean; includePartialMessages?: boolean;
inputFormat?: "text" | "stream-json"; settingSources?: string; settings?: string; strictMcpConfig?: boolean; verbose?: boolean;
outputFormat?: "text" | "json" | "stream-json"; // default stream-json
});
import { CodexAgent } from "smithers-orchestrator";
new CodexAgent({
sandbox?: "read-only" | "workspace-write" | "danger-full-access";
fullAuto?: boolean; dangerouslyBypassApprovalsAndSandbox?: boolean;
config?: Record<string, unknown> | string[];
enable?: string[]; disable?: string[];
oss?: boolean; localProvider?: string;
image?: string[]; profile?: string; cd?: string; addDir?: string[];
skipGitRepoCheck?: boolean; color?: "always" | "never" | "auto";
outputSchema?: string; outputLastMessage?: string; json?: boolean;
configDir?: string; apiKey?: string;
});
import { GeminiAgent } from "smithers-orchestrator";
new GeminiAgent({
sandbox?: boolean; approvalMode?: "default" | "auto_edit" | "yolo" | "plan";
allowedTools?: string[]; allowedMcpServerNames?: string[];
extensions?: string[]; resume?: string; includeDirectories?: string[];
experimentalAcp?: boolean; listExtensions?: boolean; listSessions?: boolean; deleteSession?: string;
configDir?: string; apiKey?: string; debug?: boolean; screenReader?: boolean;
outputFormat?: "text" | "json" | "stream-json"; // default json
});
import { PiAgent, type PiExtensionUiRequest, type PiExtensionUiResponse } from "smithers-orchestrator";
new PiAgent({
provider?: string; apiKey?: string; mode?: "text" | "json" | "rpc";
print?: boolean; continue?: boolean; resume?: boolean; session?: string;
sessionDir?: string; noSession?: boolean;
models?: string | string[]; listModels?: boolean | string;
extension?: string[]; skill?: string[]; promptTemplate?: string[]; theme?: string[];
noExtensions?: boolean; noSkills?: boolean; noPromptTemplates?: boolean; noThemes?: boolean;
tools?: string[]; noTools?: boolean; files?: string[];
thinking?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
export?: string; verbose?: boolean;
onExtensionUiRequest?: (req: PiExtensionUiRequest) => Promise<PiExtensionUiResponse | null>;
});
import { KimiAgent } from "smithers-orchestrator";
new KimiAgent({
thinking?: boolean; outputFormat?: "text" | "stream-json";
finalMessageOnly?: boolean; quiet?: boolean;
agent?: "default" | "okabe"; agentFile?: string;
workDir?: string; session?: string; continue?: boolean;
skillsDir?: string; mcpConfigFile?: string[]; mcpConfig?: string[];
maxStepsPerTurn?: number; maxRetriesPerStep?: number; maxRalphIterations?: number;
verbose?: boolean; debug?: boolean; configDir?: string;
});
import { ForgeAgent } from "smithers-orchestrator";
new ForgeAgent({
directory?: string; provider?: string; agent?: string;
conversationId?: string; sandbox?: string; restricted?: boolean;
verbose?: boolean; workflow?: string; event?: string; conversation?: string;
});
import { AmpAgent } from "smithers-orchestrator";
new AmpAgent({
visibility?: "private" | "public" | "workspace" | "group";
mcpConfig?: string; settingsFile?: string;
logLevel?: "error" | "warn" | "info" | "debug" | "audit"; logFile?: string;
dangerouslyAllowAll?: boolean; ide?: boolean; jetbrains?: boolean;
});
import { OpenCodeAgent } from "smithers-orchestrator";
new OpenCodeAgent({
model?: string; agentName?: string;
attachFiles?: string[];
continueSession?: boolean; sessionId?: string;
variant?: string;
});
Hijack handoff
Most built-in CLI agents support bunx smithers-orchestrator hijack <runId>, which relaunches the agent in its native CLI session for interactive takeover. Smithers persists the native session id (or conversation id for Forge / thread id for Amp) on each task event; on hijack it waits for a safe boundary between blocking tool calls, then reopens the session via the vendor’s resume flag (claude --resume, codex resume, gemini --resume, pi --session, kimi --session, forge --conversation-id, amp threads continue). On clean exit the workflow resumes in detached mode. OpenCode stream capture is documented above, but native smithers hijack support for OpenCode is not shipped yet. See How it works → Durability and resume.
Notes
- Yolo defaults.
yolo: true (default) maps to each CLI’s “skip approvals” flag (--dangerously-skip-permissions, --dangerously-bypass-approvals-and-sandbox, --yolo, --dangerously-allow-all). Set yolo: false or use the agent-specific approval option for tighter control.
- PI rpc mode sends prompts as JSON over stdin and is required for
onExtensionUiRequest callbacks; text/json modes pass the prompt as a positional arg with files emitted as @path.
- Kimi share dir.
KimiAgent auto-creates an isolated KIMI_SHARE_DIR per invocation to prevent kimi.json corruption under concurrent runs. Set env.KIMI_SHARE_DIR to opt out.
- Gemini auth falls back to
gcloud auth application-default login when neither GOOGLE_API_KEY nor GEMINI_API_KEY is set.
- Non-idempotent retries. When a
<Task> retries, Smithers prepends a warning listing previously-called side-effect tools so the agent can verify external state before re-invoking them.