Tools & Agents
Enable LLMs to call functions during generation. Define tools with Zod schemas.
import { defineTool, executeToolCall } from "@tryhamster/gerbil";Quick Start
Create a tool file in .gerbil/tools/:
01// .gerbil/tools/weather.tool.ts02export default {03 name: "get_weather",04 description: "Get current weather for a city",05 execute: async (params, ctx) => {06 const { city } = params;07 // Your implementation08 return `Weather in ${city}: 72°F, sunny`;09 },10};No imports needed! Tools are automatically discovered from .gerbil/tools/.
Built-in Tools
gerbil_docs
Search Gerbil documentation for any topic.
import { docsTool } from "@tryhamster/gerbil";
const result = await docsTool({ query: "streaming" });// Returns documentation about streaming responsesAvailable topics:
- quickstart, generate, stream, json, thinking, embed
- models, load, ai-sdk, next, express, react, hono
- langchain, mcp, skills, define-skill, cli, tools
run_skill
Execute any Gerbil skill.
import { skillsTool } from "@tryhamster/gerbil";
const result = await skillsTool({ skill: "summarize", input: "Long article text..." });Defining Custom Tools
Simple Format (Recommended)
Tools use a simple export format with no imports required:
01// .gerbil/tools/calculator.tool.ts02export default {03 name: "calculator",04 description: "Perform basic math calculations",05 execute: async (params, ctx) => {06 const { expression } = params;07 try {08 const result = eval(expression);09 return `${expression} = ${result}`;10 } catch {11 return `Error: Invalid expression`;12 }13 },14};Tool Context
Tools receive a context object with access to the LLM:
01// .gerbil/tools/generate_joke.tool.ts02export default {03 name: "generate_joke",04 description: "Generate a joke about a topic",05 execute: async (params, ctx) => {06 const { topic } = params;07 08 // Use ctx.generate() to call the LLM!09 if (ctx?.generate) {10 const joke = await ctx.generate(`Tell me a short joke about ${topic}`);11 return joke;12 }13 14 return "Could not generate joke";15 },16};Create Tool Wizard
The REPL includes a 4-step guided wizard to create tools:
- Name — Tool name (snake_case)
- Description — What the tool does
- Parameters — Inputs (optional, press Enter to skip)
- Logic — What to return
The wizard uses AI to generate the execute function body, then saves to .gerbil/tools/.
Tool Registry
Tools are automatically registered when defined:
01import { 02 defineTool, 03 getTool, 04 listTools, 05 getToolDefinitions 06} from "@tryhamster/gerbil";07
08// Define registers automatically09const myTool = defineTool({ ... });10
11// Get by name12const tool = getTool("my-tool");13
14// List all tools15console.log(listTools());16// ["gerbil_docs", "run_skill", "my-tool"]17
18// Get all definitions (for prompt injection)19const definitions = getToolDefinitions();Using Tools
REPL Tools View
Manage tools in the REPL (press 3 or navigate to Tools):
gerbil repl# Press 3 for Tools view- x — Execute tool directly
- c — Create a new tool (guided wizard)
- o — Open tool file in VS Code
- Enter — Expand tool details
Tools are shown with badges: [builtin], [project], or [error].
REPL Agent Mode
Use tools automatically in Chat with Agent mode:
gerbil repl# In Chat view: press ⌘A to toggle Agent mode# Or Tab to cycle modes → select "Agent"In Agent mode, the model can see available tools, call them by outputting JSON, and receive tool results to synthesize a response.
Programmatic Usage
01import { 02 formatToolsForPrompt, 03 parseToolCall, 04 executeToolCall,05 getToolDefinitions 06} from "@tryhamster/gerbil";07
08// Add tools to system prompt09const tools = getToolDefinitions();10const systemPrompt = `You are a helpful assistant.11
12${formatToolsForPrompt(tools)}`;13
14// Generate response15const response = await gerbil.generate(userQuery, { 16 system: systemPrompt 17});18
19// Check for tool calls20const toolCall = parseToolCall(response.text);21if (toolCall) {22 const result = await executeToolCall(toolCall.tool, toolCall.params);23 // Continue conversation with tool result24}Tool Call Format
Gerbil uses a simple JSON format for tool calls:
{ "tool": "tool_name", "params": { "param1": "value1", "param2": "value2" }}The model is prompted to output this format when it wants to use a tool.
Connecting Skills as Tools
Skills and tools share similar structures. Expose skills as tools:
01import { useSkill, defineTool } from "@tryhamster/gerbil";02import { z } from "zod";03
04// Get a skill05const summarizeSkill = useSkill("summarize");06
07// Wrap as tool08const summarizeTool = defineTool({09 name: "summarize",10 description: "Summarize text content",11 parameters: z.object({12 content: z.string(),13 length: z.enum(["short", "medium", "long"]).default("short"),14 }),15 execute: async ({ content, length }) => {16 const result = await summarizeSkill({ content, length });17 return result;18 },19});API Reference
ToolDefinition
interface ToolDefinition<TParams = unknown> { /** Tool name (function name) */ name: string; /** Description for the LLM */ description: string; /** Zod schema for parameters */ parameters?: z.ZodType<TParams>; /** The function to execute */ execute: (params: TParams) => Promise<string>;}Functions
// Define a tool (auto-registers)defineTool(definition: ToolDefinition): Tool
// Get tool by namegetTool(name: string): Tool | undefined
// List all tool nameslistTools(): string[]
// Get all definitions for prompt injectiongetToolDefinitions(): ToolDefinition[]
// Format tools for system promptformatToolsForPrompt(tools: ToolDefinition[]): string
// Parse tool call from LLM responseparseToolCall(response: string): { tool: string; params: any } | null
// Execute a tool callexecuteToolCall(name: string, params: any): Promise<string>Model Compatibility
Tool calling works best with:
- ✓Qwen3-0.6B — Excellent tool calling support
- ✓Qwen2.5 models — Good support
- ~Phi-3 — Moderate support
- ✗SmolLM2 — May struggle with consistent formatting
Best Practices
- 1.Clear descriptions — The model uses descriptions to decide when to call tools
- 2.Simple parameters — Use basic types when possible
- 3.Helpful errors — Return clear error messages
- 4.Validate inputs — Zod schemas validate before execution
- 5.Keep responses concise — Long tool outputs consume context