@eddyskywalker/dsh-chatgpt-subscription 0.66.0 → 0.66.1
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 +23 -0
- package/lib/client.js +137 -9
- package/lib/client.js.map +1 -1
- package/lib/index.js +682 -77
- package/lib/types/client/antigravity/styles.d.ts.map +1 -1
- package/lib/types/client/glm-coding-plan/styles.d.ts.map +1 -1
- package/lib/types/client/kimi-code/KimiCodeSection.d.ts.map +1 -1
- package/lib/types/client/kimi-code/locales.d.ts +44 -2
- package/lib/types/client/kimi-code/locales.d.ts.map +1 -1
- package/lib/types/client/kimi-code/styles.d.ts.map +1 -1
- package/lib/types/client/locales-ru/kimi-code.d.ts.map +1 -1
- package/lib/types/client/workbuddy/styles.d.ts.map +1 -1
- package/lib/types/compat.d.ts +1 -1
- package/lib/types/host/cache-warmup/contracts.d.ts +1 -1
- package/lib/types/host/cache-warmup/contracts.d.ts.map +1 -1
- package/lib/types/host/cache-warmup/install.d.ts.map +1 -1
- package/lib/types/host/cache-warmup/projection.d.ts.map +1 -1
- package/lib/types/host/glm-coding-plan/adapter.d.ts +11 -0
- package/lib/types/host/glm-coding-plan/adapter.d.ts.map +1 -1
- package/lib/types/host/kimi-code/adapter.d.ts +4 -10
- package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
- package/lib/types/host/kimi-code/mapper.d.ts +11 -1
- package/lib/types/host/kimi-code/mapper.d.ts.map +1 -1
- package/lib/types/host/kimi-code/routes.d.ts.map +1 -1
- package/lib/types/host/kimi-code/session-cache-state.d.ts +19 -2
- package/lib/types/host/kimi-code/session-cache-state.d.ts.map +1 -1
- package/lib/types/host/kimi-code/tool-argument-guard.d.ts +36 -0
- package/lib/types/host/kimi-code/tool-argument-guard.d.ts.map +1 -0
- package/lib/types/host/kimi-code/tool-argument-recovery.d.ts +16 -0
- package/lib/types/host/kimi-code/tool-argument-recovery.d.ts.map +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/kimi-code-contracts.d.ts +63 -0
- package/lib/types/shared/kimi-code-contracts.d.ts.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -809,7 +809,7 @@ const ROUTE_PREFIX$5 = "/api/dsh-chatgpt-subscription";
|
|
|
809
809
|
* `test/responses-client.test.ts` asserts the two agree, so a release that
|
|
810
810
|
* forgets this constant fails the suite instead of shipping quietly.
|
|
811
811
|
*/
|
|
812
|
-
const PLUGIN_VERSION = "0.66.
|
|
812
|
+
const PLUGIN_VERSION = "0.66.1";
|
|
813
813
|
const CODEX_CHATGPT_PROVIDER_ID = "codex-chatgpt";
|
|
814
814
|
const CODEX_API_BASE = "https://chatgpt.com/backend-api/codex";
|
|
815
815
|
const CODEX_RESPONSES_URL = `${CODEX_API_BASE}/responses`;
|
|
@@ -15092,7 +15092,7 @@ async function* parseResponsesStream(response, signal, _legacyHiddenSandboxContr
|
|
|
15092
15092
|
const tools = /* @__PURE__ */ new Map();
|
|
15093
15093
|
const toolFor = (event, item) => {
|
|
15094
15094
|
const itemId = string(event.item_id) ?? string(item?.id);
|
|
15095
|
-
const outputIndex = number(event.output_index);
|
|
15095
|
+
const outputIndex = number$1(event.output_index);
|
|
15096
15096
|
const key = itemId ?? (outputIndex === void 0 ? `tool-${tools.size}` : `index-${outputIndex}`);
|
|
15097
15097
|
let tool = tools.get(key);
|
|
15098
15098
|
if (tool === void 0) {
|
|
@@ -15421,12 +15421,12 @@ function visibleReasoningDelta(delta, currentVisibleChars, alreadyTruncated) {
|
|
|
15421
15421
|
*/
|
|
15422
15422
|
function mapUsage$2(value) {
|
|
15423
15423
|
if (value === null) return null;
|
|
15424
|
-
const totalInput = number(value.input_tokens) ?? 0;
|
|
15425
|
-
const outputTokens = number(value.output_tokens) ?? 0;
|
|
15424
|
+
const totalInput = number$1(value.input_tokens) ?? 0;
|
|
15425
|
+
const outputTokens = number$1(value.output_tokens) ?? 0;
|
|
15426
15426
|
const details = record$3(value.input_tokens_details);
|
|
15427
|
-
const cached = number(details?.cached_tokens);
|
|
15428
|
-
const written = number(details?.cache_write_tokens);
|
|
15429
|
-
const reasoning = number(record$3(value.output_tokens_details)?.reasoning_tokens);
|
|
15427
|
+
const cached = number$1(details?.cached_tokens);
|
|
15428
|
+
const written = number$1(details?.cache_write_tokens);
|
|
15429
|
+
const reasoning = number$1(record$3(value.output_tokens_details)?.reasoning_tokens);
|
|
15430
15430
|
return {
|
|
15431
15431
|
inputTokens: Math.max(0, totalInput - (cached ?? 0) - (written ?? 0)),
|
|
15432
15432
|
outputTokens,
|
|
@@ -15481,7 +15481,7 @@ function record$3(value) {
|
|
|
15481
15481
|
function string(value) {
|
|
15482
15482
|
return typeof value === "string" ? value : void 0;
|
|
15483
15483
|
}
|
|
15484
|
-
function number(value) {
|
|
15484
|
+
function number$1(value) {
|
|
15485
15485
|
const parsed = Number(value);
|
|
15486
15486
|
return Number.isFinite(parsed) ? parsed : void 0;
|
|
15487
15487
|
}
|
|
@@ -16579,8 +16579,8 @@ function parseCodexUsage(value) {
|
|
|
16579
16579
|
for (const [index, value] of additional.entries()) {
|
|
16580
16580
|
const limit = record$2(value);
|
|
16581
16581
|
if (limit === null) continue;
|
|
16582
|
-
const idSource = text$
|
|
16583
|
-
addBucket(buckets, usedIds, uniqueId(slug(idSource), usedIds), readableLimitName(text$
|
|
16582
|
+
const idSource = text$5(limit.limit_name) ?? text$5(limit.metered_feature) ?? `additional-${index + 1}`;
|
|
16583
|
+
addBucket(buckets, usedIds, uniqueId(slug(idSource), usedIds), readableLimitName(text$5(limit.limit_name) ?? text$5(limit.metered_feature) ?? idSource), planType, limit.rate_limit);
|
|
16584
16584
|
}
|
|
16585
16585
|
return {
|
|
16586
16586
|
buckets,
|
|
@@ -16665,7 +16665,7 @@ function parseResetCredits(value) {
|
|
|
16665
16665
|
availableCreditIds: []
|
|
16666
16666
|
};
|
|
16667
16667
|
const available = (Array.isArray(data.credits) ? data.credits : []).map(record$2).filter((credit) => credit !== null && credit.status === "available").map((credit) => ({
|
|
16668
|
-
id: text$
|
|
16668
|
+
id: text$5(credit.id),
|
|
16669
16669
|
expiresAt: timestamp(credit.expires_at)
|
|
16670
16670
|
})).filter((credit) => credit.id !== null).sort((left, right) => (left.expiresAt ?? Number.MAX_SAFE_INTEGER) - (right.expiresAt ?? Number.MAX_SAFE_INTEGER));
|
|
16671
16671
|
const reported = numeric(data.available_count);
|
|
@@ -16699,7 +16699,7 @@ function decimalText(value) {
|
|
|
16699
16699
|
const trimmed = value.trim();
|
|
16700
16700
|
return trimmed !== "" ? trimmed : null;
|
|
16701
16701
|
}
|
|
16702
|
-
function text$
|
|
16702
|
+
function text$5(value) {
|
|
16703
16703
|
return typeof value === "string" && value.trim() !== "" ? value.trim() : null;
|
|
16704
16704
|
}
|
|
16705
16705
|
function slug(value) {
|
|
@@ -24922,7 +24922,7 @@ function classifyCommandCodeFailure(status, detail) {
|
|
|
24922
24922
|
};
|
|
24923
24923
|
}
|
|
24924
24924
|
/** Cooldown one rate-limited key takes when the provider states no delay. */
|
|
24925
|
-
const POOL_COOLDOWN_MS$
|
|
24925
|
+
const POOL_COOLDOWN_MS$6 = 15 * 6e4;
|
|
24926
24926
|
var CommandCodeAdapter = class extends LlmAdapter {
|
|
24927
24927
|
store;
|
|
24928
24928
|
modelSettings;
|
|
@@ -25110,7 +25110,7 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
25110
25110
|
}
|
|
25111
25111
|
if (response.status === 429) {
|
|
25112
25112
|
const after = retryAfterMs$1(response.headers);
|
|
25113
|
-
await pool.markCooldown(accountId, after ?? POOL_COOLDOWN_MS$
|
|
25113
|
+
await pool.markCooldown(accountId, after ?? POOL_COOLDOWN_MS$6, `${PROVIDER_NAME$10} 429`).catch(() => void 0);
|
|
25114
25114
|
if (await pool.hasAnotherAvailableAccount(tried)) continue;
|
|
25115
25115
|
break;
|
|
25116
25116
|
}
|
|
@@ -25185,7 +25185,7 @@ var CommandCodeAdapter = class extends LlmAdapter {
|
|
|
25185
25185
|
const reclassified = reclassifyInBandStreamError(error, inBand);
|
|
25186
25186
|
if (reclassified.code === "RATE_LIMIT" && pool !== null && accountId !== void 0) {
|
|
25187
25187
|
const after = retryAfterMs$1(response.headers);
|
|
25188
|
-
await pool.markCooldown(accountId, after ?? POOL_COOLDOWN_MS$
|
|
25188
|
+
await pool.markCooldown(accountId, after ?? POOL_COOLDOWN_MS$6, `${PROVIDER_NAME$10} in-stream 429`).catch(() => void 0);
|
|
25189
25189
|
}
|
|
25190
25190
|
throw reclassified;
|
|
25191
25191
|
}
|
|
@@ -26371,7 +26371,7 @@ const STREAM_IDLE_TIMEOUT_MS$5 = 3e5;
|
|
|
26371
26371
|
* A 429 here is a real quota or rate limit, not a blip, so the account is parked
|
|
26372
26372
|
* for long enough that the next request goes to a different one.
|
|
26373
26373
|
*/
|
|
26374
|
-
const POOL_COOLDOWN_MS$
|
|
26374
|
+
const POOL_COOLDOWN_MS$5 = 15 * 6e4;
|
|
26375
26375
|
/**
|
|
26376
26376
|
* NO fallback model names.
|
|
26377
26377
|
*
|
|
@@ -27766,7 +27766,7 @@ var OllamaAdapter = class extends LlmAdapter {
|
|
|
27766
27766
|
break;
|
|
27767
27767
|
}
|
|
27768
27768
|
if (lastStatus === 429) {
|
|
27769
|
-
await pool.markCooldown(accountId, POOL_COOLDOWN_MS$
|
|
27769
|
+
await pool.markCooldown(accountId, POOL_COOLDOWN_MS$5, `${PROVIDER_NAME$9} 429`).catch(() => void 0);
|
|
27770
27770
|
if (await pool.hasAnotherAvailableAccount(tried)) continue;
|
|
27771
27771
|
break;
|
|
27772
27772
|
}
|
|
@@ -29294,7 +29294,7 @@ function consecutiveWarmupHits(reports) {
|
|
|
29294
29294
|
}
|
|
29295
29295
|
}
|
|
29296
29296
|
/** 把任意输入归一成一条用量报告;形状不对返回 undefined(绝不抛)。 */
|
|
29297
|
-
function normalizeUsage(input) {
|
|
29297
|
+
function normalizeUsage$1(input) {
|
|
29298
29298
|
if (input === null || input === void 0 || typeof input !== "object") return void 0;
|
|
29299
29299
|
const sessionId = input.sessionId;
|
|
29300
29300
|
if (typeof sessionId !== "string" || sessionId.trim() === "") return void 0;
|
|
@@ -29335,7 +29335,7 @@ function recordCacheWarmupUsage(input) {
|
|
|
29335
29335
|
let sessionId = "";
|
|
29336
29336
|
let provider;
|
|
29337
29337
|
try {
|
|
29338
|
-
const usage = normalizeUsage(input);
|
|
29338
|
+
const usage = normalizeUsage$1(input);
|
|
29339
29339
|
if (usage === void 0) return neutralState("");
|
|
29340
29340
|
sessionId = usage.sessionId;
|
|
29341
29341
|
provider = usage.provider;
|
|
@@ -30799,6 +30799,57 @@ function planMultiSectionProjection(text) {
|
|
|
30799
30799
|
sections
|
|
30800
30800
|
};
|
|
30801
30801
|
}
|
|
30802
|
+
/**
|
|
30803
|
+
* PTC 工具目录:保留完整的 namespace/name 索引,重 schema 由原文 ref 补读。
|
|
30804
|
+
*
|
|
30805
|
+
* 只认 code_tools_list / code_tools_search 的根对象形状。任意字段缺失、额外根成员
|
|
30806
|
+
* 或非 PTC 调用都回退原文,避免把业务 JSON 里的 tools 数组误当成工具发现结果。
|
|
30807
|
+
*/
|
|
30808
|
+
function planToolCatalogProjection(text, toolName) {
|
|
30809
|
+
if (!isPtcTransportName(toolName)) return void 0;
|
|
30810
|
+
const candidate = parseJsonCandidate(text);
|
|
30811
|
+
if (candidate?.kind !== "object") return void 0;
|
|
30812
|
+
const record = candidate.record;
|
|
30813
|
+
if (Object.keys(record).some((key) => key !== "tools" && key !== "fallback")) return void 0;
|
|
30814
|
+
if (!Array.isArray(record.tools) || record.tools.length === 0) return void 0;
|
|
30815
|
+
const lines = [];
|
|
30816
|
+
for (const entry of record.tools) {
|
|
30817
|
+
if (!isPlainRecord$1(entry)) return void 0;
|
|
30818
|
+
if (typeof entry.name !== "string" || entry.name.trim() === "") return void 0;
|
|
30819
|
+
if (typeof entry.namespace !== "string" || entry.namespace.trim() === "") return void 0;
|
|
30820
|
+
if (typeof entry.description !== "string") return void 0;
|
|
30821
|
+
const name = entry.name.trim();
|
|
30822
|
+
const namespace = entry.namespace.trim();
|
|
30823
|
+
const description = entry.description.replace(/\s+/g, " ").trim();
|
|
30824
|
+
lines.push(` ${namespace}/${name}: ${clip(description, 180)}`);
|
|
30825
|
+
}
|
|
30826
|
+
const header = [`tools: ${record.tools.length} (complete name index; descriptions clipped)`];
|
|
30827
|
+
if (typeof record.fallback === "string" && record.fallback.trim() !== "") header.push("fallback: " + clip(record.fallback.replace(/\s+/g, " ").trim(), 240));
|
|
30828
|
+
return {
|
|
30829
|
+
kind: "preview",
|
|
30830
|
+
strategy: "tool-catalog",
|
|
30831
|
+
sections: [{ lines: header }, { lines }]
|
|
30832
|
+
};
|
|
30833
|
+
}
|
|
30834
|
+
/** 成功测试日志必须有明确通过汇总,且没有任何可识别的失败证据。 */
|
|
30835
|
+
function isSuccessfulTestEvidence(text, evidence) {
|
|
30836
|
+
if (evidence.failures.length > 0 || evidence.summary.length === 0) return false;
|
|
30837
|
+
if (!evidence.summary.some((line) => /\b\d+\s+passed\b/i.test(line))) return false;
|
|
30838
|
+
if (/(?:^|\s)[1-9]\d*\s+failed\b/i.test(text)) return false;
|
|
30839
|
+
const exitMatch = /(?:exit code|exited with code|process exited with code)[:=\s]+(-?\d+)/i.exec(text) ?? /\[exit code: (-?\d+)\]/i.exec(text);
|
|
30840
|
+
if (exitMatch !== null && Number(exitMatch[1]) !== 0) return false;
|
|
30841
|
+
for (const raw of text.split("\n")) {
|
|
30842
|
+
const trimmed = raw.trim();
|
|
30843
|
+
if (trimmed === "" || /^npm notice\b/i.test(trimmed)) continue;
|
|
30844
|
+
if (/^(?:PASS\b|[✓✔]|ok\s+\d+)/i.test(trimmed)) continue;
|
|
30845
|
+
if (/^(?:stdout|stderr)\s*\|/i.test(trimmed)) continue;
|
|
30846
|
+
if (/^\(node:\d+\).*Warning:/i.test(trimmed)) continue;
|
|
30847
|
+
if (/^\s*(?:0|no)\s+(?:errors?|failures?|failed)\b/i.test(trimmed)) continue;
|
|
30848
|
+
if (/\b\d+\s+passed\b/i.test(trimmed)) continue;
|
|
30849
|
+
if (SHELL_ERROR_LINE.test(trimmed)) return false;
|
|
30850
|
+
}
|
|
30851
|
+
return true;
|
|
30852
|
+
}
|
|
30802
30853
|
/** 对一段纯文本(非 JSON 文档)做投影计划判定。 */
|
|
30803
30854
|
function planPlainTextProjection(rawText, toolName) {
|
|
30804
30855
|
const text = stripAnsi(rawText);
|
|
@@ -30816,6 +30867,11 @@ function planPlainTextProjection(rawText, toolName) {
|
|
|
30816
30867
|
strategy: "test-failure",
|
|
30817
30868
|
sections: buildTestSections(test)
|
|
30818
30869
|
};
|
|
30870
|
+
if (test !== void 0 && isSuccessfulTestEvidence(text, test)) return {
|
|
30871
|
+
kind: "preview",
|
|
30872
|
+
strategy: "test-success",
|
|
30873
|
+
sections: buildTestSections(test)
|
|
30874
|
+
};
|
|
30819
30875
|
const grep = extractGrepEvidence(text);
|
|
30820
30876
|
if (grep !== void 0) return {
|
|
30821
30877
|
kind: "preview",
|
|
@@ -30886,6 +30942,10 @@ function planProjection(text, toolName, navigation, retrievalOnly, spilled = fal
|
|
|
30886
30942
|
const multiSection = planMultiSectionProjection(text);
|
|
30887
30943
|
if (multiSection !== void 0) return multiSection;
|
|
30888
30944
|
}
|
|
30945
|
+
if (isJsonDocument(text)) {
|
|
30946
|
+
const toolCatalog = planToolCatalogProjection(text, toolName);
|
|
30947
|
+
if (toolCatalog !== void 0) return toolCatalog;
|
|
30948
|
+
}
|
|
30889
30949
|
if (looksLikeContract(text)) return {
|
|
30890
30950
|
kind: "verbatim",
|
|
30891
30951
|
strategy: "verbatim-contract"
|
|
@@ -34470,6 +34530,150 @@ function videoBlockToInline(block, videos, videoAccepted, omit) {
|
|
|
34470
34530
|
} } : { omission: omit("unsupported-container", label) };
|
|
34471
34531
|
}
|
|
34472
34532
|
//#endregion
|
|
34533
|
+
//#region src/host/kimi-code/tool-argument-guard.ts
|
|
34534
|
+
const TOOL_ARGUMENT_BYTES_EXCEEDED_CODE = "KIMI_TOOL_ARGUMENT_BYTES_EXCEEDED";
|
|
34535
|
+
const TOOL_ARGUMENT_REPEATED_KEY_CODE = "KIMI_TOOL_ARGUMENT_REPEATED_KEY";
|
|
34536
|
+
/** Whether one adapter failure belongs to the recoverable argument guard. */
|
|
34537
|
+
function isKimiToolArgumentGuardCode(code) {
|
|
34538
|
+
return code === "KIMI_TOOL_ARGUMENT_BYTES_EXCEEDED" || code === "KIMI_TOOL_ARGUMENT_REPEATED_KEY";
|
|
34539
|
+
}
|
|
34540
|
+
const ASK_USER_ARGUMENT_LIMIT = 32 * 1024;
|
|
34541
|
+
const LARGE_PROGRAM_ARGUMENT_LIMIT = 1024 * 1024;
|
|
34542
|
+
const DEFAULT_ARGUMENT_LIMIT = 256 * 1024;
|
|
34543
|
+
const REPEATED_KEY_LIMIT = 8;
|
|
34544
|
+
const MAX_TRACKED_KEY_GROUPS = 64;
|
|
34545
|
+
const MAX_SCANNED_KEY_CHARS = 1024;
|
|
34546
|
+
/** Large source/file payloads need a different ceiling from coordination cards. */
|
|
34547
|
+
function toolArgumentLimit(toolName) {
|
|
34548
|
+
if (toolName === "ask_user_question") return ASK_USER_ARGUMENT_LIMIT;
|
|
34549
|
+
if (toolName === "write" || toolName === "edit" || toolName === "code_run" || toolName === "run_code") return LARGE_PROGRAM_ARGUMENT_LIMIT;
|
|
34550
|
+
return DEFAULT_ARGUMENT_LIMIT;
|
|
34551
|
+
}
|
|
34552
|
+
/** Split `header_comment`, `header_unused`, and `header___` into one family. */
|
|
34553
|
+
function keyFamily(key) {
|
|
34554
|
+
const suffix = /_(?:comment|unused)$|_+$/.exec(key);
|
|
34555
|
+
if (suffix === null || suffix.index === 0) return {
|
|
34556
|
+
stem: key,
|
|
34557
|
+
variant: false
|
|
34558
|
+
};
|
|
34559
|
+
return {
|
|
34560
|
+
stem: key.slice(0, suffix.index),
|
|
34561
|
+
variant: true
|
|
34562
|
+
};
|
|
34563
|
+
}
|
|
34564
|
+
var KimiToolArgumentGuard = class {
|
|
34565
|
+
toolName;
|
|
34566
|
+
bytes = 0;
|
|
34567
|
+
inString = false;
|
|
34568
|
+
escaped = false;
|
|
34569
|
+
afterString = false;
|
|
34570
|
+
stringRaw = "";
|
|
34571
|
+
stringTooLong = false;
|
|
34572
|
+
highSurrogate = "";
|
|
34573
|
+
keyGroups = /* @__PURE__ */ new Map();
|
|
34574
|
+
violation;
|
|
34575
|
+
constructor(toolName) {
|
|
34576
|
+
this.toolName = toolName;
|
|
34577
|
+
}
|
|
34578
|
+
observe(delta) {
|
|
34579
|
+
if (this.violation !== void 0) return this.violation;
|
|
34580
|
+
const text = this.highSurrogate + delta;
|
|
34581
|
+
this.highSurrogate = "";
|
|
34582
|
+
if (text === "") return void 0;
|
|
34583
|
+
const last = text.charCodeAt(text.length - 1);
|
|
34584
|
+
const complete = last >= 55296 && last <= 56319 ? text.slice(0, -1) : text;
|
|
34585
|
+
if (complete.length !== text.length) this.highSurrogate = text.at(-1) ?? "";
|
|
34586
|
+
this.bytes += Buffer.byteLength(complete, "utf8");
|
|
34587
|
+
if (this.bytes > toolArgumentLimit(this.toolName)) return this.fail("argument-bytes");
|
|
34588
|
+
for (const char of complete) {
|
|
34589
|
+
const violation = this.observeChar(char);
|
|
34590
|
+
if (violation !== void 0) return violation;
|
|
34591
|
+
}
|
|
34592
|
+
}
|
|
34593
|
+
/** Account for a trailing unmatched surrogate without leaving it unbudgeted. */
|
|
34594
|
+
finish() {
|
|
34595
|
+
if (this.highSurrogate !== "") {
|
|
34596
|
+
this.highSurrogate = "";
|
|
34597
|
+
this.bytes += Buffer.byteLength("\ud800", "utf8");
|
|
34598
|
+
if (this.bytes > toolArgumentLimit(this.toolName)) return this.fail("argument-bytes");
|
|
34599
|
+
}
|
|
34600
|
+
return this.violation;
|
|
34601
|
+
}
|
|
34602
|
+
fail(rule) {
|
|
34603
|
+
this.violation = {
|
|
34604
|
+
toolName: this.toolName || "unknown",
|
|
34605
|
+
rule,
|
|
34606
|
+
bytes: this.bytes
|
|
34607
|
+
};
|
|
34608
|
+
return this.violation;
|
|
34609
|
+
}
|
|
34610
|
+
observeChar(char) {
|
|
34611
|
+
if (this.inString) {
|
|
34612
|
+
if (this.escaped) {
|
|
34613
|
+
this.escaped = false;
|
|
34614
|
+
if (!this.stringTooLong) this.stringRaw += char;
|
|
34615
|
+
return;
|
|
34616
|
+
}
|
|
34617
|
+
if (char === "\\") {
|
|
34618
|
+
this.escaped = true;
|
|
34619
|
+
if (!this.stringTooLong) this.stringRaw += char;
|
|
34620
|
+
return;
|
|
34621
|
+
}
|
|
34622
|
+
if (char === "\"") {
|
|
34623
|
+
this.inString = false;
|
|
34624
|
+
this.afterString = true;
|
|
34625
|
+
return;
|
|
34626
|
+
}
|
|
34627
|
+
if (!this.stringTooLong) {
|
|
34628
|
+
this.stringRaw += char;
|
|
34629
|
+
if (this.stringRaw.length > MAX_SCANNED_KEY_CHARS) {
|
|
34630
|
+
this.stringTooLong = true;
|
|
34631
|
+
this.stringRaw = "";
|
|
34632
|
+
}
|
|
34633
|
+
}
|
|
34634
|
+
return;
|
|
34635
|
+
}
|
|
34636
|
+
if (this.afterString) {
|
|
34637
|
+
if (/\s/.test(char)) return void 0;
|
|
34638
|
+
this.afterString = false;
|
|
34639
|
+
if (char === ":") {
|
|
34640
|
+
this.observeKey();
|
|
34641
|
+
return this.violation;
|
|
34642
|
+
}
|
|
34643
|
+
this.stringRaw = "";
|
|
34644
|
+
this.stringTooLong = false;
|
|
34645
|
+
}
|
|
34646
|
+
if (char === "\"") {
|
|
34647
|
+
this.inString = true;
|
|
34648
|
+
this.escaped = false;
|
|
34649
|
+
this.stringRaw = "";
|
|
34650
|
+
this.stringTooLong = false;
|
|
34651
|
+
}
|
|
34652
|
+
}
|
|
34653
|
+
observeKey() {
|
|
34654
|
+
if (this.stringTooLong || this.stringRaw === "") return;
|
|
34655
|
+
try {
|
|
34656
|
+
const key = JSON.parse("\"" + this.stringRaw + "\"");
|
|
34657
|
+
if (typeof key !== "string" || key === "") return;
|
|
34658
|
+
const family = keyFamily(key);
|
|
34659
|
+
if (family.stem === "") return;
|
|
34660
|
+
const group = this.keyGroups.get(family.stem) ?? {
|
|
34661
|
+
count: 0,
|
|
34662
|
+
sawVariant: false
|
|
34663
|
+
};
|
|
34664
|
+
group.count += 1;
|
|
34665
|
+
group.sawVariant ||= family.variant;
|
|
34666
|
+
this.keyGroups.delete(family.stem);
|
|
34667
|
+
this.keyGroups.set(family.stem, group);
|
|
34668
|
+
while (this.keyGroups.size > MAX_TRACKED_KEY_GROUPS) {
|
|
34669
|
+
const oldest = this.keyGroups.keys().next();
|
|
34670
|
+
if (oldest.done !== true) this.keyGroups.delete(oldest.value);
|
|
34671
|
+
}
|
|
34672
|
+
if (group.sawVariant && group.count >= REPEATED_KEY_LIMIT) this.fail("repeated-key");
|
|
34673
|
+
} catch {}
|
|
34674
|
+
}
|
|
34675
|
+
};
|
|
34676
|
+
//#endregion
|
|
34473
34677
|
//#region src/host/kimi-code/mapper.ts
|
|
34474
34678
|
/**
|
|
34475
34679
|
* Provider-wire mapping for the Kimi Code coding endpoints.
|
|
@@ -36154,6 +36358,9 @@ function createStreamState$5(wire, sessionId, sideChannel = false) {
|
|
|
36154
36358
|
cacheWrite5mTokens: 0,
|
|
36155
36359
|
cacheWrite1hTokens: 0,
|
|
36156
36360
|
reasoningTokens: 0,
|
|
36361
|
+
cacheReadReported: false,
|
|
36362
|
+
cacheWriteReported: false,
|
|
36363
|
+
reasoningReported: false,
|
|
36157
36364
|
sawUsage: false,
|
|
36158
36365
|
toolCallIds: new ToolCallIdNormalizer()
|
|
36159
36366
|
};
|
|
@@ -36176,9 +36383,22 @@ function closeCurrent$5(state) {
|
|
|
36176
36383
|
block
|
|
36177
36384
|
}];
|
|
36178
36385
|
}
|
|
36386
|
+
function throwToolGuardViolation(state, call, violation) {
|
|
36387
|
+
if (violation === void 0) return;
|
|
36388
|
+
state.toolGuard = violation;
|
|
36389
|
+
const reason = violation.rule === "argument-bytes" ? `arguments exceeded the ${violation.rule} safety budget` : "arguments contained a runaway repeated-key family";
|
|
36390
|
+
throw new LlmError$1(`Kimi Code stopped tool call "${violation.toolName}": ${reason} at ${violation.bytes} bytes. The tool was not executed.`, violation.rule === "argument-bytes" ? TOOL_ARGUMENT_BYTES_EXCEEDED_CODE : TOOL_ARGUMENT_REPEATED_KEY_CODE);
|
|
36391
|
+
}
|
|
36392
|
+
function appendGuardedArguments(state, call, delta) {
|
|
36393
|
+
if (delta === "") return;
|
|
36394
|
+
call.arguments += delta;
|
|
36395
|
+
call.guard ??= new KimiToolArgumentGuard(call.name);
|
|
36396
|
+
throwToolGuardViolation(state, call, call.guard.observe(delta));
|
|
36397
|
+
}
|
|
36179
36398
|
function closeToolCalls$5(state) {
|
|
36180
36399
|
const out = [];
|
|
36181
36400
|
for (const [wireIndex, call] of [...state.toolCalls.entries()].sort((a, b) => a[0] - b[0])) {
|
|
36401
|
+
throwToolGuardViolation(state, call, call.guard?.finish());
|
|
36182
36402
|
const block = {
|
|
36183
36403
|
type: "tool-call",
|
|
36184
36404
|
id: toToolCallId(state.toolCallIds.normalize(call.id)),
|
|
@@ -36247,8 +36467,14 @@ function processOpenAIStreamLine(line, state) {
|
|
|
36247
36467
|
state.inputTokens = Math.max(0, prompt - cached - written);
|
|
36248
36468
|
state.cacheReadTokens = cached;
|
|
36249
36469
|
state.cacheWriteTokens = written;
|
|
36470
|
+
state.cacheReadReported = details !== void 0 && typeof details.cached_tokens === "number" && Number.isFinite(details.cached_tokens);
|
|
36471
|
+
state.cacheWriteReported = details !== void 0 && typeof details.cache_write_tokens === "number" && Number.isFinite(details.cache_write_tokens);
|
|
36250
36472
|
state.outputTokens = numberOr$8(usage.completion_tokens, state.outputTokens);
|
|
36251
|
-
if (isRecord$53(usage.completion_tokens_details))
|
|
36473
|
+
if (isRecord$53(usage.completion_tokens_details)) {
|
|
36474
|
+
const reasoning = usage.completion_tokens_details.reasoning_tokens;
|
|
36475
|
+
state.reasoningReported = typeof reasoning === "number" && Number.isFinite(reasoning);
|
|
36476
|
+
state.reasoningTokens = numberOr$8(reasoning, state.reasoningTokens);
|
|
36477
|
+
} else state.reasoningReported = false;
|
|
36252
36478
|
}
|
|
36253
36479
|
const choices = Array.isArray(chunk.choices) ? chunk.choices : [];
|
|
36254
36480
|
const choice = isRecord$53(choices[0]) ? choices[0] : void 0;
|
|
@@ -36352,7 +36578,7 @@ function applyOpenAIToolDelta(entry, state) {
|
|
|
36352
36578
|
if (name !== void 0 && name !== "") call.name = name;
|
|
36353
36579
|
}
|
|
36354
36580
|
const argsDelta = asString$21(fn.arguments) ?? "";
|
|
36355
|
-
|
|
36581
|
+
appendGuardedArguments(state, call, argsDelta);
|
|
36356
36582
|
if (!call.started) {
|
|
36357
36583
|
call.started = true;
|
|
36358
36584
|
state.hasToolCall = true;
|
|
@@ -36390,7 +36616,13 @@ function processAnthropicStreamLine(line, state) {
|
|
|
36390
36616
|
state.inputTokens = numberOr$8(usage.input_tokens, 0);
|
|
36391
36617
|
state.cacheReadTokens = numberOr$8(usage.cache_read_input_tokens, 0);
|
|
36392
36618
|
state.cacheWriteTokens = numberOr$8(usage.cache_creation_input_tokens, 0);
|
|
36619
|
+
state.cacheReadReported = typeof usage.cache_read_input_tokens === "number" && Number.isFinite(usage.cache_read_input_tokens);
|
|
36620
|
+
state.cacheWriteReported = typeof usage.cache_creation_input_tokens === "number" && Number.isFinite(usage.cache_creation_input_tokens);
|
|
36393
36621
|
state.outputTokens = numberOr$8(usage.output_tokens, 0);
|
|
36622
|
+
const reasoningDetails = isRecord$53(usage.output_tokens_details) ? usage.output_tokens_details : void 0;
|
|
36623
|
+
const reasoning = usage.reasoning_tokens ?? reasoningDetails?.reasoning_tokens;
|
|
36624
|
+
state.reasoningReported = typeof reasoning === "number" && Number.isFinite(reasoning);
|
|
36625
|
+
state.reasoningTokens = numberOr$8(reasoning, state.reasoningTokens);
|
|
36394
36626
|
}
|
|
36395
36627
|
const stop = message ? asString$21(message.stop_reason) : void 0;
|
|
36396
36628
|
if (stop !== void 0) state.finishReason = stop;
|
|
@@ -36454,7 +36686,7 @@ function processAnthropicStreamLine(line, state) {
|
|
|
36454
36686
|
const pending = state.toolCalls.get(contentIndex);
|
|
36455
36687
|
const partial = asString$21(delta.partial_json) ?? "";
|
|
36456
36688
|
if (pending !== void 0) {
|
|
36457
|
-
pending
|
|
36689
|
+
appendGuardedArguments(state, pending, partial);
|
|
36458
36690
|
out.push({
|
|
36459
36691
|
type: "tool-call-delta",
|
|
36460
36692
|
index: pending.blockIndex,
|
|
@@ -36502,6 +36734,7 @@ function processAnthropicStreamLine(line, state) {
|
|
|
36502
36734
|
const contentIndex = numberOr$8(event.index, 0);
|
|
36503
36735
|
const pending = state.toolCalls.get(contentIndex);
|
|
36504
36736
|
if (pending !== void 0) {
|
|
36737
|
+
throwToolGuardViolation(state, pending, pending.guard?.finish());
|
|
36505
36738
|
state.toolCalls.delete(contentIndex);
|
|
36506
36739
|
const block = {
|
|
36507
36740
|
type: "tool-call",
|
|
@@ -36528,6 +36761,12 @@ function processAnthropicStreamLine(line, state) {
|
|
|
36528
36761
|
if (usage) {
|
|
36529
36762
|
state.sawUsage = true;
|
|
36530
36763
|
state.outputTokens = numberOr$8(usage.output_tokens, state.outputTokens);
|
|
36764
|
+
const reasoningDetails = isRecord$53(usage.output_tokens_details) ? usage.output_tokens_details : void 0;
|
|
36765
|
+
const reasoning = usage.reasoning_tokens ?? reasoningDetails?.reasoning_tokens;
|
|
36766
|
+
if (typeof reasoning === "number" && Number.isFinite(reasoning)) {
|
|
36767
|
+
state.reasoningReported = true;
|
|
36768
|
+
state.reasoningTokens = reasoning;
|
|
36769
|
+
}
|
|
36531
36770
|
}
|
|
36532
36771
|
return out;
|
|
36533
36772
|
}
|
|
@@ -36971,7 +37210,7 @@ function closeStream$4(state, accountId) {
|
|
|
36971
37210
|
state.finished = true;
|
|
36972
37211
|
const out = [...closeCurrent$5(state), ...closeToolCalls$5(state)];
|
|
36973
37212
|
if (state.sawUsage) {
|
|
36974
|
-
recordCacheStats(state, state.sessionId, accountId);
|
|
37213
|
+
recordCacheStats(state, state.sessionId, accountId ?? state.accountId);
|
|
36975
37214
|
out.push({
|
|
36976
37215
|
type: "usage",
|
|
36977
37216
|
usage: tokenUsage$5(state)
|
|
@@ -37119,6 +37358,27 @@ var SessionCacheStateStore = class extends CommonSessionCacheStateStore {
|
|
|
37119
37358
|
normalizeRecord: normalizeRecord$2
|
|
37120
37359
|
});
|
|
37121
37360
|
}
|
|
37361
|
+
/** Append bounded request evidence, including a first request that failed before usage. */
|
|
37362
|
+
noteRequest(sessionId, request) {
|
|
37363
|
+
const base = this.read(sessionId) ?? {
|
|
37364
|
+
lastActiveAt: request.startedAt,
|
|
37365
|
+
totalTokens: 0,
|
|
37366
|
+
requests: 0,
|
|
37367
|
+
cachedTokens: 0,
|
|
37368
|
+
freshTokens: 0,
|
|
37369
|
+
outputTokens: 0,
|
|
37370
|
+
cacheWriteTokens: 0,
|
|
37371
|
+
cacheWrite5mTokens: 0,
|
|
37372
|
+
cacheWrite1hTokens: 0,
|
|
37373
|
+
updatedAt: request.endedAt
|
|
37374
|
+
};
|
|
37375
|
+
this.write(sessionId, {
|
|
37376
|
+
...base,
|
|
37377
|
+
lastActiveAt: Math.max(base.lastActiveAt, request.endedAt),
|
|
37378
|
+
recentRequests: [...base.recentRequests ?? [], request].slice(-20),
|
|
37379
|
+
updatedAt: request.endedAt
|
|
37380
|
+
});
|
|
37381
|
+
}
|
|
37122
37382
|
/** Update the warmup streak without creating a record for an unknown session. */
|
|
37123
37383
|
noteWarmupStreak(sessionId, consecutiveHits) {
|
|
37124
37384
|
this.update(sessionId, (existing) => {
|
|
@@ -37133,6 +37393,94 @@ var SessionCacheStateStore = class extends CommonSessionCacheStateStore {
|
|
|
37133
37393
|
});
|
|
37134
37394
|
}
|
|
37135
37395
|
};
|
|
37396
|
+
function optionalText(value, maxLength = 256) {
|
|
37397
|
+
return typeof value === "string" && value.trim() !== "" ? value.trim().slice(0, maxLength) : void 0;
|
|
37398
|
+
}
|
|
37399
|
+
function nullableCount(value) {
|
|
37400
|
+
return value === null ? null : nonNegative(value);
|
|
37401
|
+
}
|
|
37402
|
+
function normalizeAttempt(value) {
|
|
37403
|
+
if (!isRecord$52(value)) return void 0;
|
|
37404
|
+
const startedAt = finite(value.startedAt);
|
|
37405
|
+
if (startedAt === void 0) return void 0;
|
|
37406
|
+
const poolAction = value.poolAction === "retry-same-account" || value.poolAction === "cooldown-and-rotate" || value.poolAction === "mark-auth-failed" || value.poolAction === "none" ? value.poolAction : void 0;
|
|
37407
|
+
const status = nonNegative(value.status);
|
|
37408
|
+
const endedAt = finite(value.endedAt);
|
|
37409
|
+
const retryAfterMs = nonNegative(value.retryAfterMs);
|
|
37410
|
+
const accountId = optionalText(value.accountId);
|
|
37411
|
+
const code = optionalText(value.code);
|
|
37412
|
+
const providerRequestId = optionalText(value.providerRequestId, 128);
|
|
37413
|
+
return {
|
|
37414
|
+
startedAt,
|
|
37415
|
+
...accountId === void 0 ? {} : { accountId },
|
|
37416
|
+
...endedAt === void 0 ? {} : { endedAt },
|
|
37417
|
+
...status === void 0 ? {} : { status },
|
|
37418
|
+
...code === void 0 ? {} : { code },
|
|
37419
|
+
...poolAction === void 0 ? {} : { poolAction },
|
|
37420
|
+
...retryAfterMs === void 0 ? {} : { retryAfterMs },
|
|
37421
|
+
...providerRequestId === void 0 ? {} : { providerRequestId }
|
|
37422
|
+
};
|
|
37423
|
+
}
|
|
37424
|
+
function normalizeUsage(value) {
|
|
37425
|
+
if (!isRecord$52(value)) return void 0;
|
|
37426
|
+
const freshTokens = nonNegative(value.freshTokens);
|
|
37427
|
+
const outputTokens = nonNegative(value.outputTokens);
|
|
37428
|
+
const cacheReadTokens = nullableCount(value.cacheReadTokens);
|
|
37429
|
+
const cacheWriteTokens = nullableCount(value.cacheWriteTokens);
|
|
37430
|
+
const reasoningTokens = nullableCount(value.reasoningTokens);
|
|
37431
|
+
if (freshTokens === void 0 || outputTokens === void 0 || cacheReadTokens === void 0 || cacheWriteTokens === void 0 || reasoningTokens === void 0) return void 0;
|
|
37432
|
+
return {
|
|
37433
|
+
freshTokens,
|
|
37434
|
+
cacheReadTokens,
|
|
37435
|
+
cacheWriteTokens,
|
|
37436
|
+
outputTokens,
|
|
37437
|
+
reasoningTokens
|
|
37438
|
+
};
|
|
37439
|
+
}
|
|
37440
|
+
function normalizeRequestDiagnostic(value) {
|
|
37441
|
+
if (!isRecord$52(value)) return void 0;
|
|
37442
|
+
const id = optionalText(value.id, 128);
|
|
37443
|
+
const model = optionalText(value.model, 256);
|
|
37444
|
+
const startedAt = finite(value.startedAt);
|
|
37445
|
+
const endedAt = finite(value.endedAt);
|
|
37446
|
+
const wire = value.wire === "openai" || value.wire === "anthropic" ? value.wire : void 0;
|
|
37447
|
+
const outcome = value.outcome === "success" || value.outcome === "error" || value.outcome === "aborted" ? value.outcome : void 0;
|
|
37448
|
+
if (id === void 0 || model === void 0 || startedAt === void 0 || endedAt === void 0 || wire === void 0 || outcome === void 0) return void 0;
|
|
37449
|
+
const usage = normalizeUsage(value.usage);
|
|
37450
|
+
const attempts = (Array.isArray(value.attempts) ? value.attempts : []).map(normalizeAttempt).filter((attempt) => attempt !== void 0);
|
|
37451
|
+
const accountId = optionalText(value.accountId);
|
|
37452
|
+
const previousAccountId = optionalText(value.previousAccountId);
|
|
37453
|
+
const code = optionalText(value.code);
|
|
37454
|
+
const finishReason = optionalText(value.finishReason);
|
|
37455
|
+
const guard = isRecord$52(value.toolGuard) ? value.toolGuard : void 0;
|
|
37456
|
+
const guardName = optionalText(guard?.toolName);
|
|
37457
|
+
const guardBytes = nonNegative(guard?.bytes);
|
|
37458
|
+
const guardRule = guard?.rule === "argument-bytes" || guard?.rule === "repeated-key" ? guard.rule : void 0;
|
|
37459
|
+
return {
|
|
37460
|
+
id,
|
|
37461
|
+
startedAt,
|
|
37462
|
+
endedAt,
|
|
37463
|
+
model,
|
|
37464
|
+
wire,
|
|
37465
|
+
accountChanged: value.accountChanged === true,
|
|
37466
|
+
outcome,
|
|
37467
|
+
attempts,
|
|
37468
|
+
...accountId === void 0 ? {} : { accountId },
|
|
37469
|
+
...previousAccountId === void 0 ? {} : { previousAccountId },
|
|
37470
|
+
...code === void 0 ? {} : { code },
|
|
37471
|
+
...finishReason === void 0 ? {} : { finishReason },
|
|
37472
|
+
...usage === void 0 ? {} : { usage },
|
|
37473
|
+
...guardName === void 0 || guardBytes === void 0 || guardRule === void 0 ? {} : { toolGuard: {
|
|
37474
|
+
toolName: guardName,
|
|
37475
|
+
bytes: guardBytes,
|
|
37476
|
+
rule: guardRule
|
|
37477
|
+
} }
|
|
37478
|
+
};
|
|
37479
|
+
}
|
|
37480
|
+
function normalizeRecentRequests(value) {
|
|
37481
|
+
if (!Array.isArray(value)) return [];
|
|
37482
|
+
return value.map(normalizeRequestDiagnostic).filter((request) => request !== void 0).slice(-20);
|
|
37483
|
+
}
|
|
37136
37484
|
function normalizeRecord$2(value) {
|
|
37137
37485
|
if (!isRecord$52(value)) return void 0;
|
|
37138
37486
|
const lastActiveAt = finite(value.lastActiveAt);
|
|
@@ -37141,10 +37489,16 @@ function normalizeRecord$2(value) {
|
|
|
37141
37489
|
const drift = typeof value.lastDrift === "string" && value.lastDrift !== "" ? value.lastDrift : void 0;
|
|
37142
37490
|
const firstRequestCachedTokens = nonNegative(value.firstRequestCachedTokens);
|
|
37143
37491
|
const firstRequestPromptTokens = nonNegative(value.firstRequestPromptTokens);
|
|
37492
|
+
const lastRequestCachedTokens = nonNegative(value.lastRequestCachedTokens);
|
|
37493
|
+
const lastRequestFreshTokens = nonNegative(value.lastRequestFreshTokens);
|
|
37494
|
+
const previousRequestPromptTokens = nonNegative(value.previousRequestPromptTokens);
|
|
37495
|
+
const lastAccountId = typeof value.lastAccountId === "string" && value.lastAccountId.trim() !== "" ? value.lastAccountId.trim() : void 0;
|
|
37496
|
+
const lastAccountAt = nonNegative(value.lastAccountAt);
|
|
37144
37497
|
const warmupStreak = count$1(value.warmupConsecutiveHits);
|
|
37145
37498
|
const budgetDropped = droppedImageKeys(value.budgetDropped);
|
|
37146
37499
|
const lastRequestImageBytes = nonNegative(value.lastRequestImageBytes);
|
|
37147
37500
|
const lastDroppedImages = nonNegative(value.lastDroppedImages);
|
|
37501
|
+
const recentRequests = normalizeRecentRequests(value.recentRequests);
|
|
37148
37502
|
return {
|
|
37149
37503
|
lastActiveAt,
|
|
37150
37504
|
updatedAt,
|
|
@@ -37159,6 +37513,12 @@ function normalizeRecord$2(value) {
|
|
|
37159
37513
|
...drift === void 0 ? {} : { lastDrift: drift },
|
|
37160
37514
|
...firstRequestCachedTokens === void 0 ? {} : { firstRequestCachedTokens },
|
|
37161
37515
|
...firstRequestPromptTokens === void 0 ? {} : { firstRequestPromptTokens },
|
|
37516
|
+
...lastRequestCachedTokens === void 0 ? {} : { lastRequestCachedTokens },
|
|
37517
|
+
...lastRequestFreshTokens === void 0 ? {} : { lastRequestFreshTokens },
|
|
37518
|
+
...previousRequestPromptTokens === void 0 ? {} : { previousRequestPromptTokens },
|
|
37519
|
+
...lastAccountId === void 0 ? {} : { lastAccountId },
|
|
37520
|
+
...lastAccountAt === void 0 ? {} : { lastAccountAt },
|
|
37521
|
+
...recentRequests.length > 0 ? { recentRequests } : {},
|
|
37162
37522
|
...warmupStreak > 0 ? { warmupConsecutiveHits: warmupStreak } : {},
|
|
37163
37523
|
...budgetDropped.length > 0 ? { budgetDropped } : {},
|
|
37164
37524
|
...lastRequestImageBytes === void 0 ? {} : { lastRequestImageBytes },
|
|
@@ -38259,6 +38619,7 @@ function classifyKimiFailure(status, bodyText) {
|
|
|
38259
38619
|
const detail = summarizeFailureBody$1(bodyText);
|
|
38260
38620
|
if (isHttpContextOverflow(status, bodyText)) return {
|
|
38261
38621
|
code: CONTEXT_OVERFLOW_CODE,
|
|
38622
|
+
poolAction: "none",
|
|
38262
38623
|
retryable: false,
|
|
38263
38624
|
accountScoped: false,
|
|
38264
38625
|
upstreamOverload: false,
|
|
@@ -38266,6 +38627,7 @@ function classifyKimiFailure(status, bodyText) {
|
|
|
38266
38627
|
};
|
|
38267
38628
|
if (status === 400 && isKimiBodySizeRefusal(detail)) return {
|
|
38268
38629
|
code: CONTEXT_OVERFLOW_CODE,
|
|
38630
|
+
poolAction: "none",
|
|
38269
38631
|
retryable: false,
|
|
38270
38632
|
accountScoped: false,
|
|
38271
38633
|
upstreamOverload: false,
|
|
@@ -38273,6 +38635,7 @@ function classifyKimiFailure(status, bodyText) {
|
|
|
38273
38635
|
};
|
|
38274
38636
|
if (status === 402) return {
|
|
38275
38637
|
code: "SERVER",
|
|
38638
|
+
poolAction: "retry-same-account",
|
|
38276
38639
|
retryable: true,
|
|
38277
38640
|
accountScoped: false,
|
|
38278
38641
|
upstreamOverload: false,
|
|
@@ -38281,6 +38644,7 @@ function classifyKimiFailure(status, bodyText) {
|
|
|
38281
38644
|
if (status === 401 || status === 403) {
|
|
38282
38645
|
if (matchesAny$1(detail, ENTITLEMENT_PATTERNS)) return {
|
|
38283
38646
|
code: "PROVIDER_ERROR",
|
|
38647
|
+
poolAction: "none",
|
|
38284
38648
|
retryable: false,
|
|
38285
38649
|
accountScoped: false,
|
|
38286
38650
|
upstreamOverload: false,
|
|
@@ -38290,6 +38654,7 @@ function classifyKimiFailure(status, bodyText) {
|
|
|
38290
38654
|
const limitReached = matchesAny$1(detail, ACCOUNT_LIMIT_PATTERNS);
|
|
38291
38655
|
return {
|
|
38292
38656
|
code: "PROVIDER_ERROR",
|
|
38657
|
+
poolAction: "cooldown-and-rotate",
|
|
38293
38658
|
retryable: false,
|
|
38294
38659
|
accountScoped: true,
|
|
38295
38660
|
upstreamOverload: false,
|
|
@@ -38298,6 +38663,7 @@ function classifyKimiFailure(status, bodyText) {
|
|
|
38298
38663
|
}
|
|
38299
38664
|
return {
|
|
38300
38665
|
code: "INVALID_CREDENTIAL",
|
|
38666
|
+
poolAction: "mark-auth-failed",
|
|
38301
38667
|
retryable: false,
|
|
38302
38668
|
accountScoped: false,
|
|
38303
38669
|
upstreamOverload: false,
|
|
@@ -38307,6 +38673,7 @@ function classifyKimiFailure(status, bodyText) {
|
|
|
38307
38673
|
if (status === 429) {
|
|
38308
38674
|
if (matchesAny$1(detail, QUOTA_EXHAUSTED_PATTERNS$1)) return {
|
|
38309
38675
|
code: "PROVIDER_ERROR",
|
|
38676
|
+
poolAction: "cooldown-and-rotate",
|
|
38310
38677
|
retryable: false,
|
|
38311
38678
|
accountScoped: true,
|
|
38312
38679
|
upstreamOverload: false,
|
|
@@ -38314,6 +38681,7 @@ function classifyKimiFailure(status, bodyText) {
|
|
|
38314
38681
|
};
|
|
38315
38682
|
if (matchesAny$1(detail, UPSTREAM_OVERLOAD_PATTERNS)) return {
|
|
38316
38683
|
code: "SERVER",
|
|
38684
|
+
poolAction: "retry-same-account",
|
|
38317
38685
|
retryable: true,
|
|
38318
38686
|
accountScoped: false,
|
|
38319
38687
|
upstreamOverload: true,
|
|
@@ -38321,6 +38689,7 @@ function classifyKimiFailure(status, bodyText) {
|
|
|
38321
38689
|
};
|
|
38322
38690
|
return {
|
|
38323
38691
|
code: "RATE_LIMIT",
|
|
38692
|
+
poolAction: "retry-same-account",
|
|
38324
38693
|
retryable: true,
|
|
38325
38694
|
accountScoped: false,
|
|
38326
38695
|
upstreamOverload: false,
|
|
@@ -38329,6 +38698,7 @@ function classifyKimiFailure(status, bodyText) {
|
|
|
38329
38698
|
}
|
|
38330
38699
|
if (status >= 500) return {
|
|
38331
38700
|
code: "SERVER",
|
|
38701
|
+
poolAction: "retry-same-account",
|
|
38332
38702
|
retryable: true,
|
|
38333
38703
|
accountScoped: false,
|
|
38334
38704
|
upstreamOverload: matchesAny$1(detail, UPSTREAM_OVERLOAD_PATTERNS),
|
|
@@ -38336,6 +38706,7 @@ function classifyKimiFailure(status, bodyText) {
|
|
|
38336
38706
|
};
|
|
38337
38707
|
if (status === 400) return {
|
|
38338
38708
|
code: "PROVIDER_ERROR",
|
|
38709
|
+
poolAction: "none",
|
|
38339
38710
|
retryable: false,
|
|
38340
38711
|
accountScoped: false,
|
|
38341
38712
|
upstreamOverload: false,
|
|
@@ -38343,6 +38714,7 @@ function classifyKimiFailure(status, bodyText) {
|
|
|
38343
38714
|
};
|
|
38344
38715
|
return {
|
|
38345
38716
|
code: "PROVIDER_ERROR",
|
|
38717
|
+
poolAction: "none",
|
|
38346
38718
|
retryable: false,
|
|
38347
38719
|
accountScoped: false,
|
|
38348
38720
|
upstreamOverload: false,
|
|
@@ -38378,18 +38750,33 @@ function accountLimitCooldownMs(bodyText, now = Date.now()) {
|
|
|
38378
38750
|
resetAtMs: field !== null ? parseTimestamp(Number(field[1])) : instant !== null ? Date.parse(instant[0].replace(" ", "T")) : null,
|
|
38379
38751
|
now,
|
|
38380
38752
|
fallbackMs: BILLING_CYCLE_PATTERN.test(bodyText) ? BILLING_CYCLE_COOLDOWN_MS : ACCOUNT_LIMIT_COOLDOWN_MS,
|
|
38381
|
-
minimumMs:
|
|
38753
|
+
minimumMs: MIN_ACCOUNT_LIMIT_COOLDOWN_MS,
|
|
38382
38754
|
maximumMs: MAX_ACCOUNT_LIMIT_COOLDOWN_MS
|
|
38383
38755
|
});
|
|
38384
38756
|
}
|
|
38757
|
+
/** Minimum cooldown for a proven account-owned usage limit near its reset. */
|
|
38758
|
+
const MIN_ACCOUNT_LIMIT_COOLDOWN_MS = 15 * 6e4;
|
|
38385
38759
|
/**
|
|
38386
|
-
*
|
|
38760
|
+
* The account a shared/transient failure should use on the harness's next attempt.
|
|
38387
38761
|
*
|
|
38388
|
-
*
|
|
38389
|
-
*
|
|
38390
|
-
*
|
|
38762
|
+
* DSH rebuilds GenerateOptions for a retry, but keeps the step's original abort
|
|
38763
|
+
* signal. Keying by that signal avoids a process-global session latch: concurrent
|
|
38764
|
+
* sessions cannot affect one another, and an abandoned retry chain disappears by GC.
|
|
38391
38765
|
*/
|
|
38392
|
-
const
|
|
38766
|
+
const sameAccountRetryBySignal = /* @__PURE__ */ new WeakMap();
|
|
38767
|
+
function rememberSameAccountRetry(signal, accountId) {
|
|
38768
|
+
if (signal !== void 0 && accountId !== void 0 && !signal.aborted) sameAccountRetryBySignal.set(signal, accountId);
|
|
38769
|
+
}
|
|
38770
|
+
function clearSameAccountRetry(signal) {
|
|
38771
|
+
if (signal !== void 0) sameAccountRetryBySignal.delete(signal);
|
|
38772
|
+
}
|
|
38773
|
+
/** Only these non-secret, bounded upstream identities may enter durable diagnostics. */
|
|
38774
|
+
function upstreamRequestId(headers) {
|
|
38775
|
+
for (const name of ["x-request-id", "msh-request-id"]) {
|
|
38776
|
+
const value = headers.get(name)?.trim() ?? "";
|
|
38777
|
+
if (/^[A-Za-z0-9._:-]{1,128}$/.test(value)) return value;
|
|
38778
|
+
}
|
|
38779
|
+
}
|
|
38393
38780
|
/**
|
|
38394
38781
|
* Fallback cooldown for an account whose usage window is spent.
|
|
38395
38782
|
*
|
|
@@ -38525,30 +38912,39 @@ function reportDriftCause(sessionId, cause) {
|
|
|
38525
38912
|
if (driftWarned.size > 256) driftWarned.clear();
|
|
38526
38913
|
console.warn("[kimi-code] prompt cache rebuilt for session " + sessionId + ": the " + cause + " changed mid-conversation, so the whole prompt was reprocessed once.");
|
|
38527
38914
|
}
|
|
38528
|
-
function noteSessionCacheState(sessionId, state) {
|
|
38915
|
+
function noteSessionCacheState(sessionId, state, successful, requestDiagnostic) {
|
|
38529
38916
|
if (sessionId === void 0 || sessionId.trim() === "") return;
|
|
38530
38917
|
const stats = getCacheStats(sessionId);
|
|
38531
|
-
if (stats.requests === 0) return;
|
|
38918
|
+
if (stats.requests === 0 && requestDiagnostic === void 0) return;
|
|
38532
38919
|
const lastDrift = getLastDriftCause(sessionId);
|
|
38533
38920
|
reportDriftCause(sessionId, lastDrift);
|
|
38534
38921
|
const now = Date.now();
|
|
38535
38922
|
const imageBudget = getSessionImageBudgetStats(sessionId);
|
|
38536
38923
|
const priorRecord = sessionCacheState.read(sessionId);
|
|
38924
|
+
const previousRequestPromptTokens = priorRecord?.totalTokens;
|
|
38537
38925
|
const budgetDropped = imageBudget !== void 0 && imageBudget.droppedKeys.length > 0 ? imageBudget.droppedKeys : priorRecord?.budgetDropped;
|
|
38538
38926
|
const liveBytes = imageBudget?.requestImageBytes ?? 0;
|
|
38539
38927
|
const liveDropped = imageBudget?.droppedImages ?? 0;
|
|
38540
38928
|
const lastRequestImageBytes = liveBytes > 0 ? liveBytes : priorRecord?.lastRequestImageBytes;
|
|
38541
38929
|
const lastDroppedImages = liveDropped > 0 ? liveDropped : priorRecord?.lastDroppedImages;
|
|
38930
|
+
const recentRequests = requestDiagnostic === void 0 ? priorRecord?.recentRequests : [...priorRecord?.recentRequests ?? [], requestDiagnostic].slice(-20);
|
|
38931
|
+
const accountObservation = successful && state.accountId !== void 0 ? {
|
|
38932
|
+
lastAccountId: state.accountId,
|
|
38933
|
+
lastAccountAt: now
|
|
38934
|
+
} : {
|
|
38935
|
+
...priorRecord?.lastAccountId === void 0 ? {} : { lastAccountId: priorRecord.lastAccountId },
|
|
38936
|
+
...priorRecord?.lastAccountAt === void 0 ? {} : { lastAccountAt: priorRecord.lastAccountAt }
|
|
38937
|
+
};
|
|
38542
38938
|
const firstRequest = stats.requests === 1 ? {
|
|
38543
38939
|
firstRequestCachedTokens: state.cacheReadTokens,
|
|
38544
|
-
firstRequestPromptTokens: state.cacheReadTokens + state.inputTokens
|
|
38940
|
+
firstRequestPromptTokens: state.cacheReadTokens + state.inputTokens + state.cacheWriteTokens
|
|
38545
38941
|
} : {
|
|
38546
38942
|
...priorRecord?.firstRequestCachedTokens === void 0 ? {} : { firstRequestCachedTokens: priorRecord.firstRequestCachedTokens },
|
|
38547
38943
|
...priorRecord?.firstRequestPromptTokens === void 0 ? {} : { firstRequestPromptTokens: priorRecord.firstRequestPromptTokens }
|
|
38548
38944
|
};
|
|
38549
38945
|
sessionCacheState.write(sessionId, {
|
|
38550
38946
|
lastActiveAt: now,
|
|
38551
|
-
totalTokens: state.cacheReadTokens + state.inputTokens,
|
|
38947
|
+
totalTokens: state.cacheReadTokens + state.inputTokens + state.cacheWriteTokens,
|
|
38552
38948
|
requests: stats.requests,
|
|
38553
38949
|
cachedTokens: stats.cachedTokens,
|
|
38554
38950
|
freshTokens: stats.freshTokens,
|
|
@@ -38556,6 +38952,11 @@ function noteSessionCacheState(sessionId, state) {
|
|
|
38556
38952
|
cacheWriteTokens: stats.cacheWriteTokens,
|
|
38557
38953
|
cacheWrite5mTokens: stats.cacheWrite5mTokens,
|
|
38558
38954
|
cacheWrite1hTokens: stats.cacheWrite1hTokens,
|
|
38955
|
+
lastRequestCachedTokens: state.cacheReadTokens,
|
|
38956
|
+
lastRequestFreshTokens: state.inputTokens,
|
|
38957
|
+
...accountObservation,
|
|
38958
|
+
...recentRequests === void 0 ? {} : { recentRequests },
|
|
38959
|
+
...previousRequestPromptTokens === void 0 ? {} : { previousRequestPromptTokens },
|
|
38559
38960
|
...lastDrift === void 0 ? {} : { lastDrift },
|
|
38560
38961
|
...budgetDropped === void 0 ? {} : { budgetDropped },
|
|
38561
38962
|
...lastRequestImageBytes === void 0 ? {} : { lastRequestImageBytes },
|
|
@@ -38569,7 +38970,7 @@ function noteSessionCacheState(sessionId, state) {
|
|
|
38569
38970
|
inputTokens: state.inputTokens,
|
|
38570
38971
|
cacheReadTokens: state.cacheReadTokens,
|
|
38571
38972
|
outputTokens: state.outputTokens,
|
|
38572
|
-
totalTokens: state.cacheReadTokens + state.inputTokens,
|
|
38973
|
+
totalTokens: state.cacheReadTokens + state.inputTokens + state.cacheWriteTokens,
|
|
38573
38974
|
at: now,
|
|
38574
38975
|
...lastDrift === void 0 ? {} : { driftCause: lastDrift }
|
|
38575
38976
|
});
|
|
@@ -38737,13 +39138,18 @@ var KimiCodeAdapter = class extends LlmAdapter {
|
|
|
38737
39138
|
warm: true
|
|
38738
39139
|
});
|
|
38739
39140
|
}
|
|
38740
|
-
if (candidates.length === 0) return void 0;
|
|
38741
39141
|
const remainingShareById = {};
|
|
38742
39142
|
for (const candidate of candidates) remainingShareById[candidate.id] = remainingQuotaShare(cachedQuotaFor$1(candidate.id));
|
|
38743
|
-
const
|
|
39143
|
+
const warmAccountIds = orderAffinityCandidates({
|
|
38744
39144
|
candidates,
|
|
38745
39145
|
remainingShareById
|
|
38746
39146
|
});
|
|
39147
|
+
const sessionId = typeof options.sessionId === "string" ? options.sessionId.trim() : "";
|
|
39148
|
+
const durable = sessionId === "" ? void 0 : sessionCacheState.read(sessionId);
|
|
39149
|
+
const previousAccountId = durable?.lastAccountId;
|
|
39150
|
+
const previousAge = durable?.lastAccountAt === void 0 ? Infinity : Date.now() - durable.lastAccountAt;
|
|
39151
|
+
const previousIsWarm = previousAccountId !== void 0 && scopes.some((scope) => scope.id === previousAccountId) && previousAge >= 0 && previousAge < 15e5;
|
|
39152
|
+
const preferAccountIds = [.../* @__PURE__ */ new Set([...previousIsWarm ? [previousAccountId] : [], ...warmAccountIds])];
|
|
38747
39153
|
return preferAccountIds.length === 0 ? void 0 : { preferAccountIds };
|
|
38748
39154
|
}
|
|
38749
39155
|
/**
|
|
@@ -38852,10 +39258,27 @@ var KimiCodeAdapter = class extends LlmAdapter {
|
|
|
38852
39258
|
const normalized = normalizeGenerateOptions(options);
|
|
38853
39259
|
const sideChannel = isAuxiliaryRequest(normalized) || isSideChannelTitleRequest(normalized);
|
|
38854
39260
|
const sessionKey = typeof options.sessionId === "string" ? options.sessionId.trim() : "";
|
|
39261
|
+
const retrySignal = options.signal;
|
|
39262
|
+
const sameAccountRetryId = sideChannel || retrySignal === void 0 ? void 0 : sameAccountRetryBySignal.get(retrySignal);
|
|
39263
|
+
const previousAccountId = sideChannel || sessionKey === "" ? void 0 : sessionCacheState.read(sessionKey)?.lastAccountId;
|
|
39264
|
+
const requestDiagnostic = {
|
|
39265
|
+
id: randomUUID(),
|
|
39266
|
+
startedAt: Date.now(),
|
|
39267
|
+
endedAt: Date.now(),
|
|
39268
|
+
model: options.model,
|
|
39269
|
+
wire: "openai",
|
|
39270
|
+
...previousAccountId === void 0 ? {} : { previousAccountId },
|
|
39271
|
+
accountChanged: false,
|
|
39272
|
+
outcome: "error",
|
|
39273
|
+
attempts: []
|
|
39274
|
+
};
|
|
39275
|
+
let diagnosticState;
|
|
39276
|
+
let requestError;
|
|
38855
39277
|
const mainHeaderRelease = !sideChannel && sessionKey !== "" ? registerInFlightMainSessionHeader(sessionKey) : () => void 0;
|
|
38856
39278
|
try {
|
|
38857
39279
|
const catalog = await this.catalog().catch(() => []);
|
|
38858
39280
|
const wire = wireForCatalogEntry(options.model, catalog);
|
|
39281
|
+
requestDiagnostic.wire = wire;
|
|
38859
39282
|
const entry = catalog.find((model) => model.id === options.model);
|
|
38860
39283
|
const images = await resolveRequestImages$2(normalized, this.options.attachments, signal, KIMI_CODE_REQUEST_IMAGE_MAX_EDGE);
|
|
38861
39284
|
const priorDroppedKeys = getSessionDroppedImageKeys(options.sessionId, options.sessionId === void 0 ? void 0 : sessionCacheState.read(options.sessionId)?.budgetDropped);
|
|
@@ -38967,7 +39390,8 @@ var KimiCodeAdapter = class extends LlmAdapter {
|
|
|
38967
39390
|
let sentBuild;
|
|
38968
39391
|
const pool = this.accountPool;
|
|
38969
39392
|
const tried = /* @__PURE__ */ new Set();
|
|
38970
|
-
const
|
|
39393
|
+
const cacheAffinity = sideChannel ? void 0 : await this.cacheAffinityHint(pool, requestOptions);
|
|
39394
|
+
const affinity = sameAccountRetryId === void 0 ? cacheAffinity : { preferAccountIds: [.../* @__PURE__ */ new Set([sameAccountRetryId, ...cacheAffinity?.preferAccountIds ?? []])] };
|
|
38971
39395
|
let servedByAccountId;
|
|
38972
39396
|
let response;
|
|
38973
39397
|
while (true) {
|
|
@@ -38994,6 +39418,11 @@ var KimiCodeAdapter = class extends LlmAdapter {
|
|
|
38994
39418
|
tried.add(accountId);
|
|
38995
39419
|
apiCredentials = effective.credentials;
|
|
38996
39420
|
}
|
|
39421
|
+
const attemptDiagnostic = {
|
|
39422
|
+
startedAt: Date.now(),
|
|
39423
|
+
...accountId === void 0 ? {} : { accountId }
|
|
39424
|
+
};
|
|
39425
|
+
if (!sideChannel) requestDiagnostic.attempts.push(attemptDiagnostic);
|
|
38997
39426
|
const region = apiCredentials.region ?? await resolveRegion();
|
|
38998
39427
|
const base = (apiCredentials.baseUrl ?? codingBaseUrl(region)).replace(/\/+$/, "");
|
|
38999
39428
|
const endpoint = wire === "anthropic" ? `${base}/v1/messages?beta=true` : `${base}/v1/chat/completions`;
|
|
@@ -39088,21 +39517,30 @@ var KimiCodeAdapter = class extends LlmAdapter {
|
|
|
39088
39517
|
detail = response.ok ? "" : (await response.text().catch(() => "")).slice(0, 2e3);
|
|
39089
39518
|
}
|
|
39090
39519
|
}
|
|
39091
|
-
|
|
39520
|
+
attemptDiagnostic.status = response.status;
|
|
39521
|
+
const providerRequestId = upstreamRequestId(response.headers);
|
|
39522
|
+
if (providerRequestId !== void 0) attemptDiagnostic.providerRequestId = providerRequestId;
|
|
39523
|
+
if (response.ok) {
|
|
39524
|
+
attemptDiagnostic.endedAt = Date.now();
|
|
39525
|
+
if (accountId !== void 0) requestDiagnostic.accountId = accountId;
|
|
39526
|
+
clearSameAccountRetry(retrySignal);
|
|
39527
|
+
break;
|
|
39528
|
+
}
|
|
39092
39529
|
const failure = classifyKimiFailure(response.status, detail);
|
|
39530
|
+
attemptDiagnostic.code = failure.code;
|
|
39531
|
+
attemptDiagnostic.poolAction = failure.poolAction;
|
|
39532
|
+
attemptDiagnostic.endedAt = Date.now();
|
|
39093
39533
|
const after = response.status === 429 ? retryAfterMs$1(response.headers) : void 0;
|
|
39534
|
+
if (after !== void 0) attemptDiagnostic.retryAfterMs = after;
|
|
39535
|
+
if (failure.poolAction === "retry-same-account") rememberSameAccountRetry(retrySignal, accountId);
|
|
39536
|
+
else clearSameAccountRetry(retrySignal);
|
|
39094
39537
|
if (pool !== null && accountId !== void 0) {
|
|
39095
|
-
|
|
39096
|
-
|
|
39097
|
-
const cooldownMs = failure.accountScoped ? accountLimitCooldownMs(detail) : after ?? POOL_COOLDOWN_MS$5;
|
|
39098
|
-
await pool.markCooldown(accountId, cooldownMs, `${PROVIDER_NAME$8} 429`).catch(() => void 0);
|
|
39538
|
+
if (failure.poolAction === "cooldown-and-rotate") {
|
|
39539
|
+
await pool.markCooldown(accountId, accountLimitCooldownMs(detail), `${PROVIDER_NAME$8} ${response.status}`).catch(() => void 0);
|
|
39099
39540
|
if (await pool.hasAnotherAvailableAccount(tried)) continue;
|
|
39100
|
-
} else if (failure.
|
|
39541
|
+
} else if (failure.poolAction === "mark-auth-failed") {
|
|
39101
39542
|
await pool.markAuthFailed(accountId, failure.message).catch(() => void 0);
|
|
39102
39543
|
if (await pool.hasAnotherAvailableAccount(tried)) continue;
|
|
39103
|
-
} else if (failure.accountScoped) {
|
|
39104
|
-
await pool.markCooldown(accountId, accountLimitCooldownMs(detail), `${PROVIDER_NAME$8} 403`).catch(() => void 0);
|
|
39105
|
-
if (await pool.hasAnotherAvailableAccount(tried)) continue;
|
|
39106
39544
|
}
|
|
39107
39545
|
}
|
|
39108
39546
|
throw new LlmError(failure.message, failure.code, {
|
|
@@ -39127,6 +39565,8 @@ var KimiCodeAdapter = class extends LlmAdapter {
|
|
|
39127
39565
|
const reader = response.body.getReader();
|
|
39128
39566
|
const decoder = new TextDecoder();
|
|
39129
39567
|
const state = createStreamState$5(wire, requestOptions.sessionId, sideChannel);
|
|
39568
|
+
state.accountId = servedByAccountId;
|
|
39569
|
+
diagnosticState = state;
|
|
39130
39570
|
applyCacheWriteTiers(state, response.headers);
|
|
39131
39571
|
if (!sideChannel) markSessionActive(requestOptions.sessionId);
|
|
39132
39572
|
let buffer = "";
|
|
@@ -39170,14 +39610,42 @@ var KimiCodeAdapter = class extends LlmAdapter {
|
|
|
39170
39610
|
}
|
|
39171
39611
|
} catch (error) {
|
|
39172
39612
|
const inBand = state.streamError;
|
|
39173
|
-
if (error instanceof LlmError && !outputStarted && error.code === "PROVIDER_ERROR" && inBand !== void 0) throw await this.inBandStreamFailure(error, inBand, servedByAccountId);
|
|
39613
|
+
if (error instanceof LlmError && !outputStarted && error.code === "PROVIDER_ERROR" && inBand !== void 0) throw await this.inBandStreamFailure(error, inBand, servedByAccountId, retrySignal, requestDiagnostic.attempts.at(-1));
|
|
39174
39614
|
throw streamFailure(error, signal);
|
|
39175
39615
|
}
|
|
39176
39616
|
} finally {
|
|
39177
|
-
if (state.sawUsage && !sideChannel) noteSessionCacheState(requestOptions.sessionId ?? state.sessionId, state);
|
|
39178
39617
|
reader.cancel().catch(() => void 0);
|
|
39179
39618
|
}
|
|
39619
|
+
} catch (error) {
|
|
39620
|
+
if (error instanceof LlmError && isKimiToolArgumentGuardCode(error.code)) rememberSameAccountRetry(retrySignal, diagnosticState?.accountId);
|
|
39621
|
+
requestError = error;
|
|
39622
|
+
throw error;
|
|
39180
39623
|
} finally {
|
|
39624
|
+
const endedAt = Date.now();
|
|
39625
|
+
const finalAccountId = diagnosticState?.accountId ?? requestDiagnostic.accountId ?? requestDiagnostic.attempts.at(-1)?.accountId;
|
|
39626
|
+
const errorCode = requestError instanceof LlmError ? requestError.code : requestError === void 0 ? void 0 : "UNKNOWN";
|
|
39627
|
+
const lastAttempt = requestDiagnostic.attempts.at(-1);
|
|
39628
|
+
if (lastAttempt !== void 0 && errorCode !== void 0) {
|
|
39629
|
+
lastAttempt.code = errorCode;
|
|
39630
|
+
lastAttempt.endedAt ??= endedAt;
|
|
39631
|
+
}
|
|
39632
|
+
requestDiagnostic.endedAt = endedAt;
|
|
39633
|
+
if (finalAccountId !== void 0) requestDiagnostic.accountId = finalAccountId;
|
|
39634
|
+
requestDiagnostic.accountChanged = previousAccountId !== void 0 && finalAccountId !== void 0 && previousAccountId !== finalAccountId;
|
|
39635
|
+
requestDiagnostic.outcome = retrySignal?.aborted === true || errorCode === "ABORTED" ? "aborted" : requestError === void 0 && diagnosticState?.finished === true ? "success" : "error";
|
|
39636
|
+
if (errorCode !== void 0) requestDiagnostic.code = errorCode;
|
|
39637
|
+
else if (requestDiagnostic.outcome === "error") requestDiagnostic.code = "INCOMPLETE_STREAM";
|
|
39638
|
+
if (diagnosticState?.finishReason !== null && diagnosticState?.finishReason !== void 0) requestDiagnostic.finishReason = diagnosticState.finishReason;
|
|
39639
|
+
if (diagnosticState?.sawUsage === true) requestDiagnostic.usage = {
|
|
39640
|
+
freshTokens: diagnosticState.inputTokens,
|
|
39641
|
+
cacheReadTokens: diagnosticState.cacheReadReported ? diagnosticState.cacheReadTokens : null,
|
|
39642
|
+
cacheWriteTokens: diagnosticState.cacheWriteReported ? diagnosticState.cacheWriteTokens : null,
|
|
39643
|
+
outputTokens: diagnosticState.outputTokens,
|
|
39644
|
+
reasoningTokens: diagnosticState.reasoningReported ? diagnosticState.reasoningTokens : null
|
|
39645
|
+
};
|
|
39646
|
+
if (diagnosticState?.toolGuard !== void 0) requestDiagnostic.toolGuard = diagnosticState.toolGuard;
|
|
39647
|
+
if (!sideChannel && sessionKey !== "") if (diagnosticState?.sawUsage === true) noteSessionCacheState(diagnosticState.sessionId, diagnosticState, requestError === void 0 && diagnosticState.finished, requestDiagnostic);
|
|
39648
|
+
else sessionCacheState.noteRequest(sessionKey, requestDiagnostic);
|
|
39181
39649
|
mainHeaderRelease();
|
|
39182
39650
|
}
|
|
39183
39651
|
}
|
|
@@ -39197,37 +39665,32 @@ var KimiCodeAdapter = class extends LlmAdapter {
|
|
|
39197
39665
|
* re-issued: its body is already open and part-read, and the harness retry
|
|
39198
39666
|
* policy owns the repeat.
|
|
39199
39667
|
*/
|
|
39200
|
-
async inBandStreamFailure(thrown, inBand, accountId) {
|
|
39668
|
+
async inBandStreamFailure(thrown, inBand, accountId, retrySignal, attemptDiagnostic) {
|
|
39201
39669
|
const bodyText = JSON.stringify({ error: inBand.error });
|
|
39202
39670
|
const reclassified = inBand.vocabulary === "anthropic" ? reclassifyInBandError(thrown, inBand.error, classifyKimiFailure) : reclassifyInBandResponsesError(thrown, inBand.error, inBand.message, classifyKimiFailure);
|
|
39203
39671
|
const pool = this.accountPool;
|
|
39204
39672
|
if (pool === null || accountId === void 0) return reclassified;
|
|
39673
|
+
let action = "none";
|
|
39205
39674
|
if (inBand.vocabulary === "anthropic") {
|
|
39206
39675
|
const status = inBandAnthropicStatus(inBand.error);
|
|
39207
39676
|
if (status === null) return reclassified;
|
|
39208
|
-
|
|
39209
|
-
|
|
39210
|
-
|
|
39211
|
-
|
|
39212
|
-
|
|
39677
|
+
action = classifyKimiFailure(status, bodyText).poolAction;
|
|
39678
|
+
} else if (reclassified.code === "RATE_LIMIT" || matchesAny$1(bodyText, QUOTA_EXHAUSTED_PATTERNS$1)) action = classifyKimiFailure(429, bodyText).poolAction;
|
|
39679
|
+
else if (reclassified.code === "SERVER") action = "retry-same-account";
|
|
39680
|
+
if (attemptDiagnostic !== void 0) {
|
|
39681
|
+
attemptDiagnostic.code = reclassified.code;
|
|
39682
|
+
attemptDiagnostic.poolAction = action;
|
|
39683
|
+
attemptDiagnostic.endedAt = Date.now();
|
|
39684
|
+
}
|
|
39685
|
+
if (action === "retry-same-account") {
|
|
39686
|
+
rememberSameAccountRetry(retrySignal, accountId);
|
|
39213
39687
|
return reclassified;
|
|
39214
39688
|
}
|
|
39215
|
-
|
|
39689
|
+
clearSameAccountRetry(retrySignal);
|
|
39690
|
+
if (action === "cooldown-and-rotate") await pool.markCooldown(accountId, accountLimitCooldownMs(bodyText), `${PROVIDER_NAME$8} in-stream limit`).catch(() => void 0);
|
|
39691
|
+
else if (action === "mark-auth-failed") await pool.markAuthFailed(accountId, reclassified.message).catch(() => void 0);
|
|
39216
39692
|
return reclassified;
|
|
39217
39693
|
}
|
|
39218
|
-
/**
|
|
39219
|
-
* Cool the account whose own rate limit the stream reported.
|
|
39220
|
-
*
|
|
39221
|
-
* The window this route already defaults to, never a Retry-After: there is no
|
|
39222
|
-
* 429 response to read one from, and a delay stated on the 200 belongs to a
|
|
39223
|
-
* different message. An account-scoped verdict takes its own window instead,
|
|
39224
|
-
* because a spent balance is not back-pressure and 15 minutes would put the
|
|
39225
|
-
* account back into rotation four times inside the window that refused it.
|
|
39226
|
-
*/
|
|
39227
|
-
async coolInBandRateLimit(pool, accountId, accountScoped, bodyText) {
|
|
39228
|
-
const cooldownMs = accountScoped ? accountLimitCooldownMs(bodyText) : POOL_COOLDOWN_MS$5;
|
|
39229
|
-
await pool.markCooldown(accountId, cooldownMs, `${PROVIDER_NAME$8} in-stream 429`).catch(() => void 0);
|
|
39230
|
-
}
|
|
39231
39694
|
};
|
|
39232
39695
|
function isRefreshTimeout(error) {
|
|
39233
39696
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -39756,17 +40219,45 @@ function openingInheritanceOf(sessionId) {
|
|
|
39756
40219
|
hitRatio: Math.min(1, Math.max(0, cachedTokens / promptTokens))
|
|
39757
40220
|
};
|
|
39758
40221
|
}
|
|
40222
|
+
/**
|
|
40223
|
+
* Latest request's continuity against the previous prompt's observed 256-token
|
|
40224
|
+
* alignment baseline. Raw counts travel with the ratio so an above-baseline
|
|
40225
|
+
* reading stays visible instead of being hidden by clamping.
|
|
40226
|
+
*/
|
|
40227
|
+
function continuationOf(sessionId) {
|
|
40228
|
+
const durable = sessionCacheState.read(sessionId);
|
|
40229
|
+
const cachedTokens = durable?.lastRequestCachedTokens;
|
|
40230
|
+
const freshTokens = durable?.lastRequestFreshTokens;
|
|
40231
|
+
const previousPromptTokens = durable?.previousRequestPromptTokens;
|
|
40232
|
+
if (cachedTokens === void 0 || freshTokens === void 0 || previousPromptTokens === void 0) return void 0;
|
|
40233
|
+
const expectedCachedTokens = Math.floor(previousPromptTokens / 256) * 256;
|
|
40234
|
+
if (expectedCachedTokens <= 0) return void 0;
|
|
40235
|
+
return {
|
|
40236
|
+
cachedTokens,
|
|
40237
|
+
freshTokens,
|
|
40238
|
+
previousPromptTokens,
|
|
40239
|
+
expectedCachedTokens,
|
|
40240
|
+
retentionRatio: Math.min(1, Math.max(0, cachedTokens / expectedCachedTokens))
|
|
40241
|
+
};
|
|
40242
|
+
}
|
|
40243
|
+
function lastRequestDiagnosticOf(sessionId) {
|
|
40244
|
+
return sessionCacheState.read(sessionId)?.recentRequests?.at(-1);
|
|
40245
|
+
}
|
|
39759
40246
|
function cacheStatsOrNull(sessionId) {
|
|
39760
40247
|
const stats = getCacheStats(sessionId);
|
|
39761
40248
|
if (stats.requests === 0) return durableCacheStats(sessionId);
|
|
39762
40249
|
const lastDrift = getLastDriftCause(sessionId);
|
|
39763
40250
|
const warmup = warmupStatusOf(sessionId);
|
|
39764
40251
|
const opening = openingInheritanceOf(sessionId);
|
|
40252
|
+
const continuation = continuationOf(sessionId);
|
|
40253
|
+
const lastRequest = lastRequestDiagnosticOf(sessionId);
|
|
39765
40254
|
return {
|
|
39766
40255
|
...stats,
|
|
39767
40256
|
...lastDrift === void 0 ? {} : { lastDrift },
|
|
39768
40257
|
...warmup === void 0 ? {} : { warmup },
|
|
39769
40258
|
...opening === void 0 ? {} : { opening },
|
|
40259
|
+
...continuation === void 0 ? {} : { continuation },
|
|
40260
|
+
...lastRequest === void 0 ? {} : { lastRequest },
|
|
39770
40261
|
imageBudget: imageBudgetOf(sessionId),
|
|
39771
40262
|
cacheWriteTokens: stats.cacheWriteTokens,
|
|
39772
40263
|
cacheWrite5mTokens: stats.cacheWrite5mTokens,
|
|
@@ -39807,10 +40298,12 @@ function cacheHintOrNull(sessionId) {
|
|
|
39807
40298
|
*/
|
|
39808
40299
|
function durableCacheStats(sessionId) {
|
|
39809
40300
|
const durable = sessionCacheState.read(sessionId);
|
|
39810
|
-
if (durable === void 0 || durable.requests === 0) return null;
|
|
40301
|
+
if (durable === void 0 || durable.requests === 0 && durable.recentRequests === void 0) return null;
|
|
39811
40302
|
const lastDrift = driftCauseOf(durable.lastDrift);
|
|
39812
40303
|
const warmup = warmupStatusOf(sessionId);
|
|
39813
40304
|
const opening = openingInheritanceOf(sessionId);
|
|
40305
|
+
const continuation = continuationOf(sessionId);
|
|
40306
|
+
const lastRequest = lastRequestDiagnosticOf(sessionId);
|
|
39814
40307
|
return {
|
|
39815
40308
|
requests: durable.requests,
|
|
39816
40309
|
cachedTokens: durable.cachedTokens,
|
|
@@ -39823,6 +40316,8 @@ function durableCacheStats(sessionId) {
|
|
|
39823
40316
|
...lastDrift === void 0 ? {} : { lastDrift },
|
|
39824
40317
|
...warmup === void 0 ? {} : { warmup },
|
|
39825
40318
|
...opening === void 0 ? {} : { opening },
|
|
40319
|
+
...continuation === void 0 ? {} : { continuation },
|
|
40320
|
+
...lastRequest === void 0 ? {} : { lastRequest },
|
|
39826
40321
|
imageBudget: imageBudgetOf(sessionId)
|
|
39827
40322
|
};
|
|
39828
40323
|
}
|
|
@@ -49761,6 +50256,83 @@ function installKimiRepeatBreaker(ctx, options = {}) {
|
|
|
49761
50256
|
};
|
|
49762
50257
|
}
|
|
49763
50258
|
//#endregion
|
|
50259
|
+
//#region src/host/kimi-code/tool-argument-recovery.ts
|
|
50260
|
+
/**
|
|
50261
|
+
* One guided retry after a Kimi tool-argument stream enters a runaway shape.
|
|
50262
|
+
*
|
|
50263
|
+
* The failed attempt is already settled before `agent/request-error` runs. The
|
|
50264
|
+
* recovery notice is appended AFTER it, so the next same-step deriveMessages()
|
|
50265
|
+
* sees the instruction without changing the system prompt or tool declarations.
|
|
50266
|
+
* `agent.steer()` is deliberately not used: it targets a later step boundary.
|
|
50267
|
+
*/
|
|
50268
|
+
const MAX_RECOVERY_STEPS = 256;
|
|
50269
|
+
function text$4(value) {
|
|
50270
|
+
return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
|
|
50271
|
+
}
|
|
50272
|
+
function number(value) {
|
|
50273
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
|
|
50274
|
+
}
|
|
50275
|
+
/** The model-facing recovery instruction; raw tool arguments never enter it. */
|
|
50276
|
+
function createKimiToolArgumentRecoveryMessage(code) {
|
|
50277
|
+
const repeated = code === TOOL_ARGUMENT_REPEATED_KEY_CODE;
|
|
50278
|
+
return createUserMessage$1({
|
|
50279
|
+
content: [{
|
|
50280
|
+
type: "text",
|
|
50281
|
+
text: repeated ? "The previous tool call was stopped because its JSON arguments contained a runaway repeated-key family. Do not resume, reuse, or repair that payload. If you still need a tool, make one fresh call with minimal valid JSON and only the exact property names in its schema. For ask_user_question, use only questions, id, question, header, options, label, description, and multi_select as applicable; never append documentation annotations or underscores to property names. If no tool call is necessary, continue with the evidence already available or explain the blocker in text." : "The previous tool call was stopped because its arguments exceeded the route byte budget. Do not resend the same payload. If the existing evidence is sufficient, finish in text. Otherwise make one fresh call with the smallest sufficient arguments; for a large file or program, use a legal smaller/chunked approach instead of repeating the oversized content."
|
|
50282
|
+
}],
|
|
50283
|
+
source: {
|
|
50284
|
+
kind: PLUGIN_MESSAGE_SOURCE_KIND,
|
|
50285
|
+
form: "notice",
|
|
50286
|
+
summary: boundContextSummary(repeated ? "Runaway tool arguments: retry once with fresh minimal JSON." : "Oversized tool arguments: retry once with a smaller payload.")
|
|
50287
|
+
}
|
|
50288
|
+
});
|
|
50289
|
+
}
|
|
50290
|
+
/** Install the one-per-step request recovery hook. */
|
|
50291
|
+
function installKimiToolArgumentRecovery(ctx) {
|
|
50292
|
+
const attempted = /* @__PURE__ */ new Set();
|
|
50293
|
+
const clearAgent = (raw) => {
|
|
50294
|
+
const agent = raw;
|
|
50295
|
+
const sessionId = text$4(agent?.session?.id) ?? text$4(agent?.id);
|
|
50296
|
+
if (sessionId === void 0) return;
|
|
50297
|
+
const prefix = sessionId + ":";
|
|
50298
|
+
for (const key of [...attempted]) if (key.startsWith(prefix)) attempted.delete(key);
|
|
50299
|
+
};
|
|
50300
|
+
const disposeRequestError = ctx.on?.("agent/request-error", (async (payload, next) => {
|
|
50301
|
+
const code = payload.failure?.code;
|
|
50302
|
+
if (payload.provider !== "kimi-code" || !isKimiToolArgumentGuardCode(code)) return await next();
|
|
50303
|
+
if (payload.signal?.aborted === true) return await next();
|
|
50304
|
+
const agent = payload.agent;
|
|
50305
|
+
const sessionId = text$4(agent?.session?.id) ?? text$4(agent?.id);
|
|
50306
|
+
const turn = number(payload.turn);
|
|
50307
|
+
const step = number(payload.step);
|
|
50308
|
+
const session = agent?.session;
|
|
50309
|
+
const append = session?.append;
|
|
50310
|
+
if (sessionId === void 0 || turn === void 0 || step === void 0 || session === void 0 || append === void 0) return await next();
|
|
50311
|
+
const key = `${sessionId}:${turn}:${step}`;
|
|
50312
|
+
if (attempted.has(key)) return await next();
|
|
50313
|
+
const message = createKimiToolArgumentRecoveryMessage(code);
|
|
50314
|
+
try {
|
|
50315
|
+
append.call(session, "user/message", message, { surfaceOp: "append" });
|
|
50316
|
+
} catch {
|
|
50317
|
+
return await next();
|
|
50318
|
+
}
|
|
50319
|
+
attempted.add(key);
|
|
50320
|
+
while (attempted.size > MAX_RECOVERY_STEPS) {
|
|
50321
|
+
const oldest = attempted.keys().next();
|
|
50322
|
+
if (oldest.done !== true) attempted.delete(oldest.value);
|
|
50323
|
+
}
|
|
50324
|
+
return { kind: "retry" };
|
|
50325
|
+
}));
|
|
50326
|
+
const disposeDisposed = ctx.on?.("agent/disposed", ((payload) => {
|
|
50327
|
+
clearAgent(payload?.agent);
|
|
50328
|
+
}));
|
|
50329
|
+
return () => {
|
|
50330
|
+
disposeRequestError?.();
|
|
50331
|
+
disposeDisposed?.();
|
|
50332
|
+
attempted.clear();
|
|
50333
|
+
};
|
|
50334
|
+
}
|
|
50335
|
+
//#endregion
|
|
49764
50336
|
//#region src/host/minimax-code/account-pool.ts
|
|
49765
50337
|
/**
|
|
49766
50338
|
* MiniMax Code 号池:the account pool for the MiniMax Code (编程订阅) line.
|
|
@@ -64533,6 +65105,7 @@ var GlmCodingPlanAdapter = class extends LlmAdapter {
|
|
|
64533
65105
|
preferences;
|
|
64534
65106
|
accountPool;
|
|
64535
65107
|
options;
|
|
65108
|
+
catalogRegionSnapshot;
|
|
64536
65109
|
constructor(store = new GlmCodingPlanCredentialStore(), modelSettings = new GlmCodingPlanModelSettingsStore(), preferences, options = {}) {
|
|
64537
65110
|
super();
|
|
64538
65111
|
this.store = store;
|
|
@@ -64565,6 +65138,38 @@ var GlmCodingPlanAdapter = class extends LlmAdapter {
|
|
|
64565
65138
|
return cached.length > 0 ? cached : modelsForRegion(region, GLM_MODEL_CATALOG);
|
|
64566
65139
|
}
|
|
64567
65140
|
/**
|
|
65141
|
+
* 模型目录只需要区域,不需要一把可发请求的凭据。
|
|
65142
|
+
*
|
|
65143
|
+
* 这里刻意不调用 credentialFor:那是真实请求的选号入口,会重复解密号池并回写
|
|
65144
|
+
* lastUsedAt。目录构建会为每个模型并发调用 resolveModel,把它放在这里会让一次
|
|
65145
|
+
* 选择器刷新放大成一串 DPAPI 读写。区域快照按号池 revision 与指定账号失效,
|
|
65146
|
+
* 同一代的并发调用共享同一次只读;读不到或尚未登录时不缓存,登录后即可重试。
|
|
65147
|
+
*/
|
|
65148
|
+
catalogRegion(settings) {
|
|
65149
|
+
const pool = this.accountPool;
|
|
65150
|
+
if (pool === null) return this.readCatalogRegion(settings).catch(() => null);
|
|
65151
|
+
const revision = pool.currentIdentityRevision();
|
|
65152
|
+
const selectedAccountId = settings.selectedAccountId;
|
|
65153
|
+
const cached = this.catalogRegionSnapshot;
|
|
65154
|
+
if (cached !== void 0 && cached.revision === revision && cached.selectedAccountId === selectedAccountId) return cached.region;
|
|
65155
|
+
const snapshot = {
|
|
65156
|
+
revision,
|
|
65157
|
+
selectedAccountId,
|
|
65158
|
+
region: this.readCatalogRegion(settings).catch(() => null)
|
|
65159
|
+
};
|
|
65160
|
+
this.catalogRegionSnapshot = snapshot;
|
|
65161
|
+
snapshot.region.then((region) => {
|
|
65162
|
+
if (region === null && this.catalogRegionSnapshot === snapshot) this.catalogRegionSnapshot = void 0;
|
|
65163
|
+
});
|
|
65164
|
+
return snapshot.region;
|
|
65165
|
+
}
|
|
65166
|
+
async readCatalogRegion(settings) {
|
|
65167
|
+
if (this.accountPool === null) return (await this.store.read())?.codingPlan.region ?? null;
|
|
65168
|
+
const data = await this.accountPool.read();
|
|
65169
|
+
const usable = data.accounts.filter((account) => account.authStatus === void 0 || account.authStatus === "ok");
|
|
65170
|
+
return (usable.find((account) => account.id === settings.selectedAccountId) ?? usable.find((account) => account.id === data.activeAccountId) ?? usable.find((account) => account.isPrimary) ?? usable[0])?.credentials.codingPlan.region ?? null;
|
|
65171
|
+
}
|
|
65172
|
+
/**
|
|
64568
65173
|
* 这一行请求用哪份凭据。
|
|
64569
65174
|
*
|
|
64570
65175
|
* 有池时轮转;没有池时读单凭据存储(无头 host 与测试的形态)。
|
|
@@ -64589,10 +65194,9 @@ var GlmCodingPlanAdapter = class extends LlmAdapter {
|
|
|
64589
65194
|
async listModels(provider) {
|
|
64590
65195
|
const prov = provider || PROVIDER_ID$1;
|
|
64591
65196
|
const settings = await this.settings();
|
|
64592
|
-
if (settings.enabled === false) return [];
|
|
64593
|
-
const
|
|
64594
|
-
if (
|
|
64595
|
-
const region = pick.credentials.codingPlan.region;
|
|
65197
|
+
if (settings.enabled === false || settings.enabledModelIds.length === 0) return [];
|
|
65198
|
+
const region = await this.catalogRegion(settings);
|
|
65199
|
+
if (region === null) return [];
|
|
64596
65200
|
const available = this.catalog(region);
|
|
64597
65201
|
const enabled = new Set(settings.enabledModelIds);
|
|
64598
65202
|
return available.filter((model) => model.wire !== null && enabled.has(model.id)).map((model) => ({
|
|
@@ -64605,7 +65209,7 @@ var GlmCodingPlanAdapter = class extends LlmAdapter {
|
|
|
64605
65209
|
async resolveModel(provider, model, signal) {
|
|
64606
65210
|
if (signal?.aborted) throw new LlmError(t("glm.modelResolveAborted", { provider: PROVIDER_NAME$1 }), "ABORTED");
|
|
64607
65211
|
const settings = await this.settings();
|
|
64608
|
-
const region =
|
|
65212
|
+
const region = await this.catalogRegion(settings) ?? "intl";
|
|
64609
65213
|
const entry = resolveGlmModel(model, this.catalog(region));
|
|
64610
65214
|
const override = settings.contextWindowOverrides[model];
|
|
64611
65215
|
const contextWindow = typeof override === "number" && Number.isFinite(override) && override > 0 ? override : entry.defaultContextWindow;
|
|
@@ -97338,10 +97942,10 @@ function installCacheWarmup(ctx, options) {
|
|
|
97338
97942
|
const blocks = decision.content ?? result.content;
|
|
97339
97943
|
if (blocks.length === 0) return decision;
|
|
97340
97944
|
const baseNavigation = retrievalTool || ptcRetrieval ? cacheWarmupNavigationIntentOf(exec.agent) : void 0;
|
|
97341
|
-
const
|
|
97945
|
+
const isSearchPreviewCandidate = (exec.name === "grep" || exec.name === "glob") && blocks.reduce((sum, block) => {
|
|
97342
97946
|
return sum + (typeof block === "object" && block !== null && typeof block.text === "string" ? block.text : "").length;
|
|
97343
|
-
}, 0) >=
|
|
97344
|
-
const navigation = baseNavigation === true ||
|
|
97947
|
+
}, 0) >= CACHE_WARMUP_DEFAULTS.warmupMaxChars;
|
|
97948
|
+
const navigation = baseNavigation === true || isSearchPreviewCandidate ? true : baseNavigation;
|
|
97345
97949
|
if (retrievalTool && navigation !== true) return decision;
|
|
97346
97950
|
if (sourceTool && !settings.enabled && navigation !== true) return decision;
|
|
97347
97951
|
const route = cacheWarmupRouteOf(exec.agent);
|
|
@@ -105967,6 +106571,7 @@ function apply(ctx, pluginConfig = {}) {
|
|
|
105967
106571
|
providers: CONTROLLED_PROVIDERS.filter((provider) => provider !== "minimax-code"),
|
|
105968
106572
|
globalEnabled: () => resolveToolRunawayGuardEnabled(pluginConfig)
|
|
105969
106573
|
}), "dsh-chatgpt-subscription: shared tool runaway guard");
|
|
106574
|
+
ctx.effect(() => installKimiToolArgumentRecovery(ctx), "dsh-chatgpt-subscription: Kimi tool argument recovery");
|
|
105970
106575
|
ctx.effect(() => installDispatchExecutionGuard(ctx, { enabled: () => resolveDispatchExecutionGuardEnabled(pluginConfig) }), "dsh-chatgpt-subscription: dispatch execution guard");
|
|
105971
106576
|
ctx.effect(() => installDispatchLedger(ctx, {
|
|
105972
106577
|
enabled: () => resolveDispatchExecutionGuardEnabled(pluginConfig),
|