Sprinter Platform

Tool System

Define tools, register them, gate by permissions, bridge to AI SDK, and execute with tracking.

Overview

Tools are functions that agents can call. The tool system provides:

  • Definition -- typed input schemas via Zod, execute functions, permission requirements
  • Registration -- centralized tool registry with lookup by slug
  • Permission gating -- tools filtered by caller's permissions before agents see them
  • AI bridge -- convert platform tools to AI SDK v6 tool format
  • Execution -- tracked execution with duration, errors, and output

Defining Tools

import { defineTool } from "@sprinterai/core";
import { z } from "zod";

const roiCalculator = defineTool({
  slug: "roi-calculator",
  name: "ROI Calculator",
  description: "Calculate return on investment for a deal",
  category: "finance",
  icon: "calculator",
  requiredPermission: "entities.team.read",
  inputSchema: z.object({
    investment: z.number().describe("Initial investment amount"),
    returns: z.number().describe("Total returns"),
    years: z.number().optional().describe("Investment period in years"),
  }),
  execute: async (input) => {
    const { investment, returns, years } = input as {
      investment: number;
      returns: number;
      years?: number;
    };
    const roi = ((returns - investment) / investment) * 100;
    const annualized = years ? (Math.pow(returns / investment, 1 / years) - 1) * 100 : null;
    return {
      roi: `${roi.toFixed(1)}%`,
      annualized: annualized ? `${annualized.toFixed(1)}%` : null,
    };
  },
});

Tool Registry

import { ToolRegistry } from "@sprinterai/runtime";

const registry = new ToolRegistry();
registry.register(roiCalculator);
registry.register(dealScorer);
registry.register(companyLookup);

// Lookup by slug
const tool = registry.get("roi-calculator");

// List all tools
const all = registry.list();

// Filter by category
const financeTools = registry.list().filter(t => t.category === "finance");

Built-in Entity Tools

The platform provides 8 entity tools out of the box:

import { createEntityTools } from "@sprinterai/runtime";

const entityTools = createEntityTools(stores.entity, userPermissions);
ToolRequired Permission
searchEntitiesentities.team.read
getEntityentities.team.read
createEntityentities.team.create
updateEntityentities.team.update
deleteEntityentities.team.delete
createRelationentities.team.update
listEntityTypesentities.team.read
getEntityStatsentities.team.read

Tool Groups

Tools are organized into groups for agent configuration:

GroupTools
entitysearchEntities, getEntity, createEntity, updateEntity, deleteEntity, createRelation, listEntityTypes, getEntityStats
responsesubmitResponse
webwebSearch
workflowgetWorkflowStatus, triggerWorkflow, retryNode
contextaddCorrection, addLesson, getUsageStats
admin14 admin tools (entity type CRUD, view management, agent config, etc.)

Permission Gating

Tools declare their required permissions. When resolving tools for an agent, the platform filters out tools the caller cannot use:

import { resolveAgentTools } from "@sprinterai/runtime";

// Only tools the user has permission for are included
const tools = await resolveAgentTools({
  agent: agentDefinition,
  stores,
  permissions: userPermissions,
  includeEntityTools: true,
});

The agent never sees tools it cannot use. This is enforced at resolution time, not at execution time.

AI Bridge

Convert platform tools to AI SDK v6 format:

import { toAITool, toAIToolSet } from "@sprinterai/runtime";

// Single tool -> AI SDK tool
const aiTool = toAITool(roiCalculator);

// Multiple tools -> AI SDK tool set (with permission filtering)
const toolSet = toAIToolSet(allTools, userPermissions);

// Use with AI SDK streamText
import { streamText } from "ai";
const result = await streamText({
  model,
  tools: toolSet,
  messages,
});

Tool Execution

import { executeTool } from "@sprinterai/runtime";

const result = await executeTool({
  tool: roiCalculator,
  input: { investment: 1000000, returns: 1500000, years: 3 },
  permissions: userPermissions,
});

// result.output   -- the tool's return value
// result.error    -- error message if failed
// result.duration -- execution time in ms

If the tool declares a requiredPermission and the caller lacks it, executeTool will reject the call.

Collaborative Tools

Tools can be marked as collaborative for multi-user sessions:

const whiteboard = defineTool({
  slug: "whiteboard",
  name: "Whiteboard",
  description: "Collaborative whiteboard",
  category: "collaboration",
  collaborative: true,  // enables tool sessions
  inputSchema: z.object({ /* ... */ }),
  execute: async (input) => { /* ... */ },
});

Collaborative tools support sessions (ToolSession) where multiple users interact with the tool's state over time.

Custom Tool UI

Tools can have custom input forms and output displays. Register UI components alongside the tool definition:

// features/custom/tools/roi-calculator/input-form.tsx
export function ROICalculatorInput({ onSubmit }) {
  // Custom form UI
}

// features/custom/tools/roi-calculator/output-display.tsx
export function ROICalculatorOutput({ data }) {
  // Custom output rendering
}

Tool Types

interface ToolDefinition {
  slug: string;
  name: string;
  description: string;
  category: string;
  icon?: string;
  inputSchema: z.ZodType;
  execute: (input: unknown) => Promise<unknown>;
  collaborative?: boolean;
  requiredPermission?: AppPermission;
}

interface ToolSession {
  id: string;
  tool_slug: string;
  status: ToolSessionStatus; // "active" | "completed" | "archived"
  created_by: string;
  participants: string[];
  metadata: Record<string, unknown>;
}

interface ToolRun {
  id: string;
  tool_slug: string;
  session_id: string | null;
  input: Record<string, unknown>;
  output: Record<string, unknown> | null;
  error: string | null;
  duration_ms: number;
  created_at: string;
}