What Are Tools?
Tools are callable capabilities that extend what AI agents can do beyond generating text. They allow agents to:- Execute code: Run custom business logic
- Access data: Query databases and APIs
- Perform actions: Create records, send emails, trigger workflows
- Call other AI: Invoke sub-prompts or hand off to specialized agents
In AgentBuilder, “tools” includes function tools, prompt tools, and agent tools. Callable
dual_ai agent tools can execute as autonomous subagents.Quick Start
Create your first tool inagents/tools/search_database.ts:
That’s it! Your tool is now available to any prompt that includes it in its
tools array. The framework auto-discovers it from the agents/tools/ directory.Tool Types
AgentBuilder supports three types of tools that all appear the same to LLMs:Function Tools
Custom TypeScript functionsDefined in:
agents/tools/Best for:- Database queries
- API calls
- File operations
- Business logic
Prompt Tools
Other prompts called as sub-promptsDefined in:
agents/prompts/ with exposeAsTool: trueBest for:- Specialized analysis
- Content generation
- Data summarization
- Validation tasks
Agent Tools
Full agents for handoffsDefined in:
agents/agents/ with exposeAsTool: trueBest for:- Specialist routing
- Complex workflows
- Domain expertise
- Multi-turn tasks
Runtime Subagent Lifecycle Tools
When a prompt defines resumable subagent relationships, AgentBuilder injects runtime lifecycle tools:subagent_createsubagent_message
agents/tools/.
subagent_create requires a non-empty name for the spawned child instance.
Non-resumable subagents still behave like regular tool calls.
How They Work Together
ThreadState Context
Every tool receives aThreadState object providing execution context:
ThreadState gives tools access to thread storage, message operations, file system, and execution state. See the ThreadState documentation for details.
Sandboxed Code Execution
Usestate.runCode() when a tool needs to evaluate model- or user-authored JavaScript/TypeScript. The code runs in a Dynamic Worker sandbox with no implicit host capabilities and is loaded by stable content ID when possible. Bridge only the functions and data you want the code to access. Use modules when the entry source imports local relative modules, and execute when you want to run a named export or pass arguments.
reports, and can be stopped with run.terminate(reason) from a caller-owned timeout.
Input Validation with Zod
Tools use Zod schemas to validate arguments:Tool Results
Tools return aToolResult object:
Common Patterns
Text ResultThread Environment Variables
Tools can declare required thread environment variables using thevariables option:
secret should be redacted from tool output and errors; values marked text may be shown. Tools can write thread env values with state.setEnv(name, value, { type: 'text' | 'secret' }).
When a tool reads state.env(name), AgentBuilder resolves values in this order:
thread, user account, AgentBuilder instance, agent definition, then prompt definition.
User-account and instance-level variables can also persist their own text /
secret display type, so safe defaults may preload in the UI without forcing
secrets to be revealed.
Provider-Executed Tools
Some tools are executed by the LLM provider rather than locally. Provider packages usually expose these names throughgetTools(), and models opt in with
providerTools:
tools, just like local tools.
AgentBuilder marks those definitions with executionMode: 'provider' and
passes them to the provider. The local tool executor does not run provider tools;
the provider package owns native request translation, execution, and reporting
completed calls through the generic provider-tool log path. Legacy provider
events such as web search are adapted into the same log format.
Generated prompt files may store selected provider tools as
provider:<toolName> so they remain distinct from local tools with the same
name.
Common Use Cases
Database Query Tool
API Integration Tool
Tool Chaining
UsequeueTool to chain multiple tools:
Returning File Attachments
ThreadState Utilities
AgentBuilder provides utility functions for tools:queueTool
queueTool
Queue another tool to execute after the current one
injectMessage
injectMessage
Add a message to conversation without triggering execution
getMessages
getMessages
Retrieve message history
emitThreadEvent
emitThreadEvent
Send custom events to frontend
Best Practices
Write Clear Descriptions
Write Clear Descriptions
Tool descriptions help LLMs understand when to use each tool:Good:Avoid:
Describe All Parameters
Describe All Parameters
Use
.describe() on every parameter:Handle Errors Gracefully
Handle Errors Gracefully
Return errors as tool results, don’t throw:
Use snake_case Names
Use snake_case Names
File names should use snake_case:Good:
search_database.ts, create_ticket.tsAvoid: SearchDatabase.ts, createTicket.tsKeep Tools Focused
Keep Tools Focused
Each tool should do one thing well:Good:
lookup_customer.ts- Just lookupupdate_customer.ts- Just updatedelete_customer.ts- Just delete
customer_manager.ts- Does everything
Use rootState for Queueing
Use rootState for Queueing
When queueing tools from sub-prompts, use
state.rootState:Next Steps
API Reference
View complete tool API specification
ThreadState
Learn about execution context and utilities
Prompts
Configure prompts that use tools
Examples
Explore real-world tool patterns