@lyogvce/dsh-codex-subscription 0.2.4 → 0.2.5
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/lib/client.js +1 -0
- package/lib/index.d.ts +28 -24
- package/lib/index.js +119 -81
- package/package.json +1 -1
package/lib/client.js
CHANGED
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
import { PiCodexModel } from "@earendil-works/pi-ai/providers/openai-codex";
|
|
2
|
+
//#region src/host-types.d.ts
|
|
3
|
+
interface LlmServiceLike {
|
|
4
|
+
registerAdapter: (providers: string[], adapter: unknown) => (() => void) & {
|
|
5
|
+
replace?: (next: string[]) => void;
|
|
6
|
+
};
|
|
7
|
+
emitAdaptersUpdated?: () => void;
|
|
8
|
+
}
|
|
9
|
+
type PluginLogLevel = 'INFO' | 'WARN' | 'ERROR';
|
|
10
|
+
type PluginLogFn = (level: PluginLogLevel, event: string, detail: Record<string, unknown>) => void;
|
|
11
|
+
interface LoggerLike {
|
|
12
|
+
info?: (message: string) => void;
|
|
13
|
+
warn?: (message: string) => void;
|
|
14
|
+
error?: (message: string) => void;
|
|
15
|
+
}
|
|
16
|
+
interface PluginContextLike {
|
|
17
|
+
llm: LlmServiceLike;
|
|
18
|
+
logger?: LoggerLike | undefined;
|
|
19
|
+
get?: (name: string) => unknown;
|
|
20
|
+
on?: (event: string, listener: () => void) => () => void;
|
|
21
|
+
effect?: (factory: () => void | (() => void), label?: string) => () => void;
|
|
22
|
+
inject?: (services: readonly string[], callback: (ctx: PluginContextLike) => void) => () => void;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
2
25
|
//#region src/auth.d.ts
|
|
3
26
|
interface CodexAuthTokens {
|
|
4
27
|
access_token?: string;
|
|
@@ -19,7 +42,7 @@ interface JwtClaims {
|
|
|
19
42
|
interface AuthManagerOptions {
|
|
20
43
|
getCodexHome: () => string;
|
|
21
44
|
getClientVersion?: (() => string) | undefined;
|
|
22
|
-
onLog?:
|
|
45
|
+
onLog?: PluginLogFn | undefined;
|
|
23
46
|
fetchImpl?: typeof fetch | undefined;
|
|
24
47
|
now?: (() => number) | undefined;
|
|
25
48
|
}
|
|
@@ -36,6 +59,7 @@ declare function createAuthManager(options: AuthManagerOptions): {
|
|
|
36
59
|
};
|
|
37
60
|
//#endregion
|
|
38
61
|
//#region src/catalog.d.ts
|
|
62
|
+
export declare const BACKUP_CACHE_FILE_NAME = ".dsh-models-cache-backup.json";
|
|
39
63
|
interface RawReasoningLevel {
|
|
40
64
|
effort?: string;
|
|
41
65
|
description?: string;
|
|
@@ -59,6 +83,7 @@ interface RawModelsCache {
|
|
|
59
83
|
client_version?: string;
|
|
60
84
|
models?: RawCodexModelEntry[];
|
|
61
85
|
}
|
|
86
|
+
declare function parseRawModelsCache(rawText: string): RawModelsCache;
|
|
62
87
|
declare function compareClientVersions(a: string | undefined, b: string | undefined): number;
|
|
63
88
|
interface CodexModelMetadata {
|
|
64
89
|
readonly contextWindow: number;
|
|
@@ -115,32 +140,10 @@ declare function createUsageFetcher(options: UsageFetcherOptions): {
|
|
|
115
140
|
invalidate: () => void;
|
|
116
141
|
};
|
|
117
142
|
//#endregion
|
|
118
|
-
//#region src/host-types.d.ts
|
|
119
|
-
interface LlmServiceLike {
|
|
120
|
-
registerAdapter: (providers: string[], adapter: unknown) => (() => void) & {
|
|
121
|
-
replace?: (next: string[]) => void;
|
|
122
|
-
};
|
|
123
|
-
emitAdaptersUpdated?: () => void;
|
|
124
|
-
}
|
|
125
|
-
interface LoggerLike {
|
|
126
|
-
info?: (message: string) => void;
|
|
127
|
-
warn?: (message: string) => void;
|
|
128
|
-
error?: (message: string) => void;
|
|
129
|
-
}
|
|
130
|
-
interface PluginContextLike {
|
|
131
|
-
llm: LlmServiceLike;
|
|
132
|
-
logger?: LoggerLike | undefined;
|
|
133
|
-
get?: (name: string) => unknown;
|
|
134
|
-
on?: (event: string, listener: () => void) => () => void;
|
|
135
|
-
effect?: (factory: () => void | (() => void), label?: string) => () => void;
|
|
136
|
-
inject?: (services: readonly string[], callback: (ctx: PluginContextLike) => void) => () => void;
|
|
137
|
-
}
|
|
138
|
-
//#endregion
|
|
139
143
|
//#region src/index.d.ts
|
|
140
144
|
export declare const name = "codex-subscription";
|
|
141
145
|
export declare const inject: string[];
|
|
142
146
|
export declare const LOG_FILE_NAME = "dsh-codex-subscription.log";
|
|
143
|
-
export declare const BACKUP_CACHE_FILE_NAME = ".dsh-models-cache-backup.json";
|
|
144
147
|
export declare const Config: any;
|
|
145
148
|
export declare function apply(ctx: PluginContextLike, config?: Record<string, unknown>): void;
|
|
146
149
|
export declare const __test: Readonly<{
|
|
@@ -159,6 +162,7 @@ export declare const __test: Readonly<{
|
|
|
159
162
|
buildThinkingLevelMap: typeof buildThinkingLevelMap;
|
|
160
163
|
compareClientVersions: typeof compareClientVersions;
|
|
161
164
|
parseModelsCache: typeof parseModelsCache;
|
|
165
|
+
parseRawModelsCache: typeof parseRawModelsCache;
|
|
162
166
|
sanitizeCodexPayload: typeof sanitizeCodexPayload;
|
|
163
167
|
buildCodexHeaders: typeof buildCodexHeaders;
|
|
164
168
|
buildCodexUserAgent: typeof buildCodexUserAgent;
|
|
@@ -167,4 +171,4 @@ export declare const __test: Readonly<{
|
|
|
167
171
|
createUsageFetcher: typeof createUsageFetcher;
|
|
168
172
|
}>;
|
|
169
173
|
//#endregion
|
|
170
|
-
export type { CodexModelMetadata, CodexQuotaResponse, CodexQuotaSnapshot, CodexQuotaWindow, CodexResolvedCredentials, ParsedModelsCatalog, PluginContextLike, RawModelsCache };
|
|
174
|
+
export type { CodexModelMetadata, CodexQuotaResponse, CodexQuotaSnapshot, CodexQuotaWindow, CodexResolvedCredentials, ParsedModelsCatalog, PluginContextLike, PluginLogLevel, RawModelsCache };
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { appendFileSync, chmodSync, readFileSync, realpathSync, statSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { dirname, join, resolve } from "node:path";
|
|
1
|
+
import { appendFileSync, chmodSync, readFileSync, realpathSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
3
3
|
import z from "@deepseek-ai/schemastery";
|
|
4
4
|
import { LlmError, resolveImageAttachmentAccess, resolveRetryPolicy } from "@deepseek-ai/dsh-llm";
|
|
5
5
|
import { PiAiAdapter } from "@deepseek-ai/dsh-llm-pi-ai";
|
|
@@ -13,6 +13,7 @@ const PROVIDER = "openai-codex";
|
|
|
13
13
|
const DISPLAY_NAME = "Codex";
|
|
14
14
|
const DEFAULT_CLIENT_VERSION = "0.163.0";
|
|
15
15
|
const DEFAULT_CONTEXT_WINDOW = 872e3;
|
|
16
|
+
const BACKUP_CACHE_FILE_NAME = ".dsh-models-cache-backup.json";
|
|
16
17
|
const THINKING_LEVELS = [
|
|
17
18
|
"off",
|
|
18
19
|
"minimal",
|
|
@@ -29,6 +30,11 @@ const DEFAULT_DISABLED_MODELS = Object.freeze([
|
|
|
29
30
|
"gpt-5.6-terra",
|
|
30
31
|
"gpt-5.6-luna"
|
|
31
32
|
]);
|
|
33
|
+
function parseRawModelsCache(rawText) {
|
|
34
|
+
const parsed = JSON.parse(rawText);
|
|
35
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) throw new SyntaxError("models_cache.json root must be a JSON object");
|
|
36
|
+
return parsed;
|
|
37
|
+
}
|
|
32
38
|
function compareClientVersions(a, b) {
|
|
33
39
|
const parseParts = (ver) => typeof ver === "string" && ver.trim() !== "" ? ver.trim().split(/[^0-9]+/u).filter(Boolean).map((n) => Number.parseInt(n, 10)) : [];
|
|
34
40
|
const pa = parseParts(a);
|
|
@@ -362,11 +368,35 @@ function extractAccountId(parsed, accessToken) {
|
|
|
362
368
|
if (typeof jwtAccountId === "string" && jwtAccountId.trim() !== "") return jwtAccountId.trim();
|
|
363
369
|
}
|
|
364
370
|
}
|
|
365
|
-
|
|
366
|
-
let targetPath = filePath;
|
|
371
|
+
function resolveRealTargetPath(filePath) {
|
|
367
372
|
try {
|
|
368
|
-
|
|
369
|
-
} catch {
|
|
373
|
+
return realpathSync(filePath);
|
|
374
|
+
} catch {
|
|
375
|
+
try {
|
|
376
|
+
return join(realpathSync(dirname(filePath)), basename(filePath));
|
|
377
|
+
} catch {
|
|
378
|
+
return filePath;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
function writeFileAtomicSync(filePath, content) {
|
|
383
|
+
const targetPath = resolveRealTargetPath(filePath);
|
|
384
|
+
const tempPath = join(dirname(targetPath), `.${basename(targetPath)}.tmp-${process.pid}-${randomUUID()}`);
|
|
385
|
+
try {
|
|
386
|
+
writeFileSync(tempPath, content, { mode: 384 });
|
|
387
|
+
try {
|
|
388
|
+
chmodSync(tempPath, 384);
|
|
389
|
+
} catch {}
|
|
390
|
+
renameSync(tempPath, targetPath);
|
|
391
|
+
} catch (error) {
|
|
392
|
+
try {
|
|
393
|
+
unlinkSync(tempPath);
|
|
394
|
+
} catch {}
|
|
395
|
+
throw error;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
async function writeJsonAtomic(filePath, data) {
|
|
399
|
+
const targetPath = resolveRealTargetPath(filePath);
|
|
370
400
|
const tempPath = join(dirname(targetPath), `.auth.json.tmp-${process.pid}-${randomUUID()}`);
|
|
371
401
|
const content = `${JSON.stringify(data, null, 2)}\n`;
|
|
372
402
|
await writeFile(tempPath, content, {
|
|
@@ -431,25 +461,34 @@ function createAuthManager(options) {
|
|
|
431
461
|
return exp * 1e3 - nowFn() > TOKEN_REFRESH_LEAD_MS;
|
|
432
462
|
}
|
|
433
463
|
async function refreshToken(authPath, rawAuth) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
464
|
+
let fresh;
|
|
465
|
+
try {
|
|
466
|
+
const refreshTok = rawAuth?.tokens?.refresh_token;
|
|
467
|
+
if (typeof refreshTok !== "string" || refreshTok.trim() === "") throw new LlmError("Codex 凭证已过期且缺少 refresh_token,请重新运行 codex login", "AUTH_FAILED");
|
|
468
|
+
const response = await fetchFn(CODEX_TOKEN_URL, {
|
|
469
|
+
method: "POST",
|
|
470
|
+
headers: buildCodexHeaders({
|
|
471
|
+
"Content-Type": "application/json",
|
|
472
|
+
Accept: "application/json"
|
|
473
|
+
}, options.getClientVersion?.()),
|
|
474
|
+
body: JSON.stringify({
|
|
475
|
+
client_id: CODEX_CLIENT_ID,
|
|
476
|
+
grant_type: "refresh_token",
|
|
477
|
+
refresh_token: refreshTok,
|
|
478
|
+
scope: "openid profile email"
|
|
479
|
+
}),
|
|
480
|
+
signal: AbortSignal.timeout(TOKEN_REFRESH_TIMEOUT_MS)
|
|
481
|
+
});
|
|
482
|
+
if (!response.ok) throw new LlmError(`Codex Token 刷新失败 (HTTP ${response.status}),请重新运行 codex login`, "AUTH_FAILED");
|
|
483
|
+
fresh = await response.json();
|
|
484
|
+
if (typeof fresh?.access_token !== "string" || fresh.access_token.trim() === "") throw new LlmError("Codex Token 刷新响应缺少 access_token", "AUTH_FAILED");
|
|
485
|
+
} catch (error) {
|
|
486
|
+
options.onLog?.("ERROR", "auth.refresh_failed", {
|
|
487
|
+
authPath,
|
|
488
|
+
error: safeErrorMessage(error)
|
|
489
|
+
});
|
|
490
|
+
throw error;
|
|
491
|
+
}
|
|
453
492
|
const nextAuth = {
|
|
454
493
|
...rawAuth,
|
|
455
494
|
tokens: {
|
|
@@ -514,7 +553,6 @@ function createAuthManager(options) {
|
|
|
514
553
|
const name = "codex-subscription";
|
|
515
554
|
const inject = ["llm"];
|
|
516
555
|
const LOG_FILE_NAME = "dsh-codex-subscription.log";
|
|
517
|
-
const BACKUP_CACHE_FILE_NAME = ".dsh-models-cache-backup.json";
|
|
518
556
|
const STREAM_IDLE_TIMEOUT_MS = 3e5;
|
|
519
557
|
const MAX_REQUEST_IMAGE_BYTES = 20971520;
|
|
520
558
|
const REQUEST_IMAGE_PIXEL_BUDGET = 4194304;
|
|
@@ -532,11 +570,10 @@ function appendPluginLog(codexHome, ctx, level, event, detail) {
|
|
|
532
570
|
const logPath = join(codexHome, LOG_FILE_NAME);
|
|
533
571
|
try {
|
|
534
572
|
if (statSync(logPath).size > MAX_LOG_FILE_BYTES) {
|
|
535
|
-
const
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
});
|
|
573
|
+
const buf = readFileSync(logPath);
|
|
574
|
+
const halfOffset = Math.max(0, buf.length - Math.floor(MAX_LOG_FILE_BYTES / 2));
|
|
575
|
+
const newlineIdx = buf.indexOf(10, halfOffset);
|
|
576
|
+
writeFileAtomicSync(logPath, buf.subarray(newlineIdx >= 0 && newlineIdx + 1 < buf.length ? newlineIdx + 1 : halfOffset));
|
|
540
577
|
}
|
|
541
578
|
} catch {}
|
|
542
579
|
appendFileSync(logPath, line, {
|
|
@@ -547,19 +584,14 @@ function appendPluginLog(codexHome, ctx, level, event, detail) {
|
|
|
547
584
|
}
|
|
548
585
|
function readBackupCache(codexHome) {
|
|
549
586
|
try {
|
|
550
|
-
return
|
|
587
|
+
return parseRawModelsCache(readFileSync(join(codexHome, BACKUP_CACHE_FILE_NAME), "utf8"));
|
|
551
588
|
} catch {
|
|
552
589
|
return;
|
|
553
590
|
}
|
|
554
591
|
}
|
|
555
592
|
function writeBackupCache(codexHome, raw) {
|
|
556
593
|
try {
|
|
557
|
-
|
|
558
|
-
if (existing && compareClientVersions(raw.client_version, existing.client_version) < 0) return;
|
|
559
|
-
writeFileSync(join(codexHome, BACKUP_CACHE_FILE_NAME), `${JSON.stringify(raw, null, 2)}\n`, {
|
|
560
|
-
encoding: "utf8",
|
|
561
|
-
mode: 384
|
|
562
|
-
});
|
|
594
|
+
writeFileAtomicSync(join(codexHome, BACKUP_CACHE_FILE_NAME), `${JSON.stringify(raw, null, 2)}\n`);
|
|
563
595
|
} catch {}
|
|
564
596
|
}
|
|
565
597
|
const Config = z.object({
|
|
@@ -609,7 +641,7 @@ function apply(ctx, config = {}) {
|
|
|
609
641
|
});
|
|
610
642
|
let fileSignature;
|
|
611
643
|
let cachedRaw;
|
|
612
|
-
let
|
|
644
|
+
let rawRevision = 0;
|
|
613
645
|
let snapshotSignature;
|
|
614
646
|
let currentCatalog = {
|
|
615
647
|
clientVersion: DEFAULT_CLIENT_VERSION,
|
|
@@ -670,31 +702,54 @@ function apply(ctx, config = {}) {
|
|
|
670
702
|
const cachePath = join(codexHome, "models_cache.json");
|
|
671
703
|
const disabled = getDisabledModels();
|
|
672
704
|
const contextWindows = getContextWindows();
|
|
705
|
+
const setActiveRaw = (next) => {
|
|
706
|
+
cachedRaw = next;
|
|
707
|
+
rawRevision += 1;
|
|
708
|
+
};
|
|
709
|
+
const tryRestoreFromBackup = (extra, minVersion) => {
|
|
710
|
+
const backupRaw = readBackupCache(codexHome);
|
|
711
|
+
if (backupRaw === void 0 || minVersion !== void 0 && compareClientVersions(backupRaw.client_version, minVersion) <= 0) return false;
|
|
712
|
+
setActiveRaw(backupRaw);
|
|
713
|
+
appendPluginLog(codexHome, ctx, "WARN", "catalog.backup_restored", {
|
|
714
|
+
cachePath,
|
|
715
|
+
...extra,
|
|
716
|
+
restoredVersion: backupRaw.client_version ?? "0.163.0",
|
|
717
|
+
restoredFetchedAt: backupRaw.fetched_at ?? null
|
|
718
|
+
});
|
|
719
|
+
return true;
|
|
720
|
+
};
|
|
721
|
+
const handleReadError = (error) => {
|
|
722
|
+
if (cachedRaw === void 0) tryRestoreFromBackup({ reason: safeErrorMessage(error) });
|
|
723
|
+
appendPluginLog(codexHome, ctx, cachedRaw === void 0 ? "ERROR" : "WARN", "catalog.read_error", {
|
|
724
|
+
cachePath,
|
|
725
|
+
hasFallbackSnapshot: cachedRaw !== void 0,
|
|
726
|
+
error: safeErrorMessage(error)
|
|
727
|
+
});
|
|
728
|
+
};
|
|
729
|
+
let stat;
|
|
673
730
|
try {
|
|
674
|
-
|
|
731
|
+
stat = statSync(cachePath);
|
|
732
|
+
} catch (error) {
|
|
733
|
+
const missingSig = `missing:${cachePath}:${error?.code ?? "ERR"}`;
|
|
734
|
+
if (missingSig !== fileSignature) {
|
|
735
|
+
fileSignature = missingSig;
|
|
736
|
+
handleReadError(error);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
if (stat !== void 0) {
|
|
675
740
|
const nextFileSig = `${cachePath}:${stat.mtimeMs}:${stat.size}`;
|
|
676
741
|
if (nextFileSig !== fileSignature) {
|
|
677
|
-
const incomingRaw = JSON.parse(readFileSync(cachePath, "utf8"));
|
|
678
742
|
fileSignature = nextFileSig;
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
cachedRaw = backupRaw;
|
|
690
|
-
appendPluginLog(codexHome, ctx, "WARN", "catalog.backup_restored", {
|
|
691
|
-
cachePath,
|
|
692
|
-
diskVersion: incomingRaw.client_version ?? "unknown",
|
|
693
|
-
restoredVersion: backupRaw.client_version ?? "0.163.0",
|
|
694
|
-
restoredFetchedAt: backupRaw.fetched_at ?? null
|
|
695
|
-
});
|
|
696
|
-
} else {
|
|
697
|
-
cachedRaw = incomingRaw;
|
|
743
|
+
try {
|
|
744
|
+
const incomingRaw = parseRawModelsCache(readFileSync(cachePath, "utf8"));
|
|
745
|
+
if (cachedRaw !== void 0 && compareClientVersions(incomingRaw.client_version, cachedRaw.client_version) < 0) appendPluginLog(codexHome, ctx, "WARN", "catalog.downgrade_rejected", {
|
|
746
|
+
cachePath,
|
|
747
|
+
keptVersion: cachedRaw.client_version ?? "0.163.0",
|
|
748
|
+
rejectedVersion: incomingRaw.client_version ?? "unknown",
|
|
749
|
+
incomingFetchedAt: incomingRaw.fetched_at ?? null
|
|
750
|
+
});
|
|
751
|
+
else if (cachedRaw !== void 0 || !tryRestoreFromBackup({ diskVersion: incomingRaw.client_version ?? "unknown" }, incomingRaw.client_version)) {
|
|
752
|
+
setActiveRaw(incomingRaw);
|
|
698
753
|
writeBackupCache(codexHome, incomingRaw);
|
|
699
754
|
appendPluginLog(codexHome, ctx, "INFO", "catalog.load", {
|
|
700
755
|
cachePath,
|
|
@@ -703,31 +758,13 @@ function apply(ctx, config = {}) {
|
|
|
703
758
|
rawModelCount: Array.isArray(incomingRaw.models) ? incomingRaw.models.length : 0
|
|
704
759
|
});
|
|
705
760
|
}
|
|
761
|
+
} catch (error) {
|
|
762
|
+
handleReadError(error);
|
|
706
763
|
}
|
|
707
764
|
}
|
|
708
|
-
} catch (error) {
|
|
709
|
-
if (cachedRaw === void 0) {
|
|
710
|
-
const backupRaw = readBackupCache(codexHome);
|
|
711
|
-
if (backupRaw !== void 0) {
|
|
712
|
-
cachedRaw = backupRaw;
|
|
713
|
-
appendPluginLog(codexHome, ctx, "WARN", "catalog.backup_restored", {
|
|
714
|
-
cachePath,
|
|
715
|
-
reason: safeErrorMessage(error),
|
|
716
|
-
restoredVersion: backupRaw.client_version ?? "0.163.0"
|
|
717
|
-
});
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
if (!warnedMissingFile) {
|
|
721
|
-
warnedMissingFile = true;
|
|
722
|
-
appendPluginLog(codexHome, ctx, cachedRaw === void 0 ? "ERROR" : "WARN", "catalog.read_error", {
|
|
723
|
-
cachePath,
|
|
724
|
-
hasFallbackSnapshot: cachedRaw !== void 0,
|
|
725
|
-
error: safeErrorMessage(error)
|
|
726
|
-
});
|
|
727
|
-
}
|
|
728
765
|
}
|
|
729
766
|
const nextSnapshotSig = JSON.stringify([
|
|
730
|
-
|
|
767
|
+
rawRevision,
|
|
731
768
|
disabled,
|
|
732
769
|
contextWindows
|
|
733
770
|
]);
|
|
@@ -833,6 +870,7 @@ const __test = Object.freeze({
|
|
|
833
870
|
buildThinkingLevelMap,
|
|
834
871
|
compareClientVersions,
|
|
835
872
|
parseModelsCache,
|
|
873
|
+
parseRawModelsCache,
|
|
836
874
|
sanitizeCodexPayload,
|
|
837
875
|
buildCodexHeaders,
|
|
838
876
|
buildCodexUserAgent,
|