blun-king-cli 9.1.49 → 9.1.50
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 +1 -1
- package/README.md +1 -1
- package/blun.mjs +111 -16
- package/package.json +1 -1
package/LIESMICH.txt
CHANGED
package/README.md
CHANGED
package/blun.mjs
CHANGED
|
@@ -30172,7 +30172,8 @@ function parseEnvBudget(raw) {
|
|
|
30172
30172
|
*/
|
|
30173
30173
|
function computeCompletionBudgetCap(args) {
|
|
30174
30174
|
const maxCtx = args.capability?.max_context_tokens ?? 0;
|
|
30175
|
-
const
|
|
30175
|
+
const fallback = args.budget.fallback ?? DEFAULT_UNKNOWN_CONTEXT_FALLBACK;
|
|
30176
|
+
const cap = args.budget.hardCap ?? (maxCtx > 0 ? Math.min(maxCtx, fallback) : fallback);
|
|
30176
30177
|
return Math.max(MIN_FLOOR, cap);
|
|
30177
30178
|
}
|
|
30178
30179
|
/**
|
|
@@ -30197,7 +30198,7 @@ function applyCompletionBudgetWithDetails(args) {
|
|
|
30197
30198
|
});
|
|
30198
30199
|
if (args.retry !== void 0) cap = Math.max(args.retry.minimumCompletionTokens, Math.ceil(cap * args.retry.multiplier));
|
|
30199
30200
|
const maxContextTokens = args.capability?.max_context_tokens;
|
|
30200
|
-
if (args.usedContextTokens !== void 0 && maxContextTokens !== void 0 && maxContextTokens > 0) cap = Math.max(MIN_FLOOR, Math.min(cap, maxContextTokens - args.usedContextTokens));
|
|
30201
|
+
if (args.usedContextTokens !== void 0 && maxContextTokens !== void 0 && maxContextTokens > 0) cap = Math.max(MIN_FLOOR, Math.min(cap, maxContextTokens - args.usedContextTokens - COMPLETION_CONTEXT_SAFETY_MARGIN));
|
|
30201
30202
|
return {
|
|
30202
30203
|
provider: args.provider.withMaxCompletionTokens(cap, {
|
|
30203
30204
|
usedContextTokens: args.usedContextTokens,
|
|
@@ -30206,11 +30207,12 @@ function applyCompletionBudgetWithDetails(args) {
|
|
|
30206
30207
|
maxCompletionTokens: cap
|
|
30207
30208
|
};
|
|
30208
30209
|
}
|
|
30209
|
-
var MIN_FLOOR, DEFAULT_UNKNOWN_CONTEXT_FALLBACK, MIN_THINKING_COMPLETION_TOKENS;
|
|
30210
|
+
var MIN_FLOOR, DEFAULT_UNKNOWN_CONTEXT_FALLBACK, MIN_THINKING_COMPLETION_TOKENS, COMPLETION_CONTEXT_SAFETY_MARGIN;
|
|
30210
30211
|
var init_completion_budget = __esmMin((() => {
|
|
30211
30212
|
MIN_FLOOR = 1;
|
|
30212
30213
|
DEFAULT_UNKNOWN_CONTEXT_FALLBACK = 32e3;
|
|
30213
30214
|
MIN_THINKING_COMPLETION_TOKENS = 1024;
|
|
30215
|
+
COMPLETION_CONTEXT_SAFETY_MARGIN = 1e4;
|
|
30214
30216
|
}));
|
|
30215
30217
|
//#endregion
|
|
30216
30218
|
//#region ../../packages/agent-core/src/loop/retry.ts
|
|
@@ -262017,8 +262019,9 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262017
262019
|
GenerateImageInputSchema = object({ prompt: PromptSchema.describe("A complete visual description of the image to generate.") });
|
|
262018
262020
|
GenerateVideoInputSchema = object({
|
|
262019
262021
|
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
|
-
|
|
262022
|
+
image_id: MediaIdSchema.optional().describe("An optional completed PNG or JPEG media job id to animate into the video."),
|
|
262023
|
+
path: string().trim().min(1).optional().describe("An optional path to a local PNG or JPEG file to upload and animate. Relative paths resolve against the working directory.")
|
|
262024
|
+
}).refine((args) => !(args.image_id && args.path), { message: "Provide either image_id or path, not both." });
|
|
262022
262025
|
GenerateSpeechInputSchema = object({ input: PromptSchema.describe("The exact text to synthesize as speech.") });
|
|
262023
262026
|
GetMediaInputSchema = object({ id: MediaIdSchema.describe("The media job id returned by a generation tool.") });
|
|
262024
262027
|
UnderstandImageInputSchema = object({
|
|
@@ -262092,11 +262095,79 @@ var init_blun_media$1 = __esmMin((() => {
|
|
|
262092
262095
|
}
|
|
262093
262096
|
};
|
|
262094
262097
|
GenerateVideoTool = class extends MediaGenerationTool {
|
|
262098
|
+
kaos;
|
|
262099
|
+
workspace;
|
|
262095
262100
|
name = "GenerateVideo";
|
|
262096
|
-
description = "Generate a new video from text
|
|
262101
|
+
description = "Generate a new video from text, animate an existing completed image job, or animate a local PNG/JPEG file with BLUN media models. Pass image_id for an existing media job or path for a local or Telegram-provided image. Do not use this for understanding an existing video. This starts a billed asynchronous media job.";
|
|
262097
262102
|
parameters = toInputJsonSchema(GenerateVideoInputSchema);
|
|
262103
|
+
constructor(provider, kaos, workspace) {
|
|
262104
|
+
super(provider);
|
|
262105
|
+
this.kaos = kaos;
|
|
262106
|
+
this.workspace = workspace;
|
|
262107
|
+
}
|
|
262098
262108
|
subject(args) {
|
|
262099
|
-
return args.image_id ? `${args.image_id}: ${args.prompt}` : args.prompt;
|
|
262109
|
+
return args.path ? `${args.path}: ${args.prompt}` : args.image_id ? `${args.image_id}: ${args.prompt}` : args.prompt;
|
|
262110
|
+
}
|
|
262111
|
+
resolveExecution(args) {
|
|
262112
|
+
if (!args.path) return super.resolveExecution(args);
|
|
262113
|
+
const path = resolvePathAccessPath(args.path, {
|
|
262114
|
+
kaos: this.kaos,
|
|
262115
|
+
workspace: this.workspace,
|
|
262116
|
+
operation: "read"
|
|
262117
|
+
});
|
|
262118
|
+
return {
|
|
262119
|
+
accesses: ToolAccesses.readFile(path),
|
|
262120
|
+
description: `${this.name}: ${args.path}`,
|
|
262121
|
+
display: {
|
|
262122
|
+
kind: "file_io",
|
|
262123
|
+
operation: "read",
|
|
262124
|
+
path
|
|
262125
|
+
},
|
|
262126
|
+
approvalRule: literalRulePattern(this.name, path),
|
|
262127
|
+
matchesRule: (ruleArgs) => matchesPathRuleSubject(ruleArgs, path, {
|
|
262128
|
+
cwd: this.workspace.workspaceDir,
|
|
262129
|
+
pathClass: this.kaos.pathClass(),
|
|
262130
|
+
homeDir: this.kaos.gethome()
|
|
262131
|
+
}),
|
|
262132
|
+
execute: (ctx) => this.executionFromPath(args, path, ctx)
|
|
262133
|
+
};
|
|
262134
|
+
}
|
|
262135
|
+
async executionFromPath(args, safePath, ctx) {
|
|
262136
|
+
emitMediaProgress(ctx, this.name, "uploading");
|
|
262137
|
+
try {
|
|
262138
|
+
const fileType = detectFileType(safePath, await this.kaos.readBytes(safePath, 512), "media");
|
|
262139
|
+
if (fileType.mimeType !== "image/png" && fileType.mimeType !== "image/jpeg") return {
|
|
262140
|
+
isError: true,
|
|
262141
|
+
output: "Image-to-video accepts only PNG or JPEG files."
|
|
262142
|
+
};
|
|
262143
|
+
const data = await this.kaos.readBytes(safePath);
|
|
262144
|
+
if (data.byteLength === 0) return {
|
|
262145
|
+
isError: true,
|
|
262146
|
+
output: `"${args.path}" is empty.`
|
|
262147
|
+
};
|
|
262148
|
+
const options = {
|
|
262149
|
+
signal: ctx.signal,
|
|
262150
|
+
toolCallId: ctx.toolCallId
|
|
262151
|
+
};
|
|
262152
|
+
const upload = await this.provider.uploadMedia(data, fileType.mimeType, options);
|
|
262153
|
+
emitMediaProgress(ctx, this.name, "submitting", { sourceId: upload.id });
|
|
262154
|
+
const job = await this.provider.generateVideo(args.prompt, options, upload.id);
|
|
262155
|
+
emitMediaProgress(ctx, this.name, job.status, {
|
|
262156
|
+
id: job.id,
|
|
262157
|
+
sourceId: upload.id,
|
|
262158
|
+
...job.progress
|
|
262159
|
+
});
|
|
262160
|
+
return {
|
|
262161
|
+
output: `Media job ${job.id} accepted with status ${job.status}. ${this.requestNote}`,
|
|
262162
|
+
isError: false
|
|
262163
|
+
};
|
|
262164
|
+
} catch (error) {
|
|
262165
|
+
emitMediaProgress(ctx, this.name, "failed", { error: errorMessage$10(error) });
|
|
262166
|
+
return {
|
|
262167
|
+
isError: true,
|
|
262168
|
+
output: `Media request failed: ${errorMessage$10(error)}`
|
|
262169
|
+
};
|
|
262170
|
+
}
|
|
262100
262171
|
}
|
|
262101
262172
|
submit(args, options) {
|
|
262102
262173
|
return this.provider.generateVideo(args.prompt, options, args.image_id);
|
|
@@ -262764,7 +262835,7 @@ var init_tool$1 = __esmMin((() => {
|
|
|
262764
262835
|
toolServices?.webSearcher && new WebSearchTool(toolServices.webSearcher),
|
|
262765
262836
|
toolServices?.urlFetcher && new FetchURLTool(toolServices.urlFetcher),
|
|
262766
262837
|
toolServices?.media && new GenerateImageTool(toolServices.media),
|
|
262767
|
-
toolServices?.media && new GenerateVideoTool(toolServices.media),
|
|
262838
|
+
toolServices?.media && new GenerateVideoTool(toolServices.media, kaos, workspace),
|
|
262768
262839
|
toolServices?.media && new GenerateSpeechTool(toolServices.media),
|
|
262769
262840
|
toolServices?.media && new UnderstandImageTool(toolServices.media, kaos, workspace),
|
|
262770
262841
|
toolServices?.media && new UnderstandVideoTool(toolServices.media),
|
|
@@ -410038,6 +410109,16 @@ function trimPartialClosingFences(tokens) {
|
|
|
410038
410109
|
if (!marker || !lastLine || lastLine.length >= marker.length || lastLine !== marker[0]?.repeat(lastLine.length)) return;
|
|
410039
410110
|
token.text = token.text.slice(0, -lastLine.length).replace(/\n$/, "");
|
|
410040
410111
|
}
|
|
410112
|
+
function terminalHyperlinkTarget(value) {
|
|
410113
|
+
const candidate = value.trim();
|
|
410114
|
+
if (/^https?:\/\//iu.test(candidate) || /^file:\/\//iu.test(candidate)) try {
|
|
410115
|
+
const parsed = new URL(candidate);
|
|
410116
|
+
if (["http:", "https:", "file:"].includes(parsed.protocol)) return parsed.href;
|
|
410117
|
+
} catch {
|
|
410118
|
+
return;
|
|
410119
|
+
}
|
|
410120
|
+
if (/^[A-Za-z]:[\\/]/u.test(candidate)) return pathToFileURL(candidate).href;
|
|
410121
|
+
}
|
|
410041
410122
|
const markdownParser = new q();
|
|
410042
410123
|
markdownParser.setOptions({ tokenizer: new StrictStrikethroughTokenizer() });
|
|
410043
410124
|
var Markdown = class {
|
|
@@ -410291,7 +410372,11 @@ var Markdown = class {
|
|
|
410291
410372
|
break;
|
|
410292
410373
|
}
|
|
410293
410374
|
case "codespan":
|
|
410294
|
-
|
|
410375
|
+
{
|
|
410376
|
+
const styledCode = this.theme.code(token.text);
|
|
410377
|
+
const linkTarget = terminalHyperlinkTarget(token.text);
|
|
410378
|
+
result += (linkTarget !== void 0 && getCapabilities().hyperlinks ? hyperlink(styledCode, linkTarget) : styledCode) + stylePrefix;
|
|
410379
|
+
}
|
|
410295
410380
|
break;
|
|
410296
410381
|
case "link": {
|
|
410297
410382
|
const linkText = this.renderInlineTokens(token.tokens || [], resolvedStyleContext);
|
|
@@ -498182,11 +498267,18 @@ function mediaActivityPhaseSequence(mediaKind) {
|
|
|
498182
498267
|
}
|
|
498183
498268
|
}
|
|
498184
498269
|
function mediaActivityChainStates(job) {
|
|
498185
|
-
const
|
|
498186
|
-
const
|
|
498187
|
-
|
|
498270
|
+
const sequence = mediaActivityPhaseSequence(job.mediaKind);
|
|
498271
|
+
const normalize = (value) => {
|
|
498272
|
+
const phase = mediaActivityCanonicalPhase(value);
|
|
498273
|
+
if (phase === "processing" && !sequence.includes(phase)) return sequence[1] ?? phase;
|
|
498274
|
+
return phase;
|
|
498275
|
+
};
|
|
498276
|
+
const current = normalize(job.phaseLabel ?? job.phase);
|
|
498277
|
+
const currentIndex = sequence.indexOf(current);
|
|
498278
|
+
const history = new Set((job.phaseHistory ?? []).map(normalize));
|
|
498279
|
+
return sequence.map((phase, index) => ({
|
|
498188
498280
|
phase,
|
|
498189
|
-
state: phase === current ? "active" : history.has(phase) ? "done" : "pending"
|
|
498281
|
+
state: phase === current ? "active" : history.has(phase) || currentIndex > index ? "done" : "pending"
|
|
498190
498282
|
}));
|
|
498191
498283
|
}
|
|
498192
498284
|
function renderMediaWaveform(samples, width) {
|
|
@@ -498340,16 +498432,19 @@ var MediaActivityComponent = class {
|
|
|
498340
498432
|
const percent = Math.min(100, Math.max(0, job.percent));
|
|
498341
498433
|
progress = includeBar ? ` · ${renderProgressBar(percent / 100, 12)} · ${String(Math.round(percent))} %` : ` · ${String(Math.round(percent))} %`;
|
|
498342
498434
|
}
|
|
498343
|
-
const line = `${currentTheme.boldFg("primary", kind)} · ${phase}${details.length === 0 ? "" : ` · ${details.join(" · ")}`}${progress}`;
|
|
498435
|
+
const line = `${currentTheme.boldFg("primary", "●")} ${currentTheme.boldFg("primary", kind)} · ${phase}${details.length === 0 ? "" : ` · ${details.join(" · ")}`}${progress}`;
|
|
498344
498436
|
return truncateToWidth(line, Math.max(1, width), "…");
|
|
498345
498437
|
}
|
|
498346
498438
|
chainLine(job, width) {
|
|
498347
498439
|
const chain = mediaActivityChainStates(job).map(({ phase, state }) => {
|
|
498348
498440
|
const symbol = state === "done" ? "[x]" : state === "active" ? "[>]" : "[ ]";
|
|
498349
498441
|
const label = mediaActivityLabel("media.phase", phase, phase);
|
|
498350
|
-
|
|
498442
|
+
const text = `${symbol} ${label}`;
|
|
498443
|
+
if (state === "done") return currentTheme.fg("success", text);
|
|
498444
|
+
if (state === "active") return currentTheme.boldFg("primary", text);
|
|
498445
|
+
return currentTheme.fg("textDim", text);
|
|
498351
498446
|
});
|
|
498352
|
-
return truncateToWidth(` ${mediaUiText("media.activity.chain")} · ${chain.join(" · ")}`, Math.max(1, width), "…");
|
|
498447
|
+
return truncateToWidth(` ${currentTheme.fg("textDim", mediaUiText("media.activity.chain"))} · ${chain.join(currentTheme.fg("textDim", " · "))}`, Math.max(1, width), "…");
|
|
498353
498448
|
}
|
|
498354
498449
|
previewImage(job) {
|
|
498355
498450
|
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;
|