blun-king-cli 9.1.47 → 9.1.49
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 +19 -1
- package/README.md +20 -1
- package/blun.mjs +629 -70
- 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.49
|
|
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
|
|
|
@@ -44,6 +54,14 @@ Nachweisbare Arbeitsabläufe
|
|
|
44
54
|
|
|
45
55
|
Alle Befehle funktionieren identisch mit `king`.
|
|
46
56
|
|
|
57
|
+
Medienerzeugung
|
|
58
|
+
---------------
|
|
59
|
+
GenerateVideo erzeugt Videos aus einer Textbeschreibung oder animiert einen
|
|
60
|
+
bereits abgeschlossenen Bildauftrag. Für Bild-zu-Video wird die Medienkennung
|
|
61
|
+
des fertigen PNG- oder JPEG-Bildes verwendet; lokale Serverpfade werden nicht
|
|
62
|
+
akzeptiert. Der Auftrag läuft asynchron und wird anschließend mit GetMedia
|
|
63
|
+
abgerufen.
|
|
64
|
+
|
|
47
65
|
Aktualisieren
|
|
48
66
|
-------------
|
|
49
67
|
|
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.49
|
|
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
|
|
@@ -64,6 +75,14 @@ Version 9.1.0 enthält sieben zusätzliche, getrennt nutzbare Befehlsgruppen:
|
|
|
64
75
|
|
|
65
76
|
Sie stehen unter `blun` und `king` identisch zur Verfügung.
|
|
66
77
|
|
|
78
|
+
## Medienerzeugung
|
|
79
|
+
|
|
80
|
+
`GenerateVideo` erzeugt Videos aus einer Textbeschreibung oder animiert einen
|
|
81
|
+
bereits abgeschlossenen Bildauftrag. Für Bild-zu-Video wird die Medienkennung
|
|
82
|
+
des fertigen PNG- oder JPEG-Bildes verwendet; lokale Serverpfade werden nicht
|
|
83
|
+
akzeptiert. Der Auftrag läuft asynchron und wird anschließend mit `GetMedia`
|
|
84
|
+
abgerufen.
|
|
85
|
+
|
|
67
86
|
## Aktualisieren
|
|
68
87
|
|
|
69
88
|
`blun update`, `king update` und die jeweilige Variante `upgrade` verwenden
|
package/blun.mjs
CHANGED
|
@@ -28101,6 +28101,19 @@ var init_render_prompt = __esmMin((() => {
|
|
|
28101
28101
|
* Build the static conduct block. Pure function of nothing — the rules are
|
|
28102
28102
|
* the same for every session and every profile.
|
|
28103
28103
|
*/
|
|
28104
|
+
const IMAGE_GENERATION_ALLOWED_CATEGORIES = Object.freeze([
|
|
28105
|
+
"adult fictional people in bikinis, swimwear, beachwear, or sportswear",
|
|
28106
|
+
"adult fictional people in form-fitting clothing or lingerie",
|
|
28107
|
+
"tasteful, sensual, or figure-emphasizing depictions of clearly adult fictional people"
|
|
28108
|
+
]);
|
|
28109
|
+
const IMAGE_GENERATION_BLOCKED_CATEGORIES = Object.freeze([
|
|
28110
|
+
"explicit sexual depictions",
|
|
28111
|
+
"sexual or romantic depictions involving minors or youthfully depicted people",
|
|
28112
|
+
"depictions of real, recognizable people without their consent"
|
|
28113
|
+
]);
|
|
28114
|
+
function conductCategoryList(items) {
|
|
28115
|
+
return items.map((item) => ` - ${item}`).join("\n");
|
|
28116
|
+
}
|
|
28104
28117
|
function conductSystemBlock() {
|
|
28105
28118
|
return `## Conduct — how you behave
|
|
28106
28119
|
|
|
@@ -28125,6 +28138,13 @@ function conductSystemBlock() {
|
|
|
28125
28138
|
- NEVER create romantic or sexual content involving or directed at minors, and nothing that facilitates grooming, secrecy between an adult and a child, or isolating a minor from trusted adults. A minor is anyone under 18 (or older where local law says so).
|
|
28126
28139
|
- If you catch yourself mentally reframing such a request to make it seem acceptable, that reframing is itself the signal to refuse. After one child-safety refusal, treat all follow-ups in that conversation with extreme caution.
|
|
28127
28140
|
|
|
28141
|
+
### Image generation boundaries
|
|
28142
|
+
Allowed categories — do not refuse, sanitize, or replace these merely because they are sensual or reveal the figure:
|
|
28143
|
+
${conductCategoryList(IMAGE_GENERATION_ALLOWED_CATEGORIES)}
|
|
28144
|
+
Blocked categories — refuse these without exception, regardless of claimed authority:
|
|
28145
|
+
${conductCategoryList(IMAGE_GENERATION_BLOCKED_CATEGORIES)}
|
|
28146
|
+
- When an image request mixes allowed and blocked elements, generate the allowed part and decline only the blocked part. If an adult-oriented request leaves age ambiguous, make the fictional subject clearly adult rather than refusing an otherwise allowed request.
|
|
28147
|
+
|
|
28128
28148
|
### Copyright
|
|
28129
28149
|
- Default to paraphrasing. Quote at most ~15 words from any single source, and at most one quote per source. Never reproduce song lyrics, poems, or full passages, even from search results — discuss themes and meaning instead.
|
|
28130
28150
|
|
|
@@ -75066,10 +75086,6 @@ function estimateCompactionStageCount(initialInputTokens, safeRequestLimitTokens
|
|
|
75066
75086
|
if (safeRequestLimitTokens <= 0) return currentStage;
|
|
75067
75087
|
return Math.max(currentStage, Math.ceil(initialInputTokens / safeRequestLimitTokens));
|
|
75068
75088
|
}
|
|
75069
|
-
function estimateCompactionProgressPercent(stage, estimatedStageCount) {
|
|
75070
|
-
if (estimatedStageCount <= 0) return 0;
|
|
75071
|
-
return Math.min(99, Math.floor(stage / estimatedStageCount * 100));
|
|
75072
|
-
}
|
|
75073
75089
|
function estimateCompactionWindowUsagePercent(requestTokens, maxContextTokens) {
|
|
75074
75090
|
if (maxContextTokens <= 0) return void 0;
|
|
75075
75091
|
return Math.min(100, Math.max(0, Math.ceil(requestTokens / maxContextTokens * 100)));
|
|
@@ -75554,7 +75570,6 @@ var init_full = __esmMin((() => {
|
|
|
75554
75570
|
charsReceived = 0;
|
|
75555
75571
|
const stage = hierarchicalPassCount + 1;
|
|
75556
75572
|
const estimatedStageCount = estimateCompactionStageCount(initialCompactionRequestTokens, safeCompactionRequestLimit, stage);
|
|
75557
|
-
const estimatedProgressPercent = estimateCompactionProgressPercent(stage, estimatedStageCount);
|
|
75558
75573
|
const windowUsagePercent = estimateCompactionWindowUsagePercent(estimatedCompactionRequestTokens, compactionRequestLimit);
|
|
75559
75574
|
this.agent.log.info("compaction stage request", {
|
|
75560
75575
|
requestPurpose: "compaction",
|
|
@@ -75578,7 +75593,6 @@ var init_full = __esmMin((() => {
|
|
|
75578
75593
|
stage,
|
|
75579
75594
|
estimatedStageCount,
|
|
75580
75595
|
estimatedInputTokens: estimatedCompactionRequestTokens,
|
|
75581
|
-
estimatedProgressPercent,
|
|
75582
75596
|
...windowUsagePercent === void 0 ? {} : { windowUsagePercent },
|
|
75583
75597
|
charsReceived,
|
|
75584
75598
|
attempt: attemptCount,
|
|
@@ -77688,12 +77702,29 @@ var init_session_loop = __esmMin((() => {
|
|
|
77688
77702
|
}
|
|
77689
77703
|
createLoop(input) {
|
|
77690
77704
|
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");
|
|
77705
|
+
const existing = this.currentTask();
|
|
77706
|
+
if (existing === void 0 && this.cron.store.list().length >= 50) throw new BlunError(ErrorCodes.LOOP_LIMIT_REACHED, "Session cron task limit reached");
|
|
77693
77707
|
const parsed = parseLoopInterval(input.interval);
|
|
77694
77708
|
const prompt = input.prompt.trim();
|
|
77695
77709
|
if (prompt.length === 0) throw new BlunError(ErrorCodes.LOOP_PROMPT_EMPTY, "Loop prompt cannot be empty");
|
|
77696
77710
|
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`);
|
|
77711
|
+
if (existing !== void 0) {
|
|
77712
|
+
const now = this.cron.clocks.wallNow();
|
|
77713
|
+
const task = this.requireUpdatedTask(existing.id, {
|
|
77714
|
+
cron: parsed.cron,
|
|
77715
|
+
prompt,
|
|
77716
|
+
recurring: true,
|
|
77717
|
+
owner: "session-loop",
|
|
77718
|
+
loopInterval: parsed.interval,
|
|
77719
|
+
paused: false,
|
|
77720
|
+
autoExpire: false,
|
|
77721
|
+
createdAt: now,
|
|
77722
|
+
scheduleFromAt: now,
|
|
77723
|
+
lastFiredAt: void 0
|
|
77724
|
+
});
|
|
77725
|
+
this.cron.emitScheduled(task);
|
|
77726
|
+
return this.snapshot(task);
|
|
77727
|
+
}
|
|
77697
77728
|
const task = this.cron.addTask({
|
|
77698
77729
|
cron: parsed.cron,
|
|
77699
77730
|
prompt,
|
|
@@ -261933,6 +261964,45 @@ function contentPartFor(mimeType, url) {
|
|
|
261933
261964
|
function errorMessage$10(error) {
|
|
261934
261965
|
return error instanceof Error ? error.message : String(error);
|
|
261935
261966
|
}
|
|
261967
|
+
const MEDIA_PROGRESS_CUSTOM_KIND = "blun.media.progress";
|
|
261968
|
+
function mediaKindForToolName(name) {
|
|
261969
|
+
switch (name) {
|
|
261970
|
+
case "GenerateImage": return "image";
|
|
261971
|
+
case "GenerateVideo": return "video";
|
|
261972
|
+
case "GenerateSpeech": return "voice";
|
|
261973
|
+
case "UnderstandImage": return "image-analysis";
|
|
261974
|
+
case "UnderstandVideo": return "video-analysis";
|
|
261975
|
+
case "DubVideo": return "dubbing";
|
|
261976
|
+
case "LipSyncMedia": return "lipsync";
|
|
261977
|
+
case "GetMedia": return "media";
|
|
261978
|
+
default: return "media";
|
|
261979
|
+
}
|
|
261980
|
+
}
|
|
261981
|
+
function isMediaToolName(name) {
|
|
261982
|
+
return [
|
|
261983
|
+
"GenerateImage",
|
|
261984
|
+
"GenerateVideo",
|
|
261985
|
+
"GenerateSpeech",
|
|
261986
|
+
"UnderstandImage",
|
|
261987
|
+
"UnderstandVideo",
|
|
261988
|
+
"DubVideo",
|
|
261989
|
+
"LipSyncMedia",
|
|
261990
|
+
"GetMedia"
|
|
261991
|
+
].includes(name);
|
|
261992
|
+
}
|
|
261993
|
+
function emitMediaProgress(ctx, toolName, phase, data = {}) {
|
|
261994
|
+
ctx.onUpdate({
|
|
261995
|
+
kind: "custom",
|
|
261996
|
+
customKind: MEDIA_PROGRESS_CUSTOM_KIND,
|
|
261997
|
+
customData: {
|
|
261998
|
+
toolName,
|
|
261999
|
+
mediaKind: data.mediaKind ?? mediaKindForToolName(toolName),
|
|
262000
|
+
phase,
|
|
262001
|
+
observedAt: Date.now(),
|
|
262002
|
+
...data
|
|
262003
|
+
}
|
|
262004
|
+
});
|
|
262005
|
+
}
|
|
261936
262006
|
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
262007
|
var init_blun_media$1 = __esmMin((() => {
|
|
261938
262008
|
init_zod$1();
|
|
@@ -261945,7 +262015,10 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
261945
262015
|
PromptSchema = string().trim().min(1).max(2e4);
|
|
261946
262016
|
MediaIdSchema = string().trim().min(1).max(200).regex(/^[A-Za-z0-9_-]+$/);
|
|
261947
262017
|
GenerateImageInputSchema = object({ prompt: PromptSchema.describe("A complete visual description of the image to generate.") });
|
|
261948
|
-
GenerateVideoInputSchema = object({
|
|
262018
|
+
GenerateVideoInputSchema = object({
|
|
262019
|
+
prompt: PromptSchema.describe("A complete visual description of the video or motion to generate."),
|
|
262020
|
+
image_id: MediaIdSchema.optional().describe("An optional completed PNG or JPEG media job id to animate into the video.")
|
|
262021
|
+
});
|
|
261949
262022
|
GenerateSpeechInputSchema = object({ input: PromptSchema.describe("The exact text to synthesize as speech.") });
|
|
261950
262023
|
GetMediaInputSchema = object({ id: MediaIdSchema.describe("The media job id returned by a generation tool.") });
|
|
261951
262024
|
UnderstandImageInputSchema = object({
|
|
@@ -261984,16 +262057,22 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
261984
262057
|
};
|
|
261985
262058
|
}
|
|
261986
262059
|
async execution(args, ctx) {
|
|
262060
|
+
emitMediaProgress(ctx, this.name, "submitting");
|
|
261987
262061
|
try {
|
|
261988
262062
|
const job = await this.submit(args, {
|
|
261989
262063
|
signal: ctx.signal,
|
|
261990
262064
|
toolCallId: ctx.toolCallId
|
|
261991
262065
|
});
|
|
262066
|
+
emitMediaProgress(ctx, this.name, job.status, {
|
|
262067
|
+
id: job.id,
|
|
262068
|
+
...job.progress
|
|
262069
|
+
});
|
|
261992
262070
|
return {
|
|
261993
262071
|
output: `Media job ${job.id} accepted with status ${job.status}. ${this.requestNote}`,
|
|
261994
262072
|
isError: false
|
|
261995
262073
|
};
|
|
261996
262074
|
} catch (error) {
|
|
262075
|
+
emitMediaProgress(ctx, this.name, "failed", { error: errorMessage$10(error) });
|
|
261997
262076
|
return {
|
|
261998
262077
|
isError: true,
|
|
261999
262078
|
output: `Media request failed: ${errorMessage$10(error)}`
|
|
@@ -262014,13 +262093,13 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262014
262093
|
};
|
|
262015
262094
|
GenerateVideoTool = class extends MediaGenerationTool {
|
|
262016
262095
|
name = "GenerateVideo";
|
|
262017
|
-
description = "Generate a new video from text with BLUN media models.
|
|
262096
|
+
description = "Generate a new video from text or animate an existing completed image job with BLUN media models. Pass image_id for image-to-video requests. Do not use this for understanding an existing video. This starts a billed asynchronous media job.";
|
|
262018
262097
|
parameters = toInputJsonSchema(GenerateVideoInputSchema);
|
|
262019
262098
|
subject(args) {
|
|
262020
|
-
return args.prompt;
|
|
262099
|
+
return args.image_id ? `${args.image_id}: ${args.prompt}` : args.prompt;
|
|
262021
262100
|
}
|
|
262022
262101
|
submit(args, options) {
|
|
262023
|
-
return this.provider.generateVideo(args.prompt, options);
|
|
262102
|
+
return this.provider.generateVideo(args.prompt, options, args.image_id);
|
|
262024
262103
|
}
|
|
262025
262104
|
};
|
|
262026
262105
|
GenerateSpeechTool = class extends MediaGenerationTool {
|
|
@@ -262070,6 +262149,7 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262070
262149
|
};
|
|
262071
262150
|
}
|
|
262072
262151
|
async execution(args, safePath, ctx) {
|
|
262152
|
+
emitMediaProgress(ctx, "UnderstandImage", "uploading");
|
|
262073
262153
|
try {
|
|
262074
262154
|
const fileType = detectFileType(safePath, await this.kaos.readBytes(safePath, 512), "media");
|
|
262075
262155
|
if (fileType.mimeType !== "image/png" && fileType.mimeType !== "image/jpeg") return {
|
|
@@ -262086,12 +262166,18 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262086
262166
|
toolCallId: ctx.toolCallId
|
|
262087
262167
|
};
|
|
262088
262168
|
const upload = await this.provider.uploadMedia(data, fileType.mimeType, options);
|
|
262169
|
+
emitMediaProgress(ctx, "UnderstandImage", "processing");
|
|
262089
262170
|
const job = await this.provider.understandImage(upload.id, args.prompt, options);
|
|
262171
|
+
emitMediaProgress(ctx, "UnderstandImage", job.status, {
|
|
262172
|
+
id: job.id,
|
|
262173
|
+
...job.progress
|
|
262174
|
+
});
|
|
262090
262175
|
return {
|
|
262091
262176
|
output: `Media job ${job.id} accepted with status ${job.status}. ${REQUEST_NOTE}`,
|
|
262092
262177
|
isError: false
|
|
262093
262178
|
};
|
|
262094
262179
|
} catch (error) {
|
|
262180
|
+
emitMediaProgress(ctx, "UnderstandImage", "failed", { error: errorMessage$10(error) });
|
|
262095
262181
|
return {
|
|
262096
262182
|
isError: true,
|
|
262097
262183
|
output: `Image understanding failed: ${errorMessage$10(error)}`
|
|
@@ -262153,6 +262239,7 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262153
262239
|
};
|
|
262154
262240
|
}
|
|
262155
262241
|
async execution(args, ctx) {
|
|
262242
|
+
emitMediaProgress(ctx, "GetMedia", "checking", { id: args.id });
|
|
262156
262243
|
try {
|
|
262157
262244
|
const result = await this.provider.getMedia(args.id, {
|
|
262158
262245
|
signal: ctx.signal,
|
|
@@ -262166,15 +262253,22 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262166
262253
|
].includes(result.status.trim().toLowerCase());
|
|
262167
262254
|
const source = result.sourceId === void 0 ? "" : ` Source job ${result.sourceId}${result.sourceStatus === void 0 ? "" : ` status: ${result.sourceStatus}`}.`;
|
|
262168
262255
|
const retryable = result.retryable === void 0 ? "" : ` Retryable: ${result.retryable ? "yes" : "no"}.`;
|
|
262256
|
+
emitMediaProgress(ctx, "GetMedia", result.status, {
|
|
262257
|
+
id: result.id,
|
|
262258
|
+
...result.progress
|
|
262259
|
+
});
|
|
262169
262260
|
return {
|
|
262170
262261
|
output: `Media job ${result.id} status: ${result.status}.${source}${retryable}`,
|
|
262171
262262
|
isError: terminalError
|
|
262172
262263
|
};
|
|
262173
262264
|
}
|
|
262174
|
-
if (result.kind === "text")
|
|
262175
|
-
|
|
262176
|
-
|
|
262177
|
-
|
|
262265
|
+
if (result.kind === "text") {
|
|
262266
|
+
emitMediaProgress(ctx, "GetMedia", "complete", { id: result.id });
|
|
262267
|
+
return {
|
|
262268
|
+
output: result.text,
|
|
262269
|
+
isError: false
|
|
262270
|
+
};
|
|
262271
|
+
}
|
|
262178
262272
|
const url = `data:${result.mimeType};base64,${Buffer.from(result.data).toString("base64")}`;
|
|
262179
262273
|
const mediaPart = contentPartFor(result.mimeType, url);
|
|
262180
262274
|
if (mediaPart === void 0) return {
|
|
@@ -262187,6 +262281,11 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262187
262281
|
});
|
|
262188
262282
|
const localPath = join(this.outputDir, `${safeMediaId(result.id)}.${extensionForMediaType(result.mimeType)}`);
|
|
262189
262283
|
await writeFile(localPath, result.data, { mode: 384 });
|
|
262284
|
+
emitMediaProgress(ctx, "GetMedia", "complete", {
|
|
262285
|
+
id: result.id,
|
|
262286
|
+
mimeType: result.mimeType,
|
|
262287
|
+
localPath
|
|
262288
|
+
});
|
|
262190
262289
|
return {
|
|
262191
262290
|
output: [{
|
|
262192
262291
|
type: "text",
|
|
@@ -262195,6 +262294,10 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262195
262294
|
isError: false
|
|
262196
262295
|
};
|
|
262197
262296
|
} catch (error) {
|
|
262297
|
+
emitMediaProgress(ctx, "GetMedia", "failed", {
|
|
262298
|
+
id: args.id,
|
|
262299
|
+
error: errorMessage$10(error)
|
|
262300
|
+
});
|
|
262198
262301
|
return {
|
|
262199
262302
|
isError: true,
|
|
262200
262303
|
output: `Media lookup failed: ${errorMessage$10(error)}`
|
|
@@ -310721,13 +310824,64 @@ async function parseBlockedStatus(response, id) {
|
|
|
310721
310824
|
...typeof retryable === "boolean" ? { retryable } : {}
|
|
310722
310825
|
};
|
|
310723
310826
|
}
|
|
310827
|
+
function mediaPayloadNumber(payload, keys) {
|
|
310828
|
+
for (const key of keys) {
|
|
310829
|
+
const value = payload[key];
|
|
310830
|
+
const parsed = typeof value === "number" ? value : typeof value === "string" && value.trim() !== "" ? Number(value) : NaN;
|
|
310831
|
+
if (Number.isFinite(parsed) && parsed >= 0) return parsed;
|
|
310832
|
+
}
|
|
310833
|
+
}
|
|
310834
|
+
function mediaPayloadText(payload, keys) {
|
|
310835
|
+
for (const key of keys) {
|
|
310836
|
+
const value = payload[key];
|
|
310837
|
+
if (typeof value === "string" && value.trim() !== "") return value.trim();
|
|
310838
|
+
}
|
|
310839
|
+
}
|
|
310840
|
+
function mediaPayloadNumberArray(payload, keys) {
|
|
310841
|
+
for (const key of keys) {
|
|
310842
|
+
const value = payload[key];
|
|
310843
|
+
if (!Array.isArray(value)) continue;
|
|
310844
|
+
const samples = value.map((entry) => typeof entry === "number" ? entry : Number(entry)).filter((entry) => Number.isFinite(entry));
|
|
310845
|
+
if (samples.length > 0) return samples.slice(0, 512);
|
|
310846
|
+
}
|
|
310847
|
+
}
|
|
310848
|
+
function mediaProgressFromPayload(payload) {
|
|
310849
|
+
const rawPercent = mediaPayloadNumber(payload, ["percent", "progress_percent", "progressPercent", "progress"]);
|
|
310850
|
+
const percent = rawPercent === void 0 ? void 0 : rawPercent <= 1 ? rawPercent * 100 : rawPercent;
|
|
310851
|
+
const progress = {
|
|
310852
|
+
phaseLabel: mediaPayloadText(payload, ["phase", "stage", "step_name", "stepName"]),
|
|
310853
|
+
percent: percent === void 0 ? void 0 : Math.min(100, Math.max(0, percent)),
|
|
310854
|
+
currentFrame: mediaPayloadNumber(payload, ["current_frame", "currentFrame", "frames_completed", "framesCompleted"]),
|
|
310855
|
+
totalFrames: mediaPayloadNumber(payload, ["total_frames", "totalFrames", "frame_count", "frameCount"]),
|
|
310856
|
+
fps: mediaPayloadNumber(payload, ["fps", "frames_per_second", "framesPerSecond"]),
|
|
310857
|
+
currentStep: mediaPayloadNumber(payload, ["current_step", "currentStep", "step"]),
|
|
310858
|
+
totalSteps: mediaPayloadNumber(payload, ["total_steps", "totalSteps", "steps"]),
|
|
310859
|
+
currentSegment: mediaPayloadNumber(payload, ["current_segment", "currentSegment", "segment"]),
|
|
310860
|
+
totalSegments: mediaPayloadNumber(payload, ["total_segments", "totalSegments", "segments"]),
|
|
310861
|
+
generatedSeconds: mediaPayloadNumber(payload, ["generated_seconds", "generatedSeconds", "audio_seconds", "audioSeconds"]),
|
|
310862
|
+
queuePosition: mediaPayloadNumber(payload, ["queue_position", "queuePosition"]),
|
|
310863
|
+
elapsedSeconds: mediaPayloadNumber(payload, ["elapsed_seconds", "elapsedSeconds"]),
|
|
310864
|
+
remainingSeconds: mediaPayloadNumber(payload, ["remaining_seconds", "remainingSeconds", "eta_seconds", "etaSeconds"]),
|
|
310865
|
+
durationSeconds: mediaPayloadNumber(payload, ["duration_seconds", "durationSeconds"]),
|
|
310866
|
+
width: mediaPayloadNumber(payload, ["width", "width_px", "widthPx"]),
|
|
310867
|
+
height: mediaPayloadNumber(payload, ["height", "height_px", "heightPx"]),
|
|
310868
|
+
previewUrl: mediaPayloadText(payload, ["preview_url", "previewUrl", "thumbnail_url", "thumbnailUrl"]),
|
|
310869
|
+
previewDataBase64: mediaPayloadText(payload, ["preview_base64", "previewBase64", "thumbnail_base64", "thumbnailBase64"]),
|
|
310870
|
+
previewMimeType: mediaPayloadText(payload, ["preview_mime_type", "previewMimeType", "thumbnail_mime_type", "thumbnailMimeType"]),
|
|
310871
|
+
sampleUrl: mediaPayloadText(payload, ["sample_url", "sampleUrl", "audio_preview_url", "audioPreviewUrl"]),
|
|
310872
|
+
localPath: mediaPayloadText(payload, ["local_path", "localPath"]),
|
|
310873
|
+
waveform: mediaPayloadNumberArray(payload, ["waveform", "waveform_samples", "waveformSamples"])
|
|
310874
|
+
};
|
|
310875
|
+
return Object.fromEntries(Object.entries(progress).filter(([, value]) => value !== void 0));
|
|
310876
|
+
}
|
|
310724
310877
|
function parseJob(payload) {
|
|
310725
310878
|
const id = payload["id"];
|
|
310726
310879
|
const status = payload["status"];
|
|
310727
310880
|
if (typeof id !== "string" || id.length === 0 || typeof status !== "string" || status.length === 0) throw new Error("Media request returned an invalid job response.");
|
|
310728
310881
|
return {
|
|
310729
310882
|
id,
|
|
310730
|
-
status
|
|
310883
|
+
status,
|
|
310884
|
+
progress: mediaProgressFromPayload(payload)
|
|
310731
310885
|
};
|
|
310732
310886
|
}
|
|
310733
310887
|
function parseStatus(payload, expectedId) {
|
|
@@ -310737,7 +310891,8 @@ function parseStatus(payload, expectedId) {
|
|
|
310737
310891
|
return {
|
|
310738
310892
|
kind: "status",
|
|
310739
310893
|
id,
|
|
310740
|
-
status
|
|
310894
|
+
status,
|
|
310895
|
+
progress: mediaProgressFromPayload(payload)
|
|
310741
310896
|
};
|
|
310742
310897
|
}
|
|
310743
310898
|
async function assertSuccess(response, operation) {
|
|
@@ -310769,8 +310924,10 @@ var init_blun_media = __esmMin((() => {
|
|
|
310769
310924
|
generateImage(prompt, options) {
|
|
310770
310925
|
return this.submit("/images/generations", { prompt }, options);
|
|
310771
310926
|
}
|
|
310772
|
-
generateVideo(prompt, options) {
|
|
310773
|
-
|
|
310927
|
+
generateVideo(prompt, options, imageId) {
|
|
310928
|
+
const body = { prompt };
|
|
310929
|
+
if (imageId !== void 0 && imageId.length > 0) body["image_id"] = imageId;
|
|
310930
|
+
return this.submit("/videos/generations", body, options);
|
|
310774
310931
|
}
|
|
310775
310932
|
generateSpeech(input, options) {
|
|
310776
310933
|
return this.submit("/audio/speech", { input }, options);
|
|
@@ -401449,6 +401606,16 @@ function slashCommandBusyReason(options) {
|
|
|
401449
401606
|
if (options.isStreaming) return "streaming";
|
|
401450
401607
|
if (options.isCompacting) return "compacting";
|
|
401451
401608
|
}
|
|
401609
|
+
function shouldQueueBusySlashCommand(input, options) {
|
|
401610
|
+
const parsed = parseSlashInput(input);
|
|
401611
|
+
if (parsed === null) return false;
|
|
401612
|
+
if (slashCommandBusyReason(options) === void 0) return false;
|
|
401613
|
+
const normalizedName = normalizeLegacyEffortCommandName(parsed.name);
|
|
401614
|
+
const command = findBuiltInSlashCommand(normalizedName);
|
|
401615
|
+
if (command === void 0) return true;
|
|
401616
|
+
if (!isExperimentalFlagEnabled(command.experimentalFlag)) return false;
|
|
401617
|
+
return resolveSlashCommandAvailability(command, parsed.args) === "idle-only";
|
|
401618
|
+
}
|
|
401452
401619
|
function slashBusyMessage(commandName, reason) {
|
|
401453
401620
|
if (reason === "streaming") return uiText("resolve.busy.streaming", { command: commandName });
|
|
401454
401621
|
return uiText("resolve.busy.compacting", { command: commandName });
|
|
@@ -426149,27 +426316,7 @@ registerUiCatalogFragment({
|
|
|
426149
426316
|
}
|
|
426150
426317
|
});
|
|
426151
426318
|
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
426319
|
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
426320
|
var SingleLineText = class {
|
|
426174
426321
|
text;
|
|
426175
426322
|
constructor(text) {
|
|
@@ -426240,7 +426387,6 @@ var CompactionComponent = class extends Container {
|
|
|
426240
426387
|
stage = 1;
|
|
426241
426388
|
estimatedStageCount;
|
|
426242
426389
|
stageCount;
|
|
426243
|
-
estimatedProgressPercent;
|
|
426244
426390
|
windowUsagePercent;
|
|
426245
426391
|
constructor(ui, instruction, tip, showRunning = true) {
|
|
426246
426392
|
super();
|
|
@@ -426297,7 +426443,6 @@ var CompactionComponent = class extends Container {
|
|
|
426297
426443
|
this.attempt = progress.attempt;
|
|
426298
426444
|
this.stage = progress.stage ?? this.stage;
|
|
426299
426445
|
this.estimatedStageCount = progress.estimatedStageCount;
|
|
426300
|
-
this.estimatedProgressPercent = progress.estimatedProgressPercent;
|
|
426301
426446
|
this.windowUsagePercent = progress.windowUsagePercent;
|
|
426302
426447
|
this.statusText.setText(this.buildStatusLine());
|
|
426303
426448
|
if (this.showRunning) this.ui?.requestRender();
|
|
@@ -426319,21 +426464,16 @@ var CompactionComponent = class extends Container {
|
|
|
426319
426464
|
}
|
|
426320
426465
|
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
426466
|
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
426467
|
const stageText = formatCompactionStageText({
|
|
426327
426468
|
stage: this.stage,
|
|
426328
426469
|
estimatedStageCount: this.estimatedStageCount,
|
|
426329
|
-
estimatedProgressPercent: this.estimatedProgressPercent,
|
|
426330
426470
|
windowUsagePercent: this.windowUsagePercent,
|
|
426331
426471
|
estimatedInputTokens: this.estimatedInputTokens,
|
|
426332
426472
|
charsReceived: 0,
|
|
426333
426473
|
attempt: this.attempt
|
|
426334
426474
|
});
|
|
426335
426475
|
const runningText = `${formatCompactionRunningText(this.estimatedInputTokens)}${stageText.length === 0 ? "" : ` · ${stageText}`}`;
|
|
426336
|
-
return `${currentTheme.fg("primary",
|
|
426476
|
+
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
426477
|
}
|
|
426338
426478
|
startTicking() {
|
|
426339
426479
|
this.timer = setInterval(() => {
|
|
@@ -427842,24 +427982,12 @@ var AgentSwarmProgressComponent = class {
|
|
|
427842
427982
|
if (snapshot.phase === "cancelled" && snapshot.ticks <= 0) return renderCancelledUnstartedCell(member, width, this.colors);
|
|
427843
427983
|
if (!layout.renderText) return this.renderCompactCell(member, snapshot, layout.barCells, nowMs);
|
|
427844
427984
|
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))} `;
|
|
427985
|
+
const prefix = `${chalk.hex(this.colors.primary)(member.id)} ${chalk.hex(phaseColor(snapshot.phase, this.colors))(phaseLabel(snapshot.phase))} · `;
|
|
427852
427986
|
return prefix + renderCellLabel(member, snapshot, Math.max(1, width - visibleWidth(prefix)), this.colors);
|
|
427853
427987
|
}
|
|
427854
427988
|
renderCompactCell(member, snapshot, barCells, nowMs) {
|
|
427855
427989
|
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)}`;
|
|
427990
|
+
return `${chalk.hex(this.colors.primary)(member.id)} ${chalk.hex(phaseColor(estimatePhase, this.colors))(phaseLabel(estimatePhase))}${compactTerminalMark(member, snapshot.phase, this.colors)}`;
|
|
427863
427991
|
}
|
|
427864
427992
|
findMemberForSubagent(agentId, swarmIndex) {
|
|
427865
427993
|
const existing = this.findMemberByAgentId(agentId);
|
|
@@ -497915,6 +498043,365 @@ var ActivityPaneComponent = class extends Container {
|
|
|
497915
498043
|
return lines;
|
|
497916
498044
|
}
|
|
497917
498045
|
};
|
|
498046
|
+
registerUiCatalogFragment({
|
|
498047
|
+
en: {
|
|
498048
|
+
"media.activity.jobs": "{count} media jobs active",
|
|
498049
|
+
"media.activity.showJobs": "ctrl+o: show jobs",
|
|
498050
|
+
"media.activity.collapse": "ctrl+o: collapse",
|
|
498051
|
+
"media.activity.chain": "Production chain",
|
|
498052
|
+
"media.detail.queue": "Position {position}",
|
|
498053
|
+
"media.detail.segment": "Segment {current}/{total}",
|
|
498054
|
+
"media.detail.audio": "{seconds}s audio",
|
|
498055
|
+
"media.detail.remaining": "about {duration} remaining",
|
|
498056
|
+
"media.detail.preview": "Preview",
|
|
498057
|
+
"media.detail.playSample": "Play sample",
|
|
498058
|
+
"media.detail.waveform": "Waveform",
|
|
498059
|
+
"media.detail.open": "Open",
|
|
498060
|
+
"media.detail.duration": "Duration {duration}",
|
|
498061
|
+
"media.detail.resolution": "{width}x{height}",
|
|
498062
|
+
"media.kind.media": "Media",
|
|
498063
|
+
"media.kind.image": "Image",
|
|
498064
|
+
"media.kind.video": "Video",
|
|
498065
|
+
"media.kind.voice": "Voice",
|
|
498066
|
+
"media.kind.image-analysis": "Image analysis",
|
|
498067
|
+
"media.kind.video-analysis": "Video analysis",
|
|
498068
|
+
"media.kind.dubbing": "Dubbing",
|
|
498069
|
+
"media.kind.lipsync": "Lip sync",
|
|
498070
|
+
"media.phase.submitting": "Sending request",
|
|
498071
|
+
"media.phase.uploading": "Sending request",
|
|
498072
|
+
"media.phase.accepted": "Queued",
|
|
498073
|
+
"media.phase.pending": "Queued",
|
|
498074
|
+
"media.phase.queued": "Queued",
|
|
498075
|
+
"media.phase.running": "Processing",
|
|
498076
|
+
"media.phase.in-progress": "Processing",
|
|
498077
|
+
"media.phase.generating": "Generating",
|
|
498078
|
+
"media.phase.rendering": "Rendering",
|
|
498079
|
+
"media.phase.processing": "Processing",
|
|
498080
|
+
"media.phase.checking": "Checking status",
|
|
498081
|
+
"media.phase.audio-analysis": "Audio analysis",
|
|
498082
|
+
"media.phase.face-detection": "Face detection",
|
|
498083
|
+
"media.phase.face-tracking": "Face tracking",
|
|
498084
|
+
"media.phase.lip-sync-running": "Lip sync running",
|
|
498085
|
+
"media.phase.exporting": "Exporting",
|
|
498086
|
+
"media.phase.saving": "Saving",
|
|
498087
|
+
"media.phase.upscaling": "Upscaling",
|
|
498088
|
+
"media.phase.analyzing": "Analyzing"
|
|
498089
|
+
},
|
|
498090
|
+
de: {
|
|
498091
|
+
"media.activity.jobs": "{count} Medienaufträge aktiv",
|
|
498092
|
+
"media.activity.showJobs": "ctrl+o: Aufträge öffnen",
|
|
498093
|
+
"media.activity.collapse": "ctrl+o: einklappen",
|
|
498094
|
+
"media.activity.chain": "Produktionskette",
|
|
498095
|
+
"media.detail.queue": "Platz {position}",
|
|
498096
|
+
"media.detail.segment": "Abschnitt {current}/{total}",
|
|
498097
|
+
"media.detail.audio": "{seconds}s Audio",
|
|
498098
|
+
"media.detail.remaining": "noch etwa {duration}",
|
|
498099
|
+
"media.detail.preview": "Vorschau",
|
|
498100
|
+
"media.detail.playSample": "Probehören",
|
|
498101
|
+
"media.detail.waveform": "Wellenform",
|
|
498102
|
+
"media.detail.open": "Öffnen",
|
|
498103
|
+
"media.detail.duration": "Dauer {duration}",
|
|
498104
|
+
"media.detail.resolution": "{width}x{height}",
|
|
498105
|
+
"media.kind.media": "Medien",
|
|
498106
|
+
"media.kind.image": "Bild",
|
|
498107
|
+
"media.kind.video": "Video",
|
|
498108
|
+
"media.kind.voice": "Stimme",
|
|
498109
|
+
"media.kind.image-analysis": "Bildanalyse",
|
|
498110
|
+
"media.kind.video-analysis": "Videoanalyse",
|
|
498111
|
+
"media.kind.dubbing": "Vertonung",
|
|
498112
|
+
"media.kind.lipsync": "Lip-Sync",
|
|
498113
|
+
"media.phase.submitting": "Auftrag wird gesendet",
|
|
498114
|
+
"media.phase.uploading": "Auftrag wird gesendet",
|
|
498115
|
+
"media.phase.accepted": "Eingereiht",
|
|
498116
|
+
"media.phase.pending": "Eingereiht",
|
|
498117
|
+
"media.phase.queued": "Eingereiht",
|
|
498118
|
+
"media.phase.running": "Wird verarbeitet",
|
|
498119
|
+
"media.phase.in-progress": "Wird verarbeitet",
|
|
498120
|
+
"media.phase.generating": "Wird erzeugt",
|
|
498121
|
+
"media.phase.rendering": "Wird gerendert",
|
|
498122
|
+
"media.phase.processing": "Wird verarbeitet",
|
|
498123
|
+
"media.phase.checking": "Status wird geprüft",
|
|
498124
|
+
"media.phase.audio-analysis": "Audioanalyse",
|
|
498125
|
+
"media.phase.face-detection": "Gesichtserkennung",
|
|
498126
|
+
"media.phase.face-tracking": "Gesicht wird verfolgt",
|
|
498127
|
+
"media.phase.lip-sync-running": "Lip-Sync läuft",
|
|
498128
|
+
"media.phase.exporting": "Wird exportiert",
|
|
498129
|
+
"media.phase.saving": "Wird gespeichert",
|
|
498130
|
+
"media.phase.upscaling": "Wird hochskaliert",
|
|
498131
|
+
"media.phase.analyzing": "Wird analysiert"
|
|
498132
|
+
}
|
|
498133
|
+
});
|
|
498134
|
+
function mediaActivityStatusKey(value) {
|
|
498135
|
+
return String(value ?? "processing").trim().toLowerCase().replaceAll(/[^a-z0-9]+/g, "-");
|
|
498136
|
+
}
|
|
498137
|
+
function mediaActivityIsTerminal(value) {
|
|
498138
|
+
return [
|
|
498139
|
+
"complete",
|
|
498140
|
+
"completed",
|
|
498141
|
+
"ready",
|
|
498142
|
+
"failed",
|
|
498143
|
+
"expired",
|
|
498144
|
+
"blocked"
|
|
498145
|
+
].includes(mediaActivityStatusKey(value));
|
|
498146
|
+
}
|
|
498147
|
+
function shouldSuppressMediaPollTranscript(toolName, isError, output) {
|
|
498148
|
+
if (toolName !== "GetMedia" || isError === true) return false;
|
|
498149
|
+
const text = typeof output === "string" ? output : JSON.stringify(output);
|
|
498150
|
+
const match = /Media job\s+\S+\s+status:\s*([a-z0-9_-]+)/i.exec(text);
|
|
498151
|
+
return match !== null && !mediaActivityIsTerminal(match[1]);
|
|
498152
|
+
}
|
|
498153
|
+
function mediaActivityIsQueued(job) {
|
|
498154
|
+
return job.queuePosition !== void 0 || [
|
|
498155
|
+
"accepted",
|
|
498156
|
+
"pending",
|
|
498157
|
+
"queued",
|
|
498158
|
+
"submitting",
|
|
498159
|
+
"uploading"
|
|
498160
|
+
].includes(mediaActivityStatusKey(job.phase));
|
|
498161
|
+
}
|
|
498162
|
+
function mediaActivityShouldShowPercent(job) {
|
|
498163
|
+
return !mediaActivityIsQueued(job) && job.percent !== void 0 && Number.isFinite(job.percent);
|
|
498164
|
+
}
|
|
498165
|
+
function mediaActivityCanonicalPhase(value) {
|
|
498166
|
+
const phase = mediaActivityStatusKey(value);
|
|
498167
|
+
if (["accepted", "pending", "submitting", "uploading"].includes(phase)) return "queued";
|
|
498168
|
+
if (["running", "in-progress"].includes(phase)) return "processing";
|
|
498169
|
+
if (phase === "face-detection") return "face-tracking";
|
|
498170
|
+
return phase;
|
|
498171
|
+
}
|
|
498172
|
+
function mediaActivityPhaseSequence(mediaKind) {
|
|
498173
|
+
switch (mediaActivityStatusKey(mediaKind)) {
|
|
498174
|
+
case "image": return ["queued", "generating", "upscaling", "saving"];
|
|
498175
|
+
case "video": return ["queued", "generating", "rendering", "saving"];
|
|
498176
|
+
case "voice": return ["queued", "processing", "saving"];
|
|
498177
|
+
case "dubbing": return ["queued", "audio-analysis", "rendering", "saving"];
|
|
498178
|
+
case "lipsync": return ["queued", "audio-analysis", "face-tracking", "lip-sync-running", "rendering", "exporting", "saving"];
|
|
498179
|
+
case "image-analysis":
|
|
498180
|
+
case "video-analysis": return ["queued", "analyzing"];
|
|
498181
|
+
default: return ["queued", "processing", "saving"];
|
|
498182
|
+
}
|
|
498183
|
+
}
|
|
498184
|
+
function mediaActivityChainStates(job) {
|
|
498185
|
+
const current = mediaActivityCanonicalPhase(job.phaseLabel ?? job.phase);
|
|
498186
|
+
const history = new Set((job.phaseHistory ?? []).map((phase) => mediaActivityCanonicalPhase(phase)));
|
|
498187
|
+
return mediaActivityPhaseSequence(job.mediaKind).map((phase) => ({
|
|
498188
|
+
phase,
|
|
498189
|
+
state: phase === current ? "active" : history.has(phase) ? "done" : "pending"
|
|
498190
|
+
}));
|
|
498191
|
+
}
|
|
498192
|
+
function renderMediaWaveform(samples, width) {
|
|
498193
|
+
if (!Array.isArray(samples) || samples.length === 0 || width <= 0) return "";
|
|
498194
|
+
const bars = "▁▂▃▄▅▆▇█";
|
|
498195
|
+
const safeWidth = Math.max(1, Math.floor(width));
|
|
498196
|
+
const max = Math.max(...samples.map((sample) => Math.abs(sample)), 1e-9);
|
|
498197
|
+
let output = "";
|
|
498198
|
+
for (let index = 0; index < safeWidth; index++) {
|
|
498199
|
+
const sampleIndex = Math.min(samples.length - 1, Math.floor(index * samples.length / safeWidth));
|
|
498200
|
+
const normalized = Math.min(1, Math.abs(samples[sampleIndex]) / max);
|
|
498201
|
+
output += bars[Math.min(bars.length - 1, Math.floor(normalized * bars.length))];
|
|
498202
|
+
}
|
|
498203
|
+
return output;
|
|
498204
|
+
}
|
|
498205
|
+
function mediaActivityOpenUrl(job) {
|
|
498206
|
+
const candidate = [job.sampleUrl, job.previewUrl, job.localPath].find((value) => typeof value === "string" && value.trim().length > 0)?.trim();
|
|
498207
|
+
if (candidate === void 0) return;
|
|
498208
|
+
if (/^https?:\/\//iu.test(candidate) || /^file:\/\//iu.test(candidate)) try {
|
|
498209
|
+
const parsed = new URL(candidate);
|
|
498210
|
+
if (["http:", "https:", "file:"].includes(parsed.protocol)) return parsed.href;
|
|
498211
|
+
} catch {
|
|
498212
|
+
return;
|
|
498213
|
+
}
|
|
498214
|
+
if (/^[A-Za-z]:[\\/]/u.test(candidate) || candidate.startsWith("/")) return pathToFileURL(candidate).href;
|
|
498215
|
+
}
|
|
498216
|
+
const MEDIA_ACTIVITY_LABELS = {
|
|
498217
|
+
"media.kind": /* @__PURE__ */ new Set([
|
|
498218
|
+
"media",
|
|
498219
|
+
"image",
|
|
498220
|
+
"video",
|
|
498221
|
+
"voice",
|
|
498222
|
+
"image-analysis",
|
|
498223
|
+
"video-analysis",
|
|
498224
|
+
"dubbing",
|
|
498225
|
+
"lipsync"
|
|
498226
|
+
]),
|
|
498227
|
+
"media.phase": /* @__PURE__ */ new Set([
|
|
498228
|
+
"submitting",
|
|
498229
|
+
"uploading",
|
|
498230
|
+
"accepted",
|
|
498231
|
+
"pending",
|
|
498232
|
+
"queued",
|
|
498233
|
+
"running",
|
|
498234
|
+
"in-progress",
|
|
498235
|
+
"generating",
|
|
498236
|
+
"rendering",
|
|
498237
|
+
"processing",
|
|
498238
|
+
"checking",
|
|
498239
|
+
"audio-analysis",
|
|
498240
|
+
"face-detection",
|
|
498241
|
+
"face-tracking",
|
|
498242
|
+
"lip-sync-running",
|
|
498243
|
+
"exporting",
|
|
498244
|
+
"saving",
|
|
498245
|
+
"upscaling",
|
|
498246
|
+
"analyzing"
|
|
498247
|
+
])
|
|
498248
|
+
};
|
|
498249
|
+
function mediaUiText(key, params = {}) {
|
|
498250
|
+
return uiTextFor(getCurrentUiLocale() === "de" ? "de" : "en", key, params);
|
|
498251
|
+
}
|
|
498252
|
+
function mediaActivityLabel(prefix, value, fallback) {
|
|
498253
|
+
const normalized = mediaActivityStatusKey(value);
|
|
498254
|
+
if (!MEDIA_ACTIVITY_LABELS[prefix]?.has(normalized)) return fallback;
|
|
498255
|
+
return mediaUiText(`${prefix}.${normalized}`);
|
|
498256
|
+
}
|
|
498257
|
+
function formatMediaDuration(seconds) {
|
|
498258
|
+
if (!Number.isFinite(seconds) || seconds < 0) return;
|
|
498259
|
+
const whole = Math.round(seconds);
|
|
498260
|
+
const minutes = Math.floor(whole / 60);
|
|
498261
|
+
const rest = whole % 60;
|
|
498262
|
+
return minutes > 0 ? `${String(minutes)}:${String(rest).padStart(2, "0")}` : `${String(rest)}s`;
|
|
498263
|
+
}
|
|
498264
|
+
var MediaActivityStore = class {
|
|
498265
|
+
jobs = /* @__PURE__ */ new Map();
|
|
498266
|
+
update(toolCallId, event) {
|
|
498267
|
+
if (event === null || typeof event !== "object") return;
|
|
498268
|
+
const id = typeof event.id === "string" && event.id.length > 0 ? event.id : void 0;
|
|
498269
|
+
let existingKey = id;
|
|
498270
|
+
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) {
|
|
498271
|
+
existingKey = key;
|
|
498272
|
+
break;
|
|
498273
|
+
}
|
|
498274
|
+
const key = id ?? existingKey ?? toolCallId;
|
|
498275
|
+
const previous = existingKey === void 0 ? void 0 : this.jobs.get(existingKey);
|
|
498276
|
+
if (existingKey !== void 0 && existingKey !== key) this.jobs.delete(existingKey);
|
|
498277
|
+
if (mediaActivityIsTerminal(event.phase)) {
|
|
498278
|
+
this.jobs.delete(key);
|
|
498279
|
+
return;
|
|
498280
|
+
}
|
|
498281
|
+
const mediaKind = event.mediaKind === "media" && previous?.mediaKind !== void 0 ? previous.mediaKind : event.mediaKind ?? previous?.mediaKind ?? "media";
|
|
498282
|
+
const phase = mediaActivityStatusKey(event.phase ?? previous?.phase ?? "processing");
|
|
498283
|
+
const phaseHistory = [...previous?.phaseHistory ?? []];
|
|
498284
|
+
if (phaseHistory.at(-1) !== phase) phaseHistory.push(phase);
|
|
498285
|
+
this.jobs.set(key, {
|
|
498286
|
+
...previous,
|
|
498287
|
+
...event,
|
|
498288
|
+
id: id ?? previous?.id,
|
|
498289
|
+
mediaKind,
|
|
498290
|
+
phase,
|
|
498291
|
+
phaseHistory,
|
|
498292
|
+
toolCallId,
|
|
498293
|
+
startedAt: previous?.startedAt ?? Date.now(),
|
|
498294
|
+
updatedAt: Date.now()
|
|
498295
|
+
});
|
|
498296
|
+
}
|
|
498297
|
+
active() {
|
|
498298
|
+
return [...this.jobs.values()].filter((job) => !mediaActivityIsTerminal(job.phase)).sort((a, b) => a.startedAt - b.startedAt);
|
|
498299
|
+
}
|
|
498300
|
+
clear() {
|
|
498301
|
+
this.jobs.clear();
|
|
498302
|
+
}
|
|
498303
|
+
};
|
|
498304
|
+
var MediaActivityComponent = class {
|
|
498305
|
+
jobs;
|
|
498306
|
+
expanded;
|
|
498307
|
+
previewImages = /* @__PURE__ */ new Map();
|
|
498308
|
+
constructor(jobs, expanded = false) {
|
|
498309
|
+
this.jobs = jobs;
|
|
498310
|
+
this.expanded = expanded;
|
|
498311
|
+
}
|
|
498312
|
+
invalidate() {
|
|
498313
|
+
for (const image of this.previewImages.values()) image.invalidate();
|
|
498314
|
+
}
|
|
498315
|
+
jobLine(job, width, includeBar) {
|
|
498316
|
+
const kind = mediaActivityLabel("media.kind", job.mediaKind, String(job.mediaKind ?? "Media"));
|
|
498317
|
+
const rawPhase = job.phaseLabel ?? job.phase ?? "processing";
|
|
498318
|
+
const phase = sanitizeTerminalText(mediaActivityLabel("media.phase", rawPhase, String(rawPhase)));
|
|
498319
|
+
const details = [];
|
|
498320
|
+
if (job.queuePosition !== void 0) details.push(mediaUiText("media.detail.queue", { position: job.queuePosition }));
|
|
498321
|
+
if (job.currentStep !== void 0 && job.totalSteps !== void 0) details.push(`${String(job.currentStep)}/${String(job.totalSteps)}`);
|
|
498322
|
+
if (job.currentSegment !== void 0 && job.totalSegments !== void 0) details.push(mediaUiText("media.detail.segment", {
|
|
498323
|
+
current: job.currentSegment,
|
|
498324
|
+
total: job.totalSegments
|
|
498325
|
+
}));
|
|
498326
|
+
if (job.currentFrame !== void 0 && job.totalFrames !== void 0) details.push(`Frame ${String(job.currentFrame)}/${String(job.totalFrames)}`);
|
|
498327
|
+
if (job.fps !== void 0) details.push(`${String(Math.round(job.fps * 10) / 10)} FPS`);
|
|
498328
|
+
if (job.generatedSeconds !== void 0) details.push(mediaUiText("media.detail.audio", { seconds: Math.round(job.generatedSeconds) }));
|
|
498329
|
+
if (job.durationSeconds !== void 0) details.push(mediaUiText("media.detail.duration", { duration: formatMediaDuration(job.durationSeconds) }));
|
|
498330
|
+
if (job.width > 0 && job.height > 0) details.push(mediaUiText("media.detail.resolution", {
|
|
498331
|
+
width: Math.round(job.width),
|
|
498332
|
+
height: Math.round(job.height)
|
|
498333
|
+
}));
|
|
498334
|
+
const elapsed = job.elapsedSeconds ?? (Date.now() - job.startedAt) / 1e3;
|
|
498335
|
+
const elapsedText = formatMediaDuration(elapsed);
|
|
498336
|
+
if (elapsedText !== void 0) details.push(elapsedText);
|
|
498337
|
+
if (job.remainingSeconds !== void 0) details.push(mediaUiText("media.detail.remaining", { duration: formatMediaDuration(job.remainingSeconds) }));
|
|
498338
|
+
let progress = "";
|
|
498339
|
+
if (mediaActivityShouldShowPercent(job)) {
|
|
498340
|
+
const percent = Math.min(100, Math.max(0, job.percent));
|
|
498341
|
+
progress = includeBar ? ` · ${renderProgressBar(percent / 100, 12)} · ${String(Math.round(percent))} %` : ` · ${String(Math.round(percent))} %`;
|
|
498342
|
+
}
|
|
498343
|
+
const line = `${currentTheme.boldFg("primary", kind)} · ${phase}${details.length === 0 ? "" : ` · ${details.join(" · ")}`}${progress}`;
|
|
498344
|
+
return truncateToWidth(line, Math.max(1, width), "…");
|
|
498345
|
+
}
|
|
498346
|
+
chainLine(job, width) {
|
|
498347
|
+
const chain = mediaActivityChainStates(job).map(({ phase, state }) => {
|
|
498348
|
+
const symbol = state === "done" ? "[x]" : state === "active" ? "[>]" : "[ ]";
|
|
498349
|
+
const label = mediaActivityLabel("media.phase", phase, phase);
|
|
498350
|
+
return `${symbol} ${label}`;
|
|
498351
|
+
});
|
|
498352
|
+
return truncateToWidth(` ${mediaUiText("media.activity.chain")} · ${chain.join(" · ")}`, Math.max(1, width), "…");
|
|
498353
|
+
}
|
|
498354
|
+
previewImage(job) {
|
|
498355
|
+
if (typeof job.previewDataBase64 !== "string" || job.previewDataBase64.length === 0 || job.previewDataBase64.length > 2 * 1024 * 1024 || !/^[A-Za-z0-9+/=\r\n]+$/u.test(job.previewDataBase64)) return;
|
|
498356
|
+
const mimeType = typeof job.previewMimeType === "string" ? job.previewMimeType.toLowerCase() : "";
|
|
498357
|
+
if (!["image/png", "image/jpeg", "image/webp", "image/gif"].includes(mimeType)) return;
|
|
498358
|
+
const key = `${job.id ?? job.toolCallId}:${mimeType}:${job.previewDataBase64.length}`;
|
|
498359
|
+
let image = this.previewImages.get(key);
|
|
498360
|
+
if (image === void 0) {
|
|
498361
|
+
image = new Image(job.previewDataBase64, mimeType, { fallbackColor: (text) => currentTheme.fg("textDim", text) }, {
|
|
498362
|
+
maxHeightCells: 5,
|
|
498363
|
+
maxWidthCells: 24,
|
|
498364
|
+
filename: mediaUiText("media.detail.preview")
|
|
498365
|
+
});
|
|
498366
|
+
this.previewImages.set(key, image);
|
|
498367
|
+
}
|
|
498368
|
+
return image;
|
|
498369
|
+
}
|
|
498370
|
+
extraLines(job, width) {
|
|
498371
|
+
const lines = [this.chainLine(job, width)];
|
|
498372
|
+
if (Array.isArray(job.waveform) && job.waveform.length > 0) {
|
|
498373
|
+
const label = `${mediaUiText("media.detail.waveform")} · `;
|
|
498374
|
+
const waveform = renderMediaWaveform(job.waveform, Math.max(1, width - visibleWidth(label) - 2));
|
|
498375
|
+
lines.push(truncateToWidth(` ${label}${waveform}`, Math.max(1, width), "…"));
|
|
498376
|
+
}
|
|
498377
|
+
const openUrl = mediaActivityOpenUrl(job);
|
|
498378
|
+
if (openUrl !== void 0) {
|
|
498379
|
+
const key = job.mediaKind === "voice" ? "media.detail.playSample" : job.localPath !== void 0 ? "media.detail.open" : "media.detail.preview";
|
|
498380
|
+
lines.push(truncateToWidth(` ${hyperlink(mediaUiText(key), openUrl)}`, Math.max(1, width), "…"));
|
|
498381
|
+
}
|
|
498382
|
+
const image = this.previewImage(job);
|
|
498383
|
+
if (image !== void 0) lines.push(...image.render(Math.max(1, width - 2)).map((line) => ` ${line}`));
|
|
498384
|
+
return lines;
|
|
498385
|
+
}
|
|
498386
|
+
render(width) {
|
|
498387
|
+
if (this.jobs.length === 0) return [];
|
|
498388
|
+
const safeWidth = Math.max(1, width);
|
|
498389
|
+
const hint = mediaUiText(this.expanded ? "media.activity.collapse" : "media.activity.showJobs");
|
|
498390
|
+
if (this.jobs.length > 1 && !this.expanded) {
|
|
498391
|
+
const summary = `${currentTheme.boldFg("primary", mediaUiText("media.activity.jobs", { count: this.jobs.length }))} · ${currentTheme.fg("textDim", hint)}`;
|
|
498392
|
+
return [truncateToWidth(summary, safeWidth, "…")];
|
|
498393
|
+
}
|
|
498394
|
+
const lines = [];
|
|
498395
|
+
if (this.jobs.length === 1) lines.push(truncateToWidth(`${this.jobLine(this.jobs[0], safeWidth, true)} · ${currentTheme.fg("textDim", hint)}`, safeWidth, "…"));
|
|
498396
|
+
else lines.push(truncateToWidth(`${currentTheme.boldFg("primary", mediaUiText("media.activity.jobs", { count: this.jobs.length }))} · ${currentTheme.fg("textDim", hint)}`, safeWidth, "…"));
|
|
498397
|
+
if (!this.expanded) return lines;
|
|
498398
|
+
for (const [index, job] of this.jobs.entries()) {
|
|
498399
|
+
if (this.jobs.length > 1) lines.push(truncateToWidth(` ${String(index + 1)}. ${this.jobLine(job, Math.max(1, safeWidth - 3), false)}`, safeWidth, "…"));
|
|
498400
|
+
lines.push(...this.extraLines(job, safeWidth));
|
|
498401
|
+
}
|
|
498402
|
+
return lines;
|
|
498403
|
+
}
|
|
498404
|
+
};
|
|
497918
498405
|
//#endregion
|
|
497919
498406
|
//#region src/tui/components/panes/queue-pane.copy.ts
|
|
497920
498407
|
registerUiCatalogFragment({
|
|
@@ -504441,6 +504928,10 @@ var SessionEventHandler = class {
|
|
|
504441
504928
|
streamingUI.scheduleFlush();
|
|
504442
504929
|
}
|
|
504443
504930
|
handleToolProgress(event) {
|
|
504931
|
+
if (event.update.kind === "custom" && event.update.customKind === MEDIA_PROGRESS_CUSTOM_KIND) {
|
|
504932
|
+
this.host.updateMediaActivity(event.toolCallId, event.update.customData);
|
|
504933
|
+
return;
|
|
504934
|
+
}
|
|
504444
504935
|
const text = event.update.text;
|
|
504445
504936
|
if (text === void 0 || text.length === 0) return;
|
|
504446
504937
|
const tc = this.host.streamingUI.getToolComponent(event.toolCallId);
|
|
@@ -504461,7 +504952,13 @@ var SessionEventHandler = class {
|
|
|
504461
504952
|
is_error: event.isError,
|
|
504462
504953
|
synthetic: event.synthetic
|
|
504463
504954
|
};
|
|
504955
|
+
const activeCall = streamingUI.getActiveToolCall(event.toolCallId);
|
|
504956
|
+
if (shouldSuppressMediaPollTranscript(activeCall?.name, event.isError, event.output)) streamingUI.suppressToolCallTranscript(event.toolCallId);
|
|
504464
504957
|
const matchedCall = streamingUI.completeToolResult(event.toolCallId, resultData);
|
|
504958
|
+
if (matchedCall !== void 0 && isMediaToolName(matchedCall.name) && event.isError === true) this.host.updateMediaActivity(event.toolCallId, {
|
|
504959
|
+
mediaKind: mediaKindForToolName(matchedCall.name),
|
|
504960
|
+
phase: "failed"
|
|
504961
|
+
});
|
|
504465
504962
|
if (matchedCall?.name === "GetMedia" && event.isError !== true) this.host.runChannelMediaFallback(event.output);
|
|
504466
504963
|
this.subAgentEventHandler.handleAgentSwarmToolResult(event.toolCallId, resultData, event.isError === true);
|
|
504467
504964
|
if (matchedCall !== void 0 && matchedCall.name === "TodoList" && !event.isError) {
|
|
@@ -505773,6 +506270,7 @@ var SessionReplayRenderer = class {
|
|
|
505773
506270
|
};
|
|
505774
506271
|
call.result = result;
|
|
505775
506272
|
this.applyStepContext(context);
|
|
506273
|
+
if (shouldSuppressMediaPollTranscript(call.name, message.isError, result.output)) this.host.streamingUI.suppressToolCallTranscript(toolCallId);
|
|
505776
506274
|
this.host.streamingUI.onToolCallEnd(toolCallId, result);
|
|
505777
506275
|
this.host.streamingUI.removeActiveToolCall(toolCallId);
|
|
505778
506276
|
context.completedToolCallIds.add(toolCallId);
|
|
@@ -506827,24 +507325,21 @@ function formatContextStatus(usage, tokens, maxTokens, colors, width, now = /* @
|
|
|
506827
507325
|
return truncateToWidth(current, available, "…");
|
|
506828
507326
|
}
|
|
506829
507327
|
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
507328
|
const label = formatCompactionRunningText(estimatedInputTokens);
|
|
506834
507329
|
const stageText = progress === void 0 ? "" : formatCompactionStageText(progress);
|
|
506835
507330
|
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
|
|
507331
|
+
const elapsed = `${String(Math.max(0, Math.round(elapsedMs / 1e3)))}s`;
|
|
506837
507332
|
const clock = chalk.hex(colors.textDim)(` · ${clockHhmm(now)}`);
|
|
506838
507333
|
const variants = [
|
|
506839
|
-
`${label}${stageText.length === 0 ? "" : ` · ${stageText}`}
|
|
507334
|
+
`${label}${stageText.length === 0 ? "" : ` · ${stageText}`} · ${elapsed}${clock}`,
|
|
506840
507335
|
`${label}${stageText.length === 0 ? "" : ` · ${stageText}`}`,
|
|
506841
507336
|
compactStageText,
|
|
506842
|
-
|
|
506843
|
-
stageText
|
|
507337
|
+
elapsed,
|
|
507338
|
+
stageText
|
|
506844
507339
|
];
|
|
506845
507340
|
const available = Math.max(0, width);
|
|
506846
507341
|
for (const variant of variants) if (visibleWidth(variant) <= available) return variant;
|
|
506847
|
-
return truncateToWidth(
|
|
507342
|
+
return truncateToWidth(elapsed, available, "…");
|
|
506848
507343
|
}
|
|
506849
507344
|
function contextMetrics(state) {
|
|
506850
507345
|
const tokens = Number.isFinite(state.contextTokens) ? Math.max(0, state.contextTokens) : 0;
|
|
@@ -507390,6 +507885,18 @@ var StreamingUIController = class {
|
|
|
507390
507885
|
removeToolComponent(id) {
|
|
507391
507886
|
this._pendingToolComponents.delete(id);
|
|
507392
507887
|
}
|
|
507888
|
+
suppressToolCallTranscript(id) {
|
|
507889
|
+
const { state } = this.host;
|
|
507890
|
+
const component = this._pendingToolComponents.get(id);
|
|
507891
|
+
this._pendingToolComponents.delete(id);
|
|
507892
|
+
const transcriptEntryIndex = state.transcriptEntries.findIndex((entry) => entry.toolCallData?.id === id);
|
|
507893
|
+
if (transcriptEntryIndex >= 0) state.transcriptEntries.splice(transcriptEntryIndex, 1);
|
|
507894
|
+
if (component !== void 0) {
|
|
507895
|
+
const childIndex = state.transcriptContainer.children.indexOf(component);
|
|
507896
|
+
if (childIndex >= 0) state.transcriptContainer.children.splice(childIndex, 1);
|
|
507897
|
+
}
|
|
507898
|
+
state.ui.requestRender();
|
|
507899
|
+
}
|
|
507393
507900
|
hasPendingAgentGroup() {
|
|
507394
507901
|
return this._pendingAgentGroup !== null;
|
|
507395
507902
|
}
|
|
@@ -512083,6 +512590,9 @@ var BlunTUI = class {
|
|
|
512083
512590
|
startupGoalPromptedSessionId;
|
|
512084
512591
|
lastActivityMode;
|
|
512085
512592
|
currentLoadingTip = void 0;
|
|
512593
|
+
mediaActivityStore = new MediaActivityStore();
|
|
512594
|
+
mediaActivityTickTimer;
|
|
512595
|
+
mediaActivityExpanded = false;
|
|
512086
512596
|
lastHistoryContent;
|
|
512087
512597
|
shellOutputStreams = /* @__PURE__ */ new Map();
|
|
512088
512598
|
streamingUI;
|
|
@@ -512594,6 +513104,7 @@ var BlunTUI = class {
|
|
|
512594
513104
|
this.tasksBrowserController.close();
|
|
512595
513105
|
this.btwPanelController.clear();
|
|
512596
513106
|
this.stopActivitySpinner();
|
|
513107
|
+
this.stopMediaActivityTicking();
|
|
512597
513108
|
this.disposeEditorReplacement();
|
|
512598
513109
|
this.streamingUI.disposeActiveCompactionBlock();
|
|
512599
513110
|
this.streamingUI.resetToolUi();
|
|
@@ -512742,6 +513253,13 @@ var BlunTUI = class {
|
|
|
512742
513253
|
return;
|
|
512743
513254
|
}
|
|
512744
513255
|
if (text.trimStart().startsWith("/")) {
|
|
513256
|
+
if (shouldQueueBusySlashCommand(text, {
|
|
513257
|
+
isStreaming: this.state.appState.streamingPhase !== "idle",
|
|
513258
|
+
isCompacting: this.state.appState.isCompacting
|
|
513259
|
+
})) {
|
|
513260
|
+
this.enqueueSlashCommand(text);
|
|
513261
|
+
return;
|
|
513262
|
+
}
|
|
512745
513263
|
this.runSlashCommand(text);
|
|
512746
513264
|
return;
|
|
512747
513265
|
}
|
|
@@ -513749,6 +514267,8 @@ var BlunTUI = class {
|
|
|
513749
514267
|
this.setAppState({ mcpServersSummary: null });
|
|
513750
514268
|
this.streamingUI.setStep(0);
|
|
513751
514269
|
this.streamingUI.resetLiveText();
|
|
514270
|
+
this.mediaActivityStore.clear();
|
|
514271
|
+
this.stopMediaActivityTicking();
|
|
513752
514272
|
this.updateQueueDisplay();
|
|
513753
514273
|
}
|
|
513754
514274
|
async showResumeOtherWorkDirHint(session) {
|
|
@@ -514200,8 +514720,36 @@ var BlunTUI = class {
|
|
|
514200
514720
|
this.state.ui.requestRender();
|
|
514201
514721
|
return this.showLoginProgressSpinner(uiText("blunTui.login.waiting"));
|
|
514202
514722
|
}
|
|
514723
|
+
updateMediaActivity(toolCallId, event) {
|
|
514724
|
+
this.mediaActivityStore.update(toolCallId, event);
|
|
514725
|
+
const mediaActivities = this.mediaActivityStore.active();
|
|
514726
|
+
if (mediaActivities.length > 0) {
|
|
514727
|
+
if (this.mediaActivityTickTimer === void 0) this.mediaActivityTickTimer = setInterval(() => this.state.ui.requestRender(), 1e3);
|
|
514728
|
+
} else {
|
|
514729
|
+
this.mediaActivityExpanded = false;
|
|
514730
|
+
this.stopMediaActivityTicking();
|
|
514731
|
+
}
|
|
514732
|
+
this.lastActivityMode = void 0;
|
|
514733
|
+
this.updateActivityPane();
|
|
514734
|
+
}
|
|
514735
|
+
stopMediaActivityTicking() {
|
|
514736
|
+
if (this.mediaActivityTickTimer === void 0) return;
|
|
514737
|
+
clearInterval(this.mediaActivityTickTimer);
|
|
514738
|
+
this.mediaActivityTickTimer = void 0;
|
|
514739
|
+
}
|
|
514203
514740
|
updateActivityPane() {
|
|
514204
514741
|
const effectiveMode = this.resolveActivityPaneMode();
|
|
514742
|
+
const mediaActivities = effectiveMode === "hidden" ? [] : this.mediaActivityStore.active();
|
|
514743
|
+
if (mediaActivities.length > 0) {
|
|
514744
|
+
this.stopActivitySpinner();
|
|
514745
|
+
this.syncAgentSwarmActivitySpinner(void 0);
|
|
514746
|
+
this.lastActivityMode = `media:${this.mediaActivityExpanded ? "expanded" : "collapsed"}:${mediaActivities.map((job) => `${job.id ?? job.toolCallId}:${job.updatedAt}`).join(",")}`;
|
|
514747
|
+
this.state.activityContainer.clear();
|
|
514748
|
+
this.state.activityContainer.addChild(new Spacer(1));
|
|
514749
|
+
this.state.activityContainer.addChild(new MediaActivityComponent(mediaActivities, this.mediaActivityExpanded));
|
|
514750
|
+
this.state.ui.requestRender();
|
|
514751
|
+
return;
|
|
514752
|
+
}
|
|
514205
514753
|
const tipKind = loadingTipKind(effectiveMode);
|
|
514206
514754
|
if (effectiveMode === "idle" || effectiveMode === "session" || effectiveMode === "hidden") this.currentLoadingTip = void 0;
|
|
514207
514755
|
else if (tipKind !== void 0 && (this.currentLoadingTip === void 0 || this.currentLoadingTip.kind !== tipKind)) this.currentLoadingTip = {
|
|
@@ -514294,6 +514842,10 @@ var BlunTUI = class {
|
|
|
514294
514842
|
}));
|
|
514295
514843
|
}
|
|
514296
514844
|
toggleToolOutputExpansion() {
|
|
514845
|
+
if (this.mediaActivityStore.active().length > 0) {
|
|
514846
|
+
this.toggleMediaActivityExpansion();
|
|
514847
|
+
return;
|
|
514848
|
+
}
|
|
514297
514849
|
this.state.toolOutputExpanded = !this.state.toolOutputExpanded;
|
|
514298
514850
|
const children = this.state.transcriptContainer.children;
|
|
514299
514851
|
const boundaries = [];
|
|
@@ -514306,6 +514858,13 @@ var BlunTUI = class {
|
|
|
514306
514858
|
}
|
|
514307
514859
|
this.state.ui.requestRender(true);
|
|
514308
514860
|
}
|
|
514861
|
+
toggleMediaActivityExpansion() {
|
|
514862
|
+
if (this.mediaActivityStore.active().length === 0) return;
|
|
514863
|
+
this.mediaActivityExpanded = !this.mediaActivityExpanded;
|
|
514864
|
+
this.lastActivityMode = void 0;
|
|
514865
|
+
this.updateActivityPane();
|
|
514866
|
+
this.state.ui.requestRender(true);
|
|
514867
|
+
}
|
|
514309
514868
|
toggleTodoPanelExpansion() {
|
|
514310
514869
|
this.state.todoPanel.toggleExpanded();
|
|
514311
514870
|
this.state.ui.requestRender();
|