@probelabs/probe 0.6.0-rc277 → 0.6.0-rc279
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-rc279-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc279-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc279-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc279-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/{probe-v0.6.0-rc277-x86_64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc279-x86_64-unknown-linux-musl.tar.gz} +0 -0
- package/build/agent/ProbeAgent.js +63 -11
- package/build/agent/index.js +129 -33
- package/build/agent/shared/prompts.js +30 -8
- package/build/delegate.js +40 -11
- package/build/tools/analyzeAll.js +8 -4
- package/build/tools/vercel.js +7 -4
- package/cjs/agent/ProbeAgent.cjs +132 -34
- package/cjs/index.cjs +129 -33
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +63 -11
- package/src/agent/shared/prompts.js +30 -8
- package/src/delegate.js +40 -11
- package/src/tools/analyzeAll.js +8 -4
- package/src/tools/vercel.js +7 -4
- package/bin/binaries/probe-v0.6.0-rc277-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc277-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc277-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc277-x86_64-pc-windows-msvc.zip +0 -0
package/build/delegate.js
CHANGED
|
@@ -386,12 +386,18 @@ export async function delegate({
|
|
|
386
386
|
mcpConfig = null,
|
|
387
387
|
mcpConfigPath = null,
|
|
388
388
|
delegationManager = null, // Optional per-instance manager, falls back to default singleton
|
|
389
|
-
concurrencyLimiter = null // Optional global AI concurrency limiter
|
|
389
|
+
concurrencyLimiter = null, // Optional global AI concurrency limiter
|
|
390
|
+
parentAbortSignal = null // Optional AbortSignal from parent to cancel this delegation
|
|
390
391
|
}) {
|
|
391
392
|
if (!task || typeof task !== 'string') {
|
|
392
393
|
throw new Error('Task parameter is required and must be a string');
|
|
393
394
|
}
|
|
394
395
|
|
|
396
|
+
// Check if parent has already been cancelled
|
|
397
|
+
if (parentAbortSignal?.aborted) {
|
|
398
|
+
throw new Error('Delegation cancelled: parent operation was aborted');
|
|
399
|
+
}
|
|
400
|
+
|
|
395
401
|
// Support runtime timeout override via environment variables when timeout not explicitly passed
|
|
396
402
|
// This allows operators to configure delegation timeouts without code changes
|
|
397
403
|
// Priority: DELEGATION_TIMEOUT_MS (milliseconds) > DELEGATION_TIMEOUT_SECONDS > DELEGATION_TIMEOUT (seconds)
|
|
@@ -481,24 +487,47 @@ export async function delegate({
|
|
|
481
487
|
console.error(`[DELEGATE] Subagent config: promptType=${promptType}, enableDelegate=false, maxIterations=${remainingIterations}`);
|
|
482
488
|
}
|
|
483
489
|
|
|
484
|
-
// Set up timeout
|
|
485
|
-
//
|
|
486
|
-
//
|
|
487
|
-
// This is acceptable since:
|
|
488
|
-
// 1. The promise will eventually resolve/reject and be garbage collected
|
|
489
|
-
// 2. The delegation slot is properly released on timeout
|
|
490
|
-
// 3. The parent receives timeout error and can handle it
|
|
491
|
-
// Future improvement: Add signal parameter to ProbeAgent.answer(task, [], { signal })
|
|
490
|
+
// Set up timeout and parent abort handling.
|
|
491
|
+
// When timeout fires or parent aborts, we cancel the subagent so it
|
|
492
|
+
// stops making API calls and releases resources promptly.
|
|
492
493
|
const timeoutPromise = new Promise((_, reject) => {
|
|
493
494
|
timeoutId = setTimeout(() => {
|
|
495
|
+
subagent.cancel();
|
|
494
496
|
reject(new Error(`Delegation timed out after ${timeout} seconds`));
|
|
495
497
|
}, timeout * 1000);
|
|
496
498
|
});
|
|
497
499
|
|
|
498
|
-
//
|
|
500
|
+
// Listen for parent abort signal
|
|
501
|
+
let parentAbortHandler;
|
|
502
|
+
const parentAbortPromise = new Promise((_, reject) => {
|
|
503
|
+
if (parentAbortSignal) {
|
|
504
|
+
if (parentAbortSignal.aborted) {
|
|
505
|
+
subagent.cancel();
|
|
506
|
+
reject(new Error('Delegation cancelled: parent operation was aborted'));
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
parentAbortHandler = () => {
|
|
510
|
+
subagent.cancel();
|
|
511
|
+
reject(new Error('Delegation cancelled: parent operation was aborted'));
|
|
512
|
+
};
|
|
513
|
+
parentAbortSignal.addEventListener('abort', parentAbortHandler, { once: true });
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
// Execute the task with timeout and parent abort
|
|
499
518
|
const answerOptions = schema ? { schema } : undefined;
|
|
500
519
|
const answerPromise = answerOptions ? subagent.answer(task, [], answerOptions) : subagent.answer(task);
|
|
501
|
-
const
|
|
520
|
+
const racers = [answerPromise, timeoutPromise];
|
|
521
|
+
if (parentAbortSignal) racers.push(parentAbortPromise);
|
|
522
|
+
let response;
|
|
523
|
+
try {
|
|
524
|
+
response = await Promise.race(racers);
|
|
525
|
+
} finally {
|
|
526
|
+
// Clean up parent abort listener to prevent memory leaks
|
|
527
|
+
if (parentAbortHandler && parentAbortSignal) {
|
|
528
|
+
parentAbortSignal.removeEventListener('abort', parentAbortHandler);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
502
531
|
|
|
503
532
|
// Clear timeout immediately after race completes to prevent memory leak
|
|
504
533
|
// Note: timeoutId is always set by this point (synchronous in Promise constructor)
|
|
@@ -192,7 +192,8 @@ Instructions:
|
|
|
192
192
|
promptType: 'code-researcher',
|
|
193
193
|
allowedTools: ['extract'],
|
|
194
194
|
maxIterations: 5,
|
|
195
|
-
delegationManager: options.delegationManager // Per-instance delegation limits
|
|
195
|
+
delegationManager: options.delegationManager, // Per-instance delegation limits
|
|
196
|
+
parentAbortSignal: options.parentAbortSignal || null
|
|
196
197
|
// timeout removed - inherit default from delegate (300s)
|
|
197
198
|
});
|
|
198
199
|
|
|
@@ -328,7 +329,8 @@ Organize all findings into clear categories with items listed under each.${compl
|
|
|
328
329
|
promptType: 'code-researcher',
|
|
329
330
|
allowedTools: [],
|
|
330
331
|
maxIterations: 5,
|
|
331
|
-
delegationManager: options.delegationManager // Per-instance delegation limits
|
|
332
|
+
delegationManager: options.delegationManager, // Per-instance delegation limits
|
|
333
|
+
parentAbortSignal: options.parentAbortSignal || null
|
|
332
334
|
// timeout removed - inherit default from delegate (300s)
|
|
333
335
|
});
|
|
334
336
|
|
|
@@ -404,7 +406,8 @@ CRITICAL: Do NOT guess keywords. Actually run searches and see what returns resu
|
|
|
404
406
|
promptType: 'code-researcher',
|
|
405
407
|
// Full tool access for exploration and experimentation
|
|
406
408
|
maxIterations: 15,
|
|
407
|
-
delegationManager: options.delegationManager // Per-instance delegation limits
|
|
409
|
+
delegationManager: options.delegationManager, // Per-instance delegation limits
|
|
410
|
+
parentAbortSignal: options.parentAbortSignal || null
|
|
408
411
|
// timeout removed - inherit default from delegate (300s)
|
|
409
412
|
});
|
|
410
413
|
|
|
@@ -475,7 +478,8 @@ When done, use the attempt_completion tool with your answer as the result.`;
|
|
|
475
478
|
promptType: 'code-researcher',
|
|
476
479
|
allowedTools: [],
|
|
477
480
|
maxIterations: 5,
|
|
478
|
-
delegationManager: options.delegationManager // Per-instance delegation limits
|
|
481
|
+
delegationManager: options.delegationManager, // Per-instance delegation limits
|
|
482
|
+
parentAbortSignal: options.parentAbortSignal || null
|
|
479
483
|
// timeout removed - inherit default from delegate (300s)
|
|
480
484
|
});
|
|
481
485
|
|
package/build/tools/vercel.js
CHANGED
|
@@ -277,7 +277,8 @@ export const searchTool = (options = {}) => {
|
|
|
277
277
|
promptType: 'code-searcher',
|
|
278
278
|
allowedTools: ['search', 'extract', 'listFiles', 'attempt_completion'],
|
|
279
279
|
searchDelegate: false,
|
|
280
|
-
schema: CODE_SEARCH_SCHEMA
|
|
280
|
+
schema: CODE_SEARCH_SCHEMA,
|
|
281
|
+
parentAbortSignal: options.parentAbortSignal || null
|
|
281
282
|
});
|
|
282
283
|
|
|
283
284
|
const delegateResult = options.tracer?.withSpan
|
|
@@ -581,7 +582,7 @@ export const delegateTool = (options = {}) => {
|
|
|
581
582
|
name: 'delegate',
|
|
582
583
|
description: delegateDescription,
|
|
583
584
|
inputSchema: delegateSchema,
|
|
584
|
-
execute: async ({ task, currentIteration, maxIterations, parentSessionId, path, provider, model, tracer, searchDelegate }) => {
|
|
585
|
+
execute: async ({ task, currentIteration, maxIterations, parentSessionId, path, provider, model, tracer, searchDelegate, parentAbortSignal }) => {
|
|
585
586
|
// Validate required parameters - throw errors for consistency
|
|
586
587
|
if (!task || typeof task !== 'string') {
|
|
587
588
|
throw new Error('Task parameter is required and must be a non-empty string');
|
|
@@ -673,7 +674,8 @@ export const delegateTool = (options = {}) => {
|
|
|
673
674
|
enableMcp,
|
|
674
675
|
mcpConfig,
|
|
675
676
|
mcpConfigPath,
|
|
676
|
-
delegationManager // Per-instance delegation limits
|
|
677
|
+
delegationManager, // Per-instance delegation limits
|
|
678
|
+
parentAbortSignal
|
|
677
679
|
});
|
|
678
680
|
|
|
679
681
|
return result;
|
|
@@ -733,7 +735,8 @@ export const analyzeAllTool = (options = {}) => {
|
|
|
733
735
|
provider: options.provider,
|
|
734
736
|
model: options.model,
|
|
735
737
|
tracer: options.tracer,
|
|
736
|
-
delegationManager // Per-instance delegation limits
|
|
738
|
+
delegationManager, // Per-instance delegation limits
|
|
739
|
+
parentAbortSignal: options.parentAbortSignal || null
|
|
737
740
|
});
|
|
738
741
|
|
|
739
742
|
return result;
|
package/cjs/agent/ProbeAgent.cjs
CHANGED
|
@@ -31241,12 +31241,17 @@ async function delegate({
|
|
|
31241
31241
|
mcpConfigPath = null,
|
|
31242
31242
|
delegationManager = null,
|
|
31243
31243
|
// Optional per-instance manager, falls back to default singleton
|
|
31244
|
-
concurrencyLimiter = null
|
|
31244
|
+
concurrencyLimiter = null,
|
|
31245
31245
|
// Optional global AI concurrency limiter
|
|
31246
|
+
parentAbortSignal = null
|
|
31247
|
+
// Optional AbortSignal from parent to cancel this delegation
|
|
31246
31248
|
}) {
|
|
31247
31249
|
if (!task || typeof task !== "string") {
|
|
31248
31250
|
throw new Error("Task parameter is required and must be a string");
|
|
31249
31251
|
}
|
|
31252
|
+
if (parentAbortSignal?.aborted) {
|
|
31253
|
+
throw new Error("Delegation cancelled: parent operation was aborted");
|
|
31254
|
+
}
|
|
31250
31255
|
const hasExplicitTimeout = Object.prototype.hasOwnProperty.call(arguments?.[0] ?? {}, "timeout");
|
|
31251
31256
|
if (!hasExplicitTimeout) {
|
|
31252
31257
|
const envTimeoutMs = parseInt(process.env.DELEGATION_TIMEOUT_MS || "", 10);
|
|
@@ -31331,12 +31336,37 @@ async function delegate({
|
|
|
31331
31336
|
}
|
|
31332
31337
|
const timeoutPromise = new Promise((_, reject2) => {
|
|
31333
31338
|
timeoutId = setTimeout(() => {
|
|
31339
|
+
subagent.cancel();
|
|
31334
31340
|
reject2(new Error(`Delegation timed out after ${timeout} seconds`));
|
|
31335
31341
|
}, timeout * 1e3);
|
|
31336
31342
|
});
|
|
31343
|
+
let parentAbortHandler;
|
|
31344
|
+
const parentAbortPromise = new Promise((_, reject2) => {
|
|
31345
|
+
if (parentAbortSignal) {
|
|
31346
|
+
if (parentAbortSignal.aborted) {
|
|
31347
|
+
subagent.cancel();
|
|
31348
|
+
reject2(new Error("Delegation cancelled: parent operation was aborted"));
|
|
31349
|
+
return;
|
|
31350
|
+
}
|
|
31351
|
+
parentAbortHandler = () => {
|
|
31352
|
+
subagent.cancel();
|
|
31353
|
+
reject2(new Error("Delegation cancelled: parent operation was aborted"));
|
|
31354
|
+
};
|
|
31355
|
+
parentAbortSignal.addEventListener("abort", parentAbortHandler, { once: true });
|
|
31356
|
+
}
|
|
31357
|
+
});
|
|
31337
31358
|
const answerOptions = schema ? { schema } : void 0;
|
|
31338
31359
|
const answerPromise = answerOptions ? subagent.answer(task, [], answerOptions) : subagent.answer(task);
|
|
31339
|
-
const
|
|
31360
|
+
const racers = [answerPromise, timeoutPromise];
|
|
31361
|
+
if (parentAbortSignal) racers.push(parentAbortPromise);
|
|
31362
|
+
let response;
|
|
31363
|
+
try {
|
|
31364
|
+
response = await Promise.race(racers);
|
|
31365
|
+
} finally {
|
|
31366
|
+
if (parentAbortHandler && parentAbortSignal) {
|
|
31367
|
+
parentAbortSignal.removeEventListener("abort", parentAbortHandler);
|
|
31368
|
+
}
|
|
31369
|
+
}
|
|
31340
31370
|
if (timeoutId !== null) {
|
|
31341
31371
|
clearTimeout(timeoutId);
|
|
31342
31372
|
timeoutId = null;
|
|
@@ -31749,8 +31779,9 @@ Instructions:
|
|
|
31749
31779
|
promptType: "code-researcher",
|
|
31750
31780
|
allowedTools: ["extract"],
|
|
31751
31781
|
maxIterations: 5,
|
|
31752
|
-
delegationManager: options.delegationManager
|
|
31782
|
+
delegationManager: options.delegationManager,
|
|
31753
31783
|
// Per-instance delegation limits
|
|
31784
|
+
parentAbortSignal: options.parentAbortSignal || null
|
|
31754
31785
|
// timeout removed - inherit default from delegate (300s)
|
|
31755
31786
|
});
|
|
31756
31787
|
return { chunk, result };
|
|
@@ -31849,8 +31880,9 @@ Organize all findings into clear categories with items listed under each.${compl
|
|
|
31849
31880
|
promptType: "code-researcher",
|
|
31850
31881
|
allowedTools: [],
|
|
31851
31882
|
maxIterations: 5,
|
|
31852
|
-
delegationManager: options.delegationManager
|
|
31883
|
+
delegationManager: options.delegationManager,
|
|
31853
31884
|
// Per-instance delegation limits
|
|
31885
|
+
parentAbortSignal: options.parentAbortSignal || null
|
|
31854
31886
|
// timeout removed - inherit default from delegate (300s)
|
|
31855
31887
|
});
|
|
31856
31888
|
return result;
|
|
@@ -31914,8 +31946,9 @@ CRITICAL: Do NOT guess keywords. Actually run searches and see what returns resu
|
|
|
31914
31946
|
promptType: "code-researcher",
|
|
31915
31947
|
// Full tool access for exploration and experimentation
|
|
31916
31948
|
maxIterations: 15,
|
|
31917
|
-
delegationManager: options.delegationManager
|
|
31949
|
+
delegationManager: options.delegationManager,
|
|
31918
31950
|
// Per-instance delegation limits
|
|
31951
|
+
parentAbortSignal: options.parentAbortSignal || null
|
|
31919
31952
|
// timeout removed - inherit default from delegate (300s)
|
|
31920
31953
|
});
|
|
31921
31954
|
const plan = parsePlanningResult(stripResultTags(result));
|
|
@@ -31972,8 +32005,9 @@ When done, use the attempt_completion tool with your answer as the result.`;
|
|
|
31972
32005
|
promptType: "code-researcher",
|
|
31973
32006
|
allowedTools: [],
|
|
31974
32007
|
maxIterations: 5,
|
|
31975
|
-
delegationManager: options.delegationManager
|
|
32008
|
+
delegationManager: options.delegationManager,
|
|
31976
32009
|
// Per-instance delegation limits
|
|
32010
|
+
parentAbortSignal: options.parentAbortSignal || null
|
|
31977
32011
|
// timeout removed - inherit default from delegate (300s)
|
|
31978
32012
|
});
|
|
31979
32013
|
return stripResultTags(result);
|
|
@@ -36657,7 +36691,8 @@ var init_vercel = __esm({
|
|
|
36657
36691
|
promptType: "code-searcher",
|
|
36658
36692
|
allowedTools: ["search", "extract", "listFiles", "attempt_completion"],
|
|
36659
36693
|
searchDelegate: false,
|
|
36660
|
-
schema: CODE_SEARCH_SCHEMA
|
|
36694
|
+
schema: CODE_SEARCH_SCHEMA,
|
|
36695
|
+
parentAbortSignal: options.parentAbortSignal || null
|
|
36661
36696
|
});
|
|
36662
36697
|
const delegateResult = options.tracer?.withSpan ? await options.tracer.withSpan("search.delegate", runDelegation, {
|
|
36663
36698
|
"search.query": searchQuery,
|
|
@@ -36871,7 +36906,7 @@ var init_vercel = __esm({
|
|
|
36871
36906
|
name: "delegate",
|
|
36872
36907
|
description: delegateDescription,
|
|
36873
36908
|
inputSchema: delegateSchema,
|
|
36874
|
-
execute: async ({ task, currentIteration, maxIterations, parentSessionId, path: path9, provider, model, tracer, searchDelegate }) => {
|
|
36909
|
+
execute: async ({ task, currentIteration, maxIterations, parentSessionId, path: path9, provider, model, tracer, searchDelegate, parentAbortSignal }) => {
|
|
36875
36910
|
if (!task || typeof task !== "string") {
|
|
36876
36911
|
throw new Error("Task parameter is required and must be a non-empty string");
|
|
36877
36912
|
}
|
|
@@ -36929,8 +36964,9 @@ var init_vercel = __esm({
|
|
|
36929
36964
|
enableMcp,
|
|
36930
36965
|
mcpConfig,
|
|
36931
36966
|
mcpConfigPath,
|
|
36932
|
-
delegationManager
|
|
36967
|
+
delegationManager,
|
|
36933
36968
|
// Per-instance delegation limits
|
|
36969
|
+
parentAbortSignal
|
|
36934
36970
|
});
|
|
36935
36971
|
return result;
|
|
36936
36972
|
}
|
|
@@ -36968,8 +37004,9 @@ var init_vercel = __esm({
|
|
|
36968
37004
|
provider: options.provider,
|
|
36969
37005
|
model: options.model,
|
|
36970
37006
|
tracer: options.tracer,
|
|
36971
|
-
delegationManager
|
|
37007
|
+
delegationManager,
|
|
36972
37008
|
// Per-instance delegation limits
|
|
37009
|
+
parentAbortSignal: options.parentAbortSignal || null
|
|
36973
37010
|
});
|
|
36974
37011
|
return result;
|
|
36975
37012
|
} catch (error2) {
|
|
@@ -58878,7 +58915,7 @@ ${taskManager.formatTasksForPrompt()}`;
|
|
|
58878
58915
|
}
|
|
58879
58916
|
};
|
|
58880
58917
|
}
|
|
58881
|
-
var taskItemSchema, taskSchema, taskSystemPrompt
|
|
58918
|
+
var taskItemSchema, taskSchema, taskSystemPrompt;
|
|
58882
58919
|
var init_taskTool = __esm({
|
|
58883
58920
|
"src/agent/tasks/taskTool.js"() {
|
|
58884
58921
|
"use strict";
|
|
@@ -58939,11 +58976,6 @@ Tasks = logical units of work, not files or steps.
|
|
|
58939
58976
|
- Circular dependencies are rejected
|
|
58940
58977
|
- attempt_completion is blocked while tasks remain unresolved
|
|
58941
58978
|
`;
|
|
58942
|
-
taskGuidancePrompt = `Does this request have MULTIPLE DISTINCT GOALS?
|
|
58943
|
-
- "Do A AND B AND C" (multiple goals) \u2192 Create tasks for each goal
|
|
58944
|
-
- "Investigate/explain/find X" (single goal) \u2192 Skip tasks, just answer directly
|
|
58945
|
-
Multiple internal steps for ONE goal = NO tasks needed.
|
|
58946
|
-
If creating tasks, use the task tool with action="create" first.`;
|
|
58947
58979
|
}
|
|
58948
58980
|
});
|
|
58949
58981
|
|
|
@@ -97700,8 +97732,20 @@ If the solution is clear, you can jump to implementation right away. If not, ask
|
|
|
97700
97732
|
- Check imports and existing utilities before creating new helpers \u2014 the project may already have what you need.
|
|
97701
97733
|
|
|
97702
97734
|
# Task Planning
|
|
97703
|
-
|
|
97704
|
-
-
|
|
97735
|
+
When the request has **multiple distinct goals** (e.g. "Fix bug A AND add feature B"), use the task tool to track them:
|
|
97736
|
+
- Call the task tool with action="create" and a tasks array. Each task must have an "id" field.
|
|
97737
|
+
- Update task status to "in_progress" when starting and "completed" when done.
|
|
97738
|
+
- All tasks must be completed or cancelled before calling attempt_completion.
|
|
97739
|
+
- Stay flexible \u2014 add, remove, or reorganize tasks as your understanding changes.
|
|
97740
|
+
|
|
97741
|
+
Do NOT create tasks for single-goal requests, even complex ones. Multiple internal steps for one goal (search, read, analyze, implement) do not need tasks.
|
|
97742
|
+
|
|
97743
|
+
# Discovering Project Commands
|
|
97744
|
+
Before building or testing, determine the project's toolchain:
|
|
97745
|
+
- Check for Makefile, package.json (scripts), Cargo.toml, go.mod, pyproject.toml, or similar
|
|
97746
|
+
- Look for CI config (.github/workflows/, .gitlab-ci.yml) to see what commands CI runs
|
|
97747
|
+
- Read README for build/test instructions if the above are unclear
|
|
97748
|
+
- Common patterns: \`make build\`/\`make test\`, \`npm run build\`/\`npm test\`, \`cargo build\`/\`cargo test\`, \`go build ./...\`/\`go test ./...\`, \`python -m pytest\`
|
|
97705
97749
|
|
|
97706
97750
|
# During Implementation
|
|
97707
97751
|
- Always create a new branch before making changes to the codebase.
|
|
@@ -97712,12 +97756,22 @@ If the solution is clear, you can jump to implementation right away. If not, ask
|
|
|
97712
97756
|
- When editing files, keep edits focused and minimal. For changes spanning more than a few lines, prefer line-targeted editing (start_line/end_line) over text replacement (old_string) \u2014 it constrains scope and prevents accidental removal of adjacent content. Never include unrelated sections in an edit operation.
|
|
97713
97757
|
- After every significant change, verify the project still builds and passes linting. Do not wait until the end to discover breakage.
|
|
97714
97758
|
|
|
97715
|
-
#
|
|
97716
|
-
|
|
97717
|
-
-
|
|
97718
|
-
-
|
|
97719
|
-
-
|
|
97720
|
-
-
|
|
97759
|
+
# Writing Tests
|
|
97760
|
+
Every change must include tests. Before writing them:
|
|
97761
|
+
- Find existing test files for the module you changed \u2014 look in \`tests/\`, \`__tests__/\`, \`*_test.go\`, \`*.test.js\`, \`*.spec.ts\`, or co-located test modules (\`#[cfg(test)]\` in Rust).
|
|
97762
|
+
- Read those tests to understand the project's testing patterns: framework, assertion style, mocking approach, file naming, test organization.
|
|
97763
|
+
- Prefer extending an existing test file over creating a new one when your change is in the same module.
|
|
97764
|
+
- Write tests that cover the main path and important edge cases. Include a failing-input test when relevant.
|
|
97765
|
+
- When fixing a bug, write a failing test first that reproduces the bug, then fix the code to make it pass.
|
|
97766
|
+
|
|
97767
|
+
# Verify Changes
|
|
97768
|
+
Before committing or creating a PR, run through this checklist:
|
|
97769
|
+
1. **Build** \u2014 run the project-appropriate build command (go build, npm run build, cargo build, make, etc.). Fix any compilation errors.
|
|
97770
|
+
2. **Lint & typecheck** \u2014 run linter/formatter if the project has one (eslint, clippy, golangci-lint, etc.). Fix any new warnings.
|
|
97771
|
+
3. **Test** \u2014 run the full test suite (go test ./..., npm test, cargo test, make test, pytest, etc.). Fix any failures, including pre-existing tests you may have broken.
|
|
97772
|
+
4. **Review** \u2014 re-read your diff. Ensure no debug code, no unrelated changes, no secrets, no missing files.
|
|
97773
|
+
|
|
97774
|
+
Do NOT skip verification. Do NOT proceed to PR creation with a broken build or failing tests.
|
|
97721
97775
|
|
|
97722
97776
|
# GitHub Integration
|
|
97723
97777
|
- Use the \`gh\` CLI for all GitHub operations: issues, pull requests, checks, releases.
|
|
@@ -108697,9 +108751,24 @@ __export(ProbeAgent_exports, {
|
|
|
108697
108751
|
ENGINE_ACTIVITY_TIMEOUT_DEFAULT: () => ENGINE_ACTIVITY_TIMEOUT_DEFAULT,
|
|
108698
108752
|
ENGINE_ACTIVITY_TIMEOUT_MAX: () => ENGINE_ACTIVITY_TIMEOUT_MAX,
|
|
108699
108753
|
ENGINE_ACTIVITY_TIMEOUT_MIN: () => ENGINE_ACTIVITY_TIMEOUT_MIN,
|
|
108700
|
-
ProbeAgent: () => ProbeAgent
|
|
108754
|
+
ProbeAgent: () => ProbeAgent,
|
|
108755
|
+
debugLogToolResults: () => debugLogToolResults,
|
|
108756
|
+
debugTruncate: () => debugTruncate
|
|
108701
108757
|
});
|
|
108702
108758
|
module.exports = __toCommonJS(ProbeAgent_exports);
|
|
108759
|
+
function debugTruncate(s5, limit = 200) {
|
|
108760
|
+
if (s5.length <= limit) return s5;
|
|
108761
|
+
const half = Math.floor(limit / 2);
|
|
108762
|
+
return s5.substring(0, half) + ` ... [${s5.length} chars] ... ` + s5.substring(s5.length - half);
|
|
108763
|
+
}
|
|
108764
|
+
function debugLogToolResults(toolResults) {
|
|
108765
|
+
if (!toolResults || toolResults.length === 0) return;
|
|
108766
|
+
for (const tr of toolResults) {
|
|
108767
|
+
const argsStr = JSON.stringify(tr.args || {});
|
|
108768
|
+
const resultStr = typeof tr.result === "string" ? tr.result : JSON.stringify(tr.result || "");
|
|
108769
|
+
console.log(`[DEBUG] tool: ${tr.toolName} | args: ${debugTruncate(argsStr)} | result: ${debugTruncate(resultStr)}`);
|
|
108770
|
+
}
|
|
108771
|
+
}
|
|
108703
108772
|
var import_dotenv2, import_anthropic2, import_openai2, import_google2, import_ai6, import_crypto9, import_events4, import_fs15, import_promises6, import_path18, ENGINE_ACTIVITY_TIMEOUT_DEFAULT, ENGINE_ACTIVITY_TIMEOUT_MIN, ENGINE_ACTIVITY_TIMEOUT_MAX, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, MAX_IMAGE_FILE_SIZE, ProbeAgent;
|
|
108704
108773
|
var init_ProbeAgent = __esm({
|
|
108705
108774
|
"src/agent/ProbeAgent.js"() {
|
|
@@ -108818,6 +108887,7 @@ var init_ProbeAgent = __esm({
|
|
|
108818
108887
|
this.enableExecutePlan = !!options.enableExecutePlan;
|
|
108819
108888
|
this.debug = options.debug || process.env.DEBUG === "1";
|
|
108820
108889
|
this.cancelled = false;
|
|
108890
|
+
this._abortController = new AbortController();
|
|
108821
108891
|
this.tracer = options.tracer || null;
|
|
108822
108892
|
this.outline = !!options.outline;
|
|
108823
108893
|
this.searchDelegate = options.searchDelegate !== void 0 ? !!options.searchDelegate : true;
|
|
@@ -109263,6 +109333,8 @@ var init_ProbeAgent = __esm({
|
|
|
109263
109333
|
searchDelegateModel: this.searchDelegateModel,
|
|
109264
109334
|
delegationManager: this.delegationManager,
|
|
109265
109335
|
// Per-instance delegation limits
|
|
109336
|
+
parentAbortSignal: this._abortController.signal,
|
|
109337
|
+
// Propagate cancellation to delegations
|
|
109266
109338
|
outputBuffer: this._outputBuffer,
|
|
109267
109339
|
concurrencyLimiter: this.concurrencyLimiter,
|
|
109268
109340
|
// Global AI concurrency limiter
|
|
@@ -109710,6 +109782,15 @@ var init_ProbeAgent = __esm({
|
|
|
109710
109782
|
}
|
|
109711
109783
|
const controller = new AbortController();
|
|
109712
109784
|
const timeoutState = { timeoutId: null };
|
|
109785
|
+
if (this._abortController.signal.aborted) {
|
|
109786
|
+
controller.abort();
|
|
109787
|
+
} else {
|
|
109788
|
+
const onAgentAbort = () => controller.abort();
|
|
109789
|
+
this._abortController.signal.addEventListener("abort", onAgentAbort, { once: true });
|
|
109790
|
+
controller.signal.addEventListener("abort", () => {
|
|
109791
|
+
this._abortController.signal.removeEventListener("abort", onAgentAbort);
|
|
109792
|
+
}, { once: true });
|
|
109793
|
+
}
|
|
109713
109794
|
if (this.maxOperationTimeout && this.maxOperationTimeout > 0) {
|
|
109714
109795
|
timeoutState.timeoutId = setTimeout(() => {
|
|
109715
109796
|
controller.abort();
|
|
@@ -110013,7 +110094,8 @@ var init_ProbeAgent = __esm({
|
|
|
110013
110094
|
allowEdit: this.allowEdit,
|
|
110014
110095
|
allowedTools: allowedToolsForDelegate,
|
|
110015
110096
|
debug: this.debug,
|
|
110016
|
-
tracer: this.tracer
|
|
110097
|
+
tracer: this.tracer,
|
|
110098
|
+
parentAbortSignal: this._abortController.signal
|
|
110017
110099
|
};
|
|
110018
110100
|
if (this.debug) {
|
|
110019
110101
|
console.log(`[DEBUG] Executing delegate tool`);
|
|
@@ -111175,12 +111257,6 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
111175
111257
|
});
|
|
111176
111258
|
const systemMessage = await this.getSystemMessage();
|
|
111177
111259
|
let userMessage = { role: "user", content: message.trim() };
|
|
111178
|
-
if (this.enableTasks) {
|
|
111179
|
-
userMessage.content = userMessage.content + "\n\n" + taskGuidancePrompt;
|
|
111180
|
-
if (this.debug) {
|
|
111181
|
-
console.log("[DEBUG] Task guidance injected into user message");
|
|
111182
|
-
}
|
|
111183
|
-
}
|
|
111184
111260
|
if (options.schema && !options._schemaFormatted) {
|
|
111185
111261
|
const schemaInstructions = generateSchemaInstructions(options.schema, { debug: this.debug });
|
|
111186
111262
|
userMessage.content = message.trim() + schemaInstructions;
|
|
@@ -111336,6 +111412,10 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
111336
111412
|
completionResult = result;
|
|
111337
111413
|
completionAttempted = true;
|
|
111338
111414
|
}, toolContext);
|
|
111415
|
+
if (this.debug) {
|
|
111416
|
+
const toolNames = Object.keys(tools2);
|
|
111417
|
+
console.log(`[DEBUG] Agent tools registered (${toolNames.length}): ${toolNames.join(", ")}`);
|
|
111418
|
+
}
|
|
111339
111419
|
let maxResponseTokens = this.maxResponseTokens;
|
|
111340
111420
|
if (!maxResponseTokens) {
|
|
111341
111421
|
maxResponseTokens = 4e3;
|
|
@@ -111375,6 +111455,7 @@ You are working with a workspace. Available paths: ${workspaceDesc}
|
|
|
111375
111455
|
}
|
|
111376
111456
|
if (this.debug) {
|
|
111377
111457
|
console.log(`[DEBUG] Step ${currentIteration}/${maxIterations} finished (reason: ${finishReason}, tools: ${toolResults?.length || 0})`);
|
|
111458
|
+
debugLogToolResults(toolResults);
|
|
111378
111459
|
}
|
|
111379
111460
|
}
|
|
111380
111461
|
};
|
|
@@ -111531,6 +111612,7 @@ Double-check your response based on the criteria above. If everything looks good
|
|
|
111531
111612
|
}
|
|
111532
111613
|
if (this.debug) {
|
|
111533
111614
|
console.log(`[DEBUG] Completion prompt step finished (reason: ${finishReason}, tools: ${toolResults?.length || 0})`);
|
|
111615
|
+
debugLogToolResults(toolResults);
|
|
111534
111616
|
}
|
|
111535
111617
|
}
|
|
111536
111618
|
};
|
|
@@ -112241,6 +112323,9 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
112241
112323
|
* Clean up resources (including MCP connections)
|
|
112242
112324
|
*/
|
|
112243
112325
|
async cleanup() {
|
|
112326
|
+
if (!this._abortController.signal.aborted) {
|
|
112327
|
+
this._abortController.abort();
|
|
112328
|
+
}
|
|
112244
112329
|
if (this.mcpBridge) {
|
|
112245
112330
|
try {
|
|
112246
112331
|
await this.mcpBridge.cleanup();
|
|
@@ -112264,14 +112349,25 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
112264
112349
|
this.clearHistory();
|
|
112265
112350
|
}
|
|
112266
112351
|
/**
|
|
112267
|
-
* Cancel the current request
|
|
112352
|
+
* Cancel the current request and all in-flight delegations.
|
|
112353
|
+
* Aborts the internal AbortController so streamText, subagents,
|
|
112354
|
+
* and any code checking the signal will stop.
|
|
112268
112355
|
*/
|
|
112269
112356
|
cancel() {
|
|
112270
112357
|
this.cancelled = true;
|
|
112358
|
+
this._abortController.abort();
|
|
112271
112359
|
if (this.debug) {
|
|
112272
112360
|
console.log(`[DEBUG] Agent cancelled for session ${this.sessionId}`);
|
|
112273
112361
|
}
|
|
112274
112362
|
}
|
|
112363
|
+
/**
|
|
112364
|
+
* Get the abort signal for this agent.
|
|
112365
|
+
* Delegations and subagents should check this signal.
|
|
112366
|
+
* @returns {AbortSignal}
|
|
112367
|
+
*/
|
|
112368
|
+
get abortSignal() {
|
|
112369
|
+
return this._abortController.signal;
|
|
112370
|
+
}
|
|
112275
112371
|
};
|
|
112276
112372
|
}
|
|
112277
112373
|
});
|
|
@@ -112281,7 +112377,9 @@ init_ProbeAgent();
|
|
|
112281
112377
|
ENGINE_ACTIVITY_TIMEOUT_DEFAULT,
|
|
112282
112378
|
ENGINE_ACTIVITY_TIMEOUT_MAX,
|
|
112283
112379
|
ENGINE_ACTIVITY_TIMEOUT_MIN,
|
|
112284
|
-
ProbeAgent
|
|
112380
|
+
ProbeAgent,
|
|
112381
|
+
debugLogToolResults,
|
|
112382
|
+
debugTruncate
|
|
112285
112383
|
});
|
|
112286
112384
|
/*! Bundled license information:
|
|
112287
112385
|
|