@probelabs/probe 0.6.0-rc312 → 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.83" : "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]
27650
-
27651
- Use the task tool to track progress on complex requests with multiple distinct goals.
27775
+ taskSystemPrompt = `<task_management_system>
27652
27776
 
27653
- ## When to Use Tasks
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>
27654
27781
 
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
 
@@ -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) {
@@ -102261,7 +102490,8 @@ async function delegate({
102261
102490
  // Simpler responses
102262
102491
  maxIterations: remainingIterations,
102263
102492
  debug,
102264
- 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,
102265
102495
  path: path9,
102266
102496
  // Workspace root (from delegateTool)
102267
102497
  allowedFolders,