pi-crew 0.9.37 → 0.9.39
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 +34 -0
- package/dist/build-meta.json +28 -56
- package/dist/index.mjs +58 -291
- package/dist/index.mjs.map +4 -4
- package/package.json +1 -1
- package/src/config/config.ts +2 -2
- package/src/extension/crew-vibes/figures.ts +13 -6
- package/src/extension/crew-vibes/index.ts +36 -13
- package/src/extension/register.ts +66 -7
- package/src/extension/registration/subagent-tools.ts +1 -18
- package/src/extension/team-tool/context.ts +1 -0
- package/src/extension/team-tool/run.ts +1 -0
- package/src/runtime/progress-tracker.ts +0 -140
- package/src/state/locks.ts +23 -0
- package/src/state/state-store.ts +3 -0
- package/src/ui/tool-renderers/index.ts +20 -3
- package/src/ui/widget/widget-formatters.ts +10 -0
package/dist/index.mjs
CHANGED
|
@@ -10277,7 +10277,7 @@ function parseIsolationPolicy(value) {
|
|
|
10277
10277
|
}
|
|
10278
10278
|
function parseRuntimeConfig(value) {
|
|
10279
10279
|
const obj = asRecord(value);
|
|
10280
|
-
if (!obj) return
|
|
10280
|
+
if (!obj) return { inheritContext: true };
|
|
10281
10281
|
const runtime = {
|
|
10282
10282
|
mode: parseWithSchema(
|
|
10283
10283
|
Type.Union([Type.Literal("auto"), Type.Literal("scaffold"), Type.Literal("child-process"), Type.Literal("live-session")]),
|
|
@@ -10287,7 +10287,7 @@ function parseRuntimeConfig(value) {
|
|
|
10287
10287
|
allowChildProcessFallback: parseWithSchema(Type.Boolean(), obj.allowChildProcessFallback),
|
|
10288
10288
|
maxTurns: parsePositiveInteger(obj.maxTurns, LIMIT_CEILINGS.runtimeMaxTurns),
|
|
10289
10289
|
graceTurns: parsePositiveInteger(obj.graceTurns, LIMIT_CEILINGS.runtimeGraceTurns),
|
|
10290
|
-
inheritContext: parseWithSchema(Type.Boolean(), obj.inheritContext),
|
|
10290
|
+
inheritContext: parseWithSchema(Type.Boolean(), obj.inheritContext) ?? true,
|
|
10291
10291
|
promptMode: parseWithSchema(Type.Union([Type.Literal("replace"), Type.Literal("append")]), obj.promptMode),
|
|
10292
10292
|
groupJoin: parseWithSchema(Type.Union([Type.Literal("off"), Type.Literal("group"), Type.Literal("smart")]), obj.groupJoin),
|
|
10293
10293
|
groupJoinAckTimeoutMs: parsePositiveInteger(obj.groupJoinAckTimeoutMs, 864e5),
|
|
@@ -20964,10 +20964,19 @@ function agentStats(agent, liveHandle) {
|
|
|
20964
20964
|
} catch {
|
|
20965
20965
|
}
|
|
20966
20966
|
const ms = computeLiveDurationMs(act);
|
|
20967
|
+
if (total > 0 && ms > 1e3) {
|
|
20968
|
+
const tps = Math.round(total / (ms / 1e3));
|
|
20969
|
+
if (tps > 0) parts.push(alignMetric(`${formatTokensCompact(tps)}/s`, TPS_METRIC_WIDTH));
|
|
20970
|
+
}
|
|
20967
20971
|
parts.push(alignMetric(`${(ms / 1e3).toFixed(1)}s`, DURATION_METRIC_WIDTH));
|
|
20968
20972
|
} else {
|
|
20969
20973
|
if (agent.toolUses) parts.push(alignMetric(`${agent.toolUses} tools`, TOOLS_METRIC_WIDTH));
|
|
20970
20974
|
if (agent.progress?.tokens) parts.push(alignMetric(formatTokensCompact(agent.progress.tokens), TOKENS_METRIC_WIDTH));
|
|
20975
|
+
const ageMs = agent.startedAt ? Math.max(0, Date.now() - new Date(agent.startedAt).getTime()) : 0;
|
|
20976
|
+
if (agent.progress?.tokens && ageMs > 1e3) {
|
|
20977
|
+
const tps = Math.round(agent.progress.tokens / (ageMs / 1e3));
|
|
20978
|
+
if (tps > 0) parts.push(alignMetric(`${formatTokensCompact(tps)}/s`, TPS_METRIC_WIDTH));
|
|
20979
|
+
}
|
|
20971
20980
|
const age = elapsed(agent.completedAt ?? agent.startedAt);
|
|
20972
20981
|
if (age) parts.push(alignMetric(age, DURATION_METRIC_WIDTH));
|
|
20973
20982
|
}
|
|
@@ -20980,7 +20989,7 @@ function notificationBadge(count2, env = process.env) {
|
|
|
20980
20989
|
const label = count2 > NOTIFICATION_BADGE_CAP ? `${NOTIFICATION_BADGE_CAP}+ alerts` : `${count2} alerts`;
|
|
20981
20990
|
return supportsEmoji ? ` \xB7 ${label}` : ` [${label}]`;
|
|
20982
20991
|
}
|
|
20983
|
-
var TOOLS_METRIC_WIDTH, TOKENS_METRIC_WIDTH, CTX_METRIC_WIDTH, DURATION_METRIC_WIDTH, TOOL_LABELS, TOOL_ICONS, NOTIFICATION_BADGE_CAP;
|
|
20992
|
+
var TOOLS_METRIC_WIDTH, TOKENS_METRIC_WIDTH, TPS_METRIC_WIDTH, CTX_METRIC_WIDTH, DURATION_METRIC_WIDTH, TOOL_LABELS, TOOL_ICONS, NOTIFICATION_BADGE_CAP;
|
|
20984
20993
|
var init_widget_formatters = __esm({
|
|
20985
20994
|
"src/ui/widget/widget-formatters.ts"() {
|
|
20986
20995
|
"use strict";
|
|
@@ -20989,6 +20998,7 @@ var init_widget_formatters = __esm({
|
|
|
20989
20998
|
init_live_duration();
|
|
20990
20999
|
TOOLS_METRIC_WIDTH = 8;
|
|
20991
21000
|
TOKENS_METRIC_WIDTH = 10;
|
|
21001
|
+
TPS_METRIC_WIDTH = 9;
|
|
20992
21002
|
CTX_METRIC_WIDTH = 7;
|
|
20993
21003
|
DURATION_METRIC_WIDTH = 6;
|
|
20994
21004
|
TOOL_LABELS = {
|
|
@@ -52049,9 +52059,21 @@ function renderAgentResult(result4, options, theme, ctx) {
|
|
|
52049
52059
|
const contentLines = [];
|
|
52050
52060
|
const isPartial = options?.isPartial === true;
|
|
52051
52061
|
if (isPartial && !ctx.expanded) {
|
|
52052
|
-
const spinner = theme.fg("
|
|
52053
|
-
const
|
|
52054
|
-
|
|
52062
|
+
const spinner = theme.fg("accent", spinnerFrame(d.agentId));
|
|
52063
|
+
const parts = [theme.fg("muted", "working")];
|
|
52064
|
+
const progressText = extractContentText(result4?.content);
|
|
52065
|
+
if (progressText) {
|
|
52066
|
+
const elapsedMatch = progressText.match(/elapsed=(\d+)s/);
|
|
52067
|
+
const tokenMatch = progressText.match(/tokens=(\d+)/);
|
|
52068
|
+
const toolMatch = progressText.match(/tool:\s+(\S+)/);
|
|
52069
|
+
const elapsedSec = elapsedMatch ? parseInt(elapsedMatch[1], 10) : 0;
|
|
52070
|
+
const tokens = tokenMatch ? parseInt(tokenMatch[1], 10) : 0;
|
|
52071
|
+
const tps = elapsedSec > 0 ? Math.round(tokens / elapsedSec) : 0;
|
|
52072
|
+
if (elapsedSec > 0) parts.push(theme.fg("dim", formatDuration2(elapsedSec * 1e3)));
|
|
52073
|
+
if (tps > 0) parts.push(theme.fg("dim", `${formatTokens2(tps)} tok/s`));
|
|
52074
|
+
if (toolMatch) parts.push(theme.fg("dim", `\xB7 ${toolMatch[1]}`));
|
|
52075
|
+
}
|
|
52076
|
+
contentLines.push(padVisual(` ${spinner} ${parts.join(" ")}`, innerW));
|
|
52055
52077
|
return buildFrameBottom(contentLines, w, theme, "borderAccent", "borderAccent");
|
|
52056
52078
|
}
|
|
52057
52079
|
if (!results?.length && !d.agentId) {
|
|
@@ -52292,6 +52314,7 @@ var init_tool_renderers = __esm({
|
|
|
52292
52314
|
"src/ui/tool-renderers/index.ts"() {
|
|
52293
52315
|
"use strict";
|
|
52294
52316
|
init_visual();
|
|
52317
|
+
init_spinner();
|
|
52295
52318
|
init_tool_render();
|
|
52296
52319
|
init_brief_mode();
|
|
52297
52320
|
init_card_colors();
|
|
@@ -82189,6 +82212,7 @@ var CREW_SHORTCUT_KEYS = CREW_SHORTCUTS.map((s) => s.key);
|
|
|
82189
82212
|
|
|
82190
82213
|
// src/extension/crew-vibes/index.ts
|
|
82191
82214
|
init_pi_ui_compat();
|
|
82215
|
+
init_internal_error();
|
|
82192
82216
|
|
|
82193
82217
|
// src/extension/crew-vibes/config.ts
|
|
82194
82218
|
import { existsSync as existsSync77, mkdirSync as mkdirSync43, readFileSync as readFileSync75, writeFileSync as writeFileSync33 } from "node:fs";
|
|
@@ -82410,8 +82434,8 @@ var PUA_CREW_FRAMES = [
|
|
|
82410
82434
|
"\uE70E ",
|
|
82411
82435
|
"\uE70F "
|
|
82412
82436
|
];
|
|
82413
|
-
function crewFrames(style = "
|
|
82414
|
-
if (style === "pua" && isWebTerminal()) return BRAILLE_FRAMES;
|
|
82437
|
+
function crewFrames(style = "braille") {
|
|
82438
|
+
if (style === "pua" && (isWebTerminal() || !hasCrewFontFile())) return BRAILLE_FRAMES;
|
|
82415
82439
|
return style === "pua" ? PUA_CREW_FRAMES : BRAILLE_FRAMES;
|
|
82416
82440
|
}
|
|
82417
82441
|
function intervalForSpeed(config, speed) {
|
|
@@ -83207,6 +83231,13 @@ var SpeedAnimator = class {
|
|
|
83207
83231
|
};
|
|
83208
83232
|
|
|
83209
83233
|
// src/extension/crew-vibes/index.ts
|
|
83234
|
+
function safeUiCall(scope, fn) {
|
|
83235
|
+
try {
|
|
83236
|
+
fn();
|
|
83237
|
+
} catch (error) {
|
|
83238
|
+
logInternalError(`crew-vibes.${scope}`, error, void 0, "warn");
|
|
83239
|
+
}
|
|
83240
|
+
}
|
|
83210
83241
|
function isAssistantMessage(message) {
|
|
83211
83242
|
return typeof message === "object" && message !== null && message.role === "assistant";
|
|
83212
83243
|
}
|
|
@@ -83249,39 +83280,44 @@ function registerCrewVibes(pi) {
|
|
|
83249
83280
|
function installFooter(ctx) {
|
|
83250
83281
|
if (!ctx?.hasUI) return;
|
|
83251
83282
|
if (!metersActive()) {
|
|
83252
|
-
setFooter(ctx, void 0);
|
|
83283
|
+
safeUiCall("clear-footer", () => setFooter(ctx, void 0));
|
|
83253
83284
|
return;
|
|
83254
83285
|
}
|
|
83255
|
-
|
|
83256
|
-
|
|
83286
|
+
safeUiCall("install-footer", () => {
|
|
83287
|
+
setFooter(ctx, (tui, theme, footerData) => createCrewVibesFooter({ tui, theme, footerData, ctx, source: footerSource }));
|
|
83288
|
+
requestRender(ctx);
|
|
83289
|
+
});
|
|
83257
83290
|
}
|
|
83258
83291
|
function refreshFooter(ctx) {
|
|
83259
|
-
if (ctx?.hasUI) requestRender(ctx);
|
|
83292
|
+
if (ctx?.hasUI) safeUiCall("refresh-footer", () => requestRender(ctx));
|
|
83260
83293
|
}
|
|
83261
83294
|
function publishSpeedFooter(ctx, speed = footerAnimator.value()) {
|
|
83262
83295
|
if (!config.enabled || !config.speed.enabled || !config.speed.footer) {
|
|
83263
|
-
setSpeedStatus(ctx, config, void 0);
|
|
83296
|
+
safeUiCall("clear-speed-status", () => setSpeedStatus(ctx, config, void 0));
|
|
83264
83297
|
return;
|
|
83265
83298
|
}
|
|
83266
|
-
setSpeedStatus(ctx, config, renderSpeedFooter(themeOf(ctx), config.speed, speed));
|
|
83299
|
+
safeUiCall("publish-speed-status", () => setSpeedStatus(ctx, config, renderSpeedFooter(themeOf(ctx), config.speed, speed)));
|
|
83267
83300
|
}
|
|
83268
83301
|
function applyIndicator(ctx, speed, force = false) {
|
|
83269
83302
|
if (!ctx.hasUI || !ctx.ui.setWorkingIndicator) return;
|
|
83270
83303
|
if (!config.enabled || !config.speed.enabled || !config.speed.indicator) {
|
|
83271
|
-
ctx.ui.setWorkingIndicator();
|
|
83304
|
+
safeUiCall("reset-indicator", () => ctx.ui.setWorkingIndicator?.());
|
|
83272
83305
|
return;
|
|
83273
83306
|
}
|
|
83274
83307
|
const next = intervalForSpeed(config.speed, speed);
|
|
83275
83308
|
if (!force && Math.abs(next - currentIntervalMs) < 10) return;
|
|
83276
|
-
|
|
83277
|
-
|
|
83278
|
-
|
|
83279
|
-
|
|
83309
|
+
safeUiCall(
|
|
83310
|
+
"set-indicator",
|
|
83311
|
+
() => ctx.ui.setWorkingIndicator?.({
|
|
83312
|
+
frames: crewIndicatorFrames(themeOf(ctx)),
|
|
83313
|
+
intervalMs: next
|
|
83314
|
+
})
|
|
83315
|
+
);
|
|
83280
83316
|
currentIntervalMs = next;
|
|
83281
83317
|
}
|
|
83282
83318
|
function renderWorking(ctx, speed) {
|
|
83283
83319
|
if (!config.enabled || !config.speed.enabled || !ctx.hasUI) return;
|
|
83284
|
-
ctx.ui.setWorkingMessage(renderWorkingMessage(themeOf(ctx), config.speed, speed));
|
|
83320
|
+
safeUiCall("set-working-message", () => ctx.ui.setWorkingMessage?.(renderWorkingMessage(themeOf(ctx), config.speed, speed)));
|
|
83285
83321
|
}
|
|
83286
83322
|
function stopLiveTimer() {
|
|
83287
83323
|
if (!liveTimer) return;
|
|
@@ -83452,7 +83488,7 @@ function registerCrewVibes(pi) {
|
|
|
83452
83488
|
stopLiveTimer();
|
|
83453
83489
|
if (ctx && config.enabled && ctx.hasUI) {
|
|
83454
83490
|
applyIndicator(ctx, speedTracker.lastTokS);
|
|
83455
|
-
ctx.ui.setWorkingMessage();
|
|
83491
|
+
safeUiCall("clear-working-message", () => ctx.ui.setWorkingMessage?.());
|
|
83456
83492
|
}
|
|
83457
83493
|
});
|
|
83458
83494
|
pi.on("model_select", (event, ctx) => {
|
|
@@ -84118,259 +84154,6 @@ function initI18n(pi) {
|
|
|
84118
84154
|
|
|
84119
84155
|
// src/extension/registration/subagent-tools.ts
|
|
84120
84156
|
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
|
|
84374
84157
|
init_role_permission();
|
|
84375
84158
|
init_state_store();
|
|
84376
84159
|
init_manager();
|
|
@@ -84738,20 +84521,7 @@ function startAgentToolProgress(cwd, agentRecordId, onUpdate, manager) {
|
|
|
84738
84521
|
agents,
|
|
84739
84522
|
error: record.error
|
|
84740
84523
|
});
|
|
84741
|
-
|
|
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 }] });
|
|
84524
|
+
onUpdate({ content: [{ type: "text", text }] });
|
|
84755
84525
|
} catch (error) {
|
|
84756
84526
|
logInternalError("subagent-tools.progress", error, `agentId=${agentRecordId}`);
|
|
84757
84527
|
}
|
|
@@ -85883,9 +85653,6 @@ Subagent may need manual intervention.`
|
|
|
85883
85653
|
const record = event;
|
|
85884
85654
|
const eventType = typeof record.type === "string" ? record.type : void 0;
|
|
85885
85655
|
if (eventType) lifecycleState.overflowTracker?.feedEvent(taskId, runId, eventType);
|
|
85886
|
-
if (record && typeof record === "object") {
|
|
85887
|
-
globalProgressTracker.handleWorkerEvent(taskId, runId, record);
|
|
85888
|
-
}
|
|
85889
85656
|
}
|
|
85890
85657
|
});
|
|
85891
85658
|
registerSubagentTools(pi, subagentManager, {
|