agent
Describe an agent.
Pure: no I/O, no env reads, no sockets. Checked by Agent.check() or on the first run.
Import from @threads/core (TypeScript) or threads (Python).
function agent(options: {
model: Model;
instructions?: string;
name?: Name;
tools?: readonly (Tool | McpServer)[];
extensions?: readonly Extension[];
sandbox?: Sandbox;
memory?: MemoryProvider;
memoryWrite?: "deny" | "ask" | "allow_principal" | "allow";
knowledge?: KnowledgeProvider;
skills?: readonly Skill[];
output?: z.ZodType<Output>;
outputRetries?: number;
subagents?: readonly (Agent<unknown, unknown>)[];
handoffs?: readonly (Agent<unknown, unknown>)[];
fallback?: readonly Model[];
permissions?: Partial<Policy.permissions>;
approvers?: readonly Principal[];
budget?: Budget;
retry?: Partial<Policy.retry>;
context?: Partial<Policy.context>;
egress?: readonly string[] | "unenforced";
web?: { fetch?: boolean; search?: SearchBackend };
git?: { credential: Secret; forgeUrl?: string; apiUrl?: string };
computer?: boolean;
lsp?: { languages: readonly string[] };
}): Agent<Deps, Output>Parameters
modelModelrequiredThe model every turn is sent to: a model adapter such as anthropic() or openai(), or scriptedModel() in tests. Fallback models are tried after it. See Model.
instructionsstringPinned system text (the pinned prompt prefix).
nameNamedefault agentUnique among the agents a host, subagent list or handoff list names.
toolsreadonly (Tool | McpServer)[]default []App tools and MCP servers. Built-in tools come from the sandbox and the options below.
extensionsreadonly Extension[]default []Instructions and hooks run in this order.
sandboxSandboxThe sandbox the sandbox tools run in: bash and the file tools (read, write, edit, ls, glob, grep). The git, lsp and computer options also need one. Omitted: no sandbox tools. See Sandbox.
memoryMemoryProviderSaved cross-run memory: localMemory() or a memory adapter. It pins save_memory, search_memory and forget_memory. Omitted: the agent has no memory tools. See MemoryProvider.
memoryWrite / memory_write"deny" | "ask" | "allow_principal" | "allow"default askWrite authority for save_memory.
knowledgeKnowledgeProviderRetrieval over sources the host admits: localKnowledge(paths) or a knowledge adapter. It pins search_knowledge. Omitted: the agent has no knowledge tool. See KnowledgeProvider.
skillsreadonly Skill[]default []Pinned in config_hash (name, description, sha256 of body). The system prompt lists them after the extension instructions as "Skills you can load with load_skill:" then one "- name: description" line each, in the given order; load_skill (pinned only when this is non-empty) appends the body as injected{source: skill, trust: trusted_instruction, origin: {id: name, version: sha256 of body}}. Unique names; a description is one non-empty line.
outputz.ZodType<Output>Structured final output: a schema the final answer must parse with. Omitted: completed.output is the final text.
outputRetries / output_retriesnumberdefault 2Failed candidates per turn (a rejected final_output or a plain-text end) before turn_completed{output_invalid}. An integer from 0 to 2^53-1; anything else is ConfigError invalid_config.
subagentsreadonly (Agent<unknown, unknown>)[]default []Agents spawn_agent may start, by name. Team tools come with them. A subagent with output reports the canonical JSON of its accepted output.
handoffsreadonly (Agent<unknown, unknown>)[]default []Agents this one may hand the conversation to, pinned as policy.handoffs.
fallbackreadonly Model[]default []Fallback models in order. With the default fallback_scope turn, the next user_input reverts to the settings before the fallback (settings_changed{reason: revert}), gated by before_model_switch.
permissionsPartial<Policy.permissions>The permission policy every tool call is decided under: mode, allow, ask and deny rules, protected_paths, allow_bypass and plan_exit_mode. In TypeScript the fields you give override the defaults; Python takes a complete Permissions. Omitted: mode default, no rules, the built-in protected paths, allow_bypass false and plan_exit_mode default.
approversreadonly Principal[]Who may answer approval challenges and resolve parked effects for runs this agent roots, its subagents and handoff targets included. Omitted: only the root run's originating principal (the principal of the root thread's latest user_input).
budgetBudgetThread budget: limits such as max_turns, max_model_requests, max_input_tokens, max_output_tokens, max_cost_nanos and max_wall_ms, checked before every model request. It covers the thread and every descendant. Omitted: no thread budget.
on_unknown_usagePolicy.on_unknown_usagedefault upper_boundPython only. How a budget counts a model attempt the provider reports no usage for. upper_bound counts it at its conservative upper bound; stop lets a limit the model can't bound per attempt pass setup and refuses it at run time instead of failing setup with budget_unenforceable.
retryPartial<Policy.retry>Model retry settings: max_retries, base_delay_ms, max_delay_ms, max_retry_after_ms, max_total_wait_ms, crash_resends, fallback_after, fallback_scope and heartbeat_ms. In TypeScript the fields you give override the defaults; Python takes a complete Retry. Omitted: the default policy (8 retries, 1000 ms base delay doubling up to 32000 ms, fallback after 3 failures in a turn).
contextPartial<Policy.context>Context-window settings: reserve_tokens, clearing old tool results, spilling large results, compaction and what is restored after it, output continuations and tool deferral. In TypeScript the fields you give override the defaults; Python takes a complete Context. Omitted: the default context policy.
egressreadonly string[] | "unenforced"default []Sandbox egress allowlist of hosts. [] is deny-all. unenforced opts in to a provider that can't enforce it; stub mode then refuses. Host allowlists are not supported yet in either language: use [] (deny-all) or "unenforced".
web{ fetch?: boolean; search?: SearchBackend }Host-side web tools: web_fetch and web_search run on the host, not in the sandbox. Omitted: no web tools.
web.fetchbooleandefault falsetrue pins web_fetch, which fetches a URL from the host. false (the default) leaves it out.
web.searchSearchBackendThe search backend web_search uses (an adapter such as exa, brave or tavily). Omitted: no web_search tool.
git{ credential: Secret; forgeUrl?: string; apiUrl?: string }Enables the git gateway tools git_clone, git_fetch, git_push and open_pull_request. The forge is GitHub; the credential is revealed only on the host and never enters the sandbox. Needs a sandbox. Omitted: no git tools.
git.credentialSecretrequiredThe forge token, as a secret(). It is revealed only on the host when a git tool talks to the forge, never in the sandbox.
git.forgeUrl / git.forge_urlstringdefault https://github.comA repo owner/name lives at <forge_url>/<owner>/<name>.git.
git.apiUrl / git.api_urlstringdefault https://api.github.comThe forge REST API open_pull_request uses.
computerbooleandefault falsePins computer_screenshot (read_only) and computer (actions, unguarded). Needs a sandbox whose info.desktop is native or image; otherwise a setup error capability_missing.
lsp{ languages: readonly string[] }Pins lsp for these languages (typescript, python, go, rust), run in the sandbox image's language servers. Needs a sandbox; an unknown language is unknown_preset. A server that isn't installed or ready answers unavailable at run time. Omitted: no lsp tool.
lsp.languagesreadonly string[]requiredThe languages lsp serves: typescript, python, go or rust. Any other name is a setup error unknown_preset.