SPB Git

spb/khaelor Public

KHAELOR — a terminal-native autonomous engineering agent powered by Anthropic.

TypeScript 82.9% HTML 14.9% CSS 1.1% JavaScript 0.7%
2.6 KB · 76 lines typescript
Raw Blame History
1/**2 * KHAELOR3 * File: src/tools/registry.ts4 * Description: ToolDefinition interface and ToolRegistry — schema export for the Anthropic tools parameter.5 *6 * Author: Simon-Pierre Boucher7 * Contact: contact@spboucher.ai8 */910import { KhaelorError } from "../shared/index.js";11import type { ParsedInput, ToolJsonSchema } from "./schema.js";12import { validateToolInput } from "./schema.js";13import type { ToolCapabilityHint, ToolContext, ToolName, ToolResult } from "./types.js";1415/**16 * A tool the model can call (TOOL_PROTOCOL §1.2). The JSON schema is the17 * source of truth for the Anthropic `input_schema`; `capability` is the18 * coarse hint the executor's permission layer refines into capability19 * requests before `execute` runs. Tools never check permissions themselves.20 */21export interface ToolDefinition<P = unknown> {22  readonly name: ToolName;23  /** Model-facing description — the exact text sent in the tools array. */24  readonly description: string;25  /** Flat object schema, ≤5 properties (ADR-8). */26  readonly inputSchema: ToolJsonSchema;27  /** Coarse capability hint for the permission layer. */28  readonly capability: ToolCapabilityHint;29  /** Runs only after approval. Must respect ctx.signal. */30  execute(input: P, ctx: ToolContext): Promise<ToolResult>;31}3233/** One entry of the Anthropic request's `tools` array. */34export interface AnthropicToolParam {35  name: string;36  description: string;37  input_schema: ToolJsonSchema;38}3940/** Validate a raw tool_use input against a tool's schema (repair prose on failure). */41export function parseToolInput<P>(tool: ToolDefinition<P>, input: unknown): ParsedInput<P> {42  return validateToolInput<P>(tool.name, tool.inputSchema, input);43}4445/** Registry of the tools available to the model (TOOL_PROTOCOL §1.2). */46export class ToolRegistry {47  private readonly tools = new Map<ToolName, ToolDefinition>();4849  register(tool: ToolDefinition): void {50    if (this.tools.has(tool.name)) {51      throw new KhaelorError("internal", `Tool "${tool.name}" is already registered.`);52    }53    if (Object.keys(tool.inputSchema.properties).length > 5) {54      throw new KhaelorError("internal", `Tool "${tool.name}" exceeds the 5-parameter limit (ADR-8).`);55    }56    this.tools.set(tool.name, tool);57  }5859  list(): ToolDefinition[] {60    return [...this.tools.values()];61  }6263  get(name: string): ToolDefinition | undefined {64    return this.tools.get(name as ToolName);65  }6667  /** `[{name, description, input_schema}]` for the Anthropic request. */68  toAnthropicTools(): AnthropicToolParam[] {69    return this.list().map((tool) => ({70      name: tool.name,71      description: tool.description,72      input_schema: tool.inputSchema,73    }));74  }75}76