Tools

Tools are callable capabilities exposed to models during execution.

1. Tool Categories

TypeDescriptionWhere Defined
Function toolCustom executable logicdefineTool()
Prompt toolNested prompt invocationdefinePrompt({ exposeAsTool: true })
Agent toolAgent 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: true means execution cannot continue until a value resolves.
  • type: 'secret' indicates sensitive values that should be encrypted at rest.
  • scoped: true blocks 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 to true, 1, or yes (case-insensitive).

See Subagents for full lifecycle and communication rules.

6. Resumable Lifecycle Tools

For resumable subagents, runtimes provide built-in lifecycle tools:

  • subagent_create
  • subagent_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)