@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/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 with proper cleanup
485
- // TODO: Implement AbortController support in ProbeAgent.answer() for proper cancellation
486
- // Current limitation: When timeout occurs, subagent.answer() continues running in background
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
- // Execute the task with timeout
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 response = await Promise.race([answerPromise, timeoutPromise]);
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
 
@@ -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;
@@ -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 response = await Promise.race([answerPromise, timeoutPromise]);
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, taskGuidancePrompt;
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
- - If the task tool is available, use it to break complex work into milestones before starting implementation.
97704
- - Stay flexible \u2014 if your understanding changes mid-task, add, remove, or reorganize tasks as needed. The plan should serve you, not constrain you.
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
- # After Implementation
97716
- - Verify the project builds successfully. If it doesn't, fix the build before moving on.
97717
- - Run lint and typecheck commands if known for the project. Fix any new warnings or errors you introduced.
97718
- - Add tests for any new or changed functionality. Tests must cover the main path and important edge cases.
97719
- - Run the project's full test suite. If any tests fail (including pre-existing ones you may have broken), fix them before finishing.
97720
- - When the task is done, respond to the user with a concise summary of what was implemented, what files were changed, and any relevant details. Include links (e.g. pull request URL) so the user has everything they need.
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