pi-crew 0.9.36 → 0.9.37

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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.37] — cold context + subagent streaming (2026-07-14)
4
+
5
+ Two performance improvements targeting perceived subagent slowness:
6
+
7
+ ### Phase 1: Cold Context (inheritContext default → true)
8
+
9
+ - **`inheritContext` default changed from `false` → `true`** — subagents now receive parent conversation context by default, eliminating redundant re-exploration of files the main session already processed. Configurable via `runtime.inheritContext`.
10
+ - **`buildParentContext()` token budget** — 12K char budget with most-recent-first retention prevents token bloat on large parent sessions.
11
+ - **Noisy content filtering** — skips file dumps (code blocks, `ls` output, import lists >1K chars) and truncates long assistant messages to 200 chars. Compaction summaries kept in full.
12
+ - **Tests**: `test/unit/build-parent-context.test.ts` (10 cases).
13
+
14
+ ### Phase 2: Subagent Streaming (child-process → widget)
15
+
16
+ - **`ProgressTracker.handleWorkerEvent()`** — bridges child-process JSON events (from `onJsonEvent`) into `crewEventBus`, enabling real-time widget display of tool calls, assistant text, and token usage for BOTH runtimes (previously only live-session had streaming).
17
+ - **`register.ts` onJsonEvent** — now forwards events to `globalProgressTracker` (was only feeding `overflowTracker`).
18
+ - **`subagent-tools.ts` inline progress** — enriched with real-time worker progress: ⚡ current tool, 📊 tokens, 💬 partial assistant text.
19
+ - **Throttled to 500ms per worker** to prevent widget flooding.
20
+ - **Tests**: `test/unit/progress-tracker-worker.test.ts` (8 cases).
21
+
3
22
  ## [0.9.36] — security audit round 1 (2026-07-14)
4
23
 
5
24
  Three security hardening fixes from the first formal security audit pass (run via `team_20260714045239_bb49d72211b966a2` + verified via `team_20260714062932_638dbb0310cc9f77`, 12/12 targeted tests pass, typecheck clean):
@@ -8410,7 +8410,7 @@
8410
8410
  "format": "esm"
8411
8411
  },
8412
8412
  "src/extension/team-tool/context.ts": {
8413
- "bytes": 3419,
8413
+ "bytes": 5581,
8414
8414
  "imports": [
8415
8415
  {
8416
8416
  "path": "src/extension/tool-result.ts",
@@ -8577,7 +8577,7 @@
8577
8577
  "format": "esm"
8578
8578
  },
8579
8579
  "src/extension/team-tool/handle-settings.ts": {
8580
- "bytes": 17990,
8580
+ "bytes": 17989,
8581
8581
  "imports": [
8582
8582
  {
8583
8583
  "path": "src/config/config.ts",
@@ -16950,7 +16950,7 @@
16950
16950
  "format": "esm"
16951
16951
  },
16952
16952
  "src/ui/settings-overlay.ts": {
16953
- "bytes": 31026,
16953
+ "bytes": 31025,
16954
16954
  "imports": [
16955
16955
  {
16956
16956
  "path": "src/utils/visual.ts",
@@ -17720,8 +17720,30 @@
17720
17720
  ],
17721
17721
  "format": "esm"
17722
17722
  },
17723
+ "src/observability/event-bus.ts": {
17724
+ "bytes": 2219,
17725
+ "imports": [
17726
+ {
17727
+ "path": "src/utils/internal-error.ts",
17728
+ "kind": "import-statement",
17729
+ "original": "../utils/internal-error.ts"
17730
+ }
17731
+ ],
17732
+ "format": "esm"
17733
+ },
17734
+ "src/runtime/progress-tracker.ts": {
17735
+ "bytes": 7543,
17736
+ "imports": [
17737
+ {
17738
+ "path": "src/observability/event-bus.ts",
17739
+ "kind": "import-statement",
17740
+ "original": "../observability/event-bus.ts"
17741
+ }
17742
+ ],
17743
+ "format": "esm"
17744
+ },
17723
17745
  "src/extension/registration/subagent-tools.ts": {
17724
- "bytes": 17386,
17746
+ "bytes": 18292,
17725
17747
  "imports": [
17726
17748
  {
17727
17749
  "path": "node_modules/@sinclair/typebox/build/esm/index.mjs",
@@ -17753,6 +17775,11 @@
17753
17775
  "kind": "import-statement",
17754
17776
  "original": "../../runtime/crew-agent-records.ts"
17755
17777
  },
17778
+ {
17779
+ "path": "src/runtime/progress-tracker.ts",
17780
+ "kind": "import-statement",
17781
+ "original": "../../runtime/progress-tracker.ts"
17782
+ },
17756
17783
  {
17757
17784
  "path": "src/runtime/role-permission.ts",
17758
17785
  "kind": "import-statement",
@@ -17993,7 +18020,7 @@
17993
18020
  "format": "esm"
17994
18021
  },
17995
18022
  "src/extension/register.ts": {
17996
- "bytes": 68063,
18023
+ "bytes": 68402,
17997
18024
  "imports": [
17998
18025
  {
17999
18026
  "path": "node:fs",
@@ -18315,6 +18342,11 @@
18315
18342
  "kind": "import-statement",
18316
18343
  "original": "../i18n.ts"
18317
18344
  },
18345
+ {
18346
+ "path": "src/runtime/progress-tracker.ts",
18347
+ "kind": "import-statement",
18348
+ "original": "../runtime/progress-tracker.ts"
18349
+ },
18318
18350
  {
18319
18351
  "path": "src/runtime/session-resources.ts",
18320
18352
  "kind": "import-statement",
@@ -18415,7 +18447,7 @@
18415
18447
  "imports": [],
18416
18448
  "exports": [],
18417
18449
  "inputs": {},
18418
- "bytes": 6697128
18450
+ "bytes": 6717985
18419
18451
  },
18420
18452
  "dist/index.mjs": {
18421
18453
  "imports": [
@@ -20931,7 +20963,7 @@
20931
20963
  "bytesInOutput": 1541
20932
20964
  },
20933
20965
  "src/extension/team-tool/context.ts": {
20934
- "bytesInOutput": 2198
20966
+ "bytesInOutput": 3237
20935
20967
  },
20936
20968
  "src/extension/team-tool/intent-policy.ts": {
20937
20969
  "bytesInOutput": 1245
@@ -20952,7 +20984,7 @@
20952
20984
  "bytesInOutput": 1876
20953
20985
  },
20954
20986
  "src/extension/team-tool/handle-settings.ts": {
20955
- "bytesInOutput": 16052
20987
+ "bytesInOutput": 16051
20956
20988
  },
20957
20989
  "src/workflows/validate-workflow.ts": {
20958
20990
  "bytesInOutput": 1927
@@ -21960,7 +21992,7 @@
21960
21992
  "bytesInOutput": 15659
21961
21993
  },
21962
21994
  "src/ui/settings-overlay.ts": {
21963
- "bytesInOutput": 30589
21995
+ "bytesInOutput": 30588
21964
21996
  },
21965
21997
  "src/extension/registration/commands.ts": {
21966
21998
  "bytesInOutput": 40488
@@ -22020,7 +22052,7 @@
22020
22052
  "bytesInOutput": 3150
22021
22053
  },
22022
22054
  "src/extension/register.ts": {
22023
- "bytesInOutput": 45555
22055
+ "bytesInOutput": 45685
22024
22056
  },
22025
22057
  "src/runtime/batch-barrier.ts": {
22026
22058
  "bytesInOutput": 3060
@@ -22104,11 +22136,17 @@
22104
22136
  "bytesInOutput": 647
22105
22137
  },
22106
22138
  "src/extension/registration/subagent-tools.ts": {
22107
- "bytesInOutput": 15548
22139
+ "bytesInOutput": 16197
22108
22140
  },
22109
22141
  "src/i18n.ts": {
22110
22142
  "bytesInOutput": 6837
22111
22143
  },
22144
+ "src/observability/event-bus.ts": {
22145
+ "bytesInOutput": 1170
22146
+ },
22147
+ "src/runtime/progress-tracker.ts": {
22148
+ "bytesInOutput": 6660
22149
+ },
22112
22150
  "src/extension/session-summary.ts": {
22113
22151
  "bytesInOutput": 512
22114
22152
  },
@@ -22125,7 +22163,7 @@
22125
22163
  "bytesInOutput": 81
22126
22164
  }
22127
22165
  },
22128
- "bytes": 3172923
22166
+ "bytes": 3182689
22129
22167
  }
22130
22168
  }
22131
22169
  }
package/dist/index.mjs CHANGED
@@ -24757,6 +24757,7 @@ var init_workflow_serializer = __esm({
24757
24757
  // src/extension/team-tool/context.ts
24758
24758
  var context_exports = {};
24759
24759
  __export(context_exports, {
24760
+ MAX_PARENT_CONTEXT_CHARS: () => MAX_PARENT_CONTEXT_CHARS,
24760
24761
  buildParentContext: () => buildParentContext,
24761
24762
  configRecord: () => configRecord,
24762
24763
  formatScoped: () => formatScoped,
@@ -24780,6 +24781,10 @@ function extractTextContent(content) {
24780
24781
  (part) => part && typeof part === "object" && !Array.isArray(part) && typeof part.text === "string" ? part.text : ""
24781
24782
  ).filter(Boolean).join("\n");
24782
24783
  }
24784
+ function isNoisyContent(text) {
24785
+ if (text.length < NOISY_THRESHOLD) return false;
24786
+ return NOISY_PREFIXES.some((prefix) => text.startsWith(prefix));
24787
+ }
24783
24788
  function buildParentContext(ctx) {
24784
24789
  const branch = ctx.sessionManager?.getBranch?.();
24785
24790
  if (!Array.isArray(branch) || branch.length === 0) return void 0;
@@ -24787,28 +24792,50 @@ function buildParentContext(ctx) {
24787
24792
  for (const entry of branch.slice(-20)) {
24788
24793
  if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
24789
24794
  const record = entry;
24790
- if (record.type === "compaction" && typeof record.summary === "string") parts.push(`[Summary]: ${record.summary}`);
24795
+ if (record.type === "compaction" && typeof record.summary === "string") {
24796
+ parts.push(`[Summary]: ${record.summary}`);
24797
+ continue;
24798
+ }
24791
24799
  const message = record.message && typeof record.message === "object" && !Array.isArray(record.message) ? record.message : void 0;
24792
24800
  if (!message || message.role !== "user" && message.role !== "assistant") continue;
24793
- const text = extractTextContent(message.content).trim();
24794
- if (text) parts.push(`[${message.role === "user" ? "User" : "Assistant"}]: ${text}`);
24801
+ let text = extractTextContent(message.content).trim();
24802
+ if (!text) continue;
24803
+ if (isNoisyContent(text)) continue;
24804
+ if (message.role === "assistant" && text.length > MAX_ASSISTANT_MSG_CHARS) {
24805
+ text = `${text.slice(0, TRUNCATED_ASSISTANT_CHARS)}\u2026`;
24806
+ }
24807
+ parts.push(`[${message.role === "user" ? "User" : "Assistant"}]: ${text}`);
24795
24808
  }
24796
24809
  if (!parts.length) return void 0;
24810
+ let totalChars = 0;
24811
+ const budgeted = [];
24812
+ for (const part of [...parts].reverse()) {
24813
+ if (totalChars + part.length > MAX_PARENT_CONTEXT_CHARS) break;
24814
+ budgeted.unshift(part);
24815
+ totalChars += part.length;
24816
+ }
24817
+ if (!budgeted.length) return void 0;
24797
24818
  return [
24798
24819
  `# Parent Conversation Context`,
24799
24820
  "The following context was inherited from the parent Pi session. Treat it as reference-only.",
24800
24821
  "",
24801
- parts.join("\n\n")
24822
+ budgeted.join("\n\n")
24802
24823
  ].join("\n");
24803
24824
  }
24804
24825
  function configRecord(config) {
24805
24826
  if (!config || typeof config !== "object" || Array.isArray(config)) return {};
24806
24827
  return config;
24807
24828
  }
24829
+ var MAX_PARENT_CONTEXT_CHARS, MAX_ASSISTANT_MSG_CHARS, TRUNCATED_ASSISTANT_CHARS, NOISY_THRESHOLD, NOISY_PREFIXES;
24808
24830
  var init_context = __esm({
24809
24831
  "src/extension/team-tool/context.ts"() {
24810
24832
  "use strict";
24811
24833
  init_tool_result();
24834
+ MAX_PARENT_CONTEXT_CHARS = 12e3;
24835
+ MAX_ASSISTANT_MSG_CHARS = 500;
24836
+ TRUNCATED_ASSISTANT_CHARS = 200;
24837
+ NOISY_THRESHOLD = 1e3;
24838
+ NOISY_PREFIXES = ["```", "total ", "drwx", "-rw", "import ", "export "];
24812
24839
  }
24813
24840
  });
24814
24841
 
@@ -26191,7 +26218,7 @@ var init_handle_settings = __esm({
26191
26218
  "runtime.mode": "auto",
26192
26219
  "runtime.maxTurns": 1e4,
26193
26220
  "runtime.graceTurns": 5,
26194
- "runtime.inheritContext": false,
26221
+ "runtime.inheritContext": true,
26195
26222
  "runtime.promptMode": "replace",
26196
26223
  "runtime.completionMutationGuard": "warn",
26197
26224
  "runtime.isolationPolicy": void 0,
@@ -75794,7 +75821,7 @@ var init_settings_overlay = __esm({
75794
75821
  "runtime.mode": "auto",
75795
75822
  "runtime.maxTurns": 1e4,
75796
75823
  "runtime.graceTurns": 5,
75797
- "runtime.inheritContext": false,
75824
+ "runtime.inheritContext": true,
75798
75825
  "runtime.promptMode": "replace",
75799
75826
  "runtime.completionMutationGuard": "warn",
75800
75827
  "runtime.isolationPolicy": void 0,
@@ -84091,6 +84118,259 @@ function initI18n(pi) {
84091
84118
 
84092
84119
  // src/extension/registration/subagent-tools.ts
84093
84120
  init_crew_agent_records();
84121
+
84122
+ // src/observability/event-bus.ts
84123
+ init_internal_error();
84124
+ var EventBus = class _EventBus {
84125
+ listeners = /* @__PURE__ */ new Map();
84126
+ static _instance;
84127
+ static getInstance() {
84128
+ if (!_EventBus._instance) {
84129
+ _EventBus._instance = new _EventBus();
84130
+ }
84131
+ return _EventBus._instance;
84132
+ }
84133
+ /**
84134
+ * Dispose of the EventBus instance and clear all listeners.
84135
+ * Resets the singleton so a new instance can be created.
84136
+ */
84137
+ dispose() {
84138
+ this.listeners.clear();
84139
+ _EventBus._instance = void 0;
84140
+ }
84141
+ emit(event) {
84142
+ const listeners2 = this.listeners.get(event.type);
84143
+ if (listeners2) {
84144
+ for (const listener of listeners2) {
84145
+ try {
84146
+ listener(event);
84147
+ } catch (e) {
84148
+ logInternalError("event-bus.listener", e, `type=${event.type} runId=${event.runId}`);
84149
+ }
84150
+ }
84151
+ }
84152
+ }
84153
+ on(type, listener) {
84154
+ if (!this.listeners.has(type)) {
84155
+ this.listeners.set(type, /* @__PURE__ */ new Set());
84156
+ }
84157
+ this.listeners.get(type).add(listener);
84158
+ return () => {
84159
+ this.listeners.get(type)?.delete(listener);
84160
+ };
84161
+ }
84162
+ off(type, listener) {
84163
+ this.listeners.get(type)?.delete(listener);
84164
+ }
84165
+ };
84166
+ var crewEventBus = EventBus.getInstance();
84167
+
84168
+ // src/runtime/progress-tracker.ts
84169
+ var ProgressTracker = class _ProgressTracker {
84170
+ sessions = /* @__PURE__ */ new Map();
84171
+ track(session, agentId, runId) {
84172
+ if (this.sessions.has(agentId)) {
84173
+ return this.sessions.get(agentId).progress;
84174
+ }
84175
+ const progress = {
84176
+ toolCalls: 0,
84177
+ currentTool: null,
84178
+ toolStartTime: null,
84179
+ errors: [],
84180
+ turns: 0,
84181
+ tokens: { input: 0, output: 0 },
84182
+ status: "running"
84183
+ };
84184
+ const unsubscribe = session.subscribe((event) => {
84185
+ this.handleEvent(event, progress, agentId, runId);
84186
+ });
84187
+ this.sessions.set(agentId, { unsubscribe, progress });
84188
+ return progress;
84189
+ }
84190
+ handleEvent(event, progress, agentId, runId) {
84191
+ switch (event.type) {
84192
+ case "tool_execution_start":
84193
+ progress.toolCalls++;
84194
+ progress.currentTool = event.toolName;
84195
+ progress.toolStartTime = Date.now();
84196
+ crewEventBus.emit({
84197
+ type: "agent:progress",
84198
+ runId,
84199
+ agentId,
84200
+ payload: { ...progress },
84201
+ timestamp: Date.now()
84202
+ });
84203
+ break;
84204
+ case "tool_execution_end":
84205
+ progress.currentTool = null;
84206
+ progress.toolStartTime = null;
84207
+ if (event.isError) {
84208
+ progress.errors.push(String(event.result ?? "Unknown error"));
84209
+ crewEventBus.emit({
84210
+ type: "agent:error",
84211
+ runId,
84212
+ agentId,
84213
+ payload: String(event.result ?? "Unknown error"),
84214
+ timestamp: Date.now()
84215
+ });
84216
+ }
84217
+ crewEventBus.emit({
84218
+ type: "agent:progress",
84219
+ runId,
84220
+ agentId,
84221
+ payload: { ...progress },
84222
+ timestamp: Date.now()
84223
+ });
84224
+ break;
84225
+ case "turn_start":
84226
+ progress.turns++;
84227
+ break;
84228
+ case "agent_end":
84229
+ progress.status = "completed";
84230
+ crewEventBus.emit({
84231
+ type: "agent:complete",
84232
+ runId,
84233
+ agentId,
84234
+ payload: { ...progress },
84235
+ timestamp: Date.now()
84236
+ });
84237
+ break;
84238
+ case "agent_start":
84239
+ progress.status = "running";
84240
+ break;
84241
+ }
84242
+ }
84243
+ untrack(agentId) {
84244
+ const tracked = this.sessions.get(agentId);
84245
+ if (tracked) {
84246
+ tracked.unsubscribe();
84247
+ this.sessions.delete(agentId);
84248
+ }
84249
+ }
84250
+ getProgress(agentId) {
84251
+ return this.sessions.get(agentId)?.progress;
84252
+ }
84253
+ // ── Child-process worker event bridge ──────────────────────────────────
84254
+ //
84255
+ // For child-process runtime, events arrive as raw JSON from the child pi
84256
+ // process's stdout (via onJsonEvent). These methods bridge those events into
84257
+ // the same crewEventBus stream that live-session uses, so the widget shows
84258
+ // real-time tool calls and assistant text for BOTH runtimes.
84259
+ workerProgress = /* @__PURE__ */ new Map();
84260
+ /** Throttle: don't emit more than 1 progress event per 500ms per worker. */
84261
+ lastEmitTs = /* @__PURE__ */ new Map();
84262
+ static EMIT_THROTTLE_MS = 500;
84263
+ /**
84264
+ * Handle a raw child-process JSON event (from onJsonEvent callback).
84265
+ * Processes tool_execution_start/end, agent_start/end, and assistant text.
84266
+ */
84267
+ handleWorkerEvent(taskId, runId, event) {
84268
+ let progress = this.workerProgress.get(taskId);
84269
+ if (!progress) {
84270
+ progress = {
84271
+ toolCalls: 0,
84272
+ currentTool: null,
84273
+ toolStartTime: null,
84274
+ errors: [],
84275
+ turns: 0,
84276
+ tokens: { input: 0, output: 0 },
84277
+ status: "running"
84278
+ };
84279
+ this.workerProgress.set(taskId, progress);
84280
+ }
84281
+ const eventType = typeof event.type === "string" ? event.type : void 0;
84282
+ switch (eventType) {
84283
+ case "tool_execution_start": {
84284
+ progress.toolCalls++;
84285
+ progress.currentTool = typeof event.toolName === "string" ? event.toolName : "unknown";
84286
+ progress.toolStartTime = Date.now();
84287
+ this.emitThrottled(taskId, runId, progress);
84288
+ break;
84289
+ }
84290
+ case "tool_execution_end": {
84291
+ progress.currentTool = null;
84292
+ progress.toolStartTime = null;
84293
+ if (event.isError) {
84294
+ progress.errors.push(String(event.result ?? "Unknown error"));
84295
+ crewEventBus.emit({
84296
+ type: "agent:error",
84297
+ runId,
84298
+ agentId: taskId,
84299
+ payload: String(event.result ?? "Unknown error"),
84300
+ timestamp: Date.now()
84301
+ });
84302
+ }
84303
+ this.emitThrottled(taskId, runId, progress);
84304
+ break;
84305
+ }
84306
+ case "turn_start":
84307
+ case "turn_end":
84308
+ progress.turns++;
84309
+ break;
84310
+ case "agent_start":
84311
+ progress.status = "running";
84312
+ break;
84313
+ case "agent_end":
84314
+ case "agent_settled":
84315
+ progress.status = "completed";
84316
+ this.emitThrottled(taskId, runId, progress);
84317
+ break;
84318
+ case "message":
84319
+ case "message_end": {
84320
+ const message = event.message;
84321
+ if (message?.role === "assistant") {
84322
+ const text = extractWorkerText(message.content);
84323
+ if (text) {
84324
+ progress.partialText = text.slice(-2e3);
84325
+ this.emitThrottled(taskId, runId, progress);
84326
+ }
84327
+ }
84328
+ if (eventType === "message_end" && event.usage && typeof event.usage === "object") {
84329
+ const usage = event.usage;
84330
+ if (typeof usage.input === "number") progress.tokens.input += usage.input;
84331
+ if (typeof usage.output === "number") progress.tokens.output += usage.output;
84332
+ }
84333
+ break;
84334
+ }
84335
+ }
84336
+ }
84337
+ /** Get the accumulated progress for a child-process worker task. */
84338
+ getWorkerProgress(taskId) {
84339
+ return this.workerProgress.get(taskId);
84340
+ }
84341
+ /** Remove a worker from tracking after completion. */
84342
+ untrackWorker(taskId) {
84343
+ this.workerProgress.delete(taskId);
84344
+ this.lastEmitTs.delete(taskId);
84345
+ }
84346
+ /**
84347
+ * Emit a progress event to crewEventBus, throttled to avoid flooding
84348
+ * the widget with re-renders (max 1 event per EMIT_THROTTLE_MS per worker).
84349
+ */
84350
+ emitThrottled(taskId, runId, progress) {
84351
+ const now = Date.now();
84352
+ const last = this.lastEmitTs.get(taskId) ?? 0;
84353
+ if (now - last < _ProgressTracker.EMIT_THROTTLE_MS) return;
84354
+ this.lastEmitTs.set(taskId, now);
84355
+ crewEventBus.emit({
84356
+ type: "agent:progress",
84357
+ runId,
84358
+ agentId: taskId,
84359
+ payload: { ...progress },
84360
+ timestamp: now
84361
+ });
84362
+ }
84363
+ };
84364
+ var globalProgressTracker = new ProgressTracker();
84365
+ function extractWorkerText(content) {
84366
+ if (typeof content === "string") return content;
84367
+ if (!Array.isArray(content)) return "";
84368
+ return content.map(
84369
+ (part) => part && typeof part === "object" && !Array.isArray(part) && typeof part.text === "string" ? part.text : ""
84370
+ ).filter(Boolean).join("\n");
84371
+ }
84372
+
84373
+ // src/extension/registration/subagent-tools.ts
84094
84374
  init_role_permission();
84095
84375
  init_state_store();
84096
84376
  init_manager();
@@ -84458,7 +84738,20 @@ function startAgentToolProgress(cwd, agentRecordId, onUpdate, manager) {
84458
84738
  agents,
84459
84739
  error: record.error
84460
84740
  });
84461
- onUpdate({ content: [{ type: "text", text }] });
84741
+ let progressLine = text;
84742
+ if (tasks && tasks.length > 0) {
84743
+ const wp = globalProgressTracker.getWorkerProgress(tasks[0].id);
84744
+ if (wp) {
84745
+ const toolLine = wp.currentTool ? `
84746
+ \u26A1 tool: ${wp.currentTool}` : "";
84747
+ const tokenLine = wp.tokens.input + wp.tokens.output > 0 ? `
84748
+ \u{1F4CA} tokens: ${(wp.tokens.input / 1e3).toFixed(1)}K in, ${(wp.tokens.output / 1e3).toFixed(1)}K out` : "";
84749
+ const textLine = wp.partialText ? `
84750
+ \u{1F4AC} ${wp.partialText.slice(-150).replace(/\n/g, " ")}` : "";
84751
+ progressLine = `${text}${toolLine}${tokenLine}${textLine}`;
84752
+ }
84753
+ }
84754
+ onUpdate({ content: [{ type: "text", text: progressLine }] });
84462
84755
  } catch (error) {
84463
84756
  logInternalError("subagent-tools.progress", error, `agentId=${agentRecordId}`);
84464
84757
  }
@@ -85590,6 +85883,9 @@ Subagent may need manual intervention.`
85590
85883
  const record = event;
85591
85884
  const eventType = typeof record.type === "string" ? record.type : void 0;
85592
85885
  if (eventType) lifecycleState.overflowTracker?.feedEvent(taskId, runId, eventType);
85886
+ if (record && typeof record === "object") {
85887
+ globalProgressTracker.handleWorkerEvent(taskId, runId, record);
85888
+ }
85593
85889
  }
85594
85890
  });
85595
85891
  registerSubagentTools(pi, subagentManager, {