Skip to main content

Agent

$.agent starts and lists subagents and teammates, and it registers new agent types. agent.offer decides which agent types the model sees. agent.spawn picks the model of a new agent or refuses it.

Return { isOffered: false } or { deny } from a hook to turn something off. Hook agent.spawn to pick a model or refuse, and agent.offer to hide a type.

Official pages: Use the Mods API, Mods Reference. Source: the program (types-2.1.304.d.ts). In a "Where it can be used" cell, "Run time" means in a hook, in a closure that a hook drew, or in a timer callback. It does not mean inside register.

Example​

This hook sends every subagent that does not name a model to haiku.

on('agent.spawn', async ($, e, next) => next(e.model ? e : { ...e, model: 'haiku' }))

Members of the Agent Noun​

ItemStatusWhat it doesHow it worksWhere it can be used
$.agent.spawnDocumentedSpawns a subagent. It is the event agent.spawn, the same call the engine makes when the Agent tool starts one.(input: AgentSpawnArgs) => Promise<AgentSpawnResult>. Starts a subagent in the background and resolves { model, agentId } or { deny }.Run time.
$.agent.listDocumentedReturns the agents of the session so far, subagents and teammates, whoever spawned them.() => Promise<AgentInfo[]>. One entry for each agent until the engine drops its task. A workflow's agents are not listed.Run time.
$.agent.registerDocumentedDefines an agent type, named <plugin>:<name>, that the Agent tool dispatches from the next turn on.(spec: AgentSpec) => Promise<...>. Takes the same fields as an agent file. A second call with the same name replaces the first. Rejects on an invalid spec.After the session binds at session.start (rejects before).

Engine Events​

ItemStatusWhat it doesHow it worksWhere it can be used
agent.offerDocumentedFires when the engine offers an agent type to the model, in the agent listing and again at dispatch. next(e) resolves to { isOffered: true }.Input AgentOfferInput. Result AgentOfferResult. Return { isOffered: false } to hide the type from the model and refuse its dispatch.on('agent.offer', ...). In tests: $.agent.offer(...) on the test engine (not on a hook's $).
agent.spawnDocumentedFires when the Agent tool, or a workflow script's agent() call, is about to start an agent, before the model is resolved.Input AgentSpawnInput. Result AgentSpawnResult: { model } or { deny }. A guard that fails is skipped and the subagent starts.on('agent.spawn', ...). Also $.agent.spawn(...).

Events Raised by Agent Calls​

ItemStatusWhat it doesHow it worksWhere it can be used
agent.listDocumentedThe argument of $.agent.list().Input NoArgs. Value AgentInfo[]. A hook above the caller returns next(e), { deny: reason }, or { value }.on('agent.list', ...)
agent.registerDocumentedThe argument of $.agent.register(spec). A hook above can rewrite any of it, but the type stays the caller's.Input AgentSpec. Value { agent: string }.on('agent.register', ...)

Agent Types​

Call Records and Status​

ItemStatusWhat it is forShape and limits
AgentCallRecordDocumentedWhat an Agent call raised by a plugin ($.tool.call({ tool: "Agent", ... })) answers as result once the agent settles. text is its final answer.Fields agentId (as $.agent.list() names it) and resolvedModel?. A plugin's spawn always runs in the background.
AgentStatusDocumentedWhere an agent's loop stands.'pending' | 'running' | 'waiting' | 'idle' | 'completed' | 'failed' | 'killed'. idle means between turns until a message wakes it. A message may resume an ended agent under the same id.
AgentLoopDocumentedWhich model loop an event happened in.Field agentId?: the loop's agent id inside a subagent or teammate, absent on the main loop. Pinned. next.origin names the plugin that caused the call.
AgentTeammateRecordDocumentedWhat an Agent call that started a teammate answers as result.status ('teammate_spawned'), agentId?, agent_id (older spelling), teammate_id, name (any @ replaced, with a suffix such as scout-2 when taken), team_name?, agent_type?, resolvedModel?, model?, prompt.

What $.agent.list() Returns​

ItemStatusWhat it is forShape and limits
AgentInfo.idDocumentedThe agent's one id.string. The Agent tool calls it agentId. The classic events call it agent_id. A teammate in its own terminal pane uses its address as the id.
AgentInfo.teammateIdDocumentedA teammate's address in its team, <name>@<team>.string, optional. Absent for other agents.
AgentInfo.descriptionDocumentedThe Agent call's short description of the task.string.
AgentInfo.typeDocumentedThe agent type it was spawned as (general-purpose, Explore), or teammate.string.
AgentInfo.statusDocumentedWhere its loop stands now.AgentStatus.
AgentInfo.parentIdDocumentedThe id of the agent whose loop spawned it.string, optional. Absent when the main loop did.
AgentInfo.spawnedByDocumentedThe plugin whose $.agent.spawn (or Agent $.tool.call) started it.string, optional. Absent when the model or the person did.
AgentInfo.nameDocumentedWhat SendMessage addresses it by, when it has one.string, optional. Two agents may hold one name. id tells them apart.

Offer Types​

ItemStatusWhat it is forShape and limits
AgentOfferInput.agentDocumentedWhich type (Explore, Plan, a plugin's agent). It is the key a matcher narrows on.string.
AgentOfferInput.descriptionDocumentedThe text of its listing line (whenToUse).string.
AgentOfferInput.sourceDocumentedWhere the definition came from (built-in, plugin, a settings source).string.
AgentOfferInput.providerDocumentedWho provides this agent: the plugin and its tier. A built-in is { plugin: "engine", tier: "core" }.Origin. Pinned.
AgentOfferResult.isOfferedDocumentedWhether the model is offered the type, in its listing and at dispatch.boolean.

Spawn Types​

AgentSpawnArgs is the input of the call: the prompt field of AgentSpawnInput plus optional description, subagentType, model, name, and cwd. A hook may rewrite the content keys of AgentSpawnInput. Every other key is pinned.

ItemStatusWhat it is forShape and limits
AgentSpawnInput.tool_use_idDocumentedThe Agent tool call this spawn belongs to. Pinned.string. For a workflow agent it is the Workflow tool call that started the run.
AgentSpawnInput.promptDocumentedThe task the subagent gets. A rewrite is the prompt it runs with.string. On a workflow run that hides its script, it is a placeholder, and a rewrite is not applied.
AgentSpawnInput.descriptionDocumentedThe short description of the task. A rewrite is what the task shows as.string.
AgentSpawnInput.subagentTypeDocumentedThe resolved agent type (general-purpose, Explore, a plugin's agent, fork).string. A name that matches no agent refuses the spawn.
AgentSpawnInput.providerDocumentedWho provides this agent. Pinned.Origin.
AgentSpawnInput.modelDocumentedThe Agent tool's model parameter as given, an alias (haiku) or a full id.string, optional. A hook sets it to pick the model. Forks inherit the model, so it is ignored for them.
AgentSpawnInput.parentModelDocumentedThe parent's effective model, what inherit resolves to. Pinned.string.
AgentSpawnInput.parentAgentIdDocumentedThe id of the loop the spawn happens in. Pinned.string, optional. Absent from main.
AgentSpawnInput.permissionModeDocumentedThe parent's permission mode, which the subagent inherits. Pinned.string, optional.
AgentSpawnInput.backgroundDocumentedTrue when the subagent runs in the background or remotely.boolean. The agent definition or remote isolation can force it on. Disabled background tasks force it off. A teammate's is always true.
AgentSpawnInput.forkDocumentedTrue for a fork of the parent. It inherits the parent's context and model. Pinned.boolean.
AgentSpawnInput.isTeammateDocumentedPresent and true when the call starts a teammate. Pinned.true, optional. A teammate is a named agent of the session's team. It goes idle between turns and wakes on a message.
AgentSpawnInput.workflowDocumentedPresent when a workflow script's agent() starts the agent. Pinned.object, optional. A hook may rewrite prompt and model only. A deny becomes the error that the script's agent() throws.
AgentSpawnInput.resumeDocumentedPresent when the run resumes a subagent or brings a teammate back from disk.object, optional. A hook can only refuse it. A deny leaves the agent parked.
AgentSpawnInput.nameDocumentedThe name given by the call, which SendMessage can address. Pinned.string, optional. A teammate whose name the team already has gets a suffix.
AgentSpawnInput.cwdDocumentedThe directory the subagent runs in, when the call set one. A rewrite is where it runs.string, optional. A teammate runs in the session's directory.
AgentSpawnResult.modelDocumentedWhat the subagent runs on.string. From core it is the resolved id. From a hook it can be an alias or an id.
AgentSpawnResult.agentIdDocumentedThe id of the started subagent.string, optional. Set by core. A hook that answers without next started none.
AgentSpawnResult.teammateIdDocumentedA started teammate's address, <name>@<team>.string, optional. Set by core.
AgentSpawnResult.denyDocumentedRefuses the spawn, so nothing starts.string. The text is the Agent tool's error, or the error a workflow's agent() call throws. Returned after next(e) was answered, it fails the hook.

AgentSpawnResult is either { model, agentId, teammateId? } or { deny }. The answer of the subagent comes in its own turn.complete with this agentId.

Agent Spec​

AgentSpec is what $.agent.register takes. It is an agent definition as spelled in settings JSON, plus a name. It accepts every field that an agent file or a --agents entry accepts.

ItemStatusWhat it is forShape and limits
AgentSpec.nameDocumentedThe short name of the type. The type is <plugin>:<name>.string. Letters, digits, _, -, up to 64.
AgentSpec.descriptionDocumentedWhen to delegate to this agent. The model reads it in its listing, and agent.offer gets it.string.
AgentSpec.promptDocumentedThe agent's system prompt, whole. It replaces the session's.string.
AgentSpec.toolsDocumentedWhat the agent may call, by tool name (Read, Bash, mcp__x__y). A call to any other is refused. Left out means every tool of the parent.readonly string[], optional.
AgentSpec.disallowedToolsDocumentedTools withheld from the agent, out of whatever tools allows.readonly string[], optional.
AgentSpec.modelDocumentedThe agent's model: an alias (haiku, sonnet, opus), a full id, or inherit. Left out means the session's subagent default.string, optional.
AgentSpec.effortDocumentedThe agent's effort: low, medium, high, xhigh, max, or an integer budget.string | number, optional.
AgentSpec.permissionModeDocumentedHow the agent's permission asks are decided: default, acceptEdits, plan, auto, dontAsk, or bypassPermissions. Left out means the parent's.string, optional.
AgentSpec.mcpServersDocumentedServers connected over MCP for the agent's run: a configured server's name, or one server's config inline.readonly (string | Record<string, unknown>)[], optional.
AgentSpec.hooksDocumentedSettings hooks in force while the agent runs, in the hooks shape of settings.json.Record<string, unknown>, optional.
AgentSpec.maxTurnsDocumentedThe most turns the agent takes before it stops.number, optional.
AgentSpec.autoCompactWindowDocumentedToken count, 100000 to 1000000, at which the agent compacts its own conversation. It only lowers the window.number, optional.
AgentSpec.skillsDocumentedSkill names preloaded into the agent's context before its first turn.readonly string[], optional.
AgentSpec.initialPromptDocumentedThe agent's first user turn. {{intent}} in it takes the spawn's prompt. Left out means the spawn's prompt is the first turn.string, optional.
AgentSpec.memoryDocumentedA persistent memory the agent keeps between runs, and where.'user' | 'project' | 'local', optional.
AgentSpec.backgroundDocumentedEvery spawn of the agent runs in the background.true, optional.
AgentSpec.omitClaudeMdDocumentedThe agent's context carries no CLAUDE.md block.true, optional.
AgentSpec.isolationDocumentedWhere the agent runs apart from the session: worktree (its own git worktree) or remote (a cloud session where the build allows one).'worktree' | 'remote', optional.