cmdr-agent 2.4.0 → 2.5.1

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.
Files changed (109) hide show
  1. package/dist/bin/cmdr.js +117 -27
  2. package/dist/bin/cmdr.js.map +1 -1
  3. package/dist/package.json +9 -4
  4. package/dist/src/cli/ink/App.d.ts +2 -2
  5. package/dist/src/cli/ink/App.d.ts.map +1 -1
  6. package/dist/src/cli/ink/App.js +118 -65
  7. package/dist/src/cli/ink/App.js.map +1 -1
  8. package/dist/src/cli/ink/PromptInput.d.ts +17 -0
  9. package/dist/src/cli/ink/PromptInput.d.ts.map +1 -0
  10. package/dist/src/cli/ink/PromptInput.js +202 -0
  11. package/dist/src/cli/ink/PromptInput.js.map +1 -0
  12. package/dist/src/cli/ink/StatusBar.d.ts +1 -1
  13. package/dist/src/cli/ink/StatusBar.d.ts.map +1 -1
  14. package/dist/src/cli/ink/StatusBar.js +116 -21
  15. package/dist/src/cli/ink/StatusBar.js.map +1 -1
  16. package/dist/src/cli/ink/input-buffer.d.ts +34 -0
  17. package/dist/src/cli/ink/input-buffer.d.ts.map +1 -0
  18. package/dist/src/cli/ink/input-buffer.js +152 -0
  19. package/dist/src/cli/ink/input-buffer.js.map +1 -0
  20. package/dist/src/cli/progress.d.ts +59 -0
  21. package/dist/src/cli/progress.d.ts.map +1 -0
  22. package/dist/src/cli/progress.js +172 -0
  23. package/dist/src/cli/progress.js.map +1 -0
  24. package/dist/src/cli/renderer.d.ts +14 -3
  25. package/dist/src/cli/renderer.d.ts.map +1 -1
  26. package/dist/src/cli/renderer.js +93 -32
  27. package/dist/src/cli/renderer.js.map +1 -1
  28. package/dist/src/cli/repl.d.ts.map +1 -1
  29. package/dist/src/cli/repl.js +46 -28
  30. package/dist/src/cli/repl.js.map +1 -1
  31. package/dist/src/cli/spinner.d.ts +4 -1
  32. package/dist/src/cli/spinner.d.ts.map +1 -1
  33. package/dist/src/cli/spinner.js +34 -1
  34. package/dist/src/cli/spinner.js.map +1 -1
  35. package/dist/src/cli/theme.d.ts +14 -12
  36. package/dist/src/cli/theme.d.ts.map +1 -1
  37. package/dist/src/cli/theme.js +192 -123
  38. package/dist/src/cli/theme.js.map +1 -1
  39. package/dist/src/cli/themes.d.ts +17 -1
  40. package/dist/src/cli/themes.d.ts.map +1 -1
  41. package/dist/src/cli/themes.js +125 -27
  42. package/dist/src/cli/themes.js.map +1 -1
  43. package/dist/src/core/agent-runner.d.ts +12 -0
  44. package/dist/src/core/agent-runner.d.ts.map +1 -1
  45. package/dist/src/core/agent-runner.js +176 -5
  46. package/dist/src/core/agent-runner.js.map +1 -1
  47. package/dist/src/core/event-bus.d.ts +12 -0
  48. package/dist/src/core/event-bus.d.ts.map +1 -1
  49. package/dist/src/core/event-bus.js.map +1 -1
  50. package/dist/src/core/presets.d.ts.map +1 -1
  51. package/dist/src/core/presets.js +1 -0
  52. package/dist/src/core/presets.js.map +1 -1
  53. package/dist/src/core/types.d.ts +17 -0
  54. package/dist/src/core/types.d.ts.map +1 -1
  55. package/dist/src/core/types.js +8 -1
  56. package/dist/src/core/types.js.map +1 -1
  57. package/dist/src/llm/anthropic.d.ts +1 -0
  58. package/dist/src/llm/anthropic.d.ts.map +1 -1
  59. package/dist/src/llm/anthropic.js +20 -1
  60. package/dist/src/llm/anthropic.js.map +1 -1
  61. package/dist/src/llm/ollama.d.ts +2 -12
  62. package/dist/src/llm/ollama.d.ts.map +1 -1
  63. package/dist/src/llm/ollama.js +46 -250
  64. package/dist/src/llm/ollama.js.map +1 -1
  65. package/dist/src/llm/openai.d.ts +1 -0
  66. package/dist/src/llm/openai.d.ts.map +1 -1
  67. package/dist/src/llm/openai.js +21 -7
  68. package/dist/src/llm/openai.js.map +1 -1
  69. package/dist/src/llm/repair/retry-policy.d.ts +48 -0
  70. package/dist/src/llm/repair/retry-policy.d.ts.map +1 -0
  71. package/dist/src/llm/repair/retry-policy.js +85 -0
  72. package/dist/src/llm/repair/retry-policy.js.map +1 -0
  73. package/dist/src/llm/repair/tool-repair.d.ts +39 -0
  74. package/dist/src/llm/repair/tool-repair.d.ts.map +1 -0
  75. package/dist/src/llm/repair/tool-repair.js +313 -0
  76. package/dist/src/llm/repair/tool-repair.js.map +1 -0
  77. package/dist/src/llm/shared/text-cleanup.d.ts +16 -0
  78. package/dist/src/llm/shared/text-cleanup.d.ts.map +1 -0
  79. package/dist/src/llm/shared/text-cleanup.js +120 -0
  80. package/dist/src/llm/shared/text-cleanup.js.map +1 -0
  81. package/dist/src/llm/shared/tool-parsing.d.ts +70 -0
  82. package/dist/src/llm/shared/tool-parsing.d.ts.map +1 -0
  83. package/dist/src/llm/shared/tool-parsing.js +355 -0
  84. package/dist/src/llm/shared/tool-parsing.js.map +1 -0
  85. package/dist/src/llm/validation/tool-call-schema.d.ts +83 -0
  86. package/dist/src/llm/validation/tool-call-schema.d.ts.map +1 -0
  87. package/dist/src/llm/validation/tool-call-schema.js +145 -0
  88. package/dist/src/llm/validation/tool-call-schema.js.map +1 -0
  89. package/dist/src/tools/built-in/bash.d.ts +5 -1
  90. package/dist/src/tools/built-in/bash.d.ts.map +1 -1
  91. package/dist/src/tools/built-in/bash.js +34 -46
  92. package/dist/src/tools/built-in/bash.js.map +1 -1
  93. package/dist/src/tools/built-in/index.d.ts +2 -1
  94. package/dist/src/tools/built-in/index.d.ts.map +1 -1
  95. package/dist/src/tools/built-in/index.js +3 -1
  96. package/dist/src/tools/built-in/index.js.map +1 -1
  97. package/dist/src/tools/built-in/pdf-report.d.ts +39 -0
  98. package/dist/src/tools/built-in/pdf-report.d.ts.map +1 -0
  99. package/dist/src/tools/built-in/pdf-report.js +326 -0
  100. package/dist/src/tools/built-in/pdf-report.js.map +1 -0
  101. package/dist/src/tools/executor.d.ts +7 -1
  102. package/dist/src/tools/executor.d.ts.map +1 -1
  103. package/dist/src/tools/executor.js +20 -5
  104. package/dist/src/tools/executor.js.map +1 -1
  105. package/dist/src/tools/shell/shell-executor.d.ts +71 -0
  106. package/dist/src/tools/shell/shell-executor.d.ts.map +1 -0
  107. package/dist/src/tools/shell/shell-executor.js +238 -0
  108. package/dist/src/tools/shell/shell-executor.js.map +1 -0
  109. package/package.json +9 -4
@@ -0,0 +1,355 @@
1
+ /**
2
+ * Unified tool call parser for all LLM adapters.
3
+ *
4
+ * Consolidates the tool parsing logic that was duplicated across
5
+ * ollama.ts, openai.ts, and anthropic.ts into a single, well-tested module.
6
+ *
7
+ * Supports:
8
+ * - Native API tool calls (Ollama, OpenAI, Anthropic)
9
+ * - Text-based JSON format: ```tool_call\n{JSON}\n```
10
+ * - XML function format: <function=name><parameter=key>value</parameter></function>
11
+ * - Invoke format: <invoke name="..."><parameter name="...">value</parameter></invoke>
12
+ * - MiniMax wrapper: <minimax:tool_call>...</minimax:tool_call>
13
+ *
14
+ * Each strategy runs in order and returns on first match (waterfall).
15
+ */
16
+ import { validateToolCallShape } from '../validation/tool-call-schema.js';
17
+ import { cleanLLMOutput } from './text-cleanup.js';
18
+ const DEFAULT_CONFIG = {
19
+ jsonToolFormat: true,
20
+ xmlToolFormat: true,
21
+ invokeFormat: true,
22
+ };
23
+ // ---------------------------------------------------------------------------
24
+ // ID generation
25
+ // ---------------------------------------------------------------------------
26
+ let _idCounter = 0;
27
+ function generateToolId() {
28
+ _idCounter++;
29
+ return `tool_${Date.now()}_${_idCounter.toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
30
+ }
31
+ // ---------------------------------------------------------------------------
32
+ // Unified resolution: native → text waterfall
33
+ // ---------------------------------------------------------------------------
34
+ /**
35
+ * Three-stage tool resolution waterfall.
36
+ * This is the main entry point for all adapters.
37
+ *
38
+ * 1. Native tool_calls from API (highest confidence)
39
+ * 2. Text-based JSON format
40
+ * 3. Text-based XML format
41
+ *
42
+ * Returns an array of ContentBlocks (text + tool_use mixed).
43
+ */
44
+ export function resolveToolCalls(nativeToolCalls, textContent, config, hasTools) {
45
+ const cfg = { ...DEFAULT_CONFIG, ...config };
46
+ // Stage 1: Native tool_calls from API response
47
+ if (nativeToolCalls && nativeToolCalls.length > 0) {
48
+ const content = [];
49
+ if (textContent) {
50
+ content.push({ type: 'text', text: textContent });
51
+ }
52
+ for (const tc of nativeToolCalls) {
53
+ const args = typeof tc.function.arguments === 'string'
54
+ ? safeParseJson(tc.function.arguments)
55
+ : tc.function.arguments;
56
+ const validation = validateToolCallShape({
57
+ name: tc.function.name,
58
+ arguments: args,
59
+ });
60
+ if (validation.ok) {
61
+ content.push({
62
+ type: 'tool_use',
63
+ id: tc.id ?? generateToolId(),
64
+ name: validation.toolCall.name,
65
+ input: validation.toolCall.arguments,
66
+ });
67
+ }
68
+ }
69
+ return content;
70
+ }
71
+ // Stage 0: Pre-parse cleanup for text-based parsing
72
+ const cleanedText = hasTools && textContent ? cleanLLMOutput(textContent) : textContent;
73
+ // Stage 2+3: Parse text-based tool calls only if tools are available
74
+ if (hasTools && cleanedText) {
75
+ const parsed = parseTextToolCalls(cleanedText, cfg);
76
+ if (parsed.length > 0)
77
+ return parsed;
78
+ }
79
+ // No tool calls — return as pure text (use original, uncleaned text for display)
80
+ if (textContent) {
81
+ return [{ type: 'text', text: textContent }];
82
+ }
83
+ return [];
84
+ }
85
+ // ---------------------------------------------------------------------------
86
+ // Text-based tool call extraction (all strategies)
87
+ // ---------------------------------------------------------------------------
88
+ /**
89
+ * Parse tool calls from text output using multiple strategies.
90
+ * Returns ContentBlock[] with interleaved text and tool_use blocks.
91
+ */
92
+ export function parseTextToolCalls(text, config) {
93
+ const cfg = { ...DEFAULT_CONFIG, ...config };
94
+ // Strategy 1: ```tool_call JSON format
95
+ if (cfg.jsonToolFormat) {
96
+ const result = parseJsonToolCalls(text);
97
+ if (result.length > 0 && result.some(b => b.type === 'tool_use')) {
98
+ return result;
99
+ }
100
+ }
101
+ // Strategy 2: <function=name> XML format
102
+ if (cfg.xmlToolFormat) {
103
+ const result = parseXmlFunctionCalls(text);
104
+ if (result.length > 0 && result.some(b => b.type === 'tool_use')) {
105
+ return result;
106
+ }
107
+ }
108
+ // Strategy 3: <invoke name="..."> format (MiniMax, etc.)
109
+ if (cfg.invokeFormat) {
110
+ const result = parseInvokeCalls(text);
111
+ if (result.length > 0 && result.some(b => b.type === 'tool_use')) {
112
+ return result;
113
+ }
114
+ }
115
+ // No tool calls found
116
+ if (text) {
117
+ return [{ type: 'text', text }];
118
+ }
119
+ return [];
120
+ }
121
+ // ---------------------------------------------------------------------------
122
+ // Strategy 1: JSON ```tool_call``` format
123
+ // ---------------------------------------------------------------------------
124
+ function parseJsonToolCalls(text) {
125
+ const content = [];
126
+ const toolCallRegex = /```tool_call\s*\n([\s\S]*?)\n```/g;
127
+ let lastIndex = 0;
128
+ let match;
129
+ let foundToolCalls = false;
130
+ while ((match = toolCallRegex.exec(text)) !== null) {
131
+ foundToolCalls = true;
132
+ // Add preceding text
133
+ if (match.index > lastIndex) {
134
+ const before = text.slice(lastIndex, match.index).trim();
135
+ if (before)
136
+ content.push({ type: 'text', text: before });
137
+ }
138
+ const blockContent = match[1].trim();
139
+ const parsedObjects = parseMultipleJsonObjects(blockContent);
140
+ if (parsedObjects.length > 0) {
141
+ for (const parsed of parsedObjects) {
142
+ const validation = validateToolCallShape(parsed);
143
+ if (validation.ok) {
144
+ content.push({
145
+ type: 'tool_use',
146
+ id: generateToolId(),
147
+ name: validation.toolCall.name,
148
+ input: validation.toolCall.arguments,
149
+ });
150
+ }
151
+ }
152
+ }
153
+ else {
154
+ // Could not parse — keep as text
155
+ content.push({ type: 'text', text: match[0] });
156
+ }
157
+ lastIndex = match.index + match[0].length;
158
+ }
159
+ if (foundToolCalls && lastIndex < text.length) {
160
+ const remainder = text.slice(lastIndex).trim();
161
+ if (remainder)
162
+ content.push({ type: 'text', text: remainder });
163
+ }
164
+ return foundToolCalls ? content : [];
165
+ }
166
+ // ---------------------------------------------------------------------------
167
+ // Strategy 2: XML <function=name> format
168
+ // ---------------------------------------------------------------------------
169
+ function parseXmlFunctionCalls(text) {
170
+ const content = [];
171
+ const xmlToolRegex = /<function=(\w+)>([\s\S]*?)<\/function>/g;
172
+ const paramRegex = /<parameter=(\w+)>([\s\S]*?)<\/parameter>/g;
173
+ let lastIndex = 0;
174
+ let match;
175
+ let foundToolCalls = false;
176
+ while ((match = xmlToolRegex.exec(text)) !== null) {
177
+ foundToolCalls = true;
178
+ if (match.index > lastIndex) {
179
+ const before = text.slice(lastIndex, match.index).trim();
180
+ if (before)
181
+ content.push({ type: 'text', text: before });
182
+ }
183
+ const toolName = match[1];
184
+ const paramsBlock = match[2];
185
+ const input = {};
186
+ let paramMatch;
187
+ while ((paramMatch = paramRegex.exec(paramsBlock)) !== null) {
188
+ input[paramMatch[1]] = paramMatch[2].trim();
189
+ }
190
+ paramRegex.lastIndex = 0;
191
+ content.push({
192
+ type: 'tool_use',
193
+ id: generateToolId(),
194
+ name: toolName,
195
+ input,
196
+ });
197
+ lastIndex = match.index + match[0].length;
198
+ }
199
+ if (foundToolCalls && lastIndex < text.length) {
200
+ const remainder = text.slice(lastIndex).trim();
201
+ if (remainder)
202
+ content.push({ type: 'text', text: remainder });
203
+ }
204
+ return foundToolCalls ? content : [];
205
+ }
206
+ // ---------------------------------------------------------------------------
207
+ // Strategy 3: <invoke name="..."> format (MiniMax/Kimi style)
208
+ // ---------------------------------------------------------------------------
209
+ function parseInvokeCalls(text) {
210
+ const content = [];
211
+ const invokeRegex = /<invoke\s+name="([^"]+)">((?:.|\n)*?)<\/invoke>/g;
212
+ const invokeParamRegex = /<parameter\s+name="([^"]+)">((?:.|\n)*?)<\/parameter>/g;
213
+ let lastIndex = 0;
214
+ let match;
215
+ let foundToolCalls = false;
216
+ while ((match = invokeRegex.exec(text)) !== null) {
217
+ foundToolCalls = true;
218
+ if (match.index > lastIndex) {
219
+ const before = text.slice(lastIndex, match.index).trim();
220
+ // Strip wrapper tags like <minimax:tool_call>
221
+ const cleaned = before.replace(/<\/?[\w:]+>/g, '').trim();
222
+ if (cleaned)
223
+ content.push({ type: 'text', text: cleaned });
224
+ }
225
+ const toolName = match[1];
226
+ const paramsBlock = match[2];
227
+ const input = {};
228
+ let paramMatch;
229
+ while ((paramMatch = invokeParamRegex.exec(paramsBlock)) !== null) {
230
+ input[paramMatch[1]] = paramMatch[2].trim();
231
+ }
232
+ invokeParamRegex.lastIndex = 0;
233
+ content.push({
234
+ type: 'tool_use',
235
+ id: generateToolId(),
236
+ name: toolName,
237
+ input,
238
+ });
239
+ lastIndex = match.index + match[0].length;
240
+ }
241
+ if (foundToolCalls) {
242
+ if (lastIndex < text.length) {
243
+ const remainder = text.slice(lastIndex).replace(/<\/?[\w:]+>/g, '').trim();
244
+ if (remainder)
245
+ content.push({ type: 'text', text: remainder });
246
+ }
247
+ return content;
248
+ }
249
+ return [];
250
+ }
251
+ // ---------------------------------------------------------------------------
252
+ // JSON parsing utilities
253
+ // ---------------------------------------------------------------------------
254
+ /**
255
+ * Parse multiple JSON objects from a block that may contain:
256
+ * - A single JSON object
257
+ * - A JSON array
258
+ * - One object per line
259
+ * - Comma-separated objects
260
+ */
261
+ export function parseMultipleJsonObjects(block) {
262
+ const results = [];
263
+ // Try 1: Single JSON object or array
264
+ try {
265
+ const parsed = JSON.parse(block);
266
+ if (parsed && typeof parsed === 'object') {
267
+ if (parsed.name && parsed.arguments) {
268
+ results.push(parsed);
269
+ return results;
270
+ }
271
+ if (Array.isArray(parsed)) {
272
+ for (const item of parsed) {
273
+ if (item?.name && item?.arguments)
274
+ results.push(item);
275
+ }
276
+ if (results.length > 0)
277
+ return results;
278
+ }
279
+ }
280
+ }
281
+ catch {
282
+ // Not valid single JSON — try multi-line
283
+ }
284
+ // Try 2: One JSON object per line
285
+ const lines = block.split('\n');
286
+ for (const line of lines) {
287
+ const trimmed = line.trim();
288
+ if (!trimmed || !trimmed.startsWith('{'))
289
+ continue;
290
+ try {
291
+ const parsed = JSON.parse(trimmed);
292
+ if (parsed?.name && parsed?.arguments) {
293
+ results.push(parsed);
294
+ }
295
+ }
296
+ catch {
297
+ // Try stripping trailing comma
298
+ const noComma = trimmed.replace(/,\s*$/, '');
299
+ try {
300
+ const parsed = JSON.parse(noComma);
301
+ if (parsed?.name && parsed?.arguments) {
302
+ results.push(parsed);
303
+ }
304
+ }
305
+ catch {
306
+ // Skip unparseable
307
+ }
308
+ }
309
+ }
310
+ return results;
311
+ }
312
+ /**
313
+ * Safely parse a JSON string, returning an empty object on failure.
314
+ */
315
+ function safeParseJson(str) {
316
+ try {
317
+ const parsed = JSON.parse(str);
318
+ return typeof parsed === 'object' && parsed !== null ? parsed : {};
319
+ }
320
+ catch {
321
+ return {};
322
+ }
323
+ }
324
+ // ---------------------------------------------------------------------------
325
+ // Tool prompt builder (for models without native tool support)
326
+ // ---------------------------------------------------------------------------
327
+ /**
328
+ * Build the tool-call instruction suffix to inject into the system prompt
329
+ * for models that don't support native tool calling.
330
+ */
331
+ export function buildToolPromptSuffix(tools, options) {
332
+ const toolDescs = tools.map(t => `- ${t.name}: ${t.description}\n Input: ${JSON.stringify(t.inputSchema)}`).join('\n');
333
+ return `\n\nYou have access to the following tools. To use a tool, respond with a JSON block:
334
+
335
+ \`\`\`tool_call
336
+ {"name": "tool_name", "arguments": {"arg1": "value1"}}
337
+ \`\`\`
338
+
339
+ To call MULTIPLE tools, use one JSON object per line inside a single \`\`\`tool_call block:
340
+
341
+ \`\`\`tool_call
342
+ {"name": "tool1", "arguments": {"arg": "val"}}
343
+ {"name": "tool2", "arguments": {"arg": "val"}}
344
+ \`\`\`
345
+
346
+ Available tools:
347
+ ${toolDescs}
348
+
349
+ IMPORTANT: Use ONLY the \`\`\`tool_call JSON format shown above. Do NOT use XML, <invoke>, <function>, or any other format for tool calls.
350
+ Always use tools when you need to interact with the filesystem or run commands.
351
+ After receiving a tool result, continue your analysis.${options?.strict ? `
352
+
353
+ CRITICAL: When calling tools, output ONLY the tool call format. Do not include explanatory text, reasoning, or commentary before or after tool calls. Tool calls must use the exact argument types specified in the schema (numbers as numbers, booleans as booleans, not strings).` : ''}`;
354
+ }
355
+ //# sourceMappingURL=tool-parsing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-parsing.js","sourceRoot":"","sources":["../../../../src/llm/shared/tool-parsing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Tool call validation layer using Zod schemas.
3
+ *
4
+ * Mirrors Claude Code's approach: every tool call is validated through its
5
+ * registered Zod schema before execution. Malformed calls are rejected
6
+ * early with clear error messages to the model, enabling retry with
7
+ * corrected format.
8
+ */
9
+ import { z, type ZodSchema } from 'zod';
10
+ import type { ToolUseBlock } from '../../core/types.js';
11
+ /**
12
+ * Schema for a single parsed tool call object.
13
+ * All parsed tool calls (from native API, JSON text, XML text) must conform to this.
14
+ */
15
+ export declare const ToolCallSchema: z.ZodObject<{
16
+ name: z.ZodString;
17
+ arguments: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
18
+ }, "strip", z.ZodTypeAny, {
19
+ name: string;
20
+ arguments: Record<string, unknown>;
21
+ }, {
22
+ name: string;
23
+ arguments?: Record<string, unknown> | undefined;
24
+ }>;
25
+ export type ParsedToolCall = z.infer<typeof ToolCallSchema>;
26
+ /**
27
+ * Validate a raw parsed tool call against the canonical schema.
28
+ * Returns a normalized tool call or validation errors.
29
+ */
30
+ export declare function validateToolCallShape(raw: unknown): {
31
+ ok: true;
32
+ toolCall: ParsedToolCall;
33
+ } | {
34
+ ok: false;
35
+ errors: string[];
36
+ };
37
+ /**
38
+ * Validate a tool call's arguments against the tool's registered Zod input schema.
39
+ * Returns { ok: true, parsed } or { ok: false, message } with a corrective hint.
40
+ */
41
+ export declare function validateToolInput(toolName: string, args: Record<string, unknown>, inputSchema: ZodSchema): {
42
+ ok: true;
43
+ parsed: unknown;
44
+ } | {
45
+ ok: false;
46
+ message: string;
47
+ };
48
+ export interface ValidatedToolCall {
49
+ readonly id: string;
50
+ readonly name: string;
51
+ readonly input: Record<string, unknown>;
52
+ readonly rawInput: Record<string, unknown>;
53
+ }
54
+ export interface RejectedToolCall {
55
+ readonly id: string;
56
+ readonly name: string;
57
+ readonly error: string;
58
+ }
59
+ /**
60
+ * Validate a batch of tool use blocks against registered tool definitions.
61
+ * Separates valid tool calls from rejected ones with clear error messages.
62
+ *
63
+ * Mirrors Claude Code's flow: Zod input validation → tool-specific validateInput → execute
64
+ */
65
+ export declare function validateToolCallBatch(toolUseBlocks: ToolUseBlock[], toolLookup: Map<string, {
66
+ inputSchema: ZodSchema;
67
+ }>, availableToolNames: Set<string>): {
68
+ valid: ValidatedToolCall[];
69
+ rejected: RejectedToolCall[];
70
+ };
71
+ /**
72
+ * Detect if text contains leaked tool call formatting.
73
+ * When a model outputs tool call syntax in its text response instead of
74
+ * through the proper tool calling mechanism, we detect it here so the
75
+ * parser can try to extract valid tool calls from it.
76
+ */
77
+ export declare function detectToolCallLeakage(text: string): boolean;
78
+ /**
79
+ * Build a corrective system message to send back to the model
80
+ * when tool call leakage is detected.
81
+ */
82
+ export declare function buildLeakageCorrectionPrompt(): string;
83
+ //# sourceMappingURL=tool-call-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-call-schema.d.ts","sourceRoot":"","sources":["../../../../src/llm/validation/tool-call-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,KAAK,SAAS,EAAiB,MAAM,KAAK,CAAA;AACtD,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAMnE;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;;;;;;EAGzB,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG;IACnD,EAAE,EAAE,IAAI,CAAA;IACR,QAAQ,EAAE,cAAc,CAAA;CACzB,GAAG;IACF,EAAE,EAAE,KAAK,CAAA;IACT,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CASA;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,WAAW,EAAE,SAAS,GACrB;IACD,EAAE,EAAE,IAAI,CAAA;IACR,MAAM,EAAE,OAAO,CAAA;CAChB,GAAG;IACF,EAAE,EAAE,KAAK,CAAA;IACT,OAAO,EAAE,MAAM,CAAA;CAChB,CASA;AAsBD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC3C;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,YAAY,EAAE,EAC7B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,WAAW,EAAE,SAAS,CAAA;CAAE,CAAC,EACnD,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,GAC9B;IACD,KAAK,EAAE,iBAAiB,EAAE,CAAA;IAC1B,QAAQ,EAAE,gBAAgB,EAAE,CAAA;CAC7B,CA6CA;AAoBD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,CAMrD"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Tool call validation layer using Zod schemas.
3
+ *
4
+ * Mirrors Claude Code's approach: every tool call is validated through its
5
+ * registered Zod schema before execution. Malformed calls are rejected
6
+ * early with clear error messages to the model, enabling retry with
7
+ * corrected format.
8
+ */
9
+ import { z } from 'zod';
10
+ // ---------------------------------------------------------------------------
11
+ // Canonical tool call schema — validates the SHAPE of any tool call
12
+ // ---------------------------------------------------------------------------
13
+ /**
14
+ * Schema for a single parsed tool call object.
15
+ * All parsed tool calls (from native API, JSON text, XML text) must conform to this.
16
+ */
17
+ export const ToolCallSchema = z.object({
18
+ name: z.string().min(1, 'Tool name must be a non-empty string'),
19
+ arguments: z.record(z.unknown()).default({}),
20
+ });
21
+ /**
22
+ * Validate a raw parsed tool call against the canonical schema.
23
+ * Returns a normalized tool call or validation errors.
24
+ */
25
+ export function validateToolCallShape(raw) {
26
+ const result = ToolCallSchema.safeParse(raw);
27
+ if (result.success) {
28
+ return { ok: true, toolCall: result.data };
29
+ }
30
+ return {
31
+ ok: false,
32
+ errors: result.error.errors.map(e => `${e.path.join('.')}: ${e.message}`),
33
+ };
34
+ }
35
+ // ---------------------------------------------------------------------------
36
+ // Tool-specific input validation
37
+ // ---------------------------------------------------------------------------
38
+ /**
39
+ * Validate a tool call's arguments against the tool's registered Zod input schema.
40
+ * Returns { ok: true, parsed } or { ok: false, message } with a corrective hint.
41
+ */
42
+ export function validateToolInput(toolName, args, inputSchema) {
43
+ const result = inputSchema.safeParse(args);
44
+ if (result.success) {
45
+ return { ok: true, parsed: result.data };
46
+ }
47
+ return {
48
+ ok: false,
49
+ message: formatZodError(toolName, result.error),
50
+ };
51
+ }
52
+ /**
53
+ * Format a ZodError into a clear corrective message for the model.
54
+ * The message tells the model exactly what was wrong and how to fix it.
55
+ */
56
+ function formatZodError(toolName, error) {
57
+ const issues = error.errors.map(e => {
58
+ const path = e.path.length > 0 ? `"${e.path.join('.')}"` : 'root';
59
+ return ` - ${path}: ${e.message}`;
60
+ }).join('\n');
61
+ return (`Tool "${toolName}" received invalid arguments:\n${issues}\n` +
62
+ `Please retry with corrected arguments matching the tool's input schema.`);
63
+ }
64
+ /**
65
+ * Validate a batch of tool use blocks against registered tool definitions.
66
+ * Separates valid tool calls from rejected ones with clear error messages.
67
+ *
68
+ * Mirrors Claude Code's flow: Zod input validation → tool-specific validateInput → execute
69
+ */
70
+ export function validateToolCallBatch(toolUseBlocks, toolLookup, availableToolNames) {
71
+ const valid = [];
72
+ const rejected = [];
73
+ for (const block of toolUseBlocks) {
74
+ // Check tool exists
75
+ if (!availableToolNames.has(block.name)) {
76
+ rejected.push({
77
+ id: block.id,
78
+ name: block.name,
79
+ error: `Unknown tool "${block.name}". Available tools: ${[...availableToolNames].join(', ')}`,
80
+ });
81
+ continue;
82
+ }
83
+ const toolDef = toolLookup.get(block.name);
84
+ if (!toolDef) {
85
+ rejected.push({
86
+ id: block.id,
87
+ name: block.name,
88
+ error: `Tool "${block.name}" has no registered schema.`,
89
+ });
90
+ continue;
91
+ }
92
+ // Validate input against schema
93
+ const validation = validateToolInput(block.name, block.input, toolDef.inputSchema);
94
+ if (!validation.ok) {
95
+ rejected.push({
96
+ id: block.id,
97
+ name: block.name,
98
+ error: validation.message,
99
+ });
100
+ continue;
101
+ }
102
+ valid.push({
103
+ id: block.id,
104
+ name: block.name,
105
+ input: validation.parsed,
106
+ rawInput: block.input,
107
+ });
108
+ }
109
+ return { valid, rejected };
110
+ }
111
+ // ---------------------------------------------------------------------------
112
+ // Leakage detection — detect when models leak tool format into text
113
+ // ---------------------------------------------------------------------------
114
+ /** Patterns that indicate a model is leaking tool call format into text output. */
115
+ const LEAKAGE_PATTERNS = [
116
+ // JSON tool_call format leaking
117
+ /```tool_call[\s\S]*?```/,
118
+ // XML function format leaking
119
+ /<function=\w+>[\s\S]*?<\/function>/,
120
+ // Invoke format leaking
121
+ /<invoke\s+name="[^"]+">[\s\S]*?<\/invoke>/,
122
+ // MiniMax wrapper leaking
123
+ /<minimax:tool_call>[\s\S]*?<\/minimax:tool_call>/,
124
+ // OpenAI function_call format leaking into text
125
+ /"function_call"\s*:\s*\{/,
126
+ ];
127
+ /**
128
+ * Detect if text contains leaked tool call formatting.
129
+ * When a model outputs tool call syntax in its text response instead of
130
+ * through the proper tool calling mechanism, we detect it here so the
131
+ * parser can try to extract valid tool calls from it.
132
+ */
133
+ export function detectToolCallLeakage(text) {
134
+ return LEAKAGE_PATTERNS.some(p => p.test(text));
135
+ }
136
+ /**
137
+ * Build a corrective system message to send back to the model
138
+ * when tool call leakage is detected.
139
+ */
140
+ export function buildLeakageCorrectionPrompt() {
141
+ return ('Your previous response contained tool call formatting in the text output. ' +
142
+ 'Please use the proper tool calling mechanism instead of embedding tool calls in text. ' +
143
+ 'Use the tool_call format or the native tool use API to call tools.');
144
+ }
145
+ //# sourceMappingURL=tool-call-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-call-schema.js","sourceRoot":"","sources":["../../../../src/llm/validation/tool-call-schema.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,9 @@
1
1
  /**
2
- * Built-in bash tool — execute shell commands.
2
+ * Built-in bash/shell tool — execute shell commands cross-platform.
3
+ *
4
+ * Uses the ShellExecutor for platform-aware execution.
5
+ * On Unix: uses bash/zsh/sh (auto-detected).
6
+ * On Windows: uses PowerShell or cmd.exe (auto-detected).
3
7
  */
4
8
  export declare const bashTool: import("../registry.js").ToolDefinition<{
5
9
  command: string;
@@ -1 +1 @@
1
- {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../../src/tools/built-in/bash.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,eAAO,MAAM,QAAQ;;;;EAmCnB,CAAA"}
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../../src/tools/built-in/bash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,eAAO,MAAM,QAAQ;;;;EAkDnB,CAAA"}