Skip to content

Tools

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.

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 } };
},
};
  • Must match /^[a-zA-Z_][a-zA-Z0-9_]*$/
  • Use snake_case (LLMs work best with this)
  • Must be unique within an agent

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.

Every handler must return a ToolResult:

interface ToolResult {
success: boolean;
data: unknown; // Any JSON-serializable value
error?: string; // Error message if success is false
}

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 automatically
import { WebSearch } from "@schift-io/sdk";
const webSearch = new WebSearch({}, schift.transport);
const agent = new Agent({
tools: [webSearch.asTool()],
...
});
// Agent now has "web_search" tool
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.

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() };
}