blun-king-cli 9.1.47 → 9.1.48
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/LIESMICH.txt +11 -1
- package/README.md +12 -1
- package/blun.mjs +393 -64
- package/package.json +1 -1
package/LIESMICH.txt
CHANGED
|
@@ -9,7 +9,7 @@ Installation
|
|
|
9
9
|
------------
|
|
10
10
|
Die geprüfte Version exakt global installieren:
|
|
11
11
|
|
|
12
|
-
npm install -g blun-king-cli@9.1.
|
|
12
|
+
npm install -g blun-king-cli@9.1.48
|
|
13
13
|
|
|
14
14
|
Start
|
|
15
15
|
-----
|
|
@@ -31,6 +31,16 @@ Die Grenzwerte lassen sich vor dem Start über diese Umgebungsvariablen ändern:
|
|
|
31
31
|
BLUN_TURN_WATCHDOG_IDLE_MINUTES
|
|
32
32
|
BLUN_TURN_WATCHDOG_MAX_FAILED_REPETITIONS
|
|
33
33
|
|
|
34
|
+
Befehle und Loops während eines laufenden Zugs
|
|
35
|
+
------------------------------------------------
|
|
36
|
+
Slash-Befehle, die einen freien Agenten benötigen, werden während eines
|
|
37
|
+
laufenden Zugs in ihrer Eingabereihenfolge vorgemerkt und danach ausgeführt.
|
|
38
|
+
Status-, Stopp- und andere sichere Steuerbefehle bleiben sofort verfügbar.
|
|
39
|
+
|
|
40
|
+
Ein neuer /loop ersetzt den bisherigen Loop derselben Sitzung. Dabei bleibt
|
|
41
|
+
genau ein gespeicherter Loop aktiv. /loop stop, /loop pause und /loop status
|
|
42
|
+
wirken auch dann sofort, wenn der Agent gerade arbeitet.
|
|
43
|
+
|
|
34
44
|
Nachweisbare Arbeitsabläufe
|
|
35
45
|
---------------------------
|
|
36
46
|
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Voraussetzung ist Node.js 24.15 oder neuer. Die geprüfte Version wird exakt
|
|
|
9
9
|
installiert:
|
|
10
10
|
|
|
11
11
|
```powershell
|
|
12
|
-
npm install -g blun-king-cli@9.1.
|
|
12
|
+
npm install -g blun-king-cli@9.1.48
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Reproduzierbares Staging und Packen
|
|
@@ -45,6 +45,17 @@ Die Grenzwerte lassen sich vor dem Start mit
|
|
|
45
45
|
`BLUN_TURN_WATCHDOG_IDLE_MINUTES` und
|
|
46
46
|
`BLUN_TURN_WATCHDOG_MAX_FAILED_REPETITIONS` ändern.
|
|
47
47
|
|
|
48
|
+
## Befehle und Loops während eines laufenden Zugs
|
|
49
|
+
|
|
50
|
+
Slash-Befehle, die einen freien Agenten benötigen, werden während eines
|
|
51
|
+
laufenden Zugs in ihrer Eingabereihenfolge vorgemerkt und danach ausgeführt.
|
|
52
|
+
Status-, Stopp- und andere sichere Steuerbefehle bleiben sofort verfügbar.
|
|
53
|
+
|
|
54
|
+
Ein neuer `/loop` ersetzt den bisherigen Loop derselben Sitzung. Dabei bleibt
|
|
55
|
+
genau ein gespeicherter Loop aktiv; der neue Auftrag, das neue Intervall und
|
|
56
|
+
der neue Startzeitpunkt gelten vollständig. `/loop stop`, `/loop pause` und
|
|
57
|
+
`/loop status` wirken auch dann sofort, wenn der Agent gerade arbeitet.
|
|
58
|
+
|
|
48
59
|
Beim ersten Start werden das Telegram-Plugin und die mitgelieferten Skills
|
|
49
60
|
eingerichtet. Die Anmeldung erfolgt anschließend in der
|
|
50
61
|
Konsole mit `/login` über den BLUN-OAuth-Server. Das Paket erzeugt keine
|
package/blun.mjs
CHANGED
|
@@ -75066,10 +75066,6 @@ function estimateCompactionStageCount(initialInputTokens, safeRequestLimitTokens
|
|
|
75066
75066
|
if (safeRequestLimitTokens <= 0) return currentStage;
|
|
75067
75067
|
return Math.max(currentStage, Math.ceil(initialInputTokens / safeRequestLimitTokens));
|
|
75068
75068
|
}
|
|
75069
|
-
function estimateCompactionProgressPercent(stage, estimatedStageCount) {
|
|
75070
|
-
if (estimatedStageCount <= 0) return 0;
|
|
75071
|
-
return Math.min(99, Math.floor(stage / estimatedStageCount * 100));
|
|
75072
|
-
}
|
|
75073
75069
|
function estimateCompactionWindowUsagePercent(requestTokens, maxContextTokens) {
|
|
75074
75070
|
if (maxContextTokens <= 0) return void 0;
|
|
75075
75071
|
return Math.min(100, Math.max(0, Math.ceil(requestTokens / maxContextTokens * 100)));
|
|
@@ -75554,7 +75550,6 @@ var init_full = __esmMin((() => {
|
|
|
75554
75550
|
charsReceived = 0;
|
|
75555
75551
|
const stage = hierarchicalPassCount + 1;
|
|
75556
75552
|
const estimatedStageCount = estimateCompactionStageCount(initialCompactionRequestTokens, safeCompactionRequestLimit, stage);
|
|
75557
|
-
const estimatedProgressPercent = estimateCompactionProgressPercent(stage, estimatedStageCount);
|
|
75558
75553
|
const windowUsagePercent = estimateCompactionWindowUsagePercent(estimatedCompactionRequestTokens, compactionRequestLimit);
|
|
75559
75554
|
this.agent.log.info("compaction stage request", {
|
|
75560
75555
|
requestPurpose: "compaction",
|
|
@@ -75578,7 +75573,6 @@ var init_full = __esmMin((() => {
|
|
|
75578
75573
|
stage,
|
|
75579
75574
|
estimatedStageCount,
|
|
75580
75575
|
estimatedInputTokens: estimatedCompactionRequestTokens,
|
|
75581
|
-
estimatedProgressPercent,
|
|
75582
75576
|
...windowUsagePercent === void 0 ? {} : { windowUsagePercent },
|
|
75583
75577
|
charsReceived,
|
|
75584
75578
|
attempt: attemptCount,
|
|
@@ -77688,12 +77682,29 @@ var init_session_loop = __esmMin((() => {
|
|
|
77688
77682
|
}
|
|
77689
77683
|
createLoop(input) {
|
|
77690
77684
|
if (process.env["BLUN_DISABLE_CRON"] === "1") throw new BlunError(ErrorCodes.LOOP_DISABLED, "Recurring loops are disabled");
|
|
77691
|
-
|
|
77692
|
-
if (this.cron.store.list().length >= 50) throw new BlunError(ErrorCodes.LOOP_LIMIT_REACHED, "Session cron task limit reached");
|
|
77685
|
+
const existing = this.currentTask();
|
|
77686
|
+
if (existing === void 0 && this.cron.store.list().length >= 50) throw new BlunError(ErrorCodes.LOOP_LIMIT_REACHED, "Session cron task limit reached");
|
|
77693
77687
|
const parsed = parseLoopInterval(input.interval);
|
|
77694
77688
|
const prompt = input.prompt.trim();
|
|
77695
77689
|
if (prompt.length === 0) throw new BlunError(ErrorCodes.LOOP_PROMPT_EMPTY, "Loop prompt cannot be empty");
|
|
77696
77690
|
if (Buffer.byteLength(prompt, "utf8") > MAX_LOOP_PROMPT_BYTES) throw new BlunError(ErrorCodes.LOOP_PROMPT_TOO_LONG, `Loop prompt cannot exceed ${String(MAX_LOOP_PROMPT_BYTES)} UTF-8 bytes`);
|
|
77691
|
+
if (existing !== void 0) {
|
|
77692
|
+
const now = this.cron.clocks.wallNow();
|
|
77693
|
+
const task = this.requireUpdatedTask(existing.id, {
|
|
77694
|
+
cron: parsed.cron,
|
|
77695
|
+
prompt,
|
|
77696
|
+
recurring: true,
|
|
77697
|
+
owner: "session-loop",
|
|
77698
|
+
loopInterval: parsed.interval,
|
|
77699
|
+
paused: false,
|
|
77700
|
+
autoExpire: false,
|
|
77701
|
+
createdAt: now,
|
|
77702
|
+
scheduleFromAt: now,
|
|
77703
|
+
lastFiredAt: void 0
|
|
77704
|
+
});
|
|
77705
|
+
this.cron.emitScheduled(task);
|
|
77706
|
+
return this.snapshot(task);
|
|
77707
|
+
}
|
|
77697
77708
|
const task = this.cron.addTask({
|
|
77698
77709
|
cron: parsed.cron,
|
|
77699
77710
|
prompt,
|
|
@@ -261933,6 +261944,45 @@ function contentPartFor(mimeType, url) {
|
|
|
261933
261944
|
function errorMessage$10(error) {
|
|
261934
261945
|
return error instanceof Error ? error.message : String(error);
|
|
261935
261946
|
}
|
|
261947
|
+
const MEDIA_PROGRESS_CUSTOM_KIND = "blun.media.progress";
|
|
261948
|
+
function mediaKindForToolName(name) {
|
|
261949
|
+
switch (name) {
|
|
261950
|
+
case "GenerateImage": return "image";
|
|
261951
|
+
case "GenerateVideo": return "video";
|
|
261952
|
+
case "GenerateSpeech": return "voice";
|
|
261953
|
+
case "UnderstandImage": return "image-analysis";
|
|
261954
|
+
case "UnderstandVideo": return "video-analysis";
|
|
261955
|
+
case "DubVideo": return "dubbing";
|
|
261956
|
+
case "LipSyncMedia": return "lipsync";
|
|
261957
|
+
case "GetMedia": return "media";
|
|
261958
|
+
default: return "media";
|
|
261959
|
+
}
|
|
261960
|
+
}
|
|
261961
|
+
function isMediaToolName(name) {
|
|
261962
|
+
return [
|
|
261963
|
+
"GenerateImage",
|
|
261964
|
+
"GenerateVideo",
|
|
261965
|
+
"GenerateSpeech",
|
|
261966
|
+
"UnderstandImage",
|
|
261967
|
+
"UnderstandVideo",
|
|
261968
|
+
"DubVideo",
|
|
261969
|
+
"LipSyncMedia",
|
|
261970
|
+
"GetMedia"
|
|
261971
|
+
].includes(name);
|
|
261972
|
+
}
|
|
261973
|
+
function emitMediaProgress(ctx, toolName, phase, data = {}) {
|
|
261974
|
+
ctx.onUpdate({
|
|
261975
|
+
kind: "custom",
|
|
261976
|
+
customKind: MEDIA_PROGRESS_CUSTOM_KIND,
|
|
261977
|
+
customData: {
|
|
261978
|
+
toolName,
|
|
261979
|
+
mediaKind: data.mediaKind ?? mediaKindForToolName(toolName),
|
|
261980
|
+
phase,
|
|
261981
|
+
observedAt: Date.now(),
|
|
261982
|
+
...data
|
|
261983
|
+
}
|
|
261984
|
+
});
|
|
261985
|
+
}
|
|
261936
261986
|
var PromptSchema, MediaIdSchema, GenerateImageInputSchema, GenerateVideoInputSchema, GenerateSpeechInputSchema, GetMediaInputSchema, UnderstandImageInputSchema, UnderstandVideoInputSchema, DubVideoInputSchema, LipSyncMediaInputSchema, REQUEST_NOTE, LIPSYNC_REQUEST_NOTE, MediaGenerationTool, GenerateImageTool, GenerateVideoTool, GenerateSpeechTool, UnderstandImageTool, UnderstandVideoTool, DubVideoTool, LipSyncMediaTool, GetMediaTool;
|
|
261937
261987
|
var init_blun_media$1 = __esmMin((() => {
|
|
261938
261988
|
init_zod$1();
|
|
@@ -261984,16 +262034,22 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
261984
262034
|
};
|
|
261985
262035
|
}
|
|
261986
262036
|
async execution(args, ctx) {
|
|
262037
|
+
emitMediaProgress(ctx, this.name, "submitting");
|
|
261987
262038
|
try {
|
|
261988
262039
|
const job = await this.submit(args, {
|
|
261989
262040
|
signal: ctx.signal,
|
|
261990
262041
|
toolCallId: ctx.toolCallId
|
|
261991
262042
|
});
|
|
262043
|
+
emitMediaProgress(ctx, this.name, job.status, {
|
|
262044
|
+
id: job.id,
|
|
262045
|
+
...job.progress
|
|
262046
|
+
});
|
|
261992
262047
|
return {
|
|
261993
262048
|
output: `Media job ${job.id} accepted with status ${job.status}. ${this.requestNote}`,
|
|
261994
262049
|
isError: false
|
|
261995
262050
|
};
|
|
261996
262051
|
} catch (error) {
|
|
262052
|
+
emitMediaProgress(ctx, this.name, "failed", { error: errorMessage$10(error) });
|
|
261997
262053
|
return {
|
|
261998
262054
|
isError: true,
|
|
261999
262055
|
output: `Media request failed: ${errorMessage$10(error)}`
|
|
@@ -262070,6 +262126,7 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262070
262126
|
};
|
|
262071
262127
|
}
|
|
262072
262128
|
async execution(args, safePath, ctx) {
|
|
262129
|
+
emitMediaProgress(ctx, "UnderstandImage", "uploading");
|
|
262073
262130
|
try {
|
|
262074
262131
|
const fileType = detectFileType(safePath, await this.kaos.readBytes(safePath, 512), "media");
|
|
262075
262132
|
if (fileType.mimeType !== "image/png" && fileType.mimeType !== "image/jpeg") return {
|
|
@@ -262086,12 +262143,18 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262086
262143
|
toolCallId: ctx.toolCallId
|
|
262087
262144
|
};
|
|
262088
262145
|
const upload = await this.provider.uploadMedia(data, fileType.mimeType, options);
|
|
262146
|
+
emitMediaProgress(ctx, "UnderstandImage", "processing");
|
|
262089
262147
|
const job = await this.provider.understandImage(upload.id, args.prompt, options);
|
|
262148
|
+
emitMediaProgress(ctx, "UnderstandImage", job.status, {
|
|
262149
|
+
id: job.id,
|
|
262150
|
+
...job.progress
|
|
262151
|
+
});
|
|
262090
262152
|
return {
|
|
262091
262153
|
output: `Media job ${job.id} accepted with status ${job.status}. ${REQUEST_NOTE}`,
|
|
262092
262154
|
isError: false
|
|
262093
262155
|
};
|
|
262094
262156
|
} catch (error) {
|
|
262157
|
+
emitMediaProgress(ctx, "UnderstandImage", "failed", { error: errorMessage$10(error) });
|
|
262095
262158
|
return {
|
|
262096
262159
|
isError: true,
|
|
262097
262160
|
output: `Image understanding failed: ${errorMessage$10(error)}`
|
|
@@ -262153,6 +262216,7 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262153
262216
|
};
|
|
262154
262217
|
}
|
|
262155
262218
|
async execution(args, ctx) {
|
|
262219
|
+
emitMediaProgress(ctx, "GetMedia", "checking", { id: args.id });
|
|
262156
262220
|
try {
|
|
262157
262221
|
const result = await this.provider.getMedia(args.id, {
|
|
262158
262222
|
signal: ctx.signal,
|
|
@@ -262166,15 +262230,22 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262166
262230
|
].includes(result.status.trim().toLowerCase());
|
|
262167
262231
|
const source = result.sourceId === void 0 ? "" : ` Source job ${result.sourceId}${result.sourceStatus === void 0 ? "" : ` status: ${result.sourceStatus}`}.`;
|
|
262168
262232
|
const retryable = result.retryable === void 0 ? "" : ` Retryable: ${result.retryable ? "yes" : "no"}.`;
|
|
262233
|
+
emitMediaProgress(ctx, "GetMedia", result.status, {
|
|
262234
|
+
id: result.id,
|
|
262235
|
+
...result.progress
|
|
262236
|
+
});
|
|
262169
262237
|
return {
|
|
262170
262238
|
output: `Media job ${result.id} status: ${result.status}.${source}${retryable}`,
|
|
262171
262239
|
isError: terminalError
|
|
262172
262240
|
};
|
|
262173
262241
|
}
|
|
262174
|
-
if (result.kind === "text")
|
|
262175
|
-
|
|
262176
|
-
|
|
262177
|
-
|
|
262242
|
+
if (result.kind === "text") {
|
|
262243
|
+
emitMediaProgress(ctx, "GetMedia", "complete", { id: result.id });
|
|
262244
|
+
return {
|
|
262245
|
+
output: result.text,
|
|
262246
|
+
isError: false
|
|
262247
|
+
};
|
|
262248
|
+
}
|
|
262178
262249
|
const url = `data:${result.mimeType};base64,${Buffer.from(result.data).toString("base64")}`;
|
|
262179
262250
|
const mediaPart = contentPartFor(result.mimeType, url);
|
|
262180
262251
|
if (mediaPart === void 0) return {
|
|
@@ -262187,6 +262258,11 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262187
262258
|
});
|
|
262188
262259
|
const localPath = join(this.outputDir, `${safeMediaId(result.id)}.${extensionForMediaType(result.mimeType)}`);
|
|
262189
262260
|
await writeFile(localPath, result.data, { mode: 384 });
|
|
262261
|
+
emitMediaProgress(ctx, "GetMedia", "complete", {
|
|
262262
|
+
id: result.id,
|
|
262263
|
+
mimeType: result.mimeType,
|
|
262264
|
+
localPath
|
|
262265
|
+
});
|
|
262190
262266
|
return {
|
|
262191
262267
|
output: [{
|
|
262192
262268
|
type: "text",
|
|
@@ -262195,6 +262271,10 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262195
262271
|
isError: false
|
|
262196
262272
|
};
|
|
262197
262273
|
} catch (error) {
|
|
262274
|
+
emitMediaProgress(ctx, "GetMedia", "failed", {
|
|
262275
|
+
id: args.id,
|
|
262276
|
+
error: errorMessage$10(error)
|
|
262277
|
+
});
|
|
262198
262278
|
return {
|
|
262199
262279
|
isError: true,
|
|
262200
262280
|
output: `Media lookup failed: ${errorMessage$10(error)}`
|
|
@@ -310721,13 +310801,47 @@ async function parseBlockedStatus(response, id) {
|
|
|
310721
310801
|
...typeof retryable === "boolean" ? { retryable } : {}
|
|
310722
310802
|
};
|
|
310723
310803
|
}
|
|
310804
|
+
function mediaPayloadNumber(payload, keys) {
|
|
310805
|
+
for (const key of keys) {
|
|
310806
|
+
const value = payload[key];
|
|
310807
|
+
const parsed = typeof value === "number" ? value : typeof value === "string" && value.trim() !== "" ? Number(value) : NaN;
|
|
310808
|
+
if (Number.isFinite(parsed) && parsed >= 0) return parsed;
|
|
310809
|
+
}
|
|
310810
|
+
}
|
|
310811
|
+
function mediaPayloadText(payload, keys) {
|
|
310812
|
+
for (const key of keys) {
|
|
310813
|
+
const value = payload[key];
|
|
310814
|
+
if (typeof value === "string" && value.trim() !== "") return value.trim();
|
|
310815
|
+
}
|
|
310816
|
+
}
|
|
310817
|
+
function mediaProgressFromPayload(payload) {
|
|
310818
|
+
const rawPercent = mediaPayloadNumber(payload, ["percent", "progress_percent", "progressPercent", "progress"]);
|
|
310819
|
+
const percent = rawPercent === void 0 ? void 0 : rawPercent <= 1 ? rawPercent * 100 : rawPercent;
|
|
310820
|
+
const progress = {
|
|
310821
|
+
phaseLabel: mediaPayloadText(payload, ["phase", "stage", "step_name", "stepName"]),
|
|
310822
|
+
percent: percent === void 0 ? void 0 : Math.min(100, Math.max(0, percent)),
|
|
310823
|
+
currentFrame: mediaPayloadNumber(payload, ["current_frame", "currentFrame", "frames_completed", "framesCompleted"]),
|
|
310824
|
+
totalFrames: mediaPayloadNumber(payload, ["total_frames", "totalFrames", "frame_count", "frameCount"]),
|
|
310825
|
+
fps: mediaPayloadNumber(payload, ["fps", "frames_per_second", "framesPerSecond"]),
|
|
310826
|
+
currentStep: mediaPayloadNumber(payload, ["current_step", "currentStep", "step"]),
|
|
310827
|
+
totalSteps: mediaPayloadNumber(payload, ["total_steps", "totalSteps", "steps"]),
|
|
310828
|
+
currentSegment: mediaPayloadNumber(payload, ["current_segment", "currentSegment", "segment"]),
|
|
310829
|
+
totalSegments: mediaPayloadNumber(payload, ["total_segments", "totalSegments", "segments"]),
|
|
310830
|
+
generatedSeconds: mediaPayloadNumber(payload, ["generated_seconds", "generatedSeconds", "audio_seconds", "audioSeconds"]),
|
|
310831
|
+
queuePosition: mediaPayloadNumber(payload, ["queue_position", "queuePosition"]),
|
|
310832
|
+
elapsedSeconds: mediaPayloadNumber(payload, ["elapsed_seconds", "elapsedSeconds"]),
|
|
310833
|
+
remainingSeconds: mediaPayloadNumber(payload, ["remaining_seconds", "remainingSeconds", "eta_seconds", "etaSeconds"])
|
|
310834
|
+
};
|
|
310835
|
+
return Object.fromEntries(Object.entries(progress).filter(([, value]) => value !== void 0));
|
|
310836
|
+
}
|
|
310724
310837
|
function parseJob(payload) {
|
|
310725
310838
|
const id = payload["id"];
|
|
310726
310839
|
const status = payload["status"];
|
|
310727
310840
|
if (typeof id !== "string" || id.length === 0 || typeof status !== "string" || status.length === 0) throw new Error("Media request returned an invalid job response.");
|
|
310728
310841
|
return {
|
|
310729
310842
|
id,
|
|
310730
|
-
status
|
|
310843
|
+
status,
|
|
310844
|
+
progress: mediaProgressFromPayload(payload)
|
|
310731
310845
|
};
|
|
310732
310846
|
}
|
|
310733
310847
|
function parseStatus(payload, expectedId) {
|
|
@@ -310737,7 +310851,8 @@ function parseStatus(payload, expectedId) {
|
|
|
310737
310851
|
return {
|
|
310738
310852
|
kind: "status",
|
|
310739
310853
|
id,
|
|
310740
|
-
status
|
|
310854
|
+
status,
|
|
310855
|
+
progress: mediaProgressFromPayload(payload)
|
|
310741
310856
|
};
|
|
310742
310857
|
}
|
|
310743
310858
|
async function assertSuccess(response, operation) {
|
|
@@ -401449,6 +401564,16 @@ function slashCommandBusyReason(options) {
|
|
|
401449
401564
|
if (options.isStreaming) return "streaming";
|
|
401450
401565
|
if (options.isCompacting) return "compacting";
|
|
401451
401566
|
}
|
|
401567
|
+
function shouldQueueBusySlashCommand(input, options) {
|
|
401568
|
+
const parsed = parseSlashInput(input);
|
|
401569
|
+
if (parsed === null) return false;
|
|
401570
|
+
if (slashCommandBusyReason(options) === void 0) return false;
|
|
401571
|
+
const normalizedName = normalizeLegacyEffortCommandName(parsed.name);
|
|
401572
|
+
const command = findBuiltInSlashCommand(normalizedName);
|
|
401573
|
+
if (command === void 0) return true;
|
|
401574
|
+
if (!isExperimentalFlagEnabled(command.experimentalFlag)) return false;
|
|
401575
|
+
return resolveSlashCommandAvailability(command, parsed.args) === "idle-only";
|
|
401576
|
+
}
|
|
401452
401577
|
function slashBusyMessage(commandName, reason) {
|
|
401453
401578
|
if (reason === "streaming") return uiText("resolve.busy.streaming", { command: commandName });
|
|
401454
401579
|
return uiText("resolve.busy.compacting", { command: commandName });
|
|
@@ -426149,27 +426274,7 @@ registerUiCatalogFragment({
|
|
|
426149
426274
|
}
|
|
426150
426275
|
});
|
|
426151
426276
|
const TICK_INTERVAL = 200;
|
|
426152
|
-
const COMPACTION_TOKENS_PER_SECOND = 4250;
|
|
426153
|
-
const MIN_ESTIMATED_DURATION_MS = 1e3;
|
|
426154
|
-
const ACTIVE_PERCENT_LIMIT = 97;
|
|
426155
426277
|
const BAR_WIDTH = 12;
|
|
426156
|
-
const LOAD_PHASE_SHARE = .72;
|
|
426157
|
-
const TAIL_PHASE_SHARE = .25;
|
|
426158
|
-
function estimateCompactionDurationMs(inputTokens) {
|
|
426159
|
-
if (inputTokens === void 0 || !Number.isFinite(inputTokens) || inputTokens <= 0) return;
|
|
426160
|
-
return Math.max(MIN_ESTIMATED_DURATION_MS, Math.round(inputTokens / COMPACTION_TOKENS_PER_SECOND * 1e3));
|
|
426161
|
-
}
|
|
426162
|
-
function estimateCompactionPercent(elapsedMs, inputTokens) {
|
|
426163
|
-
const durationMs = estimateCompactionDurationMs(inputTokens);
|
|
426164
|
-
if (durationMs === void 0) return 0;
|
|
426165
|
-
const safeElapsedMs = Math.max(0, elapsedMs);
|
|
426166
|
-
let estimate = Math.min(1, safeElapsedMs / durationMs) * LOAD_PHASE_SHARE;
|
|
426167
|
-
if (safeElapsedMs > durationMs) {
|
|
426168
|
-
const tailFraction = 1 - Math.exp(-(safeElapsedMs - durationMs) / durationMs);
|
|
426169
|
-
estimate += tailFraction * TAIL_PHASE_SHARE;
|
|
426170
|
-
}
|
|
426171
|
-
return Math.min(ACTIVE_PERCENT_LIMIT, Math.max(0, Math.round(estimate * 100)));
|
|
426172
|
-
}
|
|
426173
426278
|
var SingleLineText = class {
|
|
426174
426279
|
text;
|
|
426175
426280
|
constructor(text) {
|
|
@@ -426240,7 +426345,6 @@ var CompactionComponent = class extends Container {
|
|
|
426240
426345
|
stage = 1;
|
|
426241
426346
|
estimatedStageCount;
|
|
426242
426347
|
stageCount;
|
|
426243
|
-
estimatedProgressPercent;
|
|
426244
426348
|
windowUsagePercent;
|
|
426245
426349
|
constructor(ui, instruction, tip, showRunning = true) {
|
|
426246
426350
|
super();
|
|
@@ -426297,7 +426401,6 @@ var CompactionComponent = class extends Container {
|
|
|
426297
426401
|
this.attempt = progress.attempt;
|
|
426298
426402
|
this.stage = progress.stage ?? this.stage;
|
|
426299
426403
|
this.estimatedStageCount = progress.estimatedStageCount;
|
|
426300
|
-
this.estimatedProgressPercent = progress.estimatedProgressPercent;
|
|
426301
426404
|
this.windowUsagePercent = progress.windowUsagePercent;
|
|
426302
426405
|
this.statusText.setText(this.buildStatusLine());
|
|
426303
426406
|
if (this.showRunning) this.ui?.requestRender();
|
|
@@ -426319,21 +426422,16 @@ var CompactionComponent = class extends Container {
|
|
|
426319
426422
|
}
|
|
426320
426423
|
if (this.failed) return `${currentTheme.fg("error", STATUS_BULLET)}${currentTheme.boldFg("error", this.failureTitle ?? uiText("compaction.failed"))}${currentTheme.fg("textDim", ` · ${this.failureDetail ?? uiText("compaction.failureDetail")}`)}`;
|
|
426321
426424
|
if (this.canceled) return `${currentTheme.fg("warning", STATUS_BULLET)}${currentTheme.boldFg("warning", uiText("compaction.canceled"))}`;
|
|
426322
|
-
const elapsedMs = Math.max(0, Date.now() - this.attemptStartedAtMs);
|
|
426323
|
-
const percent = this.estimatedProgressPercent ?? estimateCompactionPercent(elapsedMs, this.estimatedInputTokens);
|
|
426324
|
-
const filled = Math.round(percent / 100 * BAR_WIDTH);
|
|
426325
|
-
const bar = `[${"█".repeat(filled)}${"░".repeat(BAR_WIDTH - filled)}]`;
|
|
426326
426425
|
const stageText = formatCompactionStageText({
|
|
426327
426426
|
stage: this.stage,
|
|
426328
426427
|
estimatedStageCount: this.estimatedStageCount,
|
|
426329
|
-
estimatedProgressPercent: this.estimatedProgressPercent,
|
|
426330
426428
|
windowUsagePercent: this.windowUsagePercent,
|
|
426331
426429
|
estimatedInputTokens: this.estimatedInputTokens,
|
|
426332
426430
|
charsReceived: 0,
|
|
426333
426431
|
attempt: this.attempt
|
|
426334
426432
|
});
|
|
426335
426433
|
const runningText = `${formatCompactionRunningText(this.estimatedInputTokens)}${stageText.length === 0 ? "" : ` · ${stageText}`}`;
|
|
426336
|
-
return `${currentTheme.fg("primary",
|
|
426434
|
+
return `${currentTheme.fg("primary", STATUS_BULLET)}${currentTheme.boldFg("primary", runningText)}${currentTheme.fg("textDim", ` · ${String(this.elapsedSeconds())}s`)}${this.attempt > 1 ? currentTheme.fg("textDim", uiText("compaction.attempt", { attempt: this.attempt })) : ""}${currentTheme.fg("textDim", ` · ${uiText("compaction.cancelHint")}`)}${this.instruction ? currentTheme.fg("textDim", ` · ${this.instruction}`) : ""}${this.tip ? currentTheme.fg("textDim", ` · ${this.tip}`) : ""}`;
|
|
426337
426435
|
}
|
|
426338
426436
|
startTicking() {
|
|
426339
426437
|
this.timer = setInterval(() => {
|
|
@@ -427842,24 +427940,12 @@ var AgentSwarmProgressComponent = class {
|
|
|
427842
427940
|
if (snapshot.phase === "cancelled" && snapshot.ticks <= 0) return renderCancelledUnstartedCell(member, width, this.colors);
|
|
427843
427941
|
if (!layout.renderText) return this.renderCompactCell(member, snapshot, layout.barCells, nowMs);
|
|
427844
427942
|
if (snapshot.phase === "queued" && snapshot.ticks <= 0) return renderQueuedCell(member, width, this.colors);
|
|
427845
|
-
const
|
|
427846
|
-
memberKey: member.id,
|
|
427847
|
-
phase: snapshot.phase,
|
|
427848
|
-
capacityTicks: layout.barCells * PROGRESS_LEVELS.length,
|
|
427849
|
-
nowMs
|
|
427850
|
-
});
|
|
427851
|
-
const prefix = `${chalk.hex(this.colors.primary)(member.id)} ${progressBar(estimate.displayTicks, snapshot.phase, layout.barCells, this.colors, snapshot.phaseElapsedMs, cancelledProgressColor(member, snapshot.phase, this.colors))} `;
|
|
427943
|
+
const prefix = `${chalk.hex(this.colors.primary)(member.id)} ${chalk.hex(phaseColor(snapshot.phase, this.colors))(phaseLabel(snapshot.phase))} · `;
|
|
427852
427944
|
return prefix + renderCellLabel(member, snapshot, Math.max(1, width - visibleWidth(prefix)), this.colors);
|
|
427853
427945
|
}
|
|
427854
427946
|
renderCompactCell(member, snapshot, barCells, nowMs) {
|
|
427855
427947
|
const estimatePhase = snapshot.phase === "pending" ? "queued" : snapshot.phase;
|
|
427856
|
-
|
|
427857
|
-
memberKey: member.id,
|
|
427858
|
-
phase: estimatePhase,
|
|
427859
|
-
capacityTicks: barCells * PROGRESS_LEVELS.length,
|
|
427860
|
-
nowMs
|
|
427861
|
-
});
|
|
427862
|
-
return `${chalk.hex(this.colors.primary)(member.id)} ${progressBar(estimate.displayTicks, estimatePhase, barCells, this.colors, snapshot.phaseElapsedMs, cancelledProgressColor(member, snapshot.phase, this.colors))}${compactTerminalMark(member, snapshot.phase, this.colors)}`;
|
|
427948
|
+
return `${chalk.hex(this.colors.primary)(member.id)} ${chalk.hex(phaseColor(estimatePhase, this.colors))(phaseLabel(estimatePhase))}${compactTerminalMark(member, snapshot.phase, this.colors)}`;
|
|
427863
427949
|
}
|
|
427864
427950
|
findMemberForSubagent(agentId, swarmIndex) {
|
|
427865
427951
|
const existing = this.findMemberByAgentId(agentId);
|
|
@@ -497915,6 +498001,208 @@ var ActivityPaneComponent = class extends Container {
|
|
|
497915
498001
|
return lines;
|
|
497916
498002
|
}
|
|
497917
498003
|
};
|
|
498004
|
+
registerUiCatalogFragment({
|
|
498005
|
+
en: {
|
|
498006
|
+
"media.activity.jobs": "{count} media jobs active",
|
|
498007
|
+
"media.detail.queue": "Position {position}",
|
|
498008
|
+
"media.detail.segment": "Segment {current}/{total}",
|
|
498009
|
+
"media.detail.audio": "{seconds}s audio",
|
|
498010
|
+
"media.detail.remaining": "about {duration} remaining",
|
|
498011
|
+
"media.kind.media": "Media",
|
|
498012
|
+
"media.kind.image": "Image",
|
|
498013
|
+
"media.kind.video": "Video",
|
|
498014
|
+
"media.kind.voice": "Voice",
|
|
498015
|
+
"media.kind.image-analysis": "Image analysis",
|
|
498016
|
+
"media.kind.video-analysis": "Video analysis",
|
|
498017
|
+
"media.kind.dubbing": "Dubbing",
|
|
498018
|
+
"media.kind.lipsync": "Lip sync",
|
|
498019
|
+
"media.phase.submitting": "Sending request",
|
|
498020
|
+
"media.phase.uploading": "Sending request",
|
|
498021
|
+
"media.phase.accepted": "Queued",
|
|
498022
|
+
"media.phase.pending": "Queued",
|
|
498023
|
+
"media.phase.queued": "Queued",
|
|
498024
|
+
"media.phase.running": "Processing",
|
|
498025
|
+
"media.phase.in-progress": "Processing",
|
|
498026
|
+
"media.phase.generating": "Generating",
|
|
498027
|
+
"media.phase.rendering": "Rendering",
|
|
498028
|
+
"media.phase.processing": "Processing",
|
|
498029
|
+
"media.phase.checking": "Checking status",
|
|
498030
|
+
"media.phase.audio-analysis": "Audio analysis",
|
|
498031
|
+
"media.phase.face-detection": "Face detection",
|
|
498032
|
+
"media.phase.face-tracking": "Face tracking",
|
|
498033
|
+
"media.phase.lip-sync-running": "Lip sync running",
|
|
498034
|
+
"media.phase.exporting": "Exporting",
|
|
498035
|
+
"media.phase.saving": "Saving",
|
|
498036
|
+
"media.phase.upscaling": "Upscaling",
|
|
498037
|
+
"media.phase.analyzing": "Analyzing"
|
|
498038
|
+
},
|
|
498039
|
+
de: {
|
|
498040
|
+
"media.activity.jobs": "{count} Medienaufträge aktiv",
|
|
498041
|
+
"media.detail.queue": "Platz {position}",
|
|
498042
|
+
"media.detail.segment": "Abschnitt {current}/{total}",
|
|
498043
|
+
"media.detail.audio": "{seconds}s Audio",
|
|
498044
|
+
"media.detail.remaining": "noch etwa {duration}",
|
|
498045
|
+
"media.kind.media": "Medien",
|
|
498046
|
+
"media.kind.image": "Bild",
|
|
498047
|
+
"media.kind.video": "Video",
|
|
498048
|
+
"media.kind.voice": "Stimme",
|
|
498049
|
+
"media.kind.image-analysis": "Bildanalyse",
|
|
498050
|
+
"media.kind.video-analysis": "Videoanalyse",
|
|
498051
|
+
"media.kind.dubbing": "Vertonung",
|
|
498052
|
+
"media.kind.lipsync": "Lip-Sync",
|
|
498053
|
+
"media.phase.submitting": "Auftrag wird gesendet",
|
|
498054
|
+
"media.phase.uploading": "Auftrag wird gesendet",
|
|
498055
|
+
"media.phase.accepted": "Eingereiht",
|
|
498056
|
+
"media.phase.pending": "Eingereiht",
|
|
498057
|
+
"media.phase.queued": "Eingereiht",
|
|
498058
|
+
"media.phase.running": "Wird verarbeitet",
|
|
498059
|
+
"media.phase.in-progress": "Wird verarbeitet",
|
|
498060
|
+
"media.phase.generating": "Wird erzeugt",
|
|
498061
|
+
"media.phase.rendering": "Wird gerendert",
|
|
498062
|
+
"media.phase.processing": "Wird verarbeitet",
|
|
498063
|
+
"media.phase.checking": "Status wird geprüft",
|
|
498064
|
+
"media.phase.audio-analysis": "Audioanalyse",
|
|
498065
|
+
"media.phase.face-detection": "Gesichtserkennung",
|
|
498066
|
+
"media.phase.face-tracking": "Gesicht wird verfolgt",
|
|
498067
|
+
"media.phase.lip-sync-running": "Lip-Sync läuft",
|
|
498068
|
+
"media.phase.exporting": "Wird exportiert",
|
|
498069
|
+
"media.phase.saving": "Wird gespeichert",
|
|
498070
|
+
"media.phase.upscaling": "Wird hochskaliert",
|
|
498071
|
+
"media.phase.analyzing": "Wird analysiert"
|
|
498072
|
+
}
|
|
498073
|
+
});
|
|
498074
|
+
function mediaActivityStatusKey(value) {
|
|
498075
|
+
return String(value ?? "processing").trim().toLowerCase().replaceAll(/[^a-z0-9]+/g, "-");
|
|
498076
|
+
}
|
|
498077
|
+
function mediaActivityIsTerminal(value) {
|
|
498078
|
+
return [
|
|
498079
|
+
"complete",
|
|
498080
|
+
"completed",
|
|
498081
|
+
"ready",
|
|
498082
|
+
"failed",
|
|
498083
|
+
"expired",
|
|
498084
|
+
"blocked"
|
|
498085
|
+
].includes(mediaActivityStatusKey(value));
|
|
498086
|
+
}
|
|
498087
|
+
const MEDIA_ACTIVITY_LABELS = {
|
|
498088
|
+
"media.kind": /* @__PURE__ */ new Set([
|
|
498089
|
+
"media",
|
|
498090
|
+
"image",
|
|
498091
|
+
"video",
|
|
498092
|
+
"voice",
|
|
498093
|
+
"image-analysis",
|
|
498094
|
+
"video-analysis",
|
|
498095
|
+
"dubbing",
|
|
498096
|
+
"lipsync"
|
|
498097
|
+
]),
|
|
498098
|
+
"media.phase": /* @__PURE__ */ new Set([
|
|
498099
|
+
"submitting",
|
|
498100
|
+
"uploading",
|
|
498101
|
+
"accepted",
|
|
498102
|
+
"pending",
|
|
498103
|
+
"queued",
|
|
498104
|
+
"running",
|
|
498105
|
+
"in-progress",
|
|
498106
|
+
"generating",
|
|
498107
|
+
"rendering",
|
|
498108
|
+
"processing",
|
|
498109
|
+
"checking",
|
|
498110
|
+
"audio-analysis",
|
|
498111
|
+
"face-detection",
|
|
498112
|
+
"face-tracking",
|
|
498113
|
+
"lip-sync-running",
|
|
498114
|
+
"exporting",
|
|
498115
|
+
"saving",
|
|
498116
|
+
"upscaling",
|
|
498117
|
+
"analyzing"
|
|
498118
|
+
])
|
|
498119
|
+
};
|
|
498120
|
+
function mediaUiText(key, params = {}) {
|
|
498121
|
+
return uiTextFor(getCurrentUiLocale() === "de" ? "de" : "en", key, params);
|
|
498122
|
+
}
|
|
498123
|
+
function mediaActivityLabel(prefix, value, fallback) {
|
|
498124
|
+
const normalized = mediaActivityStatusKey(value);
|
|
498125
|
+
if (!MEDIA_ACTIVITY_LABELS[prefix]?.has(normalized)) return fallback;
|
|
498126
|
+
return mediaUiText(`${prefix}.${normalized}`);
|
|
498127
|
+
}
|
|
498128
|
+
function formatMediaDuration(seconds) {
|
|
498129
|
+
if (!Number.isFinite(seconds) || seconds < 0) return;
|
|
498130
|
+
const whole = Math.round(seconds);
|
|
498131
|
+
const minutes = Math.floor(whole / 60);
|
|
498132
|
+
const rest = whole % 60;
|
|
498133
|
+
return minutes > 0 ? `${String(minutes)}:${String(rest).padStart(2, "0")}` : `${String(rest)}s`;
|
|
498134
|
+
}
|
|
498135
|
+
var MediaActivityStore = class {
|
|
498136
|
+
jobs = /* @__PURE__ */ new Map();
|
|
498137
|
+
update(toolCallId, event) {
|
|
498138
|
+
if (event === null || typeof event !== "object") return;
|
|
498139
|
+
const id = typeof event.id === "string" && event.id.length > 0 ? event.id : void 0;
|
|
498140
|
+
let existingKey = id;
|
|
498141
|
+
if (existingKey === void 0 || !this.jobs.has(existingKey)) for (const [key, job] of this.jobs) if (job.toolCallId === toolCallId || id !== void 0 && job.id === id) {
|
|
498142
|
+
existingKey = key;
|
|
498143
|
+
break;
|
|
498144
|
+
}
|
|
498145
|
+
const key = id ?? existingKey ?? toolCallId;
|
|
498146
|
+
const previous = existingKey === void 0 ? void 0 : this.jobs.get(existingKey);
|
|
498147
|
+
if (existingKey !== void 0 && existingKey !== key) this.jobs.delete(existingKey);
|
|
498148
|
+
if (mediaActivityIsTerminal(event.phase)) {
|
|
498149
|
+
this.jobs.delete(key);
|
|
498150
|
+
return;
|
|
498151
|
+
}
|
|
498152
|
+
const mediaKind = event.mediaKind === "media" && previous?.mediaKind !== void 0 ? previous.mediaKind : event.mediaKind ?? previous?.mediaKind ?? "media";
|
|
498153
|
+
this.jobs.set(key, {
|
|
498154
|
+
...previous,
|
|
498155
|
+
...event,
|
|
498156
|
+
id: id ?? previous?.id,
|
|
498157
|
+
mediaKind,
|
|
498158
|
+
toolCallId,
|
|
498159
|
+
startedAt: previous?.startedAt ?? Date.now(),
|
|
498160
|
+
updatedAt: Date.now()
|
|
498161
|
+
});
|
|
498162
|
+
}
|
|
498163
|
+
active() {
|
|
498164
|
+
return [...this.jobs.values()].filter((job) => !mediaActivityIsTerminal(job.phase)).sort((a, b) => a.startedAt - b.startedAt);
|
|
498165
|
+
}
|
|
498166
|
+
clear() {
|
|
498167
|
+
this.jobs.clear();
|
|
498168
|
+
}
|
|
498169
|
+
};
|
|
498170
|
+
var MediaActivityComponent = class {
|
|
498171
|
+
jobs;
|
|
498172
|
+
constructor(jobs) {
|
|
498173
|
+
this.jobs = jobs;
|
|
498174
|
+
}
|
|
498175
|
+
invalidate() {}
|
|
498176
|
+
render(width) {
|
|
498177
|
+
if (this.jobs.length === 0) return [];
|
|
498178
|
+
const job = this.jobs[0];
|
|
498179
|
+
const kind = mediaActivityLabel("media.kind", job.mediaKind, String(job.mediaKind ?? "Media"));
|
|
498180
|
+
const rawPhase = job.phaseLabel ?? job.phase ?? "processing";
|
|
498181
|
+
const phase = sanitizeTerminalText(mediaActivityLabel("media.phase", rawPhase, String(rawPhase)));
|
|
498182
|
+
const details = [];
|
|
498183
|
+
if (job.queuePosition !== void 0) details.push(mediaUiText("media.detail.queue", { position: job.queuePosition }));
|
|
498184
|
+
if (job.currentStep !== void 0 && job.totalSteps !== void 0) details.push(`${String(job.currentStep)}/${String(job.totalSteps)}`);
|
|
498185
|
+
if (job.currentSegment !== void 0 && job.totalSegments !== void 0) details.push(mediaUiText("media.detail.segment", {
|
|
498186
|
+
current: job.currentSegment,
|
|
498187
|
+
total: job.totalSegments
|
|
498188
|
+
}));
|
|
498189
|
+
if (job.currentFrame !== void 0 && job.totalFrames !== void 0) details.push(`Frame ${String(job.currentFrame)}/${String(job.totalFrames)}`);
|
|
498190
|
+
if (job.fps !== void 0) details.push(`${String(Math.round(job.fps * 10) / 10)} FPS`);
|
|
498191
|
+
if (job.generatedSeconds !== void 0) details.push(mediaUiText("media.detail.audio", { seconds: Math.round(job.generatedSeconds) }));
|
|
498192
|
+
const elapsed = job.elapsedSeconds ?? (Date.now() - job.startedAt) / 1e3;
|
|
498193
|
+
const elapsedText = formatMediaDuration(elapsed);
|
|
498194
|
+
if (elapsedText !== void 0) details.push(elapsedText);
|
|
498195
|
+
if (job.remainingSeconds !== void 0) details.push(mediaUiText("media.detail.remaining", { duration: formatMediaDuration(job.remainingSeconds) }));
|
|
498196
|
+
let progress = "";
|
|
498197
|
+
if (job.percent !== void 0 && Number.isFinite(job.percent)) {
|
|
498198
|
+
const percent = Math.min(100, Math.max(0, job.percent));
|
|
498199
|
+
progress = ` · ${renderProgressBar(percent / 100, 12)} · ${String(Math.round(percent))} %`;
|
|
498200
|
+
}
|
|
498201
|
+
const summary = this.jobs.length > 1 ? ` · ${mediaUiText("media.activity.jobs", { count: this.jobs.length })}` : "";
|
|
498202
|
+
const line = `${currentTheme.boldFg("primary", kind)} · ${phase}${details.length === 0 ? "" : ` · ${details.join(" · ")}`}${progress}${summary}`;
|
|
498203
|
+
return [truncateToWidth(line, Math.max(1, width), "…")];
|
|
498204
|
+
}
|
|
498205
|
+
};
|
|
497918
498206
|
//#endregion
|
|
497919
498207
|
//#region src/tui/components/panes/queue-pane.copy.ts
|
|
497920
498208
|
registerUiCatalogFragment({
|
|
@@ -504441,6 +504729,10 @@ var SessionEventHandler = class {
|
|
|
504441
504729
|
streamingUI.scheduleFlush();
|
|
504442
504730
|
}
|
|
504443
504731
|
handleToolProgress(event) {
|
|
504732
|
+
if (event.update.kind === "custom" && event.update.customKind === MEDIA_PROGRESS_CUSTOM_KIND) {
|
|
504733
|
+
this.host.updateMediaActivity(event.toolCallId, event.update.customData);
|
|
504734
|
+
return;
|
|
504735
|
+
}
|
|
504444
504736
|
const text = event.update.text;
|
|
504445
504737
|
if (text === void 0 || text.length === 0) return;
|
|
504446
504738
|
const tc = this.host.streamingUI.getToolComponent(event.toolCallId);
|
|
@@ -504462,6 +504754,10 @@ var SessionEventHandler = class {
|
|
|
504462
504754
|
synthetic: event.synthetic
|
|
504463
504755
|
};
|
|
504464
504756
|
const matchedCall = streamingUI.completeToolResult(event.toolCallId, resultData);
|
|
504757
|
+
if (matchedCall !== void 0 && isMediaToolName(matchedCall.name) && event.isError === true) this.host.updateMediaActivity(event.toolCallId, {
|
|
504758
|
+
mediaKind: mediaKindForToolName(matchedCall.name),
|
|
504759
|
+
phase: "failed"
|
|
504760
|
+
});
|
|
504465
504761
|
if (matchedCall?.name === "GetMedia" && event.isError !== true) this.host.runChannelMediaFallback(event.output);
|
|
504466
504762
|
this.subAgentEventHandler.handleAgentSwarmToolResult(event.toolCallId, resultData, event.isError === true);
|
|
504467
504763
|
if (matchedCall !== void 0 && matchedCall.name === "TodoList" && !event.isError) {
|
|
@@ -506827,24 +507123,21 @@ function formatContextStatus(usage, tokens, maxTokens, colors, width, now = /* @
|
|
|
506827
507123
|
return truncateToWidth(current, available, "…");
|
|
506828
507124
|
}
|
|
506829
507125
|
function formatCompactionStatus(elapsedMs, estimatedInputTokens, progress, colors, width, now = /* @__PURE__ */ new Date()) {
|
|
506830
|
-
const percent = progress?.estimatedProgressPercent ?? estimateCompactionPercent(elapsedMs, estimatedInputTokens);
|
|
506831
|
-
const filled = Math.max(1, Math.ceil((1 - percent / 100) * CONTEXT_BAR_WIDTH));
|
|
506832
|
-
const bar = chalk.hex(colors.primary)(`${"█".repeat(filled)}${"░".repeat(CONTEXT_BAR_WIDTH - filled)}`);
|
|
506833
507126
|
const label = formatCompactionRunningText(estimatedInputTokens);
|
|
506834
507127
|
const stageText = progress === void 0 ? "" : formatCompactionStageText(progress);
|
|
506835
507128
|
const compactStageText = progress?.stage === void 0 || progress.estimatedStageCount === void 0 ? "" : `${String(progress.stage)}/~${String(progress.estimatedStageCount)}${progress.windowUsagePercent === void 0 ? "" : ` · ${String(progress.windowUsagePercent)}%`}`;
|
|
506836
|
-
const
|
|
507129
|
+
const elapsed = `${String(Math.max(0, Math.round(elapsedMs / 1e3)))}s`;
|
|
506837
507130
|
const clock = chalk.hex(colors.textDim)(` · ${clockHhmm(now)}`);
|
|
506838
507131
|
const variants = [
|
|
506839
|
-
`${label}${stageText.length === 0 ? "" : ` · ${stageText}`}
|
|
507132
|
+
`${label}${stageText.length === 0 ? "" : ` · ${stageText}`} · ${elapsed}${clock}`,
|
|
506840
507133
|
`${label}${stageText.length === 0 ? "" : ` · ${stageText}`}`,
|
|
506841
507134
|
compactStageText,
|
|
506842
|
-
|
|
506843
|
-
stageText
|
|
507135
|
+
elapsed,
|
|
507136
|
+
stageText
|
|
506844
507137
|
];
|
|
506845
507138
|
const available = Math.max(0, width);
|
|
506846
507139
|
for (const variant of variants) if (visibleWidth(variant) <= available) return variant;
|
|
506847
|
-
return truncateToWidth(
|
|
507140
|
+
return truncateToWidth(elapsed, available, "…");
|
|
506848
507141
|
}
|
|
506849
507142
|
function contextMetrics(state) {
|
|
506850
507143
|
const tokens = Number.isFinite(state.contextTokens) ? Math.max(0, state.contextTokens) : 0;
|
|
@@ -512083,6 +512376,8 @@ var BlunTUI = class {
|
|
|
512083
512376
|
startupGoalPromptedSessionId;
|
|
512084
512377
|
lastActivityMode;
|
|
512085
512378
|
currentLoadingTip = void 0;
|
|
512379
|
+
mediaActivityStore = new MediaActivityStore();
|
|
512380
|
+
mediaActivityTickTimer;
|
|
512086
512381
|
lastHistoryContent;
|
|
512087
512382
|
shellOutputStreams = /* @__PURE__ */ new Map();
|
|
512088
512383
|
streamingUI;
|
|
@@ -512594,6 +512889,7 @@ var BlunTUI = class {
|
|
|
512594
512889
|
this.tasksBrowserController.close();
|
|
512595
512890
|
this.btwPanelController.clear();
|
|
512596
512891
|
this.stopActivitySpinner();
|
|
512892
|
+
this.stopMediaActivityTicking();
|
|
512597
512893
|
this.disposeEditorReplacement();
|
|
512598
512894
|
this.streamingUI.disposeActiveCompactionBlock();
|
|
512599
512895
|
this.streamingUI.resetToolUi();
|
|
@@ -512742,6 +513038,13 @@ var BlunTUI = class {
|
|
|
512742
513038
|
return;
|
|
512743
513039
|
}
|
|
512744
513040
|
if (text.trimStart().startsWith("/")) {
|
|
513041
|
+
if (shouldQueueBusySlashCommand(text, {
|
|
513042
|
+
isStreaming: this.state.appState.streamingPhase !== "idle",
|
|
513043
|
+
isCompacting: this.state.appState.isCompacting
|
|
513044
|
+
})) {
|
|
513045
|
+
this.enqueueSlashCommand(text);
|
|
513046
|
+
return;
|
|
513047
|
+
}
|
|
512745
513048
|
this.runSlashCommand(text);
|
|
512746
513049
|
return;
|
|
512747
513050
|
}
|
|
@@ -513749,6 +514052,8 @@ var BlunTUI = class {
|
|
|
513749
514052
|
this.setAppState({ mcpServersSummary: null });
|
|
513750
514053
|
this.streamingUI.setStep(0);
|
|
513751
514054
|
this.streamingUI.resetLiveText();
|
|
514055
|
+
this.mediaActivityStore.clear();
|
|
514056
|
+
this.stopMediaActivityTicking();
|
|
513752
514057
|
this.updateQueueDisplay();
|
|
513753
514058
|
}
|
|
513754
514059
|
async showResumeOtherWorkDirHint(session) {
|
|
@@ -514200,8 +514505,32 @@ var BlunTUI = class {
|
|
|
514200
514505
|
this.state.ui.requestRender();
|
|
514201
514506
|
return this.showLoginProgressSpinner(uiText("blunTui.login.waiting"));
|
|
514202
514507
|
}
|
|
514508
|
+
updateMediaActivity(toolCallId, event) {
|
|
514509
|
+
this.mediaActivityStore.update(toolCallId, event);
|
|
514510
|
+
if (this.mediaActivityStore.active().length > 0) {
|
|
514511
|
+
if (this.mediaActivityTickTimer === void 0) this.mediaActivityTickTimer = setInterval(() => this.state.ui.requestRender(), 1e3);
|
|
514512
|
+
} else this.stopMediaActivityTicking();
|
|
514513
|
+
this.lastActivityMode = void 0;
|
|
514514
|
+
this.updateActivityPane();
|
|
514515
|
+
}
|
|
514516
|
+
stopMediaActivityTicking() {
|
|
514517
|
+
if (this.mediaActivityTickTimer === void 0) return;
|
|
514518
|
+
clearInterval(this.mediaActivityTickTimer);
|
|
514519
|
+
this.mediaActivityTickTimer = void 0;
|
|
514520
|
+
}
|
|
514203
514521
|
updateActivityPane() {
|
|
514204
514522
|
const effectiveMode = this.resolveActivityPaneMode();
|
|
514523
|
+
const mediaActivities = effectiveMode === "hidden" ? [] : this.mediaActivityStore.active();
|
|
514524
|
+
if (mediaActivities.length > 0) {
|
|
514525
|
+
this.stopActivitySpinner();
|
|
514526
|
+
this.syncAgentSwarmActivitySpinner(void 0);
|
|
514527
|
+
this.lastActivityMode = `media:${mediaActivities.map((job) => `${job.id ?? job.toolCallId}:${job.updatedAt}`).join(",")}`;
|
|
514528
|
+
this.state.activityContainer.clear();
|
|
514529
|
+
this.state.activityContainer.addChild(new Spacer(1));
|
|
514530
|
+
this.state.activityContainer.addChild(new MediaActivityComponent(mediaActivities));
|
|
514531
|
+
this.state.ui.requestRender();
|
|
514532
|
+
return;
|
|
514533
|
+
}
|
|
514205
514534
|
const tipKind = loadingTipKind(effectiveMode);
|
|
514206
514535
|
if (effectiveMode === "idle" || effectiveMode === "session" || effectiveMode === "hidden") this.currentLoadingTip = void 0;
|
|
514207
514536
|
else if (tipKind !== void 0 && (this.currentLoadingTip === void 0 || this.currentLoadingTip.kind !== tipKind)) this.currentLoadingTip = {
|