Tools
Tools are callable capabilities exposed to models during execution.
1. Tool Categories
| Type | Description | Where Defined |
|---|---|---|
| Function tool | Custom executable logic | defineTool() |
| Prompt tool | Nested prompt invocation | definePrompt({ exposeAsTool: true }) |
| Agent tool | Agent callable (handoff or subagent) | defineAgent({ exposeAsTool: true }) |
2. Function Tool Definition
defineTool({
description: 'Search indexed docs',
args: z.object({ query: z.string() }),
execute: async (state, args) => {
const vectorStoreId = await state.env('VECTOR_STORE_ID');
return { status: 'success', result: '...' };
},
variables: [
{
name: 'VECTOR_STORE_ID',
type: 'text',
required: true,
description: 'Vector store identifier',
},
],
});
3. Variable Declarations
Tool and prompt definitions can declare required variables:
interface VariableDefinition {
name: string;
type: 'text' | 'secret';
required: boolean;
scoped?: boolean;
description: string;
}
Semantics:
required: truemeans execution cannot continue until a value resolves.type: 'secret'indicates sensitive values that should be encrypted at rest.scoped: trueblocks inheritance from parent thread env for that variable name.- Scoped variables still flow downward from the thread where they are declared/provided to descendants in that subtree.
4. Prompt Tool Configuration
When a prompt is used as a tool, callers can configure return shaping and initial input mapping:
interface SubpromptConfig {
name: string;
includeTextResponse?: boolean;
includeToolCalls?: boolean;
includeErrors?: boolean;
initUserMessageProperty?: string;
initAttachmentsProperty?: string;
}
5. Subagent Tool Configuration
When dual_ai agents are used as tools, use SubagentToolConfig:
interface SubagentToolConfig {
name: string;
blocking?: boolean;
initUserMessageProperty?: string;
initAttachmentsProperty?: string;
initAgentNameProperty?: string;
immediate?: boolean;
optional?: string;
resumable?: false | {
receives_messages: 'side_a' | 'side_b';
maxInstances?: number;
};
}
Behavioral summary:
- non-resumable: direct tool-call semantics.
- resumable: runtime lifecycle tooling with persistent references.
immediate: true: execute as soon as the prompt becomes active, before the first model step.optional: 'FLAG_NAME': branch is enabled only when that environment flag resolves totrue,1, oryes(case-insensitive).
See Subagents for full lifecycle and communication rules.
6. Resumable Lifecycle Tools
For resumable subagents, runtimes provide built-in lifecycle tools:
subagent_createsubagent_message
These tools are runtime-injected and scoped to what is currently enabled and available for that prompt/thread state.
If subagent_create cannot proceed because required scoped variables are missing, runtimes should return a structured bootstrap error (for example subagent_env_required) including a request ID and a temporary variables endpoint:
GET /threads/{parent_thread_id}/variables/{request_id}POST /threads/{parent_thread_id}/variables/{request_id}
The POST flow stores the provided values and immediately boots the deferred subagent instance.
7. Attachment Semantics Across Threads
When tool-driven subagent communication crosses thread boundaries:
- parent -> child attachment paths must be copied to child-local paths
- child -> parent attachment paths must be copied to parent-local paths
Returned attachment references must always be valid for the receiving thread filesystem.
8. Conformance Notes
Implementations MUST:
- validate tool args against schema
- execute local tools sequentially in returned order
- persist tool results as messages
- surface tool errors as tool results (not hard-crash the run)