dsh-codex-community 0.0.1 → 0.0.2
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 +48 -0
- package/README.en.md +12 -10
- package/README.md +12 -10
- package/THIRD_PARTY_NOTICES.md +2 -0
- package/dist/client/index.js +487 -49
- package/dist/host/index.mjs +3 -0
- package/dist/internal/authorization-bridge.mjs +12 -0
- package/dist/internal/codex-account-usage.mjs +509 -0
- package/dist/internal/codex-model-capabilities.mjs +90 -0
- package/dist/internal/codex-pi-provider.mjs +30 -3
- package/dist/internal/codex-provider-runtime.mjs +27 -1
- package/dist/internal/codex-route-adapter.mjs +36 -3
- package/dist/internal/session-preference-bridge.mjs +150 -0
- package/docs/architecture.en.md +20 -11
- package/docs/architecture.md +20 -11
- package/docs/compatibility.en.md +13 -12
- package/docs/compatibility.md +13 -12
- package/docs/configuration.en.md +23 -1
- package/docs/configuration.md +23 -1
- package/docs/releases/v0.0.1.md +0 -2
- package/docs/releases/v0.0.2.acceptance.json +160 -0
- package/docs/releases/v0.0.2.md +56 -0
- package/docs/releasing.en.md +1 -1
- package/docs/releasing.md +1 -1
- package/docs/troubleshooting.en.md +19 -3
- package/docs/troubleshooting.md +19 -3
- package/package.json +11 -1
- package/types/client.d.ts +59 -0
package/dist/client/index.js
CHANGED
|
@@ -7,6 +7,7 @@ window.__ModuleLoader__.load({
|
|
|
7
7
|
const h = React.createElement
|
|
8
8
|
|
|
9
9
|
const CHANNEL = "/dsh-codex"
|
|
10
|
+
const SESSION_CHANNEL = "/dsh-codex-session"
|
|
10
11
|
const NS = "settings.codex"
|
|
11
12
|
const CODEX_PROVIDER = "dsh-codex"
|
|
12
13
|
const CODEX_SETTINGS_NS = "dsh-codex"
|
|
@@ -47,10 +48,21 @@ window.__ModuleLoader__.load({
|
|
|
47
48
|
logoutFailed: "退出登录失败,请重试。",
|
|
48
49
|
responseFailed: "提交登录信息失败,请重试。",
|
|
49
50
|
requestFailed: "暂时无法连接本机授权服务。",
|
|
51
|
+
locale: "zh-CN",
|
|
50
52
|
quotaTitle: "使用额度",
|
|
51
53
|
quotaProduct: "Codex",
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
quotaLoading: "正在读取账户额度…",
|
|
55
|
+
quotaLoadFailed: "暂时无法刷新账户额度。",
|
|
56
|
+
quotaStaleHelp: "继续显示上一次验证成功的数据。",
|
|
57
|
+
quotaUnknown: "尚无可验证的额度数据。",
|
|
58
|
+
quotaUnknownHelp: "登录后会在每次进入此页面和手动刷新时读取;读取失败时保留最近的安全观测。",
|
|
59
|
+
quotaFiveHour: "5 小时额度",
|
|
60
|
+
quotaWeekly: "每周额度",
|
|
61
|
+
quotaMinuteWindow: "分钟额度",
|
|
62
|
+
quotaRemaining: "剩余",
|
|
63
|
+
quotaUsed: "已使用",
|
|
64
|
+
quotaResetsAt: "重置时间",
|
|
65
|
+
quotaUpdatedAt: "数据更新时间",
|
|
54
66
|
quotaRecentSuccess: "最近一次 Codex 请求成功",
|
|
55
67
|
quotaSuccessCaution: "这只表示最近一次请求成功,不代表账户剩余额度。",
|
|
56
68
|
quotaExhausted: "最近观测到 Codex 账户额度已用尽。",
|
|
@@ -59,8 +71,10 @@ window.__ModuleLoader__.load({
|
|
|
59
71
|
quotaResetIn: "预计还有约",
|
|
60
72
|
quotaMinutes: "分钟",
|
|
61
73
|
quotaNoReset: "未获得通过校验的重置时间;状态会在有限时间后自动回到未知。",
|
|
62
|
-
modelsTitle: "
|
|
63
|
-
modelsDescription: "选择要在模型选择器中显示的 Codex
|
|
74
|
+
modelsTitle: "当前安装的 Codex 模型",
|
|
75
|
+
modelsDescription: "选择要在模型选择器中显示的 Codex 模型。当前目录条目的名称、上下文窗口和最大输出直接来自当前安装的 Codex provider catalog,不推测目录未提供的能力;隐藏后,已有会话中保存的精确模型仍可继续使用。",
|
|
76
|
+
modelsContextWindow: "上下文",
|
|
77
|
+
modelsMaxOutput: "最大输出",
|
|
64
78
|
modelsLoading: "正在读取 Codex 模型目录…",
|
|
65
79
|
modelsUnavailable: "当前环境没有可用的 Codex 模型管理接口。",
|
|
66
80
|
modelsReadOnly: "当前设置存储为只读,无法修改启用模型。",
|
|
@@ -74,6 +88,16 @@ window.__ModuleLoader__.load({
|
|
|
74
88
|
modelsRetry: "重新读取",
|
|
75
89
|
modelsLoadFailed: "读取 Codex 模型目录失败。",
|
|
76
90
|
modelsSaveFailed: "保存模型启用设置失败。",
|
|
91
|
+
fastEnable: "启用 Fast(1.5×)",
|
|
92
|
+
fastDisable: "关闭 Fast,恢复默认速度",
|
|
93
|
+
fastUnsupported: "当前模型不支持 Fast(1.5×)",
|
|
94
|
+
fastLoading: "正在读取 Fast 状态",
|
|
95
|
+
fastUnavailable: "暂时无法读取 Fast 状态,点击重试",
|
|
96
|
+
legacyReasoningRepair: "修复并设为新会话默认模型",
|
|
97
|
+
legacyReasoningRepairing: "正在修复…",
|
|
98
|
+
legacyReasoningRepaired: "已修复并设为新会话默认模型",
|
|
99
|
+
legacyReasoningRepairRetry: "重试修复并设为新会话默认模型",
|
|
100
|
+
legacyReasoningRepairHelp: "旧会话保存了当前不支持的 Off/Minimal。点击后会切换到此模型当前默认档位;与模型选择器相同,此操作也会把该模型保存为未来新会话的默认模型。",
|
|
77
101
|
}
|
|
78
102
|
const en = {
|
|
79
103
|
nav: "OpenAI Codex",
|
|
@@ -108,10 +132,21 @@ window.__ModuleLoader__.load({
|
|
|
108
132
|
logoutFailed: "Could not sign out. Please try again.",
|
|
109
133
|
responseFailed: "Could not submit the sign-in response. Please try again.",
|
|
110
134
|
requestFailed: "The local authorization service is temporarily unavailable.",
|
|
135
|
+
locale: "en-US",
|
|
111
136
|
quotaTitle: "Usage",
|
|
112
137
|
quotaProduct: "Codex",
|
|
113
|
-
|
|
114
|
-
|
|
138
|
+
quotaLoading: "Reading account usage…",
|
|
139
|
+
quotaLoadFailed: "Account usage could not be refreshed.",
|
|
140
|
+
quotaStaleHelp: "The last successfully verified data remains visible.",
|
|
141
|
+
quotaUnknown: "No verifiable usage data is available yet.",
|
|
142
|
+
quotaUnknownHelp: "After sign-in, usage is read whenever this page opens and when you refresh it; the latest safe observation remains available if the read fails.",
|
|
143
|
+
quotaFiveHour: "5-hour limit",
|
|
144
|
+
quotaWeekly: "Weekly limit",
|
|
145
|
+
quotaMinuteWindow: "minute limit",
|
|
146
|
+
quotaRemaining: "Remaining",
|
|
147
|
+
quotaUsed: "Used",
|
|
148
|
+
quotaResetsAt: "Resets",
|
|
149
|
+
quotaUpdatedAt: "Data updated",
|
|
115
150
|
quotaRecentSuccess: "The latest Codex request succeeded",
|
|
116
151
|
quotaSuccessCaution: "This only describes the latest request; it does not represent remaining account quota.",
|
|
117
152
|
quotaExhausted: "Codex account quota was exhausted in the latest observation.",
|
|
@@ -120,8 +155,10 @@ window.__ModuleLoader__.load({
|
|
|
120
155
|
quotaResetIn: "Approximately",
|
|
121
156
|
quotaMinutes: "minutes remaining",
|
|
122
157
|
quotaNoReset: "No reset time passed validation; this state automatically returns to unknown after a bounded interval.",
|
|
123
|
-
modelsTitle: "
|
|
124
|
-
modelsDescription: "Choose which Codex models appear in the model selector. Hidden models remain available to existing conversations that saved an exact model.",
|
|
158
|
+
modelsTitle: "Codex models in this installation",
|
|
159
|
+
modelsDescription: "Choose which Codex models appear in the model selector. For current catalog entries, names, context windows, and maximum output values come directly from the installed Codex provider catalog; capabilities omitted by the catalog are not inferred. Hidden models remain available to existing conversations that saved an exact model.",
|
|
160
|
+
modelsContextWindow: "Context",
|
|
161
|
+
modelsMaxOutput: "Max output",
|
|
125
162
|
modelsLoading: "Reading the Codex model catalog…",
|
|
126
163
|
modelsUnavailable: "Codex model management is unavailable in this environment.",
|
|
127
164
|
modelsReadOnly: "The settings store is read-only, so enabled models cannot be changed.",
|
|
@@ -135,6 +172,16 @@ window.__ModuleLoader__.load({
|
|
|
135
172
|
modelsRetry: "Reload",
|
|
136
173
|
modelsLoadFailed: "Could not read the Codex model catalog.",
|
|
137
174
|
modelsSaveFailed: "Could not save the enabled models.",
|
|
175
|
+
fastEnable: "Enable Fast (1.5×)",
|
|
176
|
+
fastDisable: "Turn off Fast and restore standard speed",
|
|
177
|
+
fastUnsupported: "The current model does not support Fast (1.5×)",
|
|
178
|
+
fastLoading: "Reading Fast status",
|
|
179
|
+
fastUnavailable: "Fast status is temporarily unavailable; click to retry",
|
|
180
|
+
legacyReasoningRepair: "Repair and set as future default",
|
|
181
|
+
legacyReasoningRepairing: "Repairing…",
|
|
182
|
+
legacyReasoningRepaired: "Repaired and set as future default",
|
|
183
|
+
legacyReasoningRepairRetry: "Retry repair and set as future default",
|
|
184
|
+
legacyReasoningRepairHelp: "This conversation saved an unsupported Off/Minimal level. Click to switch to this model's current default. Like using the model selector, this also saves it as the default model for future conversations.",
|
|
138
185
|
}
|
|
139
186
|
|
|
140
187
|
function createAuthorizationClient(connection) {
|
|
@@ -164,9 +211,199 @@ window.__ModuleLoader__.load({
|
|
|
164
211
|
}),
|
|
165
212
|
cancel: (attemptId) => call("cancel", attemptId === undefined ? {} : { attemptId }),
|
|
166
213
|
logout: () => call("logout", {}),
|
|
214
|
+
usage: (signal) => call("usage", {}, signal),
|
|
167
215
|
})
|
|
168
216
|
}
|
|
169
217
|
|
|
218
|
+
function createSessionPreferenceClient(connection) {
|
|
219
|
+
const call = async (endpoint, payload, signal) => {
|
|
220
|
+
const result = await connection.rpc.call(SESSION_CHANNEL, endpoint, payload, signal)
|
|
221
|
+
if (!result.ok) {
|
|
222
|
+
const error = new Error(result.error.message)
|
|
223
|
+
error.code = result.error.code
|
|
224
|
+
throw error
|
|
225
|
+
}
|
|
226
|
+
return result.value
|
|
227
|
+
}
|
|
228
|
+
return Object.freeze({
|
|
229
|
+
forSession(sessionId) {
|
|
230
|
+
return Object.freeze({
|
|
231
|
+
get: (signal) => call("get", { sessionId }, signal),
|
|
232
|
+
setFast: (fast, signal) => call("set-fast", { sessionId, fast }, signal),
|
|
233
|
+
})
|
|
234
|
+
},
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function supportsFastModel(modelId) {
|
|
239
|
+
return modelId === "gpt-5.4"
|
|
240
|
+
|| modelId === "gpt-5.5"
|
|
241
|
+
|| modelId === "gpt-5.6-luna"
|
|
242
|
+
|| modelId === "gpt-5.6-sol"
|
|
243
|
+
|| modelId === "gpt-5.6-terra"
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function CodexFastToggle({
|
|
247
|
+
session,
|
|
248
|
+
useModelDirectory,
|
|
249
|
+
preferenceClient,
|
|
250
|
+
selectModel,
|
|
251
|
+
t,
|
|
252
|
+
}) {
|
|
253
|
+
const current = useModelDirectory((state) => state.current ?? null)
|
|
254
|
+
const [preference, setPreference] = React.useState({ status: "loading", fast: false })
|
|
255
|
+
const [repair, setRepair] = React.useState({ key: null, status: "idle" })
|
|
256
|
+
const mountedRef = React.useRef(false)
|
|
257
|
+
const generationRef = React.useRef(0)
|
|
258
|
+
const controllerRef = React.useRef(null)
|
|
259
|
+
const repairAttemptRef = React.useRef(null)
|
|
260
|
+
const isCodex = current?.provider === CODEX_PROVIDER
|
|
261
|
+
const supported = isCodex && supportsFastModel(current?.model)
|
|
262
|
+
|
|
263
|
+
const refreshPreference = React.useCallback(async () => {
|
|
264
|
+
if (!mountedRef.current || !isCodex) return
|
|
265
|
+
const generation = ++generationRef.current
|
|
266
|
+
controllerRef.current?.abort()
|
|
267
|
+
const controller = new AbortController()
|
|
268
|
+
controllerRef.current = controller
|
|
269
|
+
setPreference((value) => ({ status: "loading", fast: value.fast }))
|
|
270
|
+
try {
|
|
271
|
+
const value = await preferenceClient.get(controller.signal)
|
|
272
|
+
if (!mountedRef.current || generation !== generationRef.current || controller.signal.aborted) return
|
|
273
|
+
setPreference({ status: "ready", fast: value?.fast === true })
|
|
274
|
+
} catch {
|
|
275
|
+
if (!mountedRef.current || generation !== generationRef.current || controller.signal.aborted) return
|
|
276
|
+
setPreference((value) => ({ status: "error", fast: value.fast }))
|
|
277
|
+
} finally {
|
|
278
|
+
if (controllerRef.current === controller) controllerRef.current = null
|
|
279
|
+
}
|
|
280
|
+
}, [isCodex, preferenceClient])
|
|
281
|
+
|
|
282
|
+
React.useEffect(() => {
|
|
283
|
+
mountedRef.current = true
|
|
284
|
+
if (isCodex) void refreshPreference()
|
|
285
|
+
return () => {
|
|
286
|
+
mountedRef.current = false
|
|
287
|
+
generationRef.current += 1
|
|
288
|
+
controllerRef.current?.abort()
|
|
289
|
+
controllerRef.current = null
|
|
290
|
+
}
|
|
291
|
+
}, [isCodex, preferenceClient, refreshPreference])
|
|
292
|
+
|
|
293
|
+
const legacySelection = isCodex
|
|
294
|
+
&& (current?.reasoningEffort === "off" || current?.reasoningEffort === "minimal")
|
|
295
|
+
const legacyKey = legacySelection ? `${current.model}:${current.reasoningEffort}` : null
|
|
296
|
+
const repairStatus = repair.key === legacyKey ? repair.status : "idle"
|
|
297
|
+
|
|
298
|
+
const repairLegacySelection = async () => {
|
|
299
|
+
if (
|
|
300
|
+
!mountedRef.current
|
|
301
|
+
|| !legacySelection
|
|
302
|
+
|| typeof selectModel !== "function"
|
|
303
|
+
|| session?.removed === true
|
|
304
|
+
|| repairStatus === "saving"
|
|
305
|
+
|| repairStatus === "done"
|
|
306
|
+
|| repairAttemptRef.current === legacyKey
|
|
307
|
+
) return
|
|
308
|
+
const key = legacyKey
|
|
309
|
+
repairAttemptRef.current = key
|
|
310
|
+
setRepair({ key, status: "saving" })
|
|
311
|
+
try {
|
|
312
|
+
await selectModel({
|
|
313
|
+
provider: CODEX_PROVIDER,
|
|
314
|
+
model: current.model,
|
|
315
|
+
})
|
|
316
|
+
if (mountedRef.current) setRepair({ key, status: "done" })
|
|
317
|
+
} catch {
|
|
318
|
+
if (repairAttemptRef.current === key) repairAttemptRef.current = null
|
|
319
|
+
if (mountedRef.current) setRepair({ key, status: "error" })
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const toggleFast = async () => {
|
|
324
|
+
if (!mountedRef.current || !supported || session?.removed === true) return
|
|
325
|
+
if (preference.status === "error") {
|
|
326
|
+
void refreshPreference()
|
|
327
|
+
return
|
|
328
|
+
}
|
|
329
|
+
if (preference.status !== "ready") return
|
|
330
|
+
const generation = ++generationRef.current
|
|
331
|
+
controllerRef.current?.abort()
|
|
332
|
+
const controller = new AbortController()
|
|
333
|
+
controllerRef.current = controller
|
|
334
|
+
const nextFast = !preference.fast
|
|
335
|
+
setPreference({ status: "saving", fast: preference.fast })
|
|
336
|
+
try {
|
|
337
|
+
const value = await preferenceClient.setFast(nextFast, controller.signal)
|
|
338
|
+
if (!mountedRef.current || generation !== generationRef.current || controller.signal.aborted) return
|
|
339
|
+
setPreference({ status: "ready", fast: value?.fast === true })
|
|
340
|
+
} catch {
|
|
341
|
+
if (!mountedRef.current || generation !== generationRef.current || controller.signal.aborted) return
|
|
342
|
+
setPreference({ status: "error", fast: preference.fast })
|
|
343
|
+
} finally {
|
|
344
|
+
if (controllerRef.current === controller) controllerRef.current = null
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (!isCodex) return null
|
|
349
|
+
const label = !supported
|
|
350
|
+
? t("fastUnsupported")
|
|
351
|
+
: preference.status === "loading" || preference.status === "saving"
|
|
352
|
+
? t("fastLoading")
|
|
353
|
+
: preference.status === "error"
|
|
354
|
+
? t("fastUnavailable")
|
|
355
|
+
: preference.fast
|
|
356
|
+
? t("fastDisable")
|
|
357
|
+
: t("fastEnable")
|
|
358
|
+
const disabled = !supported
|
|
359
|
+
|| session?.removed === true
|
|
360
|
+
|| preference.status === "loading"
|
|
361
|
+
|| preference.status === "saving"
|
|
362
|
+
|
|
363
|
+
const fastButton = h("button", {
|
|
364
|
+
type: "button",
|
|
365
|
+
className: "dshCodexFastToggle",
|
|
366
|
+
"data-fast": preference.fast ? "true" : undefined,
|
|
367
|
+
"aria-label": label,
|
|
368
|
+
"aria-pressed": preference.fast,
|
|
369
|
+
"aria-busy": preference.status === "loading" || preference.status === "saving" ? "true" : undefined,
|
|
370
|
+
title: label,
|
|
371
|
+
disabled,
|
|
372
|
+
onClick: () => void toggleFast(),
|
|
373
|
+
}, h("svg", {
|
|
374
|
+
viewBox: "0 0 24 24",
|
|
375
|
+
width: 16,
|
|
376
|
+
height: 16,
|
|
377
|
+
fill: "none",
|
|
378
|
+
stroke: "currentColor",
|
|
379
|
+
strokeWidth: 2,
|
|
380
|
+
strokeLinecap: "round",
|
|
381
|
+
strokeLinejoin: "round",
|
|
382
|
+
"aria-hidden": "true",
|
|
383
|
+
}, h("path", { d: "M13 2 4.5 13h7L11 22l8.5-11h-7L13 2Z" })))
|
|
384
|
+
|
|
385
|
+
if (!legacySelection || typeof selectModel !== "function") return fastButton
|
|
386
|
+
const repairLabel = repairStatus === "saving"
|
|
387
|
+
? t("legacyReasoningRepairing")
|
|
388
|
+
: repairStatus === "done"
|
|
389
|
+
? t("legacyReasoningRepaired")
|
|
390
|
+
: repairStatus === "error"
|
|
391
|
+
? t("legacyReasoningRepairRetry")
|
|
392
|
+
: t("legacyReasoningRepair")
|
|
393
|
+
return h(React.Fragment, null,
|
|
394
|
+
h("button", {
|
|
395
|
+
type: "button",
|
|
396
|
+
className: "dshCodexLegacyRepair",
|
|
397
|
+
"data-status": repairStatus,
|
|
398
|
+
"aria-label": repairLabel,
|
|
399
|
+
"aria-busy": repairStatus === "saving" ? "true" : undefined,
|
|
400
|
+
title: t("legacyReasoningRepairHelp"),
|
|
401
|
+
disabled: session?.removed === true || repairStatus === "saving" || repairStatus === "done",
|
|
402
|
+
onClick: () => void repairLegacySelection(),
|
|
403
|
+
}, repairLabel),
|
|
404
|
+
fastButton)
|
|
405
|
+
}
|
|
406
|
+
|
|
170
407
|
function resultValue(response) {
|
|
171
408
|
if (response?.result?.ok === true) return response.result.value
|
|
172
409
|
const message = response?.result?.error?.message
|
|
@@ -193,6 +430,102 @@ window.__ModuleLoader__.load({
|
|
|
193
430
|
}
|
|
194
431
|
}
|
|
195
432
|
|
|
433
|
+
function safeAccountUsage(value) {
|
|
434
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return undefined
|
|
435
|
+
if (!Number.isSafeInteger(value.observedAt) || value.observedAt < 0) return undefined
|
|
436
|
+
if (!Array.isArray(value.rateLimits) || value.rateLimits.length > 16) return undefined
|
|
437
|
+
const rateLimits = []
|
|
438
|
+
for (const candidate of value.rateLimits) {
|
|
439
|
+
if (typeof candidate !== "object" || candidate === null || Array.isArray(candidate)) continue
|
|
440
|
+
if (typeof candidate.limitId !== "string" || candidate.limitId.length < 1 || candidate.limitId.length > 128) continue
|
|
441
|
+
const primary = safeUsageWindow(candidate.primary)
|
|
442
|
+
const secondary = safeUsageWindow(candidate.secondary)
|
|
443
|
+
if (primary === undefined && secondary === undefined) continue
|
|
444
|
+
rateLimits.push({
|
|
445
|
+
limitId: candidate.limitId,
|
|
446
|
+
...(typeof candidate.limitName === "string" && candidate.limitName.length > 0 && candidate.limitName.length <= 256
|
|
447
|
+
? { limitName: candidate.limitName }
|
|
448
|
+
: {}),
|
|
449
|
+
...(primary === undefined ? {} : { primary }),
|
|
450
|
+
...(secondary === undefined ? {} : { secondary }),
|
|
451
|
+
})
|
|
452
|
+
}
|
|
453
|
+
if (rateLimits.length === 0) return undefined
|
|
454
|
+
return { observedAt: value.observedAt, rateLimits }
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function safeUsageWindow(value) {
|
|
458
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return undefined
|
|
459
|
+
if (typeof value.usedPercent !== "number" || !Number.isFinite(value.usedPercent) || value.usedPercent < 0 || value.usedPercent > 100) return undefined
|
|
460
|
+
if (!Number.isSafeInteger(value.windowDurationMins) || value.windowDurationMins < 1 || value.windowDurationMins > 525_600) return undefined
|
|
461
|
+
if (!Number.isSafeInteger(value.resetsAt) || value.resetsAt < 0) return undefined
|
|
462
|
+
return {
|
|
463
|
+
usedPercent: value.usedPercent,
|
|
464
|
+
windowDurationMins: value.windowDurationMins,
|
|
465
|
+
resetsAt: value.resetsAt,
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
function percentText(value) {
|
|
470
|
+
return String(Math.round(value * 10) / 10)
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
function usageWindowLabel(window, t) {
|
|
474
|
+
if (window.windowDurationMins === 300) return t("quotaFiveHour")
|
|
475
|
+
if (window.windowDurationMins === 10_080) return t("quotaWeekly")
|
|
476
|
+
return `${window.windowDurationMins} ${t("quotaMinuteWindow")}`
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function renderObservedQuota(quota, t) {
|
|
480
|
+
if (quota.status === "recent-success") {
|
|
481
|
+
return h(React.Fragment, null,
|
|
482
|
+
h("p", { className: "dshCodexQuotaState" }, `${t("quotaRecentSuccess")} · ${new Date(quota.observedAt).toLocaleString(t("locale"))}`),
|
|
483
|
+
h("p", { className: "dshCodexMuted" }, t("quotaSuccessCaution")))
|
|
484
|
+
}
|
|
485
|
+
if (quota.status === "exhausted") {
|
|
486
|
+
return h(React.Fragment, null,
|
|
487
|
+
h("p", { className: "dshCodexQuotaState dshCodexQuotaExhausted" }, t("quotaExhausted")),
|
|
488
|
+
h("p", { className: "dshCodexMuted" }, `${t("quotaObservedAt")} · ${new Date(quota.observedAt).toLocaleString(t("locale"))}`),
|
|
489
|
+
quota.resetAt === undefined
|
|
490
|
+
? h("p", { className: "dshCodexMuted" }, t("quotaNoReset"))
|
|
491
|
+
: h("p", { className: "dshCodexMuted" }, `${t("quotaResetAt")} · ${new Date(quota.resetAt).toLocaleString(t("locale"))} · ${t("quotaResetIn")} ${quota.remainingMinutes} ${t("quotaMinutes")}`))
|
|
492
|
+
}
|
|
493
|
+
return h(React.Fragment, null,
|
|
494
|
+
h("p", { className: "dshCodexQuotaState dshCodexQuotaUnknown" }, t("quotaUnknown")),
|
|
495
|
+
h("p", { className: "dshCodexMuted" }, t("quotaUnknownHelp")))
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
function renderAccountUsage(usage, t) {
|
|
499
|
+
return h(React.Fragment, null,
|
|
500
|
+
...usage.rateLimits.map((limit) => {
|
|
501
|
+
const windows = [limit.primary, limit.secondary].filter((window) => window !== undefined)
|
|
502
|
+
const limitLabel = limit.limitId === "codex"
|
|
503
|
+
? t("quotaProduct")
|
|
504
|
+
: limit.limitName ?? limit.limitId
|
|
505
|
+
return h("section", { key: limit.limitId, className: "dshCodexQuotaGroup" },
|
|
506
|
+
h("p", { className: "dshCodexQuotaProduct" }, limitLabel),
|
|
507
|
+
...windows.map((window) => {
|
|
508
|
+
const remaining = Math.max(0, Math.min(100, 100 - window.usedPercent))
|
|
509
|
+
const remainingText = percentText(remaining)
|
|
510
|
+
const usedText = percentText(window.usedPercent)
|
|
511
|
+
const label = usageWindowLabel(window, t)
|
|
512
|
+
return h("div", { key: `${limit.limitId}-${window.windowDurationMins}`, className: "dshCodexQuotaWindow" },
|
|
513
|
+
h("div", { className: "dshCodexQuotaWindowHeader" },
|
|
514
|
+
h("span", null, label),
|
|
515
|
+
h("strong", null, `${t("quotaRemaining")} ${remainingText}%`)),
|
|
516
|
+
h("progress", {
|
|
517
|
+
max: 100,
|
|
518
|
+
value: remaining,
|
|
519
|
+
"aria-label": `${limitLabel} · ${label} · ${t("quotaRemaining")} ${remainingText}%`,
|
|
520
|
+
}),
|
|
521
|
+
h("div", { className: "dshCodexQuotaMeta" },
|
|
522
|
+
h("span", null, `${t("quotaUsed")} ${usedText}%`),
|
|
523
|
+
h("span", null, `${t("quotaResetsAt")}:${new Date(window.resetsAt).toLocaleString(t("locale"))}`)))
|
|
524
|
+
}))
|
|
525
|
+
}),
|
|
526
|
+
h("p", { className: "dshCodexMuted dshCodexQuotaUpdated" }, `${t("quotaUpdatedAt")}:${new Date(usage.observedAt).toLocaleString(t("locale"))}`))
|
|
527
|
+
}
|
|
528
|
+
|
|
196
529
|
function objectAtPath(root, path) {
|
|
197
530
|
let current = root
|
|
198
531
|
for (const key of path) {
|
|
@@ -217,11 +550,28 @@ window.__ModuleLoader__.load({
|
|
|
217
550
|
rows.push({
|
|
218
551
|
id: candidate.id,
|
|
219
552
|
...(typeof candidate.name === "string" && candidate.name.length > 0 ? { name: candidate.name } : {}),
|
|
553
|
+
...(Number.isSafeInteger(candidate.contextWindow) && candidate.contextWindow > 0
|
|
554
|
+
? { contextWindow: candidate.contextWindow }
|
|
555
|
+
: {}),
|
|
556
|
+
...(Number.isSafeInteger(candidate.maxTokens) && candidate.maxTokens > 0
|
|
557
|
+
? { maxTokens: candidate.maxTokens }
|
|
558
|
+
: {}),
|
|
220
559
|
})
|
|
221
560
|
}
|
|
222
561
|
return rows
|
|
223
562
|
}
|
|
224
563
|
|
|
564
|
+
function formatModelTokenCount(value, locale) {
|
|
565
|
+
const divisor = value >= 1_000_000 ? 1_000_000 : value >= 1_000 ? 1_000 : 1
|
|
566
|
+
const suffix = divisor === 1_000_000 ? "M" : divisor === 1_000 ? "K" : ""
|
|
567
|
+
const compact = value / divisor
|
|
568
|
+
try {
|
|
569
|
+
return `${compact.toLocaleString(locale, { maximumFractionDigits: 1 })}${suffix}`
|
|
570
|
+
} catch {
|
|
571
|
+
return `${Math.round(compact * 10) / 10}${suffix}`
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
225
575
|
function modelSavePlan(snapshot, selectedIds) {
|
|
226
576
|
const selected = new Set(selectedIds)
|
|
227
577
|
const modelIds = snapshot.models.map((model) => model.id)
|
|
@@ -340,6 +690,7 @@ window.__ModuleLoader__.load({
|
|
|
340
690
|
|
|
341
691
|
function AuthorizationSettings({ client, t }) {
|
|
342
692
|
const [snapshot, setSnapshot] = React.useState({ status: "loading" })
|
|
693
|
+
const [usageSnapshot, setUsageSnapshot] = React.useState({ status: "idle" })
|
|
343
694
|
const [attempt, setAttempt] = React.useState(null)
|
|
344
695
|
const [notices, setNotices] = React.useState([])
|
|
345
696
|
const [prompt, setPrompt] = React.useState(null)
|
|
@@ -368,6 +719,29 @@ window.__ModuleLoader__.load({
|
|
|
368
719
|
const value = await client.describe(controller.signal)
|
|
369
720
|
if (!mountedRef.current || generation !== refreshGenerationRef.current || controller.signal.aborted) return
|
|
370
721
|
setSnapshot({ status: "ready", value })
|
|
722
|
+
const credentialState = value?.credential?.state
|
|
723
|
+
const signedIn = credentialState === "signed-in"
|
|
724
|
+
|| (credentialState === undefined && value?.credential?.configured === true)
|
|
725
|
+
if (!signedIn || typeof client.usage !== "function") {
|
|
726
|
+
setUsageSnapshot({ status: "idle" })
|
|
727
|
+
return
|
|
728
|
+
}
|
|
729
|
+
setUsageSnapshot((current) => ({
|
|
730
|
+
status: "loading",
|
|
731
|
+
...(current.value === undefined ? {} : { value: current.value }),
|
|
732
|
+
}))
|
|
733
|
+
try {
|
|
734
|
+
const usage = safeAccountUsage(await client.usage(controller.signal))
|
|
735
|
+
if (usage === undefined) throw new Error("invalid account usage")
|
|
736
|
+
if (!mountedRef.current || generation !== refreshGenerationRef.current || controller.signal.aborted) return
|
|
737
|
+
setUsageSnapshot({ status: "ready", value: usage })
|
|
738
|
+
} catch {
|
|
739
|
+
if (!mountedRef.current || generation !== refreshGenerationRef.current || controller.signal.aborted) return
|
|
740
|
+
setUsageSnapshot((current) => ({
|
|
741
|
+
status: "error",
|
|
742
|
+
...(current.value === undefined ? {} : { value: current.value }),
|
|
743
|
+
}))
|
|
744
|
+
}
|
|
371
745
|
} catch {
|
|
372
746
|
if (!mountedRef.current || generation !== refreshGenerationRef.current || controller.signal.aborted) return
|
|
373
747
|
setSnapshot({ status: "error" })
|
|
@@ -381,9 +755,6 @@ window.__ModuleLoader__.load({
|
|
|
381
755
|
React.useEffect(() => {
|
|
382
756
|
mountedRef.current = true
|
|
383
757
|
void refresh()
|
|
384
|
-
const timer = typeof window.setInterval === "function"
|
|
385
|
-
? window.setInterval(() => void refresh(), 60_000)
|
|
386
|
-
: undefined
|
|
387
758
|
return () => {
|
|
388
759
|
mountedRef.current = false
|
|
389
760
|
refreshGenerationRef.current += 1
|
|
@@ -396,7 +767,6 @@ window.__ModuleLoader__.load({
|
|
|
396
767
|
attemptRef.current = null
|
|
397
768
|
current?.controller.abort()
|
|
398
769
|
if (current !== null && !current.done) void client.cancel(current.id).catch(() => undefined)
|
|
399
|
-
if (timer !== undefined) window.clearInterval(timer)
|
|
400
770
|
}
|
|
401
771
|
}, [client])
|
|
402
772
|
|
|
@@ -646,22 +1016,22 @@ window.__ModuleLoader__.load({
|
|
|
646
1016
|
onClick: () => void logout(),
|
|
647
1017
|
}, loggingOut ? t("signingOut") : t("signOut")) : null)
|
|
648
1018
|
|
|
1019
|
+
const liveUsage = usageSnapshot.value
|
|
649
1020
|
let quotaBody
|
|
650
|
-
if (
|
|
1021
|
+
if (liveUsage !== undefined) {
|
|
651
1022
|
quotaBody = h(React.Fragment, null,
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
1023
|
+
renderAccountUsage(liveUsage, t),
|
|
1024
|
+
usageSnapshot.status === "error"
|
|
1025
|
+
? h("p", { role: "status", className: "dshCodexError" }, `${t("quotaLoadFailed")} ${t("quotaStaleHelp")}`)
|
|
1026
|
+
: null)
|
|
1027
|
+
} else if (usageSnapshot.status === "loading") {
|
|
1028
|
+
quotaBody = h("p", { className: "dshCodexMuted", "aria-busy": "true" }, t("quotaLoading"))
|
|
1029
|
+
} else if (usageSnapshot.status === "error") {
|
|
655
1030
|
quotaBody = h(React.Fragment, null,
|
|
656
|
-
h("p", {
|
|
657
|
-
|
|
658
|
-
quota.resetAt === undefined
|
|
659
|
-
? h("p", { className: "dshCodexMuted" }, t("quotaNoReset"))
|
|
660
|
-
: h("p", { className: "dshCodexMuted" }, `${t("quotaResetAt")} · ${new Date(quota.resetAt).toLocaleString()} · ${t("quotaResetIn")} ${quota.remainingMinutes} ${t("quotaMinutes")}`))
|
|
1031
|
+
h("p", { role: "status", className: "dshCodexError" }, t("quotaLoadFailed")),
|
|
1032
|
+
renderObservedQuota(quota, t))
|
|
661
1033
|
} else {
|
|
662
|
-
quotaBody =
|
|
663
|
-
h("p", { className: "dshCodexQuotaState dshCodexQuotaUnknown" }, t("quotaUnknown")),
|
|
664
|
-
h("p", { className: "dshCodexMuted" }, t("quotaUnknownHelp")))
|
|
1034
|
+
quotaBody = renderObservedQuota(quota, t)
|
|
665
1035
|
}
|
|
666
1036
|
|
|
667
1037
|
return h("section", {
|
|
@@ -741,10 +1111,12 @@ window.__ModuleLoader__.load({
|
|
|
741
1111
|
h("button", {
|
|
742
1112
|
type: "button",
|
|
743
1113
|
className: "dshCodexButton dshCodexRefreshButton",
|
|
744
|
-
disabled: actionBusy,
|
|
1114
|
+
disabled: actionBusy || usageSnapshot.status === "loading",
|
|
745
1115
|
onClick: refresh,
|
|
746
1116
|
}, t("refresh"))),
|
|
747
|
-
|
|
1117
|
+
liveUsage === undefined
|
|
1118
|
+
? h("p", { className: "dshCodexQuotaProduct" }, t("quotaProduct"))
|
|
1119
|
+
: null,
|
|
748
1120
|
quotaBody))
|
|
749
1121
|
}
|
|
750
1122
|
|
|
@@ -851,20 +1223,40 @@ window.__ModuleLoader__.load({
|
|
|
851
1223
|
const original = new Set(snapshot.selectedIds)
|
|
852
1224
|
const dirty = selected.size !== original.size || [...selected].some((id) => !original.has(id))
|
|
853
1225
|
const plan = modelSavePlan(snapshot, selectedIds)
|
|
854
|
-
const modelItems = snapshot.models.map((model) =>
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
1226
|
+
const modelItems = snapshot.models.map((model) => {
|
|
1227
|
+
const metadata = [
|
|
1228
|
+
...(model.contextWindow === undefined
|
|
1229
|
+
? []
|
|
1230
|
+
: [`${t("modelsContextWindow")} ${formatModelTokenCount(model.contextWindow, t("locale"))}`]),
|
|
1231
|
+
...(model.maxTokens === undefined
|
|
1232
|
+
? []
|
|
1233
|
+
: [`${t("modelsMaxOutput")} ${formatModelTokenCount(model.maxTokens, t("locale"))}`]),
|
|
1234
|
+
]
|
|
1235
|
+
return h("li", { key: model.id },
|
|
1236
|
+
h("label", {
|
|
1237
|
+
className: "dshCodexModelOption",
|
|
1238
|
+
"data-selected": selected.has(model.id) ? "true" : undefined,
|
|
1239
|
+
},
|
|
1240
|
+
h("input", {
|
|
1241
|
+
type: "checkbox",
|
|
1242
|
+
checked: selected.has(model.id),
|
|
1243
|
+
disabled: saving || !snapshot.writable,
|
|
1244
|
+
onChange: () => toggle(model.id),
|
|
1245
|
+
}),
|
|
1246
|
+
h("span", { className: "dshCodexModelCopy" },
|
|
1247
|
+
h("span", { className: "dshCodexModelHeading" },
|
|
1248
|
+
h("strong", null, model.name ?? model.id),
|
|
1249
|
+
model.name === undefined || model.name === model.id
|
|
1250
|
+
? null
|
|
1251
|
+
: h("code", { className: "dshCodexModelId" }, model.id)),
|
|
1252
|
+
metadata.length === 0
|
|
1253
|
+
? null
|
|
1254
|
+
: h("span", { className: "dshCodexModelCapabilities" },
|
|
1255
|
+
...metadata.map((label) => h("span", {
|
|
1256
|
+
key: label,
|
|
1257
|
+
className: "dshCodexModelBadge",
|
|
1258
|
+
}, label))))))
|
|
1259
|
+
})
|
|
868
1260
|
content = h(React.Fragment, null,
|
|
869
1261
|
snapshot.writable ? null : h("p", { className: "dshCodexMuted" }, t("modelsReadOnly")),
|
|
870
1262
|
h("ul", {
|
|
@@ -915,6 +1307,7 @@ window.__ModuleLoader__.load({
|
|
|
915
1307
|
ctx.effect(() => ctx.locale.register(NS, { zh, en }), "dsh-codex: client dictionaries")
|
|
916
1308
|
const t = ctx.locale.bind(NS)
|
|
917
1309
|
const client = createAuthorizationClient(ctx.connection)
|
|
1310
|
+
const sessionPreferenceClient = createSessionPreferenceClient(ctx.connection)
|
|
918
1311
|
const modelClient = createModelEnablementClient(ctx.connection, ctx.settingsScope?.describe?.())
|
|
919
1312
|
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
920
1313
|
name: "settings.section",
|
|
@@ -924,6 +1317,25 @@ window.__ModuleLoader__.load({
|
|
|
924
1317
|
locale: NS,
|
|
925
1318
|
inject: () => ({ client, modelClient, t }),
|
|
926
1319
|
}, CodexSettings))
|
|
1320
|
+
ctx.inject?.(["slots", "modelDirectories"], (scope) => {
|
|
1321
|
+
scope.slots.inject("conversation.input.right", () => scope.slots.register({
|
|
1322
|
+
name: "conversation.input.right",
|
|
1323
|
+
id: "dsh-codex-fast",
|
|
1324
|
+
order: 100,
|
|
1325
|
+
locale: NS,
|
|
1326
|
+
inject: (sessionId) => {
|
|
1327
|
+
const directory = scope.modelDirectories.directoryFor(sessionId)
|
|
1328
|
+
return {
|
|
1329
|
+
preferenceClient: sessionPreferenceClient.forSession(sessionId),
|
|
1330
|
+
selectModel: (selection) => directory.select(selection),
|
|
1331
|
+
t,
|
|
1332
|
+
hooks: {
|
|
1333
|
+
modelDirectory: directory.store,
|
|
1334
|
+
},
|
|
1335
|
+
}
|
|
1336
|
+
},
|
|
1337
|
+
}, CodexFastToggle))
|
|
1338
|
+
})
|
|
927
1339
|
}
|
|
928
1340
|
|
|
929
1341
|
function installStyle() {
|
|
@@ -936,16 +1348,15 @@ window.__ModuleLoader__.load({
|
|
|
936
1348
|
document.head.appendChild(style)
|
|
937
1349
|
}
|
|
938
1350
|
style.textContent = [
|
|
939
|
-
"
|
|
940
|
-
".dshCodexPage{box-sizing:border-box;display:flex;width:100%;max-width:1120px;min-width:0;flex-direction:column;gap:28px;padding:6px 0 40px;color:var(--dsw-alias-label-primary)}",
|
|
1351
|
+
".dshCodexPage{box-sizing:border-box;display:flex;width:100%;min-width:0;flex-direction:column;gap:14px;padding:6px 0 32px;color:var(--dsw-alias-label-primary);font:inherit}",
|
|
941
1352
|
".dshCodexPage *{box-sizing:border-box}",
|
|
942
1353
|
".dshCodexHero{display:flex;min-width:0;flex-direction:column;gap:8px}",
|
|
943
1354
|
".dshCodexHero h2,.dshCodexHero p{margin:0}",
|
|
944
1355
|
".dshCodexHero h2{font-size:16px;font-weight:500;line-height:24px}",
|
|
945
1356
|
".dshCodexHero p{max-width:760px;color:var(--dsw-alias-label-tertiary);font-size:14px;line-height:22px}",
|
|
946
|
-
".dshCodexPanel{display:flex;width:100%;min-width:0;
|
|
1357
|
+
".dshCodexPanel{display:flex;width:100%;min-width:0;color:var(--dsw-alias-label-primary);flex-direction:column;gap:14px}",
|
|
947
1358
|
".dshCodexPanel p,.dshCodexPanel label{overflow-wrap:anywhere;word-break:break-word}",
|
|
948
|
-
".dshCodexCard{border:1px solid var(--dsw-alias-border-l2);border-radius:18px;background:var(--dsw-alias-bg-module-platform,var(--dsw-alias-bg-layer-3));padding:
|
|
1359
|
+
".dshCodexCard{border:1px solid var(--dsw-alias-border-l2);border-radius:18px;background:var(--dsw-alias-bg-module-platform,var(--dsw-alias-bg-layer-3));padding:20px}",
|
|
949
1360
|
".dshCodexHeader{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}",
|
|
950
1361
|
".dshCodexHeader>div{min-width:0}",
|
|
951
1362
|
".dshCodexHeader h3,.dshCodexHeader p,.dshCodexNotices p,.dshCodexQuota p{margin:0}",
|
|
@@ -957,7 +1368,7 @@ window.__ModuleLoader__.load({
|
|
|
957
1368
|
".dshCodexStatus[data-state=active] .dshCodexStatusDot{background:var(--dsw-alias-state-success-primary)}",
|
|
958
1369
|
".dshCodexStatus[data-state=invalid] .dshCodexStatusDot{background:var(--dsw-alias-state-error-primary)}",
|
|
959
1370
|
".dshCodexStatus[data-state=busy] .dshCodexStatusDot{background:var(--dsw-alias-state-business-primary)}",
|
|
960
|
-
".dshCodexQuota{display:flex;min-width:0;flex-direction:column;gap:10px;border-top:1px solid var(--dsw-alias-border-l2);padding-top:
|
|
1371
|
+
".dshCodexQuota{display:flex;min-width:0;flex-direction:column;gap:10px;border-top:1px solid var(--dsw-alias-border-l2);padding-top:18px}",
|
|
961
1372
|
".dshCodexQuotaHeader{display:flex;min-width:0;align-items:center;justify-content:space-between;gap:12px}",
|
|
962
1373
|
".dshCodexQuota h3{margin:0;font-size:16px;font-weight:500;line-height:24px}",
|
|
963
1374
|
".dshCodexQuotaProduct{font-size:14px;font-weight:500;line-height:22px}",
|
|
@@ -966,6 +1377,19 @@ window.__ModuleLoader__.load({
|
|
|
966
1377
|
".dshCodexQuotaUnknown::before{background:var(--dsw-alias-label-tertiary)}",
|
|
967
1378
|
".dshCodexQuotaExhausted::before{background:var(--dsw-alias-state-error-primary)}",
|
|
968
1379
|
".dshCodexQuotaExhausted{color:var(--dsw-alias-state-error-primary)}",
|
|
1380
|
+
".dshCodexQuotaGroup{display:flex;min-width:0;flex-direction:column;gap:10px}",
|
|
1381
|
+
".dshCodexQuotaGroup+.dshCodexQuotaGroup{border-top:1px solid var(--dsw-alias-border-l2);padding-top:14px}",
|
|
1382
|
+
".dshCodexQuotaWindow{display:flex;min-width:0;flex-direction:column;gap:7px}",
|
|
1383
|
+
".dshCodexQuotaWindow+.dshCodexQuotaWindow{margin-top:4px}",
|
|
1384
|
+
".dshCodexQuotaWindowHeader,.dshCodexQuotaMeta{display:flex;min-width:0;align-items:center;justify-content:space-between;gap:12px}",
|
|
1385
|
+
".dshCodexQuotaWindowHeader{font-size:14px;line-height:22px}",
|
|
1386
|
+
".dshCodexQuotaWindowHeader strong{font-weight:400;color:var(--dsw-alias-label-secondary)}",
|
|
1387
|
+
".dshCodexQuotaMeta{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}",
|
|
1388
|
+
".dshCodexQuotaWindow progress{display:block;width:100%;height:8px;overflow:hidden;border:0;border-radius:999px;appearance:none;-webkit-appearance:none;background:var(--dsw-alias-bg-layer-1)}",
|
|
1389
|
+
".dshCodexQuotaWindow progress::-webkit-progress-bar{border-radius:999px;background:var(--dsw-alias-bg-layer-1)}",
|
|
1390
|
+
".dshCodexQuotaWindow progress::-webkit-progress-value{border-radius:999px;background:var(--dsw-alias-state-business-primary)}",
|
|
1391
|
+
".dshCodexQuotaWindow progress::-moz-progress-bar{border-radius:999px;background:var(--dsw-alias-state-business-primary)}",
|
|
1392
|
+
".dshCodexQuotaUpdated{margin-top:2px!important}",
|
|
969
1393
|
".dshCodexMuted{color:var(--dsw-alias-label-tertiary);font-size:14px;line-height:22px}",
|
|
970
1394
|
".dshCodexWarning{max-width:820px;color:var(--dsw-alias-label-secondary);font-size:14px;line-height:22px}",
|
|
971
1395
|
".dshCodexActions{display:flex;min-width:0;flex-wrap:wrap;gap:8px}",
|
|
@@ -976,6 +1400,15 @@ window.__ModuleLoader__.load({
|
|
|
976
1400
|
".dshCodexButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}",
|
|
977
1401
|
".dshCodexButton:focus-visible,.dshCodexModelOption:has(input:focus-visible){outline:2px solid var(--dsw-alias-brand-primary,var(--dsw-alias-border-l3));outline-offset:2px}",
|
|
978
1402
|
".dshCodexButton:disabled{cursor:not-allowed;opacity:.5}",
|
|
1403
|
+
".dshCodexFastToggle{box-sizing:border-box;display:inline-flex;width:28px;height:28px;flex:none;align-items:center;justify-content:center;border:0;border-radius:999px;background:transparent;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;padding:0;transition:background-color .15s ease,color .15s ease}",
|
|
1404
|
+
".dshCodexFastToggle:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2));color:var(--dsw-alias-label-primary)}",
|
|
1405
|
+
".dshCodexFastToggle[data-fast=true]{background:var(--dsw-alias-state-business-secondary,var(--dsw-alias-bg-layer-2));color:var(--dsw-alias-state-business-primary)}",
|
|
1406
|
+
".dshCodexFastToggle:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,var(--dsw-alias-border-l3));outline-offset:2px}",
|
|
1407
|
+
".dshCodexFastToggle:disabled{cursor:not-allowed;opacity:.45}",
|
|
1408
|
+
".dshCodexLegacyRepair{box-sizing:border-box;display:inline-flex;min-width:0;height:28px;flex:none;align-items:center;border:1px solid var(--dsw-alias-border-l2);border-radius:14px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-state-warning-primary,var(--dsw-alias-label-secondary));font:inherit;font-size:12px;line-height:18px;cursor:pointer;padding:0 10px;white-space:nowrap}",
|
|
1409
|
+
".dshCodexLegacyRepair:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}",
|
|
1410
|
+
".dshCodexLegacyRepair:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,var(--dsw-alias-border-l3));outline-offset:2px}",
|
|
1411
|
+
".dshCodexLegacyRepair:disabled{cursor:not-allowed;opacity:.55}",
|
|
979
1412
|
".dshCodexPrimary{border-color:var(--dsw-alias-button-primary-fill,var(--dsw-alias-state-business-primary));background:var(--dsw-alias-button-primary-fill,var(--dsw-alias-state-business-primary));color:var(--dsw-alias-label-primary-foreground,#fff)}",
|
|
980
1413
|
".dshCodexPrimary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover,var(--dsw-alias-state-business-primary))}",
|
|
981
1414
|
".dshCodexModelList{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:36px;row-gap:8px;margin:0;padding:0;list-style:none}",
|
|
@@ -984,9 +1417,12 @@ window.__ModuleLoader__.load({
|
|
|
984
1417
|
".dshCodexModelOption:has(input:disabled){cursor:not-allowed;opacity:.65}",
|
|
985
1418
|
".dshCodexModelOption:has(input:disabled):hover{background:transparent}",
|
|
986
1419
|
".dshCodexModelOption input{width:18px;height:18px;flex:none;margin:2px 0 0;accent-color:var(--dsw-alias-state-business-primary)}",
|
|
987
|
-
".
|
|
1420
|
+
".dshCodexModelCopy{display:flex;min-width:0;flex:1;flex-direction:column;gap:7px}",
|
|
1421
|
+
".dshCodexModelHeading{display:flex;min-width:0;flex-direction:column;gap:1px}",
|
|
988
1422
|
".dshCodexModelOption strong{overflow-wrap:anywhere;font-size:14px;font-weight:500;line-height:22px}",
|
|
989
|
-
".
|
|
1423
|
+
".dshCodexModelId{overflow-wrap:anywhere;color:var(--dsw-alias-label-tertiary);font-family:inherit;font-size:12px;line-height:18px}",
|
|
1424
|
+
".dshCodexModelCapabilities{display:flex;min-width:0;flex-wrap:wrap;gap:6px}",
|
|
1425
|
+
".dshCodexModelBadge{display:inline-flex;align-items:center;border-radius:999px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);font-family:inherit;font-size:12px;line-height:18px;padding:2px 8px}",
|
|
990
1426
|
".dshCodexModelActions{justify-content:flex-end;border-top:1px solid var(--dsw-alias-border-l2);padding-top:20px}",
|
|
991
1427
|
".dshCodexNotices{display:flex;min-width:0;flex-direction:column;gap:10px;margin:0;padding:0;list-style:none}",
|
|
992
1428
|
".dshCodexNotices li,.dshCodexPrompt{box-sizing:border-box;min-width:0;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-1);padding:14px 16px}",
|
|
@@ -998,9 +1434,9 @@ window.__ModuleLoader__.load({
|
|
|
998
1434
|
".dshCodexPrompt input,.dshCodexPrompt select{box-sizing:border-box;width:100%;min-width:0;height:38px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;padding:0 10px}",
|
|
999
1435
|
".dshCodexError{margin:0;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}",
|
|
1000
1436
|
".dshCodexSuccess{margin:0;color:var(--dsw-alias-state-success-primary);font-size:12px;line-height:18px}",
|
|
1001
|
-
"@media(max-width:760px){.
|
|
1437
|
+
"@media(max-width:760px){.dshCodexModelList{grid-template-columns:1fr}.dshCodexModelActions{justify-content:flex-start}}",
|
|
1002
1438
|
"@media(max-width:640px){.dshCodexAuthToolbar,.dshCodexHeader{align-items:stretch;flex-direction:column}.dshCodexAuthActions{margin-left:0;justify-content:flex-start}}",
|
|
1003
|
-
"@media(max-width:480px){
|
|
1439
|
+
"@media(max-width:480px){.dshCodexPage{gap:12px;padding:0 0 24px}.dshCodexCard{border-radius:14px;padding:16px}.dshCodexQuotaWindowHeader,.dshCodexQuotaMeta{align-items:flex-start;flex-direction:column;gap:2px}.dshCodexActions{align-items:stretch;flex-direction:column}.dshCodexButton{width:100%}}",
|
|
1004
1440
|
].join("")
|
|
1005
1441
|
const references = style[STYLE_REF_KEY]
|
|
1006
1442
|
style[STYLE_REF_KEY] = Number.isSafeInteger(references) && references > 0
|
|
@@ -1024,12 +1460,14 @@ window.__ModuleLoader__.load({
|
|
|
1024
1460
|
exports.AuthorizationSettings = AuthorizationSettings
|
|
1025
1461
|
exports.CHANNEL = CHANNEL
|
|
1026
1462
|
exports.CODEX_PROVIDER = CODEX_PROVIDER
|
|
1463
|
+
exports.CodexFastToggle = CodexFastToggle
|
|
1027
1464
|
exports.CodexSettings = CodexSettings
|
|
1028
1465
|
exports.ModelEnablementSettings = ModelEnablementSettings
|
|
1029
1466
|
exports.NS = NS
|
|
1030
1467
|
exports.apply = apply
|
|
1031
1468
|
exports.createAuthorizationClient = createAuthorizationClient
|
|
1032
1469
|
exports.createModelEnablementClient = createModelEnablementClient
|
|
1470
|
+
exports.createSessionPreferenceClient = createSessionPreferenceClient
|
|
1033
1471
|
exports.inject = inject
|
|
1034
1472
|
exports.safeQuotaSnapshot = safeQuotaSnapshot
|
|
1035
1473
|
return module.exports
|