@eddyskywalker/dsh-chatgpt-subscription 0.22.0 → 0.23.0
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 +19 -0
- package/README.md +5 -2
- package/lib/client.js +100 -17
- package/lib/client.js.map +1 -1
- package/lib/index.js +385 -520
- package/lib/types/client/glm-coding-plan/GlmCodingPlanSection.d.ts.map +1 -1
- package/lib/types/client/glm-coding-plan/locales.d.ts +8 -11
- package/lib/types/client/glm-coding-plan/locales.d.ts.map +1 -1
- package/lib/types/client/ollama/OllamaSection.d.ts.map +1 -1
- package/lib/types/client/ollama/api.d.ts +13 -0
- package/lib/types/client/ollama/api.d.ts.map +1 -1
- package/lib/types/client/ollama/locales.d.ts +24 -0
- package/lib/types/client/ollama/locales.d.ts.map +1 -1
- package/lib/types/client/step-code/locales.d.ts +2 -2
- package/lib/types/host/glm-coding-plan/adapter.d.ts +1 -14
- package/lib/types/host/glm-coding-plan/adapter.d.ts.map +1 -1
- package/lib/types/host/glm-coding-plan/client.d.ts.map +1 -1
- package/lib/types/host/glm-coding-plan/types.d.ts +0 -10
- package/lib/types/host/glm-coding-plan/types.d.ts.map +1 -1
- package/lib/types/host/ollama/adapter.d.ts +26 -2
- package/lib/types/host/ollama/adapter.d.ts.map +1 -1
- package/lib/types/host/ollama/client.d.ts +16 -1
- package/lib/types/host/ollama/client.d.ts.map +1 -1
- package/lib/types/host/ollama/routes.d.ts +1 -1
- package/lib/types/host/ollama/routes.d.ts.map +1 -1
- package/lib/types/host/ollama/types.d.ts +74 -8
- package/lib/types/host/ollama/types.d.ts.map +1 -1
- package/lib/types/index.d.ts +0 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/ollama-contracts.d.ts +30 -0
- package/lib/types/shared/ollama-contracts.d.ts.map +1 -1
- package/package.json +1 -1
- package/lib/types/host/glm-coding-plan/signing.d.ts +0 -323
- package/lib/types/host/glm-coding-plan/signing.d.ts.map +0 -1
package/lib/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { HarnessError, LlmAdapter, LlmError, LlmError as LlmError$1, ProviderReq
|
|
|
5
5
|
import fs, { chmod, lstat, mkdir, open, readFile, rename, stat, unlink } from "node:fs/promises";
|
|
6
6
|
import path, { basename, dirname, join, relative, resolve } from "node:path";
|
|
7
7
|
import os, { homedir, platform, userInfo } from "node:os";
|
|
8
|
-
import
|
|
8
|
+
import { createDecipheriv, createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
|
|
9
9
|
import { isDeepStrictEqual } from "node:util";
|
|
10
10
|
import { execSync, spawn } from "node:child_process";
|
|
11
11
|
import fs$1, { appendFileSync, constants, copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, statSync, utimesSync, writeFileSync } from "node:fs";
|
|
@@ -278,7 +278,7 @@ const GPT_6_REASONING_EFFORTS = [
|
|
|
278
278
|
"xhigh",
|
|
279
279
|
"max"
|
|
280
280
|
];
|
|
281
|
-
function reasoningEffortsForModel(model) {
|
|
281
|
+
function reasoningEffortsForModel$1(model) {
|
|
282
282
|
const profile = resolveCodexCatalogEntry(model).reasoningProfile;
|
|
283
283
|
if (profile === "gpt-6") return GPT_6_REASONING_EFFORTS;
|
|
284
284
|
return profile === "gpt-5.6" ? GPT_56_REASONING_EFFORTS : STANDARD_REASONING_EFFORTS;
|
|
@@ -396,7 +396,7 @@ function resolveCodexModel(model, preferences, live) {
|
|
|
396
396
|
const liveEntry = live?.find((candidate) => candidate.id === model);
|
|
397
397
|
const configuredContextWindow = (preferences?.status())?.contextWindowOverrides[model];
|
|
398
398
|
const listedEfforts = liveEntry?.reasoningEfforts?.filter(isCodexReasoningEffort);
|
|
399
|
-
const efforts = listedEfforts !== void 0 && listedEfforts.length > 0 ? listedEfforts : reasoningEffortsForModel(model);
|
|
399
|
+
const efforts = listedEfforts !== void 0 && listedEfforts.length > 0 ? listedEfforts : reasoningEffortsForModel$1(model);
|
|
400
400
|
const statedDefault = liveEntry?.defaultReasoningEffort ?? entry.defaultReasoningEffort;
|
|
401
401
|
const defaultEffort = isCodexReasoningEffort(statedDefault) && efforts.includes(statedDefault) ? statedDefault : efforts[0];
|
|
402
402
|
return {
|
|
@@ -17334,6 +17334,8 @@ const CLOUD_BASE_URL = "https://ollama.com";
|
|
|
17334
17334
|
/** Native surface. */
|
|
17335
17335
|
const NATIVE_CHAT_PATH = "/api/chat";
|
|
17336
17336
|
const NATIVE_TAGS_PATH = "/api/tags";
|
|
17337
|
+
/** Per-model metadata: the one surface where a model states its own thinking levels. */
|
|
17338
|
+
const NATIVE_SHOW_PATH = "/api/show";
|
|
17337
17339
|
const OPENAI_CHAT_PATH = "/chat/completions";
|
|
17338
17340
|
/**
|
|
17339
17341
|
* Default context window for a model whose catalog entry states none.
|
|
@@ -17361,12 +17363,13 @@ const DEFAULT_MAX_OUTPUT_TOKENS = 8192;
|
|
|
17361
17363
|
*
|
|
17362
17364
|
* @param modelId - the routed model id.
|
|
17363
17365
|
* @param requested - the caller's cap, undefined when it stated none.
|
|
17366
|
+
* @param declared - the model's own thinking metadata, when it was read.
|
|
17364
17367
|
* @returns the cap to request, raised only when that is the difference between an
|
|
17365
17368
|
* empty truncated answer and a usable one.
|
|
17366
17369
|
*/
|
|
17367
|
-
function floorForcedThinkingTokens$1(modelId, requested) {
|
|
17370
|
+
function floorForcedThinkingTokens$1(modelId, requested, declared) {
|
|
17368
17371
|
if (requested === void 0) return void 0;
|
|
17369
|
-
if (thinkingModeForModel(modelId) !== "levels") return requested;
|
|
17372
|
+
if (thinkingModeForModel(modelId, declared) !== "levels") return requested;
|
|
17370
17373
|
return Math.max(requested, 512);
|
|
17371
17374
|
}
|
|
17372
17375
|
/** How long a catalog sync may take before the cached list is used instead. */
|
|
@@ -17427,13 +17430,110 @@ function ollamaModelSupportsImage(modelId) {
|
|
|
17427
17430
|
return supportsOllamaImage(modelId, "openai", "api-key");
|
|
17428
17431
|
}
|
|
17429
17432
|
/**
|
|
17433
|
+
* The ladder a levels model takes when no metadata could be read for it.
|
|
17434
|
+
*
|
|
17435
|
+
* The list is the fallback, not the answer: it can only ever name families this
|
|
17436
|
+
* file already knows, and a model the service describes with any other level
|
|
17437
|
+
* names has to be sent those names verbatim.
|
|
17438
|
+
*/
|
|
17439
|
+
const DEFAULT_LEVEL_EFFORTS = Object.freeze([
|
|
17440
|
+
{
|
|
17441
|
+
id: "low",
|
|
17442
|
+
name: "low"
|
|
17443
|
+
},
|
|
17444
|
+
{
|
|
17445
|
+
id: "medium",
|
|
17446
|
+
name: "medium"
|
|
17447
|
+
},
|
|
17448
|
+
{
|
|
17449
|
+
id: "high",
|
|
17450
|
+
name: "high"
|
|
17451
|
+
}
|
|
17452
|
+
]);
|
|
17453
|
+
/**
|
|
17454
|
+
* The on/off positions a boolean ladder is made of.
|
|
17455
|
+
*
|
|
17456
|
+
* The ids are the two values `thinkForModel` puts on the wire for such a model:
|
|
17457
|
+
* `none` becomes `false`, `low` becomes `true`. The names are the user's, because
|
|
17458
|
+
* on a model that thinks, a bare "none" reads as "this model cannot think"
|
|
17459
|
+
* rather than as the switch that turns its thinking off.
|
|
17460
|
+
*/
|
|
17461
|
+
const BOOLEAN_EFFORTS = Object.freeze([{
|
|
17462
|
+
value: false,
|
|
17463
|
+
id: "none",
|
|
17464
|
+
name: "关闭思考"
|
|
17465
|
+
}, {
|
|
17466
|
+
value: true,
|
|
17467
|
+
id: "low",
|
|
17468
|
+
name: "开启思考"
|
|
17469
|
+
}]);
|
|
17470
|
+
/** The same two positions as the picker renders them, without the wire value. */
|
|
17471
|
+
function booleanEfforts() {
|
|
17472
|
+
return BOOLEAN_EFFORTS.map(({ id, name }) => ({
|
|
17473
|
+
id,
|
|
17474
|
+
name
|
|
17475
|
+
}));
|
|
17476
|
+
}
|
|
17477
|
+
/**
|
|
17478
|
+
* The ladder this model declares, one row per value it accepts.
|
|
17479
|
+
*
|
|
17480
|
+
* Every row is derived from `declared.values` itself, so the ladder can neither
|
|
17481
|
+
* offer a position the wire would refuse nor hide one it will take: a model that
|
|
17482
|
+
* declares `[true]` - thinking on, with no way to switch it off - is offered
|
|
17483
|
+
* exactly that one position and never the off switch, which `false` there would
|
|
17484
|
+
* be refused for.
|
|
17485
|
+
*
|
|
17486
|
+
* Levels keep the model's own spelling and declaration order; the on/off pair
|
|
17487
|
+
* follows them in a fixed order (off, then on). So two models declaring the same
|
|
17488
|
+
* values in a different order offer the same ladder, and the last position a
|
|
17489
|
+
* picker shows is the one that turns thinking on rather than off.
|
|
17490
|
+
*/
|
|
17491
|
+
function declaredEfforts(declared) {
|
|
17492
|
+
const levels = [];
|
|
17493
|
+
const switches = /* @__PURE__ */ new Map();
|
|
17494
|
+
const taken = /* @__PURE__ */ new Set();
|
|
17495
|
+
for (const value of declared.values) {
|
|
17496
|
+
if (typeof value === "string") {
|
|
17497
|
+
if (taken.has(value)) continue;
|
|
17498
|
+
taken.add(value);
|
|
17499
|
+
levels.push({
|
|
17500
|
+
value,
|
|
17501
|
+
id: value,
|
|
17502
|
+
name: value
|
|
17503
|
+
});
|
|
17504
|
+
continue;
|
|
17505
|
+
}
|
|
17506
|
+
const known = BOOLEAN_EFFORTS.find((entry) => entry.value === value);
|
|
17507
|
+
if (known === void 0 || switches.has(value) || taken.has(known.id)) continue;
|
|
17508
|
+
switches.set(value, known);
|
|
17509
|
+
taken.add(known.id);
|
|
17510
|
+
}
|
|
17511
|
+
const off = switches.get(false);
|
|
17512
|
+
const on = switches.get(true);
|
|
17513
|
+
return [
|
|
17514
|
+
...levels,
|
|
17515
|
+
...off === void 0 ? [] : [off],
|
|
17516
|
+
...on === void 0 ? [] : [on]
|
|
17517
|
+
];
|
|
17518
|
+
}
|
|
17519
|
+
/**
|
|
17430
17520
|
* Resolve model-specific thinking support in Ollama.
|
|
17521
|
+
*
|
|
17522
|
+
* The service's own metadata outranks the prefix list: `/api/show` is where a
|
|
17523
|
+
* model states the levels it accepts, and it is the only source there is for a
|
|
17524
|
+
* family this file has never heard of. The prefix list stays as the fallback for
|
|
17525
|
+
* a model whose metadata could not be read, and that fallback is unchanged.
|
|
17526
|
+
*
|
|
17431
17527
|
* Source: official https://github.com/ollama/ollama/blob/main/docs/capabilities/thinking.mdx
|
|
17432
|
-
* - 'levels': gpt-oss
|
|
17433
|
-
* - 'boolean': deepseek-r1, qwq, qwen3
|
|
17434
|
-
* - 'none':
|
|
17528
|
+
* - 'levels': named levels (gpt-oss: low, medium, high; cannot disable thinking)
|
|
17529
|
+
* - 'boolean': booleans (deepseek-r1, qwq, qwen3: true, false)
|
|
17530
|
+
* - 'none': declared [false], declared nothing, or unknown
|
|
17435
17531
|
*/
|
|
17436
|
-
function thinkingModeForModel(modelId) {
|
|
17532
|
+
function thinkingModeForModel(modelId, declared) {
|
|
17533
|
+
if (declared !== void 0) {
|
|
17534
|
+
if (declared.values.some((value) => typeof value === "string")) return "levels";
|
|
17535
|
+
return declared.values.includes(true) ? "boolean" : "none";
|
|
17536
|
+
}
|
|
17437
17537
|
if (!supportsOllamaThinkingControl(modelId, "native", "api-key")) return "none";
|
|
17438
17538
|
const base = modelId.toLowerCase().split(":")[0] ?? "";
|
|
17439
17539
|
if (base === "gpt-oss") return "levels";
|
|
@@ -17441,18 +17541,80 @@ function thinkingModeForModel(modelId) {
|
|
|
17441
17541
|
return "none";
|
|
17442
17542
|
}
|
|
17443
17543
|
/**
|
|
17544
|
+
* The efforts one model can actually be sent, in display order.
|
|
17545
|
+
*
|
|
17546
|
+
* This set is the whole contract with the harness: a level outside it is
|
|
17547
|
+
* rejected before a request is built (see `resolveCallWithInfo`), so it must be
|
|
17548
|
+
* exactly what the wire accepts and no more - which is why, when the model has
|
|
17549
|
+
* declared its own values, this returns that table row for row instead of
|
|
17550
|
+
* choosing from a fixed menu. A model that declares `[false]` is the one case
|
|
17551
|
+
* with a declared value and no ladder at all: `[false]` is the service saying
|
|
17552
|
+
* there is no thinking here to turn on or off.
|
|
17553
|
+
*
|
|
17554
|
+
* Without metadata the families this file knows answer instead, unchanged:
|
|
17555
|
+
* gpt-oss takes the three levels, and a boolean family takes the on/off pair.
|
|
17556
|
+
*/
|
|
17557
|
+
function reasoningEffortsForModel(modelId, declared) {
|
|
17558
|
+
if (declared !== void 0) {
|
|
17559
|
+
if (thinkingModeForModel(modelId, declared) === "none") return [];
|
|
17560
|
+
return declaredEfforts(declared).map(({ id, name }) => ({
|
|
17561
|
+
id,
|
|
17562
|
+
name
|
|
17563
|
+
}));
|
|
17564
|
+
}
|
|
17565
|
+
const mode = thinkingModeForModel(modelId);
|
|
17566
|
+
if (mode === "none") return [];
|
|
17567
|
+
if (mode === "boolean") return booleanEfforts();
|
|
17568
|
+
return [...DEFAULT_LEVEL_EFFORTS];
|
|
17569
|
+
}
|
|
17570
|
+
/**
|
|
17571
|
+
* The effort this model's ladder should start on.
|
|
17572
|
+
*
|
|
17573
|
+
* A stored default is a per-route preference, not a per-model promise: the
|
|
17574
|
+
* settings card offers one ladder for the whole line, so a level chosen for one
|
|
17575
|
+
* model can be one this model cannot express - and DSH rejects a level that is
|
|
17576
|
+
* not on the ladder before a request is built. So the order is: the configured
|
|
17577
|
+
* level when this model has it, then the level the model itself defaults to,
|
|
17578
|
+
* then the ladder's own first entry.
|
|
17579
|
+
*
|
|
17580
|
+
* The last step skips a "thinking off" position. A user who picked a thinking
|
|
17581
|
+
* model and was handed that position would silently get a model that never
|
|
17582
|
+
* thinks, which is a worse wrong answer than the mildest level that does think.
|
|
17583
|
+
*/
|
|
17584
|
+
function resolveOllamaDefaultEffort(modelId, declared, configured) {
|
|
17585
|
+
const efforts = reasoningEffortsForModel(modelId, declared);
|
|
17586
|
+
if (efforts.length === 0) return void 0;
|
|
17587
|
+
if (typeof configured === "string" && efforts.some((effort) => effort.id === configured)) return configured;
|
|
17588
|
+
if (declared?.default !== void 0) {
|
|
17589
|
+
const wanted = declared.default;
|
|
17590
|
+
const match = efforts.find((effort) => thinkForModel(modelId, effort.id, declared) === wanted);
|
|
17591
|
+
if (match !== void 0) return match.id;
|
|
17592
|
+
}
|
|
17593
|
+
return efforts.find((effort) => effort.id !== "none")?.id ?? efforts[0]?.id;
|
|
17594
|
+
}
|
|
17595
|
+
/**
|
|
17444
17596
|
* Map reasoning effort to wire think parameter for the target model.
|
|
17445
17597
|
* Per Ollama docs:
|
|
17446
|
-
* -
|
|
17447
|
-
*
|
|
17598
|
+
* - a model that has declared its own values: the effort reverses to the one
|
|
17599
|
+
* value that model declared for it, and nothing else is sent. A level the
|
|
17600
|
+
* model never declared is omitted rather than coerced - a model that declares
|
|
17601
|
+
* `[true]` is never asked for `false`, and one that declares ['low','high'] is
|
|
17602
|
+
* never handed 'medium'. Omitting is the service's own default, which is a
|
|
17603
|
+
* weaker turn and never a failed one.
|
|
17604
|
+
* - gpt-oss with no metadata: only 'low' | 'medium' | 'high' are valid. gpt-oss cannot disable
|
|
17605
|
+
* thinking, so 'none' as well as 'xhigh'/'max'/garbage MUST be omitted (undefined).
|
|
17448
17606
|
* - boolean models: 'none' -> false; 'low'|'medium'|'high'|'auto'|'true' -> true; garbage -> undefined.
|
|
17449
17607
|
* - all other models: omit (undefined).
|
|
17450
17608
|
*/
|
|
17451
|
-
function thinkForModel(modelId, reasoningEffort) {
|
|
17609
|
+
function thinkForModel(modelId, reasoningEffort, declared) {
|
|
17452
17610
|
if (reasoningEffort === void 0 || reasoningEffort === null) return void 0;
|
|
17611
|
+
const effort = String(reasoningEffort).toLowerCase();
|
|
17612
|
+
if (declared !== void 0) {
|
|
17613
|
+
for (const entry of declaredEfforts(declared)) if (entry.id.toLowerCase() === effort) return entry.value;
|
|
17614
|
+
return;
|
|
17615
|
+
}
|
|
17453
17616
|
const mode = thinkingModeForModel(modelId);
|
|
17454
17617
|
if (mode === "none") return void 0;
|
|
17455
|
-
const effort = String(reasoningEffort).toLowerCase();
|
|
17456
17618
|
if (mode === "boolean") {
|
|
17457
17619
|
if (effort === "none") return false;
|
|
17458
17620
|
if (effort === "low" || effort === "medium" || effort === "high" || effort === "auto" || effort === "true") return true;
|
|
@@ -18130,6 +18292,55 @@ async function fetchCatalog$1(fetchFn, credentials) {
|
|
|
18130
18292
|
}
|
|
18131
18293
|
return { models: result };
|
|
18132
18294
|
}
|
|
18295
|
+
/**
|
|
18296
|
+
* Read what one model says about its own thinking.
|
|
18297
|
+
*
|
|
18298
|
+
* `POST /api/show` is the only place a model states the values `think` accepts,
|
|
18299
|
+
* and the ladder this line offers has to be exactly those values: DSH rejects an
|
|
18300
|
+
* effort that is not on the ladder before a request is built, and the service
|
|
18301
|
+
* rejects a `think` it does not know. So the metadata, not a prefix list, is
|
|
18302
|
+
* what the picker is built from.
|
|
18303
|
+
*
|
|
18304
|
+
* Returns undefined rather than throwing for every way this can fail - no key, a
|
|
18305
|
+
* 401, a 500, a proxy's HTML where JSON was promised, a document that is not
|
|
18306
|
+
* `/api/show`. The caller falls back to what it already knew about the model,
|
|
18307
|
+
* and a failed probe must never be what breaks a turn.
|
|
18308
|
+
*/
|
|
18309
|
+
async function fetchModelThinking(fetchFn, credentials, modelId) {
|
|
18310
|
+
let response;
|
|
18311
|
+
try {
|
|
18312
|
+
response = await fetchFn(`${CLOUD_BASE_URL}${NATIVE_SHOW_PATH}`, {
|
|
18313
|
+
method: "POST",
|
|
18314
|
+
headers: headersFor(credentials, "application/json"),
|
|
18315
|
+
body: JSON.stringify({ model: modelId }),
|
|
18316
|
+
signal: AbortSignal.timeout(CATALOG_TIMEOUT_MS)
|
|
18317
|
+
});
|
|
18318
|
+
} catch {
|
|
18319
|
+
return;
|
|
18320
|
+
}
|
|
18321
|
+
if (!response.ok) return void 0;
|
|
18322
|
+
let data;
|
|
18323
|
+
try {
|
|
18324
|
+
data = await response.json();
|
|
18325
|
+
} catch {
|
|
18326
|
+
return;
|
|
18327
|
+
}
|
|
18328
|
+
if (typeof data !== "object" || data === null || Array.isArray(data)) return void 0;
|
|
18329
|
+
const thinking = data.thinking;
|
|
18330
|
+
if (typeof thinking !== "object" || thinking === null || Array.isArray(thinking)) return void 0;
|
|
18331
|
+
const record = thinking;
|
|
18332
|
+
if (!Array.isArray(record.values)) return void 0;
|
|
18333
|
+
const values = [];
|
|
18334
|
+
for (const value of record.values) if (typeof value === "boolean") values.push(value);
|
|
18335
|
+
else if (typeof value === "string" && value !== "") values.push(value);
|
|
18336
|
+
if (values.length === 0) return void 0;
|
|
18337
|
+
const fallback = record.default;
|
|
18338
|
+
const declaredDefault = typeof fallback === "boolean" || typeof fallback === "string" ? fallback : void 0;
|
|
18339
|
+
return {
|
|
18340
|
+
values,
|
|
18341
|
+
...declaredDefault === void 0 ? {} : { default: declaredDefault }
|
|
18342
|
+
};
|
|
18343
|
+
}
|
|
18133
18344
|
//#endregion
|
|
18134
18345
|
//#region src/host/ollama/mapper.ts
|
|
18135
18346
|
function createStreamState$6() {
|
|
@@ -18342,6 +18553,16 @@ var OllamaAdapter = class extends LlmAdapter {
|
|
|
18342
18553
|
* than minting pool state that would outlive the process.
|
|
18343
18554
|
*/
|
|
18344
18555
|
accountPool;
|
|
18556
|
+
/**
|
|
18557
|
+
* What `/api/show` has already said, per model id.
|
|
18558
|
+
*
|
|
18559
|
+
* Only a successful read is remembered. A failed one is a transient condition
|
|
18560
|
+
* (no key, a 500, a proxy), and caching it would pin every model to the
|
|
18561
|
+
* fallback ladder for the life of the process - so it is asked again next time.
|
|
18562
|
+
*/
|
|
18563
|
+
thinkingCache = /* @__PURE__ */ new Map();
|
|
18564
|
+
/** Probes currently in flight, so one model asked twice at once is read once. */
|
|
18565
|
+
thinkingProbes = /* @__PURE__ */ new Map();
|
|
18345
18566
|
constructor(store = new FileCredentialStore$5(), modelSettings = new FileModelSettingsStore$5(), options = {}, accountPool) {
|
|
18346
18567
|
super();
|
|
18347
18568
|
this.store = store;
|
|
@@ -18390,6 +18611,34 @@ var OllamaAdapter = class extends LlmAdapter {
|
|
|
18390
18611
|
if (this.accountPool !== null) return (await this.accountPool.getEffectiveCredential(/* @__PURE__ */ new Set(), this.options.fetchFn ?? fetch).catch(() => null))?.credentials ?? null;
|
|
18391
18612
|
return this.store.read().catch(() => null);
|
|
18392
18613
|
}
|
|
18614
|
+
/**
|
|
18615
|
+
* What this model says about its own thinking, read once and remembered.
|
|
18616
|
+
*
|
|
18617
|
+
* Never throws and never rejects: an adapter that cannot reach `/api/show`
|
|
18618
|
+
* (no key stored yet, service down) is a line that still resolves models and
|
|
18619
|
+
* still chats, one step behind on the ladder.
|
|
18620
|
+
*/
|
|
18621
|
+
async thinkingCapability(modelId) {
|
|
18622
|
+
const cached = this.thinkingCache.get(modelId);
|
|
18623
|
+
if (cached !== void 0) return cached;
|
|
18624
|
+
const inflight = this.thinkingProbes.get(modelId);
|
|
18625
|
+
if (inflight !== void 0) return await inflight;
|
|
18626
|
+
const tracked = (async () => {
|
|
18627
|
+
try {
|
|
18628
|
+
const credentials = await this.anyCredentials();
|
|
18629
|
+
if (credentials === null) return void 0;
|
|
18630
|
+
const declared = await fetchModelThinking(this.options.fetchFn ?? fetch, credentials, modelId);
|
|
18631
|
+
if (declared !== void 0) this.thinkingCache.set(modelId, declared);
|
|
18632
|
+
return declared;
|
|
18633
|
+
} catch {
|
|
18634
|
+
return;
|
|
18635
|
+
}
|
|
18636
|
+
})().finally(() => {
|
|
18637
|
+
this.thinkingProbes.delete(modelId);
|
|
18638
|
+
});
|
|
18639
|
+
this.thinkingProbes.set(modelId, tracked);
|
|
18640
|
+
return await tracked;
|
|
18641
|
+
}
|
|
18393
18642
|
async listModels(provider) {
|
|
18394
18643
|
const prov = provider || "ollama";
|
|
18395
18644
|
const settings = await this.settings();
|
|
@@ -18405,14 +18654,25 @@ var OllamaAdapter = class extends LlmAdapter {
|
|
|
18405
18654
|
}
|
|
18406
18655
|
async resolveModel(provider, modelId, signal) {
|
|
18407
18656
|
if (signal?.aborted) throw new LlmError("Ollama model resolution aborted", "ABORTED");
|
|
18657
|
+
const settings = await this.settings();
|
|
18408
18658
|
const entry = (await this.catalog()).find((model) => model.id === modelId);
|
|
18659
|
+
const declared = signal?.aborted ? void 0 : await this.thinkingCapability(modelId);
|
|
18660
|
+
const efforts = reasoningEffortsForModel(modelId, declared);
|
|
18661
|
+
const defaultEffort = resolveOllamaDefaultEffort(modelId, declared, settings.defaultReasoningEffort);
|
|
18409
18662
|
return {
|
|
18410
18663
|
provider,
|
|
18411
18664
|
id: modelId,
|
|
18412
18665
|
name: entry?.name ?? modelId,
|
|
18413
18666
|
inputModalities: ollamaModelSupportsImage(modelId) ? ["text", "image"] : ["text"],
|
|
18414
18667
|
context: { contextWindow: contextWindowFor(entry) },
|
|
18415
|
-
...outputReservation(contextWindowFor(entry), DEFAULT_MAX_OUTPUT_TOKENS)
|
|
18668
|
+
...outputReservation(contextWindowFor(entry), DEFAULT_MAX_OUTPUT_TOKENS),
|
|
18669
|
+
...efforts.length === 0 ? {} : { reasoning: {
|
|
18670
|
+
efforts: efforts.map((effort) => ({
|
|
18671
|
+
id: ReasoningEffortId(effort.id),
|
|
18672
|
+
name: effort.name
|
|
18673
|
+
})),
|
|
18674
|
+
...defaultEffort === void 0 ? {} : { defaultEffort: ReasoningEffortId(defaultEffort) }
|
|
18675
|
+
} }
|
|
18416
18676
|
};
|
|
18417
18677
|
}
|
|
18418
18678
|
async prepareCall(provider, model, signal) {
|
|
@@ -18428,7 +18688,13 @@ var OllamaAdapter = class extends LlmAdapter {
|
|
|
18428
18688
|
const fetchFn = this.options.fetchFn ?? fetch;
|
|
18429
18689
|
const options = normalizeGenerateOptions(rawOptions);
|
|
18430
18690
|
const wire = wireForModel$1(options.model);
|
|
18431
|
-
const
|
|
18691
|
+
const configured = (await this.settings()).defaultReasoningEffort;
|
|
18692
|
+
const effort = options.reasoningEffort ?? configured ?? void 0;
|
|
18693
|
+
const declared = effort === void 0 && options.maxTokens === void 0 ? void 0 : await this.thinkingCapability(options.model);
|
|
18694
|
+
const request = await toOllamaRequest(effort === void 0 || effort === null ? options : {
|
|
18695
|
+
...options,
|
|
18696
|
+
reasoningEffort: ReasoningEffortId(String(effort))
|
|
18697
|
+
}, this.options.attachments, signal, declared);
|
|
18432
18698
|
const pool = this.accountPool;
|
|
18433
18699
|
const tried = /* @__PURE__ */ new Set();
|
|
18434
18700
|
let lastStatus;
|
|
@@ -18687,7 +18953,7 @@ async function processMessageContent(content, model, attachments, signal) {
|
|
|
18687
18953
|
* Project DSH's request shape onto Ollama's, per surface.
|
|
18688
18954
|
* Consumes the canonical Message vocabulary produced by normalizeGenerateOptions.
|
|
18689
18955
|
*/
|
|
18690
|
-
async function toOllamaRequest(options, attachments, signal) {
|
|
18956
|
+
async function toOllamaRequest(options, attachments, signal, declared) {
|
|
18691
18957
|
if (signal?.aborted) throw abortException(signal);
|
|
18692
18958
|
const messages = [];
|
|
18693
18959
|
const trimmedSystem = typeof options.system === "string" && options.system.trim() !== "" ? options.system.trim() : void 0;
|
|
@@ -18751,10 +19017,10 @@ async function toOllamaRequest(options, attachments, signal) {
|
|
|
18751
19017
|
model: options.model,
|
|
18752
19018
|
messages
|
|
18753
19019
|
};
|
|
18754
|
-
const flooredMax = floorForcedThinkingTokens$1(options.model, options.maxTokens);
|
|
19020
|
+
const flooredMax = floorForcedThinkingTokens$1(options.model, options.maxTokens, declared);
|
|
18755
19021
|
if (flooredMax !== void 0) request.maxOutputTokens = flooredMax;
|
|
18756
19022
|
if (options.temperature !== void 0) request.temperature = options.temperature;
|
|
18757
|
-
const think = thinkForModel(options.model, options.reasoningEffort);
|
|
19023
|
+
const think = thinkForModel(options.model, options.reasoningEffort, declared);
|
|
18758
19024
|
if (think !== void 0) request.think = think;
|
|
18759
19025
|
const tools = options.tools;
|
|
18760
19026
|
if (Array.isArray(tools) && tools.length > 0) request.tools = tools.map((tool) => ({
|
|
@@ -18816,10 +19082,51 @@ function textOf$7(content) {
|
|
|
18816
19082
|
return "";
|
|
18817
19083
|
}
|
|
18818
19084
|
//#endregion
|
|
19085
|
+
//#region src/shared/ollama-contracts.ts
|
|
19086
|
+
/**
|
|
19087
|
+
* The thinking levels this line's card offers.
|
|
19088
|
+
*
|
|
19089
|
+
* Deliberately narrower than the union of what every model accepts. Ollama's
|
|
19090
|
+
* thinking control comes in three shapes (see {@link thinkingModeForModel} in
|
|
19091
|
+
* src/host/ollama/types.ts): gpt-oss takes low/medium/high, the boolean models
|
|
19092
|
+
* (deepseek-r1, qwq, qwen3) take only on/off, and every other model takes no
|
|
19093
|
+
* thinking control at all. These four strings are the vocabulary both shapes can
|
|
19094
|
+
* be expressed with, so one dropdown covers the whole line.
|
|
19095
|
+
*
|
|
19096
|
+
* Whether a given model can actually honour a level is decided by the host, not
|
|
19097
|
+
* by this list: {@link thinkForModel} in src/host/ollama/types.ts drops what a
|
|
19098
|
+
* model cannot express, so picking 'high' is safe for a user whose catalog holds
|
|
19099
|
+
* a mixture of families.
|
|
19100
|
+
*/
|
|
19101
|
+
const OLLAMA_REASONING_EFFORTS = [
|
|
19102
|
+
"none",
|
|
19103
|
+
"low",
|
|
19104
|
+
"medium",
|
|
19105
|
+
"high"
|
|
19106
|
+
];
|
|
19107
|
+
/**
|
|
19108
|
+
* Whether a submitted value names a level this line accepts.
|
|
19109
|
+
*
|
|
19110
|
+
* The route uses this to refuse an unknown level outright. Storing one anyway
|
|
19111
|
+
* would be silently useless: {@link thinkForModel} drops a level a model cannot
|
|
19112
|
+
* express, so the card would keep showing a choice that does nothing at all.
|
|
19113
|
+
*/
|
|
19114
|
+
function isOllamaReasoningEffort(value) {
|
|
19115
|
+
return typeof value === "string" && OLLAMA_REASONING_EFFORTS.includes(value);
|
|
19116
|
+
}
|
|
19117
|
+
//#endregion
|
|
18819
19118
|
//#region src/host/ollama/routes.ts
|
|
18820
19119
|
const ROUTE_PREFIX$3 = "/ollama/api";
|
|
18821
19120
|
/** Where a user creates the keys this line stores. */
|
|
18822
19121
|
const OLLAMA_KEYS_URL = "https://ollama.com/settings/keys";
|
|
19122
|
+
/**
|
|
19123
|
+
* The one sentence every refused thinking level answers with.
|
|
19124
|
+
*
|
|
19125
|
+
* Names the accepted values because the card sends its own dropdown values, so a
|
|
19126
|
+
* rejected body is a stale card talking to a newer line (or the reverse), and
|
|
19127
|
+
* the fix is on whichever side moved.
|
|
19128
|
+
*/
|
|
19129
|
+
const UNSUPPORTED_EFFORT_ERROR = "Unsupported reasoning effort. Expected null, or one of: none, low, medium, high.";
|
|
18823
19130
|
function sendJson$7(response, status, body) {
|
|
18824
19131
|
const payload = JSON.stringify(body);
|
|
18825
19132
|
response.writeHead(status, { "content-type": "application/json; charset=utf-8" });
|
|
@@ -18892,7 +19199,8 @@ async function getOllamaWebStatus(options) {
|
|
|
18892
19199
|
})),
|
|
18893
19200
|
enabledModelIds: settings.enabledModelIds,
|
|
18894
19201
|
usable: accounts.some((account) => isUsable(account, now)),
|
|
18895
|
-
catalogSynced: settings.catalogModels.length > 0
|
|
19202
|
+
catalogSynced: settings.catalogModels.length > 0,
|
|
19203
|
+
defaultReasoningEffort: settings.defaultReasoningEffort ?? null
|
|
18896
19204
|
};
|
|
18897
19205
|
}
|
|
18898
19206
|
/**
|
|
@@ -18923,10 +19231,25 @@ function registerOllamaRoutes(ctx, options) {
|
|
|
18923
19231
|
error: "Cross-origin request rejected."
|
|
18924
19232
|
});
|
|
18925
19233
|
const body = await readRequestJson$7(request).catch(() => ({}));
|
|
19234
|
+
let effort;
|
|
19235
|
+
if (body.defaultReasoningEffort !== void 0) {
|
|
19236
|
+
const submitted = body.defaultReasoningEffort;
|
|
19237
|
+
if (submitted !== null && !isOllamaReasoningEffort(submitted)) return sendJson$7(response, 400, {
|
|
19238
|
+
ok: false,
|
|
19239
|
+
error: UNSUPPORTED_EFFORT_ERROR
|
|
19240
|
+
});
|
|
19241
|
+
effort = submitted;
|
|
19242
|
+
}
|
|
19243
|
+
let touched = false;
|
|
18926
19244
|
if (typeof body.enabled === "boolean") {
|
|
18927
19245
|
await modelSettings.update({ enabled: body.enabled });
|
|
18928
|
-
|
|
19246
|
+
touched = true;
|
|
19247
|
+
}
|
|
19248
|
+
if (effort !== void 0) {
|
|
19249
|
+
await modelSettings.update({ defaultReasoningEffort: effort });
|
|
19250
|
+
touched = true;
|
|
18929
19251
|
}
|
|
19252
|
+
if (touched) ctx.emit?.("llm/adapters-updated");
|
|
18930
19253
|
return sendJson$7(response, 200, {
|
|
18931
19254
|
ok: true,
|
|
18932
19255
|
value: await modelSettings.read()
|
|
@@ -19009,6 +19332,15 @@ function registerOllamaRoutes(ctx, options) {
|
|
|
19009
19332
|
error: "Cross-origin request rejected."
|
|
19010
19333
|
});
|
|
19011
19334
|
const body = await readRequestJson$7(request).catch(() => ({}));
|
|
19335
|
+
let effort;
|
|
19336
|
+
if (body.defaultReasoningEffort !== void 0) {
|
|
19337
|
+
const submitted = body.defaultReasoningEffort;
|
|
19338
|
+
if (submitted !== null && !isOllamaReasoningEffort(submitted)) return sendJson$7(response, 400, {
|
|
19339
|
+
ok: false,
|
|
19340
|
+
error: UNSUPPORTED_EFFORT_ERROR
|
|
19341
|
+
});
|
|
19342
|
+
effort = submitted;
|
|
19343
|
+
}
|
|
19012
19344
|
let touched = false;
|
|
19013
19345
|
if (typeof body.enabled === "boolean") {
|
|
19014
19346
|
await modelSettings.update({ enabled: body.enabled });
|
|
@@ -19018,6 +19350,10 @@ function registerOllamaRoutes(ctx, options) {
|
|
|
19018
19350
|
await modelSettings.update({ enabledModelIds: Array.isArray(body.enabledModelIds) ? body.enabledModelIds.filter((id) => typeof id === "string") : null });
|
|
19019
19351
|
touched = true;
|
|
19020
19352
|
}
|
|
19353
|
+
if (effort !== void 0) {
|
|
19354
|
+
await modelSettings.update({ defaultReasoningEffort: effort });
|
|
19355
|
+
touched = true;
|
|
19356
|
+
}
|
|
19021
19357
|
if (touched) ctx.emit?.("llm/adapters-updated");
|
|
19022
19358
|
return sendJson$7(response, 200, {
|
|
19023
19359
|
ok: true,
|
|
@@ -20480,7 +20816,7 @@ async function kimiIdentityHeaders(extra = {}) {
|
|
|
20480
20816
|
* `AbortSignal.any` keeps whichever fires first, so an abandoned login stops
|
|
20481
20817
|
* promptly while a hung endpoint still cannot hold the request forever.
|
|
20482
20818
|
*/
|
|
20483
|
-
function withTimeout$
|
|
20819
|
+
function withTimeout$7(signal, ms) {
|
|
20484
20820
|
const timeout = AbortSignal.timeout(ms);
|
|
20485
20821
|
return signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
|
|
20486
20822
|
}
|
|
@@ -20524,7 +20860,7 @@ async function requestDeviceAuthorization(options = {}) {
|
|
|
20524
20860
|
accept: "application/json"
|
|
20525
20861
|
}),
|
|
20526
20862
|
body: new URLSearchParams$1({ client_id: KIMI_CODE_CLIENT_ID }).toString(),
|
|
20527
|
-
signal: withTimeout$
|
|
20863
|
+
signal: withTimeout$7(options.signal, OAUTH_TIMEOUT_MS$2)
|
|
20528
20864
|
});
|
|
20529
20865
|
const payload = await response.json().catch(() => void 0);
|
|
20530
20866
|
if (!response.ok) {
|
|
@@ -20570,7 +20906,7 @@ async function pollDeviceToken$1(host, deviceCode, options) {
|
|
|
20570
20906
|
device_code: deviceCode,
|
|
20571
20907
|
grant_type: DEVICE_CODE_GRANT_TYPE$1
|
|
20572
20908
|
}).toString(),
|
|
20573
|
-
signal: withTimeout$
|
|
20909
|
+
signal: withTimeout$7(options.signal, OAUTH_TIMEOUT_MS$2)
|
|
20574
20910
|
});
|
|
20575
20911
|
const payload = await response.json().catch(() => void 0);
|
|
20576
20912
|
const record = asRecord$13(payload) ?? {};
|
|
@@ -20694,7 +21030,7 @@ async function refreshAccessToken$1(refreshToken, options = {}) {
|
|
|
20694
21030
|
grant_type: "refresh_token",
|
|
20695
21031
|
refresh_token: refreshToken
|
|
20696
21032
|
}).toString(),
|
|
20697
|
-
signal: withTimeout$
|
|
21033
|
+
signal: withTimeout$7(options.signal, OAUTH_TIMEOUT_MS$2)
|
|
20698
21034
|
});
|
|
20699
21035
|
const payload = await response.json().catch(() => void 0);
|
|
20700
21036
|
const { code, description } = oauthErrorFields$2(payload);
|
|
@@ -27967,7 +28303,7 @@ const OAUTH_HEADERS = {
|
|
|
27967
28303
|
accept: "application/json",
|
|
27968
28304
|
"content-type": "application/x-www-form-urlencoded"
|
|
27969
28305
|
};
|
|
27970
|
-
function withTimeout$
|
|
28306
|
+
function withTimeout$6(signal, ms) {
|
|
27971
28307
|
const timeout = AbortSignal.timeout(ms);
|
|
27972
28308
|
return signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
|
|
27973
28309
|
}
|
|
@@ -28035,7 +28371,7 @@ async function requestDeviceAuthorization$1(options = {}) {
|
|
|
28035
28371
|
code_challenge: pkce.challenge,
|
|
28036
28372
|
code_challenge_method: PKCE_CHALLENGE_METHOD
|
|
28037
28373
|
}).toString(),
|
|
28038
|
-
signal: withTimeout$
|
|
28374
|
+
signal: withTimeout$6(options.signal, OAUTH_TIMEOUT_MS$1)
|
|
28039
28375
|
});
|
|
28040
28376
|
const payload = await response.json().catch(() => void 0);
|
|
28041
28377
|
if (!response.ok) {
|
|
@@ -28093,7 +28429,7 @@ async function pollDeviceToken(authorization, options = {}) {
|
|
|
28093
28429
|
code_verifier: authorization.codeVerifier,
|
|
28094
28430
|
grant_type: DEVICE_CODE_GRANT_TYPE
|
|
28095
28431
|
}).toString(),
|
|
28096
|
-
signal: withTimeout$
|
|
28432
|
+
signal: withTimeout$6(options.signal, OAUTH_TIMEOUT_MS$1)
|
|
28097
28433
|
});
|
|
28098
28434
|
const payload = await response.json().catch(() => void 0);
|
|
28099
28435
|
const record = asRecord$11(payload) ?? {};
|
|
@@ -28155,7 +28491,7 @@ async function refreshAccessToken$2(refreshToken, options) {
|
|
|
28155
28491
|
scope: MINIMAX_CODE_SCOPE,
|
|
28156
28492
|
audience: MINIMAX_CODE_AUDIENCE
|
|
28157
28493
|
}).toString(),
|
|
28158
|
-
signal: withTimeout$
|
|
28494
|
+
signal: withTimeout$6(options.signal, OAUTH_TIMEOUT_MS$1)
|
|
28159
28495
|
});
|
|
28160
28496
|
const payload = await response.json().catch(() => void 0);
|
|
28161
28497
|
const { code, description } = oauthErrorFields$1(payload);
|
|
@@ -28188,7 +28524,7 @@ async function revokeToken(token, options) {
|
|
|
28188
28524
|
token,
|
|
28189
28525
|
token_type_hint: "refresh_token"
|
|
28190
28526
|
}).toString(),
|
|
28191
|
-
signal: withTimeout$
|
|
28527
|
+
signal: withTimeout$6(options.signal, OAUTH_TIMEOUT_MS$1)
|
|
28192
28528
|
})).ok;
|
|
28193
28529
|
} catch {
|
|
28194
28530
|
return false;
|
|
@@ -28460,7 +28796,7 @@ async function pollWebLogin(store, loginId, options = {}) {
|
|
|
28460
28796
|
*/
|
|
28461
28797
|
/** Timeout for the connection probe and any other one-shot call. */
|
|
28462
28798
|
const PROBE_TIMEOUT_MS = 3e4;
|
|
28463
|
-
function withTimeout$
|
|
28799
|
+
function withTimeout$5(signal, ms) {
|
|
28464
28800
|
const timeout = AbortSignal.timeout(ms);
|
|
28465
28801
|
return signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
|
|
28466
28802
|
}
|
|
@@ -28570,7 +28906,7 @@ async function testConnection(store, options = {}) {
|
|
|
28570
28906
|
content: "ping"
|
|
28571
28907
|
}]
|
|
28572
28908
|
}),
|
|
28573
|
-
signal: withTimeout$
|
|
28909
|
+
signal: withTimeout$5(options.signal, PROBE_TIMEOUT_MS)
|
|
28574
28910
|
});
|
|
28575
28911
|
const latencyMs = Date.now() - startedAt;
|
|
28576
28912
|
if (!response.ok) {
|
|
@@ -28635,7 +28971,7 @@ async function createMessage(store, request, options = {}) {
|
|
|
28635
28971
|
content: request.prompt
|
|
28636
28972
|
}]
|
|
28637
28973
|
}),
|
|
28638
|
-
signal: withTimeout$
|
|
28974
|
+
signal: withTimeout$5(options.signal, PROBE_TIMEOUT_MS)
|
|
28639
28975
|
});
|
|
28640
28976
|
const payload = await response.json().catch(() => void 0);
|
|
28641
28977
|
return {
|
|
@@ -28908,7 +29244,7 @@ async function fetchTokenPlanQuota(credentials, options = {}) {
|
|
|
28908
29244
|
const response = await fetchFn(tokenPlanRemainsUrl(host), {
|
|
28909
29245
|
method: "GET",
|
|
28910
29246
|
headers: quotaRequestHeaders(credentials.accessToken, remainsPath),
|
|
28911
|
-
signal: withTimeout$
|
|
29247
|
+
signal: withTimeout$5(options.signal, QUOTA_TIMEOUT_MS)
|
|
28912
29248
|
});
|
|
28913
29249
|
if (response.status === 401 || response.status === 403) {
|
|
28914
29250
|
if (await options.isCredentialStale?.() === true) return null;
|
|
@@ -30604,7 +30940,7 @@ function ms(value) {
|
|
|
30604
30940
|
function text$1(value) {
|
|
30605
30941
|
return typeof value === "string" && value !== "" ? value : void 0;
|
|
30606
30942
|
}
|
|
30607
|
-
function withTimeout$
|
|
30943
|
+
function withTimeout$4(signal, ms_) {
|
|
30608
30944
|
const timeout = AbortSignal.timeout(ms_);
|
|
30609
30945
|
return signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
|
|
30610
30946
|
}
|
|
@@ -30660,7 +30996,7 @@ async function resetCardCall(input) {
|
|
|
30660
30996
|
method: input.method,
|
|
30661
30997
|
headers: resetCardRequestHeaders(input.accessToken),
|
|
30662
30998
|
...input.body === void 0 ? {} : { body: input.body },
|
|
30663
|
-
signal: withTimeout$
|
|
30999
|
+
signal: withTimeout$4(input.signal, RESET_CARD_TIMEOUT_MS)
|
|
30664
31000
|
});
|
|
30665
31001
|
} catch (error) {
|
|
30666
31002
|
throw new MinimaxCodeResetCardError("reset-card call could not be reached: " + (error instanceof Error ? error.message : String(error)), null, null);
|
|
@@ -40597,7 +40933,7 @@ function oauthErrorFields(payload) {
|
|
|
40597
40933
|
* Whichever fires first wins, so an abandoned sign-in stops promptly while a
|
|
40598
40934
|
* hung endpoint still cannot hold the request open forever.
|
|
40599
40935
|
*/
|
|
40600
|
-
function withTimeout$
|
|
40936
|
+
function withTimeout$3(signal, ms) {
|
|
40601
40937
|
const timeout = AbortSignal.timeout(ms);
|
|
40602
40938
|
return signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
|
|
40603
40939
|
}
|
|
@@ -40739,7 +41075,7 @@ async function postTokenGrant(body, options, requireRefreshToken, secrets) {
|
|
|
40739
41075
|
accept: "application/json"
|
|
40740
41076
|
},
|
|
40741
41077
|
body: JSON.stringify(body),
|
|
40742
|
-
signal: withTimeout$
|
|
41078
|
+
signal: withTimeout$3(options.signal, OAUTH_TIMEOUT_MS)
|
|
40743
41079
|
});
|
|
40744
41080
|
} catch (error) {
|
|
40745
41081
|
throw new ClaudeRetryableError("Could not reach the Claude token endpoint.", error);
|
|
@@ -44605,10 +44941,6 @@ function cliPollUrl(flowId, env = process.env) {
|
|
|
44605
44941
|
function keyName(env = process.env) {
|
|
44606
44942
|
return textOverride$1(env, "DSH_GLM_KEY_NAME") || "dsh-glm-coding-plan";
|
|
44607
44943
|
}
|
|
44608
|
-
/** 签名层是否被显式打开;默认关闭(证据等级 C,见 `CLIENT_SIGNING_DEFAULT_ENABLED`)。 */
|
|
44609
|
-
function clientSigningEnabled(env = process.env) {
|
|
44610
|
-
return (env.DSH_GLM_CLIENT_SIGNING ?? "").trim() === "1";
|
|
44611
|
-
}
|
|
44612
44944
|
/** 认不出区域时的默认部署。国际区是本仓库的历史默认值(沿用 `9ad8a53` 的 `regionForBaseUrl`)。 */
|
|
44613
44945
|
const DEFAULT_REGION = "intl";
|
|
44614
44946
|
/** 把自由输入的区域名规整到本线路认识的部署;认不出来时返回 undefined。 */
|
|
@@ -46680,7 +47012,7 @@ function asRecord$5(value) {
|
|
|
46680
47012
|
function asString$6(value) {
|
|
46681
47013
|
return typeof value === "string" && value !== "" ? value : void 0;
|
|
46682
47014
|
}
|
|
46683
|
-
function withTimeout$
|
|
47015
|
+
function withTimeout$2(signal, ms) {
|
|
46684
47016
|
const timeout = AbortSignal.timeout(ms);
|
|
46685
47017
|
return signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
|
|
46686
47018
|
}
|
|
@@ -46754,7 +47086,7 @@ async function loginBizToken(accessToken, region, options = {}) {
|
|
|
46754
47086
|
"user-agent": USER_AGENT$1
|
|
46755
47087
|
},
|
|
46756
47088
|
body: JSON.stringify({ token: accessToken }),
|
|
46757
|
-
signal: withTimeout$
|
|
47089
|
+
signal: withTimeout$2(options.signal, options.timeoutMs ?? 2e4)
|
|
46758
47090
|
});
|
|
46759
47091
|
status = response.status;
|
|
46760
47092
|
ok = response.ok;
|
|
@@ -46809,7 +47141,7 @@ async function bizRequest(options) {
|
|
|
46809
47141
|
"user-agent": USER_AGENT$1
|
|
46810
47142
|
},
|
|
46811
47143
|
...options.body === void 0 ? {} : { body: JSON.stringify(options.body) },
|
|
46812
|
-
signal: withTimeout$
|
|
47144
|
+
signal: withTimeout$2(options.signal, options.timeoutMs ?? 2e4)
|
|
46813
47145
|
});
|
|
46814
47146
|
} catch (error) {
|
|
46815
47147
|
fail(options.region, options.action + " 请求失败:" + (error instanceof Error ? error.message : String(error)), error);
|
|
@@ -47028,7 +47360,7 @@ async function verifyCodingPlanKey(region, codingPlanKey, options = {}) {
|
|
|
47028
47360
|
accept: "application/json",
|
|
47029
47361
|
"user-agent": USER_AGENT$1
|
|
47030
47362
|
},
|
|
47031
|
-
signal: withTimeout$
|
|
47363
|
+
signal: withTimeout$2(options.signal, options.timeoutMs ?? 2e4)
|
|
47032
47364
|
});
|
|
47033
47365
|
} catch (error) {
|
|
47034
47366
|
fail(region, "配额验活请求失败:" + (error instanceof Error ? error.message : String(error)), error);
|
|
@@ -47160,7 +47492,7 @@ function asText$1(value) {
|
|
|
47160
47492
|
function clampPercent(value) {
|
|
47161
47493
|
return Math.max(0, Math.min(100, value));
|
|
47162
47494
|
}
|
|
47163
|
-
function withTimeout$
|
|
47495
|
+
function withTimeout$1(signal, ms) {
|
|
47164
47496
|
const timeout = AbortSignal.timeout(ms);
|
|
47165
47497
|
return signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
|
|
47166
47498
|
}
|
|
@@ -47269,7 +47601,7 @@ async function fetchCatalog(region, codingPlanKey, options = {}) {
|
|
|
47269
47601
|
const response = await fetchFn(url, {
|
|
47270
47602
|
method: "GET",
|
|
47271
47603
|
headers: glmOpenAiProbeHeaders(codingPlanKey),
|
|
47272
|
-
signal: withTimeout$
|
|
47604
|
+
signal: withTimeout$1(options.signal, options.timeoutMs ?? 2e4)
|
|
47273
47605
|
});
|
|
47274
47606
|
const text = await response.text().catch(() => "");
|
|
47275
47607
|
if (!response.ok) {
|
|
@@ -47509,7 +47841,7 @@ async function fetchSubscriptionPlan(region, codingPlanKey, options = {}) {
|
|
|
47509
47841
|
const response = await fetchFn(subscriptionUrl(region, options.env ?? process.env), {
|
|
47510
47842
|
method: "GET",
|
|
47511
47843
|
headers: quotaRequestHeaders$1(codingPlanKey),
|
|
47512
|
-
signal: withTimeout$
|
|
47844
|
+
signal: withTimeout$1(options.signal, options.timeoutMs ?? 2e4)
|
|
47513
47845
|
});
|
|
47514
47846
|
if (!response.ok) return null;
|
|
47515
47847
|
const payload = await response.json().catch(() => void 0);
|
|
@@ -47556,7 +47888,7 @@ async function fetchGlmQuota(region, codingPlanKey, options = {}) {
|
|
|
47556
47888
|
response = await fetchFn(quotaUrl(region, env), {
|
|
47557
47889
|
method: "GET",
|
|
47558
47890
|
headers: quotaRequestHeaders$1(codingPlanKey),
|
|
47559
|
-
signal: withTimeout$
|
|
47891
|
+
signal: withTimeout$1(options.signal, options.timeoutMs ?? 2e4)
|
|
47560
47892
|
});
|
|
47561
47893
|
} catch (error) {
|
|
47562
47894
|
return {
|
|
@@ -47593,7 +47925,7 @@ async function fetchGlmQuota(region, codingPlanKey, options = {}) {
|
|
|
47593
47925
|
});
|
|
47594
47926
|
if (snapshot === null) return {
|
|
47595
47927
|
snapshot: null,
|
|
47596
|
-
error: failure("
|
|
47928
|
+
error: failure("上游没有返回可显示的额度窗口。"),
|
|
47597
47929
|
fromCache: false
|
|
47598
47930
|
};
|
|
47599
47931
|
return {
|
|
@@ -47616,450 +47948,6 @@ async function fetchGlmQuota(region, codingPlanKey, options = {}) {
|
|
|
47616
47948
|
if (quotaInFlight$1.get(key) === request) quotaInFlight$1.delete(key);
|
|
47617
47949
|
}
|
|
47618
47950
|
}
|
|
47619
|
-
//#endregion
|
|
47620
|
-
//#region src/host/glm-coding-plan/signing.ts
|
|
47621
|
-
/**
|
|
47622
|
-
* GLM(ZCode 账号)线路的 Client Request Signing V4(计划 §6.1 的 `signing.ts`,工作包 W4)。
|
|
47623
|
-
*
|
|
47624
|
-
* ## 一句话说清它的地位:这一层**默认关闭**,而且它不进入默认路径
|
|
47625
|
-
*
|
|
47626
|
-
* 唯一有真实调用记录的实现(hj01857655/ZCode)做过 A/B 对照:**带签名与不带签名的响应
|
|
47627
|
-
* 归一化后完全一致**(都是 HTTP 429 / 业务码 1113「没有余额也没有可用的资源包」)。
|
|
47628
|
-
* 也就是说:
|
|
47629
|
-
*
|
|
47630
|
-
* - 没有人观察到服务端因为**缺**签名而拒绝请求;
|
|
47631
|
-
* - 也没有一份证据能证明带签名能换到额外额度(参考实现注释里说的「150% 额度 / 夜间免费
|
|
47632
|
-
* Flash」是它的**声称**,不是实测结论)。
|
|
47633
|
-
*
|
|
47634
|
-
* 按计划的证据分级(§2)这属于 **C 级 = 社区经验或架构推断,无实测**,实施规则是
|
|
47635
|
-
* 「**实现但默认不启用**,做对照实验」。所以:
|
|
47636
|
-
*
|
|
47637
|
-
* 1. `CLIENT_SIGNING_DEFAULT_ENABLED = false`(`types.ts`,冻结),本文件不重定义它;
|
|
47638
|
-
* 2. `buildSigningHeaders()` 是**唯一对外的签名入口**,它在门控关闭时返回空表并且
|
|
47639
|
-
* **一次网络请求都不发**——这是结构性保证,不是靠调用方自觉;
|
|
47640
|
-
* 3. 门控由 `types.ts` 的 `clientSigningEnabled(env)` 读 `DSH_GLM_CLIENT_SIGNING=1` 打开。
|
|
47641
|
-
*
|
|
47642
|
-
* 门控关掉之后,`applyGlmClientSigning()` 拿到一个空表,调用方的请求头**一个键都不会变**。
|
|
47643
|
-
*
|
|
47644
|
-
* ## 实现来源与许可
|
|
47645
|
-
*
|
|
47646
|
-
* 移植自 MIT 许可的现成实现(本身就是 DSH 插件里的 TS 文件,纯 `node:crypto` 零依赖):
|
|
47647
|
-
*
|
|
47648
|
-
* - 来源:<https://raw.githubusercontent.com/ShanWuYinShe/dsh-plugins/main/packages/dsh-any-connect/src/zcode-signer.ts>
|
|
47649
|
-
* (仓库 ShanWuYinShe/dsh-plugins,路径 `packages/dsh-any-connect/src/zcode-signer.ts`,219 行)
|
|
47650
|
-
* - 许可:**MIT**(计划 R7:只有 MIT 仓库可以复制代码;bacnh85/pi-extensions 与
|
|
47651
|
-
* TriDefender/zcode-api 的许可为 null,只读协议、照协议重写)
|
|
47652
|
-
* - 随附参考测试:同仓库 `test/zcode-signer.test.ts`
|
|
47653
|
-
*
|
|
47654
|
-
* 协议逐字要点(与上实现一致,本文件未改动算法):
|
|
47655
|
-
*
|
|
47656
|
-
* - 握手:`POST {握手 origin}/api/paas/c1f3a7e2/v2/client`,头 `Authorization: {apiKeyId}.{apiKeySecret}`
|
|
47657
|
-
* (**裸 Key,不加 Bearer**),体四字段 `{apiKey, nonce, sig, ts}`
|
|
47658
|
-
* - 密钥派生:HKDF-SHA256,`salt = 'WD_CLIENT_SIGN_KDF_SALT'`,`info = 'getSignKey_hmac'`(导出
|
|
47659
|
-
* HMAC 密钥)/ `'ed25519_priv'`(导出解私钥用的 AES-GCM 密钥),长度均为 32 字节
|
|
47660
|
-
* - HMAC 消息:`"get_sign_key\n{apiKeyId}\n{ts}\n{nonce}"`,**换行分隔**(空格分隔会被拒),
|
|
47661
|
-
* 结果 base64
|
|
47662
|
-
* - 响应 `data.privateCipher` → AES-256-GCM 解密,iv 取前 12 字节、tag 取末 16 字节、
|
|
47663
|
-
* AAD = apiKeyId;解密出的明文**又是 base64** 的 PKCS#8 Ed25519 私钥(双层编码)
|
|
47664
|
-
* - 业务签名消息:`"{apiKeyId}\n{ts}\n{clientVersion}\n{sessionId}\n{nonce}"`,Ed25519 签名后
|
|
47665
|
-
* **base64**(不是 hex)
|
|
47666
|
-
* - PoW:`sha256("{apiKeyId}\n{appId}\n{sessionId}\n{ts}")` 的 hex 取**前 32 字符**作 seed,
|
|
47667
|
-
* 在 `sha256("{seed}\n{nonce}{counter hex 8 位}")` 上找前导 0 位 >= 8 的解
|
|
47668
|
-
* - App id = `'zcode'`
|
|
47669
|
-
*
|
|
47670
|
-
* ## 相对参考实现改掉的三处(计划 R2 / 任务书,逐条对应)
|
|
47671
|
-
*
|
|
47672
|
-
* 1. **握手 origin 改成 `https://api.z.ai`。**
|
|
47673
|
-
* 参考实现硬编码 `open.bigmodel.cn`,但实测记录逐字写着「`/api/paas/*` 在 zcode.z.ai 上
|
|
47674
|
-
* 404,get_sign_key 端点回应在 api.z.ai 这个 origin」(计划 R2)。本线路默认用 api.z.ai,
|
|
47675
|
-
* 并按 `types.ts` 的覆盖写法接受 `DSH_GLM_SIGN_HANDSHAKE_BASE` /
|
|
47676
|
-
* `DSH_GLM_SIGN_HANDSHAKE_URL` 覆盖(读取发生在调用时,不是模块加载时)。
|
|
47677
|
-
* 2. **clientVersion 默认提到 `3.15.1`**(参考实现是 `3.4.0`)。这个值同时进签名串与
|
|
47678
|
-
* `X-Client-Version` / `X-ZCode-App-Version` / `User-Agent` 三个头,写错签名直接失效;
|
|
47679
|
-
* TriDefender 的测试注释称 3.15.1 起 `/api/v1/agent/configs` 这个 gate 已移除。
|
|
47680
|
-
* 默认值可被 `DSH_GLM_SIGN_CLIENT_VERSION` 覆盖。
|
|
47681
|
-
* 3. **不移植 gate 逻辑。** 第二参考实现(pi-extensions,许可 null,只读协议)里有
|
|
47682
|
-
* 「先探 `/api/v1/agent/configs` 决定要不要签名」的门控,本线路**不做这个探测**:
|
|
47683
|
-
* 计划已把门控收敛成「默认关闭 + `DSH_GLM_CLIENT_SIGNING` 显式打开」,
|
|
47684
|
-
* 多一次探测就多一个会失败的上游依赖。
|
|
47685
|
-
*
|
|
47686
|
-
* ## 另外三处刻意偏离参考实现(理由随代码给出)
|
|
47687
|
-
*
|
|
47688
|
-
* - **不发 `Authorization`。** 参考实现返回的表里带 `Authorization: Bearer {id}.{secret}`,
|
|
47689
|
-
* 但本线路模型面的认证头是 W5/W6 的活,且 Anthropic 面要求**双头**
|
|
47690
|
-
* (`x-api-key` + `Authorization: Bearer` 同值,计划 §3.3 逐字引用官方注释)。
|
|
47691
|
-
* 签名器若顺手覆盖 `Authorization`,会把装配层算好的认证头顶掉,所以这一行不归它。
|
|
47692
|
-
* - **默认不覆盖调用方的 `User-Agent`。** `types.ts` 的 `USER_AGENT` 明写「如实报成这个
|
|
47693
|
-
* 第三方插件,不冒充官方客户端」。`buildSigningHeaders()` 作为原样移植仍然返回
|
|
47694
|
-
* `ZCode/{version}`,但 `applyGlmClientSigning()` 默认保留调用方已有的 `User-Agent`,
|
|
47695
|
-
* 要替换得显式传 `overrideUserAgent: true`。签名层本身整层都是「假装成官方客户端」,
|
|
47696
|
-
* 这道默认值让「开签名」不必等于「改身份」。
|
|
47697
|
-
* - **成功码同时认 `0` 与 `200`。** 参考实现只认 `code === 200`;本线路业务面信封把两者都
|
|
47698
|
-
* 当成功(见 `exchange.ts` 的 `isBizSuccessCode`),握手面在同一个 origin 上,只认一个会
|
|
47699
|
-
* 凭空制造一次失败。
|
|
47700
|
-
*
|
|
47701
|
-
* ## 未验证(缺什么证据)
|
|
47702
|
-
*
|
|
47703
|
-
* - 握手路径里的 `c1f3a7e2` 是否会轮换(计划 §9 明确未验证第 2 条)。缺一份上游变更通告,
|
|
47704
|
-
* 所以路径做成常量 + URL 覆盖。
|
|
47705
|
-
* - 私钥是否长期稳定:没有任何证据说服务端会为同一把 Coding Plan Key 重新下发私钥,
|
|
47706
|
-
* 因此这里按「一把凭据一把私钥」缓存到进程结束,W6 换凭据时应调 `clearPrivateKey()`。
|
|
47707
|
-
* - 明文**直接是 DER**(不做 base64)的形状没有证据;这里按 ASN.1 首字节做一次形状判定,
|
|
47708
|
-
* 两种形状都能解开,但只有 base64 双层那一种是参考实现实测过的。
|
|
47709
|
-
* - `X-Title: 'Z Code@cli'` / `X-Release-Channel: 'stable'` / `X-ZCode-Agent: 'glm'` 三个头
|
|
47710
|
-
* 是否参与签名校验无从判断;它们原样保留参考实现的取值,未做删减实验。
|
|
47711
|
-
* - 服务端是否真的因缺签名返回 `VERIFY_SIGNATURE_INVALID`:**从未被观察到**(计划 §9 末条)。
|
|
47712
|
-
*/
|
|
47713
|
-
/** HKDF 的 salt,逐字来自参考实现的 `KDF_SALT`。 */
|
|
47714
|
-
const SIGNING_KDF_SALT = "WD_CLIENT_SIGN_KDF_SALT";
|
|
47715
|
-
/** 导出 HMAC 密钥的 HKDF info,逐字来自参考实现的 `INFO_HMAC`。 */
|
|
47716
|
-
const SIGNING_INFO_HMAC = "getSignKey_hmac";
|
|
47717
|
-
/** 导出「解私钥用的 AES-GCM 密钥」的 HKDF info,逐字来自参考实现的 `INFO_PRIV`。 */
|
|
47718
|
-
const SIGNING_INFO_PRIV = "ed25519_priv";
|
|
47719
|
-
/** HMAC 消息的第一行,逐字来自参考实现。**换行分隔**,空格分隔会被服务端拒。 */
|
|
47720
|
-
const SIGNING_HMAC_PREFIX = "get_sign_key";
|
|
47721
|
-
/** 握手路径(逐字来自参考实现)。**未验证**:`c1f3a7e2` 是否会轮换(计划 §9 第 2 条)。 */
|
|
47722
|
-
const SIGNING_HANDSHAKE_PATH = "/api/paas/c1f3a7e2/v2/client";
|
|
47723
|
-
/** PoW 计数器能取到的最大值(含):答案的末 8 位十六进制就是它。 */
|
|
47724
|
-
const POW_MAX_COUNTER = 4294967295;
|
|
47725
|
-
/** 一次握手请求体里的 nonce 字节数(12 字节 → 24 个十六进制字符)。 */
|
|
47726
|
-
const HANDSHAKE_NONCE_BYTES = 12;
|
|
47727
|
-
/** 一次业务请求头里的 nonce 字节数(16 字节 → 32 个十六进制字符)。 */
|
|
47728
|
-
const REQUEST_NONCE_BYTES = 16;
|
|
47729
|
-
/** 签名层的任何失败都抛这一类,调用方按「签名不可用」降级(关闭该功能,而不是让请求整体失败)。 */
|
|
47730
|
-
var GlmSigningError = class extends Error {
|
|
47731
|
-
constructor(message, options) {
|
|
47732
|
-
super(message, options === void 0 ? void 0 : { cause: options.cause });
|
|
47733
|
-
this.name = "GlmSigningError";
|
|
47734
|
-
}
|
|
47735
|
-
};
|
|
47736
|
-
/**
|
|
47737
|
-
* 拆 `{apiKeyId}.{apiKeySecret}`。
|
|
47738
|
-
*
|
|
47739
|
-
* 严格只允许**一个**点:secret 里再有点会被判为非法,而不是悄悄把后面的部分截掉——
|
|
47740
|
-
* 上游对畸形 Key 的处置是 401(`ERROR_CODE.AUTH_INVALID`),本地早失败比发一次注定失败的
|
|
47741
|
-
* 握手请求好。返回值里没有 secret 之外的东西,日志里不要打印它。
|
|
47742
|
-
*/
|
|
47743
|
-
function parseGlmCodingPlanApiKey(raw) {
|
|
47744
|
-
const trimmed = raw.trim();
|
|
47745
|
-
const dot = trimmed.indexOf(".");
|
|
47746
|
-
if (dot <= 0 || dot !== trimmed.lastIndexOf(".")) return void 0;
|
|
47747
|
-
const apiKeyId = trimmed.slice(0, dot).trim();
|
|
47748
|
-
const apiKeySecret = trimmed.slice(dot + 1).trim();
|
|
47749
|
-
if (apiKeyId === "" || apiKeySecret === "") return void 0;
|
|
47750
|
-
return {
|
|
47751
|
-
apiKeyId,
|
|
47752
|
-
apiKeySecret,
|
|
47753
|
-
credential: trimmed
|
|
47754
|
-
};
|
|
47755
|
-
}
|
|
47756
|
-
function requireApiKey(raw) {
|
|
47757
|
-
const parsed = parseGlmCodingPlanApiKey(raw);
|
|
47758
|
-
if (parsed === void 0) throw new GlmSigningError("Coding Plan Key 格式非法(应为 apiKeyId.apiKeySecret)");
|
|
47759
|
-
return parsed;
|
|
47760
|
-
}
|
|
47761
|
-
/**
|
|
47762
|
-
* 覆盖读取方式照抄 `types.ts` 末尾那两个函数:调用时读 `env`、空串视作未设置、host 值去掉尾部斜杠。
|
|
47763
|
-
*
|
|
47764
|
-
* 不复用 `types.ts` 的 `hostOverride` 是因为它是模块私有的;这里复制的是**写法**而不是常量,
|
|
47765
|
-
* 覆盖表本身是本文件独有的(见文件头「实现来源」一节)。
|
|
47766
|
-
*/
|
|
47767
|
-
function signHostOverride(env, name) {
|
|
47768
|
-
const value = (env[name] ?? "").trim();
|
|
47769
|
-
return value === "" ? "" : value.replace(/\/+$/, "");
|
|
47770
|
-
}
|
|
47771
|
-
function signTextOverride(env, name) {
|
|
47772
|
-
const value = (env[name] ?? "").trim();
|
|
47773
|
-
return value === "" ? "" : value;
|
|
47774
|
-
}
|
|
47775
|
-
/**
|
|
47776
|
-
* 握手 origin:`DSH_GLM_SIGN_HANDSHAKE_BASE` 覆盖,默认 `https://api.z.ai`。
|
|
47777
|
-
*
|
|
47778
|
-
* 做成 origin 而不是整串 URL,是为了让「换个部署/反代根」这件事与 `types.ts` 里
|
|
47779
|
-
* `businessHost` / `apiBaseForRegion` 的形状一致;路径部分是常量。
|
|
47780
|
-
*/
|
|
47781
|
-
function signingHandshakeOrigin(env = process.env) {
|
|
47782
|
-
return signHostOverride(env, "DSH_GLM_SIGN_HANDSHAKE_BASE") || "https://api.z.ai";
|
|
47783
|
-
}
|
|
47784
|
-
/**
|
|
47785
|
-
* 握手完整 URL。
|
|
47786
|
-
*
|
|
47787
|
-
* `DSH_GLM_SIGN_HANDSHAKE_URL`(整串覆盖)优先于 `DSH_GLM_SIGN_HANDSHAKE_BASE`。
|
|
47788
|
-
* 单独留一个整串覆盖是因为 `c1f3a7e2` 这段路径**是否会轮换没有验证**(计划 §9 第 2 条),
|
|
47789
|
-
* 上游一旦换路径,只改环境变量就能救,不必发一个版本。
|
|
47790
|
-
*/
|
|
47791
|
-
function signingHandshakeUrl(env = process.env) {
|
|
47792
|
-
const whole = signHostOverride(env, "DSH_GLM_SIGN_HANDSHAKE_URL");
|
|
47793
|
-
if (whole !== "") return whole;
|
|
47794
|
-
return signingHandshakeOrigin(env) + SIGNING_HANDSHAKE_PATH;
|
|
47795
|
-
}
|
|
47796
|
-
/** 签名用的 clientVersion:`DSH_GLM_SIGN_CLIENT_VERSION` 覆盖,默认 `3.15.1`。 */
|
|
47797
|
-
function signingClientVersion(env = process.env) {
|
|
47798
|
-
return signTextOverride(env, "DSH_GLM_SIGN_CLIENT_VERSION") || "3.15.1";
|
|
47799
|
-
}
|
|
47800
|
-
/**
|
|
47801
|
-
* PoW 的 seed:`sha256("{apiKeyId}\n{appId}\n{sessionId}\n{ts}")` 的 hex 前 32 个字符。
|
|
47802
|
-
*
|
|
47803
|
-
* 单独抽出来是因为它同时是**签名前的诊断信息**:seed 算错时 PoW 必然解不出,
|
|
47804
|
-
* 而解不出与「难度太高」是两种完全不同的故障。
|
|
47805
|
-
*/
|
|
47806
|
-
function signingPowSeed(input) {
|
|
47807
|
-
const appId = input.appId ?? "zcode";
|
|
47808
|
-
const message = `${input.apiKeyId}\n${appId}\n${input.sessionId}\n${input.ts}`;
|
|
47809
|
-
return crypto.createHash("sha256").update(message).digest("hex").slice(0, 32);
|
|
47810
|
-
}
|
|
47811
|
-
/**
|
|
47812
|
-
* 解 PoW:找一个让 `sha256("{seed}\n{nonce}{counter}")` 前导 0 位 >= powBits 的 `{nonce}{counter}`。
|
|
47813
|
-
*
|
|
47814
|
-
* 答案的形状是 24 个字符的随机 nonce + 8 位十六进制计数器(原样照抄参考实现)。
|
|
47815
|
-
* 8 位难度平均 256 次尝试、12 位平均 4096 次,都是纯 CPU 的小量级,不构成请求路径上的负担;
|
|
47816
|
-
* 上游要更高难度时改 `powBits` 即可,本文件不做「自适应难度」。
|
|
47817
|
-
*/
|
|
47818
|
-
function solveSigningProofOfWork(input) {
|
|
47819
|
-
const powBits = input.powBits ?? 8;
|
|
47820
|
-
const seed = signingPowSeed(input);
|
|
47821
|
-
const nonce = input.noncePrefix ?? crypto.randomBytes(HANDSHAKE_NONCE_BYTES).toString("hex");
|
|
47822
|
-
const fullBytes = Math.floor(powBits / 8);
|
|
47823
|
-
const remBits = powBits % 8;
|
|
47824
|
-
const remMask = remBits === 0 ? 0 : 255 << 8 - remBits & 255;
|
|
47825
|
-
for (let counter = 0; counter <= POW_MAX_COUNTER; counter += 1) {
|
|
47826
|
-
const candidate = nonce + counter.toString(16).padStart(8, "0");
|
|
47827
|
-
const digest = crypto.createHash("sha256").update(`${seed}\n${candidate}`).digest();
|
|
47828
|
-
let matched = true;
|
|
47829
|
-
for (let i = 0; i < fullBytes; i += 1) if (digest[i] !== 0) {
|
|
47830
|
-
matched = false;
|
|
47831
|
-
break;
|
|
47832
|
-
}
|
|
47833
|
-
if (matched && (remBits === 0 || ((digest[fullBytes] ?? 255) & remMask) === 0)) return candidate;
|
|
47834
|
-
}
|
|
47835
|
-
throw new GlmSigningError("解不开签名用的 proof-of-work(counter 空间已耗尽)");
|
|
47836
|
-
}
|
|
47837
|
-
function withTimeout$1(signal, ms) {
|
|
47838
|
-
const timeout = AbortSignal.timeout(ms);
|
|
47839
|
-
return signal === void 0 ? timeout : AbortSignal.any([signal, timeout]);
|
|
47840
|
-
}
|
|
47841
|
-
/** 大小写不敏感地写一个头:同名不同大小写的两个键会被 `fetch` 合并成一条,后者覆盖前者。 */
|
|
47842
|
-
function putHeader(target, name, value) {
|
|
47843
|
-
const lower = name.toLowerCase();
|
|
47844
|
-
for (const key of Object.keys(target)) if (key.toLowerCase() === lower && key !== name) delete target[key];
|
|
47845
|
-
target[name] = value;
|
|
47846
|
-
}
|
|
47847
|
-
/**
|
|
47848
|
-
* 一把 Coding Plan Key 的签名器。
|
|
47849
|
-
*
|
|
47850
|
-
* **实例化而不是模块级单例**:一个号池可以同时持有两区多个账号(计划 §1、§8.2),
|
|
47851
|
-
* 而握手结果与私钥都是**按凭据**缓存的,单例会把第二个账号的私钥混进第一个账号的缓存。
|
|
47852
|
-
*
|
|
47853
|
-
* 但缓存只在实例内:模块级表会让 `{id}.{secret}` 这种含密的值在进程里长期驻留,
|
|
47854
|
-
* 而它并不需要跨实例复用——W6 建一个签名器用到底即可(同 `biz-token-cache.ts` 的取舍理由)。
|
|
47855
|
-
*
|
|
47856
|
-
* W5/W6 不应直接构造本类,请走 `applyGlmClientSigning()`(受门控)。
|
|
47857
|
-
*/
|
|
47858
|
-
var GlmClientSigner = class {
|
|
47859
|
-
env;
|
|
47860
|
-
fetchFn;
|
|
47861
|
-
handshakeTimeoutMs;
|
|
47862
|
-
/** 已解出的私钥(PKCS#8 DER),按裸凭据分桶。 */
|
|
47863
|
-
privateKeys = /* @__PURE__ */ new Map();
|
|
47864
|
-
/** 在飞的握手,按裸凭据分桶:并发调用只打一次上游。 */
|
|
47865
|
-
handshakes = /* @__PURE__ */ new Map();
|
|
47866
|
-
constructor(options = {}) {
|
|
47867
|
-
this.env = options.env ?? process.env;
|
|
47868
|
-
this.fetchFn = options.fetchFn ?? fetch;
|
|
47869
|
-
this.handshakeTimeoutMs = options.handshakeTimeoutMs ?? 3e4;
|
|
47870
|
-
}
|
|
47871
|
-
/** 本实例当前会打的握手 URL(诊断用,设置卡片展示「签名会打到哪里」)。 */
|
|
47872
|
-
get handshakeUrl() {
|
|
47873
|
-
return signingHandshakeUrl(this.env);
|
|
47874
|
-
}
|
|
47875
|
-
/**
|
|
47876
|
-
* 拿到这把凭据的 Ed25519 私钥(PKCS#8 DER),必要时先握手一次。
|
|
47877
|
-
*
|
|
47878
|
-
* 缓存策略是「一把凭据一把私钥,直到 `clearPrivateKey()`」。
|
|
47879
|
-
* **未验证**:服务端会不会为同一把 Coding Plan Key 重新下发私钥,没有任何证据;
|
|
47880
|
-
* 若上游轮换私钥,症状会是「签名被拒」,处置是调 `clearPrivateKey()` 让它重握手。
|
|
47881
|
-
*
|
|
47882
|
-
* 这是低层原语,**不受门控**——门控在唯一对外的 `buildSigningHeaders()` 上。
|
|
47883
|
-
*/
|
|
47884
|
-
async ensurePrivateKey(apiKey, signal) {
|
|
47885
|
-
const parsed = requireApiKey(apiKey);
|
|
47886
|
-
const cached = this.privateKeys.get(parsed.credential);
|
|
47887
|
-
if (cached !== void 0) return cached;
|
|
47888
|
-
const joined = this.handshakes.get(parsed.credential);
|
|
47889
|
-
if (joined !== void 0) return joined;
|
|
47890
|
-
const pending = this.performHandshake(parsed, signal).then((key) => {
|
|
47891
|
-
this.privateKeys.set(parsed.credential, key);
|
|
47892
|
-
return key;
|
|
47893
|
-
}).finally(() => {
|
|
47894
|
-
if (this.handshakes.get(parsed.credential) === pending) this.handshakes.delete(parsed.credential);
|
|
47895
|
-
});
|
|
47896
|
-
this.handshakes.set(parsed.credential, pending);
|
|
47897
|
-
return pending;
|
|
47898
|
-
}
|
|
47899
|
-
/** 丢掉缓存的私钥(换凭据、怀疑上游轮换私钥时调用);不给参数则全丢。 */
|
|
47900
|
-
clearPrivateKey(apiKey) {
|
|
47901
|
-
if (apiKey === void 0) {
|
|
47902
|
-
this.privateKeys.clear();
|
|
47903
|
-
return;
|
|
47904
|
-
}
|
|
47905
|
-
const parsed = parseGlmCodingPlanApiKey(apiKey);
|
|
47906
|
-
if (parsed !== void 0) this.privateKeys.delete(parsed.credential);
|
|
47907
|
-
}
|
|
47908
|
-
/**
|
|
47909
|
-
* 握手一次并解出私钥。
|
|
47910
|
-
*
|
|
47911
|
-
* 步骤逐字照参考实现:HKDF 导出 HMAC 密钥 → 用 `"get_sign_key\n{id}\n{ts}\n{nonce}"`
|
|
47912
|
-
* (换行分隔)算 base64 签名 → POST → 取 `data.privateCipher` → HKDF 导出 AES-GCM 密钥解密。
|
|
47913
|
-
*/
|
|
47914
|
-
async performHandshake(parsed, signal) {
|
|
47915
|
-
const ts = String(Date.now());
|
|
47916
|
-
const nonce = crypto.randomBytes(HANDSHAKE_NONCE_BYTES).toString("hex");
|
|
47917
|
-
const url = signingHandshakeUrl(this.env);
|
|
47918
|
-
const hmacKey = crypto.hkdfSync("sha256", parsed.apiKeySecret, SIGNING_KDF_SALT, SIGNING_INFO_HMAC, 32);
|
|
47919
|
-
const hmac = crypto.createHmac("sha256", Buffer.from(hmacKey));
|
|
47920
|
-
hmac.update(`${SIGNING_HMAC_PREFIX}\n${parsed.apiKeyId}\n${ts}\n${nonce}`);
|
|
47921
|
-
const sig = hmac.digest("base64");
|
|
47922
|
-
let payload;
|
|
47923
|
-
let status = 0;
|
|
47924
|
-
try {
|
|
47925
|
-
const response = await this.fetchFn(url, {
|
|
47926
|
-
method: "POST",
|
|
47927
|
-
headers: {
|
|
47928
|
-
authorization: parsed.credential,
|
|
47929
|
-
"content-type": "application/json",
|
|
47930
|
-
accept: "application/json"
|
|
47931
|
-
},
|
|
47932
|
-
body: JSON.stringify({
|
|
47933
|
-
apiKey: parsed.credential,
|
|
47934
|
-
nonce,
|
|
47935
|
-
sig,
|
|
47936
|
-
ts
|
|
47937
|
-
}),
|
|
47938
|
-
signal: withTimeout$1(signal, this.handshakeTimeoutMs)
|
|
47939
|
-
});
|
|
47940
|
-
status = response.status;
|
|
47941
|
-
payload = await response.json().catch(() => void 0);
|
|
47942
|
-
} catch (error) {
|
|
47943
|
-
throw new GlmSigningError(`签名握手(${url})请求失败(HTTP ${status || "—"}):` + (error instanceof Error ? error.message : String(error)), { cause: error });
|
|
47944
|
-
}
|
|
47945
|
-
if (typeof payload !== "object" || payload === null || Array.isArray(payload)) throw new GlmSigningError(`签名握手(${url})响应不是 JSON 对象(HTTP ${status})`);
|
|
47946
|
-
const envelope = payload;
|
|
47947
|
-
if (envelope.code !== 200 && envelope.code !== 0) {
|
|
47948
|
-
const msg = typeof envelope.msg === "string" ? envelope.msg : "unknown";
|
|
47949
|
-
throw new GlmSigningError(`签名握手被拒(HTTP ${status}):code=${String(envelope.code)} msg=${msg}`);
|
|
47950
|
-
}
|
|
47951
|
-
const privateCipher = envelope.data?.privateCipher;
|
|
47952
|
-
if (typeof privateCipher !== "string" || privateCipher === "") throw new GlmSigningError(`签名握手响应里没有 data.privateCipher(HTTP ${status})`);
|
|
47953
|
-
return this.decryptPrivateKey(parsed, privateCipher);
|
|
47954
|
-
}
|
|
47955
|
-
/**
|
|
47956
|
-
* 解 `privateCipher`:base64 → iv(12) ‖ ciphertext ‖ tag(16) → AES-256-GCM。
|
|
47957
|
-
*
|
|
47958
|
-
* AAD 是 apiKeyId(逐字来自参考实现)。解密出的明文按形状判定:
|
|
47959
|
-
*
|
|
47960
|
-
* - 明文**首字节是 0x30**(ASN.1 SEQUENCE)→ 明文本身就是 PKCS#8 DER;
|
|
47961
|
-
* - 否则按参考实现的实测口径再解一层 base64(双层编码)。
|
|
47962
|
-
*
|
|
47963
|
-
* **未验证**:第一种形状没有任何证据,只是为了上游哪天改掉这层 base64 时不至于整体失败。
|
|
47964
|
-
*/
|
|
47965
|
-
decryptPrivateKey(parsed, privateCipher) {
|
|
47966
|
-
const cipherBytes = Buffer.from(privateCipher, "base64");
|
|
47967
|
-
const IV_BYTES = 12;
|
|
47968
|
-
if (cipherBytes.length <= 28) throw new GlmSigningError(`签名握手返回的 privateCipher 太短(${cipherBytes.length} 字节)`);
|
|
47969
|
-
const aesKey = crypto.hkdfSync("sha256", parsed.apiKeySecret, SIGNING_KDF_SALT, SIGNING_INFO_PRIV, 32);
|
|
47970
|
-
const iv = cipherBytes.subarray(0, IV_BYTES);
|
|
47971
|
-
const ciphertextWithTag = cipherBytes.subarray(IV_BYTES);
|
|
47972
|
-
const ciphertext = ciphertextWithTag.subarray(0, -16);
|
|
47973
|
-
const tag = ciphertextWithTag.subarray(-16);
|
|
47974
|
-
let plaintext;
|
|
47975
|
-
try {
|
|
47976
|
-
const decipher = crypto.createDecipheriv("aes-256-gcm", Buffer.from(aesKey), iv);
|
|
47977
|
-
decipher.setAuthTag(tag);
|
|
47978
|
-
decipher.setAAD(Buffer.from(parsed.apiKeyId, "utf8"));
|
|
47979
|
-
plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
47980
|
-
} catch (error) {
|
|
47981
|
-
throw new GlmSigningError("签名握手返回的 privateCipher 解不开(密钥、AAD 或密文长度不对)", { cause: error });
|
|
47982
|
-
}
|
|
47983
|
-
if (plaintext.length > 0 && plaintext[0] === 48) return plaintext;
|
|
47984
|
-
return Buffer.from(plaintext.toString("utf8").trim(), "base64");
|
|
47985
|
-
}
|
|
47986
|
-
/**
|
|
47987
|
-
* 生成本次请求的签名头表。**这是签名层唯一对外的入口,受门控。**
|
|
47988
|
-
*
|
|
47989
|
-
* 门控关闭(默认)时:返回**空表**,并且一次网络请求都不发——所以「默认路径不产生
|
|
47990
|
-
* 任何 X-Client-* 头」不是一句约定,而是这条分支的必然结果。
|
|
47991
|
-
*
|
|
47992
|
-
* 返回的表里**没有 `Authorization`**:本线路模型面的认证头由 W5/W6 装配,
|
|
47993
|
-
* Anthropic 面要求 `x-api-key` 与 `Authorization: Bearer` 双头同值(计划 §3.3),
|
|
47994
|
-
* 签名器越权写那一行会把装配层算好的头顶掉。
|
|
47995
|
-
*/
|
|
47996
|
-
async buildSigningHeaders(input) {
|
|
47997
|
-
if (!clientSigningEnabled(this.env)) return {};
|
|
47998
|
-
const parsed = requireApiKey(input.apiKey);
|
|
47999
|
-
const privateKeyDer = await this.ensurePrivateKey(input.apiKey, input.signal);
|
|
48000
|
-
const sessionId = input.sessionId ?? crypto.randomUUID();
|
|
48001
|
-
const clientVersion = input.clientVersion ?? signingClientVersion(this.env);
|
|
48002
|
-
const ts = String(Date.now());
|
|
48003
|
-
const clientNonce = crypto.randomBytes(REQUEST_NONCE_BYTES).toString("hex");
|
|
48004
|
-
const pow = solveSigningProofOfWork({
|
|
48005
|
-
apiKeyId: parsed.apiKeyId,
|
|
48006
|
-
appId: input.appId,
|
|
48007
|
-
sessionId,
|
|
48008
|
-
ts,
|
|
48009
|
-
powBits: input.powBits
|
|
48010
|
-
});
|
|
48011
|
-
const signData = `${parsed.apiKeyId}\n${ts}\n${clientVersion}\n${sessionId}\n${clientNonce}`;
|
|
48012
|
-
const privateKey = crypto.createPrivateKey({
|
|
48013
|
-
key: privateKeyDer,
|
|
48014
|
-
format: "der",
|
|
48015
|
-
type: "pkcs8"
|
|
48016
|
-
});
|
|
48017
|
-
const clientSig = crypto.sign(null, Buffer.from(signData, "utf8"), privateKey).toString("base64");
|
|
48018
|
-
const platform = os.platform();
|
|
48019
|
-
const osCategory = platform === "darwin" ? "macos" : platform === "win32" ? "windows" : "linux";
|
|
48020
|
-
return {
|
|
48021
|
-
"User-Agent": `ZCode/${clientVersion}`,
|
|
48022
|
-
"X-App-Id": input.appId ?? "zcode",
|
|
48023
|
-
"X-Client-Version": clientVersion,
|
|
48024
|
-
"X-ZCode-App-Version": clientVersion,
|
|
48025
|
-
"X-Session-Id": sessionId,
|
|
48026
|
-
"X-Client-Ts": ts,
|
|
48027
|
-
"X-Client-Nonce": clientNonce,
|
|
48028
|
-
"X-Client-Pow": pow,
|
|
48029
|
-
"X-Client-Sig": clientSig,
|
|
48030
|
-
"X-Title": "Z Code@cli",
|
|
48031
|
-
"X-Release-Channel": "stable",
|
|
48032
|
-
"X-ZCode-Agent": "glm",
|
|
48033
|
-
"X-Platform": `${platform}-${os.arch()}`,
|
|
48034
|
-
"X-Os-Category": osCategory
|
|
48035
|
-
};
|
|
48036
|
-
}
|
|
48037
|
-
};
|
|
48038
|
-
/**
|
|
48039
|
-
* 把签名头合并进调用方的请求头表,**就地写入并返回同一对象**。
|
|
48040
|
-
*
|
|
48041
|
-
* 门控关闭时返回原对象且**一个键都不动**——这是计划 §8.2「断言默认路径不产生 X-Client-* 头」
|
|
48042
|
-
* 对装配层(W5/W6)的保证:不调用方需要写任何 `if`。
|
|
48043
|
-
*
|
|
48044
|
-
* 合并时大小写不敏感地覆盖同名头,避免调用方已经写了 `x-client-version` 时
|
|
48045
|
-
* `fetch` 拿到两条同名头、取值取决于键的插入顺序。
|
|
48046
|
-
*/
|
|
48047
|
-
async function applyGlmClientSigning(headers, input, options = {}) {
|
|
48048
|
-
if (!clientSigningEnabled(options.env ?? process.env)) return headers;
|
|
48049
|
-
const signing = await (options.signer ?? new GlmClientSigner(options)).buildSigningHeaders({
|
|
48050
|
-
apiKey: input.apiKey,
|
|
48051
|
-
sessionId: options.sessionId,
|
|
48052
|
-
clientVersion: options.clientVersion,
|
|
48053
|
-
powBits: options.powBits,
|
|
48054
|
-
signal: input.signal
|
|
48055
|
-
});
|
|
48056
|
-
const overrideUserAgent = options.overrideUserAgent === true;
|
|
48057
|
-
for (const [name, value] of Object.entries(signing)) {
|
|
48058
|
-
if (!overrideUserAgent && name.toLowerCase() === "user-agent") continue;
|
|
48059
|
-
putHeader(headers, name, value);
|
|
48060
|
-
}
|
|
48061
|
-
return headers;
|
|
48062
|
-
}
|
|
48063
47951
|
/** 凭据文件在数据根下的两段目录名(逐字:`join(base, ".zcode", "v2", "credentials.json")`)。 */
|
|
48064
47952
|
const ZCODE_CREDENTIAL_DIR_SEGMENTS = [".zcode", "v2"];
|
|
48065
47953
|
/** 凭据文件名(逐字:`shared-credentials.ts` 的 `resolveSharedZCodeCredentialsPath`)。 */
|
|
@@ -48934,14 +48822,11 @@ function registerGlmCodingPlanPreferenceStore(settings, fallbackStore = new GlmC
|
|
|
48934
48822
|
* Chat Completions 线,`null`(目录没有转录过的 id)**拒绝这个模型**——挑错的表现是
|
|
48935
48823
|
* 1212 `WRONG_METHOD`,比直接拒绝更难排查。
|
|
48936
48824
|
*
|
|
48937
|
-
*
|
|
48825
|
+
* 另外两件事也刻意留在这里而不是散进两个 mapper:
|
|
48938
48826
|
*
|
|
48939
48827
|
* - **ladder 由本层传入**:`glmEffortForLadder` / `buildChatRequest` 只收敛,不查目录。
|
|
48940
48828
|
* 梯子来自 `GlmModelOption.reasoningEfforts`,空数组 = 该模型完全不发思考控制
|
|
48941
48829
|
* (**有意语义**,不是 bug)。
|
|
48942
|
-
* - **签名层就地合并**:`applyGlmClientSigning` 门控关闭时原样返回、零网络请求,
|
|
48943
|
-
* 所以这里不写任何 `if`。sessionId 在一个适配器实例的生命周期内固定复用,
|
|
48944
|
-
* 每次新生成会让 PoW seed 与签名串都变。
|
|
48945
48830
|
* - **冷却键看状态码 429 与正文里的重置时刻**,而不是只看 `code`。冻结的错误码表里
|
|
48946
48831
|
* 七条 429 有五条是额度类(`USAGE_LIMIT` / `PLAN_LIMIT` / `NO_BALANCE` / `PLAN_EXPIRED` /
|
|
48947
48832
|
* `MODEL_NOT_IN_PLAN`),它们不可重试,而「`code === 'RATE_LIMIT'` 才冷却」会让
|
|
@@ -49096,16 +48981,6 @@ var GlmCodingPlanAdapter = class extends LlmAdapter {
|
|
|
49096
48981
|
preferences;
|
|
49097
48982
|
accountPool;
|
|
49098
48983
|
options;
|
|
49099
|
-
/**
|
|
49100
|
-
* 签名器:每个适配器实例一个。
|
|
49101
|
-
*
|
|
49102
|
-
* 握手结果与私钥按凭据缓存,而一个池里可以同时有两区多个账号,所以做成实例级而不是模块级单例。
|
|
49103
|
-
* 默认门控关闭时它从不被用到(`applyGlmClientSigning` 直接原样返回),
|
|
49104
|
-
* 换凭据时也不需要手动清——因为它按 `apiKey` 派生缓存键。
|
|
49105
|
-
*/
|
|
49106
|
-
signer;
|
|
49107
|
-
/** 一个实例内固定复用的会话 id;每次新生成都会改变 PoW seed 与签名串。 */
|
|
49108
|
-
signingSessionId;
|
|
49109
48984
|
constructor(store = new GlmCodingPlanCredentialStore(), modelSettings = new GlmCodingPlanModelSettingsStore(), preferences, options = {}) {
|
|
49110
48985
|
super();
|
|
49111
48986
|
this.store = store;
|
|
@@ -49113,8 +48988,6 @@ var GlmCodingPlanAdapter = class extends LlmAdapter {
|
|
|
49113
48988
|
this.preferences = preferences;
|
|
49114
48989
|
this.options = options;
|
|
49115
48990
|
this.accountPool = options.accountPool ?? null;
|
|
49116
|
-
this.signer = new GlmClientSigner({ ...options.fetchFn === void 0 ? {} : { fetchFn: options.fetchFn } });
|
|
49117
|
-
this.signingSessionId = "dsh-glm-coding-plan";
|
|
49118
48991
|
}
|
|
49119
48992
|
providerInfo(provider) {
|
|
49120
48993
|
return {
|
|
@@ -49237,19 +49110,11 @@ var GlmCodingPlanAdapter = class extends LlmAdapter {
|
|
|
49237
49110
|
});
|
|
49238
49111
|
const key = picked.credentials.codingPlan.codingPlanKey;
|
|
49239
49112
|
const headers = plan.wire === "anthropic" ? glmAnthropicHeaders(key, plan.headers) : glmOpenAiHeaders(key, plan.headers);
|
|
49240
|
-
const signed = clientSigningEnabled(process.env) ? await applyGlmClientSigning(headers, {
|
|
49241
|
-
apiKey: key,
|
|
49242
|
-
signal
|
|
49243
|
-
}, {
|
|
49244
|
-
signer: this.signer,
|
|
49245
|
-
sessionId: this.signingSessionId,
|
|
49246
|
-
...this.options.fetchFn === void 0 ? {} : { fetchFn: this.options.fetchFn }
|
|
49247
|
-
}) : headers;
|
|
49248
49113
|
const body = JSON.stringify(plan.body);
|
|
49249
49114
|
try {
|
|
49250
49115
|
response = await fetchWithContextBudgetRecovery(fetchFn)(plan.url, {
|
|
49251
49116
|
method: "POST",
|
|
49252
|
-
headers
|
|
49117
|
+
headers,
|
|
49253
49118
|
body,
|
|
49254
49119
|
signal
|
|
49255
49120
|
});
|
|
@@ -59719,4 +59584,4 @@ function localWebServerBaseUrl(host, port) {
|
|
|
59719
59584
|
return `http://${host === "0.0.0.0" ? "127.0.0.1" : host}:${port}`;
|
|
59720
59585
|
}
|
|
59721
59586
|
//#endregion
|
|
59722
|
-
export { AccountPoolCore, AccountPoolStore, AntigravityAdapter, ADOPTED_CREDENTIAL_EXPIRED_HINT as CLAUDE_ADOPTED_CREDENTIAL_EXPIRED_HINT, API_BASE as CLAUDE_API_BASE, DEFAULT_VISIBLE_MODEL_IDS as CLAUDE_DEFAULT_VISIBLE_MODELS, FALLBACK_MODELS as CLAUDE_FALLBACK_MODELS, MESSAGES_PATH as CLAUDE_MESSAGES_PATH, CLAUDE_MODELS, CLAUDE_MODEL_IDS, PROVIDER_ID as CLAUDE_PROVIDER_ID, PROVIDER_NAME as CLAUDE_PROVIDER_NAME, QUOTA_CACHE_TTL_MS as CLAUDE_QUOTA_CACHE_TTL_MS, CLAUDE_REASONING_EFFORTS, ROUTE_PREFIX as CLAUDE_ROUTE_PREFIX, ClaudeAccountPool, ClaudeAdapter, FileCredentialStore as ClaudeCredentialStore, FileModelSettingsStore as ClaudeModelSettingsStore, CodexAccountPool, CodexChatGptAdapter, CommandCodeAccountPool, CommandCodeAdapter, FileCredentialStore$1 as CommandCodeCredentialStore, FileModelSettingsStore$1 as CommandCodeModelSettingsStore, Config, DEFAULT_GUARD_OPTIONS, DEFAULT_SUBAGENT_INHERIT_TOOLS, FileCredentialStore$2 as FileCredentialStore, FileModelSettingsStore$2 as FileModelSettingsStore, GLM_CODING_PLAN_PREFERENCES_NAMESPACE, QUOTA_WINDOW_MINUTES as GLM_CODING_PLAN_QUOTA_WINDOW_MINUTES, GLM_CODING_PLAN_RETRY_POLICY_CONFIG, PROVIDER_ID$1 as GLM_CODING_PLAN_ROUTE_PROVIDER_ID, PROVIDER_NAME$1 as GLM_CODING_PLAN_ROUTE_PROVIDER_NAME, GLM_MODEL_CATALOG, GLM_MODEL_IDS, GLM_POOL_COOLDOWN_MS, GlmAdoptedCredentialRefreshError, GlmClientSigner, GlmCodingPlanAccountPool, GlmCodingPlanAdapter, GlmCodingPlanCredentialStore, GlmCodingPlanModelSettingsStore, KIMI_CODE_MODELS, KIMI_CODE_RETRY_POLICY_CONFIG, KimiCodeAccountPool, KimiCodeAdapter, FileCredentialStore$3 as KimiCodeCredentialStore, FileModelSettingsStore$3 as KimiCodeModelSettingsStore, LinuxFileTokenStore, AGENT_LLM_PREFIX as MINIMAX_CODE_AGENT_LLM_PREFIX, DEFAULT_MAX_MESSAGE_BODY_BYTES as MINIMAX_CODE_MAX_MESSAGE_BODY_BYTES, MESSAGES_PATH$1 as MINIMAX_CODE_MESSAGES_PATH, MINIMAX_CODE_MODELS, PROBE_MODEL as MINIMAX_CODE_PROBE_MODEL, MINIMAX_CODE_PROVIDER_ID, MINIMAX_CODE_PROVIDER_NAME, MINIMAX_CODE_REASONING_EFFORTS, REGION_HOSTS as MINIMAX_CODE_REGION_HOSTS, MINIMAX_CODE_RETRY_POLICY_CONFIG, MINIMAX_CODE_ROUTE_PREFIX, MacKeychainTokenStore, MinimaxCodeAccountPool, MinimaxCodeAdapter, MinimaxCodeCheckinService, MinimaxCodeCredentialStore, MinimaxCodeModelSettingsStore, OAuthService, ProxyManager, RELAY_PROBE_ENV, RELAY_PROBE_FILE_ENV, RELAY_PROBE_FILE_NAME, RELAY_PROBE_MAX_BYTES, RELAY_SOURCE_KINDS, RESUME_HINT, RESUME_HINT_STRICT, RelayProbe, ResponsesClient, STEP_CODE_POOL_COOLDOWN_MS, STEP_CODE_PROFILES, STEP_CODE_PROVIDER_ID, STEP_CODE_PROVIDER_NAME, STEP_CODE_RETRY_POLICY_CONFIG, STEP_CODE_ROUTE_PREFIX, SUBAGENT_MODEL_SELECTION_NAMESPACE, SUBAGENT_POLICY_EVENT, SearchProviderSwitcher, StepCodeAccountPool, StepCodeAdapter, StepCodeCredentialRefreshError, StepCodeCredentialStore, StepCodeModelSettingsStore, StepCodeQuotaCredentialStore, UsageService, FALLBACK_MODELS$1 as WORKBUDDY_MODELS, WORKBUDDY_MODEL_IDS, WindowsDpapiTokenStore, WorkBuddyAdapter, WorkBuddyCheckinService, FileCredentialStore$4 as WorkBuddyCredentialStore, FileModelSettingsStore$4 as WorkBuddyModelSettingsStore, adoptZcodeSignIn as adoptGlmZcodeSignIn, adoptedPoolAccountKey, apply, applyGlmClientSigning, assertRequestBodyFits as assertMinimaxCodeBodyFits, assertStreamComplete as assertMinimaxCodeStreamComplete, auditChildRoutes, auditedRoutesOf, authorizedRoutesFor, beginLogin as beginClaudeLogin, beginWebLogin as beginKimiCodeLogin, beginWebLogin$1 as beginMinimaxCodeLogin, beginWebLogin$2 as beginWebLogin, buildClaudeModelOptions, buildGlmRequestPlan, buildMinimaxCodeModelOptions, buildMinimaxRequest, cachedStepCodeModelCatalog, cancelLogin as cancelClaudeLogin, cancelWebLogin as cancelMinimaxCodeLogin, catalogModelOptions, childRoutesOf, clampOutputToContext as clampMinimaxCodeOutputToContext, classifyFailure as classifyClaudeFailure, classifyKimiFailure, classifyMinimaxFailure, classifyFailure$1 as classifyWorkBuddyFailure, claudeCliVersion, claudeCodeCredentialPaths, claudeCodeCredentialPresence, codeForFailure as claudeCodeForFailure, credentialPath as claudeCredentialPath, defaultContextWindowFor as claudeDefaultContextWindow, maxOutputTokensFor as claudeMaxOutputTokens, claudeModelCanDisableThinking, modelSettingsPath as claudeModelSettingsPath, claudeModelSupportsImage, claudeModelSupportsTemperature, claudePoolPath, claudeReasoningEfforts, claudeThinkingMode, toLlmError as claudeToLlmError, clearCachedQuota, clearCachedCatalog as clearClaudeCatalog, clearCachedQuota$1 as clearClaudeQuota, clearCachedQuota$2 as clearCommandCodeQuota, clearCachedQuota$3 as clearKimiCodeQuota, clearCachedQuota$4 as clearMinimaxCodeQuota, clearCachedCatalog$1 as clearWorkBuddyCatalog, clearCachedQuota$5 as clearWorkBuddyQuota, closeMinimaxStream, codeBuddyAuthDir, codexPoolPath, collapseScore, commandCodeAccountKey, credentialPath$1 as commandCodeCredentialPath, modelSettingsPath$1 as commandCodeModelSettingsPath, commandCodePoolPath, contextWindowForModel, convergeGlmEffort, createCodexFetchProvider, createCodexImageTool, createCodexSearchProvider, createFileRelayProbeSink, createMinimaxCodeAccountsHandler, createMessage as createMinimaxCodeMessage, createPkcePair as createMinimaxCodePkcePair, createStreamState as createMinimaxCodeStreamState, createPlatformTokenStore, createSubagentAuthorization, credentialPath$2 as credentialPath, credentialsFromAdopt, credentialsFromCliLogin, delegationDenialReason, delegationModeOf, describeCredentials as describeMinimaxCodeCredentials, detectSystemProxy, dshHomeDir, effectiveRouteOf, ensureAccessToken as ensureClaudeAccessToken, ensureAccessToken$1 as ensureKimiCodeAccessToken, ensureAccessToken$2 as ensureMinimaxCodeAccessToken, fetchAccountQuota, fetchAccountQuota$1 as fetchClaudeQuota, fetchAccountQuota$2 as fetchCommandCodeQuota, fetchGlmQuota, fetchAccountQuota$3 as fetchKimiCodeQuota, fetchUserInfo as fetchKimiCodeUserInfo, fetchTokenPlanQuota as fetchMinimaxCodeQuota, fetchAccountQuota$4 as fetchWorkBuddyQuota, getCachedQuota as getCachedGlmCodingPlanQuota, getCachedQuota$1 as getCachedQuota, getLoginStatus as getClaudeLoginStatus, getCachedQuota$2 as getClaudeQuota, getClaudeWebStatus, getWebLoginStatus as getCommandCodeLoginStatus, getCachedQuota$3 as getCommandCodeQuota, getCommandCodeWebStatus, getGlmCodingPlanStatus, getWebLoginStatus$1 as getKimiCodeLoginStatus, getCachedQuota$4 as getKimiCodeQuota, getKimiCodeWebStatus, getWebLogin as getMinimaxCodeLogin, getCachedQuota$5 as getMinimaxCodeQuota, getMinimaxCodeWebStatus, getStepCodeStatus, getCachedQuota$6 as getWorkBuddyQuota, getWorkBuddyWebStatus, glmCatalogSize, authorizeUrl as glmCodingPlanAuthorizeUrl, catalogSize as glmCodingPlanCatalogCount, credentialPath$3 as glmCodingPlanCredentialPath, modelSettingsPath$2 as glmCodingPlanModelSettingsPath, modelsForRegion as glmCodingPlanModelsForRegion, glmCodingPlanPoolIdentity, glmCodingPlanPoolPath, glmCodingPlanPoolQuota, glmCodingPlanPoolStatus, glmCodingPlanSettingsSource, glmCooldownDecision, glmSubPathOf, inheritOverrideReason, inheritRouteDenialReason, inheritedRouteOf, inject, installReasoningCollapseGuard, installRelayProbe, installSubagentModelAuthorization, isAdoptedClaudeCredential, isAdoptedCredentialExpired, isAdoptedCredential as isAdoptedGlmCodingPlanCredential, isAdoptedZcodeCredential as isAdoptedGlmZcodeCredential, isAdoptedPoolCredential, isClaudeReasoningEffort, isGlmReasoningEffort, isMinimaxCodeReasoningEffort, isRefreshTokenRejected as isMinimaxCodeRefreshTokenRejected, isThinkingDisabledEffort, credentialPath$4 as kimiCodeCredentialPath, kimiCodeModelDef, modelSettingsPath$3 as kimiCodeModelSettingsPath, kimiCodePoolPath, listModelIds as listMinimaxCodeModelIds, loadCatalog as loadClaudeCatalog, loadProviderModels as loadCommandCodeModels, loadCatalog$1 as loadGlmCodingPlanCatalog, loadProviderModels$1 as loadKimiCodeModels, loadConfigCatalog as loadWorkBuddyModels, loginAndSave, mapCodexUsage, mergeGlmCodingPlanSettings, accountFromCredentials as minimaxCodeAccountFromCredentials, accountHost as minimaxCodeAccountHost, agentBaseUrl as minimaxCodeAgentBaseUrl, authJsonPath as minimaxCodeAuthJsonPath, authStateJsonPath as minimaxCodeAuthStateJsonPath, catalogSize$1 as minimaxCodeCatalogSize, credentialIsFresh as minimaxCodeCredentialIsFresh, effortForModel as minimaxCodeEffortForModel, minimaxHomeDir as minimaxCodeHomeDir, maxMessageBodyBytes as minimaxCodeMaxMessageBodyBytes, maxOutputTokensFor$1 as minimaxCodeMaxOutputTokens, messagesUrl as minimaxCodeMessagesUrl, minimaxCodeModelDef, minimaxCodeModelIds, minimaxCodeModelName, modelRequestHeaders as minimaxCodeModelRequestHeaders, modelSettingsPath$4 as minimaxCodeModelSettingsPath, outputConfigFor as minimaxCodeOutputConfig, pluginCredentialPath as minimaxCodePluginCredentialPath, minimaxCodePoolIdentity, minimaxCodePoolPath, minimaxCodePoolStatus, quotaHostCandidates as minimaxCodeQuotaHostCandidates, quotaRequestHeaders as minimaxCodeQuotaRequestHeaders, subPathOf as minimaxCodeSubPathOf, tokenPlanRemainsUrl as minimaxCodeTokenPlanRemainsUrl, modelSettingsPath$5 as modelSettingsPath, normalizeDelegationToolNames, normalizeRegion as normalizeGlmCodingPlanRegion, normalizeInheritToolNames, normalizeRotationStrategy, parseAllowedRoutes, parseClaudeCredentialDocument, parseClaudeCredentials, parseClaudePoolData, parseUsagePayload as parseClaudeUsagePayload, parseCodexPoolData, parseCodexUsage, parseCommandCodePoolData, parseGlmCodingPlanApiKey, parseGlmCodingPlanCredentials, parseGlmCodingPlanPoolData, parseKimiCodePoolData, parseMinimaxCodeCredentials, parseMinimaxCodePoolData, parseTokenPlanQuota as parseMinimaxCodeQuota, parseAnthropicUsage as parseMinimaxCodeUsage, parseResponsesStream, parseBilling as parseWorkBuddyBilling, parseConfigModels as parseWorkBuddyConfigModels, parseCredentialFile as parseWorkBuddyCredential, policyRoutesOf, pollWebLogin as pollMinimaxCodeLogin, probeConnection as probeClaudeConnection, processMinimaxStreamLine, readChildDescriptor, readClaudeCodeCredentials, readGlmResetAt, readStepCodeCacheStats, redactToken as redactMinimaxCodeToken, refreshAntigravityToken, refreshAccessToken as refreshClaudeToken, refreshAccessToken$1 as refreshKimiCodeToken, refreshAccessToken$2 as refreshMinimaxCodeToken, refreshCredentials as refreshWorkBuddyCredentials, registerClaudePreferenceStore, registerClaudeRoutes, registerCommandCodePreferenceStore, registerCommandCodeRoutes, registerGlmCodingPlanPreferenceStore, registerGlmCodingPlanRoutes, registerKimiCodePreferenceStore, registerKimiCodeRoutes, registerMinimaxCodePreferenceStore, registerMinimaxCodeRoutes, registerStepCodePreferenceStore, registerStepCodeRoutes, registerWorkBuddyPreferenceStore, registerWorkBuddyRoutes, relayProbeEnabled, relayProbeEnvFile, relayProbeEnvValue, relayProbeLogPath, rememberStepCodeCacheUsage, requestDeviceAuthorization as requestKimiCodeDeviceAuthorization, requestDeviceAuthorization$1 as requestMinimaxCodeDeviceAuthorization, resetWebLogins as resetMinimaxCodeLogins, resolveEnabledModelIds as resolveClaudeEnabledModelIds, resolveLoginInput as resolveClaudeLoginInput, resolveClaudeModel, resolveGlmModel, resolveGuardOptions, resolveRegion as resolveKimiCodeRegion, resolveMinimaxCodeEnabledModelIds, resolveQuotaCounts as resolveMinimaxCodeQuotaCounts, resolveWorkBuddyModel, revokeToken as revokeMinimaxCodeToken, saveApiKey as saveCommandCodeApiKey, scanCredentials as scanWorkBuddyCredentials, setClaudeCliVersion, beginWebLogin$3 as startCommandCodeLogin, stepCodeCatalogSize, credentialPath$5 as stepCodeCredentialPath, stepCodeModelCatalogFrom, modelSettingsPath$6 as stepCodeModelSettingsPath, stepCodePoolIdentity, stepCodePoolPath, stepCodePoolQuota, stepCodePoolStatus, stepCodePoolStatusSlice, quotaCredentialPath as stepCodeQuotaCredentialPath, stepCodeSettingsSource, stepCodeSubPathOf, subagentModelSelectionPreference, submitLoginInput as submitClaudeLoginInput, summarizeFailureBody as summarizeMinimaxCodeFailureBody, testConnection as testMinimaxCodeConnection, unauthorizedRouteReason, validateAuthorizationScope, validateDelegationToolNames, validateInheritToolNames, verifyCodingPlanKey as verifyGlmCodingPlanKey, violationText, modelSettingsPath$7 as workBuddyModelSettingsPath, modelsForRegion$1 as workBuddyModelsForRegion, zcodeCredentialsPath };
|
|
59587
|
+
export { AccountPoolCore, AccountPoolStore, AntigravityAdapter, ADOPTED_CREDENTIAL_EXPIRED_HINT as CLAUDE_ADOPTED_CREDENTIAL_EXPIRED_HINT, API_BASE as CLAUDE_API_BASE, DEFAULT_VISIBLE_MODEL_IDS as CLAUDE_DEFAULT_VISIBLE_MODELS, FALLBACK_MODELS as CLAUDE_FALLBACK_MODELS, MESSAGES_PATH as CLAUDE_MESSAGES_PATH, CLAUDE_MODELS, CLAUDE_MODEL_IDS, PROVIDER_ID as CLAUDE_PROVIDER_ID, PROVIDER_NAME as CLAUDE_PROVIDER_NAME, QUOTA_CACHE_TTL_MS as CLAUDE_QUOTA_CACHE_TTL_MS, CLAUDE_REASONING_EFFORTS, ROUTE_PREFIX as CLAUDE_ROUTE_PREFIX, ClaudeAccountPool, ClaudeAdapter, FileCredentialStore as ClaudeCredentialStore, FileModelSettingsStore as ClaudeModelSettingsStore, CodexAccountPool, CodexChatGptAdapter, CommandCodeAccountPool, CommandCodeAdapter, FileCredentialStore$1 as CommandCodeCredentialStore, FileModelSettingsStore$1 as CommandCodeModelSettingsStore, Config, DEFAULT_GUARD_OPTIONS, DEFAULT_SUBAGENT_INHERIT_TOOLS, FileCredentialStore$2 as FileCredentialStore, FileModelSettingsStore$2 as FileModelSettingsStore, GLM_CODING_PLAN_PREFERENCES_NAMESPACE, QUOTA_WINDOW_MINUTES as GLM_CODING_PLAN_QUOTA_WINDOW_MINUTES, GLM_CODING_PLAN_RETRY_POLICY_CONFIG, PROVIDER_ID$1 as GLM_CODING_PLAN_ROUTE_PROVIDER_ID, PROVIDER_NAME$1 as GLM_CODING_PLAN_ROUTE_PROVIDER_NAME, GLM_MODEL_CATALOG, GLM_MODEL_IDS, GLM_POOL_COOLDOWN_MS, GlmAdoptedCredentialRefreshError, GlmCodingPlanAccountPool, GlmCodingPlanAdapter, GlmCodingPlanCredentialStore, GlmCodingPlanModelSettingsStore, KIMI_CODE_MODELS, KIMI_CODE_RETRY_POLICY_CONFIG, KimiCodeAccountPool, KimiCodeAdapter, FileCredentialStore$3 as KimiCodeCredentialStore, FileModelSettingsStore$3 as KimiCodeModelSettingsStore, LinuxFileTokenStore, AGENT_LLM_PREFIX as MINIMAX_CODE_AGENT_LLM_PREFIX, DEFAULT_MAX_MESSAGE_BODY_BYTES as MINIMAX_CODE_MAX_MESSAGE_BODY_BYTES, MESSAGES_PATH$1 as MINIMAX_CODE_MESSAGES_PATH, MINIMAX_CODE_MODELS, PROBE_MODEL as MINIMAX_CODE_PROBE_MODEL, MINIMAX_CODE_PROVIDER_ID, MINIMAX_CODE_PROVIDER_NAME, MINIMAX_CODE_REASONING_EFFORTS, REGION_HOSTS as MINIMAX_CODE_REGION_HOSTS, MINIMAX_CODE_RETRY_POLICY_CONFIG, MINIMAX_CODE_ROUTE_PREFIX, MacKeychainTokenStore, MinimaxCodeAccountPool, MinimaxCodeAdapter, MinimaxCodeCheckinService, MinimaxCodeCredentialStore, MinimaxCodeModelSettingsStore, OAuthService, ProxyManager, RELAY_PROBE_ENV, RELAY_PROBE_FILE_ENV, RELAY_PROBE_FILE_NAME, RELAY_PROBE_MAX_BYTES, RELAY_SOURCE_KINDS, RESUME_HINT, RESUME_HINT_STRICT, RelayProbe, ResponsesClient, STEP_CODE_POOL_COOLDOWN_MS, STEP_CODE_PROFILES, STEP_CODE_PROVIDER_ID, STEP_CODE_PROVIDER_NAME, STEP_CODE_RETRY_POLICY_CONFIG, STEP_CODE_ROUTE_PREFIX, SUBAGENT_MODEL_SELECTION_NAMESPACE, SUBAGENT_POLICY_EVENT, SearchProviderSwitcher, StepCodeAccountPool, StepCodeAdapter, StepCodeCredentialRefreshError, StepCodeCredentialStore, StepCodeModelSettingsStore, StepCodeQuotaCredentialStore, UsageService, FALLBACK_MODELS$1 as WORKBUDDY_MODELS, WORKBUDDY_MODEL_IDS, WindowsDpapiTokenStore, WorkBuddyAdapter, WorkBuddyCheckinService, FileCredentialStore$4 as WorkBuddyCredentialStore, FileModelSettingsStore$4 as WorkBuddyModelSettingsStore, adoptZcodeSignIn as adoptGlmZcodeSignIn, adoptedPoolAccountKey, apply, assertRequestBodyFits as assertMinimaxCodeBodyFits, assertStreamComplete as assertMinimaxCodeStreamComplete, auditChildRoutes, auditedRoutesOf, authorizedRoutesFor, beginLogin as beginClaudeLogin, beginWebLogin as beginKimiCodeLogin, beginWebLogin$1 as beginMinimaxCodeLogin, beginWebLogin$2 as beginWebLogin, buildClaudeModelOptions, buildGlmRequestPlan, buildMinimaxCodeModelOptions, buildMinimaxRequest, cachedStepCodeModelCatalog, cancelLogin as cancelClaudeLogin, cancelWebLogin as cancelMinimaxCodeLogin, catalogModelOptions, childRoutesOf, clampOutputToContext as clampMinimaxCodeOutputToContext, classifyFailure as classifyClaudeFailure, classifyKimiFailure, classifyMinimaxFailure, classifyFailure$1 as classifyWorkBuddyFailure, claudeCliVersion, claudeCodeCredentialPaths, claudeCodeCredentialPresence, codeForFailure as claudeCodeForFailure, credentialPath as claudeCredentialPath, defaultContextWindowFor as claudeDefaultContextWindow, maxOutputTokensFor as claudeMaxOutputTokens, claudeModelCanDisableThinking, modelSettingsPath as claudeModelSettingsPath, claudeModelSupportsImage, claudeModelSupportsTemperature, claudePoolPath, claudeReasoningEfforts, claudeThinkingMode, toLlmError as claudeToLlmError, clearCachedQuota, clearCachedCatalog as clearClaudeCatalog, clearCachedQuota$1 as clearClaudeQuota, clearCachedQuota$2 as clearCommandCodeQuota, clearCachedQuota$3 as clearKimiCodeQuota, clearCachedQuota$4 as clearMinimaxCodeQuota, clearCachedCatalog$1 as clearWorkBuddyCatalog, clearCachedQuota$5 as clearWorkBuddyQuota, closeMinimaxStream, codeBuddyAuthDir, codexPoolPath, collapseScore, commandCodeAccountKey, credentialPath$1 as commandCodeCredentialPath, modelSettingsPath$1 as commandCodeModelSettingsPath, commandCodePoolPath, contextWindowForModel, convergeGlmEffort, createCodexFetchProvider, createCodexImageTool, createCodexSearchProvider, createFileRelayProbeSink, createMinimaxCodeAccountsHandler, createMessage as createMinimaxCodeMessage, createPkcePair as createMinimaxCodePkcePair, createStreamState as createMinimaxCodeStreamState, createPlatformTokenStore, createSubagentAuthorization, credentialPath$2 as credentialPath, credentialsFromAdopt, credentialsFromCliLogin, delegationDenialReason, delegationModeOf, describeCredentials as describeMinimaxCodeCredentials, detectSystemProxy, dshHomeDir, effectiveRouteOf, ensureAccessToken as ensureClaudeAccessToken, ensureAccessToken$1 as ensureKimiCodeAccessToken, ensureAccessToken$2 as ensureMinimaxCodeAccessToken, fetchAccountQuota, fetchAccountQuota$1 as fetchClaudeQuota, fetchAccountQuota$2 as fetchCommandCodeQuota, fetchGlmQuota, fetchAccountQuota$3 as fetchKimiCodeQuota, fetchUserInfo as fetchKimiCodeUserInfo, fetchTokenPlanQuota as fetchMinimaxCodeQuota, fetchAccountQuota$4 as fetchWorkBuddyQuota, getCachedQuota as getCachedGlmCodingPlanQuota, getCachedQuota$1 as getCachedQuota, getLoginStatus as getClaudeLoginStatus, getCachedQuota$2 as getClaudeQuota, getClaudeWebStatus, getWebLoginStatus as getCommandCodeLoginStatus, getCachedQuota$3 as getCommandCodeQuota, getCommandCodeWebStatus, getGlmCodingPlanStatus, getWebLoginStatus$1 as getKimiCodeLoginStatus, getCachedQuota$4 as getKimiCodeQuota, getKimiCodeWebStatus, getWebLogin as getMinimaxCodeLogin, getCachedQuota$5 as getMinimaxCodeQuota, getMinimaxCodeWebStatus, getStepCodeStatus, getCachedQuota$6 as getWorkBuddyQuota, getWorkBuddyWebStatus, glmCatalogSize, authorizeUrl as glmCodingPlanAuthorizeUrl, catalogSize as glmCodingPlanCatalogCount, credentialPath$3 as glmCodingPlanCredentialPath, modelSettingsPath$2 as glmCodingPlanModelSettingsPath, modelsForRegion as glmCodingPlanModelsForRegion, glmCodingPlanPoolIdentity, glmCodingPlanPoolPath, glmCodingPlanPoolQuota, glmCodingPlanPoolStatus, glmCodingPlanSettingsSource, glmCooldownDecision, glmSubPathOf, inheritOverrideReason, inheritRouteDenialReason, inheritedRouteOf, inject, installReasoningCollapseGuard, installRelayProbe, installSubagentModelAuthorization, isAdoptedClaudeCredential, isAdoptedCredentialExpired, isAdoptedCredential as isAdoptedGlmCodingPlanCredential, isAdoptedZcodeCredential as isAdoptedGlmZcodeCredential, isAdoptedPoolCredential, isClaudeReasoningEffort, isGlmReasoningEffort, isMinimaxCodeReasoningEffort, isRefreshTokenRejected as isMinimaxCodeRefreshTokenRejected, isThinkingDisabledEffort, credentialPath$4 as kimiCodeCredentialPath, kimiCodeModelDef, modelSettingsPath$3 as kimiCodeModelSettingsPath, kimiCodePoolPath, listModelIds as listMinimaxCodeModelIds, loadCatalog as loadClaudeCatalog, loadProviderModels as loadCommandCodeModels, loadCatalog$1 as loadGlmCodingPlanCatalog, loadProviderModels$1 as loadKimiCodeModels, loadConfigCatalog as loadWorkBuddyModels, loginAndSave, mapCodexUsage, mergeGlmCodingPlanSettings, accountFromCredentials as minimaxCodeAccountFromCredentials, accountHost as minimaxCodeAccountHost, agentBaseUrl as minimaxCodeAgentBaseUrl, authJsonPath as minimaxCodeAuthJsonPath, authStateJsonPath as minimaxCodeAuthStateJsonPath, catalogSize$1 as minimaxCodeCatalogSize, credentialIsFresh as minimaxCodeCredentialIsFresh, effortForModel as minimaxCodeEffortForModel, minimaxHomeDir as minimaxCodeHomeDir, maxMessageBodyBytes as minimaxCodeMaxMessageBodyBytes, maxOutputTokensFor$1 as minimaxCodeMaxOutputTokens, messagesUrl as minimaxCodeMessagesUrl, minimaxCodeModelDef, minimaxCodeModelIds, minimaxCodeModelName, modelRequestHeaders as minimaxCodeModelRequestHeaders, modelSettingsPath$4 as minimaxCodeModelSettingsPath, outputConfigFor as minimaxCodeOutputConfig, pluginCredentialPath as minimaxCodePluginCredentialPath, minimaxCodePoolIdentity, minimaxCodePoolPath, minimaxCodePoolStatus, quotaHostCandidates as minimaxCodeQuotaHostCandidates, quotaRequestHeaders as minimaxCodeQuotaRequestHeaders, subPathOf as minimaxCodeSubPathOf, tokenPlanRemainsUrl as minimaxCodeTokenPlanRemainsUrl, modelSettingsPath$5 as modelSettingsPath, normalizeDelegationToolNames, normalizeRegion as normalizeGlmCodingPlanRegion, normalizeInheritToolNames, normalizeRotationStrategy, parseAllowedRoutes, parseClaudeCredentialDocument, parseClaudeCredentials, parseClaudePoolData, parseUsagePayload as parseClaudeUsagePayload, parseCodexPoolData, parseCodexUsage, parseCommandCodePoolData, parseGlmCodingPlanCredentials, parseGlmCodingPlanPoolData, parseKimiCodePoolData, parseMinimaxCodeCredentials, parseMinimaxCodePoolData, parseTokenPlanQuota as parseMinimaxCodeQuota, parseAnthropicUsage as parseMinimaxCodeUsage, parseResponsesStream, parseBilling as parseWorkBuddyBilling, parseConfigModels as parseWorkBuddyConfigModels, parseCredentialFile as parseWorkBuddyCredential, policyRoutesOf, pollWebLogin as pollMinimaxCodeLogin, probeConnection as probeClaudeConnection, processMinimaxStreamLine, readChildDescriptor, readClaudeCodeCredentials, readGlmResetAt, readStepCodeCacheStats, redactToken as redactMinimaxCodeToken, refreshAntigravityToken, refreshAccessToken as refreshClaudeToken, refreshAccessToken$1 as refreshKimiCodeToken, refreshAccessToken$2 as refreshMinimaxCodeToken, refreshCredentials as refreshWorkBuddyCredentials, registerClaudePreferenceStore, registerClaudeRoutes, registerCommandCodePreferenceStore, registerCommandCodeRoutes, registerGlmCodingPlanPreferenceStore, registerGlmCodingPlanRoutes, registerKimiCodePreferenceStore, registerKimiCodeRoutes, registerMinimaxCodePreferenceStore, registerMinimaxCodeRoutes, registerStepCodePreferenceStore, registerStepCodeRoutes, registerWorkBuddyPreferenceStore, registerWorkBuddyRoutes, relayProbeEnabled, relayProbeEnvFile, relayProbeEnvValue, relayProbeLogPath, rememberStepCodeCacheUsage, requestDeviceAuthorization as requestKimiCodeDeviceAuthorization, requestDeviceAuthorization$1 as requestMinimaxCodeDeviceAuthorization, resetWebLogins as resetMinimaxCodeLogins, resolveEnabledModelIds as resolveClaudeEnabledModelIds, resolveLoginInput as resolveClaudeLoginInput, resolveClaudeModel, resolveGlmModel, resolveGuardOptions, resolveRegion as resolveKimiCodeRegion, resolveMinimaxCodeEnabledModelIds, resolveQuotaCounts as resolveMinimaxCodeQuotaCounts, resolveWorkBuddyModel, revokeToken as revokeMinimaxCodeToken, saveApiKey as saveCommandCodeApiKey, scanCredentials as scanWorkBuddyCredentials, setClaudeCliVersion, beginWebLogin$3 as startCommandCodeLogin, stepCodeCatalogSize, credentialPath$5 as stepCodeCredentialPath, stepCodeModelCatalogFrom, modelSettingsPath$6 as stepCodeModelSettingsPath, stepCodePoolIdentity, stepCodePoolPath, stepCodePoolQuota, stepCodePoolStatus, stepCodePoolStatusSlice, quotaCredentialPath as stepCodeQuotaCredentialPath, stepCodeSettingsSource, stepCodeSubPathOf, subagentModelSelectionPreference, submitLoginInput as submitClaudeLoginInput, summarizeFailureBody as summarizeMinimaxCodeFailureBody, testConnection as testMinimaxCodeConnection, unauthorizedRouteReason, validateAuthorizationScope, validateDelegationToolNames, validateInheritToolNames, verifyCodingPlanKey as verifyGlmCodingPlanKey, violationText, modelSettingsPath$7 as workBuddyModelSettingsPath, modelsForRegion$1 as workBuddyModelsForRegion, zcodeCredentialsPath };
|