@riotprompt/riotprompt 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.kodrdriv-test-cache.json +6 -0
- package/README.md +2 -2
- package/dist/builder.js +3 -0
- package/dist/builder.js.map +1 -1
- package/dist/context-manager.d.ts +135 -0
- package/dist/context-manager.js +220 -0
- package/dist/context-manager.js.map +1 -0
- package/dist/conversation-logger.d.ts +283 -0
- package/dist/conversation-logger.js +454 -0
- package/dist/conversation-logger.js.map +1 -0
- package/dist/conversation.d.ts +271 -0
- package/dist/conversation.js +622 -0
- package/dist/conversation.js.map +1 -0
- package/dist/formatter.js.map +1 -1
- package/dist/iteration-strategy.d.ts +231 -0
- package/dist/iteration-strategy.js +486 -0
- package/dist/iteration-strategy.js.map +1 -0
- package/dist/loader.js +3 -0
- package/dist/loader.js.map +1 -1
- package/dist/message-builder.d.ts +156 -0
- package/dist/message-builder.js +254 -0
- package/dist/message-builder.js.map +1 -0
- package/dist/override.js +3 -0
- package/dist/override.js.map +1 -1
- package/dist/recipes.d.ts +42 -0
- package/dist/recipes.js +189 -4
- package/dist/recipes.js.map +1 -1
- package/dist/reflection.d.ts +250 -0
- package/dist/reflection.js +416 -0
- package/dist/reflection.js.map +1 -0
- package/dist/riotprompt.cjs +3549 -218
- package/dist/riotprompt.cjs.map +1 -1
- package/dist/riotprompt.d.ts +18 -2
- package/dist/riotprompt.js +9 -1
- package/dist/riotprompt.js.map +1 -1
- package/dist/token-budget.d.ts +177 -0
- package/dist/token-budget.js +404 -0
- package/dist/token-budget.js.map +1 -0
- package/dist/tools.d.ts +239 -0
- package/dist/tools.js +324 -0
- package/dist/tools.js.map +1 -0
- package/package.json +23 -20
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-budget.js","sources":["../src/token-budget.ts"],"sourcesContent":["import { encoding_for_model, Tiktoken, TiktokenModel } from 'tiktoken';\nimport type { ConversationMessage } from './conversation';\nimport { Model } from './chat';\nimport { DEFAULT_LOGGER, wrapLogger } from './logger';\n\n// ===== TYPE DEFINITIONS =====\n\n/**\n * Token usage information\n */\nexport interface TokenUsage {\n used: number;\n max: number;\n remaining: number;\n percentage: number;\n}\n\n/**\n * Compression statistics\n */\nexport interface CompressionStats {\n messagesBefore: number;\n messagesAfter: number;\n tokensBefore: number;\n tokensAfter: number;\n tokensSaved: number;\n strategy: CompressionStrategy;\n}\n\n/**\n * Compression strategy\n */\nexport type CompressionStrategy = 'priority-based' | 'fifo' | 'summarize' | 'adaptive';\n\n/**\n * Token budget configuration\n */\nexport interface TokenBudgetConfig {\n // Hard limits\n max: number;\n reserveForResponse: number;\n warningThreshold?: number; // Default: 0.8 (80%)\n\n // Compression strategy\n strategy: CompressionStrategy;\n\n // Behavior when budget exceeded\n onBudgetExceeded: 'compress' | 'error' | 'warn' | 'truncate';\n\n // What to preserve\n preserveRecent?: number;\n preserveSystem?: boolean; // Default: true\n preserveHighPriority?: boolean; // Default: true\n\n // Monitoring\n onWarning?: (usage: TokenUsage) => void;\n onCompression?: (stats: CompressionStats) => void;\n}\n\n// ===== TOKEN COUNTER =====\n\n/**\n * TokenCounter counts tokens using tiktoken for accurate model-specific counting.\n *\n * Features:\n * - Model-specific token counting\n * - Message overhead calculation\n * - Tool call token estimation\n * - Response token estimation\n *\n * @example\n * ```typescript\n * const counter = new TokenCounter('gpt-4o');\n *\n * const tokens = counter.count('Hello, world!');\n * console.log(`Text uses ${tokens} tokens`);\n *\n * const messageTokens = counter.countMessage({\n * role: 'user',\n * content: 'What is the weather?'\n * });\n * ```\n */\nexport class TokenCounter {\n private encoder: Tiktoken;\n private model: Model;\n private logger: any;\n\n constructor(model: Model, logger?: any) {\n this.model = model;\n this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'TokenCounter');\n\n // Map RiotPrompt models to Tiktoken models\n const tiktokenModel = this.mapToTiktokenModel(model);\n this.encoder = encoding_for_model(tiktokenModel);\n\n this.logger.debug('Created TokenCounter', { model });\n }\n\n /**\n * Count tokens in text\n */\n count(text: string): number {\n if (!text) return 0;\n return this.encoder.encode(text).length;\n }\n\n /**\n * Count tokens in a single message\n */\n countMessage(message: ConversationMessage): number {\n let tokens = 4; // Base overhead per message\n\n // Content tokens\n if (message.content) {\n tokens += this.count(message.content);\n }\n\n // Role tokens\n tokens += 1;\n\n // Tool call tokens\n if (message.tool_calls) {\n for (const toolCall of message.tool_calls) {\n tokens += this.count(JSON.stringify(toolCall));\n tokens += 3; // Tool call overhead\n }\n }\n\n // Tool result tokens\n if (message.tool_call_id) {\n tokens += this.count(message.tool_call_id);\n tokens += 2; // Tool result overhead\n }\n\n return tokens;\n }\n\n /**\n * Count tokens in entire conversation\n */\n countConversation(messages: ConversationMessage[]): number {\n let total = 3; // Conversation start overhead\n\n for (const message of messages) {\n total += this.countMessage(message);\n }\n\n return total;\n }\n\n /**\n * Count with additional overhead estimation\n */\n countWithOverhead(\n messages: ConversationMessage[],\n includeToolOverhead: boolean = false\n ): number {\n let total = this.countConversation(messages);\n\n // Add tool definition overhead if tools are present\n if (includeToolOverhead) {\n const hasTools = messages.some(m => m.tool_calls && m.tool_calls.length > 0);\n if (hasTools) {\n total += 100; // Estimated tool definition overhead\n }\n }\n\n return total;\n }\n\n /**\n * Estimate tokens needed for response\n */\n estimateResponseTokens(messages: ConversationMessage[]): number {\n // Heuristic: average response is about 20% of input\n const inputTokens = this.countConversation(messages);\n return Math.max(500, Math.floor(inputTokens * 0.2));\n }\n\n /**\n * Map RiotPrompt model to Tiktoken model\n */\n private mapToTiktokenModel(model: Model): TiktokenModel {\n switch (model) {\n case 'gpt-4o':\n case 'gpt-4o-mini':\n return 'gpt-4o';\n case 'o1-preview':\n case 'o1-mini':\n case 'o1':\n case 'o3-mini':\n case 'o1-pro':\n // O1 models use gpt-4o tokenization\n return 'gpt-4o';\n default:\n return 'gpt-4o';\n }\n }\n\n /**\n * Free encoder resources\n */\n dispose(): void {\n this.encoder.free();\n }\n}\n\n// ===== TOKEN BUDGET MANAGER =====\n\n/**\n * TokenBudgetManager manages token budgets and compression strategies.\n *\n * Features:\n * - Monitor token usage\n * - Automatic compression when budget exceeded\n * - Multiple compression strategies\n * - Priority-based message retention\n * - Usage statistics and callbacks\n *\n * @example\n * ```typescript\n * const manager = new TokenBudgetManager({\n * max: 8000,\n * reserveForResponse: 1000,\n * strategy: 'priority-based',\n * onBudgetExceeded: 'compress'\n * }, 'gpt-4o');\n *\n * // Check if message can be added\n * if (manager.canAddMessage(message)) {\n * messages.push(message);\n * } else {\n * // Compress conversation\n * messages = manager.compress(messages);\n * messages.push(message);\n * }\n * ```\n */\nexport class TokenBudgetManager {\n private config: Required<TokenBudgetConfig>;\n private counter: TokenCounter;\n private logger: any;\n\n constructor(config: TokenBudgetConfig, model: Model, logger?: any) {\n this.config = {\n warningThreshold: 0.8,\n preserveRecent: 3,\n preserveSystem: true,\n preserveHighPriority: true,\n onWarning: () => {},\n onCompression: () => {},\n ...config,\n } as Required<TokenBudgetConfig>;\n\n this.counter = new TokenCounter(model, logger);\n this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'TokenBudgetManager');\n\n this.logger.debug('Created TokenBudgetManager', {\n max: this.config.max,\n strategy: this.config.strategy\n });\n }\n\n /**\n * Get current token usage\n */\n getCurrentUsage(messages: ConversationMessage[]): TokenUsage {\n const used = this.counter.countConversation(messages);\n const max = this.config.max;\n const remaining = Math.max(0, max - used - this.config.reserveForResponse);\n const percentage = (used / max) * 100;\n\n return { used, max, remaining, percentage };\n }\n\n /**\n * Get remaining tokens available\n */\n getRemainingTokens(messages: ConversationMessage[]): number {\n return this.getCurrentUsage(messages).remaining;\n }\n\n /**\n * Check if near token limit\n */\n isNearLimit(messages: ConversationMessage[], threshold?: number): boolean {\n const usage = this.getCurrentUsage(messages);\n const checkThreshold = threshold ?? this.config.warningThreshold;\n\n const isNear = usage.percentage >= (checkThreshold * 100);\n\n if (isNear) {\n this.config.onWarning?.(usage);\n }\n\n return isNear;\n }\n\n /**\n * Check if a message can be added without exceeding budget\n */\n canAddMessage(message: ConversationMessage, currentMessages: ConversationMessage[]): boolean {\n const currentTokens = this.counter.countConversation(currentMessages);\n const messageTokens = this.counter.countMessage(message);\n const total = currentTokens + messageTokens + this.config.reserveForResponse;\n\n return total <= this.config.max;\n }\n\n /**\n * Compress messages according to strategy\n */\n compress(messages: ConversationMessage[]): ConversationMessage[] {\n const before = messages.length;\n const tokensBefore = this.counter.countConversation(messages);\n const targetTokens = this.config.max - this.config.reserveForResponse;\n\n this.logger.debug('Compressing messages', {\n before,\n tokensBefore,\n targetTokens,\n strategy: this.config.strategy\n });\n\n // No compression needed\n if (tokensBefore <= targetTokens) {\n return messages;\n }\n\n let compressed: ConversationMessage[];\n\n switch (this.config.strategy) {\n case 'priority-based':\n compressed = this.compressByPriority(messages, targetTokens);\n break;\n case 'fifo':\n compressed = this.compressFIFO(messages, targetTokens);\n break;\n case 'adaptive':\n compressed = this.compressAdaptive(messages, targetTokens);\n break;\n case 'summarize':\n // For now, fall back to FIFO (summarization would require LLM call)\n compressed = this.compressFIFO(messages, targetTokens);\n break;\n default:\n compressed = this.compressFIFO(messages, targetTokens);\n }\n\n const tokensAfter = this.counter.countConversation(compressed);\n\n const stats: CompressionStats = {\n messagesBefore: before,\n messagesAfter: compressed.length,\n tokensBefore,\n tokensAfter,\n tokensSaved: tokensBefore - tokensAfter,\n strategy: this.config.strategy,\n };\n\n this.config.onCompression?.(stats);\n\n this.logger.info('Compressed conversation', stats);\n\n return compressed;\n }\n\n /**\n * Compress by priority (keep high-priority messages)\n */\n private compressByPriority(\n messages: ConversationMessage[],\n targetTokens: number\n ): ConversationMessage[] {\n // Calculate priority for each message\n const withPriority = messages.map((msg, idx) => ({\n message: msg,\n priority: this.calculatePriority(msg, idx, messages.length),\n tokens: this.counter.countMessage(msg),\n index: idx,\n }));\n\n // Sort by priority (descending)\n withPriority.sort((a, b) => b.priority - a.priority);\n\n // Keep highest priority messages that fit in budget\n const kept: typeof withPriority = [];\n let totalTokens = 0;\n\n for (const item of withPriority) {\n if (totalTokens + item.tokens <= targetTokens) {\n kept.push(item);\n totalTokens += item.tokens;\n }\n }\n\n // Sort back to original order\n kept.sort((a, b) => a.index - b.index);\n\n return kept.map(item => item.message);\n }\n\n /**\n * Compress using FIFO (remove oldest first)\n */\n private compressFIFO(\n messages: ConversationMessage[],\n targetTokens: number\n ): ConversationMessage[] {\n const preserved: ConversationMessage[] = [];\n let totalTokens = 0;\n\n // Always preserve system messages if configured\n const systemMessages = messages.filter(m => m.role === 'system');\n if (this.config.preserveSystem) {\n for (const msg of systemMessages) {\n preserved.push(msg);\n totalTokens += this.counter.countMessage(msg);\n }\n }\n\n // Preserve recent messages\n const recentCount = this.config.preserveRecent ?? 3;\n const recentMessages = messages.slice(-recentCount).filter(m => m.role !== 'system');\n for (const msg of recentMessages) {\n if (!preserved.includes(msg)) {\n const tokens = this.counter.countMessage(msg);\n if (totalTokens + tokens <= targetTokens) {\n preserved.push(msg);\n totalTokens += tokens;\n }\n }\n }\n\n // Add older messages if space available\n const otherMessages = messages.filter(\n m => !preserved.includes(m) && m.role !== 'system'\n );\n\n for (let i = otherMessages.length - 1; i >= 0; i--) {\n const msg = otherMessages[i];\n const tokens = this.counter.countMessage(msg);\n\n if (totalTokens + tokens <= targetTokens) {\n preserved.unshift(msg);\n totalTokens += tokens;\n } else {\n break;\n }\n }\n\n // Sort to maintain conversation order\n return messages.filter(m => preserved.includes(m));\n }\n\n /**\n * Adaptive compression based on conversation phase\n */\n private compressAdaptive(\n messages: ConversationMessage[],\n targetTokens: number\n ): ConversationMessage[] {\n const messageCount = messages.length;\n\n // Early phase: minimal compression (keep most messages)\n if (messageCount <= 5) {\n return this.compressFIFO(messages, targetTokens);\n }\n\n // Mid phase: moderate compression\n if (messageCount <= 15) {\n // Use FIFO but preserve more recent messages\n const modifiedConfig = { ...this.config, preserveRecent: 5 };\n const tempManager = new TokenBudgetManager(\n modifiedConfig,\n 'gpt-4o', // Model doesn't matter here\n this.logger\n );\n return tempManager.compressFIFO(messages, targetTokens);\n }\n\n // Late phase: aggressive compression (priority-based)\n return this.compressByPriority(messages, targetTokens);\n }\n\n /**\n * Calculate message priority for compression\n */\n private calculatePriority(\n message: ConversationMessage,\n index: number,\n total: number\n ): number {\n let priority = 1.0;\n\n // System messages: highest priority\n if (message.role === 'system') {\n priority = 10.0;\n }\n\n // Recent messages: higher priority\n const recencyBonus = index / total;\n priority += recencyBonus * 2;\n\n // Tool results: moderate priority\n if (message.role === 'tool') {\n priority += 0.5;\n }\n\n // Messages with tool calls: keep for context\n if (message.tool_calls && message.tool_calls.length > 0) {\n priority += 0.8;\n }\n\n return priority;\n }\n\n /**\n * Truncate to exact number of messages\n */\n truncate(messages: ConversationMessage[], maxMessages: number): ConversationMessage[] {\n if (messages.length <= maxMessages) {\n return messages;\n }\n\n // Keep system messages + recent messages\n const systemMessages = messages.filter(m => m.role === 'system');\n const otherMessages = messages.filter(m => m.role !== 'system');\n\n const recentOther = otherMessages.slice(-(maxMessages - systemMessages.length));\n\n return [...systemMessages, ...recentOther];\n }\n\n /**\n * Dispose resources\n */\n dispose(): void {\n this.counter.dispose();\n }\n}\n\nexport default TokenBudgetManager;\n\n"],"names":["TokenCounter","count","text","encoder","encode","length","countMessage","message","tokens","content","tool_calls","toolCall","JSON","stringify","tool_call_id","countConversation","messages","total","countWithOverhead","includeToolOverhead","hasTools","some","m","estimateResponseTokens","inputTokens","Math","max","floor","mapToTiktokenModel","model","dispose","free","logger","wrapLogger","DEFAULT_LOGGER","tiktokenModel","encoding_for_model","debug","TokenBudgetManager","getCurrentUsage","used","counter","config","remaining","reserveForResponse","percentage","getRemainingTokens","isNearLimit","threshold","usage","checkThreshold","warningThreshold","isNear","onWarning","canAddMessage","currentMessages","currentTokens","messageTokens","compress","before","tokensBefore","targetTokens","strategy","compressed","compressByPriority","compressFIFO","compressAdaptive","tokensAfter","stats","messagesBefore","messagesAfter","tokensSaved","onCompression","info","withPriority","map","msg","idx","priority","calculatePriority","index","sort","a","b","kept","totalTokens","item","push","preserved","systemMessages","filter","role","preserveSystem","recentCount","preserveRecent","recentMessages","slice","includes","otherMessages","i","unshift","messageCount","modifiedConfig","tempManager","recencyBonus","truncate","maxMessages","recentOther","preserveHighPriority"],"mappings":"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"}
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parameter definition for a tool
|
|
3
|
+
*/
|
|
4
|
+
export interface ToolParameter {
|
|
5
|
+
type: 'string' | 'number' | 'boolean' | 'array' | 'object';
|
|
6
|
+
description: string;
|
|
7
|
+
items?: ToolParameter;
|
|
8
|
+
properties?: Record<string, ToolParameter>;
|
|
9
|
+
required?: string[];
|
|
10
|
+
enum?: string[];
|
|
11
|
+
default?: any;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Context provided to tool execution
|
|
15
|
+
*/
|
|
16
|
+
export interface ToolContext {
|
|
17
|
+
workingDirectory?: string;
|
|
18
|
+
storage?: any;
|
|
19
|
+
logger?: any;
|
|
20
|
+
conversationState?: any;
|
|
21
|
+
[key: string]: any;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Example usage of a tool
|
|
25
|
+
*/
|
|
26
|
+
export interface ToolExample {
|
|
27
|
+
scenario: string;
|
|
28
|
+
params: any;
|
|
29
|
+
expectedResult: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Cost hint for tool execution
|
|
33
|
+
*/
|
|
34
|
+
export type ToolCost = 'cheap' | 'moderate' | 'expensive';
|
|
35
|
+
/**
|
|
36
|
+
* Tool definition
|
|
37
|
+
*/
|
|
38
|
+
export interface Tool {
|
|
39
|
+
name: string;
|
|
40
|
+
description: string;
|
|
41
|
+
parameters: {
|
|
42
|
+
type: 'object';
|
|
43
|
+
properties: Record<string, ToolParameter>;
|
|
44
|
+
required?: string[];
|
|
45
|
+
};
|
|
46
|
+
execute: (params: any, context?: ToolContext) => Promise<any>;
|
|
47
|
+
category?: string;
|
|
48
|
+
cost?: ToolCost;
|
|
49
|
+
examples?: ToolExample[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* OpenAI-compatible tool format
|
|
53
|
+
*/
|
|
54
|
+
export interface OpenAITool {
|
|
55
|
+
type: 'function';
|
|
56
|
+
function: {
|
|
57
|
+
name: string;
|
|
58
|
+
description: string;
|
|
59
|
+
parameters: {
|
|
60
|
+
type: 'object';
|
|
61
|
+
properties: Record<string, any>;
|
|
62
|
+
required?: string[];
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Anthropic-compatible tool format
|
|
68
|
+
*/
|
|
69
|
+
export interface AnthropicTool {
|
|
70
|
+
name: string;
|
|
71
|
+
description: string;
|
|
72
|
+
input_schema: {
|
|
73
|
+
type: 'object';
|
|
74
|
+
properties: Record<string, any>;
|
|
75
|
+
required?: string[];
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Tool execution result
|
|
80
|
+
*/
|
|
81
|
+
export interface ToolExecutionResult {
|
|
82
|
+
success: boolean;
|
|
83
|
+
result?: any;
|
|
84
|
+
error?: string;
|
|
85
|
+
duration?: number;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Usage statistics for a tool
|
|
89
|
+
*/
|
|
90
|
+
export interface ToolUsageStats {
|
|
91
|
+
calls: number;
|
|
92
|
+
failures: number;
|
|
93
|
+
successRate: number;
|
|
94
|
+
averageDuration?: number;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Tool definition for export
|
|
98
|
+
*/
|
|
99
|
+
export interface ToolDefinition {
|
|
100
|
+
name: string;
|
|
101
|
+
description: string;
|
|
102
|
+
parameters: Tool['parameters'];
|
|
103
|
+
category?: string;
|
|
104
|
+
cost?: ToolCost;
|
|
105
|
+
examples?: ToolExample[];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* ToolRegistry manages tool definitions and execution.
|
|
109
|
+
*
|
|
110
|
+
* Features:
|
|
111
|
+
* - Register and manage tools
|
|
112
|
+
* - Execute tools with context
|
|
113
|
+
* - Track usage statistics
|
|
114
|
+
* - Export to different formats (OpenAI, Anthropic)
|
|
115
|
+
* - Filter by category
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const registry = ToolRegistry.create({
|
|
120
|
+
* workingDirectory: process.cwd(),
|
|
121
|
+
* logger: myLogger
|
|
122
|
+
* });
|
|
123
|
+
*
|
|
124
|
+
* registry.register({
|
|
125
|
+
* name: 'read_file',
|
|
126
|
+
* description: 'Read a file',
|
|
127
|
+
* parameters: {
|
|
128
|
+
* type: 'object',
|
|
129
|
+
* properties: {
|
|
130
|
+
* path: { type: 'string', description: 'File path' }
|
|
131
|
+
* },
|
|
132
|
+
* required: ['path']
|
|
133
|
+
* },
|
|
134
|
+
* execute: async ({ path }) => {
|
|
135
|
+
* return await fs.readFile(path, 'utf-8');
|
|
136
|
+
* }
|
|
137
|
+
* });
|
|
138
|
+
*
|
|
139
|
+
* const result = await registry.execute('read_file', { path: 'test.txt' });
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
export declare class ToolRegistry {
|
|
143
|
+
private tools;
|
|
144
|
+
private context;
|
|
145
|
+
private logger;
|
|
146
|
+
private usageStats;
|
|
147
|
+
private constructor();
|
|
148
|
+
/**
|
|
149
|
+
* Create a new ToolRegistry instance
|
|
150
|
+
*/
|
|
151
|
+
static create(context?: ToolContext, logger?: any): ToolRegistry;
|
|
152
|
+
/**
|
|
153
|
+
* Register a single tool
|
|
154
|
+
*/
|
|
155
|
+
register(tool: Tool): void;
|
|
156
|
+
/**
|
|
157
|
+
* Register multiple tools at once
|
|
158
|
+
*/
|
|
159
|
+
registerAll(tools: Tool[]): void;
|
|
160
|
+
/**
|
|
161
|
+
* Get a tool by name
|
|
162
|
+
*/
|
|
163
|
+
get(name: string): Tool | undefined;
|
|
164
|
+
/**
|
|
165
|
+
* Get all registered tools
|
|
166
|
+
*/
|
|
167
|
+
getAll(): Tool[];
|
|
168
|
+
/**
|
|
169
|
+
* Get tools by category
|
|
170
|
+
*/
|
|
171
|
+
getByCategory(category: string): Tool[];
|
|
172
|
+
/**
|
|
173
|
+
* Check if a tool is registered
|
|
174
|
+
*/
|
|
175
|
+
has(name: string): boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Get number of registered tools
|
|
178
|
+
*/
|
|
179
|
+
count(): number;
|
|
180
|
+
/**
|
|
181
|
+
* Execute a tool by name
|
|
182
|
+
*/
|
|
183
|
+
execute(name: string, params: any): Promise<any>;
|
|
184
|
+
/**
|
|
185
|
+
* Execute multiple tools in sequence
|
|
186
|
+
*/
|
|
187
|
+
executeBatch(calls: Array<{
|
|
188
|
+
name: string;
|
|
189
|
+
params: any;
|
|
190
|
+
}>): Promise<any[]>;
|
|
191
|
+
/**
|
|
192
|
+
* Export tools in OpenAI format
|
|
193
|
+
*/
|
|
194
|
+
toOpenAIFormat(): OpenAITool[];
|
|
195
|
+
/**
|
|
196
|
+
* Export tools in Anthropic format
|
|
197
|
+
*/
|
|
198
|
+
toAnthropicFormat(): AnthropicTool[];
|
|
199
|
+
/**
|
|
200
|
+
* Get tool definitions (without execute function)
|
|
201
|
+
*/
|
|
202
|
+
getDefinitions(): ToolDefinition[];
|
|
203
|
+
/**
|
|
204
|
+
* Get usage statistics for all tools
|
|
205
|
+
*/
|
|
206
|
+
getUsageStats(): Map<string, ToolUsageStats>;
|
|
207
|
+
/**
|
|
208
|
+
* Get most frequently used tools
|
|
209
|
+
*/
|
|
210
|
+
getMostUsed(limit?: number): Tool[];
|
|
211
|
+
/**
|
|
212
|
+
* Get list of all categories
|
|
213
|
+
*/
|
|
214
|
+
getCategories(): string[];
|
|
215
|
+
/**
|
|
216
|
+
* Update execution context
|
|
217
|
+
*/
|
|
218
|
+
updateContext(context: Partial<ToolContext>): void;
|
|
219
|
+
/**
|
|
220
|
+
* Get current context
|
|
221
|
+
*/
|
|
222
|
+
getContext(): ToolContext;
|
|
223
|
+
/**
|
|
224
|
+
* Clear all tools
|
|
225
|
+
*/
|
|
226
|
+
clear(): void;
|
|
227
|
+
/**
|
|
228
|
+
* Unregister a specific tool
|
|
229
|
+
*/
|
|
230
|
+
unregister(name: string): boolean;
|
|
231
|
+
/**
|
|
232
|
+
* Reset usage statistics
|
|
233
|
+
*/
|
|
234
|
+
resetStats(): void;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Export the registry for use in other modules
|
|
238
|
+
*/
|
|
239
|
+
export default ToolRegistry;
|
package/dist/tools.js
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { wrapLogger, DEFAULT_LOGGER } from './logger.js';
|
|
3
|
+
|
|
4
|
+
function _define_property(obj, key, value) {
|
|
5
|
+
if (key in obj) {
|
|
6
|
+
Object.defineProperty(obj, key, {
|
|
7
|
+
value: value,
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
writable: true
|
|
11
|
+
});
|
|
12
|
+
} else {
|
|
13
|
+
obj[key] = value;
|
|
14
|
+
}
|
|
15
|
+
return obj;
|
|
16
|
+
}
|
|
17
|
+
// ===== VALIDATION SCHEMAS =====
|
|
18
|
+
// Simplified parameter schema - just validate structure, not deep nesting
|
|
19
|
+
const ToolSchema = z.object({
|
|
20
|
+
name: z.string().min(1),
|
|
21
|
+
description: z.string().min(1),
|
|
22
|
+
parameters: z.object({
|
|
23
|
+
type: z.literal('object'),
|
|
24
|
+
properties: z.record(z.string(), z.any()).default({}),
|
|
25
|
+
required: z.array(z.string()).optional()
|
|
26
|
+
}).passthrough(),
|
|
27
|
+
execute: z.custom((val)=>typeof val === 'function', {
|
|
28
|
+
message: 'execute must be a function'
|
|
29
|
+
}),
|
|
30
|
+
category: z.string().optional(),
|
|
31
|
+
cost: z.enum([
|
|
32
|
+
'cheap',
|
|
33
|
+
'moderate',
|
|
34
|
+
'expensive'
|
|
35
|
+
]).optional(),
|
|
36
|
+
examples: z.array(z.object({
|
|
37
|
+
scenario: z.string(),
|
|
38
|
+
params: z.any(),
|
|
39
|
+
expectedResult: z.string()
|
|
40
|
+
})).optional()
|
|
41
|
+
}).passthrough(); // Allow additional fields at tool level too
|
|
42
|
+
// ===== TOOL REGISTRY =====
|
|
43
|
+
/**
|
|
44
|
+
* ToolRegistry manages tool definitions and execution.
|
|
45
|
+
*
|
|
46
|
+
* Features:
|
|
47
|
+
* - Register and manage tools
|
|
48
|
+
* - Execute tools with context
|
|
49
|
+
* - Track usage statistics
|
|
50
|
+
* - Export to different formats (OpenAI, Anthropic)
|
|
51
|
+
* - Filter by category
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* const registry = ToolRegistry.create({
|
|
56
|
+
* workingDirectory: process.cwd(),
|
|
57
|
+
* logger: myLogger
|
|
58
|
+
* });
|
|
59
|
+
*
|
|
60
|
+
* registry.register({
|
|
61
|
+
* name: 'read_file',
|
|
62
|
+
* description: 'Read a file',
|
|
63
|
+
* parameters: {
|
|
64
|
+
* type: 'object',
|
|
65
|
+
* properties: {
|
|
66
|
+
* path: { type: 'string', description: 'File path' }
|
|
67
|
+
* },
|
|
68
|
+
* required: ['path']
|
|
69
|
+
* },
|
|
70
|
+
* execute: async ({ path }) => {
|
|
71
|
+
* return await fs.readFile(path, 'utf-8');
|
|
72
|
+
* }
|
|
73
|
+
* });
|
|
74
|
+
*
|
|
75
|
+
* const result = await registry.execute('read_file', { path: 'test.txt' });
|
|
76
|
+
* ```
|
|
77
|
+
*/ class ToolRegistry {
|
|
78
|
+
/**
|
|
79
|
+
* Create a new ToolRegistry instance
|
|
80
|
+
*/ static create(context, logger) {
|
|
81
|
+
return new ToolRegistry(context, logger);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Register a single tool
|
|
85
|
+
*/ register(tool) {
|
|
86
|
+
// Validate tool
|
|
87
|
+
try {
|
|
88
|
+
ToolSchema.parse(tool);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
throw new Error(`Invalid tool definition for "${tool.name}": ${error}`);
|
|
91
|
+
}
|
|
92
|
+
if (this.tools.has(tool.name)) {
|
|
93
|
+
this.logger.warn(`Tool "${tool.name}" already registered, overwriting`);
|
|
94
|
+
}
|
|
95
|
+
this.tools.set(tool.name, tool);
|
|
96
|
+
this.usageStats.set(tool.name, {
|
|
97
|
+
calls: 0,
|
|
98
|
+
failures: 0,
|
|
99
|
+
totalDuration: 0
|
|
100
|
+
});
|
|
101
|
+
this.logger.debug('Registered tool', {
|
|
102
|
+
name: tool.name,
|
|
103
|
+
category: tool.category
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Register multiple tools at once
|
|
108
|
+
*/ registerAll(tools) {
|
|
109
|
+
this.logger.debug('Registering multiple tools', {
|
|
110
|
+
count: tools.length
|
|
111
|
+
});
|
|
112
|
+
tools.forEach((tool)=>this.register(tool));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get a tool by name
|
|
116
|
+
*/ get(name) {
|
|
117
|
+
return this.tools.get(name);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get all registered tools
|
|
121
|
+
*/ getAll() {
|
|
122
|
+
return Array.from(this.tools.values());
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get tools by category
|
|
126
|
+
*/ getByCategory(category) {
|
|
127
|
+
return this.getAll().filter((tool)=>tool.category === category);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Check if a tool is registered
|
|
131
|
+
*/ has(name) {
|
|
132
|
+
return this.tools.has(name);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get number of registered tools
|
|
136
|
+
*/ count() {
|
|
137
|
+
return this.tools.size;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Execute a tool by name
|
|
141
|
+
*/ async execute(name, params) {
|
|
142
|
+
const tool = this.tools.get(name);
|
|
143
|
+
if (!tool) {
|
|
144
|
+
throw new Error(`Tool "${name}" not found`);
|
|
145
|
+
}
|
|
146
|
+
this.logger.debug('Executing tool', {
|
|
147
|
+
name,
|
|
148
|
+
params
|
|
149
|
+
});
|
|
150
|
+
const startTime = Date.now();
|
|
151
|
+
const stats = this.usageStats.get(name);
|
|
152
|
+
stats.calls++;
|
|
153
|
+
try {
|
|
154
|
+
const result = await tool.execute(params, this.context);
|
|
155
|
+
const duration = Date.now() - startTime;
|
|
156
|
+
stats.totalDuration += duration;
|
|
157
|
+
this.logger.debug('Tool execution succeeded', {
|
|
158
|
+
name,
|
|
159
|
+
duration
|
|
160
|
+
});
|
|
161
|
+
return result;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
stats.failures++;
|
|
164
|
+
this.logger.error('Tool execution failed', {
|
|
165
|
+
name,
|
|
166
|
+
error
|
|
167
|
+
});
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Execute multiple tools in sequence
|
|
173
|
+
*/ async executeBatch(calls) {
|
|
174
|
+
this.logger.debug('Executing batch', {
|
|
175
|
+
count: calls.length
|
|
176
|
+
});
|
|
177
|
+
const results = [];
|
|
178
|
+
for (const call of calls){
|
|
179
|
+
try {
|
|
180
|
+
const result = await this.execute(call.name, call.params);
|
|
181
|
+
results.push(result);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
results.push({
|
|
184
|
+
error: String(error)
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return results;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Export tools in OpenAI format
|
|
192
|
+
*/ toOpenAIFormat() {
|
|
193
|
+
return this.getAll().map((tool)=>({
|
|
194
|
+
type: 'function',
|
|
195
|
+
function: {
|
|
196
|
+
name: tool.name,
|
|
197
|
+
description: tool.description,
|
|
198
|
+
parameters: {
|
|
199
|
+
type: 'object',
|
|
200
|
+
properties: tool.parameters.properties,
|
|
201
|
+
required: tool.parameters.required
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}));
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Export tools in Anthropic format
|
|
208
|
+
*/ toAnthropicFormat() {
|
|
209
|
+
return this.getAll().map((tool)=>({
|
|
210
|
+
name: tool.name,
|
|
211
|
+
description: tool.description,
|
|
212
|
+
input_schema: {
|
|
213
|
+
type: 'object',
|
|
214
|
+
properties: tool.parameters.properties,
|
|
215
|
+
required: tool.parameters.required
|
|
216
|
+
}
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get tool definitions (without execute function)
|
|
221
|
+
*/ getDefinitions() {
|
|
222
|
+
return this.getAll().map((tool)=>({
|
|
223
|
+
name: tool.name,
|
|
224
|
+
description: tool.description,
|
|
225
|
+
parameters: tool.parameters,
|
|
226
|
+
category: tool.category,
|
|
227
|
+
cost: tool.cost,
|
|
228
|
+
examples: tool.examples
|
|
229
|
+
}));
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Get usage statistics for all tools
|
|
233
|
+
*/ getUsageStats() {
|
|
234
|
+
const stats = new Map();
|
|
235
|
+
this.usageStats.forEach((rawStats, name)=>{
|
|
236
|
+
stats.set(name, {
|
|
237
|
+
calls: rawStats.calls,
|
|
238
|
+
failures: rawStats.failures,
|
|
239
|
+
successRate: rawStats.calls > 0 ? (rawStats.calls - rawStats.failures) / rawStats.calls : 0,
|
|
240
|
+
averageDuration: rawStats.calls > 0 ? rawStats.totalDuration / rawStats.calls : undefined
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
return stats;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Get most frequently used tools
|
|
247
|
+
*/ getMostUsed(limit = 5) {
|
|
248
|
+
const sorted = Array.from(this.usageStats.entries()).sort((a, b)=>b[1].calls - a[1].calls).slice(0, limit).map(([name])=>this.tools.get(name)).filter((tool)=>tool !== undefined);
|
|
249
|
+
return sorted;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Get list of all categories
|
|
253
|
+
*/ getCategories() {
|
|
254
|
+
const categories = new Set();
|
|
255
|
+
this.getAll().forEach((tool)=>{
|
|
256
|
+
if (tool.category) {
|
|
257
|
+
categories.add(tool.category);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
return Array.from(categories).sort();
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Update execution context
|
|
264
|
+
*/ updateContext(context) {
|
|
265
|
+
this.context = {
|
|
266
|
+
...this.context,
|
|
267
|
+
...context
|
|
268
|
+
};
|
|
269
|
+
this.logger.debug('Updated context', {
|
|
270
|
+
keys: Object.keys(context)
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Get current context
|
|
275
|
+
*/ getContext() {
|
|
276
|
+
return {
|
|
277
|
+
...this.context
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Clear all tools
|
|
282
|
+
*/ clear() {
|
|
283
|
+
this.logger.debug('Clearing all tools');
|
|
284
|
+
this.tools.clear();
|
|
285
|
+
this.usageStats.clear();
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Unregister a specific tool
|
|
289
|
+
*/ unregister(name) {
|
|
290
|
+
if (this.tools.has(name)) {
|
|
291
|
+
this.tools.delete(name);
|
|
292
|
+
this.usageStats.delete(name);
|
|
293
|
+
this.logger.debug('Unregistered tool', {
|
|
294
|
+
name
|
|
295
|
+
});
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Reset usage statistics
|
|
302
|
+
*/ resetStats() {
|
|
303
|
+
this.logger.debug('Resetting usage statistics');
|
|
304
|
+
this.usageStats.forEach((stats)=>{
|
|
305
|
+
stats.calls = 0;
|
|
306
|
+
stats.failures = 0;
|
|
307
|
+
stats.totalDuration = 0;
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
constructor(context = {}, logger){
|
|
311
|
+
_define_property(this, "tools", void 0);
|
|
312
|
+
_define_property(this, "context", void 0);
|
|
313
|
+
_define_property(this, "logger", void 0);
|
|
314
|
+
_define_property(this, "usageStats", void 0);
|
|
315
|
+
this.tools = new Map();
|
|
316
|
+
this.context = context;
|
|
317
|
+
this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'ToolRegistry');
|
|
318
|
+
this.usageStats = new Map();
|
|
319
|
+
this.logger.debug('Created ToolRegistry');
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export { ToolRegistry, ToolRegistry as default };
|
|
324
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sources":["../src/tools.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { DEFAULT_LOGGER, wrapLogger } from \"./logger\";\n\n// ===== TYPE DEFINITIONS =====\n\n/**\n * Parameter definition for a tool\n */\nexport interface ToolParameter {\n type: 'string' | 'number' | 'boolean' | 'array' | 'object';\n description: string;\n items?: ToolParameter;\n properties?: Record<string, ToolParameter>;\n required?: string[];\n enum?: string[];\n default?: any;\n}\n\n/**\n * Context provided to tool execution\n */\nexport interface ToolContext {\n workingDirectory?: string;\n storage?: any;\n logger?: any;\n conversationState?: any;\n [key: string]: any;\n}\n\n/**\n * Example usage of a tool\n */\nexport interface ToolExample {\n scenario: string;\n params: any;\n expectedResult: string;\n}\n\n/**\n * Cost hint for tool execution\n */\nexport type ToolCost = 'cheap' | 'moderate' | 'expensive';\n\n/**\n * Tool definition\n */\nexport interface Tool {\n name: string;\n description: string;\n parameters: {\n type: 'object';\n properties: Record<string, ToolParameter>;\n required?: string[];\n };\n execute: (params: any, context?: ToolContext) => Promise<any>;\n\n // Optional metadata\n category?: string;\n cost?: ToolCost;\n examples?: ToolExample[];\n}\n\n/**\n * OpenAI-compatible tool format\n */\nexport interface OpenAITool {\n type: 'function';\n function: {\n name: string;\n description: string;\n parameters: {\n type: 'object';\n properties: Record<string, any>;\n required?: string[];\n };\n };\n}\n\n/**\n * Anthropic-compatible tool format\n */\nexport interface AnthropicTool {\n name: string;\n description: string;\n input_schema: {\n type: 'object';\n properties: Record<string, any>;\n required?: string[];\n };\n}\n\n/**\n * Tool execution result\n */\nexport interface ToolExecutionResult {\n success: boolean;\n result?: any;\n error?: string;\n duration?: number;\n}\n\n/**\n * Usage statistics for a tool\n */\nexport interface ToolUsageStats {\n calls: number;\n failures: number;\n successRate: number;\n averageDuration?: number;\n}\n\n/**\n * Tool definition for export\n */\nexport interface ToolDefinition {\n name: string;\n description: string;\n parameters: Tool['parameters'];\n category?: string;\n cost?: ToolCost;\n examples?: ToolExample[];\n}\n\n// ===== VALIDATION SCHEMAS =====\n\n// Simplified parameter schema - just validate structure, not deep nesting\nconst ToolSchema = z.object({\n name: z.string().min(1),\n description: z.string().min(1),\n parameters: z.object({\n type: z.literal('object'),\n properties: z.record(z.string(), z.any()).default({}), // Allow any parameter structure\n required: z.array(z.string()).optional(),\n }).passthrough(), // Allow additional fields\n execute: z.custom<(params: any, context?: any) => Promise<any>>(\n (val) => typeof val === 'function',\n { message: 'execute must be a function' }\n ),\n category: z.string().optional(),\n cost: z.enum(['cheap', 'moderate', 'expensive']).optional(),\n examples: z.array(z.object({\n scenario: z.string(),\n params: z.any(),\n expectedResult: z.string(),\n })).optional(),\n}).passthrough(); // Allow additional fields at tool level too\n\n// ===== TOOL REGISTRY =====\n\n/**\n * ToolRegistry manages tool definitions and execution.\n *\n * Features:\n * - Register and manage tools\n * - Execute tools with context\n * - Track usage statistics\n * - Export to different formats (OpenAI, Anthropic)\n * - Filter by category\n *\n * @example\n * ```typescript\n * const registry = ToolRegistry.create({\n * workingDirectory: process.cwd(),\n * logger: myLogger\n * });\n *\n * registry.register({\n * name: 'read_file',\n * description: 'Read a file',\n * parameters: {\n * type: 'object',\n * properties: {\n * path: { type: 'string', description: 'File path' }\n * },\n * required: ['path']\n * },\n * execute: async ({ path }) => {\n * return await fs.readFile(path, 'utf-8');\n * }\n * });\n *\n * const result = await registry.execute('read_file', { path: 'test.txt' });\n * ```\n */\nexport class ToolRegistry {\n private tools: Map<string, Tool>;\n private context: ToolContext;\n private logger: any;\n private usageStats: Map<string, { calls: number; failures: number; totalDuration: number }>;\n\n private constructor(context: ToolContext = {}, logger?: any) {\n this.tools = new Map();\n this.context = context;\n this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'ToolRegistry');\n this.usageStats = new Map();\n\n this.logger.debug('Created ToolRegistry');\n }\n\n /**\n * Create a new ToolRegistry instance\n */\n static create(context?: ToolContext, logger?: any): ToolRegistry {\n return new ToolRegistry(context, logger);\n }\n\n /**\n * Register a single tool\n */\n register(tool: Tool): void {\n // Validate tool\n try {\n ToolSchema.parse(tool);\n } catch (error) {\n throw new Error(`Invalid tool definition for \"${tool.name}\": ${error}`);\n }\n\n if (this.tools.has(tool.name)) {\n this.logger.warn(`Tool \"${tool.name}\" already registered, overwriting`);\n }\n\n this.tools.set(tool.name, tool);\n this.usageStats.set(tool.name, { calls: 0, failures: 0, totalDuration: 0 });\n\n this.logger.debug('Registered tool', { name: tool.name, category: tool.category });\n }\n\n /**\n * Register multiple tools at once\n */\n registerAll(tools: Tool[]): void {\n this.logger.debug('Registering multiple tools', { count: tools.length });\n\n tools.forEach(tool => this.register(tool));\n }\n\n /**\n * Get a tool by name\n */\n get(name: string): Tool | undefined {\n return this.tools.get(name);\n }\n\n /**\n * Get all registered tools\n */\n getAll(): Tool[] {\n return Array.from(this.tools.values());\n }\n\n /**\n * Get tools by category\n */\n getByCategory(category: string): Tool[] {\n return this.getAll().filter(tool => tool.category === category);\n }\n\n /**\n * Check if a tool is registered\n */\n has(name: string): boolean {\n return this.tools.has(name);\n }\n\n /**\n * Get number of registered tools\n */\n count(): number {\n return this.tools.size;\n }\n\n /**\n * Execute a tool by name\n */\n async execute(name: string, params: any): Promise<any> {\n const tool = this.tools.get(name);\n\n if (!tool) {\n throw new Error(`Tool \"${name}\" not found`);\n }\n\n this.logger.debug('Executing tool', { name, params });\n\n const startTime = Date.now();\n const stats = this.usageStats.get(name)!;\n stats.calls++;\n\n try {\n const result = await tool.execute(params, this.context);\n\n const duration = Date.now() - startTime;\n stats.totalDuration += duration;\n\n this.logger.debug('Tool execution succeeded', { name, duration });\n\n return result;\n } catch (error) {\n stats.failures++;\n\n this.logger.error('Tool execution failed', { name, error });\n\n throw error;\n }\n }\n\n /**\n * Execute multiple tools in sequence\n */\n async executeBatch(calls: Array<{ name: string; params: any }>): Promise<any[]> {\n this.logger.debug('Executing batch', { count: calls.length });\n\n const results: any[] = [];\n\n for (const call of calls) {\n try {\n const result = await this.execute(call.name, call.params);\n results.push(result);\n } catch (error) {\n results.push({ error: String(error) });\n }\n }\n\n return results;\n }\n\n /**\n * Export tools in OpenAI format\n */\n toOpenAIFormat(): OpenAITool[] {\n return this.getAll().map(tool => ({\n type: 'function' as const,\n function: {\n name: tool.name,\n description: tool.description,\n parameters: {\n type: 'object' as const,\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n },\n },\n }));\n }\n\n /**\n * Export tools in Anthropic format\n */\n toAnthropicFormat(): AnthropicTool[] {\n return this.getAll().map(tool => ({\n name: tool.name,\n description: tool.description,\n input_schema: {\n type: 'object' as const,\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n },\n }));\n }\n\n /**\n * Get tool definitions (without execute function)\n */\n getDefinitions(): ToolDefinition[] {\n return this.getAll().map(tool => ({\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n category: tool.category,\n cost: tool.cost,\n examples: tool.examples,\n }));\n }\n\n /**\n * Get usage statistics for all tools\n */\n getUsageStats(): Map<string, ToolUsageStats> {\n const stats = new Map<string, ToolUsageStats>();\n\n this.usageStats.forEach((rawStats, name) => {\n stats.set(name, {\n calls: rawStats.calls,\n failures: rawStats.failures,\n successRate: rawStats.calls > 0\n ? (rawStats.calls - rawStats.failures) / rawStats.calls\n : 0,\n averageDuration: rawStats.calls > 0\n ? rawStats.totalDuration / rawStats.calls\n : undefined,\n });\n });\n\n return stats;\n }\n\n /**\n * Get most frequently used tools\n */\n getMostUsed(limit: number = 5): Tool[] {\n const sorted = Array.from(this.usageStats.entries())\n .sort((a, b) => b[1].calls - a[1].calls)\n .slice(0, limit)\n .map(([name]) => this.tools.get(name)!)\n .filter(tool => tool !== undefined);\n\n return sorted;\n }\n\n /**\n * Get list of all categories\n */\n getCategories(): string[] {\n const categories = new Set<string>();\n\n this.getAll().forEach(tool => {\n if (tool.category) {\n categories.add(tool.category);\n }\n });\n\n return Array.from(categories).sort();\n }\n\n /**\n * Update execution context\n */\n updateContext(context: Partial<ToolContext>): void {\n this.context = { ...this.context, ...context };\n this.logger.debug('Updated context', { keys: Object.keys(context) });\n }\n\n /**\n * Get current context\n */\n getContext(): ToolContext {\n return { ...this.context };\n }\n\n /**\n * Clear all tools\n */\n clear(): void {\n this.logger.debug('Clearing all tools');\n this.tools.clear();\n this.usageStats.clear();\n }\n\n /**\n * Unregister a specific tool\n */\n unregister(name: string): boolean {\n if (this.tools.has(name)) {\n this.tools.delete(name);\n this.usageStats.delete(name);\n this.logger.debug('Unregistered tool', { name });\n return true;\n }\n\n return false;\n }\n\n /**\n * Reset usage statistics\n */\n resetStats(): void {\n this.logger.debug('Resetting usage statistics');\n\n this.usageStats.forEach(stats => {\n stats.calls = 0;\n stats.failures = 0;\n stats.totalDuration = 0;\n });\n }\n}\n\n/**\n * Export the registry for use in other modules\n */\nexport default ToolRegistry;\n\n"],"names":["ToolSchema","z","object","name","string","min","description","parameters","type","literal","properties","record","any","default","required","array","optional","passthrough","execute","custom","val","message","category","cost","enum","examples","scenario","params","expectedResult","ToolRegistry","create","context","logger","register","tool","parse","error","Error","tools","has","warn","set","usageStats","calls","failures","totalDuration","debug","registerAll","count","length","forEach","get","getAll","Array","from","values","getByCategory","filter","size","startTime","Date","now","stats","result","duration","executeBatch","results","call","push","String","toOpenAIFormat","map","function","toAnthropicFormat","input_schema","getDefinitions","getUsageStats","Map","rawStats","successRate","averageDuration","undefined","getMostUsed","limit","sorted","entries","sort","a","b","slice","getCategories","categories","Set","add","updateContext","keys","Object","getContext","clear","unregister","delete","resetStats","wrapLogger","DEFAULT_LOGGER"],"mappings":"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"}
|