blun-king-cli 9.1.48 → 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 +9 -1
- package/README.md +9 -1
- package/blun.mjs +251 -21
- 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
|
-----
|
|
@@ -54,6 +54,14 @@ Nachweisbare Arbeitsabläufe
|
|
|
54
54
|
|
|
55
55
|
Alle Befehle funktionieren identisch mit `king`.
|
|
56
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
|
+
|
|
57
65
|
Aktualisieren
|
|
58
66
|
-------------
|
|
59
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
|
|
@@ -75,6 +75,14 @@ Version 9.1.0 enthält sieben zusätzliche, getrennt nutzbare Befehlsgruppen:
|
|
|
75
75
|
|
|
76
76
|
Sie stehen unter `blun` und `king` identisch zur Verfügung.
|
|
77
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
|
+
|
|
78
86
|
## Aktualisieren
|
|
79
87
|
|
|
80
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
|
|
|
@@ -261995,7 +262015,10 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
261995
262015
|
PromptSchema = string().trim().min(1).max(2e4);
|
|
261996
262016
|
MediaIdSchema = string().trim().min(1).max(200).regex(/^[A-Za-z0-9_-]+$/);
|
|
261997
262017
|
GenerateImageInputSchema = object({ prompt: PromptSchema.describe("A complete visual description of the image to generate.") });
|
|
261998
|
-
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
|
+
});
|
|
261999
262022
|
GenerateSpeechInputSchema = object({ input: PromptSchema.describe("The exact text to synthesize as speech.") });
|
|
262000
262023
|
GetMediaInputSchema = object({ id: MediaIdSchema.describe("The media job id returned by a generation tool.") });
|
|
262001
262024
|
UnderstandImageInputSchema = object({
|
|
@@ -262070,13 +262093,13 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262070
262093
|
};
|
|
262071
262094
|
GenerateVideoTool = class extends MediaGenerationTool {
|
|
262072
262095
|
name = "GenerateVideo";
|
|
262073
|
-
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.";
|
|
262074
262097
|
parameters = toInputJsonSchema(GenerateVideoInputSchema);
|
|
262075
262098
|
subject(args) {
|
|
262076
|
-
return args.prompt;
|
|
262099
|
+
return args.image_id ? `${args.image_id}: ${args.prompt}` : args.prompt;
|
|
262077
262100
|
}
|
|
262078
262101
|
submit(args, options) {
|
|
262079
|
-
return this.provider.generateVideo(args.prompt, options);
|
|
262102
|
+
return this.provider.generateVideo(args.prompt, options, args.image_id);
|
|
262080
262103
|
}
|
|
262081
262104
|
};
|
|
262082
262105
|
GenerateSpeechTool = class extends MediaGenerationTool {
|
|
@@ -310814,6 +310837,14 @@ function mediaPayloadText(payload, keys) {
|
|
|
310814
310837
|
if (typeof value === "string" && value.trim() !== "") return value.trim();
|
|
310815
310838
|
}
|
|
310816
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
|
+
}
|
|
310817
310848
|
function mediaProgressFromPayload(payload) {
|
|
310818
310849
|
const rawPercent = mediaPayloadNumber(payload, ["percent", "progress_percent", "progressPercent", "progress"]);
|
|
310819
310850
|
const percent = rawPercent === void 0 ? void 0 : rawPercent <= 1 ? rawPercent * 100 : rawPercent;
|
|
@@ -310830,7 +310861,16 @@ function mediaProgressFromPayload(payload) {
|
|
|
310830
310861
|
generatedSeconds: mediaPayloadNumber(payload, ["generated_seconds", "generatedSeconds", "audio_seconds", "audioSeconds"]),
|
|
310831
310862
|
queuePosition: mediaPayloadNumber(payload, ["queue_position", "queuePosition"]),
|
|
310832
310863
|
elapsedSeconds: mediaPayloadNumber(payload, ["elapsed_seconds", "elapsedSeconds"]),
|
|
310833
|
-
remainingSeconds: mediaPayloadNumber(payload, ["remaining_seconds", "remainingSeconds", "eta_seconds", "etaSeconds"])
|
|
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"])
|
|
310834
310874
|
};
|
|
310835
310875
|
return Object.fromEntries(Object.entries(progress).filter(([, value]) => value !== void 0));
|
|
310836
310876
|
}
|
|
@@ -310884,8 +310924,10 @@ var init_blun_media = __esmMin((() => {
|
|
|
310884
310924
|
generateImage(prompt, options) {
|
|
310885
310925
|
return this.submit("/images/generations", { prompt }, options);
|
|
310886
310926
|
}
|
|
310887
|
-
generateVideo(prompt, options) {
|
|
310888
|
-
|
|
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);
|
|
310889
310931
|
}
|
|
310890
310932
|
generateSpeech(input, options) {
|
|
310891
310933
|
return this.submit("/audio/speech", { input }, options);
|
|
@@ -498004,10 +498046,19 @@ var ActivityPaneComponent = class extends Container {
|
|
|
498004
498046
|
registerUiCatalogFragment({
|
|
498005
498047
|
en: {
|
|
498006
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",
|
|
498007
498052
|
"media.detail.queue": "Position {position}",
|
|
498008
498053
|
"media.detail.segment": "Segment {current}/{total}",
|
|
498009
498054
|
"media.detail.audio": "{seconds}s audio",
|
|
498010
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}",
|
|
498011
498062
|
"media.kind.media": "Media",
|
|
498012
498063
|
"media.kind.image": "Image",
|
|
498013
498064
|
"media.kind.video": "Video",
|
|
@@ -498038,10 +498089,19 @@ registerUiCatalogFragment({
|
|
|
498038
498089
|
},
|
|
498039
498090
|
de: {
|
|
498040
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",
|
|
498041
498095
|
"media.detail.queue": "Platz {position}",
|
|
498042
498096
|
"media.detail.segment": "Abschnitt {current}/{total}",
|
|
498043
498097
|
"media.detail.audio": "{seconds}s Audio",
|
|
498044
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}",
|
|
498045
498105
|
"media.kind.media": "Medien",
|
|
498046
498106
|
"media.kind.image": "Bild",
|
|
498047
498107
|
"media.kind.video": "Video",
|
|
@@ -498084,6 +498144,75 @@ function mediaActivityIsTerminal(value) {
|
|
|
498084
498144
|
"blocked"
|
|
498085
498145
|
].includes(mediaActivityStatusKey(value));
|
|
498086
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
|
+
}
|
|
498087
498216
|
const MEDIA_ACTIVITY_LABELS = {
|
|
498088
498217
|
"media.kind": /* @__PURE__ */ new Set([
|
|
498089
498218
|
"media",
|
|
@@ -498150,11 +498279,16 @@ var MediaActivityStore = class {
|
|
|
498150
498279
|
return;
|
|
498151
498280
|
}
|
|
498152
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);
|
|
498153
498285
|
this.jobs.set(key, {
|
|
498154
498286
|
...previous,
|
|
498155
498287
|
...event,
|
|
498156
498288
|
id: id ?? previous?.id,
|
|
498157
498289
|
mediaKind,
|
|
498290
|
+
phase,
|
|
498291
|
+
phaseHistory,
|
|
498158
498292
|
toolCallId,
|
|
498159
498293
|
startedAt: previous?.startedAt ?? Date.now(),
|
|
498160
498294
|
updatedAt: Date.now()
|
|
@@ -498169,13 +498303,16 @@ var MediaActivityStore = class {
|
|
|
498169
498303
|
};
|
|
498170
498304
|
var MediaActivityComponent = class {
|
|
498171
498305
|
jobs;
|
|
498172
|
-
|
|
498306
|
+
expanded;
|
|
498307
|
+
previewImages = /* @__PURE__ */ new Map();
|
|
498308
|
+
constructor(jobs, expanded = false) {
|
|
498173
498309
|
this.jobs = jobs;
|
|
498310
|
+
this.expanded = expanded;
|
|
498174
498311
|
}
|
|
498175
|
-
invalidate() {
|
|
498176
|
-
|
|
498177
|
-
|
|
498178
|
-
|
|
498312
|
+
invalidate() {
|
|
498313
|
+
for (const image of this.previewImages.values()) image.invalidate();
|
|
498314
|
+
}
|
|
498315
|
+
jobLine(job, width, includeBar) {
|
|
498179
498316
|
const kind = mediaActivityLabel("media.kind", job.mediaKind, String(job.mediaKind ?? "Media"));
|
|
498180
498317
|
const rawPhase = job.phaseLabel ?? job.phase ?? "processing";
|
|
498181
498318
|
const phase = sanitizeTerminalText(mediaActivityLabel("media.phase", rawPhase, String(rawPhase)));
|
|
@@ -498189,18 +498326,80 @@ var MediaActivityComponent = class {
|
|
|
498189
498326
|
if (job.currentFrame !== void 0 && job.totalFrames !== void 0) details.push(`Frame ${String(job.currentFrame)}/${String(job.totalFrames)}`);
|
|
498190
498327
|
if (job.fps !== void 0) details.push(`${String(Math.round(job.fps * 10) / 10)} FPS`);
|
|
498191
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
|
+
}));
|
|
498192
498334
|
const elapsed = job.elapsedSeconds ?? (Date.now() - job.startedAt) / 1e3;
|
|
498193
498335
|
const elapsedText = formatMediaDuration(elapsed);
|
|
498194
498336
|
if (elapsedText !== void 0) details.push(elapsedText);
|
|
498195
498337
|
if (job.remainingSeconds !== void 0) details.push(mediaUiText("media.detail.remaining", { duration: formatMediaDuration(job.remainingSeconds) }));
|
|
498196
498338
|
let progress = "";
|
|
498197
|
-
if (
|
|
498339
|
+
if (mediaActivityShouldShowPercent(job)) {
|
|
498198
498340
|
const percent = Math.min(100, Math.max(0, job.percent));
|
|
498199
|
-
progress = ` · ${renderProgressBar(percent / 100, 12)} · ${String(Math.round(percent))} %`;
|
|
498341
|
+
progress = includeBar ? ` · ${renderProgressBar(percent / 100, 12)} · ${String(Math.round(percent))} %` : ` · ${String(Math.round(percent))} %`;
|
|
498200
498342
|
}
|
|
498201
|
-
const
|
|
498202
|
-
|
|
498203
|
-
|
|
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;
|
|
498204
498403
|
}
|
|
498205
498404
|
};
|
|
498206
498405
|
//#endregion
|
|
@@ -504753,6 +504952,8 @@ var SessionEventHandler = class {
|
|
|
504753
504952
|
is_error: event.isError,
|
|
504754
504953
|
synthetic: event.synthetic
|
|
504755
504954
|
};
|
|
504955
|
+
const activeCall = streamingUI.getActiveToolCall(event.toolCallId);
|
|
504956
|
+
if (shouldSuppressMediaPollTranscript(activeCall?.name, event.isError, event.output)) streamingUI.suppressToolCallTranscript(event.toolCallId);
|
|
504756
504957
|
const matchedCall = streamingUI.completeToolResult(event.toolCallId, resultData);
|
|
504757
504958
|
if (matchedCall !== void 0 && isMediaToolName(matchedCall.name) && event.isError === true) this.host.updateMediaActivity(event.toolCallId, {
|
|
504758
504959
|
mediaKind: mediaKindForToolName(matchedCall.name),
|
|
@@ -506069,6 +506270,7 @@ var SessionReplayRenderer = class {
|
|
|
506069
506270
|
};
|
|
506070
506271
|
call.result = result;
|
|
506071
506272
|
this.applyStepContext(context);
|
|
506273
|
+
if (shouldSuppressMediaPollTranscript(call.name, message.isError, result.output)) this.host.streamingUI.suppressToolCallTranscript(toolCallId);
|
|
506072
506274
|
this.host.streamingUI.onToolCallEnd(toolCallId, result);
|
|
506073
506275
|
this.host.streamingUI.removeActiveToolCall(toolCallId);
|
|
506074
506276
|
context.completedToolCallIds.add(toolCallId);
|
|
@@ -507683,6 +507885,18 @@ var StreamingUIController = class {
|
|
|
507683
507885
|
removeToolComponent(id) {
|
|
507684
507886
|
this._pendingToolComponents.delete(id);
|
|
507685
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
|
+
}
|
|
507686
507900
|
hasPendingAgentGroup() {
|
|
507687
507901
|
return this._pendingAgentGroup !== null;
|
|
507688
507902
|
}
|
|
@@ -512378,6 +512592,7 @@ var BlunTUI = class {
|
|
|
512378
512592
|
currentLoadingTip = void 0;
|
|
512379
512593
|
mediaActivityStore = new MediaActivityStore();
|
|
512380
512594
|
mediaActivityTickTimer;
|
|
512595
|
+
mediaActivityExpanded = false;
|
|
512381
512596
|
lastHistoryContent;
|
|
512382
512597
|
shellOutputStreams = /* @__PURE__ */ new Map();
|
|
512383
512598
|
streamingUI;
|
|
@@ -514507,9 +514722,13 @@ var BlunTUI = class {
|
|
|
514507
514722
|
}
|
|
514508
514723
|
updateMediaActivity(toolCallId, event) {
|
|
514509
514724
|
this.mediaActivityStore.update(toolCallId, event);
|
|
514510
|
-
|
|
514725
|
+
const mediaActivities = this.mediaActivityStore.active();
|
|
514726
|
+
if (mediaActivities.length > 0) {
|
|
514511
514727
|
if (this.mediaActivityTickTimer === void 0) this.mediaActivityTickTimer = setInterval(() => this.state.ui.requestRender(), 1e3);
|
|
514512
|
-
} else
|
|
514728
|
+
} else {
|
|
514729
|
+
this.mediaActivityExpanded = false;
|
|
514730
|
+
this.stopMediaActivityTicking();
|
|
514731
|
+
}
|
|
514513
514732
|
this.lastActivityMode = void 0;
|
|
514514
514733
|
this.updateActivityPane();
|
|
514515
514734
|
}
|
|
@@ -514524,10 +514743,10 @@ var BlunTUI = class {
|
|
|
514524
514743
|
if (mediaActivities.length > 0) {
|
|
514525
514744
|
this.stopActivitySpinner();
|
|
514526
514745
|
this.syncAgentSwarmActivitySpinner(void 0);
|
|
514527
|
-
this.lastActivityMode = `media:${mediaActivities.map((job) => `${job.id ?? job.toolCallId}:${job.updatedAt}`).join(",")}`;
|
|
514746
|
+
this.lastActivityMode = `media:${this.mediaActivityExpanded ? "expanded" : "collapsed"}:${mediaActivities.map((job) => `${job.id ?? job.toolCallId}:${job.updatedAt}`).join(",")}`;
|
|
514528
514747
|
this.state.activityContainer.clear();
|
|
514529
514748
|
this.state.activityContainer.addChild(new Spacer(1));
|
|
514530
|
-
this.state.activityContainer.addChild(new MediaActivityComponent(mediaActivities));
|
|
514749
|
+
this.state.activityContainer.addChild(new MediaActivityComponent(mediaActivities, this.mediaActivityExpanded));
|
|
514531
514750
|
this.state.ui.requestRender();
|
|
514532
514751
|
return;
|
|
514533
514752
|
}
|
|
@@ -514623,6 +514842,10 @@ var BlunTUI = class {
|
|
|
514623
514842
|
}));
|
|
514624
514843
|
}
|
|
514625
514844
|
toggleToolOutputExpansion() {
|
|
514845
|
+
if (this.mediaActivityStore.active().length > 0) {
|
|
514846
|
+
this.toggleMediaActivityExpansion();
|
|
514847
|
+
return;
|
|
514848
|
+
}
|
|
514626
514849
|
this.state.toolOutputExpanded = !this.state.toolOutputExpanded;
|
|
514627
514850
|
const children = this.state.transcriptContainer.children;
|
|
514628
514851
|
const boundaries = [];
|
|
@@ -514635,6 +514858,13 @@ var BlunTUI = class {
|
|
|
514635
514858
|
}
|
|
514636
514859
|
this.state.ui.requestRender(true);
|
|
514637
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
|
+
}
|
|
514638
514868
|
toggleTodoPanelExpansion() {
|
|
514639
514869
|
this.state.todoPanel.toggleExpanded();
|
|
514640
514870
|
this.state.ui.requestRender();
|