@eddyskywalker/dsh-chatgpt-subscription 0.3.4 → 0.3.6
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 +13 -0
- package/README.md +10 -7
- package/lib/client.js +13 -2
- package/lib/client.js.map +1 -1
- package/lib/index.js +682 -151
- package/lib/types/client/CodexComposerQuota.d.ts +1 -1
- package/lib/types/client/CodexComposerQuota.d.ts.map +1 -1
- package/lib/types/client/antigravity/AntigravityComposerQuota.d.ts +1 -1
- package/lib/types/client/antigravity/AntigravityComposerQuota.d.ts.map +1 -1
- package/lib/types/client/command-code/CommandCodeComposerQuota.d.ts +1 -1
- package/lib/types/client/command-code/CommandCodeComposerQuota.d.ts.map +1 -1
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/kimi-code/KimiCodeComposerQuota.d.ts +1 -1
- package/lib/types/client/kimi-code/KimiCodeComposerQuota.d.ts.map +1 -1
- package/lib/types/client/store.d.ts +19 -0
- package/lib/types/client/store.d.ts.map +1 -0
- package/lib/types/host/preset-sync.d.ts +41 -2
- package/lib/types/host/preset-sync.d.ts.map +1 -1
- package/lib/types/host/routes.d.ts +4 -1
- package/lib/types/host/routes.d.ts.map +1 -1
- package/lib/types/host/subagent-model-authorization.d.ts +114 -4
- package/lib/types/host/subagent-model-authorization.d.ts.map +1 -1
- package/lib/types/host/subagent-route-audit.d.ts +142 -0
- package/lib/types/host/subagent-route-audit.d.ts.map +1 -0
- package/lib/types/index.d.ts +11 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/contracts.d.ts +22 -1
- package/lib/types/shared/contracts.d.ts.map +1 -1
- package/package.json +29 -30
- package/presets/dispatch/agent.cordis.yml +13 -5
package/lib/index.js
CHANGED
|
@@ -3169,7 +3169,7 @@ function identityKey(credentials) {
|
|
|
3169
3169
|
//#endregion
|
|
3170
3170
|
//#region src/host/routes.ts
|
|
3171
3171
|
const MAX_BODY_BYTES$2 = 64 * 1024;
|
|
3172
|
-
function registerRoutes(ctx, oauth, usage, preferences, proxyManager, searchSwitcher) {
|
|
3172
|
+
function registerRoutes(ctx, oauth, usage, preferences, proxyManager, searchSwitcher, routeAudit) {
|
|
3173
3173
|
const handler = async (request, response) => {
|
|
3174
3174
|
const url = new URL(request.url ?? "/", "http://dsh.local");
|
|
3175
3175
|
if (request.method === "GET" && url.pathname === `/api/dsh-chatgpt-subscription/status`) {
|
|
@@ -3187,6 +3187,32 @@ function registerRoutes(ctx, oauth, usage, preferences, proxyManager, searchSwit
|
|
|
3187
3187
|
});
|
|
3188
3188
|
return;
|
|
3189
3189
|
}
|
|
3190
|
+
if (request.method === "GET" && url.pathname === `/api/dsh-chatgpt-subscription/subagent-route-audit`) {
|
|
3191
|
+
const sessionId = url.searchParams.get("sessionId");
|
|
3192
|
+
if (sessionId === null || sessionId.length === 0) {
|
|
3193
|
+
jsonError(response, 400, {
|
|
3194
|
+
code: "bad-request",
|
|
3195
|
+
message: "A sessionId query parameter is required."
|
|
3196
|
+
});
|
|
3197
|
+
return;
|
|
3198
|
+
}
|
|
3199
|
+
if (routeAudit === void 0) {
|
|
3200
|
+
jsonError(response, 404, {
|
|
3201
|
+
code: "route-audit-failed",
|
|
3202
|
+
message: "Subagent route audit is not installed."
|
|
3203
|
+
});
|
|
3204
|
+
return;
|
|
3205
|
+
}
|
|
3206
|
+
try {
|
|
3207
|
+
json(response, {
|
|
3208
|
+
ok: true,
|
|
3209
|
+
value: await routeAudit(sessionId)
|
|
3210
|
+
});
|
|
3211
|
+
} catch (error) {
|
|
3212
|
+
jsonError(response, 500, publicError(error instanceof Error ? error : /* @__PURE__ */ new Error("The route audit failed."), "route-audit-failed"));
|
|
3213
|
+
}
|
|
3214
|
+
return;
|
|
3215
|
+
}
|
|
3190
3216
|
if (request.method === "GET" && url.pathname === `/api/dsh-chatgpt-subscription/mermaid.min.js`) {
|
|
3191
3217
|
try {
|
|
3192
3218
|
const mermaidPath = createRequire(import.meta.url).resolve("mermaid/dist/mermaid.min.js");
|
|
@@ -5255,7 +5281,7 @@ function sanitizeText$2(text) {
|
|
|
5255
5281
|
function isRecord$4(value) {
|
|
5256
5282
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5257
5283
|
}
|
|
5258
|
-
function asString$
|
|
5284
|
+
function asString$6(value) {
|
|
5259
5285
|
return typeof value === "string" ? value : void 0;
|
|
5260
5286
|
}
|
|
5261
5287
|
function safeJsonParse$2(text) {
|
|
@@ -5285,7 +5311,7 @@ function attachmentOf$2(block) {
|
|
|
5285
5311
|
}
|
|
5286
5312
|
function attachmentLabel$2(block) {
|
|
5287
5313
|
const attachment = isRecord$4(block.attachment) ? block.attachment : void 0;
|
|
5288
|
-
return asString$
|
|
5314
|
+
return asString$6(attachment?.name) || asString$6(attachment?.attachmentId);
|
|
5289
5315
|
}
|
|
5290
5316
|
function collectImageRefs$2(content, refs) {
|
|
5291
5317
|
if (!Array.isArray(content)) return;
|
|
@@ -5324,7 +5350,7 @@ function base64Length$2(bytes) {
|
|
|
5324
5350
|
function requestImageBytes$2(block) {
|
|
5325
5351
|
const attachment = attachmentOf$2(block);
|
|
5326
5352
|
if (attachment) return base64Length$2(attachment.bytes);
|
|
5327
|
-
const inline = asString$
|
|
5353
|
+
const inline = asString$6(block.data) || asString$6(block.base64);
|
|
5328
5354
|
return inline ? inline.length : void 0;
|
|
5329
5355
|
}
|
|
5330
5356
|
function collectRequestImageBytes$2(content, lengths) {
|
|
@@ -5428,10 +5454,10 @@ function unavailableImageText$2(block) {
|
|
|
5428
5454
|
return `[image unavailable: ${label ? `${label} could not be read` : "the image could not be read"}; ask the user to attach it again if the image is needed]`;
|
|
5429
5455
|
}
|
|
5430
5456
|
function imageBlockToPart(block, images) {
|
|
5431
|
-
let data = asString$
|
|
5457
|
+
let data = asString$6(block.data) || asString$6(block.base64);
|
|
5432
5458
|
const source = isRecord$4(block.source) ? block.source : void 0;
|
|
5433
|
-
if (!data && source) data = asString$
|
|
5434
|
-
let mimeType = asString$
|
|
5459
|
+
if (!data && source) data = asString$6(source.data) || asString$6(source.base64);
|
|
5460
|
+
let mimeType = asString$6(block.mimeType) || asString$6(block.mediaType) || (source ? asString$6(source.mimeType) || asString$6(source.mediaType) : void 0) || "image/png";
|
|
5435
5461
|
if (data?.startsWith("data:")) {
|
|
5436
5462
|
const match = data.match(/^data:([^;,]+);base64,(.*)$/s);
|
|
5437
5463
|
if (match) {
|
|
@@ -5487,7 +5513,7 @@ function replayBlockFor(message, index) {
|
|
|
5487
5513
|
}
|
|
5488
5514
|
}
|
|
5489
5515
|
function thoughtSignature(part) {
|
|
5490
|
-
return asString$
|
|
5516
|
+
return asString$6(part?.thoughtSignature) || asString$6(part?.thought_signature) || asString$6(part?.thinkingSignature) || asString$6(part?.textSignature);
|
|
5491
5517
|
}
|
|
5492
5518
|
function replayPart(part) {
|
|
5493
5519
|
const copy = { ...part };
|
|
@@ -5506,7 +5532,7 @@ function assistantParts(message, model, runtimeModel, toolCalls) {
|
|
|
5506
5532
|
if (!isRecord$4(block)) continue;
|
|
5507
5533
|
const replay = replayBlockFor(message, index);
|
|
5508
5534
|
const originalParts = Array.isArray(replay?.parts) ? replay.parts.filter(isRecord$4) : [];
|
|
5509
|
-
if ((block.type === "text" || block.type === "reasoning") && originalParts.length > 0 && originalParts.every((part) => !part.functionCall) && originalParts.map((part) => asString$
|
|
5535
|
+
if ((block.type === "text" || block.type === "reasoning") && originalParts.length > 0 && originalParts.every((part) => !part.functionCall) && originalParts.map((part) => asString$6(part.text) || "").join("") === sanitizeText$2(String(block.text || ""))) {
|
|
5510
5536
|
parts.push(...originalParts.map(replayPart));
|
|
5511
5537
|
continue;
|
|
5512
5538
|
}
|
|
@@ -5527,7 +5553,7 @@ function assistantParts(message, model, runtimeModel, toolCalls) {
|
|
|
5527
5553
|
const toolId = String(block.id || "");
|
|
5528
5554
|
const toolName = String(block.name || "");
|
|
5529
5555
|
const originalCall = originalParts.find((part) => isRecord$4(part.functionCall));
|
|
5530
|
-
const wireId = asString$
|
|
5556
|
+
const wireId = asString$6((isRecord$4(originalCall?.functionCall) ? originalCall.functionCall : void 0)?.id) || (toolCallIdNeeded(model.id, runtimeModel) ? sanitizeToolCallId(toolId, toolName) : originalCall ? void 0 : toolId || void 0);
|
|
5531
5557
|
toolCalls.set(toolId, {
|
|
5532
5558
|
name: toolName,
|
|
5533
5559
|
id: wireId
|
|
@@ -5804,8 +5830,8 @@ function processStreamLine(line, state) {
|
|
|
5804
5830
|
if (isRecord$4(part.functionCall)) {
|
|
5805
5831
|
out.push(...closeCurrentBlock(state));
|
|
5806
5832
|
const fc = part.functionCall;
|
|
5807
|
-
const toolName = asString$
|
|
5808
|
-
const toolId = asString$
|
|
5833
|
+
const toolName = asString$6(fc.name) || "";
|
|
5834
|
+
const toolId = asString$6(fc.id) || sanitizeToolCallId("", toolName);
|
|
5809
5835
|
const argsText = JSON.stringify(isRecord$4(fc.args) ? fc.args : {});
|
|
5810
5836
|
const index = state.blocks.length;
|
|
5811
5837
|
const block = {
|
|
@@ -5843,7 +5869,7 @@ function processStreamLine(line, state) {
|
|
|
5843
5869
|
}
|
|
5844
5870
|
collectUsage(chunk.usageMetadata, state);
|
|
5845
5871
|
if (responseData !== chunk) collectUsage(responseData.usageMetadata, state);
|
|
5846
|
-
const finishReason = asString$
|
|
5872
|
+
const finishReason = asString$6(candidate?.finishReason) || asString$6(responseData.finishReason);
|
|
5847
5873
|
if (finishReason) {
|
|
5848
5874
|
state.finishReason = finishReason;
|
|
5849
5875
|
out.push(...closeCurrentBlock(state));
|
|
@@ -7528,10 +7554,10 @@ function timeoutSignal$1(signal, ms) {
|
|
|
7528
7554
|
function isRecord$3(value) {
|
|
7529
7555
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7530
7556
|
}
|
|
7531
|
-
function asRecord$
|
|
7557
|
+
function asRecord$4(value) {
|
|
7532
7558
|
return isRecord$3(value) ? value : void 0;
|
|
7533
7559
|
}
|
|
7534
|
-
function asString$
|
|
7560
|
+
function asString$5(value) {
|
|
7535
7561
|
if (typeof value === "string" && value.trim() !== "") return value;
|
|
7536
7562
|
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
7537
7563
|
}
|
|
@@ -7544,7 +7570,7 @@ function asNumber$1(value) {
|
|
|
7544
7570
|
}
|
|
7545
7571
|
function firstString$1(record, keys) {
|
|
7546
7572
|
for (const key of keys) {
|
|
7547
|
-
const value = asString$
|
|
7573
|
+
const value = asString$5(record[key]);
|
|
7548
7574
|
if (value !== void 0) return value;
|
|
7549
7575
|
}
|
|
7550
7576
|
}
|
|
@@ -7598,16 +7624,16 @@ const ORG_KEYS = [
|
|
|
7598
7624
|
];
|
|
7599
7625
|
/** Map `/alpha/whoami` (or a stored key's own facts) onto the public account DTO. */
|
|
7600
7626
|
function parseWhoami(payload, fallback = {}) {
|
|
7601
|
-
const root = asRecord$
|
|
7602
|
-
const data = asRecord$
|
|
7603
|
-
const user = asRecord$
|
|
7604
|
-
const org = asRecord$
|
|
7605
|
-
const key = asRecord$
|
|
7627
|
+
const root = asRecord$4(payload) ?? {};
|
|
7628
|
+
const data = asRecord$4(root.data) ?? root;
|
|
7629
|
+
const user = asRecord$4(deepValue(data, USER_KEYS)) ?? {};
|
|
7630
|
+
const org = asRecord$4(deepValue(data, ORG_KEYS)) ?? {};
|
|
7631
|
+
const key = asRecord$4(deepValue(data, [
|
|
7606
7632
|
"apiKey",
|
|
7607
7633
|
"key",
|
|
7608
7634
|
"credential"
|
|
7609
7635
|
])) ?? {};
|
|
7610
|
-
const subscription = asRecord$
|
|
7636
|
+
const subscription = asRecord$4(deepValue(data, [
|
|
7611
7637
|
"subscription",
|
|
7612
7638
|
"plan",
|
|
7613
7639
|
"tier"
|
|
@@ -7711,14 +7737,14 @@ function humanizeWindowKey$1(key) {
|
|
|
7711
7737
|
* — so they are read here first, by name.
|
|
7712
7738
|
*/
|
|
7713
7739
|
function parseWindowLimits(payload, consumed = []) {
|
|
7714
|
-
const root = asRecord$
|
|
7715
|
-
const limits = asRecord$
|
|
7740
|
+
const root = asRecord$4(payload) ?? {};
|
|
7741
|
+
const limits = asRecord$4(deepValue(asRecord$4(root.data) ?? root, ["windowLimits", "window_limits"]));
|
|
7716
7742
|
if (limits === void 0) return [];
|
|
7717
7743
|
const keys = [...WINDOW_ORDER$1.filter((key) => limits[key] !== void 0), ...Object.keys(limits).filter((key) => !WINDOW_ORDER$1.includes(key))];
|
|
7718
7744
|
const meters = [];
|
|
7719
7745
|
for (const key of keys) {
|
|
7720
7746
|
if (key === "limited" || key === "exceeded") continue;
|
|
7721
|
-
const record = asRecord$
|
|
7747
|
+
const record = asRecord$4(limits[key]);
|
|
7722
7748
|
if (record === void 0) continue;
|
|
7723
7749
|
const cap = firstNumber$1(record, [
|
|
7724
7750
|
"cap",
|
|
@@ -7752,8 +7778,8 @@ function parseWindowLimits(payload, consumed = []) {
|
|
|
7752
7778
|
* source for a remaining balance.
|
|
7753
7779
|
*/
|
|
7754
7780
|
function parseCreditBalances(payload, consumed = []) {
|
|
7755
|
-
const root = asRecord$
|
|
7756
|
-
const credits = asRecord$
|
|
7781
|
+
const root = asRecord$4(payload) ?? {};
|
|
7782
|
+
const credits = asRecord$4(deepValue(asRecord$4(root.data) ?? root, ["credits"]));
|
|
7757
7783
|
if (credits === void 0) return [];
|
|
7758
7784
|
const monthly = firstNumber$1(credits, ["monthlyCredits", "monthly_credits"]);
|
|
7759
7785
|
const purchased = firstNumber$1(credits, ["purchasedCredits", "purchased_credits"]);
|
|
@@ -7782,7 +7808,7 @@ function parseCreditBalances(payload, consumed = []) {
|
|
|
7782
7808
|
/** Resolve the plan id the subscription or credits payload reports, when either does. */
|
|
7783
7809
|
function parsePlanId(payloads) {
|
|
7784
7810
|
for (const payload of payloads) {
|
|
7785
|
-
const id = asString$
|
|
7811
|
+
const id = asString$5(deepValue(payload, [
|
|
7786
7812
|
"planId",
|
|
7787
7813
|
"plan_id",
|
|
7788
7814
|
"priceId",
|
|
@@ -7800,13 +7826,13 @@ function parsePlanId(payloads) {
|
|
|
7800
7826
|
* subscription's remaining credits as usable would be worse than showing none.
|
|
7801
7827
|
*/
|
|
7802
7828
|
function parseSubscriptionStatus(payload) {
|
|
7803
|
-
const root = asRecord$
|
|
7804
|
-
return asString$
|
|
7829
|
+
const root = asRecord$4(payload) ?? {};
|
|
7830
|
+
return asString$5(deepValue(asRecord$4(root.data) ?? root, ["status"])) ?? null;
|
|
7805
7831
|
}
|
|
7806
7832
|
/** End of the current billing period, in Unix milliseconds. */
|
|
7807
7833
|
function parseSubscriptionPeriodEnd(payload) {
|
|
7808
|
-
const root = asRecord$
|
|
7809
|
-
return parseTimestamp$1(deepValue(asRecord$
|
|
7834
|
+
const root = asRecord$4(payload) ?? {};
|
|
7835
|
+
return parseTimestamp$1(deepValue(asRecord$4(root.data) ?? root, ["currentPeriodEnd", "current_period_end"]));
|
|
7810
7836
|
}
|
|
7811
7837
|
/**
|
|
7812
7838
|
* Turn one billing/usage payload into meters.
|
|
@@ -8023,9 +8049,9 @@ function parseUsageWindows$1(payload) {
|
|
|
8023
8049
|
return windows;
|
|
8024
8050
|
}
|
|
8025
8051
|
function extractCreditsBalance(payload) {
|
|
8026
|
-
const root = asRecord$
|
|
8027
|
-
const data = asRecord$
|
|
8028
|
-
const credits = asRecord$
|
|
8052
|
+
const root = asRecord$4(payload) ?? {};
|
|
8053
|
+
const data = asRecord$4(root.data) ?? root;
|
|
8054
|
+
const credits = asRecord$4(data.credits);
|
|
8029
8055
|
if (credits !== void 0) {
|
|
8030
8056
|
const pools = [
|
|
8031
8057
|
"monthlyCredits",
|
|
@@ -8057,11 +8083,11 @@ let cachedCatalog;
|
|
|
8057
8083
|
let catalogInFlight = null;
|
|
8058
8084
|
/** Parse the public `/provider/v1/models` payload. */
|
|
8059
8085
|
function parseProviderModels(payload) {
|
|
8060
|
-
const root = asRecord$
|
|
8086
|
+
const root = asRecord$4(payload) ?? {};
|
|
8061
8087
|
const list = Array.isArray(root.data) ? root.data : Array.isArray(payload) ? payload : [];
|
|
8062
8088
|
const models = [];
|
|
8063
8089
|
for (const entry of list) {
|
|
8064
|
-
const record = asRecord$
|
|
8090
|
+
const record = asRecord$4(entry);
|
|
8065
8091
|
if (!record) continue;
|
|
8066
8092
|
const id = firstString$1(record, [
|
|
8067
8093
|
"id",
|
|
@@ -8262,7 +8288,7 @@ function buildModelOptions$1(catalog, enabledModelIds, overrides) {
|
|
|
8262
8288
|
function isRecord$2(value) {
|
|
8263
8289
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8264
8290
|
}
|
|
8265
|
-
function asString$
|
|
8291
|
+
function asString$4(value) {
|
|
8266
8292
|
return typeof value === "string" ? value : void 0;
|
|
8267
8293
|
}
|
|
8268
8294
|
function safeJsonParse$1(text) {
|
|
@@ -8304,7 +8330,7 @@ function attachmentOf$1(block) {
|
|
|
8304
8330
|
}
|
|
8305
8331
|
function attachmentLabel$1(block) {
|
|
8306
8332
|
const attachment = isRecord$2(block.attachment) ? block.attachment : void 0;
|
|
8307
|
-
return asString$
|
|
8333
|
+
return asString$4(attachment?.name) || asString$4(attachment?.attachmentId);
|
|
8308
8334
|
}
|
|
8309
8335
|
function collectImageRefs$1(content, refs) {
|
|
8310
8336
|
if (!Array.isArray(content)) return;
|
|
@@ -8320,7 +8346,7 @@ function base64Length$1(bytes) {
|
|
|
8320
8346
|
function requestImageBytes$1(block) {
|
|
8321
8347
|
const attachment = attachmentOf$1(block);
|
|
8322
8348
|
if (attachment) return base64Length$1(attachment.bytes);
|
|
8323
|
-
const inline = asString$
|
|
8349
|
+
const inline = asString$4(block.data) || asString$4(block.base64);
|
|
8324
8350
|
return inline ? inline.length : void 0;
|
|
8325
8351
|
}
|
|
8326
8352
|
function collectRequestImageBytes$1(content, lengths) {
|
|
@@ -8406,10 +8432,10 @@ function unavailableImageText$1(block) {
|
|
|
8406
8432
|
return `[image unavailable: ${label ? `${label} could not be read` : "the image could not be read"}; ask the user to attach it again if the image is needed]`;
|
|
8407
8433
|
}
|
|
8408
8434
|
function imageBlockToInline$1(block, images) {
|
|
8409
|
-
let data = asString$
|
|
8435
|
+
let data = asString$4(block.data) || asString$4(block.base64);
|
|
8410
8436
|
const source = isRecord$2(block.source) ? block.source : void 0;
|
|
8411
|
-
if (!data && source) data = asString$
|
|
8412
|
-
let mediaType = asString$
|
|
8437
|
+
if (!data && source) data = asString$4(source.data) || asString$4(source.base64);
|
|
8438
|
+
let mediaType = asString$4(block.mimeType) || asString$4(block.mediaType) || (source ? asString$4(source.mimeType) || asString$4(source.mediaType) : void 0) || "image/png";
|
|
8413
8439
|
if (data?.startsWith("data:")) {
|
|
8414
8440
|
const matched = data.match(/^data:([^;,]+);base64,(.*)$/s);
|
|
8415
8441
|
if (matched) {
|
|
@@ -8831,7 +8857,7 @@ function processOpenAIStreamLine$1(line, state) {
|
|
|
8831
8857
|
const choice = isRecord$2(choices[0]) ? choices[0] : void 0;
|
|
8832
8858
|
const delta = isRecord$2(choice?.delta) ? choice.delta : void 0;
|
|
8833
8859
|
if (delta) {
|
|
8834
|
-
const reasoning = asString$
|
|
8860
|
+
const reasoning = asString$4(delta.reasoning_content) ?? asString$4(delta.reasoning);
|
|
8835
8861
|
if (reasoning !== void 0 && reasoning !== "") {
|
|
8836
8862
|
out.push(...closeToolCalls$1(state));
|
|
8837
8863
|
if (state.current === null || state.current.type !== "reasoning") out.push(...openTextBlock$1(state, "reasoning"));
|
|
@@ -8843,7 +8869,7 @@ function processOpenAIStreamLine$1(line, state) {
|
|
|
8843
8869
|
text: sanitizeText$1(reasoning)
|
|
8844
8870
|
});
|
|
8845
8871
|
}
|
|
8846
|
-
const content = asString$
|
|
8872
|
+
const content = asString$4(delta.content);
|
|
8847
8873
|
if (content !== void 0 && content !== "") {
|
|
8848
8874
|
out.push(...closeToolCalls$1(state));
|
|
8849
8875
|
if (state.current === null || state.current.type !== "text") out.push(...openTextBlock$1(state, "text"));
|
|
@@ -8861,7 +8887,7 @@ function processOpenAIStreamLine$1(line, state) {
|
|
|
8861
8887
|
out.push(...applyOpenAIToolDelta$1(entry, state));
|
|
8862
8888
|
}
|
|
8863
8889
|
}
|
|
8864
|
-
const finish = asString$
|
|
8890
|
+
const finish = asString$4(choice?.finish_reason);
|
|
8865
8891
|
if (finish !== void 0 && finish !== "") {
|
|
8866
8892
|
state.finishReason = finish;
|
|
8867
8893
|
out.push(...closeCurrent$1(state));
|
|
@@ -8878,8 +8904,8 @@ function applyOpenAIToolDelta$1(entry, state) {
|
|
|
8878
8904
|
out.push(...closeCurrent$1(state));
|
|
8879
8905
|
call = {
|
|
8880
8906
|
blockIndex: state.blocks.length,
|
|
8881
|
-
id: asString$
|
|
8882
|
-
name: asString$
|
|
8907
|
+
id: asString$4(entry.id) ?? `call_${wireIndex}`,
|
|
8908
|
+
name: asString$4(fn.name) ?? "",
|
|
8883
8909
|
arguments: "",
|
|
8884
8910
|
started: false
|
|
8885
8911
|
};
|
|
@@ -8892,13 +8918,13 @@ function applyOpenAIToolDelta$1(entry, state) {
|
|
|
8892
8918
|
state.toolCalls.set(wireIndex, call);
|
|
8893
8919
|
} else {
|
|
8894
8920
|
if (call.id === `call_${wireIndex}`) {
|
|
8895
|
-
const id = asString$
|
|
8921
|
+
const id = asString$4(entry.id);
|
|
8896
8922
|
if (id !== void 0) call.id = id;
|
|
8897
8923
|
}
|
|
8898
|
-
const name = asString$
|
|
8924
|
+
const name = asString$4(fn.name);
|
|
8899
8925
|
if (name !== void 0 && name !== "") call.name = name;
|
|
8900
8926
|
}
|
|
8901
|
-
const argsDelta = asString$
|
|
8927
|
+
const argsDelta = asString$4(fn.arguments) ?? "";
|
|
8902
8928
|
if (argsDelta !== "") call.arguments += argsDelta;
|
|
8903
8929
|
if (!call.started) {
|
|
8904
8930
|
call.started = true;
|
|
@@ -8930,7 +8956,7 @@ function processAnthropicStreamLine$1(line, state) {
|
|
|
8930
8956
|
if (payload === "" || payload === "[DONE]") return [];
|
|
8931
8957
|
const event = safeJsonParse$1(payload);
|
|
8932
8958
|
if (!isRecord$2(event)) return [];
|
|
8933
|
-
const type = asString$
|
|
8959
|
+
const type = asString$4(event.type);
|
|
8934
8960
|
const out = [];
|
|
8935
8961
|
if (type === "message_start") {
|
|
8936
8962
|
const message = isRecord$2(event.message) ? event.message : void 0;
|
|
@@ -8942,21 +8968,21 @@ function processAnthropicStreamLine$1(line, state) {
|
|
|
8942
8968
|
state.cacheWriteTokens = numberOr$1(usage.cache_creation_input_tokens, 0);
|
|
8943
8969
|
state.outputTokens = numberOr$1(usage.output_tokens, 0);
|
|
8944
8970
|
}
|
|
8945
|
-
const stop = message ? asString$
|
|
8971
|
+
const stop = message ? asString$4(message.stop_reason) : void 0;
|
|
8946
8972
|
if (stop !== void 0 && stop !== null) state.finishReason = stop;
|
|
8947
8973
|
return out;
|
|
8948
8974
|
}
|
|
8949
8975
|
if (type === "content_block_start") {
|
|
8950
8976
|
const contentIndex = numberOr$1(event.index, 0);
|
|
8951
8977
|
const block = isRecord$2(event.content_block) ? event.content_block : {};
|
|
8952
|
-
const blockType = asString$
|
|
8978
|
+
const blockType = asString$4(block.type);
|
|
8953
8979
|
out.push(...closeCurrent$1(state));
|
|
8954
8980
|
if (blockType === "tool_use") {
|
|
8955
8981
|
const index = state.blocks.length;
|
|
8956
8982
|
const pending = {
|
|
8957
8983
|
blockIndex: index,
|
|
8958
|
-
id: asString$
|
|
8959
|
-
name: asString$
|
|
8984
|
+
id: asString$4(block.id) ?? `toolu_${contentIndex}`,
|
|
8985
|
+
name: asString$4(block.name) ?? "",
|
|
8960
8986
|
arguments: "",
|
|
8961
8987
|
started: true
|
|
8962
8988
|
};
|
|
@@ -8999,10 +9025,10 @@ function processAnthropicStreamLine$1(line, state) {
|
|
|
8999
9025
|
if (type === "content_block_delta") {
|
|
9000
9026
|
const contentIndex = numberOr$1(event.index, 0);
|
|
9001
9027
|
const delta = isRecord$2(event.delta) ? event.delta : {};
|
|
9002
|
-
const deltaType = asString$
|
|
9028
|
+
const deltaType = asString$4(delta.type);
|
|
9003
9029
|
if (deltaType === "input_json_delta") {
|
|
9004
9030
|
const pending = state.toolCalls.get(contentIndex);
|
|
9005
|
-
const partial = asString$
|
|
9031
|
+
const partial = asString$4(delta.partial_json) ?? "";
|
|
9006
9032
|
if (pending !== void 0) {
|
|
9007
9033
|
pending.arguments += partial;
|
|
9008
9034
|
out.push({
|
|
@@ -9015,7 +9041,7 @@ function processAnthropicStreamLine$1(line, state) {
|
|
|
9015
9041
|
}
|
|
9016
9042
|
return out;
|
|
9017
9043
|
}
|
|
9018
|
-
const text = deltaType === "thinking_delta" ? asString$
|
|
9044
|
+
const text = deltaType === "thinking_delta" ? asString$4(delta.thinking) : asString$4(delta.text);
|
|
9019
9045
|
if (text !== void 0 && text !== "") {
|
|
9020
9046
|
const index = state.contentIndexes.get(contentIndex) ?? state.current?.index;
|
|
9021
9047
|
const kind = deltaType === "thinking_delta" ? "reasoning" : "text";
|
|
@@ -9072,7 +9098,7 @@ function processAnthropicStreamLine$1(line, state) {
|
|
|
9072
9098
|
}
|
|
9073
9099
|
if (type === "message_delta") {
|
|
9074
9100
|
const delta = isRecord$2(event.delta) ? event.delta : void 0;
|
|
9075
|
-
const stop = delta ? asString$
|
|
9101
|
+
const stop = delta ? asString$4(delta.stop_reason) : void 0;
|
|
9076
9102
|
if (stop !== void 0 && stop !== "") state.finishReason = stop;
|
|
9077
9103
|
const usage = isRecord$2(event.usage) ? event.usage : void 0;
|
|
9078
9104
|
if (usage) {
|
|
@@ -9085,7 +9111,7 @@ function processAnthropicStreamLine$1(line, state) {
|
|
|
9085
9111
|
state.done = true;
|
|
9086
9112
|
return closeStream$1(state);
|
|
9087
9113
|
}
|
|
9088
|
-
if (type === "error") throw new LlmError(`Command Code stream error: ${asString$
|
|
9114
|
+
if (type === "error") throw new LlmError(`Command Code stream error: ${asString$4((isRecord$2(event.error) ? event.error : {}).message) ?? "unknown error"}`, "PROVIDER_ERROR");
|
|
9089
9115
|
return out;
|
|
9090
9116
|
}
|
|
9091
9117
|
function tokenUsage$1(state) {
|
|
@@ -10771,7 +10797,7 @@ function withTimeout(signal, ms) {
|
|
|
10771
10797
|
function oauthEndpoint(host, endpoint) {
|
|
10772
10798
|
return `${host.replace(/\/+$/, "")}${endpoint}`;
|
|
10773
10799
|
}
|
|
10774
|
-
function asRecord$
|
|
10800
|
+
function asRecord$3(value) {
|
|
10775
10801
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
10776
10802
|
}
|
|
10777
10803
|
/**
|
|
@@ -10782,8 +10808,8 @@ function asRecord$2(value) {
|
|
|
10782
10808
|
* caller decides whether the flow continues.
|
|
10783
10809
|
*/
|
|
10784
10810
|
function oauthErrorFields(payload) {
|
|
10785
|
-
const root = asRecord$
|
|
10786
|
-
const nested = asRecord$
|
|
10811
|
+
const root = asRecord$3(payload) ?? {};
|
|
10812
|
+
const nested = asRecord$3(root.error);
|
|
10787
10813
|
if (nested !== void 0) return {
|
|
10788
10814
|
code: typeof nested.code === "string" ? nested.code : "",
|
|
10789
10815
|
description: String(nested.message ?? nested.error_description ?? nested.detail ?? nested.type ?? "")
|
|
@@ -10815,7 +10841,7 @@ async function requestDeviceAuthorization(options = {}) {
|
|
|
10815
10841
|
const { description } = oauthErrorFields(payload);
|
|
10816
10842
|
throw new Error(`Device authorization failed (${response.status})${description ? `: ${description}` : ""}`);
|
|
10817
10843
|
}
|
|
10818
|
-
const record = asRecord$
|
|
10844
|
+
const record = asRecord$3(payload) ?? {};
|
|
10819
10845
|
const userCode = typeof record.user_code === "string" ? record.user_code : "";
|
|
10820
10846
|
const deviceCode = typeof record.device_code === "string" ? record.device_code : "";
|
|
10821
10847
|
const complete = typeof record.verification_uri_complete === "string" ? record.verification_uri_complete : "";
|
|
@@ -10857,7 +10883,7 @@ async function pollDeviceToken(host, deviceCode, options) {
|
|
|
10857
10883
|
signal: withTimeout(options.signal, OAUTH_TIMEOUT_MS)
|
|
10858
10884
|
});
|
|
10859
10885
|
const payload = await response.json().catch(() => void 0);
|
|
10860
|
-
const record = asRecord$
|
|
10886
|
+
const record = asRecord$3(payload) ?? {};
|
|
10861
10887
|
if (response.status === 200 && typeof record.access_token === "string" && record.access_token !== "") return {
|
|
10862
10888
|
kind: "success",
|
|
10863
10889
|
token: parseTokenResponse(record)
|
|
@@ -10983,7 +11009,7 @@ async function refreshAccessToken(refreshToken, options = {}) {
|
|
|
10983
11009
|
const payload = await response.json().catch(() => void 0);
|
|
10984
11010
|
const { code, description } = oauthErrorFields(payload);
|
|
10985
11011
|
if (response.status === 401 || response.status === 403 || code === "invalid_grant") throw new KimiCodeUnauthorizedError(description || "Token refresh was rejected; sign in again.");
|
|
10986
|
-
if (response.ok) return parseTokenResponse(asRecord$
|
|
11012
|
+
if (response.ok) return parseTokenResponse(asRecord$3(payload) ?? {});
|
|
10987
11013
|
if (!RETRYABLE_REFRESH_STATUSES.has(response.status)) throw new Error(description || `Token refresh failed (HTTP ${response.status}).`);
|
|
10988
11014
|
lastError = new KimiCodeRetryableError(description || `Token refresh failed (HTTP ${response.status}).`);
|
|
10989
11015
|
} catch (error) {
|
|
@@ -11208,10 +11234,10 @@ const FIXED_POINT_CENTS = 1e6;
|
|
|
11208
11234
|
function isRecord$1(value) {
|
|
11209
11235
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11210
11236
|
}
|
|
11211
|
-
function asRecord$
|
|
11237
|
+
function asRecord$2(value) {
|
|
11212
11238
|
return isRecord$1(value) ? value : void 0;
|
|
11213
11239
|
}
|
|
11214
|
-
function asString$
|
|
11240
|
+
function asString$3(value) {
|
|
11215
11241
|
if (typeof value === "string" && value.trim() !== "") return value;
|
|
11216
11242
|
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
11217
11243
|
}
|
|
@@ -11225,7 +11251,7 @@ function asNumber(value) {
|
|
|
11225
11251
|
}
|
|
11226
11252
|
function firstString(record, keys) {
|
|
11227
11253
|
for (const key of keys) {
|
|
11228
|
-
const value = asString$
|
|
11254
|
+
const value = asString$3(record[key]);
|
|
11229
11255
|
if (value !== void 0) return value;
|
|
11230
11256
|
}
|
|
11231
11257
|
}
|
|
@@ -11311,24 +11337,24 @@ function clearCachedCatalog() {
|
|
|
11311
11337
|
* length is dropped rather than shown as a zero-capacity model.
|
|
11312
11338
|
*/
|
|
11313
11339
|
function parseCatalogModel(value) {
|
|
11314
|
-
const record = asRecord$
|
|
11340
|
+
const record = asRecord$2(value);
|
|
11315
11341
|
if (record === void 0) return void 0;
|
|
11316
|
-
const id = asString$
|
|
11342
|
+
const id = asString$3(record.id);
|
|
11317
11343
|
if (id === void 0) return void 0;
|
|
11318
11344
|
const contextWindow = firstNumber(record, ["context_length", "contextLength"]);
|
|
11319
11345
|
if (contextWindow === void 0 || contextWindow <= 0) return void 0;
|
|
11320
|
-
const efforts = asRecord$
|
|
11346
|
+
const efforts = asRecord$2(record.think_efforts) ?? asRecord$2(record.thinkEfforts);
|
|
11321
11347
|
const validEfforts = Array.isArray(efforts?.valid_efforts) ? efforts.valid_efforts.filter((entry) => typeof entry === "string") : Array.isArray(efforts?.validEfforts) ? efforts.validEfforts.filter((entry) => typeof entry === "string") : void 0;
|
|
11322
11348
|
const modalities = ["text"];
|
|
11323
11349
|
if (record.supports_image_in === true || record.supportsImageIn === true) modalities.push("image");
|
|
11324
11350
|
if (record.supports_video_in === true || record.supportsVideoIn === true) modalities.push("video");
|
|
11325
|
-
const protocol = asString$
|
|
11351
|
+
const protocol = asString$3(record.protocol);
|
|
11326
11352
|
return {
|
|
11327
11353
|
id,
|
|
11328
|
-
name: asString$
|
|
11354
|
+
name: asString$3(record.display_name) ?? asString$3(record.displayName) ?? void 0,
|
|
11329
11355
|
contextWindow,
|
|
11330
11356
|
...validEfforts === void 0 || validEfforts.length === 0 ? {} : { reasoningEfforts: validEfforts },
|
|
11331
|
-
...asString$
|
|
11357
|
+
...asString$3(efforts?.default_effort ?? efforts?.defaultEffort) === void 0 ? {} : { defaultReasoningEffort: asString$3(efforts?.default_effort ?? efforts?.defaultEffort) },
|
|
11332
11358
|
inputModalities: modalities,
|
|
11333
11359
|
protocol: protocol === "anthropic" ? "anthropic" : "openai",
|
|
11334
11360
|
...record.supports_video_in === true || record.supportsVideoIn === true ? { supportsVideo: true } : {},
|
|
@@ -11364,7 +11390,7 @@ async function loadProviderModels$1(options = {}) {
|
|
|
11364
11390
|
});
|
|
11365
11391
|
if (!response.ok) throw new Error(`Kimi Code model listing failed (${response.status}).`);
|
|
11366
11392
|
const payload = await response.json().catch(() => void 0);
|
|
11367
|
-
const data = Array.isArray(payload) ? payload : asRecord$
|
|
11393
|
+
const data = Array.isArray(payload) ? payload : asRecord$2(payload)?.data;
|
|
11368
11394
|
if (!Array.isArray(data)) throw new Error("Kimi Code model listing was not in the documented shape.");
|
|
11369
11395
|
const models = data.map(parseCatalogModel).filter((model) => model !== void 0);
|
|
11370
11396
|
catalogCache = {
|
|
@@ -11526,7 +11552,7 @@ function usageWindow(id, record, descriptor) {
|
|
|
11526
11552
|
* than a fabricated 0%.
|
|
11527
11553
|
*/
|
|
11528
11554
|
function parseUsageWindows(payload) {
|
|
11529
|
-
const root = asRecord$
|
|
11555
|
+
const root = asRecord$2(payload) ?? {};
|
|
11530
11556
|
const windows = [];
|
|
11531
11557
|
const seen = /* @__PURE__ */ new Set();
|
|
11532
11558
|
const push = (id, record, descriptor) => {
|
|
@@ -11536,25 +11562,25 @@ function parseUsageWindows(payload) {
|
|
|
11536
11562
|
seen.add(id);
|
|
11537
11563
|
windows.push(parsed);
|
|
11538
11564
|
};
|
|
11539
|
-
const usages = asRecord$
|
|
11565
|
+
const usages = asRecord$2(root.usages) ?? asRecord$2(root.usageWindows);
|
|
11540
11566
|
if (usages !== void 0) {
|
|
11541
11567
|
const keys = [...WINDOW_ORDER.filter((key) => usages[key] !== void 0), ...Object.keys(usages).filter((key) => !WINDOW_ORDER.includes(key))];
|
|
11542
11568
|
for (const key of keys) {
|
|
11543
|
-
const record = asRecord$
|
|
11569
|
+
const record = asRecord$2(usages[key]);
|
|
11544
11570
|
if (record === void 0) continue;
|
|
11545
11571
|
push(key, record, WINDOW_DESCRIPTORS[key]);
|
|
11546
11572
|
}
|
|
11547
11573
|
}
|
|
11548
|
-
const topLevel = asRecord$
|
|
11574
|
+
const topLevel = asRecord$2(root.usage);
|
|
11549
11575
|
if (topLevel !== void 0 && seen.size === 0) push("limit_7d", topLevel, WINDOW_DESCRIPTORS.limit_7d);
|
|
11550
11576
|
const limits = Array.isArray(root.limits) ? root.limits : [];
|
|
11551
11577
|
for (const entry of limits) {
|
|
11552
|
-
const record = asRecord$
|
|
11578
|
+
const record = asRecord$2(entry);
|
|
11553
11579
|
if (record === void 0) continue;
|
|
11554
|
-
const detail = asRecord$
|
|
11555
|
-
const window = asRecord$
|
|
11580
|
+
const detail = asRecord$2(record.detail) ?? record;
|
|
11581
|
+
const window = asRecord$2(record.window);
|
|
11556
11582
|
const duration = firstNumber(window ?? {}, ["duration"]);
|
|
11557
|
-
const unit = asString$
|
|
11583
|
+
const unit = asString$3(window?.timeUnit ?? window?.time_unit);
|
|
11558
11584
|
const minutes = duration === void 0 ? null : unit === "TIME_UNIT_HOUR" ? duration * 60 : duration;
|
|
11559
11585
|
push(minutes === 300 ? "limit_5h" : minutes === 10080 ? "limit_7d" : firstString(record, ["id", "name"]) ?? `limit-${windows.length + 1}`, detail, minutes === null ? void 0 : {
|
|
11560
11586
|
label: minutes === 300 ? "5-hour" : `${minutes}-minute`,
|
|
@@ -11585,14 +11611,14 @@ function fixedPointToCents(value) {
|
|
|
11585
11611
|
* under-report a charge limit by six orders of magnitude.
|
|
11586
11612
|
*/
|
|
11587
11613
|
function moneyCents(value) {
|
|
11588
|
-
const record = asRecord$
|
|
11614
|
+
const record = asRecord$2(value);
|
|
11589
11615
|
if (record === void 0) return null;
|
|
11590
11616
|
const cents = asNumber(record.priceInCents ?? record.price_in_cents);
|
|
11591
11617
|
return cents === void 0 || !Number.isFinite(cents) ? null : Math.round(cents);
|
|
11592
11618
|
}
|
|
11593
11619
|
function moneyCurrency(value) {
|
|
11594
|
-
const record = asRecord$
|
|
11595
|
-
return record === void 0 ? void 0 : asString$
|
|
11620
|
+
const record = asRecord$2(value);
|
|
11621
|
+
return record === void 0 ? void 0 : asString$3(record.currency);
|
|
11596
11622
|
}
|
|
11597
11623
|
/**
|
|
11598
11624
|
* Read the booster wallet (the pay-as-you-go top-up pool).
|
|
@@ -11602,11 +11628,11 @@ function moneyCurrency(value) {
|
|
|
11602
11628
|
* cannot spend.
|
|
11603
11629
|
*/
|
|
11604
11630
|
function parseExtraUsage(payload) {
|
|
11605
|
-
const root = asRecord$
|
|
11606
|
-
const wallet = asRecord$
|
|
11631
|
+
const root = asRecord$2(payload) ?? {};
|
|
11632
|
+
const wallet = asRecord$2(root.boosterWallet) ?? asRecord$2(root.booster_wallet) ?? asRecord$2(root.extraUsage);
|
|
11607
11633
|
if (wallet === void 0) return null;
|
|
11608
|
-
const balance = asRecord$
|
|
11609
|
-
const balanceType = asString$
|
|
11634
|
+
const balance = asRecord$2(wallet.balance);
|
|
11635
|
+
const balanceType = asString$3(balance?.type);
|
|
11610
11636
|
const amount = asNumber(balance?.amount);
|
|
11611
11637
|
if (balance === void 0 || balanceType !== "BOOSTER" || amount === void 0 || amount <= 0) return null;
|
|
11612
11638
|
const limit = wallet.monthlyChargeLimit ?? wallet.monthly_charge_limit;
|
|
@@ -11617,7 +11643,7 @@ function parseExtraUsage(payload) {
|
|
|
11617
11643
|
monthlyChargeLimitEnabled: wallet.monthlyChargeLimitEnabled === true || wallet.monthly_charge_limit_enabled === true,
|
|
11618
11644
|
monthlyChargeLimitCents: moneyCents(limit),
|
|
11619
11645
|
monthlyUsedCents: moneyCents(used),
|
|
11620
|
-
currency: moneyCurrency(limit) ?? moneyCurrency(used) ?? asString$
|
|
11646
|
+
currency: moneyCurrency(limit) ?? moneyCurrency(used) ?? asString$3(wallet.currency) ?? "USD"
|
|
11621
11647
|
};
|
|
11622
11648
|
}
|
|
11623
11649
|
/**
|
|
@@ -11654,7 +11680,7 @@ function membershipLevelName(level) {
|
|
|
11654
11680
|
* `user_level_name` still yields a readable tier instead of a raw enum.
|
|
11655
11681
|
*/
|
|
11656
11682
|
function parsePlanName(payload) {
|
|
11657
|
-
const root = asRecord$
|
|
11683
|
+
const root = asRecord$2(payload) ?? {};
|
|
11658
11684
|
const direct = firstString(root, [
|
|
11659
11685
|
"user_level_name",
|
|
11660
11686
|
"userLevelName",
|
|
@@ -11662,18 +11688,18 @@ function parsePlanName(payload) {
|
|
|
11662
11688
|
"plan_name"
|
|
11663
11689
|
]);
|
|
11664
11690
|
if (direct !== void 0) return direct;
|
|
11665
|
-
const membership = asRecord$
|
|
11666
|
-
const named = asString$
|
|
11691
|
+
const membership = asRecord$2(asRecord$2(root.user)?.membership);
|
|
11692
|
+
const named = asString$3(membership?.level_name ?? membership?.levelName);
|
|
11667
11693
|
if (named !== void 0) return named;
|
|
11668
|
-
return membershipLevelName(asString$
|
|
11694
|
+
return membershipLevelName(asString$3(membership?.level) ?? null);
|
|
11669
11695
|
}
|
|
11670
11696
|
/** Machine tier level when the service reports one. */
|
|
11671
11697
|
function parsePlanLevel(payload) {
|
|
11672
|
-
const root = asRecord$
|
|
11698
|
+
const root = asRecord$2(payload) ?? {};
|
|
11673
11699
|
const direct = firstNumber(root, ["user_level", "userLevel"]);
|
|
11674
11700
|
if (direct !== void 0) return String(direct);
|
|
11675
|
-
const membership = asRecord$
|
|
11676
|
-
return asString$
|
|
11701
|
+
const membership = asRecord$2(asRecord$2(root.user)?.membership);
|
|
11702
|
+
return asString$3(membership?.level ?? membership?.levelId ?? membership?.level_id) ?? null;
|
|
11677
11703
|
}
|
|
11678
11704
|
/**
|
|
11679
11705
|
* Fetch and cache the account's quota snapshot.
|
|
@@ -11740,7 +11766,7 @@ function accountFromCredentials(credentials, payload, profile) {
|
|
|
11740
11766
|
const planLevel = (profile === void 0 ? null : parsePlanLevel(profile)) ?? (payload === void 0 ? null : parsePlanLevel(payload));
|
|
11741
11767
|
return {
|
|
11742
11768
|
userId: credentials.userId ?? identity.userId ?? null,
|
|
11743
|
-
nickname: (profile === void 0 ? null : firstString(asRecord$
|
|
11769
|
+
nickname: (profile === void 0 ? null : firstString(asRecord$2(profile) ?? {}, [
|
|
11744
11770
|
"nickname",
|
|
11745
11771
|
"username",
|
|
11746
11772
|
"name"
|
|
@@ -11941,7 +11967,7 @@ function videoBlockLabel(block) {
|
|
|
11941
11967
|
function isRecord(value) {
|
|
11942
11968
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11943
11969
|
}
|
|
11944
|
-
function asString$
|
|
11970
|
+
function asString$2(value) {
|
|
11945
11971
|
return typeof value === "string" ? value : void 0;
|
|
11946
11972
|
}
|
|
11947
11973
|
function safeJsonParse(text) {
|
|
@@ -12100,7 +12126,7 @@ function attachmentOf(block) {
|
|
|
12100
12126
|
}
|
|
12101
12127
|
function attachmentLabel(block) {
|
|
12102
12128
|
const attachment = isRecord(block.attachment) ? block.attachment : void 0;
|
|
12103
|
-
return asString$
|
|
12129
|
+
return asString$2(attachment?.name) || asString$2(attachment?.attachmentId);
|
|
12104
12130
|
}
|
|
12105
12131
|
function collectImageRefs(content, refs) {
|
|
12106
12132
|
if (!Array.isArray(content)) return;
|
|
@@ -12116,7 +12142,7 @@ function base64Length(bytes) {
|
|
|
12116
12142
|
function requestImageBytes(block) {
|
|
12117
12143
|
const attachment = attachmentOf(block);
|
|
12118
12144
|
if (attachment) return base64Length(attachment.bytes);
|
|
12119
|
-
const inline = asString$
|
|
12145
|
+
const inline = asString$2(block.data) || asString$2(block.base64);
|
|
12120
12146
|
return inline ? inline.length : void 0;
|
|
12121
12147
|
}
|
|
12122
12148
|
function collectRequestImageBytes(content, lengths) {
|
|
@@ -12214,7 +12240,7 @@ function collectVideoRefs(content, refs) {
|
|
|
12214
12240
|
}
|
|
12215
12241
|
/** Base64 length of one video occurrence, or undefined when it states none. */
|
|
12216
12242
|
function requestVideoBytes(block) {
|
|
12217
|
-
const inline = asString$
|
|
12243
|
+
const inline = asString$2(block.data) || asString$2(block.base64);
|
|
12218
12244
|
if (inline) return inline.length;
|
|
12219
12245
|
const attachment = videoAttachmentOf(block);
|
|
12220
12246
|
return attachment === void 0 ? void 0 : base64LengthOf(attachment.bytes);
|
|
@@ -12313,8 +12339,8 @@ function requestHasVideo(options) {
|
|
|
12313
12339
|
function videoBlockToInline(block, videos, videoAccepted) {
|
|
12314
12340
|
const label = videoBlockLabel(block);
|
|
12315
12341
|
if (!videoAccepted) return { omission: videoOmissionText("unsupported-model", label) };
|
|
12316
|
-
let data = asString$
|
|
12317
|
-
let mediaType = asString$
|
|
12342
|
+
let data = asString$2(block.data) || asString$2(block.base64);
|
|
12343
|
+
let mediaType = asString$2(block.mediaType) || asString$2(block.mimeType);
|
|
12318
12344
|
if (data?.startsWith("data:")) {
|
|
12319
12345
|
const matched = data.match(/^data:([^;,]+);base64,(.*)$/s);
|
|
12320
12346
|
if (matched) {
|
|
@@ -12341,10 +12367,10 @@ function unavailableImageText(block) {
|
|
|
12341
12367
|
return `[image unavailable: ${label ? `${label} could not be read` : "the image could not be read"}; ask the user to attach it again if the image is needed]`;
|
|
12342
12368
|
}
|
|
12343
12369
|
function imageBlockToInline(block, images) {
|
|
12344
|
-
let data = asString$
|
|
12370
|
+
let data = asString$2(block.data) || asString$2(block.base64);
|
|
12345
12371
|
const source = isRecord(block.source) ? block.source : void 0;
|
|
12346
|
-
if (!data && source) data = asString$
|
|
12347
|
-
let mediaType = asString$
|
|
12372
|
+
if (!data && source) data = asString$2(source.data) || asString$2(source.base64);
|
|
12373
|
+
let mediaType = asString$2(block.mimeType) || asString$2(block.mediaType) || (source ? asString$2(source.mimeType) || asString$2(source.mediaType) : void 0) || "image/png";
|
|
12348
12374
|
if (data?.startsWith("data:")) {
|
|
12349
12375
|
const matched = data.match(/^data:([^;,]+);base64,(.*)$/s);
|
|
12350
12376
|
if (matched) {
|
|
@@ -12968,7 +12994,7 @@ function processOpenAIStreamLine(line, state) {
|
|
|
12968
12994
|
if (!isRecord(chunk)) return [];
|
|
12969
12995
|
const out = [];
|
|
12970
12996
|
const errorPayload = isRecord(chunk.error) ? chunk.error : void 0;
|
|
12971
|
-
if (errorPayload !== void 0) throw new LlmError(`Kimi Code stream error: ${asString$
|
|
12997
|
+
if (errorPayload !== void 0) throw new LlmError(`Kimi Code stream error: ${asString$2(errorPayload.message) ?? "unknown error"}`, "PROVIDER_ERROR");
|
|
12972
12998
|
const usage = isRecord(chunk.usage) ? chunk.usage : void 0;
|
|
12973
12999
|
if (usage) {
|
|
12974
13000
|
state.sawUsage = true;
|
|
@@ -12984,7 +13010,7 @@ function processOpenAIStreamLine(line, state) {
|
|
|
12984
13010
|
const choice = isRecord(choices[0]) ? choices[0] : void 0;
|
|
12985
13011
|
const delta = isRecord(choice?.delta) ? choice.delta : void 0;
|
|
12986
13012
|
if (delta) {
|
|
12987
|
-
const reasoning = asString$
|
|
13013
|
+
const reasoning = asString$2(delta.reasoning_content) ?? asString$2(delta.reasoning);
|
|
12988
13014
|
if (reasoning !== void 0 && reasoning !== "") {
|
|
12989
13015
|
out.push(...closeToolCalls(state));
|
|
12990
13016
|
if (state.current === null || state.current.type !== "reasoning") out.push(...openTextBlock(state, "reasoning"));
|
|
@@ -12996,7 +13022,7 @@ function processOpenAIStreamLine(line, state) {
|
|
|
12996
13022
|
text: sanitizeText(reasoning)
|
|
12997
13023
|
});
|
|
12998
13024
|
}
|
|
12999
|
-
const content = asString$
|
|
13025
|
+
const content = asString$2(delta.content);
|
|
13000
13026
|
if (content !== void 0 && content !== "") {
|
|
13001
13027
|
out.push(...closeToolCalls(state));
|
|
13002
13028
|
if (state.current === null || state.current.type !== "text") out.push(...openTextBlock(state, "text"));
|
|
@@ -13014,7 +13040,7 @@ function processOpenAIStreamLine(line, state) {
|
|
|
13014
13040
|
out.push(...applyOpenAIToolDelta(entry, state));
|
|
13015
13041
|
}
|
|
13016
13042
|
}
|
|
13017
|
-
const finish = asString$
|
|
13043
|
+
const finish = asString$2(choice?.finish_reason);
|
|
13018
13044
|
if (finish !== void 0 && finish !== "") {
|
|
13019
13045
|
state.finishReason = finish;
|
|
13020
13046
|
out.push(...closeCurrent(state));
|
|
@@ -13031,8 +13057,8 @@ function applyOpenAIToolDelta(entry, state) {
|
|
|
13031
13057
|
out.push(...closeCurrent(state));
|
|
13032
13058
|
call = {
|
|
13033
13059
|
blockIndex: state.blocks.length,
|
|
13034
|
-
id: asString$
|
|
13035
|
-
name: asString$
|
|
13060
|
+
id: asString$2(entry.id) ?? `call_${wireIndex}`,
|
|
13061
|
+
name: asString$2(fn.name) ?? "",
|
|
13036
13062
|
arguments: "",
|
|
13037
13063
|
started: false
|
|
13038
13064
|
};
|
|
@@ -13045,13 +13071,13 @@ function applyOpenAIToolDelta(entry, state) {
|
|
|
13045
13071
|
state.toolCalls.set(wireIndex, call);
|
|
13046
13072
|
} else {
|
|
13047
13073
|
if (call.id === `call_${wireIndex}`) {
|
|
13048
|
-
const id = asString$
|
|
13074
|
+
const id = asString$2(entry.id);
|
|
13049
13075
|
if (id !== void 0) call.id = id;
|
|
13050
13076
|
}
|
|
13051
|
-
const name = asString$
|
|
13077
|
+
const name = asString$2(fn.name);
|
|
13052
13078
|
if (name !== void 0 && name !== "") call.name = name;
|
|
13053
13079
|
}
|
|
13054
|
-
const argsDelta = asString$
|
|
13080
|
+
const argsDelta = asString$2(fn.arguments) ?? "";
|
|
13055
13081
|
if (argsDelta !== "") call.arguments += argsDelta;
|
|
13056
13082
|
if (!call.started) {
|
|
13057
13083
|
call.started = true;
|
|
@@ -13080,7 +13106,7 @@ function processAnthropicStreamLine(line, state) {
|
|
|
13080
13106
|
if (payload === "" || payload === "[DONE]") return [];
|
|
13081
13107
|
const event = safeJsonParse(payload);
|
|
13082
13108
|
if (!isRecord(event)) return [];
|
|
13083
|
-
const type = asString$
|
|
13109
|
+
const type = asString$2(event.type);
|
|
13084
13110
|
const out = [];
|
|
13085
13111
|
if (type === "message_start") {
|
|
13086
13112
|
const message = isRecord(event.message) ? event.message : void 0;
|
|
@@ -13092,21 +13118,21 @@ function processAnthropicStreamLine(line, state) {
|
|
|
13092
13118
|
state.cacheWriteTokens = numberOr(usage.cache_creation_input_tokens, 0);
|
|
13093
13119
|
state.outputTokens = numberOr(usage.output_tokens, 0);
|
|
13094
13120
|
}
|
|
13095
|
-
const stop = message ? asString$
|
|
13121
|
+
const stop = message ? asString$2(message.stop_reason) : void 0;
|
|
13096
13122
|
if (stop !== void 0) state.finishReason = stop;
|
|
13097
13123
|
return out;
|
|
13098
13124
|
}
|
|
13099
13125
|
if (type === "content_block_start") {
|
|
13100
13126
|
const contentIndex = numberOr(event.index, 0);
|
|
13101
13127
|
const block = isRecord(event.content_block) ? event.content_block : {};
|
|
13102
|
-
const blockType = asString$
|
|
13128
|
+
const blockType = asString$2(block.type);
|
|
13103
13129
|
out.push(...closeCurrent(state));
|
|
13104
13130
|
if (blockType === "tool_use") {
|
|
13105
13131
|
const index = state.blocks.length;
|
|
13106
13132
|
const pending = {
|
|
13107
13133
|
blockIndex: index,
|
|
13108
|
-
id: asString$
|
|
13109
|
-
name: asString$
|
|
13134
|
+
id: asString$2(block.id) ?? `toolu_${contentIndex}`,
|
|
13135
|
+
name: asString$2(block.name) ?? "",
|
|
13110
13136
|
arguments: "",
|
|
13111
13137
|
started: true
|
|
13112
13138
|
};
|
|
@@ -13149,10 +13175,10 @@ function processAnthropicStreamLine(line, state) {
|
|
|
13149
13175
|
if (type === "content_block_delta") {
|
|
13150
13176
|
const contentIndex = numberOr(event.index, 0);
|
|
13151
13177
|
const delta = isRecord(event.delta) ? event.delta : {};
|
|
13152
|
-
const deltaType = asString$
|
|
13178
|
+
const deltaType = asString$2(delta.type);
|
|
13153
13179
|
if (deltaType === "input_json_delta") {
|
|
13154
13180
|
const pending = state.toolCalls.get(contentIndex);
|
|
13155
|
-
const partial = asString$
|
|
13181
|
+
const partial = asString$2(delta.partial_json) ?? "";
|
|
13156
13182
|
if (pending !== void 0) {
|
|
13157
13183
|
pending.arguments += partial;
|
|
13158
13184
|
out.push({
|
|
@@ -13165,7 +13191,7 @@ function processAnthropicStreamLine(line, state) {
|
|
|
13165
13191
|
}
|
|
13166
13192
|
return out;
|
|
13167
13193
|
}
|
|
13168
|
-
const text = deltaType === "thinking_delta" ? asString$
|
|
13194
|
+
const text = deltaType === "thinking_delta" ? asString$2(delta.thinking) : asString$2(delta.text);
|
|
13169
13195
|
if (text !== void 0 && text !== "") {
|
|
13170
13196
|
const index = state.contentIndexes.get(contentIndex) ?? state.current?.index;
|
|
13171
13197
|
const kind = deltaType === "thinking_delta" ? "reasoning" : "text";
|
|
@@ -13222,7 +13248,7 @@ function processAnthropicStreamLine(line, state) {
|
|
|
13222
13248
|
}
|
|
13223
13249
|
if (type === "message_delta") {
|
|
13224
13250
|
const delta = isRecord(event.delta) ? event.delta : void 0;
|
|
13225
|
-
const stop = delta ? asString$
|
|
13251
|
+
const stop = delta ? asString$2(delta.stop_reason) : void 0;
|
|
13226
13252
|
if (stop !== void 0 && stop !== "") state.finishReason = stop;
|
|
13227
13253
|
const usage = isRecord(event.usage) ? event.usage : void 0;
|
|
13228
13254
|
if (usage) {
|
|
@@ -13235,7 +13261,7 @@ function processAnthropicStreamLine(line, state) {
|
|
|
13235
13261
|
state.done = true;
|
|
13236
13262
|
return closeStream(state);
|
|
13237
13263
|
}
|
|
13238
|
-
if (type === "error") throw new LlmError(`Kimi Code stream error: ${asString$
|
|
13264
|
+
if (type === "error") throw new LlmError(`Kimi Code stream error: ${asString$2((isRecord(event.error) ? event.error : {}).message) ?? "unknown error"}`, "PROVIDER_ERROR");
|
|
13239
13265
|
return out;
|
|
13240
13266
|
}
|
|
13241
13267
|
let cacheStats = {
|
|
@@ -14378,11 +14404,21 @@ const SUBAGENT_POLICY_EVENT = "subagent/model-selection-policy";
|
|
|
14378
14404
|
/** Delegation tools whose child routes this guard authorizes. */
|
|
14379
14405
|
const DEFAULT_DELEGATION_TOOLS = ["subagent"];
|
|
14380
14406
|
/**
|
|
14407
|
+
* Delegation tools that start their child on the caller's own route by design.
|
|
14408
|
+
* `subagent_fork` is the shipped one: it omits `modelSelectionSettings`, so it
|
|
14409
|
+
* exposes no route parameters and seeds the child from the parent's own
|
|
14410
|
+
* conversation — a child on any other route would discard the inherited prefix
|
|
14411
|
+
* and its cache. Inherit mode is what keeps that design honest: the fork still
|
|
14412
|
+
* cannot choose, but an allowlist-carrying Session now refuses to let it run on
|
|
14413
|
+
* a route the user did not authorize.
|
|
14414
|
+
*/
|
|
14415
|
+
const DEFAULT_SUBAGENT_INHERIT_TOOLS = ["subagent_fork"];
|
|
14416
|
+
/**
|
|
14381
14417
|
* Read one deployment event field as a string.
|
|
14382
14418
|
* @param value - Candidate field value from a durable event.
|
|
14383
14419
|
* @returns the string value, or undefined for any other type.
|
|
14384
14420
|
*/
|
|
14385
|
-
function asString(value) {
|
|
14421
|
+
function asString$1(value) {
|
|
14386
14422
|
return typeof value === "string" ? value : void 0;
|
|
14387
14423
|
}
|
|
14388
14424
|
/**
|
|
@@ -14390,7 +14426,7 @@ function asString(value) {
|
|
|
14390
14426
|
* @param value - Candidate field value from a durable event.
|
|
14391
14427
|
* @returns the record value, or undefined for arrays, null, and primitives.
|
|
14392
14428
|
*/
|
|
14393
|
-
function asRecord(value) {
|
|
14429
|
+
function asRecord$1(value) {
|
|
14394
14430
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
14395
14431
|
}
|
|
14396
14432
|
/**
|
|
@@ -14407,13 +14443,13 @@ function asBoolean(value) {
|
|
|
14407
14443
|
* @returns every well-formed route, or undefined when the payload carries none.
|
|
14408
14444
|
*/
|
|
14409
14445
|
function parseAllowedRoutes(data) {
|
|
14410
|
-
const allowed = asRecord(data)?.["allowedModels"];
|
|
14446
|
+
const allowed = asRecord$1(data)?.["allowedModels"];
|
|
14411
14447
|
if (!Array.isArray(allowed)) return void 0;
|
|
14412
14448
|
const routes = [];
|
|
14413
14449
|
for (const entry of allowed) {
|
|
14414
|
-
const record = asRecord(entry);
|
|
14415
|
-
const provider = asString(record?.["provider"]);
|
|
14416
|
-
const model = asString(record?.["model"]);
|
|
14450
|
+
const record = asRecord$1(entry);
|
|
14451
|
+
const provider = asString$1(record?.["provider"]);
|
|
14452
|
+
const model = asString$1(record?.["model"]);
|
|
14417
14453
|
if (provider === void 0 || model === void 0) continue;
|
|
14418
14454
|
if (provider.length === 0 || model.length === 0) continue;
|
|
14419
14455
|
routes.push({
|
|
@@ -14458,7 +14494,7 @@ function authorizedRoutesFor(agent, sessions) {
|
|
|
14458
14494
|
if (recorded !== void 0) return recorded;
|
|
14459
14495
|
const header = session.header;
|
|
14460
14496
|
if (header?.origin !== "subagent") return void 0;
|
|
14461
|
-
const parentId = asString(header.parentSession);
|
|
14497
|
+
const parentId = asString$1(header.parentSession);
|
|
14462
14498
|
if (parentId === void 0) return void 0;
|
|
14463
14499
|
session = sessions.get(parentId);
|
|
14464
14500
|
}
|
|
@@ -14474,7 +14510,7 @@ function subagentModelSelectionPreference(settings) {
|
|
|
14474
14510
|
const register = settings["register"];
|
|
14475
14511
|
if (typeof register !== "function") return void 0;
|
|
14476
14512
|
try {
|
|
14477
|
-
const value = asRecord(register.call(settings, SUBAGENT_MODEL_SELECTION_NAMESPACE, z.object({
|
|
14513
|
+
const value = asRecord$1(register.call(settings, SUBAGENT_MODEL_SELECTION_NAMESPACE, z.object({
|
|
14478
14514
|
enabled: z.boolean().default(false),
|
|
14479
14515
|
allowedModels: z.array(z.object({
|
|
14480
14516
|
provider: z.string().min(1).required(),
|
|
@@ -14490,6 +14526,40 @@ function subagentModelSelectionPreference(settings) {
|
|
|
14490
14526
|
return;
|
|
14491
14527
|
}
|
|
14492
14528
|
}
|
|
14529
|
+
/**
|
|
14530
|
+
* Read the route an inherit-mode child would run on: the calling agent's own
|
|
14531
|
+
* effective request route. This mirrors the delegation seam's
|
|
14532
|
+
* `parentAgentOptionsForDelegation`, where the latest request header owns
|
|
14533
|
+
* provider/model after request-time model selection and the creation options
|
|
14534
|
+
* remain the fallback before the first request. `AuthorizationAgent.options` is
|
|
14535
|
+
* deliberately NOT a fallback while a header exists — after a mid-session model
|
|
14536
|
+
* switch the creation options are stale, and trusting them would authorize the
|
|
14537
|
+
* route the session no longer uses.
|
|
14538
|
+
* @param agent - Calling agent.
|
|
14539
|
+
* @returns the inherited route fields, each absent when its source did not supply it.
|
|
14540
|
+
*/
|
|
14541
|
+
function inheritedRouteOf(agent) {
|
|
14542
|
+
const session = agent?.session;
|
|
14543
|
+
let header;
|
|
14544
|
+
try {
|
|
14545
|
+
header = session?.requestHeader?.();
|
|
14546
|
+
} catch {
|
|
14547
|
+
header = void 0;
|
|
14548
|
+
}
|
|
14549
|
+
if (header?.config !== void 0) {
|
|
14550
|
+
const provider = asString$1(header.config.provider);
|
|
14551
|
+
const model = asString$1(header.config.model);
|
|
14552
|
+
if (provider !== void 0 || model !== void 0) return {
|
|
14553
|
+
provider,
|
|
14554
|
+
model,
|
|
14555
|
+
reasoningEffort: asString$1(header.config.reasoningEffort)
|
|
14556
|
+
};
|
|
14557
|
+
}
|
|
14558
|
+
return {
|
|
14559
|
+
provider: asString$1(agent?.options?.provider),
|
|
14560
|
+
model: asString$1(agent?.options?.model)
|
|
14561
|
+
};
|
|
14562
|
+
}
|
|
14493
14563
|
/** Whether an exact route is authorized by a allowlist. */
|
|
14494
14564
|
function routesInclude(allowed, provider, model) {
|
|
14495
14565
|
return allowed.some((route) => route.provider === provider && route.model === model);
|
|
@@ -14534,24 +14604,76 @@ function unauthorizedRouteReason(provider, model, allowed, explicit) {
|
|
|
14534
14604
|
return `subagent model selection: ${explicit ? "the model this call selected is not on the Session allowlist" : "the route this call would inherit from the parent is not on the Session allowlist"} (${route}). Provide an authorized provider and model — ${authorizedRoutesText(allowed)} — using list_subagent_models to inspect their reasoning efforts.`;
|
|
14535
14605
|
}
|
|
14536
14606
|
/**
|
|
14607
|
+
* Build the denial reason for an inherit-mode delegation that named a route.
|
|
14608
|
+
* The fork backend accepts no route parameters, so a named pair is not a
|
|
14609
|
+
* partial override the backend would ignore — it is a request to change the
|
|
14610
|
+
* route, which is exactly what an inherit-mode tool exists to prevent.
|
|
14611
|
+
* @param toolName - the tool the model called.
|
|
14612
|
+
* @param provider - the provider the call named.
|
|
14613
|
+
* @param model - the model the call named.
|
|
14614
|
+
* @returns the corrective reason handed back to the model.
|
|
14615
|
+
*/
|
|
14616
|
+
function inheritOverrideReason(toolName, provider, model) {
|
|
14617
|
+
return `subagent model selection: "${toolName}" always runs on the calling agent's own route and accepts no provider/model. This call named "${provider}/${model}". Remove those fields, or delegate through a tool that supports explicit child model selection.`;
|
|
14618
|
+
}
|
|
14619
|
+
/**
|
|
14620
|
+
* Build the denial reason for an inherit-mode delegation whose inherited route
|
|
14621
|
+
* is outside the allowlist. Unlike the explicit case this is not something the
|
|
14622
|
+
* call can fix by naming a route, so the reason points at the tool that can.
|
|
14623
|
+
* @param toolName - the tool the model called.
|
|
14624
|
+
* @param provider - the parent route the child would inherit, when known.
|
|
14625
|
+
* @param model - the parent model the child would inherit, when known.
|
|
14626
|
+
* @param allowed - Routes the calling Session authorizes.
|
|
14627
|
+
* @param reasoningEffort - the inherited effort, when the header recorded one.
|
|
14628
|
+
* @returns the corrective reason handed back to the model.
|
|
14629
|
+
*/
|
|
14630
|
+
function inheritRouteDenialReason(toolName, provider, model, allowed, reasoningEffort) {
|
|
14631
|
+
return `subagent model selection: "${toolName}" keeps its child on ${provider === void 0 || model === void 0 ? "the calling agent's route" : `"${provider}/${model}"${reasoningEffort === void 0 ? "" : ` (${reasoningEffort})`}`}, which this Session's allowlist does not authorize, so it is unavailable for now. Its child cannot be re-routed, so either delegate through a tool that exposes provider and model — passing one of ${authorizedRoutesText(allowed)} — or continue on an authorized model for this session, after which ${toolName} works again.`;
|
|
14632
|
+
}
|
|
14633
|
+
/**
|
|
14634
|
+
* Resolve one tool's enforcement mode from the configured policies. An
|
|
14635
|
+
* unconfigured name is `undefined`: the guard does not police it, which is how
|
|
14636
|
+
* the plain-name configuration keeps its existing meaning.
|
|
14637
|
+
* @param policies - Configured tool policies in precedence order.
|
|
14638
|
+
* @param toolName - Tool being dispatched.
|
|
14639
|
+
* @returns the first matching mode, or undefined when the guard ignores the tool.
|
|
14640
|
+
*/
|
|
14641
|
+
function delegationModeOf(policies, toolName) {
|
|
14642
|
+
for (const policy of policies) if (policy.name === toolName) return policy.mode;
|
|
14643
|
+
}
|
|
14644
|
+
/**
|
|
14537
14645
|
* Decide whether one delegation call may start its child.
|
|
14538
14646
|
* @param agent - Calling agent.
|
|
14539
14647
|
* @param toolName - Tool being dispatched.
|
|
14540
14648
|
* @param args - Parsed tool arguments.
|
|
14541
14649
|
* @param preference - Current Host preference, when the settings service exists.
|
|
14542
14650
|
* @param sessions - Session registry used for ancestor lookup.
|
|
14543
|
-
* @param toolNames - Delegation tool names this guard authorizes.
|
|
14651
|
+
* @param toolNames - Delegation tool names this guard authorizes (explicit mode).
|
|
14544
14652
|
* @param scope - Whether an unrecorded Session falls back to the preference.
|
|
14653
|
+
* @param inheritToolNames - Delegation tools that start a child on the caller's own route.
|
|
14545
14654
|
* @returns a denial reason, or undefined to leave the call untouched.
|
|
14546
14655
|
*/
|
|
14547
|
-
function delegationDenialReason(agent, toolName, args, preference, sessions, toolNames = DEFAULT_DELEGATION_TOOLS, scope = "session") {
|
|
14548
|
-
|
|
14656
|
+
function delegationDenialReason(agent, toolName, args, preference, sessions, toolNames = DEFAULT_DELEGATION_TOOLS, scope = "session", inheritToolNames = []) {
|
|
14657
|
+
const mode = delegationModeOf([...toolNames.map((name) => ({
|
|
14658
|
+
name,
|
|
14659
|
+
mode: "explicit"
|
|
14660
|
+
})), ...inheritToolNames.map((name) => ({
|
|
14661
|
+
name,
|
|
14662
|
+
mode: "inherit"
|
|
14663
|
+
}))], toolName);
|
|
14664
|
+
if (mode === void 0) return void 0;
|
|
14549
14665
|
if (preference !== void 0 && !preference.enabled) return void 0;
|
|
14550
14666
|
const allowed = authorizedRoutesFor(agent, sessions) ?? (scope === "preference" ? preference?.allowedModels ?? [] : []);
|
|
14551
14667
|
if (allowed.length === 0) return void 0;
|
|
14552
|
-
const request = asRecord(args) ?? {};
|
|
14553
|
-
const requestedProvider = asString(request["provider"]);
|
|
14554
|
-
const requestedModel = asString(request["model"]);
|
|
14668
|
+
const request = asRecord$1(args) ?? {};
|
|
14669
|
+
const requestedProvider = asString$1(request["provider"]);
|
|
14670
|
+
const requestedModel = asString$1(request["model"]);
|
|
14671
|
+
if (mode === "inherit") {
|
|
14672
|
+
if (requestedProvider !== void 0 && requestedModel !== void 0) return inheritOverrideReason(toolName, requestedProvider, requestedModel);
|
|
14673
|
+
const inherited = inheritedRouteOf(agent);
|
|
14674
|
+
if (inherited.provider !== void 0 && inherited.model !== void 0 && routesInclude(allowed, inherited.provider, inherited.model)) return void 0;
|
|
14675
|
+
return inheritRouteDenialReason(toolName, inherited.provider, inherited.model, allowed, inherited.reasoningEffort);
|
|
14676
|
+
}
|
|
14555
14677
|
if (requestedProvider === void 0) return requestedModel === void 0 ? missingRouteReason(allowed) : partialRouteReason("provider", requestedModel, allowed);
|
|
14556
14678
|
if (requestedModel === void 0) return partialRouteReason("model", requestedProvider, allowed);
|
|
14557
14679
|
if (routesInclude(allowed, requestedProvider, requestedModel)) return void 0;
|
|
@@ -14565,7 +14687,7 @@ function delegationDenialReason(agent, toolName, args, preference, sessions, too
|
|
|
14565
14687
|
* @returns a guard that denies delegations outside the Session allowlist.
|
|
14566
14688
|
*/
|
|
14567
14689
|
function createSubagentAuthorization(options) {
|
|
14568
|
-
return (agent, toolName, args) => delegationDenialReason(agent, toolName, args, subagentModelSelectionPreference(options.settings), options.sessions, options.toolNames, options.scope ?? "session");
|
|
14690
|
+
return (agent, toolName, args) => delegationDenialReason(agent, toolName, args, subagentModelSelectionPreference(options.settings), options.sessions, options.toolNames, options.scope ?? "session", options.inheritToolNames ?? []);
|
|
14569
14691
|
}
|
|
14570
14692
|
/** Delegation names this guard recognizes when configuration omits them. */
|
|
14571
14693
|
function normalizeDelegationToolNames(value) {
|
|
@@ -14573,6 +14695,29 @@ function normalizeDelegationToolNames(value) {
|
|
|
14573
14695
|
return [...new Set(names.length === 0 ? [...DEFAULT_DELEGATION_TOOLS] : names.map((name) => name.trim()))];
|
|
14574
14696
|
}
|
|
14575
14697
|
/**
|
|
14698
|
+
* Normalize the configured inherit-mode names. Unlike
|
|
14699
|
+
* {@link normalizeDelegationToolNames}, an empty array is a deliberate opt-out
|
|
14700
|
+
* (`[]`) rather than a request for the default, and `undefined` selects the
|
|
14701
|
+
* shipped default.
|
|
14702
|
+
* @param value - Candidate configuration value.
|
|
14703
|
+
* @returns the exact inherit-mode names this guard enforces.
|
|
14704
|
+
*/
|
|
14705
|
+
function normalizeInheritToolNames(value) {
|
|
14706
|
+
if (value === void 0) return [...DEFAULT_SUBAGENT_INHERIT_TOOLS];
|
|
14707
|
+
const names = Array.isArray(value) ? value.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
|
|
14708
|
+
return [...new Set(names.map((name) => name.trim()))];
|
|
14709
|
+
}
|
|
14710
|
+
/**
|
|
14711
|
+
* Validate the configured inherit-mode names. Emptiness is legal here — it
|
|
14712
|
+
* disables inherit enforcement — but a malformed entry is not.
|
|
14713
|
+
* @param toolNames - Candidate inherit-mode delegation tool names.
|
|
14714
|
+
* @returns the exact names this guard enforces in inherit mode.
|
|
14715
|
+
*/
|
|
14716
|
+
function validateInheritToolNames(toolNames) {
|
|
14717
|
+
for (const name of toolNames) if (name.length === 0 || name !== name.trim()) throw new Error(`dsh-chatgpt-subscription: subagentModelInheritTools entry "${name}" must be a non-empty trimmed string`);
|
|
14718
|
+
return [...toolNames];
|
|
14719
|
+
}
|
|
14720
|
+
/**
|
|
14576
14721
|
* Validate the plugin configuration that owns this guard.
|
|
14577
14722
|
* @param toolNames - Candidate delegation tool names.
|
|
14578
14723
|
* @returns the exact names this guard authorizes.
|
|
@@ -14591,12 +14736,15 @@ function validateDelegationToolNames(toolNames) {
|
|
|
14591
14736
|
*/
|
|
14592
14737
|
function installSubagentModelAuthorization(ctx, sessions, config = {}) {
|
|
14593
14738
|
const toolNames = validateDelegationToolNames(config.toolNames ?? [...DEFAULT_DELEGATION_TOOLS]);
|
|
14739
|
+
const inheritToolNames = validateInheritToolNames(config.inheritToolNames ?? []);
|
|
14740
|
+
if (inheritToolNames.some((name) => toolNames.includes(name))) throw new Error(`dsh-chatgpt-subscription: a delegation tool cannot be both an explicit and an inherit tool (${inheritToolNames.filter((name) => toolNames.includes(name)).join(", ")})`);
|
|
14594
14741
|
const scope = validateAuthorizationScope(config.scope ?? "session");
|
|
14595
14742
|
const settings = ctx.get?.("settings");
|
|
14596
14743
|
const authorize = createSubagentAuthorization({
|
|
14597
14744
|
settings,
|
|
14598
14745
|
sessions,
|
|
14599
14746
|
toolNames,
|
|
14747
|
+
inheritToolNames,
|
|
14600
14748
|
scope
|
|
14601
14749
|
});
|
|
14602
14750
|
return ctx.tools.guard((exec) => authorize(exec.agent, exec.name, exec.arguments));
|
|
@@ -14632,12 +14780,128 @@ function validateAuthorizationScope(scope) {
|
|
|
14632
14780
|
* Windows it can abort the process with STATUS_STACK_BUFFER_OVERRUN when the
|
|
14633
14781
|
* source path contains non-ASCII characters (nodejs/node#54476). The copy is
|
|
14634
14782
|
* per-entry instead, which also lets source mtimes ride along.
|
|
14783
|
+
*
|
|
14784
|
+
* A preset row names the package it mounts, so a name the running installation
|
|
14785
|
+
* does not ship makes the whole preset unresolvable. Text naming a package the
|
|
14786
|
+
* harness renamed is therefore reconciled with the installation before it is
|
|
14787
|
+
* compared or written.
|
|
14635
14788
|
* @module dsh-chatgpt-subscription/preset-sync
|
|
14636
14789
|
*/
|
|
14637
14790
|
/** The preset directory this package ships. */
|
|
14638
14791
|
const BUNDLED_PRESET_IDS = ["dispatch"];
|
|
14639
14792
|
/** Clock tolerance for the mtime fast path before falling through to a byte compare. */
|
|
14640
14793
|
const MTIME_TOLERANCE_MS = 1e3;
|
|
14794
|
+
/** Extensions whose text may name a package. */
|
|
14795
|
+
const REWRITABLE_EXTENSIONS = [".yml", ".yaml"];
|
|
14796
|
+
/**
|
|
14797
|
+
* Package names the harness renamed, mapped to the name that replaced each.
|
|
14798
|
+
*
|
|
14799
|
+
* Harness 0.1.6 renamed `workflow-worker-thread` to `workflow-ptc`; every
|
|
14800
|
+
* earlier release ships only the former. The bundled preset carries the
|
|
14801
|
+
* earlier spelling, which the sync replaces when the installation ships the
|
|
14802
|
+
* later one.
|
|
14803
|
+
*/
|
|
14804
|
+
const RENAMED_PACKAGES = /* @__PURE__ */ new Map([["@deepseek-ai/dsh-workflow-worker-thread", "@deepseek-ai/dsh-workflow-ptc"]]);
|
|
14805
|
+
/**
|
|
14806
|
+
* Packages whose row some supported harness generation does not ship at all.
|
|
14807
|
+
*
|
|
14808
|
+
* An enabled row naming a package the installation cannot resolve makes the
|
|
14809
|
+
* whole preset unresolvable — the roster reports it broken, which is worse than
|
|
14810
|
+
* a missing row because a broken preset can be neither selected nor copied. The
|
|
14811
|
+
* roster skips a `disabled` row in that check, so the sync disables a row whose
|
|
14812
|
+
* package is absent, and the next boot that ships the package re-enables it.
|
|
14813
|
+
*
|
|
14814
|
+
* The set is deliberately explicit rather than "every row that fails to
|
|
14815
|
+
* resolve": a resolver that fails on a working installation would then strip
|
|
14816
|
+
* the preset down to nothing, a quieter failure than the one it fixes.
|
|
14817
|
+
*/
|
|
14818
|
+
const OPTIONALLY_ABSENT_PACKAGES = ["@deepseek-ai/dsh-tool-present"];
|
|
14819
|
+
/**
|
|
14820
|
+
* Whether a bare specifier resolves from this module in the running
|
|
14821
|
+
* installation. A harness whose Node build exposes no `import.meta.resolve`
|
|
14822
|
+
* answers `false` for everything, which leaves every bundled spelling in place.
|
|
14823
|
+
* @param specifier - bare package specifier.
|
|
14824
|
+
* @returns whether the specifier resolves.
|
|
14825
|
+
*/
|
|
14826
|
+
function resolvesFromHere(specifier) {
|
|
14827
|
+
const resolve = import.meta.resolve;
|
|
14828
|
+
if (resolve === void 0) return false;
|
|
14829
|
+
try {
|
|
14830
|
+
resolve(specifier);
|
|
14831
|
+
return true;
|
|
14832
|
+
} catch {
|
|
14833
|
+
return false;
|
|
14834
|
+
}
|
|
14835
|
+
}
|
|
14836
|
+
/**
|
|
14837
|
+
* Point every renamed package name at the spelling this installation ships.
|
|
14838
|
+
*
|
|
14839
|
+
* A name that still resolves is left alone, and so is a rename whose
|
|
14840
|
+
* replacement does not resolve: with neither spelling present the preset is
|
|
14841
|
+
* unresolvable either way, and rewriting would only hide which name was tried.
|
|
14842
|
+
* @param content - bundled preset file text.
|
|
14843
|
+
* @param resolves - whether a bare specifier resolves in this installation.
|
|
14844
|
+
* @returns the text to write, equal to `content` when no rename applies.
|
|
14845
|
+
*/
|
|
14846
|
+
function reconcilePackageNames(content, resolves) {
|
|
14847
|
+
let out = content;
|
|
14848
|
+
for (const [renamed, current] of RENAMED_PACKAGES) {
|
|
14849
|
+
if (!out.includes(renamed)) continue;
|
|
14850
|
+
if (resolves(renamed) || !resolves(current)) continue;
|
|
14851
|
+
out = out.split(renamed).join(current);
|
|
14852
|
+
}
|
|
14853
|
+
return out;
|
|
14854
|
+
}
|
|
14855
|
+
/** Leading spaces of one line — the indentation its YAML keys share. */
|
|
14856
|
+
function indentationOf(line) {
|
|
14857
|
+
return line.length - line.trimStart().length;
|
|
14858
|
+
}
|
|
14859
|
+
/** The package a row line mounts, when the line is a row's `name:` key. */
|
|
14860
|
+
function rowPackageName(line) {
|
|
14861
|
+
return /^\s*name:\s*'([^']+)'\s*$/.exec(line)?.[1];
|
|
14862
|
+
}
|
|
14863
|
+
/** Whether the row whose `name:` key sits at `index` already declares `disabled`. */
|
|
14864
|
+
function rowDeclaresDisabled(lines, index) {
|
|
14865
|
+
const indent = indentationOf(lines[index] ?? "");
|
|
14866
|
+
for (const line of lines.slice(index + 1)) {
|
|
14867
|
+
if (line.trim() === "") continue;
|
|
14868
|
+
const own = indentationOf(line);
|
|
14869
|
+
if (own < indent) return false;
|
|
14870
|
+
if (own === indent && line.trimStart().startsWith("disabled:")) return true;
|
|
14871
|
+
}
|
|
14872
|
+
return false;
|
|
14873
|
+
}
|
|
14874
|
+
/**
|
|
14875
|
+
* Disable every row whose package this installation does not ship.
|
|
14876
|
+
* @param content - preset file text.
|
|
14877
|
+
* @param resolves - whether a bare specifier resolves in this installation.
|
|
14878
|
+
* @returns the text to write, equal to `content` when no row is affected.
|
|
14879
|
+
*/
|
|
14880
|
+
function disableRowsForAbsentPackages(content, resolves) {
|
|
14881
|
+
const lines = content.split("\n");
|
|
14882
|
+
const out = [];
|
|
14883
|
+
for (const [index, line] of lines.entries()) {
|
|
14884
|
+
out.push(line);
|
|
14885
|
+
const specifier = rowPackageName(line);
|
|
14886
|
+
if (specifier === void 0 || !OPTIONALLY_ABSENT_PACKAGES.includes(specifier)) continue;
|
|
14887
|
+
if (resolves(specifier) || rowDeclaresDisabled(lines, index)) continue;
|
|
14888
|
+
out.push(`${" ".repeat(indentationOf(line))}disabled: true`);
|
|
14889
|
+
}
|
|
14890
|
+
return out.join("\n");
|
|
14891
|
+
}
|
|
14892
|
+
/**
|
|
14893
|
+
* Reconcile one bundled preset file with the packages this installation ships:
|
|
14894
|
+
* a renamed package takes the spelling it carries, and a row it cannot mount is
|
|
14895
|
+
* disabled rather than left to mark the whole preset unresolvable.
|
|
14896
|
+
* @param content - bundled preset file text.
|
|
14897
|
+
* @param resolves - whether a bare specifier resolves in this installation.
|
|
14898
|
+
* @returns the text to write.
|
|
14899
|
+
*/
|
|
14900
|
+
function reconcilePreset(content, resolves) {
|
|
14901
|
+
return disableRowsForAbsentPackages(reconcilePackageNames(content, resolves), resolves);
|
|
14902
|
+
}
|
|
14903
|
+
/** Rewrite bundled preset text for the packages this installation ships. */
|
|
14904
|
+
const rewritePresetFile = (_relativePath, content) => reconcilePreset(content, resolvesFromHere);
|
|
14641
14905
|
/**
|
|
14642
14906
|
* The package root, found by walking up from this module to the nearest
|
|
14643
14907
|
* `package.json`.
|
|
@@ -14725,12 +14989,34 @@ function copyTreeSync(sourceDir, targetDir) {
|
|
|
14725
14989
|
}
|
|
14726
14990
|
}
|
|
14727
14991
|
/**
|
|
14992
|
+
* Text files below `sourceDir` whose content `rewrite` changes, keyed by path
|
|
14993
|
+
* relative to `sourceDir`.
|
|
14994
|
+
* @param sourceDir - bundled preset directory.
|
|
14995
|
+
* @param rewrite - text rewrite for the running installation.
|
|
14996
|
+
* @returns replacement text per changed file.
|
|
14997
|
+
*/
|
|
14998
|
+
function collectRewrites(sourceDir, rewrite) {
|
|
14999
|
+
const rewrites = /* @__PURE__ */ new Map();
|
|
15000
|
+
for (const file of filesUnder(sourceDir)) {
|
|
15001
|
+
if (!REWRITABLE_EXTENSIONS.some((extension) => file.endsWith(extension))) continue;
|
|
15002
|
+
const content = readFileSync(file, "utf8");
|
|
15003
|
+
const rewritten = rewrite(relative(sourceDir, file), content);
|
|
15004
|
+
if (rewritten !== content) rewrites.set(relative(sourceDir, file), rewritten);
|
|
15005
|
+
}
|
|
15006
|
+
return rewrites;
|
|
15007
|
+
}
|
|
15008
|
+
/** Write the replacement text of every rewritten file below `targetDir`. */
|
|
15009
|
+
function writeRewrites(targetDir, rewrites) {
|
|
15010
|
+
for (const [rel, content] of rewrites) writeFileSync(join(targetDir, rel), content);
|
|
15011
|
+
}
|
|
15012
|
+
/**
|
|
14728
15013
|
* Copy `sourceDir` into `targetDir` idempotently.
|
|
14729
15014
|
* @param sourceDir - bundled preset directory.
|
|
14730
15015
|
* @param targetDir - discovery-root directory for the same preset id.
|
|
15016
|
+
* @param rewrites - replacement text by path relative to `sourceDir`; a rewritten file is compared by content, since its target carries no source mtime.
|
|
14731
15017
|
* @returns whether anything was written.
|
|
14732
15018
|
*/
|
|
14733
|
-
function syncOnePreset(sourceDir, targetDir) {
|
|
15019
|
+
function syncOnePreset(sourceDir, targetDir, rewrites = /* @__PURE__ */ new Map()) {
|
|
14734
15020
|
const sourceFiles = filesUnder(sourceDir);
|
|
14735
15021
|
const sourceSet = new Set(sourceFiles.map((file) => relative(sourceDir, file)));
|
|
14736
15022
|
if (existsSync(targetDir) && !statSync(targetDir).isDirectory()) rmSync(targetDir, {
|
|
@@ -14739,12 +15025,22 @@ function syncOnePreset(sourceDir, targetDir) {
|
|
|
14739
15025
|
});
|
|
14740
15026
|
if (!existsSync(targetDir)) {
|
|
14741
15027
|
copyTreeSync(sourceDir, targetDir);
|
|
15028
|
+
writeRewrites(targetDir, rewrites);
|
|
14742
15029
|
pruneExtras(targetDir, sourceSet);
|
|
14743
15030
|
return "synced";
|
|
14744
15031
|
}
|
|
14745
15032
|
let dirty = false;
|
|
14746
15033
|
for (const file of sourceFiles) {
|
|
14747
|
-
const
|
|
15034
|
+
const rel = relative(sourceDir, file);
|
|
15035
|
+
const dest = join(targetDir, rel);
|
|
15036
|
+
const replacement = rewrites.get(rel);
|
|
15037
|
+
if (replacement !== void 0) {
|
|
15038
|
+
if (!existsSync(dest) || readFileSync(dest, "utf8") !== replacement) {
|
|
15039
|
+
dirty = true;
|
|
15040
|
+
break;
|
|
15041
|
+
}
|
|
15042
|
+
continue;
|
|
15043
|
+
}
|
|
14748
15044
|
if (!existsSync(dest) || !sameFile(file, dest)) {
|
|
14749
15045
|
dirty = true;
|
|
14750
15046
|
break;
|
|
@@ -14759,6 +15055,7 @@ function syncOnePreset(sourceDir, targetDir) {
|
|
|
14759
15055
|
if (!dirty) return "current";
|
|
14760
15056
|
pruneExtras(targetDir, sourceSet);
|
|
14761
15057
|
copyTreeSync(sourceDir, targetDir);
|
|
15058
|
+
writeRewrites(targetDir, rewrites);
|
|
14762
15059
|
pruneExtras(targetDir, sourceSet);
|
|
14763
15060
|
return "synced";
|
|
14764
15061
|
}
|
|
@@ -14769,9 +15066,10 @@ function syncOnePreset(sourceDir, targetDir) {
|
|
|
14769
15066
|
* @param sourceRoot - this package's bundled `presets/` directory.
|
|
14770
15067
|
* @param targetRoot - harness-home agent-presets discovery root.
|
|
14771
15068
|
* @param retire - previously bundled preset ids to remove when absent from the source.
|
|
15069
|
+
* @param rewrite - rewrites preset text for the running installation; omission copies the bundle verbatim.
|
|
14772
15070
|
* @returns the grouped outcome of the run.
|
|
14773
15071
|
*/
|
|
14774
|
-
function syncPresetTrees(sourceRoot, targetRoot, retire = []) {
|
|
15072
|
+
function syncPresetTrees(sourceRoot, targetRoot, retire = [], rewrite) {
|
|
14775
15073
|
const result = {
|
|
14776
15074
|
synced: [],
|
|
14777
15075
|
current: [],
|
|
@@ -14787,7 +15085,8 @@ function syncPresetTrees(sourceRoot, targetRoot, retire = []) {
|
|
|
14787
15085
|
const id = basename(source);
|
|
14788
15086
|
shipped.add(id);
|
|
14789
15087
|
try {
|
|
14790
|
-
|
|
15088
|
+
const rewrites = rewrite === void 0 ? /* @__PURE__ */ new Map() : collectRewrites(source, rewrite);
|
|
15089
|
+
if (syncOnePreset(source, join(targetRoot, id), rewrites) === "synced") result.synced.push(id);
|
|
14791
15090
|
else result.current.push(id);
|
|
14792
15091
|
} catch (error) {
|
|
14793
15092
|
result.failed.push({
|
|
@@ -14816,6 +15115,213 @@ function syncPresetTrees(sourceRoot, targetRoot, retire = []) {
|
|
|
14816
15115
|
return result;
|
|
14817
15116
|
}
|
|
14818
15117
|
//#endregion
|
|
15118
|
+
//#region src/host/subagent-route-audit.ts
|
|
15119
|
+
/**
|
|
15120
|
+
* Read one field as a string.
|
|
15121
|
+
* @param value - Candidate value from a durable event or header.
|
|
15122
|
+
* @returns the string, or undefined for any other type.
|
|
15123
|
+
*/
|
|
15124
|
+
function asString(value) {
|
|
15125
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
15126
|
+
}
|
|
15127
|
+
/**
|
|
15128
|
+
* Read one field as a plain object.
|
|
15129
|
+
* @param value - Candidate value.
|
|
15130
|
+
* @returns the record, or undefined for arrays, null, and primitives.
|
|
15131
|
+
*/
|
|
15132
|
+
function asRecord(value) {
|
|
15133
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
15134
|
+
}
|
|
15135
|
+
/**
|
|
15136
|
+
* Extract the child route a descriptor recorded.
|
|
15137
|
+
* @param data - `subagent/descriptor` payload.
|
|
15138
|
+
* @returns the declared route fields plus provider and label, each when present.
|
|
15139
|
+
*/
|
|
15140
|
+
function readChildDescriptor(data) {
|
|
15141
|
+
const record = asRecord(data);
|
|
15142
|
+
if (record === void 0) return void 0;
|
|
15143
|
+
const provider = asString(record["provider"]);
|
|
15144
|
+
const childProvider = asString(record["agentProvider"]);
|
|
15145
|
+
const childModel = asString(record["agentModel"]);
|
|
15146
|
+
const label = asString(record["label"]);
|
|
15147
|
+
if (provider === void 0 && childProvider === void 0 && childModel === void 0) return void 0;
|
|
15148
|
+
return {
|
|
15149
|
+
...provider === void 0 ? {} : { provider },
|
|
15150
|
+
...childProvider === void 0 ? {} : { childProvider },
|
|
15151
|
+
...childModel === void 0 ? {} : { childModel },
|
|
15152
|
+
...label === void 0 ? {} : { label }
|
|
15153
|
+
};
|
|
15154
|
+
}
|
|
15155
|
+
/**
|
|
15156
|
+
* Read the child-route allowlist a session recorded, from its own log.
|
|
15157
|
+
*
|
|
15158
|
+
* The live guard reads the same event through `policyRoutesOf`, which walks a
|
|
15159
|
+
* session's `eventAt` accessor. The audit holds a resolved session instead, so
|
|
15160
|
+
* it scans the snapshot it already has rather than reopening the log per child.
|
|
15161
|
+
* @param session - the session whose policy is read.
|
|
15162
|
+
* @returns the authorized routes, or undefined when the session recorded none.
|
|
15163
|
+
*/
|
|
15164
|
+
function auditedRoutesOf(session) {
|
|
15165
|
+
for (const event of session.events ?? []) {
|
|
15166
|
+
if (event.type !== "subagent/model-selection-policy") continue;
|
|
15167
|
+
const allowed = asRecord(event.data)?.["allowedModels"];
|
|
15168
|
+
if (!Array.isArray(allowed)) continue;
|
|
15169
|
+
const routes = [];
|
|
15170
|
+
for (const entry of allowed) {
|
|
15171
|
+
const provider = asString(asRecord(entry)?.["provider"]);
|
|
15172
|
+
const model = asString(asRecord(entry)?.["model"]);
|
|
15173
|
+
if (provider !== void 0 && model !== void 0) routes.push({
|
|
15174
|
+
provider,
|
|
15175
|
+
model
|
|
15176
|
+
});
|
|
15177
|
+
}
|
|
15178
|
+
if (routes.length > 0) return routes;
|
|
15179
|
+
}
|
|
15180
|
+
}
|
|
15181
|
+
/**
|
|
15182
|
+
* Collect the child routes one parent session recorded.
|
|
15183
|
+
*
|
|
15184
|
+
* Discovery uses both durable signals because they cover different backends: a
|
|
15185
|
+
* `subagent/catalog` event names every continuable child the parent created,
|
|
15186
|
+
* while a descriptor-less or one-shot child is only reachable by scanning the
|
|
15187
|
+
* registry for a session whose header names this parent.
|
|
15188
|
+
* @param parent - the parent session to inspect.
|
|
15189
|
+
* @param sessions - registry used to resolve each child's own log and header.
|
|
15190
|
+
* @returns one finding per child whose route could be read.
|
|
15191
|
+
*/
|
|
15192
|
+
function childRoutesOf(parent, sessions) {
|
|
15193
|
+
const parentId = asString(parent.id);
|
|
15194
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15195
|
+
const findings = [];
|
|
15196
|
+
const inspect = (child, childId) => {
|
|
15197
|
+
if (child === void 0 || seen.has(childId)) return;
|
|
15198
|
+
seen.add(childId);
|
|
15199
|
+
const descriptor = child.events?.map((event) => event.type === "subagent/descriptor" ? readChildDescriptor(event.data) : void 0).find((entry) => entry !== void 0);
|
|
15200
|
+
if (descriptor === void 0) return;
|
|
15201
|
+
const headerParent = asString(child.header?.parentSession);
|
|
15202
|
+
findings.push({
|
|
15203
|
+
childId,
|
|
15204
|
+
...headerParent === void 0 ? {} : { parentId: headerParent },
|
|
15205
|
+
...descriptor
|
|
15206
|
+
});
|
|
15207
|
+
};
|
|
15208
|
+
for (const event of parent.events ?? []) {
|
|
15209
|
+
if (event.type !== "subagent/catalog") continue;
|
|
15210
|
+
const childId = asString(asRecord(event.data)?.["childId"]);
|
|
15211
|
+
if (childId === void 0) continue;
|
|
15212
|
+
inspect(sessions.get(childId), childId);
|
|
15213
|
+
}
|
|
15214
|
+
if (parentId !== void 0) for (const child of listSessions(sessions)) {
|
|
15215
|
+
const childId = asString(child.id);
|
|
15216
|
+
if (childId === void 0 || childId === parentId) continue;
|
|
15217
|
+
if (asString(child.header?.parentSession) !== parentId) continue;
|
|
15218
|
+
inspect(child, childId);
|
|
15219
|
+
}
|
|
15220
|
+
return findings;
|
|
15221
|
+
}
|
|
15222
|
+
/**
|
|
15223
|
+
* Enumerate the registry, tolerating a resolver that exposes no listing.
|
|
15224
|
+
* @param sessions - the resolver to enumerate.
|
|
15225
|
+
* @returns every session it can serve, or an empty array.
|
|
15226
|
+
*/
|
|
15227
|
+
function listSessions(sessions) {
|
|
15228
|
+
const list = sessions.list;
|
|
15229
|
+
if (typeof list !== "function") return [];
|
|
15230
|
+
try {
|
|
15231
|
+
const entries = list.call(sessions);
|
|
15232
|
+
return Array.isArray(entries) ? entries : [];
|
|
15233
|
+
} catch {
|
|
15234
|
+
return [];
|
|
15235
|
+
}
|
|
15236
|
+
}
|
|
15237
|
+
/**
|
|
15238
|
+
* Read the route a session's next request would use: its latest request header,
|
|
15239
|
+
* else its declared creation options. A child that recorded no route of its own
|
|
15240
|
+
* runs here, and this is also the baseline a recorded child route is compared
|
|
15241
|
+
* against.
|
|
15242
|
+
* @param session - the session to read.
|
|
15243
|
+
* @returns the route fields, each absent when its source did not supply it.
|
|
15244
|
+
*/
|
|
15245
|
+
function sessionRouteOf(session) {
|
|
15246
|
+
const config = asRecord(asRecord(session?.requestHeader?.())?.["config"]);
|
|
15247
|
+
const provider = asString(config?.["provider"]);
|
|
15248
|
+
const model = asString(config?.["model"]);
|
|
15249
|
+
if (provider !== void 0 || model !== void 0) return {
|
|
15250
|
+
...provider === void 0 ? {} : { provider },
|
|
15251
|
+
...model === void 0 ? {} : { model }
|
|
15252
|
+
};
|
|
15253
|
+
const options = asRecord(session?.options);
|
|
15254
|
+
return {
|
|
15255
|
+
...asString(options?.["provider"]) === void 0 ? {} : { provider: asString(options?.["provider"]) },
|
|
15256
|
+
...asString(options?.["model"]) === void 0 ? {} : { model: asString(options?.["model"]) }
|
|
15257
|
+
};
|
|
15258
|
+
}
|
|
15259
|
+
/**
|
|
15260
|
+
* Resolve the route a finding actually ran on, following the parent when the
|
|
15261
|
+
* child recorded none, and report whether it matches the parent's.
|
|
15262
|
+
* @param finding - the child under audit.
|
|
15263
|
+
* @param sessions - registry used to resolve the parent.
|
|
15264
|
+
* @returns the effective route and whether it equals the parent's route.
|
|
15265
|
+
*/
|
|
15266
|
+
function effectiveRouteOf(finding, sessions) {
|
|
15267
|
+
const parentRoute = finding.parentId === void 0 ? {} : sessionRouteOf(sessions.get(finding.parentId));
|
|
15268
|
+
const route = finding.childProvider !== void 0 || finding.childModel !== void 0 ? {
|
|
15269
|
+
provider: finding.childProvider,
|
|
15270
|
+
model: finding.childModel
|
|
15271
|
+
} : parentRoute;
|
|
15272
|
+
return {
|
|
15273
|
+
...route,
|
|
15274
|
+
sameAsParent: route.provider !== void 0 && route.model !== void 0 && parentRoute.provider === route.provider && parentRoute.model === route.model
|
|
15275
|
+
};
|
|
15276
|
+
}
|
|
15277
|
+
/**
|
|
15278
|
+
* Decide whether one effective route is covered by an allowlist.
|
|
15279
|
+
* @param allowed - routes the governing Session authorized.
|
|
15280
|
+
* @param route - the route the child actually ran on.
|
|
15281
|
+
* @returns whether the route is authorized.
|
|
15282
|
+
*/
|
|
15283
|
+
function routeAllowed(allowed, route) {
|
|
15284
|
+
if (route.provider === void 0 || route.model === void 0) return true;
|
|
15285
|
+
return allowed.some((entry) => entry.provider === route.provider && entry.model === route.model);
|
|
15286
|
+
}
|
|
15287
|
+
/**
|
|
15288
|
+
* Fold one parent session's children into the violations worth reporting.
|
|
15289
|
+
* A finding with an unresolvable route is reported as neither: guessing would
|
|
15290
|
+
* turn this advisory list into a source of false accusations.
|
|
15291
|
+
* @param parent - the parent session to audit.
|
|
15292
|
+
* @param sessions - registry used to resolve children and parents.
|
|
15293
|
+
* @param allowed - routes the parent Session authorized, when it recorded any.
|
|
15294
|
+
* @returns violations, ordered as the children were discovered.
|
|
15295
|
+
*/
|
|
15296
|
+
function auditChildRoutes(parent, sessions, allowed) {
|
|
15297
|
+
if (allowed === void 0 || allowed.length === 0) return [];
|
|
15298
|
+
const violations = [];
|
|
15299
|
+
for (const finding of childRoutesOf(parent, sessions)) {
|
|
15300
|
+
const effective = effectiveRouteOf(finding, sessions);
|
|
15301
|
+
if (routeAllowed(allowed, effective)) continue;
|
|
15302
|
+
violations.push({
|
|
15303
|
+
finding,
|
|
15304
|
+
route: {
|
|
15305
|
+
provider: effective.provider,
|
|
15306
|
+
model: effective.model
|
|
15307
|
+
},
|
|
15308
|
+
sameAsParent: effective.sameAsParent
|
|
15309
|
+
});
|
|
15310
|
+
}
|
|
15311
|
+
return violations;
|
|
15312
|
+
}
|
|
15313
|
+
/**
|
|
15314
|
+
* Render one violation as a single model-facing line.
|
|
15315
|
+
* @param violation - the violation to describe.
|
|
15316
|
+
* @returns a one-line summary naming the child, its route, and its origin.
|
|
15317
|
+
*/
|
|
15318
|
+
function violationText(violation) {
|
|
15319
|
+
const { finding, route, sameAsParent } = violation;
|
|
15320
|
+
const label = finding.label === void 0 ? "" : ` "${finding.label}"`;
|
|
15321
|
+
const where = route.provider === void 0 || route.model === void 0 ? "an unresolved route" : `${route.provider}/${route.model}`;
|
|
15322
|
+
return `subagent ${finding.childId}${label} ran on ${where}${sameAsParent ? " — the same route as its parent" : " — a route of its own"}${finding.provider === void 0 ? "" : ` (provider "${finding.provider}")`}`;
|
|
15323
|
+
}
|
|
15324
|
+
//#endregion
|
|
14819
15325
|
//#region src/host/relay-probe.ts
|
|
14820
15326
|
/**
|
|
14821
15327
|
* Read-only diagnostic probe for the child→parent subagent relay.
|
|
@@ -15198,6 +15704,7 @@ const Config = z.object({
|
|
|
15198
15704
|
syncAgentPresets: z.boolean().default(true),
|
|
15199
15705
|
subagentModelAuthorization: z.boolean().default(true),
|
|
15200
15706
|
subagentModelTools: z.array(z.string()).default([]),
|
|
15707
|
+
subagentModelInheritTools: z.array(z.string()).default(DEFAULT_SUBAGENT_INHERIT_TOOLS),
|
|
15201
15708
|
subagentModelScope: z.union([z.const("session"), z.const("preference")]).default("session")
|
|
15202
15709
|
});
|
|
15203
15710
|
const inject = [
|
|
@@ -15212,7 +15719,7 @@ function apply(ctx, pluginConfig = {}) {
|
|
|
15212
15719
|
if (pluginConfig.syncAgentPresets !== false) ctx.effect(() => {
|
|
15213
15720
|
try {
|
|
15214
15721
|
const target = presetTargetRoot(dshHomeDir());
|
|
15215
|
-
const result = syncPresetTrees(bundledPresetsRoot(), target, [...BUNDLED_PRESET_IDS]);
|
|
15722
|
+
const result = syncPresetTrees(bundledPresetsRoot(), target, [...BUNDLED_PRESET_IDS], rewritePresetFile);
|
|
15216
15723
|
for (const { id, error } of result.failed) ctx.logger.warn(`[dsh-chatgpt-subscription] agent preset "${id}" sync failed: ${error}`);
|
|
15217
15724
|
if (result.synced.length > 0) ctx.logger.info(`[dsh-chatgpt-subscription] agent presets synced into ${target}: ${result.synced.join(", ")}`);
|
|
15218
15725
|
} catch (error) {
|
|
@@ -15232,6 +15739,7 @@ function apply(ctx, pluginConfig = {}) {
|
|
|
15232
15739
|
const kimiCodeModelSettings = new FileModelSettingsStore$2();
|
|
15233
15740
|
const kimiCodePreferences = registerKimiCodePreferenceStore(ctx.settings, kimiCodeModelSettings);
|
|
15234
15741
|
const delegationToolNames = normalizeDelegationToolNames(pluginConfig.subagentModelTools);
|
|
15742
|
+
const delegationInheritNames = normalizeInheritToolNames(pluginConfig.subagentModelInheritTools);
|
|
15235
15743
|
if (pluginConfig.subagentModelAuthorization !== false) ctx.inject(["sessions"], (scoped) => {
|
|
15236
15744
|
const sessions = scoped.get("sessions");
|
|
15237
15745
|
if (sessions === void 0) return;
|
|
@@ -15239,6 +15747,7 @@ function apply(ctx, pluginConfig = {}) {
|
|
|
15239
15747
|
if (typeof scoped.tools?.guard !== "function") return () => void 0;
|
|
15240
15748
|
return installSubagentModelAuthorization(scoped, sessions, {
|
|
15241
15749
|
toolNames: delegationToolNames,
|
|
15750
|
+
inheritToolNames: delegationInheritNames,
|
|
15242
15751
|
scope: pluginConfig.subagentModelScope ?? "session"
|
|
15243
15752
|
});
|
|
15244
15753
|
}, "dsh-chatgpt-subscription: subagent model authorization");
|
|
@@ -15342,7 +15851,29 @@ function apply(ctx, pluginConfig = {}) {
|
|
|
15342
15851
|
ctx.logger.warn(`[dsh-chatgpt-subscription] Web provider selection could not be applied: ${error instanceof Error ? error.message : String(error)}`);
|
|
15343
15852
|
});
|
|
15344
15853
|
};
|
|
15345
|
-
const
|
|
15854
|
+
const readRouteAudit = (sessionId) => {
|
|
15855
|
+
const sessions = ctx.get("sessions");
|
|
15856
|
+
const target = sessions.get(sessionId);
|
|
15857
|
+
if (target === void 0) throw new Error(`Unknown session "${sessionId}".`);
|
|
15858
|
+
const allowed = auditedRoutesOf(target);
|
|
15859
|
+
return Promise.resolve({
|
|
15860
|
+
sessionId,
|
|
15861
|
+
allowedModels: (allowed ?? []).map((route) => ({
|
|
15862
|
+
provider: route.provider,
|
|
15863
|
+
model: route.model
|
|
15864
|
+
})),
|
|
15865
|
+
violations: auditChildRoutes(target, sessions, allowed).map((violation) => ({
|
|
15866
|
+
childId: violation.finding.childId,
|
|
15867
|
+
parentId: violation.finding.parentId ?? null,
|
|
15868
|
+
provider: violation.finding.provider ?? null,
|
|
15869
|
+
label: violation.finding.label ?? null,
|
|
15870
|
+
routeProvider: violation.route.provider ?? null,
|
|
15871
|
+
routeModel: violation.route.model ?? null,
|
|
15872
|
+
sameAsParent: violation.sameAsParent
|
|
15873
|
+
}))
|
|
15874
|
+
});
|
|
15875
|
+
};
|
|
15876
|
+
const disposeRoutes = registerRoutes(ctx, oauth, usage, preferences, proxyManager, searchSwitcher, readRouteAudit);
|
|
15346
15877
|
const disposeAdapter = ctx.llm.registerAdapter([PROVIDER_ID$3], adapter);
|
|
15347
15878
|
const disposeImageTool = ctx.tools.register(createCodexImageTool(oauth, ctx.attachments, { fetchFn: proxyFetch }));
|
|
15348
15879
|
const disposeVideoTool = ctx.tools.register(createKimiVideoTool(ctx, { fetchFn: proxyFetch }));
|
|
@@ -15392,4 +15923,4 @@ function localWebServerBaseUrl(host, port) {
|
|
|
15392
15923
|
return `http://${host === "0.0.0.0" ? "127.0.0.1" : host}:${port}`;
|
|
15393
15924
|
}
|
|
15394
15925
|
//#endregion
|
|
15395
|
-
export { AntigravityAdapter, CodexChatGptAdapter, CommandCodeAdapter, FileCredentialStore as CommandCodeCredentialStore, FileModelSettingsStore as CommandCodeModelSettingsStore, Config, FileCredentialStore$1 as FileCredentialStore, FileModelSettingsStore$1 as FileModelSettingsStore, KIMI_CODE_MODELS, KIMI_CODE_RETRY_POLICY_CONFIG, KimiCodeAdapter, FileCredentialStore$2 as KimiCodeCredentialStore, FileModelSettingsStore$2 as KimiCodeModelSettingsStore, LinuxFileTokenStore, MacKeychainTokenStore, OAuthService, ProxyManager, RELAY_PROBE_ENV, RELAY_PROBE_FILE_ENV, RELAY_PROBE_FILE_NAME, RELAY_PROBE_MAX_BYTES, RELAY_SOURCE_KINDS, RelayProbe, ResponsesClient, SUBAGENT_MODEL_SELECTION_NAMESPACE, SUBAGENT_POLICY_EVENT, SearchProviderSwitcher, UsageService, WindowsDpapiTokenStore, apply, authorizedRoutesFor, beginWebLogin as beginKimiCodeLogin, beginWebLogin$1 as beginWebLogin, classifyKimiFailure, clearCachedQuota, clearCachedQuota$1 as clearCommandCodeQuota, clearCachedQuota$2 as clearKimiCodeQuota, credentialPath as commandCodeCredentialPath, modelSettingsPath as commandCodeModelSettingsPath, createCodexFetchProvider, createCodexImageTool, createCodexSearchProvider, createFileRelayProbeSink, createPlatformTokenStore, createSubagentAuthorization, credentialPath$1 as credentialPath, delegationDenialReason, detectSystemProxy, ensureAccessToken as ensureKimiCodeAccessToken, fetchAccountQuota, fetchAccountQuota$1 as fetchCommandCodeQuota, fetchAccountQuota$2 as fetchKimiCodeQuota, fetchUserInfo as fetchKimiCodeUserInfo, getCachedQuota, getWebLoginStatus as getCommandCodeLoginStatus, getCachedQuota$1 as getCommandCodeQuota, getCommandCodeWebStatus, getWebLoginStatus$1 as getKimiCodeLoginStatus, getCachedQuota$2 as getKimiCodeQuota, getKimiCodeWebStatus, inject, installRelayProbe, installSubagentModelAuthorization, credentialPath$2 as kimiCodeCredentialPath, kimiCodeModelDef, modelSettingsPath$1 as kimiCodeModelSettingsPath, loadProviderModels as loadCommandCodeModels, loadProviderModels$1 as loadKimiCodeModels, loginAndSave, mapCodexUsage, modelSettingsPath$2 as modelSettingsPath, normalizeDelegationToolNames, parseAllowedRoutes, parseCodexUsage, parseResponsesStream, policyRoutesOf, refreshAntigravityToken, refreshAccessToken as refreshKimiCodeToken, registerCommandCodePreferenceStore, registerCommandCodeRoutes, registerKimiCodePreferenceStore, registerKimiCodeRoutes, relayProbeEnabled, relayProbeEnvFile, relayProbeEnvValue, relayProbeLogPath, requestDeviceAuthorization as requestKimiCodeDeviceAuthorization, resolveRegion as resolveKimiCodeRegion, saveApiKey as saveCommandCodeApiKey, beginWebLogin$2 as startCommandCodeLogin, subagentModelSelectionPreference, unauthorizedRouteReason, validateAuthorizationScope, validateDelegationToolNames };
|
|
15926
|
+
export { AntigravityAdapter, CodexChatGptAdapter, CommandCodeAdapter, FileCredentialStore as CommandCodeCredentialStore, FileModelSettingsStore as CommandCodeModelSettingsStore, Config, DEFAULT_SUBAGENT_INHERIT_TOOLS, FileCredentialStore$1 as FileCredentialStore, FileModelSettingsStore$1 as FileModelSettingsStore, KIMI_CODE_MODELS, KIMI_CODE_RETRY_POLICY_CONFIG, KimiCodeAdapter, FileCredentialStore$2 as KimiCodeCredentialStore, FileModelSettingsStore$2 as KimiCodeModelSettingsStore, LinuxFileTokenStore, MacKeychainTokenStore, OAuthService, ProxyManager, RELAY_PROBE_ENV, RELAY_PROBE_FILE_ENV, RELAY_PROBE_FILE_NAME, RELAY_PROBE_MAX_BYTES, RELAY_SOURCE_KINDS, RelayProbe, ResponsesClient, SUBAGENT_MODEL_SELECTION_NAMESPACE, SUBAGENT_POLICY_EVENT, SearchProviderSwitcher, UsageService, WindowsDpapiTokenStore, apply, auditChildRoutes, auditedRoutesOf, authorizedRoutesFor, beginWebLogin as beginKimiCodeLogin, beginWebLogin$1 as beginWebLogin, childRoutesOf, classifyKimiFailure, clearCachedQuota, clearCachedQuota$1 as clearCommandCodeQuota, clearCachedQuota$2 as clearKimiCodeQuota, credentialPath as commandCodeCredentialPath, modelSettingsPath as commandCodeModelSettingsPath, createCodexFetchProvider, createCodexImageTool, createCodexSearchProvider, createFileRelayProbeSink, createPlatformTokenStore, createSubagentAuthorization, credentialPath$1 as credentialPath, delegationDenialReason, delegationModeOf, detectSystemProxy, effectiveRouteOf, ensureAccessToken as ensureKimiCodeAccessToken, fetchAccountQuota, fetchAccountQuota$1 as fetchCommandCodeQuota, fetchAccountQuota$2 as fetchKimiCodeQuota, fetchUserInfo as fetchKimiCodeUserInfo, getCachedQuota, getWebLoginStatus as getCommandCodeLoginStatus, getCachedQuota$1 as getCommandCodeQuota, getCommandCodeWebStatus, getWebLoginStatus$1 as getKimiCodeLoginStatus, getCachedQuota$2 as getKimiCodeQuota, getKimiCodeWebStatus, inheritOverrideReason, inheritRouteDenialReason, inheritedRouteOf, inject, installRelayProbe, installSubagentModelAuthorization, credentialPath$2 as kimiCodeCredentialPath, kimiCodeModelDef, modelSettingsPath$1 as kimiCodeModelSettingsPath, loadProviderModels as loadCommandCodeModels, loadProviderModels$1 as loadKimiCodeModels, loginAndSave, mapCodexUsage, modelSettingsPath$2 as modelSettingsPath, normalizeDelegationToolNames, normalizeInheritToolNames, parseAllowedRoutes, parseCodexUsage, parseResponsesStream, policyRoutesOf, readChildDescriptor, refreshAntigravityToken, refreshAccessToken as refreshKimiCodeToken, registerCommandCodePreferenceStore, registerCommandCodeRoutes, registerKimiCodePreferenceStore, registerKimiCodeRoutes, relayProbeEnabled, relayProbeEnvFile, relayProbeEnvValue, relayProbeLogPath, requestDeviceAuthorization as requestKimiCodeDeviceAuthorization, resolveRegion as resolveKimiCodeRegion, saveApiKey as saveCommandCodeApiKey, beginWebLogin$2 as startCommandCodeLogin, subagentModelSelectionPreference, unauthorizedRouteReason, validateAuthorizationScope, validateDelegationToolNames, validateInheritToolNames, violationText };
|