agent-bridge / server /toolRegistry.ts
algorembrant's picture
Upload 18 files
b9a3ef2 verified
// ---------------------------------------------------------------------------
// Tool Registry -- MCP-like typed tool system
// ---------------------------------------------------------------------------
import fs from 'fs';
import path from 'path';
export interface ToolParams {
url?: string;
prompt?: string;
input?: string;
raw?: string;
captures?: string[];
[key: string]: unknown;
}
export interface ToolResult {
transcript?: string;
downloadUrl?: string;
filename?: string;
method?: string;
message?: string;
mock?: boolean;
error?: string;
[key: string]: unknown;
}
export type ProgressEmitter = (message: string) => void;
export interface ToolDefinition {
name: string;
description: string;
syntax: string;
pattern: RegExp;
mock: boolean;
execute: (params: ToolParams, emitProgress: ProgressEmitter) => Promise<ToolResult>;
}
export interface ToolSummary {
name: string;
description: string;
syntax: string;
mock: boolean;
}
export interface ToolMatch {
tool: ToolDefinition;
params: ToolParams;
}
export class ToolRegistry {
private tools = new Map<string, ToolDefinition>();
register(tool: ToolDefinition): void {
if (!tool.name || !tool.execute) {
throw new Error('Tool must have a name and execute function.');
}
this.tools.set(tool.name, tool);
console.log(` [ToolRegistry] Registered: ${tool.name}`);
}
listTools(): ToolSummary[] {
return Array.from(this.tools.values()).map((t) => ({
name: t.name,
description: t.description,
syntax: t.syntax,
mock: t.mock,
}));
}
getTool(name: string): ToolDefinition | null {
return this.tools.get(name) ?? null;
}
matchTool(message: string): ToolMatch | null {
for (const tool of this.tools.values()) {
if (!tool.pattern) continue;
const match = message.match(tool.pattern);
if (match) {
return {
tool,
params: { ...match.groups, raw: message, captures: match.slice(1) },
};
}
}
return null;
}
}
export function setupToolRegistry(): ToolRegistry {
const registry = new ToolRegistry();
const toolsDir = path.join(__dirname, 'tools');
if (fs.existsSync(toolsDir)) {
const files = fs.readdirSync(toolsDir).filter((f) => f.endsWith('.ts') || f.endsWith('.js'));
for (const file of files) {
try {
const mod = require(path.join(toolsDir, file));
if (typeof mod.register === 'function') {
mod.register(registry);
}
} catch (err: any) {
console.error(` [ToolRegistry] Failed to load ${file}: ${err.message}`);
}
}
}
return registry;
}