Tools
What is a Tool?
Section titled “What is a Tool?”A tool is a function that an agent can call. The LLM decides when to use it based on the tool’s name and description.
Defining a Tool
Section titled “Defining a Tool”import type { AgentTool } from "@schift-io/sdk";
const getWeather: AgentTool = { name: "get_weather", description: "Get current weather for a city", parameters: { type: "object", properties: { city: { type: "string", description: "City name" }, }, required: ["city"], }, handler: async (args) => { const city = String(args.city); const temp = await fetchWeatherAPI(city); return { success: true, data: { city, temperature: temp } }; },};Tool Name Rules
Section titled “Tool Name Rules”- Must match
/^[a-zA-Z_][a-zA-Z0-9_]*$/ - Use
snake_case(LLMs work best with this) - Must be unique within an agent
Parameters (JSON Schema)
Section titled “Parameters (JSON Schema)”Parameters use a JSON Schema subset. No zod dependency required.
parameters: { type: "object", properties: { query: { type: "string", description: "Search query" }, limit: { type: "number", description: "Max results" }, category: { type: "string", description: "Filter by category", enum: ["tech", "science", "business"], }, }, required: ["query"],}If your tool takes no parameters, omit the parameters field. The tool receives a single string input.
Handler Return Value
Section titled “Handler Return Value”Every handler must return a ToolResult:
interface ToolResult { success: boolean; data: unknown; // Any JSON-serializable value error?: string; // Error message if success is false}Built-in Tools
Section titled “Built-in Tools”RAG Search
Section titled “RAG Search”When you pass a RAG instance to an Agent, it auto-registers as a tool named rag_search.
const rag = new RAG({ bucket: "docs" }, schift.transport);const agent = new Agent({ rag, ... });// Agent now has "rag_search" tool automaticallyWeb Search
Section titled “Web Search”import { WebSearch } from "@schift-io/sdk";
const webSearch = new WebSearch({}, schift.transport);const agent = new Agent({ tools: [webSearch.asTool()], ...});// Agent now has "web_search" toolRegistering Multiple Tools
Section titled “Registering Multiple Tools”const agent = new Agent({ name: "Multi-tool Agent", instructions: "Use tools to answer questions.", rag, tools: [getWeather, searchDatabase, sendEmail], transport: schift.transport,});The LLM sees all tool descriptions and picks the right one for each question.
Rate Limiting Tools
Section titled “Rate Limiting Tools”Use maxCallsPerRun to prevent a tool from being called too many times in a single run. This is useful for preventing prompt injection abuse or controlling costs.
const searchTool: AgentTool = { name: "search_database", description: "Search the product database", maxCallsPerRun: 3, // max 3 calls per agent.run() parameters: { ... }, handler: async (args) => { ... },};If the limit is exceeded, the agent receives an error and must use a different approach.
Tool Registry
Section titled “Tool Registry”Under the hood, agents use a ToolRegistry to manage tools. You can use it directly for advanced use cases:
import { ToolRegistry } from "@schift-io/sdk";
const registry = new ToolRegistry();registry.register(getWeather);registry.register(searchDatabase);
// Check if a tool existsregistry.has("get_weather"); // true
// Generate OpenAI-compatible tool definitionsconst openaiTools = registry.toOpenAI();
// Generate Anthropic-compatible tool definitionsconst anthropicTools = registry.toAnthropic();
// Filter tools by allowed namesconst filtered = registry.filtered(new Set(["get_weather"]));
// Exclude specific toolsconst without = registry.without(new Set(["search_database"]));Error Handling in Tools
Section titled “Error Handling in Tools”If your handler throws, the error is caught and returned as a failed ToolResult. The agent sees the error and can retry or use a different approach.
handler: async (args) => { const resp = await fetch(`https://api.example.com/${args.id}`); if (!resp.ok) { return { success: false, data: null, error: `API returned ${resp.status}` }; } return { success: true, data: await resp.json() };}Tool execution is subject to a timeout (toolTimeoutMs, default 30s). If a tool takes longer, it times out and the agent receives an error.