@probelabs/probe 0.6.0-rc154 → 0.6.0-rc161
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/README.md +80 -1
- package/build/agent/FallbackManager.d.ts +176 -0
- package/build/agent/FallbackManager.js +545 -0
- package/build/agent/ProbeAgent.d.ts +9 -1
- package/build/agent/ProbeAgent.js +218 -10
- package/build/agent/RetryManager.d.ts +157 -0
- package/build/agent/RetryManager.js +334 -0
- package/build/agent/acp/server.js +1 -0
- package/build/agent/acp/tools.js +6 -2
- package/build/agent/index.js +1814 -355
- package/build/agent/probeTool.js +20 -2
- package/build/agent/tools.js +16 -0
- package/build/delegate.js +326 -201
- package/build/downloader.js +46 -17
- package/build/extractor.js +12 -12
- package/build/index.js +13 -0
- package/build/tools/common.js +5 -3
- package/build/tools/edit.js +409 -0
- package/build/tools/index.js +11 -0
- package/build/tools/vercel.js +55 -14
- package/build/utils.js +18 -9
- package/cjs/agent/ProbeAgent.cjs +2268 -699
- package/cjs/index.cjs +75902 -74348
- package/package.json +2 -2
- package/src/agent/FallbackManager.d.ts +176 -0
- package/src/agent/FallbackManager.js +545 -0
- package/src/agent/ProbeAgent.d.ts +9 -1
- package/src/agent/ProbeAgent.js +218 -10
- package/src/agent/RetryManager.d.ts +157 -0
- package/src/agent/RetryManager.js +334 -0
- package/src/agent/acp/server.js +1 -0
- package/src/agent/acp/tools.js +6 -2
- package/src/agent/index.js +8 -0
- package/src/agent/probeTool.js +20 -2
- package/src/agent/tools.js +16 -0
- package/src/delegate.js +326 -201
- package/src/downloader.js +46 -17
- package/src/extractor.js +12 -12
- package/src/index.js +13 -0
- package/src/tools/common.js +5 -3
- package/src/tools/edit.js +409 -0
- package/src/tools/index.js +11 -0
- package/src/tools/vercel.js +55 -14
- package/src/utils.js +18 -9
- package/bin/binaries/probe-v0.6.0-rc154-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc154-aarch64-unknown-linux-gnu.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc154-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc154-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc154-x86_64-unknown-linux-gnu.tar.gz +0 -0
|
@@ -18,15 +18,19 @@ import { TokenCounter } from './tokenCounter.js';
|
|
|
18
18
|
import { InMemoryStorageAdapter } from './storage/InMemoryStorageAdapter.js';
|
|
19
19
|
import { HookManager, HOOK_TYPES } from './hooks/HookManager.js';
|
|
20
20
|
import { SUPPORTED_IMAGE_EXTENSIONS, IMAGE_MIME_TYPES } from './imageConfig.js';
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
22
|
createTools,
|
|
23
23
|
searchToolDefinition,
|
|
24
24
|
queryToolDefinition,
|
|
25
25
|
extractToolDefinition,
|
|
26
|
+
delegateToolDefinition,
|
|
27
|
+
bashToolDefinition,
|
|
26
28
|
listFilesToolDefinition,
|
|
27
29
|
searchFilesToolDefinition,
|
|
28
30
|
attemptCompletionToolDefinition,
|
|
29
31
|
implementToolDefinition,
|
|
32
|
+
editToolDefinition,
|
|
33
|
+
createToolDefinition,
|
|
30
34
|
attemptCompletionSchema,
|
|
31
35
|
parseXmlToolCallWithThinking
|
|
32
36
|
} from './tools.js';
|
|
@@ -54,9 +58,18 @@ import {
|
|
|
54
58
|
parseHybridXmlToolCall,
|
|
55
59
|
loadMCPConfigurationFromPath
|
|
56
60
|
} from './mcp/index.js';
|
|
61
|
+
import { RetryManager, createRetryManagerFromEnv } from './RetryManager.js';
|
|
62
|
+
import { FallbackManager, createFallbackManagerFromEnv, buildFallbackProvidersFromEnv } from './FallbackManager.js';
|
|
57
63
|
|
|
58
64
|
// Maximum tool iterations to prevent infinite loops - configurable via MAX_TOOL_ITERATIONS env var
|
|
59
|
-
const MAX_TOOL_ITERATIONS =
|
|
65
|
+
const MAX_TOOL_ITERATIONS = (() => {
|
|
66
|
+
const val = parseInt(process.env.MAX_TOOL_ITERATIONS || '30', 10);
|
|
67
|
+
if (isNaN(val) || val < 1 || val > 200) {
|
|
68
|
+
console.warn('[ProbeAgent] MAX_TOOL_ITERATIONS must be between 1 and 200, using default: 30');
|
|
69
|
+
return 30;
|
|
70
|
+
}
|
|
71
|
+
return val;
|
|
72
|
+
})();
|
|
60
73
|
const MAX_HISTORY_MESSAGES = 100;
|
|
61
74
|
|
|
62
75
|
// Supported image file extensions (imported from shared config)
|
|
@@ -75,6 +88,7 @@ export class ProbeAgent {
|
|
|
75
88
|
* @param {string} [options.customPrompt] - Custom prompt to replace the default system message
|
|
76
89
|
* @param {string} [options.promptType] - Predefined prompt type (architect, code-review, support)
|
|
77
90
|
* @param {boolean} [options.allowEdit=false] - Allow the use of the 'implement' tool
|
|
91
|
+
* @param {boolean} [options.enableDelegate=false] - Enable the delegate tool for task distribution to subagents
|
|
78
92
|
* @param {string} [options.path] - Search directory path
|
|
79
93
|
* @param {string} [options.provider] - Force specific AI provider
|
|
80
94
|
* @param {string} [options.model] - Override model name
|
|
@@ -90,6 +104,18 @@ export class ProbeAgent {
|
|
|
90
104
|
* @param {Array} [options.mcpServers] - Deprecated, use mcpConfig instead
|
|
91
105
|
* @param {Object} [options.storageAdapter] - Custom storage adapter for history management
|
|
92
106
|
* @param {Object} [options.hooks] - Hook callbacks for events (e.g., {'tool:start': callback})
|
|
107
|
+
* @param {Object} [options.retry] - Retry configuration
|
|
108
|
+
* @param {number} [options.retry.maxRetries=3] - Maximum retry attempts per provider
|
|
109
|
+
* @param {number} [options.retry.initialDelay=1000] - Initial delay in ms
|
|
110
|
+
* @param {number} [options.retry.maxDelay=30000] - Maximum delay in ms
|
|
111
|
+
* @param {number} [options.retry.backoffFactor=2] - Exponential backoff multiplier
|
|
112
|
+
* @param {Array<string>} [options.retry.retryableErrors] - List of retryable error patterns
|
|
113
|
+
* @param {Object} [options.fallback] - Fallback configuration
|
|
114
|
+
* @param {string} [options.fallback.strategy] - Fallback strategy: 'same-model', 'same-provider', 'any', 'custom'
|
|
115
|
+
* @param {Array<string>} [options.fallback.models] - List of models for same-provider fallback
|
|
116
|
+
* @param {Array<Object>} [options.fallback.providers] - List of provider configurations for custom fallback
|
|
117
|
+
* @param {boolean} [options.fallback.stopOnSuccess=true] - Stop on first success
|
|
118
|
+
* @param {number} [options.fallback.maxTotalAttempts=10] - Maximum total attempts across all providers
|
|
93
119
|
*/
|
|
94
120
|
constructor(options = {}) {
|
|
95
121
|
// Basic configuration
|
|
@@ -97,11 +123,18 @@ export class ProbeAgent {
|
|
|
97
123
|
this.customPrompt = options.customPrompt || null;
|
|
98
124
|
this.promptType = options.promptType || 'code-explorer';
|
|
99
125
|
this.allowEdit = !!options.allowEdit;
|
|
126
|
+
this.enableDelegate = !!options.enableDelegate;
|
|
100
127
|
this.debug = options.debug || process.env.DEBUG === '1';
|
|
101
128
|
this.cancelled = false;
|
|
102
129
|
this.tracer = options.tracer || null;
|
|
103
130
|
this.outline = !!options.outline;
|
|
104
|
-
this.maxResponseTokens = options.maxResponseTokens ||
|
|
131
|
+
this.maxResponseTokens = options.maxResponseTokens || (() => {
|
|
132
|
+
const val = parseInt(process.env.MAX_RESPONSE_TOKENS || '0', 10);
|
|
133
|
+
if (isNaN(val) || val < 0 || val > 200000) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return val || null;
|
|
137
|
+
})();
|
|
105
138
|
this.maxIterations = options.maxIterations || null;
|
|
106
139
|
this.disableMermaidValidation = !!options.disableMermaidValidation;
|
|
107
140
|
this.disableJsonValidation = !!options.disableJsonValidation;
|
|
@@ -168,6 +201,14 @@ export class ProbeAgent {
|
|
|
168
201
|
this.mcpBridge = null;
|
|
169
202
|
this._mcpInitialized = false; // Track if MCP initialization has been attempted
|
|
170
203
|
|
|
204
|
+
// Retry configuration
|
|
205
|
+
this.retryConfig = options.retry || {};
|
|
206
|
+
this.retryManager = null; // Will be initialized lazily when needed
|
|
207
|
+
|
|
208
|
+
// Fallback configuration
|
|
209
|
+
this.fallbackConfig = options.fallback || null;
|
|
210
|
+
this.fallbackManager = null; // Will be initialized in initializeModel
|
|
211
|
+
|
|
171
212
|
// Initialize the AI model
|
|
172
213
|
this.initializeModel();
|
|
173
214
|
|
|
@@ -281,6 +322,16 @@ export class ProbeAgent {
|
|
|
281
322
|
this.toolImplementations.bash = wrappedTools.bashToolInstance;
|
|
282
323
|
}
|
|
283
324
|
|
|
325
|
+
// Add edit and create tools if enabled
|
|
326
|
+
if (this.allowEdit) {
|
|
327
|
+
if (wrappedTools.editToolInstance) {
|
|
328
|
+
this.toolImplementations.edit = wrappedTools.editToolInstance;
|
|
329
|
+
}
|
|
330
|
+
if (wrappedTools.createToolInstance) {
|
|
331
|
+
this.toolImplementations.create = wrappedTools.createToolInstance;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
284
335
|
// Store wrapped tools for ACP system
|
|
285
336
|
this.wrappedTools = wrappedTools;
|
|
286
337
|
|
|
@@ -349,15 +400,19 @@ export class ProbeAgent {
|
|
|
349
400
|
if (forceProvider) {
|
|
350
401
|
if (forceProvider === 'anthropic' && anthropicApiKey) {
|
|
351
402
|
this.initializeAnthropicModel(anthropicApiKey, anthropicApiUrl, modelName);
|
|
403
|
+
this.initializeFallbackManager(forceProvider, modelName);
|
|
352
404
|
return;
|
|
353
405
|
} else if (forceProvider === 'openai' && openaiApiKey) {
|
|
354
406
|
this.initializeOpenAIModel(openaiApiKey, openaiApiUrl, modelName);
|
|
407
|
+
this.initializeFallbackManager(forceProvider, modelName);
|
|
355
408
|
return;
|
|
356
409
|
} else if (forceProvider === 'google' && googleApiKey) {
|
|
357
410
|
this.initializeGoogleModel(googleApiKey, googleApiUrl, modelName);
|
|
411
|
+
this.initializeFallbackManager(forceProvider, modelName);
|
|
358
412
|
return;
|
|
359
413
|
} else if (forceProvider === 'bedrock' && ((awsAccessKeyId && awsSecretAccessKey && awsRegion) || awsApiKey)) {
|
|
360
414
|
this.initializeBedrockModel(awsAccessKeyId, awsSecretAccessKey, awsRegion, awsSessionToken, awsApiKey, awsBedrockBaseUrl, modelName);
|
|
415
|
+
this.initializeFallbackManager(forceProvider, modelName);
|
|
361
416
|
return;
|
|
362
417
|
}
|
|
363
418
|
console.warn(`WARNING: Forced provider "${forceProvider}" selected but required API key is missing or invalid! Falling back to auto-detection.`);
|
|
@@ -366,17 +421,146 @@ export class ProbeAgent {
|
|
|
366
421
|
// If no provider is forced or forced provider failed, use the first available API key
|
|
367
422
|
if (anthropicApiKey) {
|
|
368
423
|
this.initializeAnthropicModel(anthropicApiKey, anthropicApiUrl, modelName);
|
|
424
|
+
this.initializeFallbackManager('anthropic', modelName);
|
|
369
425
|
} else if (openaiApiKey) {
|
|
370
426
|
this.initializeOpenAIModel(openaiApiKey, openaiApiUrl, modelName);
|
|
427
|
+
this.initializeFallbackManager('openai', modelName);
|
|
371
428
|
} else if (googleApiKey) {
|
|
372
429
|
this.initializeGoogleModel(googleApiKey, googleApiUrl, modelName);
|
|
430
|
+
this.initializeFallbackManager('google', modelName);
|
|
373
431
|
} else if ((awsAccessKeyId && awsSecretAccessKey && awsRegion) || awsApiKey) {
|
|
374
432
|
this.initializeBedrockModel(awsAccessKeyId, awsSecretAccessKey, awsRegion, awsSessionToken, awsApiKey, awsBedrockBaseUrl, modelName);
|
|
433
|
+
this.initializeFallbackManager('bedrock', modelName);
|
|
375
434
|
} else {
|
|
376
435
|
throw new Error('No API key provided. Please set ANTHROPIC_API_KEY (or ANTHROPIC_AUTH_TOKEN), OPENAI_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY (or GOOGLE_API_KEY), AWS credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION), or AWS_BEDROCK_API_KEY environment variables.');
|
|
377
436
|
}
|
|
378
437
|
}
|
|
379
438
|
|
|
439
|
+
/**
|
|
440
|
+
* Initialize fallback manager based on configuration
|
|
441
|
+
* @param {string} primaryProvider - The primary provider being used
|
|
442
|
+
* @param {string} primaryModel - The primary model being used
|
|
443
|
+
* @private
|
|
444
|
+
*/
|
|
445
|
+
initializeFallbackManager(primaryProvider, primaryModel) {
|
|
446
|
+
// Skip fallback initialization if explicitly disabled or in test mode
|
|
447
|
+
if (this.fallbackConfig === false || process.env.DISABLE_FALLBACK === '1') {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// If fallback config is provided explicitly, use it
|
|
452
|
+
if (this.fallbackConfig && this.fallbackConfig.providers) {
|
|
453
|
+
try {
|
|
454
|
+
this.fallbackManager = new FallbackManager({
|
|
455
|
+
...this.fallbackConfig,
|
|
456
|
+
debug: this.debug
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
if (this.debug) {
|
|
460
|
+
console.log(`[DEBUG] Fallback manager initialized with ${this.fallbackManager.providers.length} providers`);
|
|
461
|
+
}
|
|
462
|
+
} catch (error) {
|
|
463
|
+
console.error('[WARNING] Failed to initialize fallback manager:', error.message);
|
|
464
|
+
}
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Try to load from environment variables
|
|
469
|
+
const envFallbackManager = createFallbackManagerFromEnv(this.debug);
|
|
470
|
+
if (envFallbackManager) {
|
|
471
|
+
this.fallbackManager = envFallbackManager;
|
|
472
|
+
if (this.debug) {
|
|
473
|
+
console.log(`[DEBUG] Fallback manager initialized from environment variables`);
|
|
474
|
+
}
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Auto-build fallback from available providers if enabled
|
|
479
|
+
if (process.env.AUTO_FALLBACK === '1' || this.fallbackConfig?.auto) {
|
|
480
|
+
const providers = buildFallbackProvidersFromEnv({
|
|
481
|
+
primaryProvider,
|
|
482
|
+
primaryModel
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
if (providers.length > 1) {
|
|
486
|
+
try {
|
|
487
|
+
this.fallbackManager = new FallbackManager({
|
|
488
|
+
strategy: 'custom',
|
|
489
|
+
providers,
|
|
490
|
+
debug: this.debug
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
if (this.debug) {
|
|
494
|
+
console.log(`[DEBUG] Auto-fallback enabled with ${providers.length} providers`);
|
|
495
|
+
}
|
|
496
|
+
} catch (error) {
|
|
497
|
+
console.error('[WARNING] Failed to initialize auto-fallback:', error.message);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Execute streamText with retry and fallback support
|
|
505
|
+
* @param {Object} options - streamText options
|
|
506
|
+
* @returns {Promise<Object>} - streamText result
|
|
507
|
+
* @private
|
|
508
|
+
*/
|
|
509
|
+
async streamTextWithRetryAndFallback(options) {
|
|
510
|
+
// Initialize retry manager if not already created
|
|
511
|
+
if (!this.retryManager) {
|
|
512
|
+
this.retryManager = new RetryManager({
|
|
513
|
+
maxRetries: this.retryConfig.maxRetries ?? 3,
|
|
514
|
+
initialDelay: this.retryConfig.initialDelay ?? 1000,
|
|
515
|
+
maxDelay: this.retryConfig.maxDelay ?? 30000,
|
|
516
|
+
backoffFactor: this.retryConfig.backoffFactor ?? 2,
|
|
517
|
+
retryableErrors: this.retryConfig.retryableErrors,
|
|
518
|
+
debug: this.debug
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// If no fallback manager, just use retry with current provider
|
|
523
|
+
if (!this.fallbackManager) {
|
|
524
|
+
return await this.retryManager.executeWithRetry(
|
|
525
|
+
() => streamText(options),
|
|
526
|
+
{
|
|
527
|
+
provider: this.apiType,
|
|
528
|
+
model: this.model
|
|
529
|
+
}
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Use fallback manager with retry for each provider
|
|
534
|
+
return await this.fallbackManager.executeWithFallback(
|
|
535
|
+
async (provider, model, config) => {
|
|
536
|
+
// Create options with the fallback provider
|
|
537
|
+
const fallbackOptions = {
|
|
538
|
+
...options,
|
|
539
|
+
model: provider(model)
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
// Create a retry manager for this specific provider
|
|
543
|
+
const providerRetryManager = new RetryManager({
|
|
544
|
+
maxRetries: config.maxRetries ?? this.retryConfig.maxRetries ?? 3,
|
|
545
|
+
initialDelay: this.retryConfig.initialDelay ?? 1000,
|
|
546
|
+
maxDelay: this.retryConfig.maxDelay ?? 30000,
|
|
547
|
+
backoffFactor: this.retryConfig.backoffFactor ?? 2,
|
|
548
|
+
retryableErrors: this.retryConfig.retryableErrors,
|
|
549
|
+
debug: this.debug
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
// Execute with retry for this provider
|
|
553
|
+
return await providerRetryManager.executeWithRetry(
|
|
554
|
+
() => streamText(fallbackOptions),
|
|
555
|
+
{
|
|
556
|
+
provider: config.provider,
|
|
557
|
+
model: model
|
|
558
|
+
}
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
|
|
380
564
|
/**
|
|
381
565
|
* Initialize Anthropic model
|
|
382
566
|
*/
|
|
@@ -888,6 +1072,14 @@ ${attemptCompletionToolDefinition}
|
|
|
888
1072
|
`;
|
|
889
1073
|
if (this.allowEdit) {
|
|
890
1074
|
toolDefinitions += `${implementToolDefinition}\n`;
|
|
1075
|
+
toolDefinitions += `${editToolDefinition}\n`;
|
|
1076
|
+
toolDefinitions += `${createToolDefinition}\n`;
|
|
1077
|
+
}
|
|
1078
|
+
if (this.enableBash) {
|
|
1079
|
+
toolDefinitions += `${bashToolDefinition}\n`;
|
|
1080
|
+
}
|
|
1081
|
+
if (this.enableDelegate) {
|
|
1082
|
+
toolDefinitions += `${delegateToolDefinition}\n`;
|
|
891
1083
|
}
|
|
892
1084
|
|
|
893
1085
|
// Build XML tool guidelines
|
|
@@ -952,7 +1144,7 @@ Available Tools:
|
|
|
952
1144
|
- extract: Extract specific code blocks or lines from files.
|
|
953
1145
|
- listFiles: List files and directories in a specified location.
|
|
954
1146
|
- searchFiles: Find files matching a glob pattern with recursive search capability.
|
|
955
|
-
${this.allowEdit ? '- implement: Implement a feature or fix a bug using aider.\n' : ''}
|
|
1147
|
+
${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' : ''}
|
|
956
1148
|
- attempt_completion: Finalize the task and provide the result to the user.
|
|
957
1149
|
- attempt_complete: Quick completion using previous response (shorthand).
|
|
958
1150
|
`;
|
|
@@ -968,7 +1160,10 @@ Follow these instructions carefully:
|
|
|
968
1160
|
6. You MUST respond with exactly ONE tool call per message, using the specified XML format, until the task is complete.
|
|
969
1161
|
7. Wait for the tool execution result (provided in the next user message in a <tool_result> block) before proceeding to the next step.
|
|
970
1162
|
8. Once the task is fully completed, use the '<attempt_completion>' tool to provide the final result. This is the ONLY way to signal completion.
|
|
971
|
-
9. Prefer concise and focused search queries. Use specific keywords and phrases to narrow down results.
|
|
1163
|
+
9. Prefer concise and focused search queries. Use specific keywords and phrases to narrow down results.${this.allowEdit ? `
|
|
1164
|
+
10. When modifying files, choose the appropriate tool:
|
|
1165
|
+
- Use 'edit' for precise changes to existing files (requires exact string match)
|
|
1166
|
+
- Use 'create' for new files or complete file rewrites` : ''}
|
|
972
1167
|
</instructions>
|
|
973
1168
|
`;
|
|
974
1169
|
|
|
@@ -1257,8 +1452,8 @@ When troubleshooting:
|
|
|
1257
1452
|
const executeAIRequest = async () => {
|
|
1258
1453
|
// Prepare messages with potential image content
|
|
1259
1454
|
const messagesForAI = this.prepareMessagesWithImages(currentMessages);
|
|
1260
|
-
|
|
1261
|
-
const result = await
|
|
1455
|
+
|
|
1456
|
+
const result = await this.streamTextWithRetryAndFallback({
|
|
1262
1457
|
model: this.provider(this.model),
|
|
1263
1458
|
messages: messagesForAI,
|
|
1264
1459
|
maxTokens: maxResponseTokens,
|
|
@@ -1321,7 +1516,13 @@ When troubleshooting:
|
|
|
1321
1516
|
'search', 'query', 'extract', 'listFiles', 'searchFiles', 'attempt_completion'
|
|
1322
1517
|
];
|
|
1323
1518
|
if (this.allowEdit) {
|
|
1324
|
-
validTools.push('implement');
|
|
1519
|
+
validTools.push('implement', 'edit', 'create');
|
|
1520
|
+
}
|
|
1521
|
+
if (this.enableBash) {
|
|
1522
|
+
validTools.push('bash');
|
|
1523
|
+
}
|
|
1524
|
+
if (this.enableDelegate) {
|
|
1525
|
+
validTools.push('delegate');
|
|
1325
1526
|
}
|
|
1326
1527
|
|
|
1327
1528
|
// Try parsing with hybrid parser that supports both native and MCP tools
|
|
@@ -1462,18 +1663,24 @@ When troubleshooting:
|
|
|
1462
1663
|
|
|
1463
1664
|
// Execute tool with tracing if available
|
|
1464
1665
|
const executeToolCall = async () => {
|
|
1465
|
-
// For delegate tool, pass current iteration
|
|
1666
|
+
// For delegate tool, pass current iteration, max iterations, session ID, and config
|
|
1466
1667
|
if (toolName === 'delegate') {
|
|
1467
1668
|
const enhancedParams = {
|
|
1468
1669
|
...toolParams,
|
|
1469
1670
|
currentIteration,
|
|
1470
1671
|
maxIterations,
|
|
1672
|
+
parentSessionId: this.sessionId, // Pass parent session ID for tracking
|
|
1673
|
+
path: this.searchPath, // Inherit search path
|
|
1674
|
+
provider: this.provider, // Inherit AI provider
|
|
1675
|
+
model: this.model, // Inherit model
|
|
1471
1676
|
debug: this.debug,
|
|
1472
1677
|
tracer: this.tracer
|
|
1473
1678
|
};
|
|
1474
|
-
|
|
1679
|
+
|
|
1475
1680
|
if (this.debug) {
|
|
1476
1681
|
console.log(`[DEBUG] Executing delegate tool at iteration ${currentIteration}/${maxIterations}`);
|
|
1682
|
+
console.log(`[DEBUG] Parent session: ${this.sessionId}`);
|
|
1683
|
+
console.log(`[DEBUG] Inherited config: path=${this.searchPath}, provider=${this.provider}, model=${this.model}`);
|
|
1477
1684
|
console.log(`[DEBUG] Delegate task: ${toolParams.task?.substring(0, 100)}...`);
|
|
1478
1685
|
}
|
|
1479
1686
|
|
|
@@ -2205,6 +2412,7 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
2205
2412
|
customPrompt: this.customPrompt,
|
|
2206
2413
|
promptType: this.promptType,
|
|
2207
2414
|
allowEdit: this.allowEdit,
|
|
2415
|
+
enableDelegate: this.enableDelegate,
|
|
2208
2416
|
path: this.allowedFolders[0], // Use first allowed folder as primary path
|
|
2209
2417
|
allowedFolders: [...this.allowedFolders],
|
|
2210
2418
|
provider: this.clientApiProvider,
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript type definitions for RetryManager
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Retry configuration options
|
|
7
|
+
*/
|
|
8
|
+
export interface RetryOptions {
|
|
9
|
+
/** Maximum number of retry attempts (0-100) */
|
|
10
|
+
maxRetries?: number;
|
|
11
|
+
/** Initial delay in milliseconds (0-60000) */
|
|
12
|
+
initialDelay?: number;
|
|
13
|
+
/** Maximum delay in milliseconds (0-300000) */
|
|
14
|
+
maxDelay?: number;
|
|
15
|
+
/** Exponential backoff multiplier (1-10) */
|
|
16
|
+
backoffFactor?: number;
|
|
17
|
+
/** List of retryable error patterns */
|
|
18
|
+
retryableErrors?: string[];
|
|
19
|
+
/** Enable debug logging */
|
|
20
|
+
debug?: boolean;
|
|
21
|
+
/** Add random jitter to delays (default: true) */
|
|
22
|
+
jitter?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Context information for retry operations
|
|
27
|
+
*/
|
|
28
|
+
export interface RetryContext {
|
|
29
|
+
/** Provider name for logging */
|
|
30
|
+
provider?: string;
|
|
31
|
+
/** Model name for logging */
|
|
32
|
+
model?: string;
|
|
33
|
+
/** AbortSignal for cancellation */
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
/** Additional context data */
|
|
36
|
+
[key: string]: any;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Retry statistics
|
|
41
|
+
*/
|
|
42
|
+
export interface RetryStats {
|
|
43
|
+
/** Total number of attempts made */
|
|
44
|
+
totalAttempts: number;
|
|
45
|
+
/** Total number of retries (excluding initial attempts) */
|
|
46
|
+
totalRetries: number;
|
|
47
|
+
/** Number of successful retries */
|
|
48
|
+
successfulRetries: number;
|
|
49
|
+
/** Number of failed retries (exhausted max retries) */
|
|
50
|
+
failedRetries: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Error information extracted from an error object
|
|
55
|
+
*/
|
|
56
|
+
export interface ErrorInfo {
|
|
57
|
+
/** Error message */
|
|
58
|
+
message: string;
|
|
59
|
+
/** Error type or constructor name */
|
|
60
|
+
type: string;
|
|
61
|
+
/** Error code if available */
|
|
62
|
+
code?: string;
|
|
63
|
+
/** HTTP status code if available */
|
|
64
|
+
statusCode?: number;
|
|
65
|
+
/** Provider name if available */
|
|
66
|
+
provider?: string;
|
|
67
|
+
/** Whether the error is retryable */
|
|
68
|
+
isRetryable: boolean;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* RetryManager class for handling retry logic with exponential backoff
|
|
73
|
+
*/
|
|
74
|
+
export class RetryManager {
|
|
75
|
+
/** Maximum retry attempts */
|
|
76
|
+
maxRetries: number;
|
|
77
|
+
/** Initial delay in milliseconds */
|
|
78
|
+
initialDelay: number;
|
|
79
|
+
/** Maximum delay in milliseconds */
|
|
80
|
+
maxDelay: number;
|
|
81
|
+
/** Exponential backoff multiplier */
|
|
82
|
+
backoffFactor: number;
|
|
83
|
+
/** List of retryable error patterns */
|
|
84
|
+
retryableErrors: string[];
|
|
85
|
+
/** Debug logging enabled */
|
|
86
|
+
debug: boolean;
|
|
87
|
+
/** Jitter enabled */
|
|
88
|
+
jitter: boolean;
|
|
89
|
+
/** Retry statistics */
|
|
90
|
+
stats: RetryStats;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Create a new RetryManager
|
|
94
|
+
* @param options - Retry configuration options
|
|
95
|
+
*/
|
|
96
|
+
constructor(options?: RetryOptions);
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Execute a function with retry logic
|
|
100
|
+
* @param fn - Async function to execute
|
|
101
|
+
* @param context - Context information for logging
|
|
102
|
+
* @returns Result from the function
|
|
103
|
+
* @throws Error if all retries are exhausted or operation is aborted
|
|
104
|
+
*/
|
|
105
|
+
executeWithRetry<T>(
|
|
106
|
+
fn: () => Promise<T>,
|
|
107
|
+
context?: RetryContext
|
|
108
|
+
): Promise<T>;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Check if an error is retryable
|
|
112
|
+
* @param error - The error to check
|
|
113
|
+
* @returns True if error should be retried
|
|
114
|
+
*/
|
|
115
|
+
isRetryable(error: Error): boolean;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Get retry statistics
|
|
119
|
+
* @returns Statistics object (copy)
|
|
120
|
+
*/
|
|
121
|
+
getStats(): RetryStats;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Reset statistics
|
|
125
|
+
*/
|
|
126
|
+
resetStats(): void;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Check if an error is retryable based on error patterns
|
|
131
|
+
* @param error - The error to check
|
|
132
|
+
* @param retryableErrors - List of retryable error patterns
|
|
133
|
+
* @returns True if error should be retried
|
|
134
|
+
*/
|
|
135
|
+
export function isRetryableError(
|
|
136
|
+
error: Error,
|
|
137
|
+
retryableErrors?: string[]
|
|
138
|
+
): boolean;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Extract meaningful error information for logging
|
|
142
|
+
* @param error - The error to extract info from
|
|
143
|
+
* @returns Error information object
|
|
144
|
+
*/
|
|
145
|
+
export function extractErrorInfo(error: Error): ErrorInfo;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Create a RetryManager from environment variables
|
|
149
|
+
* @param debug - Enable debug logging
|
|
150
|
+
* @returns Configured RetryManager instance
|
|
151
|
+
*/
|
|
152
|
+
export function createRetryManagerFromEnv(debug?: boolean): RetryManager;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Default retryable error patterns
|
|
156
|
+
*/
|
|
157
|
+
export const DEFAULT_RETRYABLE_ERRORS: string[];
|