blun-king-cli 9.1.597 → 9.1.599
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/CHANGELOG.md +32 -0
- package/README.md +6 -0
- package/blun.mjs +672 -115
- package/package.json +1 -1
- package/worker-host.mjs +101 -61
package/package.json
CHANGED
package/worker-host.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// BLUN_BUILD_INPUT_SHA256:
|
|
2
|
+
// BLUN_BUILD_INPUT_SHA256:25c271186c418490335e30ef395705d13d90d816c66cac47bb57835f2482f093
|
|
3
3
|
import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
|
|
4
4
|
import { dirname as __cjsShimDirname } from 'node:path';
|
|
5
5
|
const __filename = __cjsShimFileURLToPath(import.meta.url);
|
|
@@ -1311,7 +1311,7 @@ function normalizeBlunToolSchema(schema) {
|
|
|
1311
1311
|
}
|
|
1312
1312
|
function ensureBlunPropertyTypes(schema) {
|
|
1313
1313
|
const normalized = cloneJsonValue(schema);
|
|
1314
|
-
if (!isRecord$
|
|
1314
|
+
if (!isRecord$10(normalized)) throw new Error("JSON Schema root must normalize to an object.");
|
|
1315
1315
|
recurseSchema(normalized);
|
|
1316
1316
|
return normalized;
|
|
1317
1317
|
}
|
|
@@ -1372,7 +1372,7 @@ function resolveLocalJsonPointer(root, ref) {
|
|
|
1372
1372
|
let current = root;
|
|
1373
1373
|
for (const rawPart of ref.slice(2).split("/")) {
|
|
1374
1374
|
const part = unescapeJsonPointerPart(rawPart);
|
|
1375
|
-
if (isRecord$
|
|
1375
|
+
if (isRecord$10(current)) {
|
|
1376
1376
|
if (!hasOwn(current, part)) return { found: false };
|
|
1377
1377
|
current = current[part];
|
|
1378
1378
|
} else if (Array.isArray(current)) {
|
|
@@ -1394,20 +1394,20 @@ function parseJsonPointerArrayIndex(part) {
|
|
|
1394
1394
|
return Number(part);
|
|
1395
1395
|
}
|
|
1396
1396
|
function recurseSchema(node) {
|
|
1397
|
-
if (!isRecord$
|
|
1397
|
+
if (!isRecord$10(node)) return;
|
|
1398
1398
|
visitChildSchemas(node, normalizeProperty);
|
|
1399
1399
|
}
|
|
1400
1400
|
function visitChildSchemas(node, visit) {
|
|
1401
1401
|
for (const { key, kind } of CHILD_SCHEMA_SLOTS) {
|
|
1402
1402
|
const value = node[key];
|
|
1403
1403
|
if (kind === "single") {
|
|
1404
|
-
if (isRecord$
|
|
1404
|
+
if (isRecord$10(value)) visit(value);
|
|
1405
1405
|
} else if (kind === "array") {
|
|
1406
1406
|
if (Array.isArray(value)) for (const item of value) visit(item);
|
|
1407
1407
|
} else if (kind === "map") {
|
|
1408
|
-
if (isRecord$
|
|
1408
|
+
if (isRecord$10(value)) for (const item of Object.values(value)) visit(item);
|
|
1409
1409
|
} else if (kind === "schema-or-array") {
|
|
1410
|
-
if (isRecord$
|
|
1410
|
+
if (isRecord$10(value)) visit(value);
|
|
1411
1411
|
else if (Array.isArray(value)) for (const item of value) visit(item);
|
|
1412
1412
|
}
|
|
1413
1413
|
}
|
|
@@ -1419,7 +1419,7 @@ function childSchemaKeysForParentType(parentType) {
|
|
|
1419
1419
|
});
|
|
1420
1420
|
}
|
|
1421
1421
|
function normalizeProperty(node) {
|
|
1422
|
-
if (!isRecord$
|
|
1422
|
+
if (!isRecord$10(node)) return;
|
|
1423
1423
|
if (!hasOwn(node, "type") && !hasAnyKey(node, TYPE_COMPLETION_SKIP_KEYS)) {
|
|
1424
1424
|
const enumValues = node["enum"];
|
|
1425
1425
|
if (Array.isArray(enumValues) && enumValues.length > 0) node["type"] = inferTypeFromValues(enumValues);
|
|
@@ -1503,14 +1503,14 @@ function hasAnyKey(obj, keys) {
|
|
|
1503
1503
|
}
|
|
1504
1504
|
function cloneJsonValue(value) {
|
|
1505
1505
|
if (Array.isArray(value)) return value.map((item) => cloneJsonValue(item));
|
|
1506
|
-
if (isRecord$
|
|
1506
|
+
if (isRecord$10(value)) {
|
|
1507
1507
|
const cloned = {};
|
|
1508
1508
|
for (const [key, child] of Object.entries(value)) cloned[key] = cloneJsonValue(child);
|
|
1509
1509
|
return cloned;
|
|
1510
1510
|
}
|
|
1511
1511
|
return value;
|
|
1512
1512
|
}
|
|
1513
|
-
function isRecord$
|
|
1513
|
+
function isRecord$10(value) {
|
|
1514
1514
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1515
1515
|
}
|
|
1516
1516
|
function hasOwn(obj, key) {
|
|
@@ -2703,14 +2703,14 @@ var BlunStreamedMessage = class {
|
|
|
2703
2703
|
};
|
|
2704
2704
|
function contextOverflowOutputCap(error, currentCap) {
|
|
2705
2705
|
const maxContext = error.maxContextTokens;
|
|
2706
|
-
const counts = /requested ([\d,_]+) output tokens and your prompt contains (
|
|
2706
|
+
const counts = /requested ([\d,_]+) output tokens and your prompt contains (at least )?([\d,_]+) input tokens/i.exec(error.message);
|
|
2707
2707
|
if (maxContext === void 0 || counts === null || !Number.isSafeInteger(maxContext) || maxContext <= 0) return;
|
|
2708
2708
|
const requestedOutput = Number(counts[1].replaceAll(/[,_]/g, ""));
|
|
2709
|
-
const input = Number(counts[
|
|
2709
|
+
const input = Number(counts[3].replaceAll(/[,_]/g, ""));
|
|
2710
2710
|
if (!Number.isSafeInteger(input) || input < 0 || !Number.isSafeInteger(requestedOutput) || requestedOutput <= 0 || !Number.isSafeInteger(input + requestedOutput) || input + requestedOutput <= maxContext) return;
|
|
2711
2711
|
const available = maxContext - input;
|
|
2712
2712
|
const headroom = Math.min(1024, Math.max(1, Math.ceil(available * .01)));
|
|
2713
|
-
const cap = Math.min(requestedOutput - 1, available - headroom);
|
|
2713
|
+
const cap = Math.min(counts[2] === void 0 ? requestedOutput - 1 : Math.floor(requestedOutput / 2), available - headroom);
|
|
2714
2714
|
if (cap < 1 || currentCap !== void 0 && (typeof currentCap !== "number" || !Number.isSafeInteger(currentCap) || cap >= currentCap)) return;
|
|
2715
2715
|
return cap;
|
|
2716
2716
|
}
|
|
@@ -10279,7 +10279,7 @@ function tokenFromWire(wire) {
|
|
|
10279
10279
|
}
|
|
10280
10280
|
//#endregion
|
|
10281
10281
|
//#region ../../packages/oauth/src/utils.ts
|
|
10282
|
-
function isRecord$
|
|
10282
|
+
function isRecord$9(value) {
|
|
10283
10283
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10284
10284
|
}
|
|
10285
10285
|
//#endregion
|
|
@@ -10594,7 +10594,7 @@ var FileTokenStorage = class {
|
|
|
10594
10594
|
} catch {
|
|
10595
10595
|
return;
|
|
10596
10596
|
}
|
|
10597
|
-
if (!isRecord$
|
|
10597
|
+
if (!isRecord$9(parsed)) return void 0;
|
|
10598
10598
|
return tokenFromWire(parsed);
|
|
10599
10599
|
}
|
|
10600
10600
|
async save(name, token) {
|
|
@@ -10699,7 +10699,7 @@ function extractApiErrorMessage(value) {
|
|
|
10699
10699
|
}
|
|
10700
10700
|
return;
|
|
10701
10701
|
}
|
|
10702
|
-
if (!isRecord$
|
|
10702
|
+
if (!isRecord$9(value)) return void 0;
|
|
10703
10703
|
for (const key of DIRECT_ERROR_KEYS) {
|
|
10704
10704
|
const message = stringField$1(value, key);
|
|
10705
10705
|
if (message !== void 0) return message;
|
|
@@ -10707,7 +10707,7 @@ function extractApiErrorMessage(value) {
|
|
|
10707
10707
|
const error = value["error"];
|
|
10708
10708
|
const errorString = nonEmptyString$6(error);
|
|
10709
10709
|
if (errorString !== void 0) return errorString;
|
|
10710
|
-
if (isRecord$
|
|
10710
|
+
if (isRecord$9(error)) for (const key of NESTED_ERROR_KEYS) {
|
|
10711
10711
|
const message = stringField$1(error, key);
|
|
10712
10712
|
if (message !== void 0) return message;
|
|
10713
10713
|
}
|
|
@@ -10801,7 +10801,7 @@ async function postForm(url, params, deviceHeaders, options) {
|
|
|
10801
10801
|
let data = {};
|
|
10802
10802
|
try {
|
|
10803
10803
|
const parsed = await response.json();
|
|
10804
|
-
if (isRecord$
|
|
10804
|
+
if (isRecord$9(parsed)) data = parsed;
|
|
10805
10805
|
} catch {}
|
|
10806
10806
|
return {
|
|
10807
10807
|
status,
|
|
@@ -12718,9 +12718,9 @@ function blunContextWindowsUrl(oauthHost) {
|
|
|
12718
12718
|
return `${(oauthHost ?? process.env["BLUN_OAUTH_HOST"] ?? "https://account.blun.ai").replace(/\/+$/, "")}/api/verbrauch/tarife`;
|
|
12719
12719
|
}
|
|
12720
12720
|
function parseManagedContextWindow(payload, plan) {
|
|
12721
|
-
if (!isRecord$
|
|
12721
|
+
if (!isRecord$9(payload)) return void 0;
|
|
12722
12722
|
const contextWindows = payload["kontext"];
|
|
12723
|
-
if (!isRecord$
|
|
12723
|
+
if (!isRecord$9(contextWindows)) return void 0;
|
|
12724
12724
|
const value = contextWindows[plan];
|
|
12725
12725
|
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
|
|
12726
12726
|
}
|
|
@@ -12755,7 +12755,7 @@ function parseManagedUsagePayload(payload) {
|
|
|
12755
12755
|
const plan = typeof rec["plan"] === "string" && rec["plan"].trim().length > 0 ? rec["plan"].trim() : void 0;
|
|
12756
12756
|
const contextWindowTokens = managedContextWindowFrom(rec);
|
|
12757
12757
|
const unlimited = rec["unlimited"] === true;
|
|
12758
|
-
const stand = isRecord$
|
|
12758
|
+
const stand = isRecord$9(rec["stand"]) ? rec["stand"] : void 0;
|
|
12759
12759
|
if (stand !== void 0) for (const [sourceKey, id, label] of ACCOUNT_USAGE_WINDOWS) {
|
|
12760
12760
|
const row = toAccountUsageRow(stand[sourceKey], id, label, unlimited);
|
|
12761
12761
|
if (row !== null) limits.push(row);
|
|
@@ -12765,9 +12765,9 @@ function parseManagedUsagePayload(payload) {
|
|
|
12765
12765
|
const item = rawLimits[idx];
|
|
12766
12766
|
if (!item || typeof item !== "object") continue;
|
|
12767
12767
|
const detailRaw = item["detail"];
|
|
12768
|
-
const detail = isRecord$
|
|
12768
|
+
const detail = isRecord$9(detailRaw) ? detailRaw : item;
|
|
12769
12769
|
const windowRaw = item["window"];
|
|
12770
|
-
const row = toUsageRow(detail, limitLabel(item, detail, isRecord$
|
|
12770
|
+
const row = toUsageRow(detail, limitLabel(item, detail, isRecord$9(windowRaw) ? windowRaw : {}, idx));
|
|
12771
12771
|
if (row !== null) limits.push(row);
|
|
12772
12772
|
}
|
|
12773
12773
|
return {
|
|
@@ -12808,7 +12808,7 @@ const ACCOUNT_USAGE_WINDOWS = [
|
|
|
12808
12808
|
]
|
|
12809
12809
|
];
|
|
12810
12810
|
function toAccountUsageRow(raw, id, label, accountUnlimited) {
|
|
12811
|
-
if (!isRecord$
|
|
12811
|
+
if (!isRecord$9(raw)) return null;
|
|
12812
12812
|
const used = toInt(raw["verbraucht"]);
|
|
12813
12813
|
const unlimited = accountUnlimited || raw["unlimited"] === true;
|
|
12814
12814
|
const fraction = raw["anteil"];
|
|
@@ -12841,7 +12841,7 @@ function toAccountUsageRow(raw, id, label, accountUnlimited) {
|
|
|
12841
12841
|
};
|
|
12842
12842
|
}
|
|
12843
12843
|
function toUsageRow(raw, defaultLabel) {
|
|
12844
|
-
if (!isRecord$
|
|
12844
|
+
if (!isRecord$9(raw)) return null;
|
|
12845
12845
|
const unlimited = raw["unlimited"] === true;
|
|
12846
12846
|
const limit = toInt(raw["limit"]);
|
|
12847
12847
|
let used = toInt(raw["used"]);
|
|
@@ -12962,7 +12962,7 @@ function isManagedQuotaErrorMessage(message) {
|
|
|
12962
12962
|
return /you(?:'|’)?ve reached your usage limit/.test(normalized) && /billing cycle|quota will be (?:refreshed|reset)|purchase extra usage/.test(normalized);
|
|
12963
12963
|
}
|
|
12964
12964
|
function hasManagedUsageShape(payload) {
|
|
12965
|
-
if (!isRecord$
|
|
12965
|
+
if (!isRecord$9(payload)) return false;
|
|
12966
12966
|
let recognized = false;
|
|
12967
12967
|
if ("context_window_tokens" in payload || "contextWindowTokens" in payload) {
|
|
12968
12968
|
recognized = true;
|
|
@@ -12978,15 +12978,15 @@ function hasManagedUsageShape(payload) {
|
|
|
12978
12978
|
if (!Array.isArray(limits)) return false;
|
|
12979
12979
|
for (let index = 0; index < limits.length; index++) {
|
|
12980
12980
|
const item = limits[index];
|
|
12981
|
-
if (!isRecord$
|
|
12982
|
-
const detail = isRecord$
|
|
12983
|
-
if (toUsageRow(detail, limitLabel(item, detail, isRecord$
|
|
12981
|
+
if (!isRecord$9(item)) return false;
|
|
12982
|
+
const detail = isRecord$9(item["detail"]) ? item["detail"] : item;
|
|
12983
|
+
if (toUsageRow(detail, limitLabel(item, detail, isRecord$9(item["window"]) ? item["window"] : {}, index)) === null) return false;
|
|
12984
12984
|
}
|
|
12985
12985
|
}
|
|
12986
12986
|
if ("stand" in payload) {
|
|
12987
12987
|
recognized = true;
|
|
12988
12988
|
const stand = payload["stand"];
|
|
12989
|
-
if (!isRecord$
|
|
12989
|
+
if (!isRecord$9(stand)) return false;
|
|
12990
12990
|
const windows = ACCOUNT_USAGE_WINDOWS.filter(([sourceKey]) => sourceKey in stand);
|
|
12991
12991
|
if (windows.length === 0) return false;
|
|
12992
12992
|
const unlimited = payload["unlimited"] === true;
|
|
@@ -13069,8 +13069,8 @@ function userExtras(existing, remoteOwnedFields) {
|
|
|
13069
13069
|
return out;
|
|
13070
13070
|
}
|
|
13071
13071
|
function mergeRefreshedModelAlias(existing, remote, remoteOwnedFields) {
|
|
13072
|
-
const current = isRecord$
|
|
13073
|
-
const overrides = cloneOverrides(isRecord$
|
|
13072
|
+
const current = isRecord$9(existing) ? existing : {};
|
|
13073
|
+
const overrides = cloneOverrides(isRecord$9(current["overrides"]) ? current["overrides"] : void 0);
|
|
13074
13074
|
return {
|
|
13075
13075
|
...userExtras(current, remoteOwnedFields),
|
|
13076
13076
|
...remote,
|
|
@@ -13272,7 +13272,7 @@ function parseModelContextLength(item, modelId) {
|
|
|
13272
13272
|
return values[0];
|
|
13273
13273
|
}
|
|
13274
13274
|
function toModelInfo(item) {
|
|
13275
|
-
if (!isRecord$
|
|
13275
|
+
if (!isRecord$9(item) || typeof item["id"] !== "string" || item["id"].length === 0) return;
|
|
13276
13276
|
const contextLength = parseModelContextLength(item, item["id"]);
|
|
13277
13277
|
const displayName = item["display_name"];
|
|
13278
13278
|
const normalizedDisplayName = typeof displayName === "string" && displayName.length > 0 ? displayName : void 0;
|
|
@@ -13359,7 +13359,7 @@ async function fetchManagedBlunCodeModels(options) {
|
|
|
13359
13359
|
throw new Error(message);
|
|
13360
13360
|
}
|
|
13361
13361
|
const payload = await response.json();
|
|
13362
|
-
if (!isRecord$
|
|
13362
|
+
if (!isRecord$9(payload) || !Array.isArray(payload["data"])) throw new Error(`Unexpected models response for ${baseUrl}.`);
|
|
13363
13363
|
return payload["data"].map((item) => toModelInfo(item)).filter((item) => item !== void 0);
|
|
13364
13364
|
}
|
|
13365
13365
|
throw new Error(`Failed to list BLUN models for ${baseUrl}.`);
|
|
@@ -13402,11 +13402,11 @@ function applyManagedBlunCodeConfig(config, options) {
|
|
|
13402
13402
|
apiKey
|
|
13403
13403
|
};
|
|
13404
13404
|
const upstreamKeys = new Set(options.models.map((m) => managedModelKey(m.id)));
|
|
13405
|
-
for (const [key, model] of Object.entries(existingModels)) if (RETIRED_BLUN_MODEL_KEYS.has(key) || isRecord$
|
|
13405
|
+
for (const [key, model] of Object.entries(existingModels)) if (RETIRED_BLUN_MODEL_KEYS.has(key) || isRecord$9(model) && model["provider"] === "managed:blun" && !upstreamKeys.has(key)) delete existingModels[key];
|
|
13406
13406
|
for (const model of options.models) {
|
|
13407
13407
|
const capabilities = capabilitiesForModel(model);
|
|
13408
13408
|
const key = managedModelKey(model.id);
|
|
13409
|
-
const existing = isRecord$
|
|
13409
|
+
const existing = isRecord$9(existingModels[key]) ? existingModels[key] : {};
|
|
13410
13410
|
const supportsAdaptiveThinking = capabilities?.includes("thinking") === true || capabilities?.includes("always_thinking") === true;
|
|
13411
13411
|
existingModels[key] = mergeRefreshedModelAlias(existing, {
|
|
13412
13412
|
provider: BLUN_PROVIDER_NAME$1,
|
|
@@ -13454,7 +13454,7 @@ function applyManagedBlunCodeLogoutConfig(config) {
|
|
|
13454
13454
|
let removedDefaultModel = false;
|
|
13455
13455
|
const existingModels = config.models ?? {};
|
|
13456
13456
|
for (const [key, model] of Object.entries(existingModels)) {
|
|
13457
|
-
if (!isRecord$
|
|
13457
|
+
if (!isRecord$9(model) || model["provider"] !== "managed:blun") continue;
|
|
13458
13458
|
delete existingModels[key];
|
|
13459
13459
|
if (config.defaultModel === key) removedDefaultModel = true;
|
|
13460
13460
|
}
|
|
@@ -13494,7 +13494,7 @@ function selectDefaultModel(config, models, options) {
|
|
|
13494
13494
|
function canPreserveDefaultModel(existingModels, defaultModel, managedModels) {
|
|
13495
13495
|
if (managedModels.has(defaultModel)) return true;
|
|
13496
13496
|
const existing = existingModels[defaultModel];
|
|
13497
|
-
return isRecord$
|
|
13497
|
+
return isRecord$9(existing) && existing["provider"] !== "managed:blun";
|
|
13498
13498
|
}
|
|
13499
13499
|
function assertPositiveContextLength(model) {
|
|
13500
13500
|
if (!Number.isInteger(model.contextLength) || model.contextLength <= 0) throw new Error(`BLUN model "${model.id}" must include a positive context_length.`);
|
|
@@ -13532,13 +13532,13 @@ function blunManagedQuotaUrl(oauthHost) {
|
|
|
13532
13532
|
return `${(oauthHost ?? process.env["BLUN_OAUTH_HOST"] ?? "https://account.blun.ai").replace(/\/+$/, "")}${MANAGED_QUOTA_PATH}`;
|
|
13533
13533
|
}
|
|
13534
13534
|
function parseManagedQuotaPayload(payload) {
|
|
13535
|
-
if (!isRecord$
|
|
13535
|
+
if (!isRecord$9(payload)) return void 0;
|
|
13536
13536
|
const plan = nonEmptyString$5(payload["plan"]);
|
|
13537
13537
|
const paid = payload["bezahlt"];
|
|
13538
13538
|
const creditCents = payload["guthaben_cent"];
|
|
13539
13539
|
const billingKind = nonEmptyString$5(payload["art"]);
|
|
13540
13540
|
const globalUnlimited = payload["unlimited"];
|
|
13541
|
-
if (plan === void 0 || typeof paid !== "boolean" || !Number.isSafeInteger(creditCents) || creditCents < 0 || billingKind === void 0 || globalUnlimited !== void 0 && typeof globalUnlimited !== "boolean" || !isRecord$
|
|
13541
|
+
if (plan === void 0 || typeof paid !== "boolean" || !Number.isSafeInteger(creditCents) || creditCents < 0 || billingKind === void 0 || globalUnlimited !== void 0 && typeof globalUnlimited !== "boolean" || !isRecord$9(payload["stand"])) return;
|
|
13542
13542
|
if (!hasStrictQuotaStand(payload["stand"], globalUnlimited === true)) return void 0;
|
|
13543
13543
|
const limits = parseManagedUsagePayload(payload).limits;
|
|
13544
13544
|
if (limits.length !== REQUIRED_WINDOWS.length || REQUIRED_WINDOWS.some(([, id]) => limits.filter((row) => row.id === id).length !== 1)) return;
|
|
@@ -13608,7 +13608,7 @@ function nonEmptyString$5(value) {
|
|
|
13608
13608
|
function hasStrictQuotaStand(stand, globalUnlimited) {
|
|
13609
13609
|
return REQUIRED_WINDOWS.every(([sourceKey]) => {
|
|
13610
13610
|
const row = stand[sourceKey];
|
|
13611
|
-
if (!isRecord$
|
|
13611
|
+
if (!isRecord$9(row)) return false;
|
|
13612
13612
|
const used = row["verbraucht"];
|
|
13613
13613
|
const rowUnlimited = row["unlimited"];
|
|
13614
13614
|
if (rowUnlimited !== void 0 && typeof rowUnlimited !== "boolean") return false;
|
|
@@ -20705,7 +20705,7 @@ function parseSkillText(options) {
|
|
|
20705
20705
|
throw error;
|
|
20706
20706
|
}
|
|
20707
20707
|
const frontmatter = parsed.data ?? {};
|
|
20708
|
-
if (!isRecord$
|
|
20708
|
+
if (!isRecord$8(frontmatter)) throw new SkillParseError(`Frontmatter in ${options.skillMdPath} must be a mapping at the top level`);
|
|
20709
20709
|
const metadata = normalizeMetadata(frontmatter);
|
|
20710
20710
|
if (!isSupportedSkillType(metadata.type)) throw new UnsupportedSkillTypeError(metadata.type ?? String(frontmatter["type"]));
|
|
20711
20711
|
const name = nonEmptyString$3(metadata.name);
|
|
@@ -20818,7 +20818,7 @@ function tokenizeArgs(raw) {
|
|
|
20818
20818
|
function nonEmptyString$3(value) {
|
|
20819
20819
|
return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
|
|
20820
20820
|
}
|
|
20821
|
-
function isRecord$
|
|
20821
|
+
function isRecord$8(value) {
|
|
20822
20822
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20823
20823
|
}
|
|
20824
20824
|
//#endregion
|
|
@@ -20826,7 +20826,7 @@ function isRecord$7(value) {
|
|
|
20826
20826
|
function parseCommandText(input) {
|
|
20827
20827
|
const { text, commandPath, pluginId } = input;
|
|
20828
20828
|
const parsed = parseFrontmatter(text);
|
|
20829
|
-
const frontmatter = isRecord$
|
|
20829
|
+
const frontmatter = isRecord$7(parsed.data) ? parsed.data : {};
|
|
20830
20830
|
const baseName = input.fallbackName ?? path.basename(commandPath).replace(/\.md$/i, "");
|
|
20831
20831
|
const name = nonEmptyString$2(frontmatter["name"]) ?? baseName;
|
|
20832
20832
|
const body = parsed.body.trim();
|
|
@@ -20868,7 +20868,7 @@ function descriptionFromBody(body) {
|
|
|
20868
20868
|
if (firstLine === void 0) return "No description provided.";
|
|
20869
20869
|
return firstLine.length > 240 ? `${firstLine.slice(0, 239)}…` : firstLine;
|
|
20870
20870
|
}
|
|
20871
|
-
function isRecord$
|
|
20871
|
+
function isRecord$7(value) {
|
|
20872
20872
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20873
20873
|
}
|
|
20874
20874
|
//#endregion
|
|
@@ -28376,7 +28376,7 @@ const ResumeIntentSchema = object({
|
|
|
28376
28376
|
startedAt: timestamp$2.nullable()
|
|
28377
28377
|
}).strict();
|
|
28378
28378
|
const hash$2 = (value) => createHash("sha256").update(value).digest("hex");
|
|
28379
|
-
const isRecord$
|
|
28379
|
+
const isRecord$6 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
28380
28380
|
/** Explicit resume intents, isolated from ordinary task status and output files. */
|
|
28381
28381
|
var TaskResumeStore = class {
|
|
28382
28382
|
home;
|
|
@@ -28432,9 +28432,9 @@ var TaskResumeStore = class {
|
|
|
28432
28432
|
}
|
|
28433
28433
|
async readOwnedTask(taskId) {
|
|
28434
28434
|
const task = await this.read("tasks", taskId);
|
|
28435
|
-
if (!isRecord$
|
|
28435
|
+
if (!isRecord$6(task)) throw new Error("Task has no persisted local record.");
|
|
28436
28436
|
const owner = task["resumeOwnership"];
|
|
28437
|
-
if (!isRecord$
|
|
28437
|
+
if (!isRecord$6(owner) || owner["version"] !== 1 || owner["scope"] !== hash$2(await this.root()) || owner["taskId"] !== taskId || task["taskId"] !== taskId || task["kind"] !== "agent" || owner["agentId"] !== task["agentId"] || owner["startedAt"] !== task["startedAt"]) throw new Error("Task ownership is unverified; historical or foreign records cannot be resumed automatically.");
|
|
28438
28438
|
const { resumeOwnership: _ownership, ...info } = task;
|
|
28439
28439
|
return info;
|
|
28440
28440
|
}
|
|
@@ -28686,12 +28686,12 @@ function legacyStatusToCurrent(task) {
|
|
|
28686
28686
|
return task.status;
|
|
28687
28687
|
}
|
|
28688
28688
|
function isReadablePersistedTask(obj) {
|
|
28689
|
-
return isRecord$
|
|
28689
|
+
return isRecord$5(obj) && (typeof obj["taskId"] === "string" || typeof obj["task_id"] === "string");
|
|
28690
28690
|
}
|
|
28691
28691
|
function isLegacyPersistedTask(task) {
|
|
28692
28692
|
return "task_id" in task;
|
|
28693
28693
|
}
|
|
28694
|
-
function isRecord$
|
|
28694
|
+
function isRecord$5(value) {
|
|
28695
28695
|
return typeof value === "object" && value !== null;
|
|
28696
28696
|
}
|
|
28697
28697
|
function optionalNonEmptyString(value) {
|
|
@@ -228018,7 +228018,7 @@ var HttpVisionReader = class {
|
|
|
228018
228018
|
reason: "malformed"
|
|
228019
228019
|
};
|
|
228020
228020
|
}
|
|
228021
|
-
if (!isRecord$
|
|
228021
|
+
if (!isRecord$4(payload) || payload["done"] !== true || typeof payload["response"] !== "string" || !isNonNegativeInteger(payload["prompt_eval_count"]) || !isNonNegativeInteger(payload["eval_count"])) return {
|
|
228022
228022
|
ok: false,
|
|
228023
228023
|
reason: "malformed"
|
|
228024
228024
|
};
|
|
@@ -228442,7 +228442,7 @@ function escapeXml(value) {
|
|
|
228442
228442
|
function locationKey(messageIndex, partIndex) {
|
|
228443
228443
|
return `${String(messageIndex)}:${String(partIndex)}`;
|
|
228444
228444
|
}
|
|
228445
|
-
function isRecord$
|
|
228445
|
+
function isRecord$4(value) {
|
|
228446
228446
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
228447
228447
|
}
|
|
228448
228448
|
function isNonNegativeInteger(value) {
|
|
@@ -234239,7 +234239,7 @@ const OptionalStringSchema = preprocess((value) => {
|
|
|
234239
234239
|
if (typeof value === "string") return value;
|
|
234240
234240
|
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
|
|
234241
234241
|
}, string().optional());
|
|
234242
|
-
const HookSpecificOutputSchema = preprocess((value) => isRecord$
|
|
234242
|
+
const HookSpecificOutputSchema = preprocess((value) => isRecord$3(value) ? value : void 0, looseObject({
|
|
234243
234243
|
message: OptionalStringSchema,
|
|
234244
234244
|
additionalContext: OptionalStringSchema,
|
|
234245
234245
|
permissionDecision: unknown().optional(),
|
|
@@ -234391,7 +234391,7 @@ function structuredOutput(stdout, input) {
|
|
|
234391
234391
|
return {
|
|
234392
234392
|
...result,
|
|
234393
234393
|
additionalContext: input["hook_event_name"] === "UserPromptSubmit" && hookSpecificOutput?.hookEventName === "UserPromptSubmit" ? hookSpecificOutput.additionalContext : void 0,
|
|
234394
|
-
updatedInput: input["hook_event_name"] === "PreToolUse" && hookSpecificOutput?.hookEventName === "PreToolUse" && isRecord$
|
|
234394
|
+
updatedInput: input["hook_event_name"] === "PreToolUse" && hookSpecificOutput?.hookEventName === "PreToolUse" && isRecord$3(hookSpecificOutput.updatedInput) ? hookSpecificOutput.updatedInput : void 0
|
|
234395
234395
|
};
|
|
234396
234396
|
}
|
|
234397
234397
|
return {
|
|
@@ -234460,7 +234460,7 @@ function killProcessTreeWindows(child, force) {
|
|
|
234460
234460
|
} catch {}
|
|
234461
234461
|
}
|
|
234462
234462
|
}
|
|
234463
|
-
function isRecord$
|
|
234463
|
+
function isRecord$3(value) {
|
|
234464
234464
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
234465
234465
|
}
|
|
234466
234466
|
function errorMessage$3(error) {
|
|
@@ -234581,7 +234581,16 @@ var HookEngine = class {
|
|
|
234581
234581
|
};
|
|
234582
234582
|
}
|
|
234583
234583
|
if (this.admissionClosed) return void 0;
|
|
234584
|
-
|
|
234584
|
+
let hookInput;
|
|
234585
|
+
try {
|
|
234586
|
+
hookInput = this.options.runtimeInput?.(hook, inputData) ?? inputData;
|
|
234587
|
+
} catch {
|
|
234588
|
+
return {
|
|
234589
|
+
action: "block",
|
|
234590
|
+
reason: "Hook input preparation failed."
|
|
234591
|
+
};
|
|
234592
|
+
}
|
|
234593
|
+
return runHook(hook.command, hookInput, {
|
|
234585
234594
|
timeout: hook.timeout ?? DEFAULT_HOOK_TIMEOUT_SECONDS,
|
|
234586
234595
|
cwd: hook.cwd ?? (this.options.cwd === "" ? void 0 : this.options.cwd),
|
|
234587
234596
|
env: hook.env,
|
|
@@ -235816,7 +235825,7 @@ function parsePersonalMemoryRecall(output) {
|
|
|
235816
235825
|
} catch {
|
|
235817
235826
|
return { kind: "invalid" };
|
|
235818
235827
|
}
|
|
235819
|
-
if (!isRecord$
|
|
235828
|
+
if (!isRecord$2(parsed) || !isRecord$2(parsed["personal_memory"])) return { kind: "invalid" };
|
|
235820
235829
|
const memory = parsed["personal_memory"];
|
|
235821
235830
|
const savedRaw = memory["saved"];
|
|
235822
235831
|
const threadsRaw = memory["threads"];
|
|
@@ -235825,7 +235834,7 @@ function parsePersonalMemoryRecall(output) {
|
|
|
235825
235834
|
if (savedRaw.length > MAX_SAVED_MEMORIES || threadsRaw.length > MAX_THREADS || historyRaw.length > 0) return { kind: "invalid" };
|
|
235826
235835
|
const saved = [];
|
|
235827
235836
|
for (const value of savedRaw) {
|
|
235828
|
-
if (!isRecord$
|
|
235837
|
+
if (!isRecord$2(value)) return { kind: "invalid" };
|
|
235829
235838
|
const text = boundedTrimmedString(value["text"], MAX_MEMORY_TEXT_CHARS);
|
|
235830
235839
|
const confidence = value["confidence"];
|
|
235831
235840
|
if (text === void 0 || typeof confidence !== "string" || !CONFIDENCE_VALUES.has(confidence)) return { kind: "invalid" };
|
|
@@ -235836,7 +235845,7 @@ function parsePersonalMemoryRecall(output) {
|
|
|
235836
235845
|
}
|
|
235837
235846
|
const threads = [];
|
|
235838
235847
|
for (const value of threadsRaw) {
|
|
235839
|
-
if (!isRecord$
|
|
235848
|
+
if (!isRecord$2(value)) return { kind: "invalid" };
|
|
235840
235849
|
const title = boundedTrimmedString(value["title"], MAX_THREAD_TITLE_CHARS);
|
|
235841
235850
|
const summary = boundedTrimmedString(value["summary"], MAX_THREAD_SUMMARY_CHARS);
|
|
235842
235851
|
if (title === void 0 || summary === void 0) return { kind: "invalid" };
|
|
@@ -235890,7 +235899,7 @@ function boundedTrimmedString(value, maxChars) {
|
|
|
235890
235899
|
const trimmed = value.trim();
|
|
235891
235900
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
235892
235901
|
}
|
|
235893
|
-
function isRecord$
|
|
235902
|
+
function isRecord$2(value) {
|
|
235894
235903
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
235895
235904
|
}
|
|
235896
235905
|
//#endregion
|
|
@@ -299939,6 +299948,36 @@ function mergeCallerMcpServers(base, callerServers) {
|
|
|
299939
299948
|
}
|
|
299940
299949
|
//#endregion
|
|
299941
299950
|
//#region ../../packages/agent-core/src/plugin/agent-spine-runtime.ts
|
|
299951
|
+
const PROMPT_EVENTS = new Set([
|
|
299952
|
+
"UserPromptSubmit",
|
|
299953
|
+
"TurnStart",
|
|
299954
|
+
"SubagentStart"
|
|
299955
|
+
]);
|
|
299956
|
+
/** AgentSpine reads prompt text; binary media stays in the original model input. */
|
|
299957
|
+
function projectAgentSpinePrompt(input) {
|
|
299958
|
+
if (typeof input["hook_event_name"] !== "string" || !PROMPT_EVENTS.has(input["hook_event_name"]) || !Array.isArray(input["prompt"])) return input;
|
|
299959
|
+
let changed = false;
|
|
299960
|
+
const prompt = input["prompt"].map((part) => {
|
|
299961
|
+
if (!isRecord$1(part)) return part;
|
|
299962
|
+
const field = part["type"] === "image_url" ? "imageUrl" : part["type"] === "audio_url" ? "audioUrl" : part["type"] === "video_url" ? "videoUrl" : void 0;
|
|
299963
|
+
if (field === void 0 || !isRecord$1(part[field]) || typeof part[field]["url"] !== "string") return part;
|
|
299964
|
+
const serialized = JSON.stringify(part);
|
|
299965
|
+
changed = true;
|
|
299966
|
+
return {
|
|
299967
|
+
type: "media_reference",
|
|
299968
|
+
media_type: part["type"],
|
|
299969
|
+
sha256: createHash("sha256").update(serialized).digest("hex"),
|
|
299970
|
+
original_bytes: Buffer.byteLength(serialized)
|
|
299971
|
+
};
|
|
299972
|
+
});
|
|
299973
|
+
return changed ? {
|
|
299974
|
+
...input,
|
|
299975
|
+
prompt
|
|
299976
|
+
} : input;
|
|
299977
|
+
}
|
|
299978
|
+
function isRecord$1(value) {
|
|
299979
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
299980
|
+
}
|
|
299942
299981
|
const EMPTY_RUNTIME = Object.freeze({
|
|
299943
299982
|
AGENTSPINE_KING_TIMELINE_SOURCE: "",
|
|
299944
299983
|
AGENTSPINE_KING_WIRE_PROTOCOL_VERSION: "",
|
|
@@ -300485,9 +300524,11 @@ var Session$1 = class {
|
|
|
300485
300524
|
this.experimentalFlags = options.experimentalFlags ?? new FlagResolver();
|
|
300486
300525
|
this.agentSpineRuntime = this.experimentalFlags.enabled("agent_spine_timeline") ? new AgentSpineSessionRuntime(options.agentSpineRuntime) : void 0;
|
|
300487
300526
|
this.visionReader = (this.experimentalFlags.enabled("vision_reader") ? createVisionReader(options.config?.services?.visionReader) : void 0) ?? createManagedMediaVisionReader(options.toolServices?.media);
|
|
300527
|
+
const agentSpineHooks = new Set(options.agentSpineRuntime?.hooks);
|
|
300488
300528
|
this.hookEngine = new HookEngine(options.hooks, {
|
|
300489
300529
|
cwd: options.kaos.getcwd(),
|
|
300490
300530
|
sessionId: options.id,
|
|
300531
|
+
runtimeInput: (hook, input) => agentSpineHooks.has(hook) ? projectAgentSpinePrompt(input) : input,
|
|
300491
300532
|
runtimeEnv: (hook) => {
|
|
300492
300533
|
const hostEnv = options.hookRuntimeEnv?.(hook);
|
|
300493
300534
|
const timelineEnv = this.agentSpineRuntime?.forHook(hook);
|
|
@@ -335769,7 +335810,6 @@ var BlunCore = class {
|
|
|
335769
335810
|
};
|
|
335770
335811
|
}
|
|
335771
335812
|
agentSpineRuntimeRecipients(pluginHooks, mcpConfig) {
|
|
335772
|
-
if (!this.experimentalFlags.enabled("agent_spine_timeline")) return void 0;
|
|
335773
335813
|
const plugin = this.plugins.get("agent-spine");
|
|
335774
335814
|
if (plugin?.state !== "ok" || !plugin.enabled) return void 0;
|
|
335775
335815
|
const hooks = pluginHooks.filter((hook) => hook.env?.["BLUN_PLUGIN_ROOT"] === plugin.root);
|