@probelabs/probe 0.6.0-rc311 → 0.6.0-rc313

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/cjs/index.cjs CHANGED
@@ -19642,7 +19642,7 @@ var init_dist2 = __esm({
19642
19642
  "ETIMEDOUT",
19643
19643
  "EPIPE"
19644
19644
  ];
19645
- VERSION = true ? "4.0.21" : "0.0.0-test";
19645
+ VERSION = true ? "4.0.22" : "0.0.0-test";
19646
19646
  suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
19647
19647
  suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
19648
19648
  ignoreOverride = /* @__PURE__ */ Symbol(
@@ -22410,33 +22410,36 @@ async function convertToBedrockChatMessages(prompt, isMistral = false) {
22410
22410
  providerOptions: part.providerOptions,
22411
22411
  schema: bedrockReasoningMetadataSchema
22412
22412
  });
22413
- if (reasoningMetadata != null) {
22414
- if (reasoningMetadata.signature != null) {
22415
- bedrockContent.push({
22416
- reasoningContent: {
22417
- reasoningText: {
22418
- // trim the last text part if it's the last message in the block
22419
- // because Bedrock does not allow trailing whitespace
22420
- // in pre-filled assistant responses
22421
- text: trimIfLast(
22422
- isLastBlock,
22423
- isLastMessage,
22424
- isLastContentPart,
22425
- part.text
22426
- ),
22427
- signature: reasoningMetadata.signature
22428
- }
22413
+ if ((reasoningMetadata == null ? void 0 : reasoningMetadata.signature) != null) {
22414
+ bedrockContent.push({
22415
+ reasoningContent: {
22416
+ reasoningText: {
22417
+ text: part.text,
22418
+ signature: reasoningMetadata.signature
22429
22419
  }
22430
- });
22431
- } else if (reasoningMetadata.redactedData != null) {
22432
- bedrockContent.push({
22433
- reasoningContent: {
22434
- redactedReasoning: {
22435
- data: reasoningMetadata.redactedData
22436
- }
22420
+ }
22421
+ });
22422
+ } else if ((reasoningMetadata == null ? void 0 : reasoningMetadata.redactedData) != null) {
22423
+ bedrockContent.push({
22424
+ reasoningContent: {
22425
+ redactedReasoning: {
22426
+ data: reasoningMetadata.redactedData
22437
22427
  }
22438
- });
22439
- }
22428
+ }
22429
+ });
22430
+ } else {
22431
+ bedrockContent.push({
22432
+ reasoningContent: {
22433
+ reasoningText: {
22434
+ text: trimIfLast(
22435
+ isLastBlock,
22436
+ isLastMessage,
22437
+ isLastContentPart,
22438
+ part.text
22439
+ )
22440
+ }
22441
+ }
22442
+ });
22440
22443
  }
22441
22444
  break;
22442
22445
  }
@@ -22882,7 +22885,17 @@ var init_dist3 = __esm({
22882
22885
  /**
22883
22886
  * Anthropic beta features to enable
22884
22887
  */
22885
- anthropicBeta: external_exports.array(external_exports.string()).optional()
22888
+ anthropicBeta: external_exports.array(external_exports.string()).optional(),
22889
+ /**
22890
+ * Service tier for the request.
22891
+ * @see https://docs.aws.amazon.com/bedrock/latest/userguide/service-tiers-inference.html
22892
+ *
22893
+ * - 'reserved': Uses provisioned throughput capacity
22894
+ * - 'priority': Prioritizes low-latency inference when capacity is available
22895
+ * - 'default': Standard on-demand tier
22896
+ * - 'flex': Lower-cost tier for flexible latency workloads
22897
+ */
22898
+ serviceTier: external_exports.enum(["reserved", "priority", "default", "flex"]).optional()
22886
22899
  });
22887
22900
  BedrockErrorSchema = external_exports.object({
22888
22901
  message: external_exports.string(),
@@ -23172,6 +23185,7 @@ var init_dist3 = __esm({
23172
23185
  const {
23173
23186
  reasoningConfig: _,
23174
23187
  additionalModelRequestFields: __,
23188
+ serviceTier: ___,
23175
23189
  ...filteredBedrockOptions
23176
23190
  } = (providerOptions == null ? void 0 : providerOptions.bedrock) || {};
23177
23191
  const additionalModelResponseFieldPaths = isAnthropicModel ? ["/delta/stop_sequence"] : void 0;
@@ -23186,6 +23200,11 @@ var init_dist3 = __esm({
23186
23200
  ...Object.keys(inferenceConfig).length > 0 && {
23187
23201
  inferenceConfig
23188
23202
  },
23203
+ ...bedrockOptions.serviceTier != null && {
23204
+ serviceTier: {
23205
+ type: bedrockOptions.serviceTier
23206
+ }
23207
+ },
23189
23208
  ...filteredBedrockOptions,
23190
23209
  ...toolConfig.tools !== void 0 && toolConfig.tools.length > 0 ? { toolConfig } : {}
23191
23210
  },
@@ -24094,7 +24113,7 @@ var init_dist3 = __esm({
24094
24113
  details: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
24095
24114
  preview: external_exports.unknown().optional()
24096
24115
  });
24097
- VERSION2 = true ? "4.0.82" : "0.0.0-test";
24116
+ VERSION2 = true ? "4.0.89" : "0.0.0-test";
24098
24117
  bedrockRerankingResponseSchema = lazySchema(
24099
24118
  () => zodSchema(
24100
24119
  external_exports.object({
@@ -26268,10 +26287,28 @@ var init_simpleTelemetry = __esm({
26268
26287
  }
26269
26288
  }
26270
26289
  };
26271
- SimpleAppTracer = class {
26272
- constructor(telemetry, sessionId = null) {
26290
+ SimpleAppTracer = class _SimpleAppTracer {
26291
+ constructor(telemetry, sessionId = null, options = {}) {
26273
26292
  this.telemetry = telemetry;
26274
26293
  this.sessionId = sessionId || this.generateSessionId();
26294
+ this.parentSessionId = options.parentSessionId || null;
26295
+ this.rootSessionId = options.rootSessionId || this.sessionId;
26296
+ this.agentKind = options.agentKind || "main";
26297
+ }
26298
+ /**
26299
+ * Create a child tracer for a delegated subagent.
26300
+ * Inherits the same telemetry backend but scopes events to the child session.
26301
+ * @param {string} childSessionId - The subagent's session ID
26302
+ * @param {Object} [options] - Additional options
26303
+ * @param {string} [options.agentKind='delegate'] - Kind of child agent
26304
+ * @returns {SimpleAppTracer} A new tracer scoped to the child session
26305
+ */
26306
+ createChildTracer(childSessionId, options = {}) {
26307
+ return new _SimpleAppTracer(this.telemetry, childSessionId, {
26308
+ parentSessionId: this.sessionId,
26309
+ rootSessionId: this.rootSessionId,
26310
+ agentKind: options.agentKind || "delegate"
26311
+ });
26275
26312
  }
26276
26313
  generateSessionId() {
26277
26314
  return Math.random().toString(36).substring(2, 15);
@@ -27277,11 +27314,21 @@ var init_TaskManager = __esm({
27277
27314
  const blockers = task.dependencies.filter((depId) => !this._isDependencyResolved(depId));
27278
27315
  let line = ` <task id="${this._escapeXml(task.id)}" status="${this._escapeXml(task.status)}"`;
27279
27316
  if (task.priority) line += ` priority="${this._escapeXml(task.priority)}"`;
27317
+ if (task.dependencies.length > 0) line += ` depends_on="${this._escapeXml(task.dependencies.join(","))}"`;
27280
27318
  if (blockers.length > 0) line += ` blocked_by="${this._escapeXml(blockers.join(","))}"`;
27281
27319
  line += `>${this._escapeXml(task.title)}</task>`;
27282
27320
  return line;
27283
27321
  });
27322
+ let completed = 0, inProgress = 0, pending = 0, cancelled = 0;
27323
+ for (const t of tasks) {
27324
+ if (t.status === "completed") completed++;
27325
+ else if (t.status === "in_progress") inProgress++;
27326
+ else if (t.status === "pending") pending++;
27327
+ else if (t.status === "cancelled") cancelled++;
27328
+ }
27329
+ const statusLine = ` <!-- ${completed}/${tasks.length} completed` + (inProgress > 0 ? `, ${inProgress} in progress` : "") + (pending > 0 ? `, ${pending} pending` : "") + (cancelled > 0 ? `, ${cancelled} cancelled` : "") + ` -->`;
27284
27330
  return `<task_status>
27331
+ ${statusLine}
27285
27332
  ${taskLines.join("\n")}
27286
27333
  </task_status>`;
27287
27334
  }
@@ -27415,24 +27462,76 @@ var init_zod = __esm({
27415
27462
 
27416
27463
  // src/agent/tasks/taskTool.js
27417
27464
  function createTaskCompletionBlockedMessage(taskSummary) {
27418
- return `You cannot complete yet. The following tasks are still unresolved:
27465
+ return `<task_completion_blocked>
27466
+ You CANNOT provide a final answer yet. There are unresolved tasks:
27419
27467
 
27420
27468
  ${taskSummary}
27421
27469
 
27422
- For each pending/in_progress task, either:
27423
- - Complete it: call task tool with action="complete", id="task-X"
27424
- - Cancel it: call task tool with action="update", id="task-X", status="cancelled"
27470
+ <required_actions>
27471
+ For EACH unresolved task, do ONE of the following RIGHT NOW:
27472
+ - Work is DONE \u2192 action="complete", id="<task-id>"
27473
+ - Work is NOT needed \u2192 action="update", id="<task-id>", status="cancelled"
27474
+ - Work is BLOCKED \u2192 complete its dependencies first, then return to it
27475
+ - Work is NOT started \u2192 set to "in_progress" and do the work, then complete it
27476
+ </required_actions>
27425
27477
 
27426
- After all tasks are resolved, provide your final answer.`;
27478
+ You will continue to be blocked until every task is completed or cancelled.
27479
+ </task_completion_blocked>`;
27480
+ }
27481
+ function safeStringify(value) {
27482
+ try {
27483
+ return JSON.stringify(value);
27484
+ } catch {
27485
+ return "[]";
27486
+ }
27487
+ }
27488
+ function serializeTask(task, index) {
27489
+ return {
27490
+ id: task.id,
27491
+ title: task.title,
27492
+ status: task.status,
27493
+ priority: task.priority || null,
27494
+ dependencies: task.dependencies || [],
27495
+ after: null,
27496
+ // 'after' is an insertion hint, not stored on the task
27497
+ order: index
27498
+ };
27427
27499
  }
27428
27500
  function createTaskTool(options = {}) {
27429
- const { taskManager, tracer, debug = false } = options;
27501
+ const { taskManager, tracer, debug = false, delegationTask = null } = options;
27430
27502
  if (!taskManager) {
27431
27503
  throw new Error("TaskManager instance is required");
27432
27504
  }
27505
+ const getAgentScope = () => {
27506
+ if (!tracer) return {};
27507
+ return {
27508
+ "agent.session_id": tracer.sessionId || null,
27509
+ "agent.parent_session_id": tracer.parentSessionId || null,
27510
+ "agent.root_session_id": tracer.rootSessionId || null,
27511
+ "agent.kind": tracer.agentKind || "main",
27512
+ ...delegationTask ? { "delegation.task": delegationTask } : {}
27513
+ };
27514
+ };
27515
+ const getListContext = (allTasks) => {
27516
+ const all = allTasks || taskManager.listTasks();
27517
+ const incompleteCount = all.filter((t) => t.status !== "completed" && t.status !== "cancelled").length;
27518
+ return {
27519
+ "task.total_count": all.length,
27520
+ "task.incomplete_remaining": incompleteCount
27521
+ };
27522
+ };
27433
27523
  const recordTaskEvent = (eventType, data2 = {}) => {
27434
27524
  if (tracer && typeof tracer.recordTaskEvent === "function") {
27435
- tracer.recordTaskEvent(eventType, data2);
27525
+ if (_globalSequence >= Number.MAX_SAFE_INTEGER) _globalSequence = 0;
27526
+ try {
27527
+ tracer.recordTaskEvent(eventType, {
27528
+ "task.sequence": ++_globalSequence,
27529
+ ...getAgentScope(),
27530
+ ...data2
27531
+ });
27532
+ } catch (err) {
27533
+ if (debug) console.error("[TaskTool] Failed to record telemetry event:", err);
27534
+ }
27436
27535
  }
27437
27536
  };
27438
27537
  return {
@@ -27466,26 +27565,31 @@ function createTaskTool(options = {}) {
27466
27565
  case "create": {
27467
27566
  if (tasks && Array.isArray(tasks)) {
27468
27567
  const created = taskManager.createTasks(tasks);
27469
- const ids = created.map((t) => t.id).join(", ");
27568
+ const allTasks = taskManager.listTasks();
27569
+ const taskIndex = new Map(allTasks.map((t, i) => [t.id, i]));
27470
27570
  recordTaskEvent("batch_created", {
27471
27571
  "task.action": "create",
27472
27572
  "task.count": created.length,
27473
- "task.ids": ids,
27474
- "task.total_count": taskManager.listTasks().length
27573
+ "task.items_json": safeStringify(created.map((t) => serializeTask(t, taskIndex.get(t.id) ?? 0))),
27574
+ ...getListContext(allTasks)
27475
27575
  });
27476
- return `Created ${created.length} tasks: ${ids}
27576
+ return `Created ${created.length} tasks: ${created.map((t) => t.id).join(", ")}
27477
27577
 
27478
27578
  ${taskManager.formatTasksForPrompt()}`;
27479
27579
  } else if (title) {
27480
27580
  const task = taskManager.createTask({ title, description, priority, dependencies, after });
27581
+ const allTasks = taskManager.listTasks();
27582
+ const order = allTasks.findIndex((t) => t.id === task.id);
27481
27583
  recordTaskEvent("created", {
27482
27584
  "task.action": "create",
27483
27585
  "task.id": task.id,
27484
- "task.title": title,
27485
- "task.priority": priority || "none",
27486
- "task.has_dependencies": dependencies && dependencies.length > 0,
27487
- "task.after": after || "none",
27488
- "task.total_count": taskManager.listTasks().length
27586
+ "task.title": task.title,
27587
+ "task.status": task.status,
27588
+ "task.priority": task.priority || null,
27589
+ "task.dependencies": safeStringify(task.dependencies || []),
27590
+ "task.after": after || null,
27591
+ "task.order": order,
27592
+ ...getListContext(allTasks)
27489
27593
  });
27490
27594
  return `Created task ${task.id}: ${task.title}
27491
27595
 
@@ -27497,13 +27601,15 @@ ${taskManager.formatTasksForPrompt()}`;
27497
27601
  case "update": {
27498
27602
  if (tasks && Array.isArray(tasks)) {
27499
27603
  const updated = taskManager.updateTasks(tasks);
27500
- const ids = updated.map((t) => t.id).join(", ");
27604
+ const allTasks = taskManager.listTasks();
27605
+ const taskIndex = new Map(allTasks.map((t, i) => [t.id, i]));
27501
27606
  recordTaskEvent("batch_updated", {
27502
27607
  "task.action": "update",
27503
27608
  "task.count": updated.length,
27504
- "task.ids": ids
27609
+ "task.items_json": safeStringify(updated.map((t) => serializeTask(t, taskIndex.get(t.id) ?? 0))),
27610
+ ...getListContext(allTasks)
27505
27611
  });
27506
- return `Updated ${updated.length} tasks: ${ids}
27612
+ return `Updated ${updated.length} tasks: ${updated.map((t) => t.id).join(", ")}
27507
27613
 
27508
27614
  ${taskManager.formatTasksForPrompt()}`;
27509
27615
  } else if (id) {
@@ -27514,11 +27620,18 @@ ${taskManager.formatTasksForPrompt()}`;
27514
27620
  if (priority) updates.priority = priority;
27515
27621
  if (dependencies) updates.dependencies = dependencies;
27516
27622
  const task = taskManager.updateTask(id, updates);
27623
+ const allTasks = taskManager.listTasks();
27624
+ const order = allTasks.findIndex((t) => t.id === task.id);
27517
27625
  recordTaskEvent("updated", {
27518
27626
  "task.action": "update",
27519
- "task.id": id,
27520
- "task.new_status": status || "unchanged",
27521
- "task.fields_updated": Object.keys(updates).join(", ")
27627
+ "task.id": task.id,
27628
+ "task.title": task.title,
27629
+ "task.status": task.status,
27630
+ "task.priority": task.priority || null,
27631
+ "task.dependencies": safeStringify(task.dependencies || []),
27632
+ "task.order": order,
27633
+ "task.fields_updated": Object.keys(updates).join(", "),
27634
+ ...getListContext(allTasks)
27522
27635
  });
27523
27636
  return `Updated task ${task.id}
27524
27637
 
@@ -27535,22 +27648,30 @@ ${taskManager.formatTasksForPrompt()}`;
27535
27648
  throw new Error(`Invalid task item at index ${index}: must be a string ID or object with 'id' property`);
27536
27649
  });
27537
27650
  const completed = taskManager.completeTasks(ids);
27651
+ const allTasks = taskManager.listTasks();
27652
+ const taskIndex = new Map(allTasks.map((t, i) => [t.id, i]));
27538
27653
  recordTaskEvent("batch_completed", {
27539
27654
  "task.action": "complete",
27540
27655
  "task.count": completed.length,
27541
- "task.ids": ids.join(", "),
27542
- "task.incomplete_remaining": taskManager.getIncompleteTasks().length
27656
+ "task.items_json": safeStringify(completed.map((t) => serializeTask(t, taskIndex.get(t.id) ?? 0))),
27657
+ ...getListContext(allTasks)
27543
27658
  });
27544
27659
  return `Completed ${completed.length} tasks
27545
27660
 
27546
27661
  ${taskManager.formatTasksForPrompt()}`;
27547
27662
  } else if (id) {
27548
27663
  const task = taskManager.completeTask(id);
27664
+ const allTasks = taskManager.listTasks();
27665
+ const order = allTasks.findIndex((t) => t.id === task.id);
27549
27666
  recordTaskEvent("completed", {
27550
27667
  "task.action": "complete",
27551
- "task.id": id,
27668
+ "task.id": task.id,
27552
27669
  "task.title": task.title,
27553
- "task.incomplete_remaining": taskManager.getIncompleteTasks().length
27670
+ "task.status": task.status,
27671
+ "task.priority": task.priority || null,
27672
+ "task.dependencies": safeStringify(task.dependencies || []),
27673
+ "task.order": order,
27674
+ ...getListContext(allTasks)
27554
27675
  });
27555
27676
  return `Completed task ${task.id}: ${task.title}
27556
27677
 
@@ -27566,22 +27687,26 @@ ${taskManager.formatTasksForPrompt()}`;
27566
27687
  if (t && typeof t.id === "string") return t.id;
27567
27688
  throw new Error(`Invalid task item at index ${index}: must be a string ID or object with 'id' property`);
27568
27689
  });
27690
+ const tasksBefore = ids.map((tid) => taskManager.getTask(tid)).filter(Boolean);
27569
27691
  const deleted = taskManager.deleteTasks(ids);
27570
27692
  recordTaskEvent("batch_deleted", {
27571
27693
  "task.action": "delete",
27572
27694
  "task.count": deleted.length,
27573
- "task.ids": deleted.join(", "),
27574
- "task.total_count": taskManager.listTasks().length
27695
+ "task.items_json": safeStringify(tasksBefore.map((t, i) => ({ id: t.id, title: t.title, status: t.status }))),
27696
+ ...getListContext()
27575
27697
  });
27576
27698
  return `Deleted ${deleted.length} tasks: ${deleted.join(", ")}
27577
27699
 
27578
27700
  ${taskManager.formatTasksForPrompt()}`;
27579
27701
  } else if (id) {
27702
+ const taskBefore = taskManager.getTask(id);
27580
27703
  taskManager.deleteTask(id);
27581
27704
  recordTaskEvent("deleted", {
27582
27705
  "task.action": "delete",
27583
27706
  "task.id": id,
27584
- "task.total_count": taskManager.listTasks().length
27707
+ "task.title": taskBefore?.title || null,
27708
+ "task.status": taskBefore?.status || null,
27709
+ ...getListContext()
27585
27710
  });
27586
27711
  return `Deleted task ${id}
27587
27712
 
@@ -27592,12 +27717,13 @@ ${taskManager.formatTasksForPrompt()}`;
27592
27717
  }
27593
27718
  case "list": {
27594
27719
  const allTasks = taskManager.listTasks();
27595
- const incomplete = taskManager.getIncompleteTasks();
27720
+ const ctx = getListContext(allTasks);
27596
27721
  recordTaskEvent("listed", {
27597
27722
  "task.action": "list",
27598
- "task.total_count": allTasks.length,
27599
- "task.incomplete_count": incomplete.length,
27600
- "task.completed_count": allTasks.length - incomplete.length
27723
+ "task.total_count": ctx["task.total_count"],
27724
+ "task.incomplete_count": ctx["task.incomplete_remaining"],
27725
+ "task.completed_count": ctx["task.total_count"] - ctx["task.incomplete_remaining"],
27726
+ "task.items_json": safeStringify(allTasks.map((t, i) => serializeTask(t, i)))
27601
27727
  });
27602
27728
  return taskManager.formatTasksForPrompt();
27603
27729
  }
@@ -27620,7 +27746,7 @@ ${taskManager.formatTasksForPrompt()}`;
27620
27746
  }
27621
27747
  };
27622
27748
  }
27623
- var taskItemSchema, taskSchema, taskSystemPrompt;
27749
+ var taskItemSchema, taskSchema, taskSystemPrompt, _globalSequence;
27624
27750
  var init_taskTool = __esm({
27625
27751
  "src/agent/tasks/taskTool.js"() {
27626
27752
  "use strict";
@@ -27646,41 +27772,138 @@ var init_taskTool = __esm({
27646
27772
  dependencies: external_exports2.array(external_exports2.string()).optional(),
27647
27773
  after: external_exports2.string().optional()
27648
27774
  });
27649
- taskSystemPrompt = `[Task Management]
27775
+ taskSystemPrompt = `<task_management_system>
27650
27776
 
27651
- Use the task tool to track progress on complex requests with multiple distinct goals.
27777
+ <purpose>
27778
+ Track progress on requests with multiple distinct goals using the task tool.
27779
+ Tasks are visible to the user in real time \u2014 keeping them accurate is critical.
27780
+ </purpose>
27652
27781
 
27653
- ## When to Use Tasks
27654
-
27655
- CREATE tasks when the request has **multiple separate deliverables**:
27782
+ <when_to_use_tasks>
27783
+ CREATE tasks when the request has multiple separate deliverables:
27656
27784
  - "Fix bug A AND add feature B" \u2192 two tasks
27657
27785
  - "Investigate auth, payments, AND notifications" \u2192 three tasks
27658
- - "Implement X, then add tests, then update docs" \u2192 three sequential tasks
27786
+ - "Implement X, then add tests, then update docs" \u2192 three sequential tasks with dependencies
27659
27787
 
27660
- SKIP tasks for single-goal requests, even complex ones:
27661
- - "How does ranking work?" \u2014 just investigate and answer
27662
- - "Explain the authentication flow" \u2014 just trace and explain
27788
+ DO NOT create tasks for single-goal requests, even complex ones:
27789
+ - "How does ranking work?" \u2192 just investigate and answer
27790
+ - "Explain the authentication flow" \u2192 just trace and explain
27663
27791
  Multiple internal steps (search, read, analyze) for one goal \u2260 multiple tasks.
27664
27792
 
27665
- ## Granularity
27666
-
27667
- Tasks = logical units of work, not files or steps.
27793
+ Granularity: tasks = logical units of work, not individual files or steps.
27668
27794
  - "Fix 8 similar test files" \u2192 ONE task (same fix repeated)
27669
27795
  - "Update API + tests + docs" \u2192 THREE tasks (different work types)
27670
- - Max 3\u20134 tasks. More means you're too granular.
27671
-
27672
- ## Workflow
27673
-
27674
- 1. **Plan**: Call task tool with action="create" and a tasks array up front
27675
- 2. **Execute**: Update status to "in_progress" / "completed" as you work. Add, split, or cancel tasks as you learn more.
27676
- 3. **Finish**: All tasks must be "completed" or "cancelled" before providing your final answer.
27677
-
27678
- ## Rules
27679
-
27680
- - Dependencies are enforced: a task cannot start until its dependencies are completed
27796
+ </when_to_use_tasks>
27797
+
27798
+ <dependency_chains>
27799
+ Use dependencies to enforce ordering. A task CANNOT start until ALL its dependencies are completed.
27800
+
27801
+ <pattern name="sequential_chain" description="Tasks that must happen in strict order">
27802
+ tasks: [
27803
+ { id: "design", title: "Design the API schema" },
27804
+ { id: "implement", title: "Implement endpoints", dependencies: ["design"] },
27805
+ { id: "test", title: "Write integration tests", dependencies: ["implement"] }
27806
+ ]
27807
+ Result: design \u2192 implement \u2192 test. "implement" is blocked until "design" is completed.
27808
+ </pattern>
27809
+
27810
+ <pattern name="fan_out" description="Multiple tasks unlock after one prerequisite">
27811
+ tasks: [
27812
+ { id: "setup", title: "Set up database" },
27813
+ { id: "auth", title: "Add auth module", dependencies: ["setup"] },
27814
+ { id: "api", title: "Add API routes", dependencies: ["setup"] }
27815
+ ]
27816
+ Result: both "auth" and "api" become ready once "setup" is completed.
27817
+ </pattern>
27818
+
27819
+ <pattern name="fan_in" description="One task waits for multiple prerequisites">
27820
+ tasks: [
27821
+ { id: "auth", title: "Auth module" },
27822
+ { id: "api", title: "API routes" },
27823
+ { id: "e2e", title: "End-to-end tests", dependencies: ["auth", "api"] }
27824
+ ]
27825
+ Result: "e2e" is blocked until both "auth" and "api" are completed.
27826
+ </pattern>
27827
+ </dependency_chains>
27828
+
27829
+ <modifying_tasks_mid_work>
27830
+ When new requirements emerge during execution, modify the task plan dynamically.
27831
+
27832
+ <technique name="add_subtask">
27833
+ Add a new task after an existing one, with a dependency to enforce order:
27834
+ action: "create", id: "fix-edge-case", title: "Handle null input edge case",
27835
+ dependencies: ["implement"], after: "implement"
27836
+ </technique>
27837
+
27838
+ <technique name="split_task">
27839
+ If a task is bigger than expected, create subtasks with dependencies on it, then complete or cancel the original.
27840
+ </technique>
27841
+
27842
+ <technique name="insert_into_chain">
27843
+ Insert a new task between two existing tasks in a chain:
27844
+ Step 1 \u2014 Create the new task depending on the predecessor:
27845
+ action: "create", id: "review", title: "Code review", dependencies: ["implement"], after: "implement"
27846
+ Step 2 \u2014 Update the successor to depend on the new task:
27847
+ action: "update", id: "test", dependencies: ["review"]
27848
+ Original: design \u2192 implement \u2192 test
27849
+ Result: design \u2192 implement \u2192 review \u2192 test
27850
+ </technique>
27851
+ </modifying_tasks_mid_work>
27852
+
27853
+ <workflow_rules>
27854
+ These rules are MANDATORY. Violating them produces incorrect progress tracking.
27855
+
27856
+ <rule id="1" name="plan_first">
27857
+ Call task tool with action="create" and a tasks array BEFORE starting any work.
27858
+ Use dependencies to express ordering constraints between tasks.
27859
+ </rule>
27860
+
27861
+ <rule id="2" name="mark_in_progress">
27862
+ Set the current task to status="in_progress" BEFORE you begin working on it.
27863
+ Only one task should be in_progress at a time.
27864
+ </rule>
27865
+
27866
+ <rule id="3" name="complete_immediately" priority="critical">
27867
+ The MOMENT you finish a task's work, call the task tool with action="complete" for that task.
27868
+ Do this in the SAME response \u2014 not in the next step, not at the end, not batched with other completions.
27869
+ Every task must be completed the instant its work is verified done.
27870
+ </rule>
27871
+
27872
+ <rule id="4" name="verify_before_completing">
27873
+ Do NOT mark a task completed unless you have verified the result:
27874
+ - Code compiles without errors
27875
+ - Tests pass
27876
+ - Output is correct and complete
27877
+ "I wrote the code" is NOT sufficient \u2014 you must confirm it works.
27878
+ </rule>
27879
+
27880
+ <rule id="5" name="respect_dependencies">
27881
+ NEVER work on a task whose dependencies are not yet completed.
27882
+ The task list shows blocked_by attributes \u2014 check them. If a task is blocked, complete its blockers first.
27883
+ </rule>
27884
+
27885
+ <rule id="6" name="adapt_the_plan">
27886
+ If you discover new work during execution, create new tasks with proper dependencies.
27887
+ Do NOT silently do extra work without tracking it in the task list.
27888
+ If a task needs subtasks, create them as new tasks depending on the current one.
27889
+ </rule>
27890
+
27891
+ <rule id="7" name="finish_clean">
27892
+ ALL tasks must be "completed" or "cancelled" before you provide your final answer.
27893
+ You CANNOT finish with pending or in_progress tasks. The system will block you.
27894
+ </rule>
27895
+ </workflow_rules>
27896
+
27897
+ <system_enforcement>
27898
+ - Dependencies are strictly enforced: blocked tasks cannot be started
27681
27899
  - Circular dependencies are rejected
27682
- - Completion is blocked while tasks remain unresolved
27900
+ - You will be blocked from finishing while tasks remain unresolved
27901
+ - Task status is visible to the user in real time \u2014 stale status is misleading
27902
+ </system_enforcement>
27903
+
27904
+ </task_management_system>
27683
27905
  `;
27906
+ _globalSequence = 0;
27684
27907
  }
27685
27908
  });
27686
27909
 
@@ -28521,7 +28744,7 @@ var require_brace_expansion = __commonJS({
28521
28744
  var x = numeric(n[0]);
28522
28745
  var y = numeric(n[1]);
28523
28746
  var width = Math.max(n[0].length, n[1].length);
28524
- var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1;
28747
+ var incr = n.length == 3 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
28525
28748
  var test = lte;
28526
28749
  var reverse = y < x;
28527
28750
  if (reverse) {
@@ -66171,12 +66394,12 @@ var require_code = __commonJS({
66171
66394
  exports2._ = _;
66172
66395
  var plus = new _Code("+");
66173
66396
  function str(strs, ...args) {
66174
- const expr = [safeStringify(strs[0])];
66397
+ const expr = [safeStringify2(strs[0])];
66175
66398
  let i = 0;
66176
66399
  while (i < args.length) {
66177
66400
  expr.push(plus);
66178
66401
  addCodeArg(expr, args[i]);
66179
- expr.push(plus, safeStringify(strs[++i]));
66402
+ expr.push(plus, safeStringify2(strs[++i]));
66180
66403
  }
66181
66404
  optimize(expr);
66182
66405
  return new _Code(expr);
@@ -66228,16 +66451,16 @@ var require_code = __commonJS({
66228
66451
  }
66229
66452
  exports2.strConcat = strConcat;
66230
66453
  function interpolate(x) {
66231
- return typeof x == "number" || typeof x == "boolean" || x === null ? x : safeStringify(Array.isArray(x) ? x.join(",") : x);
66454
+ return typeof x == "number" || typeof x == "boolean" || x === null ? x : safeStringify2(Array.isArray(x) ? x.join(",") : x);
66232
66455
  }
66233
66456
  function stringify(x) {
66234
- return new _Code(safeStringify(x));
66457
+ return new _Code(safeStringify2(x));
66235
66458
  }
66236
66459
  exports2.stringify = stringify;
66237
- function safeStringify(x) {
66460
+ function safeStringify2(x) {
66238
66461
  return JSON.stringify(x).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
66239
66462
  }
66240
- exports2.safeStringify = safeStringify;
66463
+ exports2.safeStringify = safeStringify2;
66241
66464
  function getProperty(key) {
66242
66465
  return typeof key == "string" && exports2.IDENTIFIER.test(key) ? new _Code(`.${key}`) : _`[${key}]`;
66243
66466
  }
@@ -97790,6 +98013,7 @@ var init_ProbeAgent = __esm({
97790
98013
  this._mcpInitialized = false;
97791
98014
  this.enableTasks = !!options.enableTasks;
97792
98015
  this.taskManager = null;
98016
+ this.delegationTask = options.delegationTask || null;
97793
98017
  this.delegationManager = new DelegationManager();
97794
98018
  this.concurrencyLimiter = options.concurrencyLimiter || null;
97795
98019
  this.requestTimeout = options.requestTimeout ?? (() => {
@@ -100236,12 +100460,17 @@ You are working with a workspace. Available paths: ${workspaceDesc}
100236
100460
  this.toolImplementations.task = createTaskTool({
100237
100461
  taskManager: this.taskManager,
100238
100462
  tracer: this.tracer,
100239
- debug: this.debug
100463
+ debug: this.debug,
100464
+ delegationTask: this.delegationTask
100240
100465
  });
100241
100466
  }
100242
100467
  if (this.tracer && typeof this.tracer.recordTaskEvent === "function") {
100243
100468
  this.tracer.recordTaskEvent("session_started", {
100244
- "task.enabled": true
100469
+ "task.enabled": true,
100470
+ "agent.session_id": this.tracer?.sessionId ?? null,
100471
+ "agent.parent_session_id": this.tracer?.parentSessionId ?? null,
100472
+ "agent.root_session_id": this.tracer?.rootSessionId ?? null,
100473
+ "agent.kind": this.tracer?.agentKind ?? "main"
100245
100474
  });
100246
100475
  }
100247
100476
  if (this.debug) {
@@ -100798,7 +101027,27 @@ IMPORTANT: This is a time budget constraint, NOT a system shutdown or error. The
100798
101027
 
100799
101028
  Do NOT say things like "the system is shutting down" or "try again later" \u2014 the user submitted a request and is waiting for YOUR answer right now.
100800
101029
 
100801
- Provide your BEST answer NOW using the information you have already gathered. Do NOT call any more tools. Summarize your findings and respond completely. If something was not completed, honestly state what was not done and provide any partial results or recommendations you can offer.`
101030
+ You MUST now produce a detailed PROGRESS REPORT so that a follow-up agent can continue your work without starting over. Structure your response as follows:
101031
+
101032
+ ## Task
101033
+ What was the original request / goal.
101034
+
101035
+ ## Completed Work
101036
+ What you successfully accomplished \u2014 include ALL findings, code snippets, file paths, data, and conclusions gathered. Be specific and include actual content, not just descriptions.
101037
+
101038
+ ## Key Findings
101039
+ Concrete facts, answers, or data points you discovered. Include file paths with line numbers, code snippets, configuration values, etc.
101040
+
101041
+ ## Attempted but Inconclusive
101042
+ What you tried that did not yield clear results \u2014 include the approach and why it was inconclusive, so the next agent does not repeat it.
101043
+
101044
+ ## Not Started / Remaining
101045
+ What parts of the task you did not get to, and any recommendations for how to approach them.
101046
+
101047
+ ## Suggested Next Steps
101048
+ Specific, actionable steps for a follow-up agent to continue this work efficiently.
101049
+
101050
+ IMPORTANT: Include ALL useful data you gathered inline \u2014 do not just say "I found X", actually include X. The next agent will only see this report, not your tool call history.`
100802
101051
  };
100803
101052
  }
100804
101053
  if (this.debug) {
@@ -100807,11 +101056,39 @@ Provide your BEST answer NOW using the information you have already gathered. Do
100807
101056
  return { toolChoice: "none" };
100808
101057
  }
100809
101058
  if (stepNumber === maxIterations - 1) {
100810
- const searchesTried = _toolCallLog.filter((tc) => tc.name === "search").map((tc) => `"${tc.args.query || ""}"${tc.args.exact ? " (exact)" : ""}`).filter((v, i, a) => a.indexOf(v) === i);
100811
- const searchSummary = searchesTried.length > 0 ? `
100812
- Searches attempted: ${searchesTried.join(", ")}` : "";
101059
+ const toolActivity = _toolCallLog.filter((tc) => tc.name !== "_assistant_text").map((tc) => {
101060
+ const argStr = tc.name === "search" ? `query="${tc.args.query || ""}"${tc.args.exact ? " exact" : ""} path=${tc.args.path || "."}` : JSON.stringify(tc.args || {}).substring(0, 200);
101061
+ const brief = tc.resultBrief ? ` \u2192 ${tc.resultBrief.substring(0, 150)}` : "";
101062
+ return ` [step ${tc.step}] ${tc.name}(${argStr})${brief}`;
101063
+ }).join("\n");
101064
+ const activityLog = toolActivity ? `
101065
+
101066
+ Tool activity so far:
101067
+ ${toolActivity}` : "";
100813
101068
  const isCodeSearcher = this.promptType === "code-searcher";
100814
- const lastIterMessage = isCodeSearcher ? `\u26A0\uFE0F LAST ITERATION \u2014 you are out of tool calls. Output your JSON response NOW with whatever files you have verified so far. Set confidence to "low" if your search was incomplete. Include the "searches" array listing all search queries you made with their paths and outcomes.${searchSummary}` : `\u26A0\uFE0F LAST ITERATION \u2014 you are out of tool calls. Provide your BEST answer NOW with the information gathered so far. If you could not find what was requested, explain exactly what you searched for and why it did not work, so the caller can try a different approach.${searchSummary}`;
101069
+ const lastIterMessage = isCodeSearcher ? `\u26A0\uFE0F LAST ITERATION \u2014 you are out of tool calls. Output your JSON response NOW with whatever files you have verified so far. Set confidence to "low" if your search was incomplete. Include the "searches" array listing all search queries you made with their paths and outcomes.${activityLog}` : `\u26A0\uFE0F ITERATION LIMIT REACHED \u2014 you have no more tool calls. You MUST now produce a detailed PROGRESS REPORT so that a follow-up agent can continue your work without starting over.
101070
+
101071
+ Structure your response as follows:
101072
+
101073
+ ## Task
101074
+ What was the original request / goal.
101075
+
101076
+ ## Completed Work
101077
+ What you successfully accomplished \u2014 include ALL findings, code snippets, file paths, data, and conclusions gathered. Be specific and include actual content, not just descriptions.
101078
+
101079
+ ## Key Findings
101080
+ Concrete facts, answers, or data points you discovered. Include file paths with line numbers, code snippets, configuration values, etc.
101081
+
101082
+ ## Attempted but Inconclusive
101083
+ What you tried that did not yield clear results \u2014 include the approach and why it was inconclusive, so the next agent does not repeat it.
101084
+
101085
+ ## Not Started / Remaining
101086
+ What parts of the task you did not get to, and any recommendations for how to approach them.
101087
+
101088
+ ## Suggested Next Steps
101089
+ Specific, actionable steps for a follow-up agent to continue this work efficiently.
101090
+
101091
+ IMPORTANT: Include ALL useful data you gathered inline \u2014 do not just say "I found X", actually include X. The next agent will only see this report, not your tool call history.${activityLog}`;
100815
101092
  return {
100816
101093
  toolChoice: "none",
100817
101094
  userMessage: lastIterMessage
@@ -100894,10 +101171,27 @@ Double-check your response based on the criteria above. If everything looks good
100894
101171
  currentIteration++;
100895
101172
  toolContext.currentIteration = currentIteration;
100896
101173
  if (toolCalls?.length > 0) {
100897
- for (const tc of toolCalls) {
100898
- _toolCallLog.push({ name: tc.toolName, args: tc.args || {} });
101174
+ for (let i = 0; i < toolCalls.length; i++) {
101175
+ const tc = toolCalls[i];
101176
+ const tr = toolResults?.[i];
101177
+ let resultBrief = "";
101178
+ if (tr) {
101179
+ const raw = typeof tr.result === "string" ? tr.result : JSON.stringify(tr.result);
101180
+ resultBrief = raw ? raw.substring(0, 500) : "";
101181
+ }
101182
+ const tcArgs = tc.args || (typeof tc.input === "string" ? (() => {
101183
+ try {
101184
+ return JSON.parse(tc.input);
101185
+ } catch {
101186
+ return {};
101187
+ }
101188
+ })() : tc.input) || {};
101189
+ _toolCallLog.push({ name: tc.toolName, args: tcArgs, resultBrief, step: currentIteration });
100899
101190
  }
100900
101191
  }
101192
+ if (text && text.trim()) {
101193
+ _toolCallLog.push({ name: "_assistant_text", args: {}, resultBrief: text.substring(0, 1e3), step: currentIteration });
101194
+ }
100901
101195
  if (this.tracer) {
100902
101196
  const stepEvent = {
100903
101197
  "iteration": currentIteration,
@@ -101232,13 +101526,27 @@ Respond with ONLY valid JSON \u2014 no markdown, no explanation, no text outside
101232
101526
 
101233
101527
  IMPORTANT: This is a time budget constraint, NOT a system shutdown or error. The system is working perfectly \u2014 you simply used all your allocated time. Do NOT say things like "the system is shutting down" or "try again later." The user is waiting for your answer RIGHT NOW.
101234
101528
 
101235
- Please provide a DETAILED summary of:
101236
- 1. What you were asked to do (the original task)
101237
- 2. What you accomplished \u2014 include ALL findings, code snippets, data, and conclusions you gathered
101238
- 3. What was still in progress or not yet started
101239
- 4. Any partial results or recommendations you can offer based on what you found so far${taskContext}${schemaContext}
101529
+ You MUST produce a detailed PROGRESS REPORT so that a follow-up agent can continue your work without starting over. Structure your response with these sections:
101530
+
101531
+ ## Task
101532
+ What was the original request / goal.
101533
+
101534
+ ## Completed Work
101535
+ What you successfully accomplished \u2014 include ALL findings, code snippets, file paths, data, and conclusions gathered. Be specific and include actual content, not just descriptions.
101536
+
101537
+ ## Key Findings
101538
+ Concrete facts, answers, or data points you discovered. Include file paths with line numbers, code snippets, configuration values, etc.
101539
+
101540
+ ## Attempted but Inconclusive
101541
+ What you tried that did not yield clear results \u2014 include the approach and why it was inconclusive, so the next agent does not repeat it.
101240
101542
 
101241
- Be thorough \u2014 this is the user's only response. Include all useful information you collected.`;
101543
+ ## Not Started / Remaining
101544
+ What parts of the task you did not get to, and any recommendations for how to approach them.
101545
+
101546
+ ## Suggested Next Steps
101547
+ Specific, actionable steps for a follow-up agent to continue this work efficiently.${taskContext}${schemaContext}
101548
+
101549
+ IMPORTANT: Include ALL useful data you gathered inline \u2014 do not just say "I found X", actually include X. The next agent will only see this report, not your tool call history.`;
101242
101550
  const summaryMessages = [
101243
101551
  ...currentMessages,
101244
101552
  { role: "user", content: summaryPrompt }
@@ -101351,18 +101659,24 @@ Be thorough \u2014 this is the user's only response. Include all useful informat
101351
101659
  const searchQueries = [];
101352
101660
  const searchDetails = [];
101353
101661
  const toolCounts = {};
101662
+ const toolTimeline = [];
101354
101663
  for (const tc of _toolCallLog) {
101664
+ if (tc.name === "_assistant_text") continue;
101355
101665
  toolCounts[tc.name] = (toolCounts[tc.name] || 0) + 1;
101356
101666
  if (tc.name === "search") {
101357
101667
  const q = tc.args.query || "";
101358
101668
  const p = tc.args.path || ".";
101359
101669
  const exact = tc.args.exact ? " (exact)" : "";
101360
101670
  searchQueries.push(`"${q}"${exact}`);
101361
- searchDetails.push({ query: q, path: p, had_results: false });
101671
+ searchDetails.push({ query: q, path: p, had_results: !!(tc.resultBrief && tc.resultBrief.trim()) });
101362
101672
  }
101673
+ const argStr = tc.name === "search" ? `query="${tc.args.query || ""}"${tc.args.exact ? " exact" : ""}` : JSON.stringify(tc.args || {}).substring(0, 150);
101674
+ const brief = tc.resultBrief ? ` \u2192 ${tc.resultBrief.substring(0, 200)}` : " \u2192 (no result)";
101675
+ toolTimeline.push(` [step ${tc.step}] ${tc.name}(${argStr})${brief}`);
101363
101676
  }
101364
101677
  const toolBreakdown = Object.entries(toolCounts).map(([name15, count]) => `${name15}: ${count}x`).join(", ");
101365
101678
  const uniqueSearches = [...new Set(searchQueries)];
101679
+ const assistantTexts = _toolCallLog.filter((tc) => tc.name === "_assistant_text" && tc.resultBrief).map((tc) => tc.resultBrief);
101366
101680
  if (this.promptType === "code-searcher") {
101367
101681
  finalResult = JSON.stringify({
101368
101682
  confidence: "low",
@@ -101371,17 +101685,33 @@ Be thorough \u2014 this is the user's only response. Include all useful informat
101371
101685
  searches: searchDetails
101372
101686
  });
101373
101687
  } else {
101374
- let summary = `I was unable to complete your request after ${currentIteration} tool iterations.
101688
+ let summary = `## Progress Report (iteration limit reached after ${currentIteration} steps)
101375
101689
 
101376
101690
  `;
101377
- summary += `Tool calls made: ${toolBreakdown || "none"}
101691
+ summary += `### Tool Usage Summary
101692
+ ${toolBreakdown || "none"}
101693
+
101378
101694
  `;
101379
101695
  if (uniqueSearches.length > 0) {
101380
- summary += `Search queries tried: ${uniqueSearches.join(", ")}
101696
+ summary += `### Search Queries Attempted
101697
+ ${uniqueSearches.join(", ")}
101698
+
101381
101699
  `;
101382
101700
  }
101383
- summary += `
101384
- The search approach may be fundamentally wrong for this query. Consider: using exact=true for literal string matching, using bash/grep for pattern-based file searches, or trying a completely different strategy instead of repeating similar searches.`;
101701
+ if (toolTimeline.length > 0) {
101702
+ summary += `### Step-by-Step Activity Log
101703
+ ${toolTimeline.join("\n")}
101704
+
101705
+ `;
101706
+ }
101707
+ if (assistantTexts.length > 0) {
101708
+ summary += `### Partial Findings
101709
+ ${assistantTexts.join("\n\n")}
101710
+
101711
+ `;
101712
+ }
101713
+ summary += `### Recommendation for Follow-Up
101714
+ The iteration limit was reached before the task could be completed. A follow-up agent should review the activity log above to avoid repeating the same searches, and consider alternative approaches such as: using exact=true for literal string matching, using bash/grep for pattern-based file searches, or trying a different strategy.`;
101385
101715
  finalResult = summary;
101386
101716
  }
101387
101717
  } catch {
@@ -102160,7 +102490,8 @@ async function delegate({
102160
102490
  // Simpler responses
102161
102491
  maxIterations: remainingIterations,
102162
102492
  debug,
102163
- tracer,
102493
+ tracer: tracer && typeof tracer.createChildTracer === "function" ? tracer.createChildTracer(sessionId, { agentKind: "delegate" }) : (tracer && debug && console.warn("[delegate] createChildTracer not available, using parent tracer \u2014 events will not be scoped to subagent"), tracer),
102494
+ delegationTask: task,
102164
102495
  path: path9,
102165
102496
  // Workspace root (from delegateTool)
102166
102497
  allowedFolders,