blun-king-cli 9.1.46 → 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 +409 -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,9 +75550,11 @@ 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", {
|
|
75555
|
+
requestPurpose: "compaction",
|
|
75556
|
+
toolSuppressionReason: "compaction_summary",
|
|
75557
|
+
selectedToolCount: compactionTools.length,
|
|
75560
75558
|
source: data.source,
|
|
75561
75559
|
stage,
|
|
75562
75560
|
estimatedStageCount,
|
|
@@ -75575,7 +75573,6 @@ var init_full = __esmMin((() => {
|
|
|
75575
75573
|
stage,
|
|
75576
75574
|
estimatedStageCount,
|
|
75577
75575
|
estimatedInputTokens: estimatedCompactionRequestTokens,
|
|
75578
|
-
estimatedProgressPercent,
|
|
75579
75576
|
...windowUsagePercent === void 0 ? {} : { windowUsagePercent },
|
|
75580
75577
|
charsReceived,
|
|
75581
75578
|
attempt: attemptCount,
|
|
@@ -77685,12 +77682,29 @@ var init_session_loop = __esmMin((() => {
|
|
|
77685
77682
|
}
|
|
77686
77683
|
createLoop(input) {
|
|
77687
77684
|
if (process.env["BLUN_DISABLE_CRON"] === "1") throw new BlunError(ErrorCodes.LOOP_DISABLED, "Recurring loops are disabled");
|
|
77688
|
-
|
|
77689
|
-
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");
|
|
77690
77687
|
const parsed = parseLoopInterval(input.interval);
|
|
77691
77688
|
const prompt = input.prompt.trim();
|
|
77692
77689
|
if (prompt.length === 0) throw new BlunError(ErrorCodes.LOOP_PROMPT_EMPTY, "Loop prompt cannot be empty");
|
|
77693
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
|
+
}
|
|
77694
77708
|
const task = this.cron.addTask({
|
|
77695
77709
|
cron: parsed.cron,
|
|
77696
77710
|
prompt,
|
|
@@ -259752,6 +259766,12 @@ function blunSelectTurnTools(tools, maxContextTokens) {
|
|
|
259752
259766
|
const lean = tools.filter((tool) => BLUN_LEAN_TOOL_NAMES.has(tool.name) || BLUN_LEAN_KEEP_RE.test(tool.name));
|
|
259753
259767
|
return lean.length > 0 ? lean : tools;
|
|
259754
259768
|
}
|
|
259769
|
+
function blunToolSuppressionReason(turnNeedsTools, eligibleTools, selectedTools) {
|
|
259770
|
+
if (!turnNeedsTools) return "greeting_optimization";
|
|
259771
|
+
if (eligibleTools.length === 0) return "no_eligible_tools";
|
|
259772
|
+
if (selectedTools.length < eligibleTools.length) return "context_budget_lean_set";
|
|
259773
|
+
return "none";
|
|
259774
|
+
}
|
|
259755
259775
|
function isGoalOutcomeReminderOrigin(origin) {
|
|
259756
259776
|
return origin?.kind === "system_trigger" && (origin.name === "goal_completion" || origin.name === "goal_blocked");
|
|
259757
259777
|
}
|
|
@@ -260566,6 +260586,13 @@ var init_turn = __esmMin((() => {
|
|
|
260566
260586
|
try {
|
|
260567
260587
|
const eligibleTools = blunToolsForOrigin(this.agent.injection.filterPersonalMemoryToolsForTurn(turnId, input, origin, this.agent.tools.loopTools), origin);
|
|
260568
260588
|
const selectedTools = turnNeedsTools ? blunSelectTurnTools(eligibleTools, this.agent.config.modelCapabilities?.max_context_tokens) : [];
|
|
260589
|
+
const toolSuppressionReason = blunToolSuppressionReason(turnNeedsTools, eligibleTools, selectedTools);
|
|
260590
|
+
this.agent.log.info("turn request tools", {
|
|
260591
|
+
requestPurpose: "conversation",
|
|
260592
|
+
toolSuppressionReason,
|
|
260593
|
+
eligibleToolCount: eligibleTools.length,
|
|
260594
|
+
selectedToolCount: selectedTools.length
|
|
260595
|
+
});
|
|
260569
260596
|
return (await runTurn({
|
|
260570
260597
|
turnId: String(turnId),
|
|
260571
260598
|
signal,
|
|
@@ -261917,6 +261944,45 @@ function contentPartFor(mimeType, url) {
|
|
|
261917
261944
|
function errorMessage$10(error) {
|
|
261918
261945
|
return error instanceof Error ? error.message : String(error);
|
|
261919
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
|
+
}
|
|
261920
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;
|
|
261921
261987
|
var init_blun_media$1 = __esmMin((() => {
|
|
261922
261988
|
init_zod$1();
|
|
@@ -261968,16 +262034,22 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
261968
262034
|
};
|
|
261969
262035
|
}
|
|
261970
262036
|
async execution(args, ctx) {
|
|
262037
|
+
emitMediaProgress(ctx, this.name, "submitting");
|
|
261971
262038
|
try {
|
|
261972
262039
|
const job = await this.submit(args, {
|
|
261973
262040
|
signal: ctx.signal,
|
|
261974
262041
|
toolCallId: ctx.toolCallId
|
|
261975
262042
|
});
|
|
262043
|
+
emitMediaProgress(ctx, this.name, job.status, {
|
|
262044
|
+
id: job.id,
|
|
262045
|
+
...job.progress
|
|
262046
|
+
});
|
|
261976
262047
|
return {
|
|
261977
262048
|
output: `Media job ${job.id} accepted with status ${job.status}. ${this.requestNote}`,
|
|
261978
262049
|
isError: false
|
|
261979
262050
|
};
|
|
261980
262051
|
} catch (error) {
|
|
262052
|
+
emitMediaProgress(ctx, this.name, "failed", { error: errorMessage$10(error) });
|
|
261981
262053
|
return {
|
|
261982
262054
|
isError: true,
|
|
261983
262055
|
output: `Media request failed: ${errorMessage$10(error)}`
|
|
@@ -262054,6 +262126,7 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262054
262126
|
};
|
|
262055
262127
|
}
|
|
262056
262128
|
async execution(args, safePath, ctx) {
|
|
262129
|
+
emitMediaProgress(ctx, "UnderstandImage", "uploading");
|
|
262057
262130
|
try {
|
|
262058
262131
|
const fileType = detectFileType(safePath, await this.kaos.readBytes(safePath, 512), "media");
|
|
262059
262132
|
if (fileType.mimeType !== "image/png" && fileType.mimeType !== "image/jpeg") return {
|
|
@@ -262070,12 +262143,18 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262070
262143
|
toolCallId: ctx.toolCallId
|
|
262071
262144
|
};
|
|
262072
262145
|
const upload = await this.provider.uploadMedia(data, fileType.mimeType, options);
|
|
262146
|
+
emitMediaProgress(ctx, "UnderstandImage", "processing");
|
|
262073
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
|
+
});
|
|
262074
262152
|
return {
|
|
262075
262153
|
output: `Media job ${job.id} accepted with status ${job.status}. ${REQUEST_NOTE}`,
|
|
262076
262154
|
isError: false
|
|
262077
262155
|
};
|
|
262078
262156
|
} catch (error) {
|
|
262157
|
+
emitMediaProgress(ctx, "UnderstandImage", "failed", { error: errorMessage$10(error) });
|
|
262079
262158
|
return {
|
|
262080
262159
|
isError: true,
|
|
262081
262160
|
output: `Image understanding failed: ${errorMessage$10(error)}`
|
|
@@ -262137,6 +262216,7 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262137
262216
|
};
|
|
262138
262217
|
}
|
|
262139
262218
|
async execution(args, ctx) {
|
|
262219
|
+
emitMediaProgress(ctx, "GetMedia", "checking", { id: args.id });
|
|
262140
262220
|
try {
|
|
262141
262221
|
const result = await this.provider.getMedia(args.id, {
|
|
262142
262222
|
signal: ctx.signal,
|
|
@@ -262150,15 +262230,22 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262150
262230
|
].includes(result.status.trim().toLowerCase());
|
|
262151
262231
|
const source = result.sourceId === void 0 ? "" : ` Source job ${result.sourceId}${result.sourceStatus === void 0 ? "" : ` status: ${result.sourceStatus}`}.`;
|
|
262152
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
|
+
});
|
|
262153
262237
|
return {
|
|
262154
262238
|
output: `Media job ${result.id} status: ${result.status}.${source}${retryable}`,
|
|
262155
262239
|
isError: terminalError
|
|
262156
262240
|
};
|
|
262157
262241
|
}
|
|
262158
|
-
if (result.kind === "text")
|
|
262159
|
-
|
|
262160
|
-
|
|
262161
|
-
|
|
262242
|
+
if (result.kind === "text") {
|
|
262243
|
+
emitMediaProgress(ctx, "GetMedia", "complete", { id: result.id });
|
|
262244
|
+
return {
|
|
262245
|
+
output: result.text,
|
|
262246
|
+
isError: false
|
|
262247
|
+
};
|
|
262248
|
+
}
|
|
262162
262249
|
const url = `data:${result.mimeType};base64,${Buffer.from(result.data).toString("base64")}`;
|
|
262163
262250
|
const mediaPart = contentPartFor(result.mimeType, url);
|
|
262164
262251
|
if (mediaPart === void 0) return {
|
|
@@ -262171,6 +262258,11 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262171
262258
|
});
|
|
262172
262259
|
const localPath = join(this.outputDir, `${safeMediaId(result.id)}.${extensionForMediaType(result.mimeType)}`);
|
|
262173
262260
|
await writeFile(localPath, result.data, { mode: 384 });
|
|
262261
|
+
emitMediaProgress(ctx, "GetMedia", "complete", {
|
|
262262
|
+
id: result.id,
|
|
262263
|
+
mimeType: result.mimeType,
|
|
262264
|
+
localPath
|
|
262265
|
+
});
|
|
262174
262266
|
return {
|
|
262175
262267
|
output: [{
|
|
262176
262268
|
type: "text",
|
|
@@ -262179,6 +262271,10 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262179
262271
|
isError: false
|
|
262180
262272
|
};
|
|
262181
262273
|
} catch (error) {
|
|
262274
|
+
emitMediaProgress(ctx, "GetMedia", "failed", {
|
|
262275
|
+
id: args.id,
|
|
262276
|
+
error: errorMessage$10(error)
|
|
262277
|
+
});
|
|
262182
262278
|
return {
|
|
262183
262279
|
isError: true,
|
|
262184
262280
|
output: `Media lookup failed: ${errorMessage$10(error)}`
|
|
@@ -310705,13 +310801,47 @@ async function parseBlockedStatus(response, id) {
|
|
|
310705
310801
|
...typeof retryable === "boolean" ? { retryable } : {}
|
|
310706
310802
|
};
|
|
310707
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
|
+
}
|
|
310708
310837
|
function parseJob(payload) {
|
|
310709
310838
|
const id = payload["id"];
|
|
310710
310839
|
const status = payload["status"];
|
|
310711
310840
|
if (typeof id !== "string" || id.length === 0 || typeof status !== "string" || status.length === 0) throw new Error("Media request returned an invalid job response.");
|
|
310712
310841
|
return {
|
|
310713
310842
|
id,
|
|
310714
|
-
status
|
|
310843
|
+
status,
|
|
310844
|
+
progress: mediaProgressFromPayload(payload)
|
|
310715
310845
|
};
|
|
310716
310846
|
}
|
|
310717
310847
|
function parseStatus(payload, expectedId) {
|
|
@@ -310721,7 +310851,8 @@ function parseStatus(payload, expectedId) {
|
|
|
310721
310851
|
return {
|
|
310722
310852
|
kind: "status",
|
|
310723
310853
|
id,
|
|
310724
|
-
status
|
|
310854
|
+
status,
|
|
310855
|
+
progress: mediaProgressFromPayload(payload)
|
|
310725
310856
|
};
|
|
310726
310857
|
}
|
|
310727
310858
|
async function assertSuccess(response, operation) {
|
|
@@ -401433,6 +401564,16 @@ function slashCommandBusyReason(options) {
|
|
|
401433
401564
|
if (options.isStreaming) return "streaming";
|
|
401434
401565
|
if (options.isCompacting) return "compacting";
|
|
401435
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
|
+
}
|
|
401436
401577
|
function slashBusyMessage(commandName, reason) {
|
|
401437
401578
|
if (reason === "streaming") return uiText("resolve.busy.streaming", { command: commandName });
|
|
401438
401579
|
return uiText("resolve.busy.compacting", { command: commandName });
|
|
@@ -426133,27 +426274,7 @@ registerUiCatalogFragment({
|
|
|
426133
426274
|
}
|
|
426134
426275
|
});
|
|
426135
426276
|
const TICK_INTERVAL = 200;
|
|
426136
|
-
const COMPACTION_TOKENS_PER_SECOND = 4250;
|
|
426137
|
-
const MIN_ESTIMATED_DURATION_MS = 1e3;
|
|
426138
|
-
const ACTIVE_PERCENT_LIMIT = 97;
|
|
426139
426277
|
const BAR_WIDTH = 12;
|
|
426140
|
-
const LOAD_PHASE_SHARE = .72;
|
|
426141
|
-
const TAIL_PHASE_SHARE = .25;
|
|
426142
|
-
function estimateCompactionDurationMs(inputTokens) {
|
|
426143
|
-
if (inputTokens === void 0 || !Number.isFinite(inputTokens) || inputTokens <= 0) return;
|
|
426144
|
-
return Math.max(MIN_ESTIMATED_DURATION_MS, Math.round(inputTokens / COMPACTION_TOKENS_PER_SECOND * 1e3));
|
|
426145
|
-
}
|
|
426146
|
-
function estimateCompactionPercent(elapsedMs, inputTokens) {
|
|
426147
|
-
const durationMs = estimateCompactionDurationMs(inputTokens);
|
|
426148
|
-
if (durationMs === void 0) return 0;
|
|
426149
|
-
const safeElapsedMs = Math.max(0, elapsedMs);
|
|
426150
|
-
let estimate = Math.min(1, safeElapsedMs / durationMs) * LOAD_PHASE_SHARE;
|
|
426151
|
-
if (safeElapsedMs > durationMs) {
|
|
426152
|
-
const tailFraction = 1 - Math.exp(-(safeElapsedMs - durationMs) / durationMs);
|
|
426153
|
-
estimate += tailFraction * TAIL_PHASE_SHARE;
|
|
426154
|
-
}
|
|
426155
|
-
return Math.min(ACTIVE_PERCENT_LIMIT, Math.max(0, Math.round(estimate * 100)));
|
|
426156
|
-
}
|
|
426157
426278
|
var SingleLineText = class {
|
|
426158
426279
|
text;
|
|
426159
426280
|
constructor(text) {
|
|
@@ -426224,7 +426345,6 @@ var CompactionComponent = class extends Container {
|
|
|
426224
426345
|
stage = 1;
|
|
426225
426346
|
estimatedStageCount;
|
|
426226
426347
|
stageCount;
|
|
426227
|
-
estimatedProgressPercent;
|
|
426228
426348
|
windowUsagePercent;
|
|
426229
426349
|
constructor(ui, instruction, tip, showRunning = true) {
|
|
426230
426350
|
super();
|
|
@@ -426281,7 +426401,6 @@ var CompactionComponent = class extends Container {
|
|
|
426281
426401
|
this.attempt = progress.attempt;
|
|
426282
426402
|
this.stage = progress.stage ?? this.stage;
|
|
426283
426403
|
this.estimatedStageCount = progress.estimatedStageCount;
|
|
426284
|
-
this.estimatedProgressPercent = progress.estimatedProgressPercent;
|
|
426285
426404
|
this.windowUsagePercent = progress.windowUsagePercent;
|
|
426286
426405
|
this.statusText.setText(this.buildStatusLine());
|
|
426287
426406
|
if (this.showRunning) this.ui?.requestRender();
|
|
@@ -426303,21 +426422,16 @@ var CompactionComponent = class extends Container {
|
|
|
426303
426422
|
}
|
|
426304
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")}`)}`;
|
|
426305
426424
|
if (this.canceled) return `${currentTheme.fg("warning", STATUS_BULLET)}${currentTheme.boldFg("warning", uiText("compaction.canceled"))}`;
|
|
426306
|
-
const elapsedMs = Math.max(0, Date.now() - this.attemptStartedAtMs);
|
|
426307
|
-
const percent = this.estimatedProgressPercent ?? estimateCompactionPercent(elapsedMs, this.estimatedInputTokens);
|
|
426308
|
-
const filled = Math.round(percent / 100 * BAR_WIDTH);
|
|
426309
|
-
const bar = `[${"█".repeat(filled)}${"░".repeat(BAR_WIDTH - filled)}]`;
|
|
426310
426425
|
const stageText = formatCompactionStageText({
|
|
426311
426426
|
stage: this.stage,
|
|
426312
426427
|
estimatedStageCount: this.estimatedStageCount,
|
|
426313
|
-
estimatedProgressPercent: this.estimatedProgressPercent,
|
|
426314
426428
|
windowUsagePercent: this.windowUsagePercent,
|
|
426315
426429
|
estimatedInputTokens: this.estimatedInputTokens,
|
|
426316
426430
|
charsReceived: 0,
|
|
426317
426431
|
attempt: this.attempt
|
|
426318
426432
|
});
|
|
426319
426433
|
const runningText = `${formatCompactionRunningText(this.estimatedInputTokens)}${stageText.length === 0 ? "" : ` · ${stageText}`}`;
|
|
426320
|
-
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}`) : ""}`;
|
|
426321
426435
|
}
|
|
426322
426436
|
startTicking() {
|
|
426323
426437
|
this.timer = setInterval(() => {
|
|
@@ -427826,24 +427940,12 @@ var AgentSwarmProgressComponent = class {
|
|
|
427826
427940
|
if (snapshot.phase === "cancelled" && snapshot.ticks <= 0) return renderCancelledUnstartedCell(member, width, this.colors);
|
|
427827
427941
|
if (!layout.renderText) return this.renderCompactCell(member, snapshot, layout.barCells, nowMs);
|
|
427828
427942
|
if (snapshot.phase === "queued" && snapshot.ticks <= 0) return renderQueuedCell(member, width, this.colors);
|
|
427829
|
-
const
|
|
427830
|
-
memberKey: member.id,
|
|
427831
|
-
phase: snapshot.phase,
|
|
427832
|
-
capacityTicks: layout.barCells * PROGRESS_LEVELS.length,
|
|
427833
|
-
nowMs
|
|
427834
|
-
});
|
|
427835
|
-
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))} · `;
|
|
427836
427944
|
return prefix + renderCellLabel(member, snapshot, Math.max(1, width - visibleWidth(prefix)), this.colors);
|
|
427837
427945
|
}
|
|
427838
427946
|
renderCompactCell(member, snapshot, barCells, nowMs) {
|
|
427839
427947
|
const estimatePhase = snapshot.phase === "pending" ? "queued" : snapshot.phase;
|
|
427840
|
-
|
|
427841
|
-
memberKey: member.id,
|
|
427842
|
-
phase: estimatePhase,
|
|
427843
|
-
capacityTicks: barCells * PROGRESS_LEVELS.length,
|
|
427844
|
-
nowMs
|
|
427845
|
-
});
|
|
427846
|
-
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)}`;
|
|
427847
427949
|
}
|
|
427848
427950
|
findMemberForSubagent(agentId, swarmIndex) {
|
|
427849
427951
|
const existing = this.findMemberByAgentId(agentId);
|
|
@@ -497899,6 +498001,208 @@ var ActivityPaneComponent = class extends Container {
|
|
|
497899
498001
|
return lines;
|
|
497900
498002
|
}
|
|
497901
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
|
+
};
|
|
497902
498206
|
//#endregion
|
|
497903
498207
|
//#region src/tui/components/panes/queue-pane.copy.ts
|
|
497904
498208
|
registerUiCatalogFragment({
|
|
@@ -504425,6 +504729,10 @@ var SessionEventHandler = class {
|
|
|
504425
504729
|
streamingUI.scheduleFlush();
|
|
504426
504730
|
}
|
|
504427
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
|
+
}
|
|
504428
504736
|
const text = event.update.text;
|
|
504429
504737
|
if (text === void 0 || text.length === 0) return;
|
|
504430
504738
|
const tc = this.host.streamingUI.getToolComponent(event.toolCallId);
|
|
@@ -504446,6 +504754,10 @@ var SessionEventHandler = class {
|
|
|
504446
504754
|
synthetic: event.synthetic
|
|
504447
504755
|
};
|
|
504448
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
|
+
});
|
|
504449
504761
|
if (matchedCall?.name === "GetMedia" && event.isError !== true) this.host.runChannelMediaFallback(event.output);
|
|
504450
504762
|
this.subAgentEventHandler.handleAgentSwarmToolResult(event.toolCallId, resultData, event.isError === true);
|
|
504451
504763
|
if (matchedCall !== void 0 && matchedCall.name === "TodoList" && !event.isError) {
|
|
@@ -506811,24 +507123,21 @@ function formatContextStatus(usage, tokens, maxTokens, colors, width, now = /* @
|
|
|
506811
507123
|
return truncateToWidth(current, available, "…");
|
|
506812
507124
|
}
|
|
506813
507125
|
function formatCompactionStatus(elapsedMs, estimatedInputTokens, progress, colors, width, now = /* @__PURE__ */ new Date()) {
|
|
506814
|
-
const percent = progress?.estimatedProgressPercent ?? estimateCompactionPercent(elapsedMs, estimatedInputTokens);
|
|
506815
|
-
const filled = Math.max(1, Math.ceil((1 - percent / 100) * CONTEXT_BAR_WIDTH));
|
|
506816
|
-
const bar = chalk.hex(colors.primary)(`${"█".repeat(filled)}${"░".repeat(CONTEXT_BAR_WIDTH - filled)}`);
|
|
506817
507126
|
const label = formatCompactionRunningText(estimatedInputTokens);
|
|
506818
507127
|
const stageText = progress === void 0 ? "" : formatCompactionStageText(progress);
|
|
506819
507128
|
const compactStageText = progress?.stage === void 0 || progress.estimatedStageCount === void 0 ? "" : `${String(progress.stage)}/~${String(progress.estimatedStageCount)}${progress.windowUsagePercent === void 0 ? "" : ` · ${String(progress.windowUsagePercent)}%`}`;
|
|
506820
|
-
const
|
|
507129
|
+
const elapsed = `${String(Math.max(0, Math.round(elapsedMs / 1e3)))}s`;
|
|
506821
507130
|
const clock = chalk.hex(colors.textDim)(` · ${clockHhmm(now)}`);
|
|
506822
507131
|
const variants = [
|
|
506823
|
-
`${label}${stageText.length === 0 ? "" : ` · ${stageText}`}
|
|
507132
|
+
`${label}${stageText.length === 0 ? "" : ` · ${stageText}`} · ${elapsed}${clock}`,
|
|
506824
507133
|
`${label}${stageText.length === 0 ? "" : ` · ${stageText}`}`,
|
|
506825
507134
|
compactStageText,
|
|
506826
|
-
|
|
506827
|
-
stageText
|
|
507135
|
+
elapsed,
|
|
507136
|
+
stageText
|
|
506828
507137
|
];
|
|
506829
507138
|
const available = Math.max(0, width);
|
|
506830
507139
|
for (const variant of variants) if (visibleWidth(variant) <= available) return variant;
|
|
506831
|
-
return truncateToWidth(
|
|
507140
|
+
return truncateToWidth(elapsed, available, "…");
|
|
506832
507141
|
}
|
|
506833
507142
|
function contextMetrics(state) {
|
|
506834
507143
|
const tokens = Number.isFinite(state.contextTokens) ? Math.max(0, state.contextTokens) : 0;
|
|
@@ -512067,6 +512376,8 @@ var BlunTUI = class {
|
|
|
512067
512376
|
startupGoalPromptedSessionId;
|
|
512068
512377
|
lastActivityMode;
|
|
512069
512378
|
currentLoadingTip = void 0;
|
|
512379
|
+
mediaActivityStore = new MediaActivityStore();
|
|
512380
|
+
mediaActivityTickTimer;
|
|
512070
512381
|
lastHistoryContent;
|
|
512071
512382
|
shellOutputStreams = /* @__PURE__ */ new Map();
|
|
512072
512383
|
streamingUI;
|
|
@@ -512578,6 +512889,7 @@ var BlunTUI = class {
|
|
|
512578
512889
|
this.tasksBrowserController.close();
|
|
512579
512890
|
this.btwPanelController.clear();
|
|
512580
512891
|
this.stopActivitySpinner();
|
|
512892
|
+
this.stopMediaActivityTicking();
|
|
512581
512893
|
this.disposeEditorReplacement();
|
|
512582
512894
|
this.streamingUI.disposeActiveCompactionBlock();
|
|
512583
512895
|
this.streamingUI.resetToolUi();
|
|
@@ -512726,6 +513038,13 @@ var BlunTUI = class {
|
|
|
512726
513038
|
return;
|
|
512727
513039
|
}
|
|
512728
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
|
+
}
|
|
512729
513048
|
this.runSlashCommand(text);
|
|
512730
513049
|
return;
|
|
512731
513050
|
}
|
|
@@ -513733,6 +514052,8 @@ var BlunTUI = class {
|
|
|
513733
514052
|
this.setAppState({ mcpServersSummary: null });
|
|
513734
514053
|
this.streamingUI.setStep(0);
|
|
513735
514054
|
this.streamingUI.resetLiveText();
|
|
514055
|
+
this.mediaActivityStore.clear();
|
|
514056
|
+
this.stopMediaActivityTicking();
|
|
513736
514057
|
this.updateQueueDisplay();
|
|
513737
514058
|
}
|
|
513738
514059
|
async showResumeOtherWorkDirHint(session) {
|
|
@@ -514184,8 +514505,32 @@ var BlunTUI = class {
|
|
|
514184
514505
|
this.state.ui.requestRender();
|
|
514185
514506
|
return this.showLoginProgressSpinner(uiText("blunTui.login.waiting"));
|
|
514186
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
|
+
}
|
|
514187
514521
|
updateActivityPane() {
|
|
514188
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
|
+
}
|
|
514189
514534
|
const tipKind = loadingTipKind(effectiveMode);
|
|
514190
514535
|
if (effectiveMode === "idle" || effectiveMode === "session" || effectiveMode === "hidden") this.currentLoadingTip = void 0;
|
|
514191
514536
|
else if (tipKind !== void 0 && (this.currentLoadingTip === void 0 || this.currentLoadingTip.kind !== tipKind)) this.currentLoadingTip = {
|