blun-king-cli 9.1.597 → 9.1.600
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 +39 -0
- package/README.md +17 -1
- package/agent-spine-plugin/CHANGELOG.md +1 -1
- package/agent-spine-plugin/docs/host-integration.md +1 -15
- package/agent-spine-plugin/docs/preflight-recall.md +1 -1
- package/agent-spine-plugin/scripts/check-install.js +1 -6
- package/agent-spine-plugin/scripts/hermetic-process.js +8 -0
- package/agent-spine-plugin/scripts/release-check.js +2 -3
- package/agent-spine-plugin/scripts/run-tests-hermetic.js +8 -11
- package/agent-spine-plugin/src/hook.js +40 -40
- package/agent-spine-plugin/src/lib/briefing.js +6 -3
- package/agent-spine-plugin/src/lib/hook-context.js +63 -64
- package/agent-spine-plugin/src/lib/hook-output.js +115 -94
- package/agent-spine-plugin/src/lib/hook-timeline.js +20 -11
- package/agent-spine-plugin/src/lib/host-instruction-budget.js +8 -14
- package/agent-spine-plugin/src/lib/mcp-timeline-tools.js +0 -7
- package/agent-spine-plugin/src/lib/pre-answer-timeline-recall.js +104 -0
- package/agent-spine-plugin/src/lib/session-timeline-codex.js +0 -4
- package/agent-spine-plugin/src/lib/session-timeline-enrollment-source.js +0 -3
- package/agent-spine-plugin/src/lib/session-timeline-enrollment-storage.js +0 -4
- package/agent-spine-plugin/src/lib/session-timeline-enrollment-transport.js +0 -2
- package/agent-spine-plugin/src/lib/session-timeline-enrollment.js +0 -22
- package/agent-spine-plugin/src/lib/session-timeline-host-origin.js +0 -4
- package/agent-spine-plugin/src/lib/session-timeline-prior.js +42 -50
- package/agent-spine-plugin/src/lib/session-timeline-provider.js +0 -3
- package/agent-spine-plugin/src/lib/session-timeline-query.js +0 -1
- package/agent-spine-plugin/src/lib/session-timeline-sid-acl.js +0 -4
- package/agent-spine-plugin/src/lib/session-timeline-source.js +0 -3
- package/agent-spine-plugin/src/lib/session-timeline-transport.js +0 -8
- package/agent-spine-plugin/src/lib/session-timeline-windows-acl.js +0 -3
- package/agent-spine-plugin/src/lib/session-timeline.js +370 -408
- package/agent-spine-plugin/src/lib/source-roots.js +26 -16
- package/agent-spine-plugin/src/lib/timeline-user-feedback.js +0 -1
- package/bin/core-bootstrap.js +18 -10
- package/bin/launcher-mode.js +5 -0
- package/bin/launcher-runtime.js +27 -0
- package/bin/verify-bundled-agent-sources.cjs +28 -2
- package/blun.mjs +798 -143
- package/bundled-agent-sources.json +192 -155
- package/package.json +1 -1
- package/standard-skills/translate-native/README.md +1334 -1
- package/standard-skills/translate-native/SKILL.md +1 -1
- package/standard-skills/translate-native/VERSION +1 -1
- package/standard-skills/translate-native/docs/PREMORTEM.md +901 -0
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION.md +208 -41
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_API.md +1319 -77
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_EVIDENCE_HTTP.md +66 -11
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_HTTP_PROVIDER.md +19 -1
- package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_RECEIPT_VERIFIER_HTTP.md +24 -6
- package/standard-skills/translate-native/integrations/commercial_localization_profile.py +23 -0
- package/standard-skills/translate-native/integrations/website_localization.py +234 -10
- package/standard-skills/translate-native/integrations/website_localization_benchmark.py +39 -3
- package/standard-skills/translate-native/integrations/website_localization_cms.py +512 -10
- package/standard-skills/translate-native/integrations/website_localization_cms_client.py +116 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_receiver.py +101 -11
- package/standard-skills/translate-native/integrations/website_localization_cms_receiver_runtime.py +12 -1
- package/standard-skills/translate-native/integrations/website_localization_cms_receiver_store.py +186 -24
- package/standard-skills/translate-native/integrations/website_localization_cms_source_client.py +64 -1
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery.py +528 -5
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_auth.py +918 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_auth_runtime.py +609 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_client.py +885 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_http.py +1244 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_runtime.py +220 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_sidecar_adapter.py +331 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_capabilities_http.py +444 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_client.py +673 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_dispatch.py +1317 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_dispatch_client.py +826 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_dispatch_http.py +1152 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_dispatch_openapi.py +896 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_dispatch_runtime.py +621 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_http.py +1180 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_submission_runtime.py +1479 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_source_http.py +133 -17
- package/standard-skills/translate-native/integrations/website_localization_cms_source_runtime.py +319 -4
- package/standard-skills/translate-native/integrations/website_localization_cms_source_service.py +72 -2
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_http.py +13 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver.py +56 -13
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver_openapi.py +335 -0
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver_runtime.py +66 -1
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_processing_monitor.py +73 -7
- package/standard-skills/translate-native/integrations/website_localization_cms_terminal_receiver_client.py +93 -9
- package/standard-skills/translate-native/integrations/website_localization_evidence_http.py +221 -11
- package/standard-skills/translate-native/integrations/website_localization_health.py +6 -0
- package/standard-skills/translate-native/integrations/website_localization_http_provider.py +1 -1
- package/standard-skills/translate-native/integrations/website_localization_quality_profiles.py +350 -0
- package/standard-skills/translate-native/integrations/website_localization_queue.py +126 -56
- package/standard-skills/translate-native/integrations/website_localization_receipt_verifier_http.py +166 -13
- package/standard-skills/translate-native/integrations/website_localization_release.py +423 -17
- package/standard-skills/translate-native/integrations/website_localization_release_coordinator.py +168 -13
- package/standard-skills/translate-native/integrations/website_localization_runner.py +10 -0
- package/standard-skills/translate-native/integrations/website_localization_worker.py +213 -9
- package/standard-skills/translate-native/provenance.json +2 -2
- package/standard-skills/translate-native/references/commercial-localization.md +96 -17
- package/standard-skills/translate-native/scripts/blun_language_guard.py +3 -1
- package/standard-skills/translate-native/scripts/check_commercial_review.py +69 -9
- package/standard-skills/translate-native/scripts/commercial_localization_profile.py +829 -31
- package/standard-tools/language-guard/VERSION +1 -1
- package/standard-tools/language-guard/blun_language_guard.py +3 -1
- package/standard-tools/language-guard/check_commercial_review.py +69 -9
- package/standard-tools/language-guard/commercial_localization_profile.py +829 -31
- package/standard-tools/language-guard/provenance.json +2 -2
- package/standard-tools/manifest.json +1 -1
- package/worker-host.mjs +215 -82
- package/agent-spine-plugin/scripts/check-install-king.js +0 -37
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:c0b3db57102f82b976cc669375212221a4788318dbd6d1bfc28e943f7bf649db
|
|
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) {
|
|
@@ -229582,7 +229582,7 @@ var FullCompaction = class {
|
|
|
229582
229582
|
this.agent.log.error("failed to refresh system prompt after compaction", { error });
|
|
229583
229583
|
}
|
|
229584
229584
|
await this.agent.injection.injectAfterCompaction();
|
|
229585
|
-
this.fitRetainedInput();
|
|
229585
|
+
this.fitRetainedInput({}, result.keptHeadUserMessageCount !== void 0);
|
|
229586
229586
|
this.lastCompactedState = {
|
|
229587
229587
|
tokenCount: this.tokenCountWithPending,
|
|
229588
229588
|
modelAlias: this.agent.activeResponderModel ?? this.agent.config.modelAlias,
|
|
@@ -229618,17 +229618,18 @@ var FullCompaction = class {
|
|
|
229618
229618
|
this.agent.turn.onCompactionFinished();
|
|
229619
229619
|
}
|
|
229620
229620
|
}
|
|
229621
|
-
fitRetainedInput(context = {}) {
|
|
229621
|
+
fitRetainedInput(context = {}, freshBudgetedSelection = false) {
|
|
229622
229622
|
const budget = this.getCompactionBudgetTokens();
|
|
229623
229623
|
const window = this.getEffectiveMaxContextTokens();
|
|
229624
229624
|
const limit = window > 0 ? window - 1 : Infinity;
|
|
229625
|
+
const hardContextLimit = window > 0 && !freshBudgetedSelection ? window : void 0;
|
|
229625
229626
|
const estimate = (messages) => this.estimateProjectedRequestTokens({
|
|
229626
229627
|
...context,
|
|
229627
229628
|
messages
|
|
229628
229629
|
});
|
|
229629
229630
|
const preserveLatestUser = this.agent.turn.hasActiveTurn;
|
|
229630
|
-
if (budget === void 0) return this.agent.context.fitCompactionPrefix(limit, estimate, preserveLatestUser);
|
|
229631
|
-
return this.agent.context.fitCompactionPrefix(Math.min(Math.floor(budget * .8), limit), estimate, preserveLatestUser) || this.agent.context.fitCompactionPrefix(Math.min(Math.floor(budget * .9) - 1, limit), estimate, preserveLatestUser);
|
|
229631
|
+
if (budget === void 0) return this.agent.context.fitCompactionPrefix(limit, estimate, preserveLatestUser, hardContextLimit);
|
|
229632
|
+
return this.agent.context.fitCompactionPrefix(Math.min(Math.floor(budget * .8), limit), estimate, preserveLatestUser, hardContextLimit) || this.agent.context.fitCompactionPrefix(Math.min(Math.floor(budget * .9) - 1, limit), estimate, preserveLatestUser, hardContextLimit);
|
|
229632
229633
|
}
|
|
229633
229634
|
buildInstruction(customInstruction) {
|
|
229634
229635
|
return renderPrompt(compaction_instruction_default, { customInstruction: customInstruction?.trim() ?? "" }).trimEnd();
|
|
@@ -233588,7 +233589,7 @@ var ContextMemory = class {
|
|
|
233588
233589
|
this.agent.microCompaction.reset();
|
|
233589
233590
|
this.agent.emitStatusUpdated();
|
|
233590
233591
|
}
|
|
233591
|
-
fitCompactionPrefix(maxRequestTokens, estimateRequest, preserveLatestUser = false) {
|
|
233592
|
+
fitCompactionPrefix(maxRequestTokens, estimateRequest, preserveLatestUser = false, hardContextLimit) {
|
|
233592
233593
|
const prefixLength = this._history.findIndex((message) => message.origin?.kind === "compaction_summary");
|
|
233593
233594
|
if (prefixLength <= 0 || !Number.isSafeInteger(maxRequestTokens) || maxRequestTokens <= 0) return false;
|
|
233594
233595
|
const suffix = this._history.slice(prefixLength);
|
|
@@ -233600,7 +233601,9 @@ var ContextMemory = class {
|
|
|
233600
233601
|
];
|
|
233601
233602
|
return Math.max(estimateTokensForMessages(messages), estimateRequest(project(messages, { dropOrphanResults: true })));
|
|
233602
233603
|
};
|
|
233603
|
-
|
|
233604
|
+
const requestTokens = estimate(this._history.slice(0, prefixLength));
|
|
233605
|
+
if (requestTokens <= maxRequestTokens) return false;
|
|
233606
|
+
if (hardContextLimit !== void 0 && requestTokens >= hardContextLimit) return false;
|
|
233604
233607
|
const sourceKey = Symbol("compaction source");
|
|
233605
233608
|
const sources = collectCompactableUserMessages(this._history.slice(0, prefixLength)).map((message) => ({
|
|
233606
233609
|
...message,
|
|
@@ -234239,7 +234242,7 @@ const OptionalStringSchema = preprocess((value) => {
|
|
|
234239
234242
|
if (typeof value === "string") return value;
|
|
234240
234243
|
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
|
|
234241
234244
|
}, string().optional());
|
|
234242
|
-
const HookSpecificOutputSchema = preprocess((value) => isRecord$
|
|
234245
|
+
const HookSpecificOutputSchema = preprocess((value) => isRecord$3(value) ? value : void 0, looseObject({
|
|
234243
234246
|
message: OptionalStringSchema,
|
|
234244
234247
|
additionalContext: OptionalStringSchema,
|
|
234245
234248
|
permissionDecision: unknown().optional(),
|
|
@@ -234391,7 +234394,7 @@ function structuredOutput(stdout, input) {
|
|
|
234391
234394
|
return {
|
|
234392
234395
|
...result,
|
|
234393
234396
|
additionalContext: input["hook_event_name"] === "UserPromptSubmit" && hookSpecificOutput?.hookEventName === "UserPromptSubmit" ? hookSpecificOutput.additionalContext : void 0,
|
|
234394
|
-
updatedInput: input["hook_event_name"] === "PreToolUse" && hookSpecificOutput?.hookEventName === "PreToolUse" && isRecord$
|
|
234397
|
+
updatedInput: input["hook_event_name"] === "PreToolUse" && hookSpecificOutput?.hookEventName === "PreToolUse" && isRecord$3(hookSpecificOutput.updatedInput) ? hookSpecificOutput.updatedInput : void 0
|
|
234395
234398
|
};
|
|
234396
234399
|
}
|
|
234397
234400
|
return {
|
|
@@ -234460,7 +234463,7 @@ function killProcessTreeWindows(child, force) {
|
|
|
234460
234463
|
} catch {}
|
|
234461
234464
|
}
|
|
234462
234465
|
}
|
|
234463
|
-
function isRecord$
|
|
234466
|
+
function isRecord$3(value) {
|
|
234464
234467
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
234465
234468
|
}
|
|
234466
234469
|
function errorMessage$3(error) {
|
|
@@ -234581,7 +234584,16 @@ var HookEngine = class {
|
|
|
234581
234584
|
};
|
|
234582
234585
|
}
|
|
234583
234586
|
if (this.admissionClosed) return void 0;
|
|
234584
|
-
|
|
234587
|
+
let hookInput;
|
|
234588
|
+
try {
|
|
234589
|
+
hookInput = this.options.runtimeInput?.(hook, inputData) ?? inputData;
|
|
234590
|
+
} catch {
|
|
234591
|
+
return {
|
|
234592
|
+
action: "block",
|
|
234593
|
+
reason: "Hook input preparation failed."
|
|
234594
|
+
};
|
|
234595
|
+
}
|
|
234596
|
+
return runHook(hook.command, hookInput, {
|
|
234585
234597
|
timeout: hook.timeout ?? DEFAULT_HOOK_TIMEOUT_SECONDS,
|
|
234586
234598
|
cwd: hook.cwd ?? (this.options.cwd === "" ? void 0 : this.options.cwd),
|
|
234587
234599
|
env: hook.env,
|
|
@@ -235816,7 +235828,7 @@ function parsePersonalMemoryRecall(output) {
|
|
|
235816
235828
|
} catch {
|
|
235817
235829
|
return { kind: "invalid" };
|
|
235818
235830
|
}
|
|
235819
|
-
if (!isRecord$
|
|
235831
|
+
if (!isRecord$2(parsed) || !isRecord$2(parsed["personal_memory"])) return { kind: "invalid" };
|
|
235820
235832
|
const memory = parsed["personal_memory"];
|
|
235821
235833
|
const savedRaw = memory["saved"];
|
|
235822
235834
|
const threadsRaw = memory["threads"];
|
|
@@ -235825,7 +235837,7 @@ function parsePersonalMemoryRecall(output) {
|
|
|
235825
235837
|
if (savedRaw.length > MAX_SAVED_MEMORIES || threadsRaw.length > MAX_THREADS || historyRaw.length > 0) return { kind: "invalid" };
|
|
235826
235838
|
const saved = [];
|
|
235827
235839
|
for (const value of savedRaw) {
|
|
235828
|
-
if (!isRecord$
|
|
235840
|
+
if (!isRecord$2(value)) return { kind: "invalid" };
|
|
235829
235841
|
const text = boundedTrimmedString(value["text"], MAX_MEMORY_TEXT_CHARS);
|
|
235830
235842
|
const confidence = value["confidence"];
|
|
235831
235843
|
if (text === void 0 || typeof confidence !== "string" || !CONFIDENCE_VALUES.has(confidence)) return { kind: "invalid" };
|
|
@@ -235836,7 +235848,7 @@ function parsePersonalMemoryRecall(output) {
|
|
|
235836
235848
|
}
|
|
235837
235849
|
const threads = [];
|
|
235838
235850
|
for (const value of threadsRaw) {
|
|
235839
|
-
if (!isRecord$
|
|
235851
|
+
if (!isRecord$2(value)) return { kind: "invalid" };
|
|
235840
235852
|
const title = boundedTrimmedString(value["title"], MAX_THREAD_TITLE_CHARS);
|
|
235841
235853
|
const summary = boundedTrimmedString(value["summary"], MAX_THREAD_SUMMARY_CHARS);
|
|
235842
235854
|
if (title === void 0 || summary === void 0) return { kind: "invalid" };
|
|
@@ -235890,7 +235902,7 @@ function boundedTrimmedString(value, maxChars) {
|
|
|
235890
235902
|
const trimmed = value.trim();
|
|
235891
235903
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
235892
235904
|
}
|
|
235893
|
-
function isRecord$
|
|
235905
|
+
function isRecord$2(value) {
|
|
235894
235906
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
235895
235907
|
}
|
|
235896
235908
|
//#endregion
|
|
@@ -264047,10 +264059,70 @@ function rejectionMessage(value) {
|
|
|
264047
264059
|
return `Response review rejected candidate: ${value.stage}/${value.reason}` + (findings?.length ? ` (${findings.join(", ")})` : "");
|
|
264048
264060
|
}
|
|
264049
264061
|
//#endregion
|
|
264062
|
+
//#region ../../packages/agent-core/src/agent/response-review-deadline.ts
|
|
264063
|
+
const IDLE_TIMEOUT_MS = 3e4;
|
|
264064
|
+
const NATIVE_FIRST_CONTENT_MS = 9e4;
|
|
264065
|
+
const ABSOLUTE_TIMEOUT_MS = 12e4;
|
|
264066
|
+
function createResponseReviewDeadline(source) {
|
|
264067
|
+
const absoluteExpiresAt = performance.now() + ABSOLUTE_TIMEOUT_MS;
|
|
264068
|
+
const absolute = createDeadlineAbortSignal(source, ABSOLUTE_TIMEOUT_MS);
|
|
264069
|
+
const controller = new AbortController();
|
|
264070
|
+
const unlink = linkAbortSignal(absolute.signal, controller);
|
|
264071
|
+
let stage = "setup";
|
|
264072
|
+
let didTimeout = false;
|
|
264073
|
+
let closed = false;
|
|
264074
|
+
let idle;
|
|
264075
|
+
let idleExpiresAt = 0;
|
|
264076
|
+
const expire = () => {
|
|
264077
|
+
didTimeout = true;
|
|
264078
|
+
controller.abort(abortError());
|
|
264079
|
+
};
|
|
264080
|
+
const expireIfDue = () => {
|
|
264081
|
+
if (closed || controller.signal.aborted) return;
|
|
264082
|
+
const now = performance.now();
|
|
264083
|
+
if (now >= absoluteExpiresAt || now >= idleExpiresAt) expire();
|
|
264084
|
+
};
|
|
264085
|
+
const refresh = (timeoutMs) => {
|
|
264086
|
+
idleExpiresAt = performance.now() + timeoutMs;
|
|
264087
|
+
if (idle !== void 0) clearTimeout(idle);
|
|
264088
|
+
idle = setTimeout(expire, timeoutMs);
|
|
264089
|
+
};
|
|
264090
|
+
refresh(IDLE_TIMEOUT_MS);
|
|
264091
|
+
return {
|
|
264092
|
+
signal: controller.signal,
|
|
264093
|
+
timedOut: () => didTimeout || absolute.timedOut(),
|
|
264094
|
+
throwIfAborted: () => {
|
|
264095
|
+
expireIfDue();
|
|
264096
|
+
controller.signal.throwIfAborted();
|
|
264097
|
+
},
|
|
264098
|
+
progress: (event) => {
|
|
264099
|
+
expireIfDue();
|
|
264100
|
+
if (closed || controller.signal.aborted) return;
|
|
264101
|
+
if (event === "native.start" && stage === "setup") {
|
|
264102
|
+
stage = "native";
|
|
264103
|
+
refresh(NATIVE_FIRST_CONTENT_MS);
|
|
264104
|
+
} else if (event === "native.text" && stage === "native") refresh(IDLE_TIMEOUT_MS);
|
|
264105
|
+
else if (event === "release.start" && stage === "native") {
|
|
264106
|
+
stage = "release";
|
|
264107
|
+
refresh(IDLE_TIMEOUT_MS);
|
|
264108
|
+
} else if (event === "verification.start" && stage === "release") {
|
|
264109
|
+
stage = "verification";
|
|
264110
|
+
refresh(IDLE_TIMEOUT_MS);
|
|
264111
|
+
}
|
|
264112
|
+
},
|
|
264113
|
+
clear: () => {
|
|
264114
|
+
closed = true;
|
|
264115
|
+
if (idle !== void 0) clearTimeout(idle);
|
|
264116
|
+
idle = void 0;
|
|
264117
|
+
unlink();
|
|
264118
|
+
absolute.clear();
|
|
264119
|
+
}
|
|
264120
|
+
};
|
|
264121
|
+
}
|
|
264122
|
+
//#endregion
|
|
264050
264123
|
//#region ../../packages/agent-core/src/agent/response-review.ts
|
|
264051
264124
|
const MAX_CANDIDATE_BYTES = 1048576;
|
|
264052
264125
|
const MAX_CANDIDATE_PARTS = 4096;
|
|
264053
|
-
const REVIEW_TIMEOUT_MS = 3e4;
|
|
264054
264126
|
const REVIEW_CANCEL_SETTLE_MS = 1e3;
|
|
264055
264127
|
const MAX_REVIEW_ATTEMPTS = 2;
|
|
264056
264128
|
function createReviewedOutputDispatcher(options) {
|
|
@@ -264137,6 +264209,7 @@ function createReviewedOutputDispatcher(options) {
|
|
|
264137
264209
|
if (pending.length === 0) return options.dispatch(event);
|
|
264138
264210
|
if (event.uuid !== stepUuid) throw new Error("Response review step mismatch");
|
|
264139
264211
|
const currentEpoch = epoch;
|
|
264212
|
+
const isCurrentCandidate = () => epoch === currentEpoch;
|
|
264140
264213
|
const parts = [...pending];
|
|
264141
264214
|
reviewing = true;
|
|
264142
264215
|
const text = parts.map((part) => part.part.type === "text" ? part.part.text : "").join("");
|
|
@@ -264150,8 +264223,9 @@ function createReviewedOutputDispatcher(options) {
|
|
|
264150
264223
|
for (let attempt = 1; attempt <= MAX_REVIEW_ATTEMPTS; attempt += 1) {
|
|
264151
264224
|
options.signal.throwIfAborted();
|
|
264152
264225
|
if (epoch !== currentEpoch) throw new Error("Response review candidate changed during verification");
|
|
264153
|
-
const deadline =
|
|
264226
|
+
const deadline = createResponseReviewDeadline(options.signal);
|
|
264154
264227
|
let requested;
|
|
264228
|
+
const pendingOperations = [];
|
|
264155
264229
|
let attemptRejection;
|
|
264156
264230
|
let attemptNativeRejection = false;
|
|
264157
264231
|
try {
|
|
@@ -264160,6 +264234,12 @@ function createReviewedOutputDispatcher(options) {
|
|
|
264160
264234
|
turnId: event.turnId,
|
|
264161
264235
|
step: event.step,
|
|
264162
264236
|
signal: deadline.signal,
|
|
264237
|
+
onProgress: (progress) => {
|
|
264238
|
+
if (isCurrentCandidate()) deadline.progress(progress);
|
|
264239
|
+
},
|
|
264240
|
+
onPendingOperation: (operation) => {
|
|
264241
|
+
pendingOperations.push(operation.then(() => void 0, () => void 0));
|
|
264242
|
+
},
|
|
264163
264243
|
onRejected: (decision) => {
|
|
264164
264244
|
if (!deadline.signal.aborted) {
|
|
264165
264245
|
const message = rejectionMessage(decision);
|
|
@@ -264169,13 +264249,14 @@ function createReviewedOutputDispatcher(options) {
|
|
|
264169
264249
|
}
|
|
264170
264250
|
});
|
|
264171
264251
|
approval = await abortable(requested, deadline.signal);
|
|
264252
|
+
deadline.throwIfAborted();
|
|
264172
264253
|
rejection = attemptRejection;
|
|
264173
264254
|
nativeRejection = attemptNativeRejection;
|
|
264174
264255
|
break;
|
|
264175
264256
|
} catch {
|
|
264176
264257
|
options.signal.throwIfAborted();
|
|
264177
264258
|
if (attemptRejection !== void 0) throw new Error(attemptRejection);
|
|
264178
|
-
if (deadline.timedOut() && attempt < MAX_REVIEW_ATTEMPTS && requested !== void 0 && epoch === currentEpoch && await waitForCancelledReview(requested)) continue;
|
|
264259
|
+
if (deadline.timedOut() && attempt < MAX_REVIEW_ATTEMPTS && requested !== void 0 && epoch === currentEpoch && await waitForCancelledReview(requested, pendingOperations)) continue;
|
|
264179
264260
|
throw new Error(deadline.timedOut() ? "Response review timed out" : "Response review failed");
|
|
264180
264261
|
} finally {
|
|
264181
264262
|
deadline.clear();
|
|
@@ -264212,10 +264293,16 @@ function createReviewedOutputDispatcher(options) {
|
|
|
264212
264293
|
if (epoch === currentEpoch) clear();
|
|
264213
264294
|
}
|
|
264214
264295
|
}
|
|
264215
|
-
async function waitForCancelledReview(requested) {
|
|
264296
|
+
async function waitForCancelledReview(requested, pendingOperations) {
|
|
264216
264297
|
const deadline = createDeadlineAbortSignal(options.signal, REVIEW_CANCEL_SETTLE_MS);
|
|
264217
264298
|
try {
|
|
264218
264299
|
await abortable(requested.then(() => void 0, () => void 0), deadline.signal);
|
|
264300
|
+
let observed = 0;
|
|
264301
|
+
while (observed < pendingOperations.length) {
|
|
264302
|
+
const batch = pendingOperations.slice(observed);
|
|
264303
|
+
observed = pendingOperations.length;
|
|
264304
|
+
await abortable(Promise.all(batch), deadline.signal);
|
|
264305
|
+
}
|
|
264219
264306
|
options.signal.throwIfAborted();
|
|
264220
264307
|
return true;
|
|
264221
264308
|
} catch {
|
|
@@ -268200,12 +268287,14 @@ function readPayload(result, includeError = false) {
|
|
|
268200
268287
|
/** Receipts never enter ordinary tool execution, hooks, replay or model history. */
|
|
268201
268288
|
function createGuardResponseReviewer(host) {
|
|
268202
268289
|
const { language, guardVersion } = host;
|
|
268203
|
-
return async ({ text, turnId, step, signal, onRejected }) => {
|
|
268290
|
+
return async ({ text, turnId, step, signal, onRejected, onPendingOperation, onProgress }) => {
|
|
268204
268291
|
const input = {
|
|
268205
268292
|
text,
|
|
268206
268293
|
turnId,
|
|
268207
268294
|
step,
|
|
268208
|
-
signal
|
|
268295
|
+
signal,
|
|
268296
|
+
onPendingOperation,
|
|
268297
|
+
onProgress
|
|
268209
268298
|
};
|
|
268210
268299
|
const targetSha256 = digest(text);
|
|
268211
268300
|
let stage = "setup";
|
|
@@ -268232,6 +268321,10 @@ function createGuardResponseReviewer(host) {
|
|
|
268232
268321
|
const blocked = (reason, findings) => {
|
|
268233
268322
|
record(signal.aborted ? "cancelled" : reason, findings);
|
|
268234
268323
|
};
|
|
268324
|
+
const track = (operation) => {
|
|
268325
|
+
onPendingOperation?.(operation.then(() => void 0, () => void 0));
|
|
268326
|
+
return operation;
|
|
268327
|
+
};
|
|
268235
268328
|
try {
|
|
268236
268329
|
if (!/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/.test(language) || /^(auto|all)$/i.test(language) || guardVersion.trim().length === 0) return blocked("invalid_settings");
|
|
268237
268330
|
const resolve = () => {
|
|
@@ -268244,13 +268337,14 @@ function createGuardResponseReviewer(host) {
|
|
|
268244
268337
|
const current = () => !signal.aborted && resolve()?.client === connection.client;
|
|
268245
268338
|
if (!current()) return blocked("connection_changed");
|
|
268246
268339
|
stage = "native";
|
|
268247
|
-
|
|
268340
|
+
onProgress?.("native.start");
|
|
268341
|
+
const native = await abortable(track(host.reviewNative({ ...input })), signal);
|
|
268248
268342
|
if (!current()) return blocked("connection_changed");
|
|
268249
268343
|
if (native === void 0) return blocked("native_unavailable");
|
|
268250
268344
|
if (!passed(native.nativeness) || !passed(native.orthography)) return blocked("native_rejected");
|
|
268251
268345
|
const authorized = async (name) => {
|
|
268252
268346
|
if (!current()) return false;
|
|
268253
|
-
return passed(await abortable(host.authorize({
|
|
268347
|
+
return passed(await abortable(track(host.authorize({
|
|
268254
268348
|
toolName: qualifyMcpToolName(SERVER_NAME, name),
|
|
268255
268349
|
targetSha256,
|
|
268256
268350
|
language,
|
|
@@ -268259,11 +268353,12 @@ function createGuardResponseReviewer(host) {
|
|
|
268259
268353
|
turnId,
|
|
268260
268354
|
step,
|
|
268261
268355
|
signal
|
|
268262
|
-
}), signal)) && current();
|
|
268356
|
+
})), signal)) && current();
|
|
268263
268357
|
};
|
|
268264
268358
|
stage = "release";
|
|
268359
|
+
onProgress?.("release.start");
|
|
268265
268360
|
if (!await authorized("release_response")) return blocked("release_denied");
|
|
268266
|
-
const releaseResult = await abortable(connection.client.callTool("release_response", {
|
|
268361
|
+
const releaseResult = await abortable(track(connection.client.callTool("release_response", {
|
|
268267
268362
|
target_text: text,
|
|
268268
268363
|
language,
|
|
268269
268364
|
content_type: "prose",
|
|
@@ -268272,7 +268367,7 @@ function createGuardResponseReviewer(host) {
|
|
|
268272
268367
|
nativeness: true,
|
|
268273
268368
|
orthography: true
|
|
268274
268369
|
}
|
|
268275
|
-
}, signal), signal);
|
|
268370
|
+
}, signal)), signal);
|
|
268276
268371
|
if (!current()) return blocked("connection_changed");
|
|
268277
268372
|
if (releaseResult.isError) return blocked("release_rejected", rejectionFindings(readPayload(releaseResult, true)));
|
|
268278
268373
|
const released = readPayload(releaseResult);
|
|
@@ -268280,8 +268375,9 @@ function createGuardResponseReviewer(host) {
|
|
|
268280
268375
|
if (!current()) return blocked("connection_changed");
|
|
268281
268376
|
if (status !== "PASS" || release_allowed !== true || blocking === true || typeof release_token !== "string" || release_token.length === 0 || release_token.length > 65536) return blocked("release_rejected", rejectionFindings(released));
|
|
268282
268377
|
stage = "verification";
|
|
268378
|
+
onProgress?.("verification.start");
|
|
268283
268379
|
if (!await authorized("verify_release_token")) return blocked("verification_denied");
|
|
268284
|
-
const { status: verificationStatus, valid, checks, payload } = readPayload(await abortable(connection.client.callTool("verify_release_token", {
|
|
268380
|
+
const { status: verificationStatus, valid, checks, payload } = readPayload(await abortable(track(connection.client.callTool("verify_release_token", {
|
|
268285
268381
|
release_token,
|
|
268286
268382
|
source_text: "",
|
|
268287
268383
|
target_text: text,
|
|
@@ -268289,7 +268385,7 @@ function createGuardResponseReviewer(host) {
|
|
|
268289
268385
|
purpose: "response",
|
|
268290
268386
|
content_type: "prose",
|
|
268291
268387
|
short_text_reviewed: false
|
|
268292
|
-
}, signal), signal)) ?? {};
|
|
268388
|
+
}, signal)), signal)) ?? {};
|
|
268293
268389
|
if (!current()) return blocked("connection_changed");
|
|
268294
268390
|
if (verificationStatus !== "PASS" || valid !== true || !isPlainRecord(checks) || !CHECK_NAMES.every((name) => checks[name] === true) || !isPlainRecord(payload)) return blocked("verification_rejected");
|
|
268295
268391
|
const { v, source_sha256, target_sha256, language: verifiedLanguage, purpose, content_type, short_text_reviewed, exp, iat } = payload;
|
|
@@ -268369,6 +268465,9 @@ async function reviewNativeResponse(agent, language, input) {
|
|
|
268369
268465
|
};
|
|
268370
268466
|
const options = {
|
|
268371
268467
|
signal,
|
|
268468
|
+
onExecution: (completion) => {
|
|
268469
|
+
input.onPendingOperation?.(completion.then(() => void 0, () => void 0));
|
|
268470
|
+
},
|
|
268372
268471
|
requestLogFields: {
|
|
268373
268472
|
turnStep: `review:${input.turnId}.${String(input.step)}`,
|
|
268374
268473
|
attempt: `${attempt}/2`
|
|
@@ -268377,13 +268476,16 @@ async function reviewNativeResponse(agent, language, input) {
|
|
|
268377
268476
|
const prompt = attempt === 1 ? NATIVE_REVIEW_PROMPT : `${NATIVE_REVIEW_PROMPT}\nThe previous review did not satisfy the required JSON format. Return exactly one object with the two required boolean keys nativeness and orthography, no wrapper or additional keys. Use true or false, not strings or null. Set a check to false if it fails or you are uncertain.`;
|
|
268378
268477
|
try {
|
|
268379
268478
|
signal.throwIfAborted();
|
|
268380
|
-
const
|
|
268479
|
+
const requested = agent.generate(provider, prompt, [], [createUserMessage(candidateMessage)], { onMessagePart: (part) => {
|
|
268381
268480
|
if (part.type === "text") receivedBytes += Buffer.byteLength(part.text);
|
|
268382
268481
|
if (receivedBytes > MAX_REVIEW_RESULT_BYTES) {
|
|
268383
268482
|
outputLimitExceeded = true;
|
|
268384
268483
|
throw new Error("Native review output exceeds limit");
|
|
268385
268484
|
}
|
|
268386
|
-
|
|
268485
|
+
if (!signal.aborted && part.type === "text" && part.text.trim().length > 0) input.onProgress?.("native.text");
|
|
268486
|
+
} }, options);
|
|
268487
|
+
input.onPendingOperation?.(requested.then(() => void 0, () => void 0));
|
|
268488
|
+
const response = await abortable(requested, signal);
|
|
268387
268489
|
if (response.usage !== null) agent.usage.record(modelAlias, response.usage, "turn");
|
|
268388
268490
|
signal.throwIfAborted();
|
|
268389
268491
|
if (response.message.toolCalls.length > 0) return invalid("tool_calls");
|
|
@@ -299939,6 +300041,36 @@ function mergeCallerMcpServers(base, callerServers) {
|
|
|
299939
300041
|
}
|
|
299940
300042
|
//#endregion
|
|
299941
300043
|
//#region ../../packages/agent-core/src/plugin/agent-spine-runtime.ts
|
|
300044
|
+
const PROMPT_EVENTS = new Set([
|
|
300045
|
+
"UserPromptSubmit",
|
|
300046
|
+
"TurnStart",
|
|
300047
|
+
"SubagentStart"
|
|
300048
|
+
]);
|
|
300049
|
+
/** AgentSpine reads prompt text; binary media stays in the original model input. */
|
|
300050
|
+
function projectAgentSpinePrompt(input) {
|
|
300051
|
+
if (typeof input["hook_event_name"] !== "string" || !PROMPT_EVENTS.has(input["hook_event_name"]) || !Array.isArray(input["prompt"])) return input;
|
|
300052
|
+
let changed = false;
|
|
300053
|
+
const prompt = input["prompt"].map((part) => {
|
|
300054
|
+
if (!isRecord$1(part)) return part;
|
|
300055
|
+
const field = part["type"] === "image_url" ? "imageUrl" : part["type"] === "audio_url" ? "audioUrl" : part["type"] === "video_url" ? "videoUrl" : void 0;
|
|
300056
|
+
if (field === void 0 || !isRecord$1(part[field]) || typeof part[field]["url"] !== "string") return part;
|
|
300057
|
+
const serialized = JSON.stringify(part);
|
|
300058
|
+
changed = true;
|
|
300059
|
+
return {
|
|
300060
|
+
type: "media_reference",
|
|
300061
|
+
media_type: part["type"],
|
|
300062
|
+
sha256: createHash("sha256").update(serialized).digest("hex"),
|
|
300063
|
+
original_bytes: Buffer.byteLength(serialized)
|
|
300064
|
+
};
|
|
300065
|
+
});
|
|
300066
|
+
return changed ? {
|
|
300067
|
+
...input,
|
|
300068
|
+
prompt
|
|
300069
|
+
} : input;
|
|
300070
|
+
}
|
|
300071
|
+
function isRecord$1(value) {
|
|
300072
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
300073
|
+
}
|
|
299942
300074
|
const EMPTY_RUNTIME = Object.freeze({
|
|
299943
300075
|
AGENTSPINE_KING_TIMELINE_SOURCE: "",
|
|
299944
300076
|
AGENTSPINE_KING_WIRE_PROTOCOL_VERSION: "",
|
|
@@ -300485,9 +300617,11 @@ var Session$1 = class {
|
|
|
300485
300617
|
this.experimentalFlags = options.experimentalFlags ?? new FlagResolver();
|
|
300486
300618
|
this.agentSpineRuntime = this.experimentalFlags.enabled("agent_spine_timeline") ? new AgentSpineSessionRuntime(options.agentSpineRuntime) : void 0;
|
|
300487
300619
|
this.visionReader = (this.experimentalFlags.enabled("vision_reader") ? createVisionReader(options.config?.services?.visionReader) : void 0) ?? createManagedMediaVisionReader(options.toolServices?.media);
|
|
300620
|
+
const agentSpineHooks = new Set(options.agentSpineRuntime?.hooks);
|
|
300488
300621
|
this.hookEngine = new HookEngine(options.hooks, {
|
|
300489
300622
|
cwd: options.kaos.getcwd(),
|
|
300490
300623
|
sessionId: options.id,
|
|
300624
|
+
runtimeInput: (hook, input) => agentSpineHooks.has(hook) ? projectAgentSpinePrompt(input) : input,
|
|
300491
300625
|
runtimeEnv: (hook) => {
|
|
300492
300626
|
const hostEnv = options.hookRuntimeEnv?.(hook);
|
|
300493
300627
|
const timelineEnv = this.agentSpineRuntime?.forHook(hook);
|
|
@@ -335769,7 +335903,6 @@ var BlunCore = class {
|
|
|
335769
335903
|
};
|
|
335770
335904
|
}
|
|
335771
335905
|
agentSpineRuntimeRecipients(pluginHooks, mcpConfig) {
|
|
335772
|
-
if (!this.experimentalFlags.enabled("agent_spine_timeline")) return void 0;
|
|
335773
335906
|
const plugin = this.plugins.get("agent-spine");
|
|
335774
335907
|
if (plugin?.state !== "ok" || !plugin.enabled) return void 0;
|
|
335775
335908
|
const hooks = pluginHooks.filter((hook) => hook.env?.["BLUN_PLUGIN_ROOT"] === plugin.root);
|