@probelabs/probe 0.6.0-rc203 → 0.6.0-rc205
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/bin/binaries/probe-v0.6.0-rc205-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc205-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc205-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc205-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc205-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/ProbeAgent.d.ts +2 -0
- package/build/agent/ProbeAgent.js +233 -40
- package/build/agent/index.js +1566 -84
- package/build/agent/simpleTelemetry.js +12 -0
- package/build/agent/tasks/TaskManager.js +604 -0
- package/build/agent/tasks/index.js +15 -0
- package/build/agent/tasks/taskTool.js +476 -0
- package/build/agent/tools.js +11 -0
- package/build/delegate.js +7 -2
- package/build/index.js +14 -1
- package/build/search.js +19 -5
- package/build/tools/common.js +67 -0
- package/build/tools/vercel.js +28 -12
- package/build/utils/error-types.js +303 -0
- package/build/utils/path-validation.js +21 -3
- package/cjs/agent/ProbeAgent.cjs +8940 -6393
- package/cjs/agent/simpleTelemetry.cjs +10 -0
- package/cjs/index.cjs +8960 -6393
- package/package.json +2 -2
- package/src/agent/ProbeAgent.d.ts +2 -0
- package/src/agent/ProbeAgent.js +233 -40
- package/src/agent/index.js +14 -2
- package/src/agent/simpleTelemetry.js +12 -0
- package/src/agent/tasks/TaskManager.js +604 -0
- package/src/agent/tasks/index.js +15 -0
- package/src/agent/tasks/taskTool.js +476 -0
- package/src/agent/tools.js +11 -0
- package/src/delegate.js +7 -2
- package/src/index.js +14 -1
- package/src/search.js +19 -5
- package/src/tools/common.js +67 -0
- package/src/tools/vercel.js +28 -12
- package/src/utils/error-types.js +303 -0
- package/src/utils/path-validation.js +21 -3
- package/bin/binaries/probe-v0.6.0-rc203-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc203-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc203-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc203-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc203-x86_64-unknown-linux-musl.tar.gz +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -76,6 +76,8 @@ export interface ProbeAgentOptions {
|
|
|
76
76
|
skillDirs?: string[];
|
|
77
77
|
/** Custom prompt to run after attempt_completion for validation/review (runs before mermaid/JSON validation) */
|
|
78
78
|
completionPrompt?: string;
|
|
79
|
+
/** Enable task management system for tracking multi-step progress */
|
|
80
|
+
enableTasks?: boolean;
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
/**
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
attemptCompletionSchema,
|
|
38
38
|
parseXmlToolCallWithThinking
|
|
39
39
|
} from './tools.js';
|
|
40
|
-
import { createMessagePreview } from '../tools/common.js';
|
|
40
|
+
import { createMessagePreview, detectUnrecognizedToolCall } from '../tools/common.js';
|
|
41
41
|
import {
|
|
42
42
|
createWrappedTools,
|
|
43
43
|
listFilesToolInstance,
|
|
@@ -69,6 +69,15 @@ import { createSkillToolInstances } from './skills/tools.js';
|
|
|
69
69
|
import { RetryManager, createRetryManagerFromEnv } from './RetryManager.js';
|
|
70
70
|
import { FallbackManager, createFallbackManagerFromEnv, buildFallbackProvidersFromEnv } from './FallbackManager.js';
|
|
71
71
|
import { handleContextLimitError } from './contextCompactor.js';
|
|
72
|
+
import { formatErrorForAI, ParameterError } from '../utils/error-types.js';
|
|
73
|
+
import {
|
|
74
|
+
TaskManager,
|
|
75
|
+
createTaskTool,
|
|
76
|
+
taskToolDefinition,
|
|
77
|
+
taskSystemPrompt,
|
|
78
|
+
taskGuidancePrompt,
|
|
79
|
+
createTaskCompletionBlockedMessage
|
|
80
|
+
} from './tasks/index.js';
|
|
72
81
|
|
|
73
82
|
// Maximum tool iterations to prevent infinite loops - configurable via MAX_TOOL_ITERATIONS env var
|
|
74
83
|
const MAX_TOOL_ITERATIONS = (() => {
|
|
@@ -118,6 +127,7 @@ export class ProbeAgent {
|
|
|
118
127
|
* @param {string} [options.mcpConfigPath] - Path to MCP configuration file
|
|
119
128
|
* @param {Object} [options.mcpConfig] - MCP configuration object (overrides mcpConfigPath)
|
|
120
129
|
* @param {Array} [options.mcpServers] - Deprecated, use mcpConfig instead
|
|
130
|
+
* @param {boolean} [options.enableTasks=false] - Enable task management system for tracking progress
|
|
121
131
|
* @param {Object} [options.storageAdapter] - Custom storage adapter for history management
|
|
122
132
|
* @param {Object} [options.hooks] - Hook callbacks for events (e.g., {'tool:start': callback})
|
|
123
133
|
* @param {Array<string>|null} [options.allowedTools] - List of allowed tool names. Use ['*'] for all tools (default), [] or null for no tools (raw AI mode), or specific tool names like ['search', 'query', 'extract']. Supports exclusion with '!' prefix (e.g., ['*', '!bash'])
|
|
@@ -255,6 +265,10 @@ export class ProbeAgent {
|
|
|
255
265
|
this.mcpBridge = null;
|
|
256
266
|
this._mcpInitialized = false; // Track if MCP initialization has been attempted
|
|
257
267
|
|
|
268
|
+
// Task management configuration
|
|
269
|
+
this.enableTasks = !!options.enableTasks;
|
|
270
|
+
this.taskManager = null; // Initialized per-request in answer()
|
|
271
|
+
|
|
258
272
|
// Retry configuration
|
|
259
273
|
this.retryConfig = options.retry || {};
|
|
260
274
|
this.retryManager = null; // Will be initialized lazily when needed
|
|
@@ -580,6 +594,9 @@ export class ProbeAgent {
|
|
|
580
594
|
// Store wrapped tools for ACP system
|
|
581
595
|
this.wrappedTools = wrappedTools;
|
|
582
596
|
|
|
597
|
+
// Note: Task tool is registered dynamically in answer() when enableTasks is true
|
|
598
|
+
// This is because TaskManager is created per-request (request-scoped)
|
|
599
|
+
|
|
583
600
|
// Log available tools in debug mode
|
|
584
601
|
if (this.debug) {
|
|
585
602
|
console.error('\n[DEBUG] ========================================');
|
|
@@ -1987,6 +2004,11 @@ ${extractGuidance}
|
|
|
1987
2004
|
toolDefinitions += `${bashToolDefinition}\n`;
|
|
1988
2005
|
}
|
|
1989
2006
|
|
|
2007
|
+
// Task tool (require both enableTasks flag AND allowedTools permission)
|
|
2008
|
+
if (this.enableTasks && isToolAllowed('task')) {
|
|
2009
|
+
toolDefinitions += `${taskToolDefinition}\n`;
|
|
2010
|
+
}
|
|
2011
|
+
|
|
1990
2012
|
// Always include attempt_completion (unless explicitly disabled in raw AI mode)
|
|
1991
2013
|
if (isToolAllowed('attempt_completion')) {
|
|
1992
2014
|
toolDefinitions += `${attemptCompletionToolDefinition}\n`;
|
|
@@ -1998,7 +2020,81 @@ ${extractGuidance}
|
|
|
1998
2020
|
toolDefinitions += `${delegateToolDefinition}\n`;
|
|
1999
2021
|
}
|
|
2000
2022
|
|
|
2001
|
-
// Build XML tool guidelines
|
|
2023
|
+
// Build XML tool guidelines with dynamic examples based on allowed tools
|
|
2024
|
+
// Build examples only for allowed tools
|
|
2025
|
+
let toolExamples = '';
|
|
2026
|
+
if (isToolAllowed('search')) {
|
|
2027
|
+
toolExamples += `
|
|
2028
|
+
<search>
|
|
2029
|
+
<query>error handling</query>
|
|
2030
|
+
<path>src/search</path>
|
|
2031
|
+
</search>
|
|
2032
|
+
`;
|
|
2033
|
+
}
|
|
2034
|
+
if (isToolAllowed('extract')) {
|
|
2035
|
+
toolExamples += `
|
|
2036
|
+
<extract>
|
|
2037
|
+
<targets>src/config.js:15-25</targets>
|
|
2038
|
+
</extract>
|
|
2039
|
+
`;
|
|
2040
|
+
}
|
|
2041
|
+
if (isToolAllowed('attempt_completion')) {
|
|
2042
|
+
toolExamples += `
|
|
2043
|
+
<attempt_completion>
|
|
2044
|
+
The configuration is loaded from src/config.js lines 15-25 which contains the database settings.
|
|
2045
|
+
</attempt_completion>
|
|
2046
|
+
`;
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
// Build available tools list dynamically based on allowedTools
|
|
2050
|
+
let availableToolsList = '';
|
|
2051
|
+
if (isToolAllowed('search')) {
|
|
2052
|
+
availableToolsList += `- search: Search code using keyword queries${this.searchDelegate ? ' (returns extracted code blocks via a dedicated subagent)' : ''}.\n`;
|
|
2053
|
+
}
|
|
2054
|
+
if (isToolAllowed('query')) {
|
|
2055
|
+
availableToolsList += '- query: Search code using structural AST patterns.\n';
|
|
2056
|
+
}
|
|
2057
|
+
if (isToolAllowed('extract')) {
|
|
2058
|
+
availableToolsList += '- extract: Extract specific code blocks or lines from files.\n';
|
|
2059
|
+
}
|
|
2060
|
+
if (isToolAllowed('listFiles')) {
|
|
2061
|
+
availableToolsList += '- listFiles: List files and directories in a specified location.\n';
|
|
2062
|
+
}
|
|
2063
|
+
if (isToolAllowed('searchFiles')) {
|
|
2064
|
+
availableToolsList += '- searchFiles: Find files matching a glob pattern with recursive search capability.\n';
|
|
2065
|
+
}
|
|
2066
|
+
if (this.enableSkills && isToolAllowed('listSkills')) {
|
|
2067
|
+
availableToolsList += '- listSkills: List available agent skills discovered in the repository.\n';
|
|
2068
|
+
}
|
|
2069
|
+
if (this.enableSkills && isToolAllowed('useSkill')) {
|
|
2070
|
+
availableToolsList += '- useSkill: Load and activate a specific skill\'s instructions.\n';
|
|
2071
|
+
}
|
|
2072
|
+
if (isToolAllowed('readImage')) {
|
|
2073
|
+
availableToolsList += '- readImage: Read and load an image file for AI analysis.\n';
|
|
2074
|
+
}
|
|
2075
|
+
if (this.allowEdit && isToolAllowed('implement')) {
|
|
2076
|
+
availableToolsList += '- implement: Implement a feature or fix a bug using aider.\n';
|
|
2077
|
+
}
|
|
2078
|
+
if (this.allowEdit && isToolAllowed('edit')) {
|
|
2079
|
+
availableToolsList += '- edit: Edit files using exact string replacement.\n';
|
|
2080
|
+
}
|
|
2081
|
+
if (this.allowEdit && isToolAllowed('create')) {
|
|
2082
|
+
availableToolsList += '- create: Create new files with specified content.\n';
|
|
2083
|
+
}
|
|
2084
|
+
if (this.enableDelegate && isToolAllowed('delegate')) {
|
|
2085
|
+
availableToolsList += '- delegate: Delegate big distinct tasks to specialized probe subagents.\n';
|
|
2086
|
+
}
|
|
2087
|
+
if (this.enableBash && isToolAllowed('bash')) {
|
|
2088
|
+
availableToolsList += '- bash: Execute bash commands for system operations.\n';
|
|
2089
|
+
}
|
|
2090
|
+
if (this.enableTasks && isToolAllowed('task')) {
|
|
2091
|
+
availableToolsList += '- task: Manage tasks for tracking progress (create, update, complete, delete, list).\n';
|
|
2092
|
+
}
|
|
2093
|
+
if (isToolAllowed('attempt_completion')) {
|
|
2094
|
+
availableToolsList += '- attempt_completion: Finalize the task and provide the result to the user.\n';
|
|
2095
|
+
availableToolsList += '- attempt_complete: Quick completion using previous response (shorthand).\n';
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2002
2098
|
let xmlToolGuidelines = `
|
|
2003
2099
|
# Tool Use Formatting
|
|
2004
2100
|
|
|
@@ -2013,20 +2109,7 @@ Structure (note the closing tags):
|
|
|
2013
2109
|
...
|
|
2014
2110
|
</tool_name>
|
|
2015
2111
|
|
|
2016
|
-
Examples
|
|
2017
|
-
<search>
|
|
2018
|
-
<query>error handling</query>
|
|
2019
|
-
<path>src/search</path>
|
|
2020
|
-
</search>
|
|
2021
|
-
|
|
2022
|
-
<extract>
|
|
2023
|
-
<targets>src/config.js:15-25</targets>
|
|
2024
|
-
</extract>
|
|
2025
|
-
|
|
2026
|
-
<attempt_completion>
|
|
2027
|
-
The configuration is loaded from src/config.js lines 15-25 which contains the database settings.
|
|
2028
|
-
</attempt_completion>
|
|
2029
|
-
|
|
2112
|
+
Examples:${toolExamples}
|
|
2030
2113
|
# Special Case: Quick Completion
|
|
2031
2114
|
If your previous response was already correct and complete, you may respond with just:
|
|
2032
2115
|
<attempt_complete>
|
|
@@ -2055,16 +2138,7 @@ I need to find code related to error handling in the search module. The most app
|
|
|
2055
2138
|
10. If your previous response was already correct and complete, you may use \`<attempt_complete>\` as a shorthand.
|
|
2056
2139
|
|
|
2057
2140
|
Available Tools:
|
|
2058
|
-
|
|
2059
|
-
- query: Search code using structural AST patterns.
|
|
2060
|
-
- extract: Extract specific code blocks or lines from files.
|
|
2061
|
-
- listFiles: List files and directories in a specified location.
|
|
2062
|
-
- searchFiles: Find files matching a glob pattern with recursive search capability.
|
|
2063
|
-
${this.enableSkills ? '- listSkills: List available agent skills discovered in the repository.\n- useSkill: Load and activate a specific skill\'s instructions.\n' : ''}- readImage: Read and load an image file for AI analysis.
|
|
2064
|
-
${this.allowEdit ? '- implement: Implement a feature or fix a bug using aider.\n- edit: Edit files using exact string replacement.\n- create: Create new files with specified content.\n' : ''}${this.enableDelegate ? '- delegate: Delegate big distinct tasks to specialized probe subagents.\n' : ''}${this.enableBash ? '- bash: Execute bash commands for system operations.\n' : ''}
|
|
2065
|
-
- attempt_completion: Finalize the task and provide the result to the user.
|
|
2066
|
-
- attempt_complete: Quick completion using previous response (shorthand).
|
|
2067
|
-
`;
|
|
2141
|
+
${availableToolsList}`;
|
|
2068
2142
|
|
|
2069
2143
|
// Common instructions
|
|
2070
2144
|
const commonInstructions = `<instructions>
|
|
@@ -2126,6 +2200,11 @@ Follow these instructions carefully:
|
|
|
2126
2200
|
}
|
|
2127
2201
|
}
|
|
2128
2202
|
|
|
2203
|
+
// Add task management system prompt if enabled
|
|
2204
|
+
if (this.enableTasks) {
|
|
2205
|
+
systemMessage += `\n${taskSystemPrompt}\n`;
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2129
2208
|
// Add MCP tools if available (filtered by allowedTools)
|
|
2130
2209
|
if (this.mcpBridge && this.mcpBridge.getToolNames().length > 0) {
|
|
2131
2210
|
const allMcpTools = this.mcpBridge.getToolNames();
|
|
@@ -2199,6 +2278,39 @@ Follow these instructions carefully:
|
|
|
2199
2278
|
// Track initial history length for storage
|
|
2200
2279
|
const oldHistoryLength = this.history.length;
|
|
2201
2280
|
|
|
2281
|
+
// START CHECKPOINT: Initialize task management for this request
|
|
2282
|
+
if (this.enableTasks) {
|
|
2283
|
+
try {
|
|
2284
|
+
// Create fresh TaskManager for each request (request-scoped)
|
|
2285
|
+
this.taskManager = new TaskManager({ debug: this.debug });
|
|
2286
|
+
|
|
2287
|
+
// Register task tool for this request
|
|
2288
|
+
const isToolAllowed = (toolName) => this.allowedTools.isEnabled(toolName);
|
|
2289
|
+
if (isToolAllowed('task')) {
|
|
2290
|
+
this.toolImplementations.task = createTaskTool({
|
|
2291
|
+
taskManager: this.taskManager,
|
|
2292
|
+
tracer: this.tracer,
|
|
2293
|
+
debug: this.debug
|
|
2294
|
+
});
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
// Record telemetry for task initialization
|
|
2298
|
+
if (this.tracer && typeof this.tracer.recordTaskEvent === 'function') {
|
|
2299
|
+
this.tracer.recordTaskEvent('session_started', {
|
|
2300
|
+
'task.enabled': true
|
|
2301
|
+
});
|
|
2302
|
+
}
|
|
2303
|
+
|
|
2304
|
+
if (this.debug) {
|
|
2305
|
+
console.log('[DEBUG] Task management initialized for this request');
|
|
2306
|
+
}
|
|
2307
|
+
} catch (taskInitError) {
|
|
2308
|
+
// Log error but don't fail the request - task management is optional
|
|
2309
|
+
console.error('[ProbeAgent] Failed to initialize task management:', taskInitError.message);
|
|
2310
|
+
this.taskManager = null;
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2202
2314
|
// Emit user message hook
|
|
2203
2315
|
await this.hooks.emit(HOOK_TYPES.MESSAGE_USER, {
|
|
2204
2316
|
sessionId: this.sessionId,
|
|
@@ -2212,6 +2324,14 @@ Follow these instructions carefully:
|
|
|
2212
2324
|
// Create user message with optional image support
|
|
2213
2325
|
let userMessage = { role: 'user', content: message.trim() };
|
|
2214
2326
|
|
|
2327
|
+
// START CHECKPOINT: Inject task guidance if tasks are enabled
|
|
2328
|
+
if (this.enableTasks) {
|
|
2329
|
+
userMessage.content = userMessage.content + '\n\n' + taskGuidancePrompt;
|
|
2330
|
+
if (this.debug) {
|
|
2331
|
+
console.log('[DEBUG] Task guidance injected into user message');
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2215
2335
|
// If schema is provided, prepend JSON format requirement to user message
|
|
2216
2336
|
if (options.schema && !options._schemaFormatted) {
|
|
2217
2337
|
const schemaInstructions = generateSchemaInstructions(options.schema, { debug: this.debug });
|
|
@@ -2518,9 +2638,16 @@ Follow these instructions carefully:
|
|
|
2518
2638
|
};
|
|
2519
2639
|
|
|
2520
2640
|
if (this.tracer) {
|
|
2641
|
+
// Prepare input preview for tracing (truncate if very long)
|
|
2642
|
+
const inputPreview = message.length > 1000
|
|
2643
|
+
? message.substring(0, 1000) + '... [truncated]'
|
|
2644
|
+
: message;
|
|
2645
|
+
|
|
2521
2646
|
await this.tracer.withSpan('ai.request', executeAIRequest, {
|
|
2522
2647
|
'ai.model': this.model,
|
|
2523
2648
|
'ai.provider': this.clientApiProvider || 'auto',
|
|
2649
|
+
'ai.input': inputPreview,
|
|
2650
|
+
'ai.input_length': message.length,
|
|
2524
2651
|
'iteration': currentIteration,
|
|
2525
2652
|
'max_tokens': maxResponseTokens,
|
|
2526
2653
|
'temperature': 0.3,
|
|
@@ -2638,6 +2765,10 @@ Follow these instructions carefully:
|
|
|
2638
2765
|
if (this.enableDelegate && this.allowedTools.isEnabled('delegate')) {
|
|
2639
2766
|
validTools.push('delegate');
|
|
2640
2767
|
}
|
|
2768
|
+
// Task tool (require both enableTasks flag AND allowedTools permission)
|
|
2769
|
+
if (this.enableTasks && this.allowedTools.isEnabled('task')) {
|
|
2770
|
+
validTools.push('task');
|
|
2771
|
+
}
|
|
2641
2772
|
}
|
|
2642
2773
|
|
|
2643
2774
|
// Try parsing with hybrid parser that supports both native and MCP tools
|
|
@@ -2653,6 +2784,40 @@ Follow these instructions carefully:
|
|
|
2653
2784
|
if (toolName === 'attempt_completion') {
|
|
2654
2785
|
completionAttempted = true;
|
|
2655
2786
|
|
|
2787
|
+
// END CHECKPOINT: Block completion if there are incomplete tasks
|
|
2788
|
+
if (this.enableTasks && this.taskManager && this.taskManager.hasIncompleteTasks()) {
|
|
2789
|
+
const taskSummary = this.taskManager.getTaskSummary();
|
|
2790
|
+
const blockedMessage = createTaskCompletionBlockedMessage(taskSummary);
|
|
2791
|
+
const incompleteTasks = this.taskManager.getIncompleteTasks();
|
|
2792
|
+
|
|
2793
|
+
// Record telemetry for blocked completion
|
|
2794
|
+
if (this.tracer && typeof this.tracer.recordTaskEvent === 'function') {
|
|
2795
|
+
this.tracer.recordTaskEvent('completion_blocked', {
|
|
2796
|
+
'task.incomplete_count': incompleteTasks.length,
|
|
2797
|
+
'task.incomplete_ids': incompleteTasks.map(t => t.id).join(', '),
|
|
2798
|
+
'task.iteration': currentIteration
|
|
2799
|
+
});
|
|
2800
|
+
}
|
|
2801
|
+
|
|
2802
|
+
if (this.debug) {
|
|
2803
|
+
console.log('[DEBUG] Task checkpoint: Blocking completion due to incomplete tasks');
|
|
2804
|
+
console.log('[DEBUG] Incomplete tasks:', taskSummary);
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2807
|
+
// Add reminder message and continue the loop
|
|
2808
|
+
currentMessages.push({
|
|
2809
|
+
role: 'assistant',
|
|
2810
|
+
content: assistantResponseContent
|
|
2811
|
+
});
|
|
2812
|
+
currentMessages.push({
|
|
2813
|
+
role: 'user',
|
|
2814
|
+
content: blockedMessage
|
|
2815
|
+
});
|
|
2816
|
+
|
|
2817
|
+
completionAttempted = false; // Reset to allow more iterations
|
|
2818
|
+
continue; // Skip the break and continue the loop
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2656
2821
|
// Handle attempt_complete shorthand - use previous response
|
|
2657
2822
|
if (params.result === '__PREVIOUS_RESPONSE__') {
|
|
2658
2823
|
// Find the last assistant message with actual content (not tool calls)
|
|
@@ -2732,7 +2897,6 @@ Follow these instructions carefully:
|
|
|
2732
2897
|
currentMessages.push({ role: 'user', content: `<tool_result>\n${toolResultContent}\n</tool_result>` });
|
|
2733
2898
|
} catch (error) {
|
|
2734
2899
|
console.error(`Error executing MCP tool ${toolName}:`, error);
|
|
2735
|
-
const toolResultContent = `Error executing MCP tool ${toolName}: ${error.message}`;
|
|
2736
2900
|
|
|
2737
2901
|
// Log MCP tool error in debug mode
|
|
2738
2902
|
if (this.debug) {
|
|
@@ -2742,7 +2906,9 @@ Follow these instructions carefully:
|
|
|
2742
2906
|
console.error(`[DEBUG] ========================================\n`);
|
|
2743
2907
|
}
|
|
2744
2908
|
|
|
2745
|
-
|
|
2909
|
+
// Format error with structured information for AI
|
|
2910
|
+
const errorXml = formatErrorForAI(error);
|
|
2911
|
+
currentMessages.push({ role: 'user', content: `<tool_result>\n${errorXml}\n</tool_result>` });
|
|
2746
2912
|
}
|
|
2747
2913
|
} else if (this.toolImplementations[toolName]) {
|
|
2748
2914
|
// Execute native tool
|
|
@@ -2810,6 +2976,7 @@ Follow these instructions carefully:
|
|
|
2810
2976
|
provider: this.apiType, // Inherit AI provider (string identifier)
|
|
2811
2977
|
model: this.model, // Inherit model
|
|
2812
2978
|
searchDelegate: this.searchDelegate,
|
|
2979
|
+
enableTasks: this.enableTasks, // Inherit task management (subagent gets isolated TaskManager)
|
|
2813
2980
|
debug: this.debug,
|
|
2814
2981
|
tracer: this.tracer
|
|
2815
2982
|
};
|
|
@@ -2912,9 +3079,11 @@ Follow these instructions carefully:
|
|
|
2912
3079
|
} catch (error) {
|
|
2913
3080
|
console.error(`[ERROR] Tool execution failed for ${toolName}:`, error);
|
|
2914
3081
|
currentMessages.push({ role: 'assistant', content: assistantResponseContent });
|
|
3082
|
+
// Format error with structured information for AI
|
|
3083
|
+
const errorXml = formatErrorForAI(error);
|
|
2915
3084
|
currentMessages.push({
|
|
2916
|
-
role: 'user',
|
|
2917
|
-
content: `<tool_result>\
|
|
3085
|
+
role: 'user',
|
|
3086
|
+
content: `<tool_result>\n${errorXml}\n</tool_result>`
|
|
2918
3087
|
});
|
|
2919
3088
|
}
|
|
2920
3089
|
} else {
|
|
@@ -2928,7 +3097,7 @@ Follow these instructions carefully:
|
|
|
2928
3097
|
|
|
2929
3098
|
currentMessages.push({
|
|
2930
3099
|
role: 'user',
|
|
2931
|
-
content: `<tool_result>\
|
|
3100
|
+
content: `<tool_result>\n<error type="parameter_error" recoverable="true">\n<message>Unknown tool '${toolName}'</message>\n<suggestion>Available tools: ${allAvailableTools.join(', ')}. Please use one of these tools.</suggestion>\n</error>\n</tool_result>`
|
|
2932
3101
|
});
|
|
2933
3102
|
}
|
|
2934
3103
|
}
|
|
@@ -2952,8 +3121,22 @@ Follow these instructions carefully:
|
|
|
2952
3121
|
// Add assistant response and ask for tool usage
|
|
2953
3122
|
currentMessages.push({ role: 'assistant', content: assistantResponseContent });
|
|
2954
3123
|
|
|
2955
|
-
//
|
|
2956
|
-
const
|
|
3124
|
+
// Check if the AI tried to use a tool that's not in the valid tools list
|
|
3125
|
+
const unrecognizedTool = detectUnrecognizedToolCall(assistantResponseContent, validTools);
|
|
3126
|
+
|
|
3127
|
+
let reminderContent;
|
|
3128
|
+
if (unrecognizedTool) {
|
|
3129
|
+
// AI tried to use a tool that's not available - provide clear error
|
|
3130
|
+
if (this.debug) {
|
|
3131
|
+
console.log(`[DEBUG] Detected unrecognized tool '${unrecognizedTool}' in assistant response.`);
|
|
3132
|
+
}
|
|
3133
|
+
const toolError = new ParameterError(`Tool '${unrecognizedTool}' is not available in this context.`, {
|
|
3134
|
+
suggestion: `Available tools: ${validTools.join(', ')}. Please use one of these tools instead.`
|
|
3135
|
+
});
|
|
3136
|
+
reminderContent = `<tool_result>\n${formatErrorForAI(toolError)}\n</tool_result>`;
|
|
3137
|
+
} else {
|
|
3138
|
+
// Standard reminder - no tool call detected at all
|
|
3139
|
+
reminderContent = `Please use one of the available tools to help answer the question, or use attempt_completion if you have enough information to provide a final answer.
|
|
2957
3140
|
|
|
2958
3141
|
Remember: Use proper XML format with BOTH opening and closing tags:
|
|
2959
3142
|
|
|
@@ -2961,17 +3144,27 @@ Remember: Use proper XML format with BOTH opening and closing tags:
|
|
|
2961
3144
|
<parameter>value</parameter>
|
|
2962
3145
|
</tool_name>
|
|
2963
3146
|
|
|
2964
|
-
|
|
2965
|
-
<attempt_complete>
|
|
3147
|
+
Available tools: ${validTools.join(', ')}
|
|
2966
3148
|
|
|
2967
|
-
|
|
3149
|
+
To complete with a direct answer:
|
|
3150
|
+
<attempt_completion>Your final answer here</attempt_completion>
|
|
3151
|
+
|
|
3152
|
+
Or if your previous response already contains a complete, direct answer (not a thinking block or JSON):
|
|
3153
|
+
<attempt_complete></attempt_complete>
|
|
3154
|
+
|
|
3155
|
+
Note: <attempt_complete></attempt_complete> reuses your PREVIOUS assistant message as the final answer. Only use this if that message was already a valid, complete response to the user's question.`;
|
|
3156
|
+
}
|
|
2968
3157
|
|
|
2969
3158
|
currentMessages.push({
|
|
2970
3159
|
role: 'user',
|
|
2971
3160
|
content: reminderContent
|
|
2972
3161
|
});
|
|
2973
3162
|
if (this.debug) {
|
|
2974
|
-
|
|
3163
|
+
if (unrecognizedTool) {
|
|
3164
|
+
console.log(`[DEBUG] Unrecognized tool '${unrecognizedTool}' used. Providing error feedback.`);
|
|
3165
|
+
} else {
|
|
3166
|
+
console.log(`[DEBUG] No tool call detected in assistant response. Prompting for tool use.`);
|
|
3167
|
+
}
|
|
2975
3168
|
}
|
|
2976
3169
|
}
|
|
2977
3170
|
|
|
@@ -3872,9 +4065,9 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
3872
4065
|
return true;
|
|
3873
4066
|
}
|
|
3874
4067
|
|
|
3875
|
-
// Empty attempt_complete reminders
|
|
3876
|
-
if (content.includes('
|
|
3877
|
-
content.includes('
|
|
4068
|
+
// Empty attempt_complete reminders (legacy and new format)
|
|
4069
|
+
if (content.includes('<attempt_complete></attempt_complete>') &&
|
|
4070
|
+
content.includes('reuses your PREVIOUS assistant message')) {
|
|
3878
4071
|
return true;
|
|
3879
4072
|
}
|
|
3880
4073
|
|