@lyogvce/dsh-codex-subscription 0.2.7 → 0.2.8
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/README.md +1 -1
- package/lib/client.js +52 -14
- package/lib/index.d.ts +5 -3
- package/lib/index.js +44 -32
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
- 底层复用 DSH 内置的 `PiAiAdapter` 与 `@earendil-works/pi-ai` 的 `openaiCodexProvider()`,固定使用 `sse` 传输(含 `zstd` 请求体压缩、规范化纯 UUID `session-id` / `x-client-request-id` 缓存头、`reasoning.encrypted_content` 签名回放与图片自动缩放卸载)。
|
|
23
23
|
5. **Codex 订阅限额内联展示与 ⚡ Fast 极速模式一键切换(`conversation.input.right`)**
|
|
24
24
|
- 当会话选中 `openai-codex` 模型时,在输入框右下角紧邻模型选择器左侧展示限额胶囊(根据 `wham/usage` 返回的 `limit_window_seconds` 自适应展示 Plus 的 `5h X% · 7d Y%` 双窗口或 Pro 的 `7d X%` 单窗口,内置 60 秒缓存、单飞合并与每轮回复结束自动刷新),点击可展开查看对应窗口进度条、重置倒计时与手动刷新按钮;切换至其他 Provider 模型时自动隐藏。
|
|
25
|
-
- **⚡ Fast 极速模式(`service_tier: "priority"`,最高 2x
|
|
25
|
+
- **⚡ 会话级 Fast 极速模式(`service_tier: "priority"`,最高 2x 推理速度)**:每个会话可在限额弹窗底部独立开关 Fast 模式(互不影响,新会话默认继承插件设置中的 `fastMode`,未配置时默认 `false` 关闭),状态自动持久化至 `~/.codex/cache/dsh-codex-subscription/runtime-state.json`。开启后当前会话胶囊显示闪电标识 `⚡`,并在该会话请求体中自动注入 `"service_tier": "priority"`。
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
package/lib/client.js
CHANGED
|
@@ -13,6 +13,11 @@ window.__ModuleLoader__.load({
|
|
|
13
13
|
"gpt-5.6-terra",
|
|
14
14
|
"gpt-5.6-luna"
|
|
15
15
|
]);
|
|
16
|
+
function normalizeCodexSessionId(sessionId) {
|
|
17
|
+
if (typeof sessionId !== "string") return void 0;
|
|
18
|
+
const stripped = sessionId.trim().replace(/^session-/iu, "").trim();
|
|
19
|
+
return stripped.length > 0 ? stripped : void 0;
|
|
20
|
+
}
|
|
16
21
|
//#endregion
|
|
17
22
|
//#region src/usage.ts
|
|
18
23
|
function safeErrorMessage(error) {
|
|
@@ -25,8 +30,16 @@ window.__ModuleLoader__.load({
|
|
|
25
30
|
//#endregion
|
|
26
31
|
//#region src/client/quota.ts
|
|
27
32
|
const RING_CIRCUMFERENCE = 2 * Math.PI * 5.5;
|
|
33
|
+
const DEFAULT_SESSION_KEY = "__default__";
|
|
28
34
|
const DEFAULT_PRIMARY_WINDOW_SECONDS = 18e3;
|
|
29
35
|
const DEFAULT_SECONDARY_WINDOW_SECONDS = 604800;
|
|
36
|
+
function resolveSessionFastMode(snapshot, sessionId) {
|
|
37
|
+
if (!snapshot) return false;
|
|
38
|
+
const key = normalizeCodexSessionId(sessionId) ?? DEFAULT_SESSION_KEY;
|
|
39
|
+
const sessionVal = snapshot.sessionFastModes?.[key];
|
|
40
|
+
if (typeof sessionVal === "boolean") return sessionVal;
|
|
41
|
+
return snapshot.defaultFastMode === true;
|
|
42
|
+
}
|
|
30
43
|
function resolveActiveProvider(directorySnapshot, projectedSelection) {
|
|
31
44
|
const dir = directorySnapshot && typeof directorySnapshot === "object" ? directorySnapshot : void 0;
|
|
32
45
|
const proj = projectedSelection && typeof projectedSelection === "object" ? projectedSelection : void 0;
|
|
@@ -139,7 +152,8 @@ window.__ModuleLoader__.load({
|
|
|
139
152
|
const ttlMs = options.ttlMs ?? 6e4;
|
|
140
153
|
let state = {
|
|
141
154
|
quota: null,
|
|
142
|
-
|
|
155
|
+
defaultFastMode: false,
|
|
156
|
+
sessionFastModes: {},
|
|
143
157
|
loading: false,
|
|
144
158
|
error: null
|
|
145
159
|
};
|
|
@@ -152,6 +166,21 @@ window.__ModuleLoader__.load({
|
|
|
152
166
|
state = next;
|
|
153
167
|
for (const listener of listeners) listener();
|
|
154
168
|
}
|
|
169
|
+
function mergeFastStateFromPayload(payload, allowSessionReplace) {
|
|
170
|
+
const defaultFastMode = typeof payload?.defaultFastMode === "boolean" ? payload.defaultFastMode : state.defaultFastMode;
|
|
171
|
+
if (allowSessionReplace && payload?.sessionFastModes && typeof payload.sessionFastModes === "object" && !Array.isArray(payload.sessionFastModes)) {
|
|
172
|
+
const nextMap = {};
|
|
173
|
+
for (const [k, v] of Object.entries(payload.sessionFastModes)) if (typeof k === "string" && k !== "" && typeof v === "boolean") nextMap[k] = v;
|
|
174
|
+
return {
|
|
175
|
+
defaultFastMode,
|
|
176
|
+
sessionFastModes: nextMap
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
defaultFastMode,
|
|
181
|
+
sessionFastModes: state.sessionFastModes
|
|
182
|
+
};
|
|
183
|
+
}
|
|
155
184
|
async function refresh(force = false) {
|
|
156
185
|
if (!force && state.quota !== null && nowFn() - state.quota.fetchedAt < ttlMs) return;
|
|
157
186
|
if (inflight !== null && (!force || inflightForce)) return inflight;
|
|
@@ -181,10 +210,10 @@ window.__ModuleLoader__.load({
|
|
|
181
210
|
}
|
|
182
211
|
const payload = await response.json();
|
|
183
212
|
if (seq !== requestSeq) return;
|
|
184
|
-
const
|
|
213
|
+
const fastState = mergeFastStateFromPayload(payload, fastSeqAtStart === fastModeSeq);
|
|
185
214
|
if (payload && payload.ok === true && payload.quota) setState({
|
|
186
215
|
quota: payload.quota,
|
|
187
|
-
|
|
216
|
+
...fastState,
|
|
188
217
|
loading: false,
|
|
189
218
|
error: null
|
|
190
219
|
});
|
|
@@ -193,7 +222,7 @@ window.__ModuleLoader__.load({
|
|
|
193
222
|
const errMsg = payload && !payload.ok && typeof payload.error === "string" ? payload.error : "Invalid response";
|
|
194
223
|
setState({
|
|
195
224
|
quota: fallbackQuota ?? null,
|
|
196
|
-
|
|
225
|
+
...fastState,
|
|
197
226
|
loading: false,
|
|
198
227
|
error: errMsg
|
|
199
228
|
});
|
|
@@ -215,12 +244,16 @@ window.__ModuleLoader__.load({
|
|
|
215
244
|
inflight = task;
|
|
216
245
|
return task;
|
|
217
246
|
}
|
|
218
|
-
async function setFastMode(enabled) {
|
|
247
|
+
async function setFastMode(sessionId, enabled) {
|
|
219
248
|
const nextFastMode = Boolean(enabled);
|
|
249
|
+
const key = normalizeCodexSessionId(sessionId) ?? DEFAULT_SESSION_KEY;
|
|
220
250
|
const seq = ++fastModeSeq;
|
|
221
251
|
setState({
|
|
222
252
|
...state,
|
|
223
|
-
|
|
253
|
+
sessionFastModes: {
|
|
254
|
+
...state.sessionFastModes,
|
|
255
|
+
[key]: nextFastMode
|
|
256
|
+
}
|
|
224
257
|
});
|
|
225
258
|
try {
|
|
226
259
|
const response = await fetchFn(USAGE_ROUTE_PATH, {
|
|
@@ -229,13 +262,16 @@ window.__ModuleLoader__.load({
|
|
|
229
262
|
"Content-Type": "application/json",
|
|
230
263
|
Accept: "application/json"
|
|
231
264
|
},
|
|
232
|
-
body: JSON.stringify({
|
|
265
|
+
body: JSON.stringify({
|
|
266
|
+
sessionId: key,
|
|
267
|
+
fastMode: nextFastMode
|
|
268
|
+
})
|
|
233
269
|
});
|
|
234
270
|
if (seq !== fastModeSeq || !response.ok) return;
|
|
235
271
|
const payload = await response.json();
|
|
236
|
-
if (seq === fastModeSeq
|
|
272
|
+
if (seq === fastModeSeq) setState({
|
|
237
273
|
...state,
|
|
238
|
-
|
|
274
|
+
...mergeFastStateFromPayload(payload, true)
|
|
239
275
|
});
|
|
240
276
|
} catch {}
|
|
241
277
|
}
|
|
@@ -388,6 +424,7 @@ window.__ModuleLoader__.load({
|
|
|
388
424
|
})), h("div", { className: "dsh-codex-quota-meta" }, h("span", null, `${t("quota.remainPrefix")}${remainPercent}%`), countdown !== "" ? h("span", null, countdown) : null));
|
|
389
425
|
};
|
|
390
426
|
const quota = quotaSnap.quota;
|
|
427
|
+
const isFastMode = resolveSessionFastMode(quotaSnap, sessionId);
|
|
391
428
|
const secondaryReached = Boolean(quota?.secondary && quota.secondary.usedPercent >= 100);
|
|
392
429
|
const primaryReached = Boolean(quota?.limitReached && !secondaryReached);
|
|
393
430
|
return h("span", {
|
|
@@ -398,7 +435,7 @@ window.__ModuleLoader__.load({
|
|
|
398
435
|
type: "button",
|
|
399
436
|
className: "dsh-codex-quota-trigger",
|
|
400
437
|
"data-level": level,
|
|
401
|
-
"data-fast":
|
|
438
|
+
"data-fast": isFastMode ? "true" : void 0,
|
|
402
439
|
"aria-label": `${t("quota.title")}: ${pillText}`,
|
|
403
440
|
"aria-haspopup": "dialog",
|
|
404
441
|
"aria-expanded": open,
|
|
@@ -425,7 +462,7 @@ window.__ModuleLoader__.load({
|
|
|
425
462
|
r: 5.5,
|
|
426
463
|
strokeDasharray: ringDash,
|
|
427
464
|
transform: "rotate(-90 7 7)"
|
|
428
|
-
})),
|
|
465
|
+
})), isFastMode ? h("svg", {
|
|
429
466
|
className: "dsh-codex-quota-fast-bolt",
|
|
430
467
|
viewBox: "0 0 12 12",
|
|
431
468
|
width: 11,
|
|
@@ -461,11 +498,11 @@ window.__ModuleLoader__.load({
|
|
|
461
498
|
type: "button",
|
|
462
499
|
role: "switch",
|
|
463
500
|
className: "dsh-codex-fast-switch",
|
|
464
|
-
"aria-checked":
|
|
501
|
+
"aria-checked": isFastMode,
|
|
465
502
|
"aria-label": t("quota.fastTitle"),
|
|
466
|
-
"data-checked":
|
|
503
|
+
"data-checked": isFastMode ? "true" : "false",
|
|
467
504
|
onClick: () => {
|
|
468
|
-
quotaStore.setFastMode(!
|
|
505
|
+
quotaStore.setFastMode(sessionId, !isFastMode);
|
|
469
506
|
}
|
|
470
507
|
}, h("span", { className: "dsh-codex-fast-switch-thumb" }))), quotaSnap.error !== null ? h("div", { className: "dsh-codex-quota-error" }, quotaSnap.error) : null) : null);
|
|
471
508
|
}
|
|
@@ -518,6 +555,7 @@ window.__ModuleLoader__.load({
|
|
|
518
555
|
PROVIDER_ID: PROVIDER,
|
|
519
556
|
USAGE_API_PATH: USAGE_ROUTE_PATH,
|
|
520
557
|
resolveActiveProvider,
|
|
558
|
+
resolveSessionFastMode,
|
|
521
559
|
isCodexProvider,
|
|
522
560
|
didTurnFinish,
|
|
523
561
|
windowLevelOf,
|
package/lib/index.d.ts
CHANGED
|
@@ -93,6 +93,7 @@ interface RawModelsCache {
|
|
|
93
93
|
models?: RawCodexModelEntry[];
|
|
94
94
|
}
|
|
95
95
|
declare function parseRawModelsCache(rawText: string): RawModelsCache;
|
|
96
|
+
declare function normalizeCodexSessionId(sessionId: string | undefined): string | undefined;
|
|
96
97
|
declare function compareClientVersions(a: string | undefined, b: string | undefined): number;
|
|
97
98
|
interface CodexModelMetadata {
|
|
98
99
|
readonly contextWindow: number;
|
|
@@ -111,7 +112,6 @@ declare function parseModelsCache(rawCache: RawModelsCache | null | undefined, b
|
|
|
111
112
|
//#endregion
|
|
112
113
|
//#region src/request.d.ts
|
|
113
114
|
declare function buildCodexUserAgent(version?: string): string;
|
|
114
|
-
declare function normalizeCodexSessionId(sessionId: string | undefined): string | undefined;
|
|
115
115
|
declare function buildCodexHeaders(existingHeaders?: Record<string, string> | undefined, clientVersion?: string): Record<string, string>;
|
|
116
116
|
declare function sanitizeCodexPayload(payload: Record<string, unknown> | null | undefined, modelMeta?: CodexModelMetadata | undefined, fastMode?: boolean): Record<string, unknown> | null | undefined;
|
|
117
117
|
//#endregion
|
|
@@ -132,12 +132,14 @@ interface CodexQuotaSnapshot {
|
|
|
132
132
|
type CodexQuotaResponse = {
|
|
133
133
|
readonly ok: true;
|
|
134
134
|
readonly quota: CodexQuotaSnapshot;
|
|
135
|
-
readonly
|
|
135
|
+
readonly defaultFastMode?: boolean | undefined;
|
|
136
|
+
readonly sessionFastModes?: Readonly<Record<string, boolean>> | undefined;
|
|
136
137
|
} | {
|
|
137
138
|
readonly ok: false;
|
|
138
139
|
readonly error: string;
|
|
139
140
|
readonly quota?: CodexQuotaSnapshot | undefined;
|
|
140
|
-
readonly
|
|
141
|
+
readonly defaultFastMode?: boolean | undefined;
|
|
142
|
+
readonly sessionFastModes?: Readonly<Record<string, boolean>> | undefined;
|
|
141
143
|
};
|
|
142
144
|
interface UsageFetcherOptions {
|
|
143
145
|
readonly resolveCredentials: () => Promise<CodexResolvedCredentials>;
|
package/lib/index.js
CHANGED
|
@@ -37,6 +37,11 @@ function parseRawModelsCache(rawText) {
|
|
|
37
37
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) throw new SyntaxError("models_cache.json root must be a JSON object");
|
|
38
38
|
return parsed;
|
|
39
39
|
}
|
|
40
|
+
function normalizeCodexSessionId(sessionId) {
|
|
41
|
+
if (typeof sessionId !== "string") return void 0;
|
|
42
|
+
const stripped = sessionId.trim().replace(/^session-/iu, "").trim();
|
|
43
|
+
return stripped.length > 0 ? stripped : void 0;
|
|
44
|
+
}
|
|
40
45
|
function isSameModelsCatalogPayload(a, b) {
|
|
41
46
|
if (!a || !b) return false;
|
|
42
47
|
const { fetched_at: _fa, ...restA } = a;
|
|
@@ -194,11 +199,6 @@ function buildCodexUserAgent(version = DEFAULT_CLIENT_VERSION) {
|
|
|
194
199
|
const term = platform() === "darwin" ? "Apple_Terminal/455" : platform() === "win32" ? "WindowsTerminal" : "xterm-256color";
|
|
195
200
|
return `codex_cli_rs/${version} (${detectOsLabel()}; ${cpu}) ${term}`;
|
|
196
201
|
}
|
|
197
|
-
function normalizeCodexSessionId(sessionId) {
|
|
198
|
-
if (typeof sessionId !== "string") return void 0;
|
|
199
|
-
const stripped = sessionId.trim().replace(/^session-/iu, "").trim();
|
|
200
|
-
return stripped.length > 0 ? stripped : void 0;
|
|
201
|
-
}
|
|
202
202
|
function buildCodexHeaders(existingHeaders, clientVersion = DEFAULT_CLIENT_VERSION) {
|
|
203
203
|
const headers = {};
|
|
204
204
|
for (const [key, value] of Object.entries(existingHeaders ?? {})) {
|
|
@@ -586,6 +586,8 @@ const MAX_REQUEST_IMAGE_BYTES = 20971520;
|
|
|
586
586
|
const REQUEST_IMAGE_PIXEL_BUDGET = 4194304;
|
|
587
587
|
const REQUEST_IMAGE_MAX_BYTES = 1048576;
|
|
588
588
|
const MAX_LOG_FILE_BYTES = 524288;
|
|
589
|
+
const MAX_PERSISTED_SESSIONS = 200;
|
|
590
|
+
const DEFAULT_SESSION_KEY = "__default__";
|
|
589
591
|
function resolvePluginCacheDir(codexHome) {
|
|
590
592
|
return join(codexHome, PLUGIN_CACHE_DIR_NAME);
|
|
591
593
|
}
|
|
@@ -630,21 +632,23 @@ function writeBackupCache(codexHome, raw) {
|
|
|
630
632
|
writeFileAtomicSync(join(resolvePluginCacheDir(codexHome), BACKUP_CACHE_FILE_NAME), `${JSON.stringify(raw, null, 2)}\n`);
|
|
631
633
|
} catch {}
|
|
632
634
|
}
|
|
633
|
-
function
|
|
635
|
+
function readPersistedSessionFastModes(codexHome) {
|
|
636
|
+
const result = new Map();
|
|
634
637
|
try {
|
|
635
|
-
const
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
}
|
|
638
|
+
const entries = JSON.parse(readFileSync(join(resolvePluginCacheDir(codexHome), RUNTIME_STATE_FILE_NAME), "utf8"))?.sessionFastModes;
|
|
639
|
+
if (entries && typeof entries === "object" && !Array.isArray(entries)) {
|
|
640
|
+
for (const [k, v] of Object.entries(entries)) if (typeof k === "string" && k !== "" && typeof v === "boolean") result.set(k, v);
|
|
641
|
+
}
|
|
642
|
+
} catch {}
|
|
643
|
+
return result;
|
|
640
644
|
}
|
|
641
|
-
function
|
|
645
|
+
function writePersistedSessionFastModes(codexHome, sessionFastModes) {
|
|
642
646
|
try {
|
|
643
|
-
writeFileAtomicSync(join(resolvePluginCacheDir(codexHome), RUNTIME_STATE_FILE_NAME), `${JSON.stringify({
|
|
647
|
+
writeFileAtomicSync(join(resolvePluginCacheDir(codexHome), RUNTIME_STATE_FILE_NAME), `${JSON.stringify({ sessionFastModes: Object.fromEntries(sessionFastModes) }, null, 2)}\n`);
|
|
644
648
|
} catch {}
|
|
645
649
|
}
|
|
646
650
|
const Config = z.object({
|
|
647
|
-
fastMode: z.boolean().default(false).description("
|
|
651
|
+
fastMode: z.boolean().default(false).description("新会话默认是否开启 Fast 极速模式(未填时默认 false;单会话可在右下角限额弹窗内独立切换)").volatile(),
|
|
648
652
|
disabledModels: z.array(z.string()).default([...DEFAULT_DISABLED_MODELS]).description("在模型选择器中屏蔽的模型 slug 列表").volatile(),
|
|
649
653
|
contextWindows: z.dict(z.number()).default({}).description("按模型 slug 覆盖上下文窗口大小(tokens),未配置时默认使用 872000").volatile()
|
|
650
654
|
});
|
|
@@ -682,19 +686,30 @@ function apply(ctx, config = {}) {
|
|
|
682
686
|
const baseModels = baseProvider.getModels();
|
|
683
687
|
const retryPolicy = resolveRetryPolicy(void 0, "codex-subscription retryPolicy");
|
|
684
688
|
const getCodexHome = () => resolveCodexHome();
|
|
685
|
-
const getConfigFastMode = () =>
|
|
689
|
+
const getConfigFastMode = () => readVolatile(config.fastMode, false) === true;
|
|
686
690
|
const getDisabledModels = () => readVolatile(config.disabledModels, DEFAULT_DISABLED_MODELS);
|
|
687
691
|
const getContextWindows = () => readVolatile(config.contextWindows, {});
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
+
const sessionFastModes = readPersistedSessionFastModes(getCodexHome());
|
|
693
|
+
const getEffectiveFastMode = (sessionId) => {
|
|
694
|
+
const key = normalizeCodexSessionId(sessionId);
|
|
695
|
+
if (key !== void 0 && sessionFastModes.has(key)) return sessionFastModes.get(key) === true;
|
|
696
|
+
if (key === void 0 && sessionFastModes.has(DEFAULT_SESSION_KEY)) return sessionFastModes.get(DEFAULT_SESSION_KEY) === true;
|
|
697
|
+
return getConfigFastMode();
|
|
698
|
+
};
|
|
699
|
+
const setSessionFastMode = (sessionId, nextFastMode) => {
|
|
692
700
|
const codexHome = getCodexHome();
|
|
693
|
-
|
|
694
|
-
|
|
701
|
+
const key = normalizeCodexSessionId(sessionId) ?? DEFAULT_SESSION_KEY;
|
|
702
|
+
sessionFastModes.delete(key);
|
|
703
|
+
sessionFastModes.set(key, nextFastMode);
|
|
704
|
+
while (sessionFastModes.size > MAX_PERSISTED_SESSIONS) {
|
|
705
|
+
const oldest = sessionFastModes.keys().next().value;
|
|
706
|
+
if (oldest === void 0) break;
|
|
707
|
+
sessionFastModes.delete(oldest);
|
|
708
|
+
}
|
|
709
|
+
writePersistedSessionFastModes(codexHome, sessionFastModes);
|
|
695
710
|
appendPluginLog(codexHome, ctx, "INFO", "fast_mode.updated", {
|
|
696
|
-
|
|
697
|
-
|
|
711
|
+
sessionId: key,
|
|
712
|
+
fastMode: nextFastMode
|
|
698
713
|
});
|
|
699
714
|
};
|
|
700
715
|
const authManager = createAuthManager({
|
|
@@ -734,7 +749,7 @@ function apply(ctx, config = {}) {
|
|
|
734
749
|
transport: "sse",
|
|
735
750
|
headers: buildCodexHeaders(rest.headers, catalog.clientVersion),
|
|
736
751
|
async onPayload(payload, requestModel) {
|
|
737
|
-
return sanitizeCodexPayload(await onPayload?.(payload, requestModel) ?? payload, modelMeta, getEffectiveFastMode());
|
|
752
|
+
return sanitizeCodexPayload(await onPayload?.(payload, requestModel) ?? payload, modelMeta, getEffectiveFastMode(normalizedSessionId));
|
|
738
753
|
}
|
|
739
754
|
};
|
|
740
755
|
}
|
|
@@ -903,10 +918,11 @@ function apply(ctx, config = {}) {
|
|
|
903
918
|
fetch: async (request) => {
|
|
904
919
|
if (request.method === "POST") {
|
|
905
920
|
const body = await request.json().catch(() => null);
|
|
906
|
-
if (typeof body?.fastMode === "boolean")
|
|
921
|
+
if (typeof body?.fastMode === "boolean") setSessionFastMode(typeof body.sessionId === "string" ? body.sessionId : void 0, body.fastMode);
|
|
907
922
|
return new Response(JSON.stringify({
|
|
908
923
|
ok: true,
|
|
909
|
-
|
|
924
|
+
defaultFastMode: getConfigFastMode(),
|
|
925
|
+
sessionFastModes: Object.fromEntries(sessionFastModes)
|
|
910
926
|
}), {
|
|
911
927
|
status: 200,
|
|
912
928
|
headers: { "content-type": "application/json" }
|
|
@@ -916,7 +932,8 @@ function apply(ctx, config = {}) {
|
|
|
916
932
|
const result = await usageFetcher.getUsage(force);
|
|
917
933
|
return new Response(JSON.stringify({
|
|
918
934
|
...result,
|
|
919
|
-
|
|
935
|
+
defaultFastMode: getConfigFastMode(),
|
|
936
|
+
sessionFastModes: Object.fromEntries(sessionFastModes)
|
|
920
937
|
}), {
|
|
921
938
|
status: 200,
|
|
922
939
|
headers: { "content-type": "application/json" }
|
|
@@ -929,11 +946,6 @@ function apply(ctx, config = {}) {
|
|
|
929
946
|
if (typeof ctx.inject === "function") ctx.inject(["connection"], mountUsageRoute);
|
|
930
947
|
else mountUsageRoute(ctx);
|
|
931
948
|
ctx.on?.("loader/volatile-update", () => {
|
|
932
|
-
const currentConfigFastMode = getConfigFastMode();
|
|
933
|
-
if (currentConfigFastMode !== lastConfigFastMode) {
|
|
934
|
-
lastConfigFastMode = currentConfigFastMode;
|
|
935
|
-
setFastModeOverride(currentConfigFastMode, "config");
|
|
936
|
-
}
|
|
937
949
|
ensureSnapshot();
|
|
938
950
|
ctx.llm.emitAdaptersUpdated?.();
|
|
939
951
|
});
|