@eddyskywalker/dsh-chatgpt-subscription 0.1.13 → 0.1.14
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 +5 -0
- package/README.md +3 -1
- package/lib/client.js +137 -34
- package/lib/client.js.map +1 -1
- package/lib/index.js +75 -7
- package/lib/types/client/CodexSubscriptionSection.d.ts +1 -0
- package/lib/types/client/CodexSubscriptionSection.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +15 -1
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/styles.d.ts.map +1 -1
- package/lib/types/host/adapter.d.ts +3 -1
- package/lib/types/host/adapter.d.ts.map +1 -1
- package/lib/types/host/model-catalog.d.ts +2 -1
- package/lib/types/host/model-catalog.d.ts.map +1 -1
- package/lib/types/host/preferences.d.ts.map +1 -1
- package/lib/types/host/routes.d.ts.map +1 -1
- package/lib/types/host/subagent-model-preference.d.ts +8 -0
- package/lib/types/host/subagent-model-preference.d.ts.map +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/contracts.d.ts +9 -0
- package/lib/types/shared/contracts.d.ts.map +1 -1
- package/lib/types/shared/model-catalog.d.ts +5 -0
- package/lib/types/shared/model-catalog.d.ts.map +1 -1
- package/lib/types/shared/preferences.d.ts.map +1 -1
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- 设置页新增内置子代理模型选择,新启动的 spawn/fork 子代理可统一路由到指定的 ChatGPT 订阅模型。
|
|
6
|
+
- 设置页新增 GPT-5.6 Sol / Terra / Luna 有效上下文窗口配置:默认 272K,可选最高 1M,并动态影响 DSH 的模型解析、压缩阈值与溢出判断。
|
|
7
|
+
|
|
3
8
|
## 0.1.12 - 2026-08-20
|
|
4
9
|
|
|
5
10
|
- 适配 DSH `0.1.0-rc.8`:peerDependencies / devDependencies 中全部 DSH 包范围从 `^0.1.0-rc.6` 提升至 `^0.1.0-rc.8`,并重新生成 package-lock.json。已在本机 rc.8 依赖集上验证:typecheck、55 项测试与 tsdown 构建全部通过,插件代码无需改动。
|
package/README.md
CHANGED
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
**设置页**
|
|
40
40
|
|
|
41
41
|
- 展示账号(脱敏 email、套餐、账号 ID 后四位)、连接状态、额度与订阅增强功能开关;
|
|
42
|
+
- 可选择新启动的内置子代理使用哪个 ChatGPT 订阅模型;该设置只改变子代理请求路由,不改变父会话模型;
|
|
43
|
+
- 5.6 Sol / Terra / Luna 默认使用 272K 有效上下文,可在设置中选择最高 1M,用于 DSH 压缩与溢出判断;其他模型保持目录声明值;
|
|
42
44
|
- 可访问的进度条、窄窗口/200% 缩放布局、深浅主题与 reduced-motion。
|
|
43
45
|
|
|
44
46
|
## 模型目录
|
|
@@ -108,7 +110,7 @@ npx @deepseek-ai/dsh plugin --profile web add "link:C:\absolute\path\to\dsh-chat
|
|
|
108
110
|
3. 完成 ChatGPT 登录;
|
|
109
111
|
4. 执行 **测试连接**。
|
|
110
112
|
|
|
111
|
-
DSH 模型选择器应显示 **“Codex(ChatGPT
|
|
113
|
+
DSH 模型选择器应显示 **“Codex(ChatGPT 订阅)”**。在同一设置页的“增强功能”中,还可配置新子代理模型和 GPT-5.6 系列的有效上下文窗口。子代理模型设置适用于 DSH 内置的 spawn/fork 子代理(其会话标记为 `origin: subagent`);外部 ACP/Codex CLI 等 provider-managed 子代理不经过本插件路由。
|
|
112
114
|
|
|
113
115
|
卸载前建议先在设置页点击 **“注销”**,它会删除当前平台的凭据和 Host 内存中的额度缓存。
|
|
114
116
|
|
package/lib/client.js
CHANGED
|
@@ -175,8 +175,6 @@ window.__ModuleLoader__.load({
|
|
|
175
175
|
const text = blocks.map((block) => block.type === "text" || block.type === "reasoning" ? block.text : "").filter(Boolean).join(" ").trim();
|
|
176
176
|
return text === "" ? null : text;
|
|
177
177
|
}
|
|
178
|
-
//#endregion
|
|
179
|
-
//#region src/shared/model-catalog.ts
|
|
180
178
|
const CODEX_MODEL_CATALOG = [
|
|
181
179
|
{
|
|
182
180
|
id: "gpt-5.6-sol",
|
|
@@ -242,7 +240,15 @@ window.__ModuleLoader__.load({
|
|
|
242
240
|
supportsReasoningSummary: false
|
|
243
241
|
}
|
|
244
242
|
];
|
|
245
|
-
CODEX_MODEL_CATALOG[0];
|
|
243
|
+
const DEFAULT_CODEX_MODEL = CODEX_MODEL_CATALOG[0];
|
|
244
|
+
const CONFIGURABLE_CONTEXT_MODEL_IDS = [
|
|
245
|
+
"gpt-5.6-sol",
|
|
246
|
+
"gpt-5.6-terra",
|
|
247
|
+
"gpt-5.6-luna"
|
|
248
|
+
];
|
|
249
|
+
function resolveCodexCatalogEntry(model) {
|
|
250
|
+
return CODEX_MODEL_CATALOG.find((entry) => entry.id === model) ?? DEFAULT_CODEX_MODEL;
|
|
251
|
+
}
|
|
246
252
|
//#endregion
|
|
247
253
|
//#region src/client/api.ts
|
|
248
254
|
var SubscriptionApi = class {
|
|
@@ -309,6 +315,7 @@ window.__ModuleLoader__.load({
|
|
|
309
315
|
const [authUrl, setAuthUrl] = (0, react.useState)(null);
|
|
310
316
|
const [popupBlocked, setPopupBlocked] = (0, react.useState)(false);
|
|
311
317
|
const [connection, setConnection] = (0, react.useState)(null);
|
|
318
|
+
const [contextDrafts, setContextDrafts] = (0, react.useState)({});
|
|
312
319
|
const load = (0, react.useCallback)(async (quiet = false) => {
|
|
313
320
|
if (!quiet) setError(null);
|
|
314
321
|
try {
|
|
@@ -419,6 +426,19 @@ window.__ModuleLoader__.load({
|
|
|
419
426
|
preferences
|
|
420
427
|
});
|
|
421
428
|
});
|
|
429
|
+
const updateContextWindow = async (model) => {
|
|
430
|
+
const current = status?.preferences.contextWindowOverrides[model] ?? resolveCodexCatalogEntry(model).contextWindow;
|
|
431
|
+
const parsed = parseCapacity(contextDrafts[model] ?? String(current));
|
|
432
|
+
if (parsed === null) {
|
|
433
|
+
setError(t("contextWindowInvalid"));
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
await updatePreferences({ contextWindowOverrides: { [model]: parsed } });
|
|
437
|
+
setContextDrafts((drafts) => ({
|
|
438
|
+
...drafts,
|
|
439
|
+
[model]: String(parsed)
|
|
440
|
+
}));
|
|
441
|
+
};
|
|
422
442
|
const logout = async () => run("logout", async () => {
|
|
423
443
|
await apiRef.current.logout();
|
|
424
444
|
eventSourceRef.current?.close();
|
|
@@ -564,38 +584,88 @@ window.__ModuleLoader__.load({
|
|
|
564
584
|
}),
|
|
565
585
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
|
|
566
586
|
title: t("enhancements"),
|
|
567
|
-
children: [
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
587
|
+
children: [
|
|
588
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
589
|
+
className: "dsh-codex-pref-row",
|
|
590
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("searchProvider") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
591
|
+
className: "dsh-codex-muted",
|
|
592
|
+
children: t("searchProviderHint")
|
|
593
|
+
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
594
|
+
className: "dsh-codex-segments",
|
|
595
|
+
role: "radiogroup",
|
|
596
|
+
"aria-label": t("searchProvider"),
|
|
597
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
598
|
+
type: "radio",
|
|
599
|
+
name: "dsh-codex-search-provider",
|
|
600
|
+
checked: status?.preferences.searchProvider === "dsh",
|
|
601
|
+
disabled: busy !== null,
|
|
602
|
+
onChange: () => updatePreferences({ searchProvider: "dsh" })
|
|
603
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("searchProviderDsh") })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
604
|
+
type: "radio",
|
|
605
|
+
name: "dsh-codex-search-provider",
|
|
606
|
+
checked: status?.preferences.searchProvider === "codex",
|
|
607
|
+
disabled: busy !== null,
|
|
608
|
+
onChange: () => updatePreferences({ searchProvider: "codex" })
|
|
609
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("searchProviderCodex") })] })]
|
|
610
|
+
})]
|
|
611
|
+
}),
|
|
612
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
613
|
+
className: "dsh-codex-pref-row",
|
|
614
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("subagentModel") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
615
|
+
className: "dsh-codex-muted",
|
|
616
|
+
children: t("subagentModelHint")
|
|
617
|
+
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
618
|
+
className: "dsh-codex-select",
|
|
619
|
+
"aria-label": t("subagentModel"),
|
|
620
|
+
value: status?.preferences.subagentModel ?? CODEX_MODEL_CATALOG[0].id,
|
|
580
621
|
disabled: busy !== null,
|
|
581
|
-
onChange: () => updatePreferences({
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
622
|
+
onChange: (event) => void updatePreferences({ subagentModel: event.currentTarget.value }),
|
|
623
|
+
children: CODEX_MODEL_CATALOG.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
624
|
+
value: model.id,
|
|
625
|
+
children: model.name
|
|
626
|
+
}, model.id))
|
|
627
|
+
})]
|
|
628
|
+
}),
|
|
629
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
630
|
+
className: "dsh-codex-context-settings",
|
|
631
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("contextWindows") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
632
|
+
className: "dsh-codex-muted",
|
|
633
|
+
children: t("contextWindowsHint")
|
|
634
|
+
})] }), CONFIGURABLE_CONTEXT_MODEL_IDS.map((model) => {
|
|
635
|
+
const fallback = status?.preferences.contextWindowOverrides[model] ?? resolveCodexCatalogEntry(model).contextWindow;
|
|
636
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
637
|
+
className: "dsh-codex-context-row",
|
|
638
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: resolveCodexCatalogEntry(model).name }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
639
|
+
className: "dsh-codex-capacity-control",
|
|
640
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
641
|
+
type: "text",
|
|
642
|
+
inputMode: "numeric",
|
|
643
|
+
value: contextDrafts[model] ?? formatCapacity(fallback),
|
|
644
|
+
disabled: busy !== null,
|
|
645
|
+
"aria-label": resolveCodexCatalogEntry(model).name + " " + t("contextWindow"),
|
|
646
|
+
onChange: (event) => setContextDrafts((drafts) => ({
|
|
647
|
+
...drafts,
|
|
648
|
+
[model]: event.currentTarget.value
|
|
649
|
+
})),
|
|
650
|
+
onBlur: () => void updateContextWindow(model),
|
|
651
|
+
onKeyDown: (event) => {
|
|
652
|
+
if (event.key === "Enter") event.currentTarget.blur();
|
|
653
|
+
}
|
|
654
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("tokens") })]
|
|
655
|
+
})]
|
|
656
|
+
}, model);
|
|
657
|
+
})]
|
|
658
|
+
}),
|
|
659
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
660
|
+
className: "dsh-codex-check",
|
|
661
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
662
|
+
type: "checkbox",
|
|
663
|
+
checked: status?.preferences.quickQuotaVisible === true,
|
|
586
664
|
disabled: busy !== null,
|
|
587
|
-
onChange: () => updatePreferences({
|
|
588
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
589
|
-
})
|
|
590
|
-
|
|
591
|
-
className: "dsh-codex-check",
|
|
592
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
593
|
-
type: "checkbox",
|
|
594
|
-
checked: status?.preferences.quickQuotaVisible === true,
|
|
595
|
-
disabled: busy !== null,
|
|
596
|
-
onChange: (event) => updatePreferences({ quickQuotaVisible: event.currentTarget.checked })
|
|
597
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("quickQuota") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("quickQuotaHint") })] })]
|
|
598
|
-
})]
|
|
665
|
+
onChange: (event) => updatePreferences({ quickQuotaVisible: event.currentTarget.checked })
|
|
666
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("quickQuota") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("quickQuotaHint") })] })]
|
|
667
|
+
})
|
|
668
|
+
]
|
|
599
669
|
}),
|
|
600
670
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
|
|
601
671
|
title: t("quota"),
|
|
@@ -777,6 +847,17 @@ window.__ModuleLoader__.load({
|
|
|
777
847
|
unitDisplay: "long"
|
|
778
848
|
}).format(value)} ${t("limitWindow")}`;
|
|
779
849
|
}
|
|
850
|
+
function parseCapacity(value) {
|
|
851
|
+
const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
|
|
852
|
+
if (matched === null) return null;
|
|
853
|
+
const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
|
|
854
|
+
const parsed = Number(matched[1]) * multiplier;
|
|
855
|
+
return Number.isSafeInteger(parsed) && parsed >= 1 && parsed <= 1e6 ? parsed : null;
|
|
856
|
+
}
|
|
857
|
+
function formatCapacity(value) {
|
|
858
|
+
if (value % 1e3 === 0) return `${value / 1e3}K`;
|
|
859
|
+
return String(value);
|
|
860
|
+
}
|
|
780
861
|
function formatPercent(value) {
|
|
781
862
|
return `${new Intl.NumberFormat(void 0, { maximumFractionDigits: 1 }).format(value)}%`;
|
|
782
863
|
}
|
|
@@ -853,6 +934,13 @@ window.__ModuleLoader__.load({
|
|
|
853
934
|
searchProviderHint: "选择 DSH Web 搜索工具使用默认来源,或改用当前 ChatGPT 订阅的 Codex 搜索来源。",
|
|
854
935
|
searchProviderDsh: "DSH 默认",
|
|
855
936
|
searchProviderCodex: "Codex 订阅",
|
|
937
|
+
subagentModel: "子代理模型",
|
|
938
|
+
subagentModelHint: "新启动的内置子代理使用此 ChatGPT 订阅模型;父会话的模型选择不受影响。",
|
|
939
|
+
contextWindows: "GPT-5.6 上下文窗口",
|
|
940
|
+
contextWindowsHint: "默认 272K;可选启用最高 1M。该值用于 DSH 的压缩与溢出判断,可输入 1M、512K 等容量。",
|
|
941
|
+
contextWindow: "上下文窗口",
|
|
942
|
+
contextWindowInvalid: "上下文窗口必须是 1 到 1M 的整数,可使用 K 或 M 后缀。",
|
|
943
|
+
tokens: "tokens",
|
|
856
944
|
quickQuota: "在输入框旁显示快捷用量",
|
|
857
945
|
quickQuotaHint: "仅在当前会话选中 codex-chatgpt 模型时显示。",
|
|
858
946
|
quota: "用量与限额",
|
|
@@ -936,6 +1024,13 @@ window.__ModuleLoader__.load({
|
|
|
936
1024
|
searchProviderHint: "Choose whether DSH web search uses its default provider or the Codex search source from this ChatGPT subscription.",
|
|
937
1025
|
searchProviderDsh: "DSH default",
|
|
938
1026
|
searchProviderCodex: "Codex subscription",
|
|
1027
|
+
subagentModel: "Subagent model",
|
|
1028
|
+
subagentModelHint: "New built-in subagents use this ChatGPT subscription model; the parent session selection is unchanged.",
|
|
1029
|
+
contextWindows: "GPT-5.6 context windows",
|
|
1030
|
+
contextWindowsHint: "Defaults to 272K, with an optional value up to 1M. DSH uses it for compaction and overflow detection; values such as 1M and 512K are accepted.",
|
|
1031
|
+
contextWindow: "Context window",
|
|
1032
|
+
contextWindowInvalid: "The context window must be an integer from 1 to 1M. K and M suffixes are accepted.",
|
|
1033
|
+
tokens: "tokens",
|
|
939
1034
|
quickQuota: "Show quick usage beside the composer",
|
|
940
1035
|
quickQuotaHint: "Shown only when the current session uses a codex-chatgpt model.",
|
|
941
1036
|
quota: "Usage and limits",
|
|
@@ -1014,6 +1109,14 @@ window.__ModuleLoader__.load({
|
|
|
1014
1109
|
.dsh-codex-segments input:checked+span{background:var(--dsw-alias-bg-base);box-shadow:0 1px 2px rgba(0,0,0,.08);color:var(--dsw-alias-label-primary)}
|
|
1015
1110
|
.dsh-codex-segments input:focus-visible+span{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}
|
|
1016
1111
|
.dsh-codex-segments input:disabled+span{cursor:default;opacity:.5}
|
|
1112
|
+
.dsh-codex-select,.dsh-codex-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px}
|
|
1113
|
+
.dsh-codex-select{max-width:210px;min-width:150px}
|
|
1114
|
+
.dsh-codex-context-settings{border-bottom:1px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}
|
|
1115
|
+
.dsh-codex-context-settings>div>strong{font-size:13px;font-weight:600}
|
|
1116
|
+
.dsh-codex-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}
|
|
1117
|
+
.dsh-codex-capacity-control{align-items:center;display:flex;gap:7px}
|
|
1118
|
+
.dsh-codex-capacity-control input{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;text-align:right;width:90px}
|
|
1119
|
+
.dsh-codex-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}
|
|
1017
1120
|
.dsh-codex-check{align-items:flex-start;border-bottom:1px solid var(--dsw-alias-border-l2);cursor:pointer;display:flex;gap:10px;padding:12px 0}
|
|
1018
1121
|
.dsh-codex-check input{flex:none;margin-top:2px}
|
|
1019
1122
|
.dsh-codex-check small{color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1.45;margin-top:2px}
|
|
@@ -1052,7 +1155,7 @@ window.__ModuleLoader__.load({
|
|
|
1052
1155
|
.dsh-codex-image-loading,.dsh-codex-image-failed{border:1px dashed var(--dsw-alias-border-l2);border-radius:8px;color:var(--dsw-alias-label-tertiary);display:inline-flex;font-size:12px;line-height:1.4;padding:18px 20px}
|
|
1053
1156
|
.dsh-codex-image-failed{color:var(--dsw-alias-label-danger,#d94b4b)}
|
|
1054
1157
|
@keyframes dsh-codex-pulse{0%,100%{opacity:.55}50%{opacity:1}}
|
|
1055
|
-
@media(max-width:560px){.dsh-codex-row,.dsh-codex-pref-row,.dsh-codex-quota-fact{align-items:flex-start;flex-direction:column;gap:3px}.dsh-codex-value,.dsh-codex-quota-fact strong{text-align:left}.dsh-codex-actions{justify-content:flex-start}.dsh-codex-grouphead{align-items:flex-start;flex-direction:column;gap:0;padding:12px 0}.dsh-codex-meter-meta{align-items:flex-start;flex-direction:column;gap:2px}.dsh-codex-errorbar{align-items:flex-start;flex-direction:column}.dsh-codex-segments{width:100%}.dsh-codex-segments label{flex:1}.dsh-codex-segments span{text-align:center}.dsh-codex-image-tool{max-width:100%;margin-left:0}}
|
|
1158
|
+
@media(max-width:560px){.dsh-codex-row,.dsh-codex-pref-row,.dsh-codex-quota-fact{align-items:flex-start;flex-direction:column;gap:3px}.dsh-codex-value,.dsh-codex-quota-fact strong{text-align:left}.dsh-codex-actions{justify-content:flex-start}.dsh-codex-grouphead{align-items:flex-start;flex-direction:column;gap:0;padding:12px 0}.dsh-codex-meter-meta{align-items:flex-start;flex-direction:column;gap:2px}.dsh-codex-errorbar{align-items:flex-start;flex-direction:column}.dsh-codex-segments{width:100%}.dsh-codex-select{max-width:none;width:100%}.dsh-codex-context-row{align-items:flex-start;flex-direction:column;gap:5px}.dsh-codex-segments label{flex:1}.dsh-codex-segments span{text-align:center}.dsh-codex-image-tool{max-width:100%;margin-left:0}}
|
|
1056
1159
|
@media(prefers-reduced-motion:reduce){.dsh-codex-meter>span{transition:none}.dsh-codex-skeleton span{animation:none}}
|
|
1057
1160
|
`;
|
|
1058
1161
|
function installStyles() {
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["formatPercent"],"sources":["../src/compat.ts","../src/client/quota.ts","../src/client/CodexComposerQuota.tsx","../src/client/CodexImageToolView.tsx","../src/shared/model-catalog.ts","../src/client/api.ts","../src/client/CodexSubscriptionSection.tsx","../src/client/locales.ts","../src/client/styles.ts","../src/client/index.tsx"],"sourcesContent":["/**\n * Compatibility constants for the ChatGPT-backed Codex flow. The backend and\n * OAuth parameters are not a public third-party API contract, so every such\n * value is isolated here for review and rollback.\n */\nexport const CHATGPT_OAUTH_ISSUER = 'https://auth.openai.com' as const\nexport const CHATGPT_OAUTH_CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann' as const\nexport const OAUTH_CALLBACK_HOST = 'localhost' as const\nexport const OAUTH_CALLBACK_PORT = 1455 as const\nexport const OAUTH_CALLBACK_PATH = '/auth/callback' as const\nexport const OAUTH_REDIRECT_URI = `http://${OAUTH_CALLBACK_HOST}:${OAUTH_CALLBACK_PORT}${OAUTH_CALLBACK_PATH}` as const\nexport const OAUTH_SCOPE = 'openid profile email offline_access' as const\nexport const OAUTH_ORIGINATOR = 'opencode' as const\nexport const OAUTH_LOGIN_TIMEOUT_MS = 5 * 60_000\nexport const TOKEN_REFRESH_MARGIN_MS = 60_000\nexport const ROUTE_PREFIX = '/api/dsh-chatgpt-subscription' as const\nexport const PLUGIN_VERSION = '0.1.0-alpha.0' as const\nexport const CODEX_CHATGPT_PROVIDER_ID = 'codex-chatgpt' as const\n\nexport const CODEX_API_BASE = 'https://chatgpt.com/backend-api/codex' as const\nexport const CODEX_RESPONSES_URL = `${CODEX_API_BASE}/responses` as const\nexport const CODEX_IMAGE_GENERATION_URL = `${CODEX_API_BASE}/images/generations` as const\nexport const CODEX_SEARCH_URL = `${CODEX_API_BASE}/alpha/search` as const\nexport const CODEX_USAGE_URL = 'https://chatgpt.com/backend-api/wham/usage' as const\nexport const CODEX_ORIGINATOR = 'opencode' as const\nexport const CODEX_ENHANCED_ORIGINATOR = 'pi' as const\nexport const CODEX_IMAGE_TOOL_NAME = 'codex_image_generate' as const\nexport const CODEX_IMAGE_MODEL = 'gpt-image-2' as const\nexport const CODEX_SEARCH_PROVIDER_ID = 'codex-subscription' as const\nexport const QUOTA_CACHE_MS = 60_000\nexport const QUOTA_MIN_UPSTREAM_INTERVAL_MS = 15_000\n\nexport const OAUTH_AUTHORIZE_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/authorize` as const\nexport const OAUTH_TOKEN_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/token` as const\n","import type { QuotaBucketDto, QuotaStatusDto, QuotaWindowDto } from '../shared/contracts.ts'\n\nexport interface SelectedQuotaWindow {\n bucket: QuotaBucketDto\n window: QuotaWindowDto\n remainingPercent: number\n}\n\nexport function selectQuotaForModel(quota: QuotaStatusDto | undefined, modelId: string | undefined): SelectedQuotaWindow | null {\n if (quota === undefined || quota.buckets.length === 0) return null\n const model = modelId?.toLowerCase() ?? ''\n const wantsSpark = model.includes('spark')\n const bucket = wantsSpark\n ? quota.buckets.find(candidate => `${candidate.id} ${candidate.name}`.toLowerCase().includes('spark'))\n : quota.buckets.find(candidate => candidate.id === 'codex')\n ?? quota.buckets.find(candidate => candidate.name.toLowerCase() === 'codex')\n if (bucket === undefined) return null\n const windows = quotaWindows(bucket)\n if (windows.length === 0) return null\n const window = windows.reduce((tightest, candidate) => (\n candidate.usedPercent > tightest.usedPercent ? candidate : tightest\n ), windows[0]!)\n return {\n bucket,\n window,\n remainingPercent: Math.max(0, 100 - window.usedPercent),\n }\n}\n\nexport function quotaWindows(bucket: QuotaBucketDto): QuotaWindowDto[] {\n if (bucket.windows.length > 0) return bucket.windows\n return [bucket.primary, bucket.secondary].filter((window): window is QuotaWindowDto => window !== null)\n}\n","import { useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { CODEX_CHATGPT_PROVIDER_ID } from '../compat.ts'\nimport type { PluginStatusDto } from '../shared/contracts.ts'\nimport { SubscriptionApi } from './api.ts'\nimport { NS } from './locales.ts'\nimport { selectQuotaForModel } from './quota.ts'\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS> & {\n api: SubscriptionApi\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\nexport function CodexComposerQuota({ api, directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n const modelState = useStore(directory)\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\n const [loading, setLoading] = useState(false)\n const mountedRef = useRef(false)\n const selected = modelState.current\n const isCodex = selected?.provider === CODEX_CHATGPT_PROVIDER_ID\n\n useEffect(() => {\n loadModelDirectory()\n }, [loadModelDirectory])\n\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n useEffect(() => {\n if (!isCodex) return\n let disposed = false\n const refresh = async (): Promise<void> => {\n setLoading(true)\n try {\n const next = await api.status()\n if (!disposed && mountedRef.current) setStatus(next)\n } catch {\n if (!disposed && mountedRef.current) setStatus(null)\n } finally {\n if (!disposed && mountedRef.current) setLoading(false)\n }\n }\n void refresh()\n const timer = window.setInterval(() => {\n if (document.visibilityState === 'visible') void refresh()\n }, 60_000)\n return () => {\n disposed = true\n window.clearInterval(timer)\n }\n }, [api, isCodex])\n\n const quota = useMemo(() => selectQuotaForModel(status?.quota, selected?.model), [selected?.model, status?.quota])\n if (!isCodex || status?.preferences.quickQuotaVisible !== true) return null\n const level = quota === null\n ? 'normal'\n : quota.remainingPercent <= 5\n ? 'danger'\n : quota.remainingPercent <= 20\n ? 'warning'\n : 'normal'\n return <span className=\"dsh-codex-composer-quota\" data-level={level} aria-label={quota === null ? t('quickQuotaLoading') : `${t('quickQuotaLabel')}: ${formatPercent(quota.remainingPercent)}`}>\n <span>{t('quickQuotaLabel')}</span>\n <strong>{quota === null ? (loading ? t('quickQuotaLoading') : '—') : formatPercent(quota.remainingPercent)}</strong>\n </span>\n}\n\nfunction useStore<T>(store: SnapshotStore<T>): T {\n return useSyncExternalStore(\n (listener) => store.subscribe(listener),\n () => store.getSnapshot(),\n () => store.getSnapshot(),\n )\n}\n\nfunction formatPercent(value: number): string {\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 0 }).format(value)}%`\n}\n","import { useEffect, useState } from 'react'\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type { ContentBlock } from '@deepseek-ai/dsh-client-connection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { NS } from './locales.ts'\n\nexport type ImageLoader = (attachment: ImageAttachmentRef) => Promise<string>\n\ntype Props = PropsRuntime<'tool.call.toolview'> & PropsLocale<typeof NS> & {\n loadImage: ImageLoader\n}\n\nexport function CodexImageToolView({ block, loadImage, t }: Props): React.JSX.Element {\n const settled = 'kind' in block\n const isError = settled ? block.isError : false\n const prompt = promptFromBlock(block)\n const images = settled && !isError ? imageBlocks(block.content) : []\n const label = isError ? t('imageToolFailed') : settled ? t('imageToolDone') : t('imageToolRunning')\n const summary = prompt ?? textSummary(settled ? block.content : [])\n return <div className=\"dsh-codex-image-tool\" data-state={isError ? 'error' : settled ? 'done' : 'running'}>\n <div className=\"dsh-codex-image-tool-head\">\n <span className=\"dsh-codex-image-dot\" aria-hidden=\"true\" />\n <span className=\"dsh-codex-image-title\">{label}</span>\n {summary !== null ? <span className=\"dsh-codex-image-summary\">{summary}</span> : null}\n </div>\n {images.length > 0 ? <div className=\"dsh-codex-image-grid\">\n {images.map((attachment) => <GeneratedImage key={String(attachment.attachmentId)} attachment={attachment} load={loadImage} label={attachment.name ?? t('image')} t={t} />)}\n </div> : null}\n </div>\n}\n\nfunction GeneratedImage({ attachment, load, label, t }: {\n attachment: ImageAttachmentRef\n load: ImageLoader\n label: string\n t: Props['t']\n}): React.JSX.Element {\n const [src, setSrc] = useState<string | null>(null)\n const [failed, setFailed] = useState(false)\n useEffect(() => {\n let disposed = false\n setSrc(null)\n setFailed(false)\n load(attachment).then((url) => {\n if (!disposed) setSrc(url)\n }, () => {\n if (!disposed) setFailed(true)\n })\n return () => {\n disposed = true\n }\n }, [attachment, load])\n if (failed) return <span className=\"dsh-codex-image-failed\">{t('imageLoadFailed')}</span>\n if (src === null) return <span className=\"dsh-codex-image-loading\">{t('imageLoading')}</span>\n return <img className=\"dsh-codex-image-preview\" src={src} alt={label} />\n}\n\nfunction promptFromBlock(block: Props['block']): string | null {\n const raw = 'kind' in block ? block.call?.argsRaw : block.argsRaw\n if (typeof raw !== 'string' || raw.trim() === '') return null\n try {\n const value = JSON.parse(raw) as unknown\n return typeof value === 'object'\n && value !== null\n && !Array.isArray(value)\n && typeof (value as { prompt?: unknown }).prompt === 'string'\n ? (value as { prompt: string }).prompt\n : null\n } catch {\n return null\n }\n}\n\nfunction imageBlocks(blocks: readonly ContentBlock[]): ImageAttachmentRef[] {\n const result: ImageAttachmentRef[] = []\n for (const block of blocks) {\n if (block.type === 'image') result.push(block.attachment)\n if (block.type === 'tool-result') result.push(...imageBlocks(block.content))\n }\n return result\n}\n\nfunction textSummary(blocks: readonly ContentBlock[]): string | null {\n const text = blocks\n .map((block) => block.type === 'text' || block.type === 'reasoning' ? block.text : '')\n .filter(Boolean)\n .join(' ')\n .trim()\n return text === '' ? null : text\n}\n","export type CodexModelModality = 'text' | 'image'\n\nexport interface CodexModelCatalogEntry {\n id: string\n name: string\n contextWindow: number\n inputModalities: readonly CodexModelModality[]\n defaultReasoningEffort: string\n reasoningProfile: 'standard' | 'gpt-5.6'\n supportsReasoningSummary: boolean\n}\n\nexport const CODEX_MODEL_CATALOG = [\n {\n id: 'gpt-5.6-sol',\n name: '5.6 Sol',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.6-terra',\n name: '5.6 Terra',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.6-luna',\n name: '5.6 Luna',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.5',\n name: '5.5',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.4',\n name: '5.4',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'none',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.4-mini',\n name: '5.4 Mini',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'none',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.3-codex-spark',\n name: '5.3 Codex Spark',\n contextWindow: 258_000,\n inputModalities: ['text'],\n defaultReasoningEffort: 'high',\n reasoningProfile: 'standard',\n supportsReasoningSummary: false,\n },\n] as const satisfies readonly CodexModelCatalogEntry[]\n\nexport type CodexModelId = typeof CODEX_MODEL_CATALOG[number]['id']\n\nexport const DEFAULT_CODEX_MODEL = CODEX_MODEL_CATALOG[0]\n\nexport function resolveCodexCatalogEntry(model: string): CodexModelCatalogEntry {\n return CODEX_MODEL_CATALOG.find((entry) => entry.id === model) ?? DEFAULT_CODEX_MODEL\n}\n\nexport function codexModelSupportsImageInput(model: string): boolean {\n return resolveCodexCatalogEntry(model).inputModalities.includes('image')\n}\n\nexport function codexModelSupportsReasoningSummary(model: string): boolean {\n return resolveCodexCatalogEntry(model).supportsReasoningSummary\n}\n","import { ROUTE_PREFIX } from '../compat.ts'\r\nimport type {\r\n ApiEnvelope,\r\n LoginEventDto,\r\n LoginStartDto,\r\n PluginStatusDto,\n QuotaStatusDto,\n ConnectionTestDto,\n SubscriptionPreferencesDto,\n SubscriptionPreferencesUpdateDto,\n} from '../shared/contracts.ts'\n\r\nexport class SubscriptionApi {\r\n status(): Promise<PluginStatusDto> {\r\n return request<PluginStatusDto>(`${ROUTE_PREFIX}/status`)\r\n }\r\n\r\n startLogin(): Promise<LoginStartDto> {\r\n return post<LoginStartDto>(`${ROUTE_PREFIX}/login/start`, {})\r\n }\r\n\r\n cancelLogin(loginId: string): Promise<{ cancelled: boolean }> {\r\n return post(`${ROUTE_PREFIX}/login/cancel`, { loginId })\r\n }\r\n\r\n logout(): Promise<{ authenticated: false }> {\r\n return post(`${ROUTE_PREFIX}/logout`, {})\r\n }\r\n\r\n refresh(): Promise<PluginStatusDto> {\r\n return post(`${ROUTE_PREFIX}/token/refresh`, {})\r\n }\r\n\r\n refreshQuota(): Promise<QuotaStatusDto> {\r\n return post(`${ROUTE_PREFIX}/quota/refresh`, {})\r\n }\r\n\r\n testConnection(): Promise<ConnectionTestDto> {\n return post(`${ROUTE_PREFIX}/connection/test`, {})\n }\n\n updatePreferences(patch: SubscriptionPreferencesUpdateDto): Promise<SubscriptionPreferencesDto> {\n return post(`${ROUTE_PREFIX}/preferences/update`, patch)\n }\n\n events(loginId: string): EventSource {\n return new EventSource(`${ROUTE_PREFIX}/login/events?loginId=${encodeURIComponent(loginId)}`)\n }\n}\n\r\nasync function post<T>(url: string, body: object): Promise<T> {\n return request<T>(url, {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json' },\r\n body: JSON.stringify(body),\r\n })\r\n}\r\n\r\nasync function request<T>(url: string, init?: RequestInit): Promise<T> {\r\n const response = await fetch(url, { ...init, credentials: 'same-origin' })\r\n const envelope = await response.json() as ApiEnvelope<T>\r\n if (!response.ok || !envelope.ok) {\r\n throw new Error(envelope.ok ? `Request failed (${response.status})` : envelope.error.message)\r\n }\r\n return envelope.value\r\n}\r\n\r\nexport function parseLoginEvent(event: MessageEvent<string>): LoginEventDto | null {\r\n try {\r\n const value = JSON.parse(event.data) as LoginEventDto\r\n return typeof value === 'object' && value !== null && typeof value.type === 'string' ? value : null\r\n } catch {\r\n return null\r\n }\r\n}\r\n","import { useCallback, useEffect, useRef, useState } from 'react'\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type { CredentialStorageDto, PluginStatusDto, QuotaBucketDto, QuotaWindowDto, SubscriptionPreferencesUpdateDto } from '../shared/contracts.ts'\r\nimport { CODEX_MODEL_CATALOG } from '../shared/model-catalog.ts'\r\nimport { SubscriptionApi, parseLoginEvent } from './api.ts'\r\nimport { NS } from './locales.ts'\r\nimport { quotaWindows } from './quota.ts'\r\n\r\ntype Props = PropsRuntime<'settings.section'> & PropsLocale<typeof NS>\r\ntype BusyAction = 'login' | 'token' | 'quota' | 'test' | 'logout' | 'preferences' | null\r\ntype Translate = Props['t']\r\n\r\nexport function CodexSubscriptionSection({ t }: Props): React.JSX.Element {\r\n const apiRef = useRef(new SubscriptionApi())\r\n const eventSourceRef = useRef<EventSource | null>(null)\r\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\r\n const [busy, setBusy] = useState<BusyAction>(null)\r\n const [error, setError] = useState<string | null>(null)\r\n const [authUrl, setAuthUrl] = useState<string | null>(null)\r\n const [popupBlocked, setPopupBlocked] = useState(false)\r\n const [connection, setConnection] = useState<{ latencyMs: number; checkedAt: number } | null>(null)\r\n\r\n const load = useCallback(async (quiet = false) => {\r\n if (!quiet) setError(null)\r\n try {\r\n const next = await apiRef.current.status()\r\n setStatus(next)\r\n if (next.error !== undefined) setError(next.error.message)\r\n } catch (cause) {\r\n if (!quiet) setError(messageOf(cause))\r\n }\r\n }, [])\r\n\r\n useEffect(() => {\r\n void load()\r\n const refreshWhenVisible = (): void => {\r\n if (document.visibilityState === 'visible') void load(true)\r\n }\r\n document.addEventListener('visibilitychange', refreshWhenVisible)\r\n const timer = window.setInterval(refreshWhenVisible, 60_000)\r\n return () => {\r\n window.clearInterval(timer)\r\n document.removeEventListener('visibilitychange', refreshWhenVisible)\r\n eventSourceRef.current?.close()\r\n }\r\n }, [load])\r\n\r\n const watchLogin = useCallback((loginId: string) => {\r\n eventSourceRef.current?.close()\r\n const source = apiRef.current.events(loginId)\r\n eventSourceRef.current = source\r\n const finish = async (message?: string): Promise<void> => {\r\n source.close()\r\n eventSourceRef.current = null\r\n setBusy(null)\r\n setAuthUrl(null)\r\n if (message !== undefined) setError(message)\r\n // Preserve the terminal OAuth error while refreshing the account DTO.\r\n await load(true)\r\n }\r\n source.addEventListener('completed', (event) => {\r\n const parsed = parseLoginEvent(event as MessageEvent<string>)\r\n if (parsed?.type === 'completed') void finish()\r\n })\r\n source.addEventListener('cancelled', () => void finish())\r\n source.addEventListener('failed', (event) => {\r\n const parsed = parseLoginEvent(event as MessageEvent<string>)\r\n void finish(parsed?.type === 'failed' ? parsed.error.message : 'ChatGPT sign-in failed.')\r\n })\r\n }, [load])\r\n\r\n useEffect(() => {\r\n const loginId = status?.login.active ? status.login.loginId : null\r\n if (loginId !== null && loginId !== undefined && eventSourceRef.current === null) watchLogin(loginId)\r\n }, [status?.login.active, status?.login.loginId, watchLogin])\r\n\r\n const startLogin = async (): Promise<void> => {\r\n setBusy('login')\r\n setError(null)\r\n setPopupBlocked(false)\r\n const popup = window.open('about:blank', 'dsh-chatgpt-oauth', 'popup,width=560,height=760')\r\n try {\r\n const login = await apiRef.current.startLogin()\r\n setAuthUrl(login.authUrl)\r\n if (popup === null) setPopupBlocked(true)\r\n else popup.location.replace(login.authUrl)\r\n watchLogin(login.loginId)\r\n await load(true)\r\n } catch (cause) {\r\n popup?.close()\r\n setBusy(null)\r\n setError(messageOf(cause))\r\n }\r\n }\r\n\r\n const cancelLogin = async (): Promise<void> => {\r\n const loginId = status?.login.loginId\r\n if (loginId === null || loginId === undefined) return\r\n setBusy('login')\r\n try {\r\n await apiRef.current.cancelLogin(loginId)\r\n eventSourceRef.current?.close()\r\n eventSourceRef.current = null\r\n setAuthUrl(null)\r\n await load()\r\n } catch (cause) {\r\n setError(messageOf(cause))\r\n } finally {\r\n setBusy(null)\r\n }\r\n }\r\n\r\n const refreshToken = async (): Promise<void> => run('token', async () => {\r\n setStatus(await apiRef.current.refresh())\r\n })\r\n\r\n const refreshQuota = async (): Promise<void> => run('quota', async () => {\r\n const quota = await apiRef.current.refreshQuota()\r\n setStatus((current) => current === null ? current : { ...current, quota })\r\n })\r\n\r\n const testConnection = async (): Promise<void> => run('test', async () => {\r\n const result = await apiRef.current.testConnection()\r\n setConnection({ latencyMs: result.latencyMs, checkedAt: result.checkedAt })\r\n })\r\n\r\n const updatePreferences = async (patch: SubscriptionPreferencesUpdateDto): Promise<void> => run('preferences', async () => {\r\n const preferences = await apiRef.current.updatePreferences(patch)\r\n setStatus((current) => current === null ? current : { ...current, preferences })\r\n })\r\n\r\n const logout = async (): Promise<void> => run('logout', async () => {\r\n await apiRef.current.logout()\r\n eventSourceRef.current?.close()\r\n eventSourceRef.current = null\r\n setAuthUrl(null)\r\n setConnection(null)\r\n await load()\r\n })\r\n\r\n const run = async (action: Exclude<BusyAction, null>, task: () => Promise<void>): Promise<void> => {\r\n setBusy(action)\r\n setError(null)\r\n try {\r\n await task()\r\n } catch (cause) {\r\n setError(messageOf(cause))\r\n } finally {\r\n setBusy(null)\r\n }\r\n }\r\n\r\n const account = status?.account\r\n return <section className=\"dsh-codex-page\" aria-labelledby=\"dsh-codex-title\">\r\n <header>\r\n <h2 id=\"dsh-codex-title\" className=\"dsh-codex-title\">{t('title')}</h2>\r\n <p className=\"dsh-codex-intro\">{t('intro')}</p>\r\n </header>\r\n\r\n {error !== null ? <div className=\"dsh-codex-errorbar\" role=\"alert\">\r\n <span>{error}</span>\r\n {status === null ? <Button disabled={busy !== null} onClick={() => load()}>{t('retry')}</Button> : null}\r\n </div> : null}\r\n\r\n {status === null && error === null ? <Skeleton label={t('loading')} /> : <>\r\n <Section title={t('account')}>\r\n <InfoRow label={status?.authenticated ? t('signedIn') : t('signedOut')} value={account?.email ?? '—'} />\r\n {status?.authenticated ? <>\r\n <InfoRow label={t('plan')} value={account?.planType ?? t('unknown')} />\r\n <InfoRow label={t('accountId')} value={account?.accountIdSuffix ?? '—'} />\r\n <InfoRow label={t('expires')} value={formatDate(account?.tokenExpiresAt)} />\r\n </> : null}\r\n <InfoRow label={t('storage')} value={storageLabel(status?.storage, t)} />\r\n <p className=\"dsh-codex-notice\">{storageNotice(status?.storage, t)}</p>\r\n {status?.login.active ? <p className=\"dsh-codex-muted\" role=\"status\">{t('pending')}</p> : null}\r\n {popupBlocked ? <p className=\"dsh-codex-error\">{t('popupBlocked')}</p> : null}\r\n {authUrl !== null ? <a className=\"dsh-codex-link\" href={authUrl} target=\"_blank\" rel=\"noreferrer\">{t('continueLogin')}</a> : null}\r\n <div className=\"dsh-codex-actions\">\r\n {status?.login.active\r\n ? <Button disabled={busy !== null} onClick={cancelLogin}>{t('cancel')}</Button>\r\n : <Button primary disabled={busy !== null || status?.storage.available === false} onClick={startLogin}>{status?.authenticated ? t('signInAgain') : t('signIn')}</Button>}\r\n {status?.authenticated ? <>\r\n <Button disabled={busy !== null} onClick={refreshToken}>{t('refreshToken')}</Button>\r\n <Button disabled={busy !== null} onClick={logout}>{t('signOut')}</Button>\r\n </> : null}\r\n </div>\r\n </Section>\r\n\r\n <Section title={t('connection')}>\r\n <InfoRow label={t('provider')} value=\"Codex(ChatGPT 订阅) · codex-chatgpt\" />\r\n <InfoRow label={t('connectionState')} value={connection === null ? t('untested') : t('connected')} />\r\n {connection !== null ? <InfoRow label={t('latency')} value={`${connection.latencyMs} ms · ${formatDate(connection.checkedAt)}`} /> : null}\r\n <div className=\"dsh-codex-models\" aria-label={t('models')}>\r\n {CODEX_MODEL_CATALOG.map((model) => <code key={model.id} title={model.id}>{model.name}</code>)}\r\n </div>\r\n <div className=\"dsh-codex-actions\">\r\n <Button disabled={!status?.authenticated || busy !== null} onClick={testConnection}>{busy === 'test' ? t('testing') : t('testConnection')}</Button>\r\n </div>\r\n </Section>\r\n\r\n <Section title={t('enhancements')}>\r\n <div className=\"dsh-codex-pref-row\">\r\n <div>\r\n <strong>{t('searchProvider')}</strong>\r\n <p className=\"dsh-codex-muted\">{t('searchProviderHint')}</p>\r\n </div>\r\n <div className=\"dsh-codex-segments\" role=\"radiogroup\" aria-label={t('searchProvider')}>\r\n <label>\r\n <input type=\"radio\" name=\"dsh-codex-search-provider\" checked={status?.preferences.searchProvider === 'dsh'} disabled={busy !== null} onChange={() => updatePreferences({ searchProvider: 'dsh' })} />\r\n <span>{t('searchProviderDsh')}</span>\r\n </label>\r\n <label>\r\n <input type=\"radio\" name=\"dsh-codex-search-provider\" checked={status?.preferences.searchProvider === 'codex'} disabled={busy !== null} onChange={() => updatePreferences({ searchProvider: 'codex' })} />\r\n <span>{t('searchProviderCodex')}</span>\r\n </label>\r\n </div>\r\n </div>\r\n <label className=\"dsh-codex-check\">\r\n <input type=\"checkbox\" checked={status?.preferences.quickQuotaVisible === true} disabled={busy !== null} onChange={(event) => updatePreferences({ quickQuotaVisible: event.currentTarget.checked })} />\r\n <span>\r\n <strong>{t('quickQuota')}</strong>\r\n <small>{t('quickQuotaHint')}</small>\r\n </span>\r\n </label>\r\n </Section>\r\n\r\n <Section title={t('quota')} aside={<Button disabled={!status?.authenticated || busy !== null} onClick={refreshQuota}>{busy === 'quota' ? t('refreshing') : t('refreshQuota')}</Button>}>\r\n <p className=\"dsh-codex-muted\">{t('quotaIntro')}</p>\r\n {status?.quota.state === 'signed-out' ? <p className=\"dsh-codex-empty\">{t('quotaSignedOut')}</p> : null}\r\n {status?.quota.buckets.map((bucket) => <QuotaBucket key={bucket.id} bucket={bucket} t={t} />)}\r\n {status?.quota.credits !== null && status?.quota.credits !== undefined ? <QuotaFact label={t('credits')} value={status.quota.credits.unlimited ? t('unlimited') : status.quota.credits.balance ?? (status.quota.credits.hasCredits ? t('available') : t('unavailable'))} /> : null}\r\n {status?.quota.individualLimit !== null && status?.quota.individualLimit !== undefined ? <QuotaFact label={t('monthlySpend')} value={individualLimitLabel(status.quota.individualLimit, t)} /> : null}\r\n {status?.quota.resetCredits !== null && status?.quota.resetCredits !== undefined ? <QuotaFact label={t('resetCredits')} value={String(status.quota.resetCredits.availableCount)} /> : null}\r\n {status?.quota.spendControlReached === true ? <p className=\"dsh-codex-warning\" role=\"status\">{t('spendControlReached')}</p> : null}\r\n {status?.quota.state === 'empty' ? <p className=\"dsh-codex-empty\">{t('noQuota')}</p> : null}\r\n {status?.quota.stale ? <p className=\"dsh-codex-warning\" role=\"status\">{t('stale')}</p> : null}\r\n {status?.quota.error ? <p className=\"dsh-codex-error\" role=\"alert\">{status.quota.error.message}</p> : null}\r\n {status?.quota.fetchedAt ? <p className=\"dsh-codex-timestamp\">{t('updated')}: {formatDate(status.quota.fetchedAt)}</p> : null}\r\n </Section>\r\n </>}\r\n\r\n <span className=\"dsh-codex-sr\" aria-live=\"polite\">{busy === null ? '' : busy}</span>\r\n </section>\r\n}\r\n\r\nfunction Section({ title, aside, children }: { title: string; aside?: React.ReactNode; children: React.ReactNode }): React.JSX.Element {\r\n return <section className=\"dsh-codex-group\">\r\n <div className=\"dsh-codex-grouphead\"><h3>{title}</h3>{aside}</div>\r\n {children}\r\n </section>\r\n}\r\n\r\nfunction Button({ primary = false, disabled, onClick, children }: { primary?: boolean; disabled?: boolean; onClick: () => void | Promise<void>; children: React.ReactNode }): React.JSX.Element {\r\n return <button className={`dsh-codex-button${primary ? ' dsh-codex-button-primary' : ''}`} type=\"button\" disabled={disabled} onClick={() => void onClick()}>{children}</button>\r\n}\r\n\r\nfunction InfoRow({ label, value }: { label: string; value: string }): React.JSX.Element {\r\n return <div className=\"dsh-codex-row\"><span className=\"dsh-codex-label\">{label}</span><span className=\"dsh-codex-value\">{value}</span></div>\r\n}\r\n\r\nexport function storageLabel(storage: CredentialStorageDto | undefined, t: Translate): string {\r\n if (storage === undefined || !storage.available) return t('storageUnavailable')\r\n if (storage.kind === 'windows-dpapi') return t('storageWindows')\r\n if (storage.kind === 'macos-keychain') return t('storageMacKeychain')\r\n if (storage.kind === 'linux-file') return t('storageLinuxFile')\r\n if (storage.kind === 'memory') return t('storageMemory')\r\n return t('storageUnavailable')\r\n}\r\n\r\nexport function storageNotice(storage: CredentialStorageDto | undefined, t: Translate): string {\r\n if (storage === undefined || !storage.available) return t('securityUnavailable')\r\n if (storage.kind === 'windows-dpapi') return t('securityWindows')\r\n if (storage.kind === 'macos-keychain') return t('securityMacKeychain')\r\n if (storage.kind === 'linux-file') return t('securityLinuxFile')\r\n if (storage.kind === 'memory') return t('securityMemory')\r\n return t('securityUnavailable')\r\n}\r\n\r\nfunction QuotaBucket({ bucket, t }: { bucket: QuotaBucketDto; t: Translate }): React.JSX.Element {\r\n const windows = quotaWindows(bucket)\r\n return <article className=\"dsh-codex-quota-card\">\r\n <div className=\"dsh-codex-quota-title\"><strong>{bucket.name}</strong>{bucket.planType ? <span>{bucket.planType}</span> : null}</div>\r\n {windows.map((window, index) => <QuotaBar key={`${window.windowDurationMins ?? 'x'}:${window.resetsAt ?? 'x'}:${index}`} label={windowLabel(window.windowDurationMins, t)} window={window} t={t} />)}\r\n </article>\r\n}\r\n\r\nfunction QuotaFact({ label, value }: { label: string; value: string }): React.JSX.Element {\r\n return <div className=\"dsh-codex-quota-fact\"><span>{label}</span><strong>{value}</strong></div>\r\n}\r\n\r\nexport function QuotaBar({ label, window, t }: { label: string; window: QuotaWindowDto; t: Translate }): React.JSX.Element {\r\n const percent = window.usedPercent\r\n const level = percent >= 95 ? 'danger' : percent >= 80 ? 'warning' : 'normal'\r\n const remaining = Math.max(0, 100 - percent)\r\n return <div className=\"dsh-codex-meter-wrap\">\r\n <div className=\"dsh-codex-meter-label\"><span>{label}</span><strong>{formatPercent(percent)}</strong></div>\r\n <div className={`dsh-codex-meter dsh-codex-meter-${level}`} role=\"progressbar\" aria-label={`${label}: ${formatPercent(percent)} ${t('used')}`} aria-valuemin={0} aria-valuemax={100} aria-valuenow={percent}>\r\n <span style={{ width: `${percent}%` }} />\r\n </div>\r\n <div className=\"dsh-codex-meter-meta\">\r\n <span>{percent >= 100 ? `${t('exhausted')} · ${formatPercent(remaining)} ${t('remaining')}` : `${formatPercent(percent)} ${t('used')} · ${formatPercent(remaining)} ${t('remaining')}`}</span>\r\n <span>{window.resetsAt === null ? '—' : `${t('resets')}: ${formatReset(window.resetsAt)}`}</span>\r\n </div>\r\n </div>\r\n}\r\n\r\nfunction Skeleton({ label }: { label: string }): React.JSX.Element {\r\n return <div className=\"dsh-codex-skeleton\" role=\"status\" aria-label={label}><span /><span /></div>\r\n}\r\n\r\nexport function windowLabel(minutes: number | null, t: Translate): string {\r\n if (minutes === null) return t('limitWindow')\r\n const [value, unit]: [number, Intl.NumberFormatOptions['unit']] = minutes >= 1440 && minutes % 1440 === 0\r\n ? [minutes / 1440, 'day']\r\n : minutes >= 60 && minutes % 60 === 0\r\n ? [minutes / 60, 'hour']\r\n : [Math.round(minutes), 'minute']\r\n return `${new Intl.NumberFormat(undefined, { style: 'unit', unit, unitDisplay: 'long' }).format(value)} ${t('limitWindow')}`\r\n}\r\n\r\nfunction formatPercent(value: number): string {\r\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value)}%`\r\n}\r\n\r\nfunction individualLimitLabel(limit: NonNullable<PluginStatusDto['quota']['individualLimit']>, t: Translate): string {\r\n const parts = [\r\n limit.remainingPercent !== null ? `${formatPercent(limit.remainingPercent)} ${t('remaining')}` : null,\r\n limit.limit !== null ? `${t('limit')}: ${limit.limit}` : null,\r\n limit.used !== null ? `${t('used')}: ${limit.used}` : null,\r\n limit.resetsAt !== null ? `${t('resets')}: ${formatReset(limit.resetsAt)}` : null,\r\n ].filter((part): part is string => part !== null)\r\n return parts.length > 0 ? parts.join(' · ') : t('unknown')\r\n}\r\n\r\nfunction formatDate(seconds: number | undefined): string {\r\n if (seconds === undefined) return '—'\r\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(seconds * 1000)\r\n}\r\n\r\nexport function formatReset(seconds: number): string {\r\n const absolute = formatDate(seconds)\r\n const diff = seconds * 1000 - Date.now()\r\n const abs = Math.abs(diff)\r\n const [amount, unit]: [number, Intl.RelativeTimeFormatUnit] = abs >= 86_400_000\r\n ? [Math.round(diff / 86_400_000), 'day']\r\n : abs >= 3_600_000\r\n ? [Math.round(diff / 3_600_000), 'hour']\r\n : [Math.round(diff / 60_000), 'minute']\r\n return `${absolute} (${new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' }).format(amount, unit)})`\r\n}\r\n\r\nfunction messageOf(error: unknown): string {\r\n return error instanceof Error ? error.message : String(error)\r\n}\r\n","export const NS = 'dsh-chatgpt-subscription' as const\n\nexport const zh = {\n title: 'Codex 订阅',\n intro: '使用 ChatGPT 账号登录,在 DSH 中使用订阅可用的 Codex 模型。',\n account: '账号',\n signedOut: '尚未登录',\n signedIn: '已登录',\n plan: '套餐',\n accountId: '账号 ID',\n expires: '令牌到期',\n storage: '凭据存储',\n storageWindows: 'Windows DPAPI(当前用户加密)',\n storageMacKeychain: 'macOS 钥匙串(Keychain 加密)',\n storageLinuxFile: 'Linux 用户私有文件(权限 0600)',\n storageMemory: '仅 Host 内存(不持久化)',\n storageUnavailable: '凭据存储不可用',\n securityWindows: '令牌由 Host 使用 Windows CurrentUser DPAPI 加密,不会进入浏览器、settings.yaml 或日志。',\n securityMacKeychain: '令牌由 Host 存入 macOS 登录钥匙串(Keychain),在本机加密保存,不会进入浏览器、settings.yaml 或日志。',\n securityLinuxFile: '令牌仅写入 Host 上当前 Linux 用户可读的 0600 文件,但不会额外加密;同 UID 进程、root、备份和磁盘快照仍可能读取。',\n securityMemory: '令牌仅保留在 Host 内存中,Host 退出后丢失。',\n securityUnavailable: 'Host 无法安全访问凭据存储;请修复文件所有者或权限后重试。',\n signIn: '使用 ChatGPT 登录',\n signInAgain: '重新登录',\n cancel: '取消登录',\n signOut: '注销',\n refreshToken: '刷新凭据',\n pending: '请在浏览器中完成登录。',\n popupBlocked: '浏览器拦截了登录窗口,请使用下面的链接继续。',\n continueLogin: '打开 ChatGPT 登录页',\n loading: '正在读取状态…',\n connection: '连接',\n provider: 'Provider',\n connectionState: '连接状态',\n connected: '可用',\n untested: '尚未测试',\n testConnection: '测试连接',\n testing: '测试中…',\n latency: '最近延迟',\n models: '可用模型',\n enhancements: '增强功能',\n searchProvider: '搜索来源',\n searchProviderHint: '选择 DSH Web 搜索工具使用默认来源,或改用当前 ChatGPT 订阅的 Codex 搜索来源。',\n searchProviderDsh: 'DSH 默认',\n searchProviderCodex: 'Codex 订阅',\n quickQuota: '在输入框旁显示快捷用量',\n quickQuotaHint: '仅在当前会话选中 codex-chatgpt 模型时显示。',\n quota: '用量与限额',\n quotaIntro: '数据来自 ChatGPT Codex 用量服务。页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshing: '刷新中…',\n noQuota: '当前套餐未返回可显示的限额窗口。',\n quotaSignedOut: '登录后可查看订阅限额。',\n stale: '显示的是上次成功获取的数据。',\n updated: '更新时间',\n primary: '主要窗口',\n secondary: '次要窗口',\n limitWindow: '额度',\n used: '已使用',\n remaining: '剩余',\n available: '可用',\n unavailable: '不可用',\n unlimited: '无限',\n credits: 'Credits',\n monthlySpend: '月度消费控制',\n resetCredits: '重置次数',\n spendControlReached: '已触发月度消费控制,新的订阅调用可能被限制。',\n limit: '上限',\n exhausted: '额度已用尽',\n resets: '重置',\n quickQuotaLabel: 'Codex 剩余',\n quickQuotaLoading: '用量…',\n imageToolRunning: '正在生成图片',\n imageToolDone: '已生成图片',\n imageToolFailed: '图片生成失败',\n image: '图片',\n openImage: '打开图片',\n openNamedImage: '打开 {name}',\n imageLoading: '加载图片…',\n imageLoadFailed: '图片加载失败,点击重试',\n imagePreviewClose: '关闭',\n imagePreviewOpenOriginal: '打开原图',\n retry: '重试',\n unknown: '未知',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n title: 'Codex subscription',\n intro: 'Sign in with ChatGPT to use Codex models available to your subscription in DSH.',\n account: 'Account',\n signedOut: 'Not signed in',\n signedIn: 'Signed in',\n plan: 'Plan',\n accountId: 'Account ID',\n expires: 'Token expires',\n storage: 'Credential storage',\n storageWindows: 'Windows DPAPI (current-user encrypted)',\n storageMacKeychain: 'macOS Keychain (encrypted)',\n storageLinuxFile: 'Linux user-private file (mode 0600)',\n storageMemory: 'Host memory only (not persistent)',\n storageUnavailable: 'Credential storage unavailable',\n securityWindows: 'The Host encrypts tokens with Windows CurrentUser DPAPI; they never enter the browser, settings.yaml, or logs.',\n securityMacKeychain: 'The Host stores tokens in the macOS login Keychain, encrypted on this machine; they never enter the browser, settings.yaml, or logs.',\n securityLinuxFile: 'Tokens are stored in a mode-0600 file readable only by the current Linux user, but are not additionally encrypted; same-UID processes, root, backups, and disk snapshots can still read them.',\n securityMemory: 'Tokens remain only in Host memory and are lost when the Host exits.',\n securityUnavailable: 'The Host cannot safely access credential storage. Fix the file owner or permissions and retry.',\n signIn: 'Sign in with ChatGPT',\n signInAgain: 'Sign in again',\n cancel: 'Cancel sign-in',\n signOut: 'Sign out',\n refreshToken: 'Refresh credentials',\n pending: 'Complete sign-in in your browser.',\n popupBlocked: 'The sign-in window was blocked. Use the link below to continue.',\n continueLogin: 'Open ChatGPT sign-in',\n loading: 'Reading status…',\n connection: 'Connection',\n provider: 'Provider',\n connectionState: 'Connection status',\n connected: 'Available',\n untested: 'Not tested',\n testConnection: 'Test connection',\n testing: 'Testing…',\n latency: 'Last latency',\n models: 'Available models',\n enhancements: 'Enhancements',\n searchProvider: 'Search provider',\n searchProviderHint: 'Choose whether DSH web search uses its default provider or the Codex search source from this ChatGPT subscription.',\n searchProviderDsh: 'DSH default',\n searchProviderCodex: 'Codex subscription',\n quickQuota: 'Show quick usage beside the composer',\n quickQuotaHint: 'Shown only when the current session uses a codex-chatgpt model.',\n quota: 'Usage and limits',\n quotaIntro: 'Data comes from the ChatGPT Codex usage service and refreshes at most once per minute while visible.',\n refreshQuota: 'Refresh usage',\n refreshing: 'Refreshing…',\n noQuota: 'Your plan did not return any displayable limit windows.',\n quotaSignedOut: 'Sign in to view subscription limits.',\n stale: 'Showing the last successfully fetched data.',\n updated: 'Updated',\n primary: 'Primary window',\n secondary: 'Secondary window',\n limitWindow: 'limit',\n used: 'used',\n remaining: 'remaining',\n available: 'Available',\n unavailable: 'Unavailable',\n unlimited: 'Unlimited',\n credits: 'Credits',\n monthlySpend: 'Monthly spend control',\n resetCredits: 'Reset credits',\n spendControlReached: 'Monthly spend control has been reached; new subscription calls may be limited.',\n limit: 'Limit',\n exhausted: 'Quota exhausted',\n resets: 'Resets',\n quickQuotaLabel: 'Codex left',\n quickQuotaLoading: 'Usage…',\n imageToolRunning: 'Generating image',\n imageToolDone: 'Generated image',\n imageToolFailed: 'Image generation failed',\n image: 'Image',\n openImage: 'Open image',\n openNamedImage: 'Open {name}',\n imageLoading: 'Loading image…',\n imageLoadFailed: 'Image failed to load. Click to retry',\n imagePreviewClose: 'Close',\n imagePreviewOpenOriginal: 'Open original',\n retry: 'Retry',\n unknown: 'Unknown',\n}\n\nexport type LocaleKey = keyof typeof zh\nexport const dictionaries = { zh, en }\n","const STYLE_ID = '@eddyskywalker/dsh-chatgpt-subscription/main'\r\n\r\nconst CSS = `\r\n.dsh-codex-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}\r\n.dsh-codex-page *{box-sizing:border-box}\r\n.dsh-codex-title{font-size:15px;font-weight:650;line-height:1.4;margin:0 0 5px}\r\n.dsh-codex-intro,.dsh-codex-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}\r\n.dsh-codex-group{border-top:1px solid var(--dsw-alias-border-l2);min-width:0}\r\n.dsh-codex-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}\r\n.dsh-codex-grouphead h3{font-size:14px;font-weight:650;margin:0}\r\n.dsh-codex-row{align-items:center;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}\r\n.dsh-codex-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}\r\n.dsh-codex-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right}\r\n.dsh-codex-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}\n.dsh-codex-button{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:1;padding:8px 13px;white-space:nowrap}\n.dsh-codex-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsh-codex-button:focus-visible,.dsh-codex-link:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-codex-button:disabled{cursor:default;opacity:.5}\r\n.dsh-codex-button-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\r\n.dsh-codex-notice{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55;margin:12px 0 0;padding:10px 12px}\r\n.dsh-codex-error,.dsh-codex-warning{font-size:12px;line-height:1.5;margin:8px 0 0}\r\n.dsh-codex-error{color:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-warning{color:var(--dsw-alias-label-warning,#c77a18)}\r\n.dsh-codex-errorbar{align-items:center;background:color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 9%,transparent);border:1px solid color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 28%,transparent);border-radius:7px;color:var(--dsw-alias-label-danger,#d94b4b);display:flex;font-size:13px;gap:12px;justify-content:space-between;padding:10px 12px}\r\n.dsh-codex-link{color:var(--dsw-alias-label-link,#3278d4);display:inline-block;font-size:13px;margin-top:8px}\r\n.dsh-codex-models{display:flex;flex-wrap:wrap;gap:6px;padding-top:12px}\n.dsh-codex-models code{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:5px;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:4px 6px}\n.dsh-codex-pref-row{align-items:center;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}\n.dsh-codex-pref-row strong,.dsh-codex-check strong{display:block;font-size:13px;font-weight:600;line-height:1.35}\n.dsh-codex-segments{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex:none;gap:2px;padding:2px}\n.dsh-codex-segments label{cursor:pointer;display:block}\n.dsh-codex-segments input{position:absolute;opacity:0;pointer-events:none}\n.dsh-codex-segments span{border-radius:6px;color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1;padding:7px 10px;white-space:nowrap}\n.dsh-codex-segments input:checked+span{background:var(--dsw-alias-bg-base);box-shadow:0 1px 2px rgba(0,0,0,.08);color:var(--dsw-alias-label-primary)}\n.dsh-codex-segments input:focus-visible+span{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-codex-segments input:disabled+span{cursor:default;opacity:.5}\n.dsh-codex-check{align-items:flex-start;border-bottom:1px solid var(--dsw-alias-border-l2);cursor:pointer;display:flex;gap:10px;padding:12px 0}\n.dsh-codex-check input{flex:none;margin-top:2px}\n.dsh-codex-check small{color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1.45;margin-top:2px}\n.dsh-codex-quota-card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}\n.dsh-codex-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between}\n.dsh-codex-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}\n.dsh-codex-quota-fact{align-items:flex-start;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;font-size:12px;gap:12px;justify-content:space-between;line-height:1.45;padding:10px 0}\n.dsh-codex-quota-fact span{color:var(--dsw-alias-label-secondary);flex:none}\n.dsh-codex-quota-fact strong{font-weight:600;min-width:0;overflow-wrap:anywhere;text-align:right}\n.dsh-codex-meter-wrap{margin-top:13px}\n.dsh-codex-meter-label,.dsh-codex-meter-meta{display:flex;gap:10px;justify-content:space-between}\r\n.dsh-codex-meter-label{font-size:12px;margin-bottom:6px}\r\n.dsh-codex-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}\r\n.dsh-codex-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;height:7px;overflow:hidden;width:100%}\r\n.dsh-codex-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}\r\n.dsh-codex-meter-warning>span{background:var(--dsw-alias-label-warning,#d58a24)}\r\n.dsh-codex-meter-danger>span{background:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-empty{border:1px dashed var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;margin:12px 0 0;padding:16px;text-align:center}\r\n.dsh-codex-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}\r\n.dsh-codex-skeleton{display:grid;gap:9px;padding-top:10px}\r\n.dsh-codex-skeleton span{animation:dsh-codex-pulse 1.4s ease-in-out infinite;background:var(--dsw-alias-bg-layer-2);border-radius:5px;height:42px}\n.dsh-codex-skeleton span:nth-child(2){animation-delay:.12s}.dsh-codex-skeleton span:nth-child(3){animation-delay:.24s}\n.dsh-codex-sr{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0 0 0 0);white-space:nowrap}\n.dsh-codex-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;color:var(--dsw-alias-label-secondary);display:inline-flex;font-size:11px;gap:6px;height:28px;line-height:1;max-width:160px;padding:0 9px;white-space:nowrap}\n.dsh-codex-composer-quota strong{color:var(--dsw-alias-label-primary);font-size:11px;font-weight:650}\n.dsh-codex-composer-quota[data-level=warning] strong{color:var(--dsw-alias-label-warning,#d58a24)}\n.dsh-codex-composer-quota[data-level=danger] strong{color:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-image-tool{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex-direction:column;gap:8px;margin:4px 0 4px 4px;max-width:520px;padding:10px 12px}\n.dsh-codex-image-tool-head{align-items:center;display:flex;font-size:13px;gap:8px;min-width:0}\n.dsh-codex-image-dot{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:50%;display:inline-block;flex:none;height:8px;width:8px}\n.dsh-codex-image-tool[data-state=error] .dsh-codex-image-dot{background:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-image-title{font-weight:600}\n.dsh-codex-image-summary{color:var(--dsw-alias-label-tertiary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsh-codex-image-grid{display:flex;flex-wrap:wrap;gap:8px}\n.dsh-codex-image-preview{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:block;max-height:260px;max-width:min(100%,360px);object-fit:contain}\n.dsh-codex-image-loading,.dsh-codex-image-failed{border:1px dashed var(--dsw-alias-border-l2);border-radius:8px;color:var(--dsw-alias-label-tertiary);display:inline-flex;font-size:12px;line-height:1.4;padding:18px 20px}\n.dsh-codex-image-failed{color:var(--dsw-alias-label-danger,#d94b4b)}\n@keyframes dsh-codex-pulse{0%,100%{opacity:.55}50%{opacity:1}}\n@media(max-width:560px){.dsh-codex-row,.dsh-codex-pref-row,.dsh-codex-quota-fact{align-items:flex-start;flex-direction:column;gap:3px}.dsh-codex-value,.dsh-codex-quota-fact strong{text-align:left}.dsh-codex-actions{justify-content:flex-start}.dsh-codex-grouphead{align-items:flex-start;flex-direction:column;gap:0;padding:12px 0}.dsh-codex-meter-meta{align-items:flex-start;flex-direction:column;gap:2px}.dsh-codex-errorbar{align-items:flex-start;flex-direction:column}.dsh-codex-segments{width:100%}.dsh-codex-segments label{flex:1}.dsh-codex-segments span{text-align:center}.dsh-codex-image-tool{max-width:100%;margin-left:0}}\n@media(prefers-reduced-motion:reduce){.dsh-codex-meter>span{transition:none}.dsh-codex-skeleton span{animation:none}}\r\n`\r\n\r\nexport function installStyles(): () => void {\r\n if (document.querySelector(`style[data-plugin-css=\"${STYLE_ID}\"]`) !== null) return () => undefined\r\n const element = document.createElement('style')\r\n element.dataset.plugin = '@eddyskywalker/dsh-chatgpt-subscription'\r\n element.dataset.pluginCss = STYLE_ID\r\n element.textContent = CSS\r\n document.head.appendChild(element)\r\n return () => element.remove()\r\n}\r\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-tool/client'\nimport { CODEX_IMAGE_TOOL_NAME } from '../compat.ts'\nimport { CodexComposerQuota } from './CodexComposerQuota.tsx'\nimport { CodexImageToolView, type ImageLoader } from './CodexImageToolView.tsx'\nimport { CodexSubscriptionSection } from './CodexSubscriptionSection.tsx'\nimport { SubscriptionApi } from './api.ts'\nimport { dictionaries, NS, type LocaleKey } from './locales.ts'\nimport { installStyles } from './styles.ts'\n\r\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\r\n interface LocaleNamespaceMap {\r\n 'dsh-chatgpt-subscription': LocaleKey\r\n }\r\n}\r\n\r\nexport const inject = ['slots', 'locale', 'modelDirectories', 'conversation']\n\r\nexport function apply(ctx: ClientContext): void {\r\n ctx.effect(() => ctx.locale.register(NS, dictionaries), 'dsh-chatgpt-subscription: dictionaries')\r\n ctx.effect(() => installStyles(), 'dsh-chatgpt-subscription: styles')\r\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'codex-subscription',\n order: 45,\n label: 'Codex 订阅',\n locale: NS,\n }, CodexSubscriptionSection))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right',\n id: 'codex-subscription-quota',\n order: 35,\n locale: NS,\n inject: (sessionId) => {\n const directory = ctx.modelDirectories.directoryFor(sessionId)\n return {\n api: new SubscriptionApi(),\n directory: directory.store,\n loadModelDirectory: () => {\n void directory.load().catch(() => undefined)\n },\n }\n },\n }, CodexComposerQuota))\n ctx.slots.inject('tool.call.toolview', () => ctx.slots.register({\n name: 'tool.call.toolview',\n key: CODEX_IMAGE_TOOL_NAME,\n locale: NS,\n inject: (sessionId) => ({\n loadImage: imageLoader(ctx, sessionId),\n }),\n }, CodexImageToolView))\n}\n\nfunction imageLoader(ctx: ClientContext, sessionId: string): ImageLoader {\n const conversation = ctx.conversation as unknown as {\n resolveImage(sessionId: string, attachment: ImageAttachmentRef): Promise<string>\n }\n return (attachment) => conversation.resolveImage(sessionId, attachment)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["formatPercent"],"sources":["../src/compat.ts","../src/client/quota.ts","../src/client/CodexComposerQuota.tsx","../src/client/CodexImageToolView.tsx","../src/shared/model-catalog.ts","../src/client/api.ts","../src/client/CodexSubscriptionSection.tsx","../src/client/locales.ts","../src/client/styles.ts","../src/client/index.tsx"],"sourcesContent":["/**\n * Compatibility constants for the ChatGPT-backed Codex flow. The backend and\n * OAuth parameters are not a public third-party API contract, so every such\n * value is isolated here for review and rollback.\n */\nexport const CHATGPT_OAUTH_ISSUER = 'https://auth.openai.com' as const\nexport const CHATGPT_OAUTH_CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann' as const\nexport const OAUTH_CALLBACK_HOST = 'localhost' as const\nexport const OAUTH_CALLBACK_PORT = 1455 as const\nexport const OAUTH_CALLBACK_PATH = '/auth/callback' as const\nexport const OAUTH_REDIRECT_URI = `http://${OAUTH_CALLBACK_HOST}:${OAUTH_CALLBACK_PORT}${OAUTH_CALLBACK_PATH}` as const\nexport const OAUTH_SCOPE = 'openid profile email offline_access' as const\nexport const OAUTH_ORIGINATOR = 'opencode' as const\nexport const OAUTH_LOGIN_TIMEOUT_MS = 5 * 60_000\nexport const TOKEN_REFRESH_MARGIN_MS = 60_000\nexport const ROUTE_PREFIX = '/api/dsh-chatgpt-subscription' as const\nexport const PLUGIN_VERSION = '0.1.0-alpha.0' as const\nexport const CODEX_CHATGPT_PROVIDER_ID = 'codex-chatgpt' as const\n\nexport const CODEX_API_BASE = 'https://chatgpt.com/backend-api/codex' as const\nexport const CODEX_RESPONSES_URL = `${CODEX_API_BASE}/responses` as const\nexport const CODEX_IMAGE_GENERATION_URL = `${CODEX_API_BASE}/images/generations` as const\nexport const CODEX_SEARCH_URL = `${CODEX_API_BASE}/alpha/search` as const\nexport const CODEX_USAGE_URL = 'https://chatgpt.com/backend-api/wham/usage' as const\nexport const CODEX_ORIGINATOR = 'opencode' as const\nexport const CODEX_ENHANCED_ORIGINATOR = 'pi' as const\nexport const CODEX_IMAGE_TOOL_NAME = 'codex_image_generate' as const\nexport const CODEX_IMAGE_MODEL = 'gpt-image-2' as const\nexport const CODEX_SEARCH_PROVIDER_ID = 'codex-subscription' as const\nexport const QUOTA_CACHE_MS = 60_000\nexport const QUOTA_MIN_UPSTREAM_INTERVAL_MS = 15_000\n\nexport const OAUTH_AUTHORIZE_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/authorize` as const\nexport const OAUTH_TOKEN_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/token` as const\n","import type { QuotaBucketDto, QuotaStatusDto, QuotaWindowDto } from '../shared/contracts.ts'\n\nexport interface SelectedQuotaWindow {\n bucket: QuotaBucketDto\n window: QuotaWindowDto\n remainingPercent: number\n}\n\nexport function selectQuotaForModel(quota: QuotaStatusDto | undefined, modelId: string | undefined): SelectedQuotaWindow | null {\n if (quota === undefined || quota.buckets.length === 0) return null\n const model = modelId?.toLowerCase() ?? ''\n const wantsSpark = model.includes('spark')\n const bucket = wantsSpark\n ? quota.buckets.find(candidate => `${candidate.id} ${candidate.name}`.toLowerCase().includes('spark'))\n : quota.buckets.find(candidate => candidate.id === 'codex')\n ?? quota.buckets.find(candidate => candidate.name.toLowerCase() === 'codex')\n if (bucket === undefined) return null\n const windows = quotaWindows(bucket)\n if (windows.length === 0) return null\n const window = windows.reduce((tightest, candidate) => (\n candidate.usedPercent > tightest.usedPercent ? candidate : tightest\n ), windows[0]!)\n return {\n bucket,\n window,\n remainingPercent: Math.max(0, 100 - window.usedPercent),\n }\n}\n\nexport function quotaWindows(bucket: QuotaBucketDto): QuotaWindowDto[] {\n if (bucket.windows.length > 0) return bucket.windows\n return [bucket.primary, bucket.secondary].filter((window): window is QuotaWindowDto => window !== null)\n}\n","import { useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { CODEX_CHATGPT_PROVIDER_ID } from '../compat.ts'\nimport type { PluginStatusDto } from '../shared/contracts.ts'\nimport { SubscriptionApi } from './api.ts'\nimport { NS } from './locales.ts'\nimport { selectQuotaForModel } from './quota.ts'\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS> & {\n api: SubscriptionApi\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\nexport function CodexComposerQuota({ api, directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n const modelState = useStore(directory)\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\n const [loading, setLoading] = useState(false)\n const mountedRef = useRef(false)\n const selected = modelState.current\n const isCodex = selected?.provider === CODEX_CHATGPT_PROVIDER_ID\n\n useEffect(() => {\n loadModelDirectory()\n }, [loadModelDirectory])\n\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n useEffect(() => {\n if (!isCodex) return\n let disposed = false\n const refresh = async (): Promise<void> => {\n setLoading(true)\n try {\n const next = await api.status()\n if (!disposed && mountedRef.current) setStatus(next)\n } catch {\n if (!disposed && mountedRef.current) setStatus(null)\n } finally {\n if (!disposed && mountedRef.current) setLoading(false)\n }\n }\n void refresh()\n const timer = window.setInterval(() => {\n if (document.visibilityState === 'visible') void refresh()\n }, 60_000)\n return () => {\n disposed = true\n window.clearInterval(timer)\n }\n }, [api, isCodex])\n\n const quota = useMemo(() => selectQuotaForModel(status?.quota, selected?.model), [selected?.model, status?.quota])\n if (!isCodex || status?.preferences.quickQuotaVisible !== true) return null\n const level = quota === null\n ? 'normal'\n : quota.remainingPercent <= 5\n ? 'danger'\n : quota.remainingPercent <= 20\n ? 'warning'\n : 'normal'\n return <span className=\"dsh-codex-composer-quota\" data-level={level} aria-label={quota === null ? t('quickQuotaLoading') : `${t('quickQuotaLabel')}: ${formatPercent(quota.remainingPercent)}`}>\n <span>{t('quickQuotaLabel')}</span>\n <strong>{quota === null ? (loading ? t('quickQuotaLoading') : '—') : formatPercent(quota.remainingPercent)}</strong>\n </span>\n}\n\nfunction useStore<T>(store: SnapshotStore<T>): T {\n return useSyncExternalStore(\n (listener) => store.subscribe(listener),\n () => store.getSnapshot(),\n () => store.getSnapshot(),\n )\n}\n\nfunction formatPercent(value: number): string {\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 0 }).format(value)}%`\n}\n","import { useEffect, useState } from 'react'\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type { ContentBlock } from '@deepseek-ai/dsh-client-connection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { NS } from './locales.ts'\n\nexport type ImageLoader = (attachment: ImageAttachmentRef) => Promise<string>\n\ntype Props = PropsRuntime<'tool.call.toolview'> & PropsLocale<typeof NS> & {\n loadImage: ImageLoader\n}\n\nexport function CodexImageToolView({ block, loadImage, t }: Props): React.JSX.Element {\n const settled = 'kind' in block\n const isError = settled ? block.isError : false\n const prompt = promptFromBlock(block)\n const images = settled && !isError ? imageBlocks(block.content) : []\n const label = isError ? t('imageToolFailed') : settled ? t('imageToolDone') : t('imageToolRunning')\n const summary = prompt ?? textSummary(settled ? block.content : [])\n return <div className=\"dsh-codex-image-tool\" data-state={isError ? 'error' : settled ? 'done' : 'running'}>\n <div className=\"dsh-codex-image-tool-head\">\n <span className=\"dsh-codex-image-dot\" aria-hidden=\"true\" />\n <span className=\"dsh-codex-image-title\">{label}</span>\n {summary !== null ? <span className=\"dsh-codex-image-summary\">{summary}</span> : null}\n </div>\n {images.length > 0 ? <div className=\"dsh-codex-image-grid\">\n {images.map((attachment) => <GeneratedImage key={String(attachment.attachmentId)} attachment={attachment} load={loadImage} label={attachment.name ?? t('image')} t={t} />)}\n </div> : null}\n </div>\n}\n\nfunction GeneratedImage({ attachment, load, label, t }: {\n attachment: ImageAttachmentRef\n load: ImageLoader\n label: string\n t: Props['t']\n}): React.JSX.Element {\n const [src, setSrc] = useState<string | null>(null)\n const [failed, setFailed] = useState(false)\n useEffect(() => {\n let disposed = false\n setSrc(null)\n setFailed(false)\n load(attachment).then((url) => {\n if (!disposed) setSrc(url)\n }, () => {\n if (!disposed) setFailed(true)\n })\n return () => {\n disposed = true\n }\n }, [attachment, load])\n if (failed) return <span className=\"dsh-codex-image-failed\">{t('imageLoadFailed')}</span>\n if (src === null) return <span className=\"dsh-codex-image-loading\">{t('imageLoading')}</span>\n return <img className=\"dsh-codex-image-preview\" src={src} alt={label} />\n}\n\nfunction promptFromBlock(block: Props['block']): string | null {\n const raw = 'kind' in block ? block.call?.argsRaw : block.argsRaw\n if (typeof raw !== 'string' || raw.trim() === '') return null\n try {\n const value = JSON.parse(raw) as unknown\n return typeof value === 'object'\n && value !== null\n && !Array.isArray(value)\n && typeof (value as { prompt?: unknown }).prompt === 'string'\n ? (value as { prompt: string }).prompt\n : null\n } catch {\n return null\n }\n}\n\nfunction imageBlocks(blocks: readonly ContentBlock[]): ImageAttachmentRef[] {\n const result: ImageAttachmentRef[] = []\n for (const block of blocks) {\n if (block.type === 'image') result.push(block.attachment)\n if (block.type === 'tool-result') result.push(...imageBlocks(block.content))\n }\n return result\n}\n\nfunction textSummary(blocks: readonly ContentBlock[]): string | null {\n const text = blocks\n .map((block) => block.type === 'text' || block.type === 'reasoning' ? block.text : '')\n .filter(Boolean)\n .join(' ')\n .trim()\n return text === '' ? null : text\n}\n","export type CodexModelModality = 'text' | 'image'\n\nexport const GPT_56_MAX_CONTEXT_WINDOW = 1_000_000\n\nexport interface CodexModelCatalogEntry {\n id: string\n name: string\n contextWindow: number\n inputModalities: readonly CodexModelModality[]\n defaultReasoningEffort: string\n reasoningProfile: 'standard' | 'gpt-5.6'\n supportsReasoningSummary: boolean\n}\n\nexport const CODEX_MODEL_CATALOG = [\n {\n id: 'gpt-5.6-sol',\n name: '5.6 Sol',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.6-terra',\n name: '5.6 Terra',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.6-luna',\n name: '5.6 Luna',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.5',\n name: '5.5',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.4',\n name: '5.4',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'none',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.4-mini',\n name: '5.4 Mini',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'none',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.3-codex-spark',\n name: '5.3 Codex Spark',\n contextWindow: 258_000,\n inputModalities: ['text'],\n defaultReasoningEffort: 'high',\n reasoningProfile: 'standard',\n supportsReasoningSummary: false,\n },\n] as const satisfies readonly CodexModelCatalogEntry[]\n\nexport type CodexModelId = typeof CODEX_MODEL_CATALOG[number]['id']\n\nexport const DEFAULT_CODEX_MODEL = CODEX_MODEL_CATALOG[0]\n\nexport const CONFIGURABLE_CONTEXT_MODEL_IDS = [\n 'gpt-5.6-sol',\n 'gpt-5.6-terra',\n 'gpt-5.6-luna',\n] as const satisfies readonly CodexModelId[]\n\nexport type ConfigurableContextModelId = typeof CONFIGURABLE_CONTEXT_MODEL_IDS[number]\n\nexport function isCodexModelId(model: unknown): model is CodexModelId {\n return typeof model === 'string' && CODEX_MODEL_CATALOG.some((entry) => entry.id === model)\n}\n\nexport function isConfigurableContextModelId(model: unknown): model is ConfigurableContextModelId {\n return typeof model === 'string' && CONFIGURABLE_CONTEXT_MODEL_IDS.some((id) => id === model)\n}\n\nexport function resolveCodexCatalogEntry(model: string): CodexModelCatalogEntry {\n return CODEX_MODEL_CATALOG.find((entry) => entry.id === model) ?? DEFAULT_CODEX_MODEL\n}\n\nexport function codexModelSupportsImageInput(model: string): boolean {\n return resolveCodexCatalogEntry(model).inputModalities.includes('image')\n}\n\nexport function codexModelSupportsReasoningSummary(model: string): boolean {\n return resolveCodexCatalogEntry(model).supportsReasoningSummary\n}\n","import { ROUTE_PREFIX } from '../compat.ts'\r\nimport type {\r\n ApiEnvelope,\r\n LoginEventDto,\r\n LoginStartDto,\r\n PluginStatusDto,\n QuotaStatusDto,\n ConnectionTestDto,\n SubscriptionPreferencesDto,\n SubscriptionPreferencesUpdateDto,\n} from '../shared/contracts.ts'\n\r\nexport class SubscriptionApi {\r\n status(): Promise<PluginStatusDto> {\r\n return request<PluginStatusDto>(`${ROUTE_PREFIX}/status`)\r\n }\r\n\r\n startLogin(): Promise<LoginStartDto> {\r\n return post<LoginStartDto>(`${ROUTE_PREFIX}/login/start`, {})\r\n }\r\n\r\n cancelLogin(loginId: string): Promise<{ cancelled: boolean }> {\r\n return post(`${ROUTE_PREFIX}/login/cancel`, { loginId })\r\n }\r\n\r\n logout(): Promise<{ authenticated: false }> {\r\n return post(`${ROUTE_PREFIX}/logout`, {})\r\n }\r\n\r\n refresh(): Promise<PluginStatusDto> {\r\n return post(`${ROUTE_PREFIX}/token/refresh`, {})\r\n }\r\n\r\n refreshQuota(): Promise<QuotaStatusDto> {\r\n return post(`${ROUTE_PREFIX}/quota/refresh`, {})\r\n }\r\n\r\n testConnection(): Promise<ConnectionTestDto> {\n return post(`${ROUTE_PREFIX}/connection/test`, {})\n }\n\n updatePreferences(patch: SubscriptionPreferencesUpdateDto): Promise<SubscriptionPreferencesDto> {\n return post(`${ROUTE_PREFIX}/preferences/update`, patch)\n }\n\n events(loginId: string): EventSource {\n return new EventSource(`${ROUTE_PREFIX}/login/events?loginId=${encodeURIComponent(loginId)}`)\n }\n}\n\r\nasync function post<T>(url: string, body: object): Promise<T> {\n return request<T>(url, {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json' },\r\n body: JSON.stringify(body),\r\n })\r\n}\r\n\r\nasync function request<T>(url: string, init?: RequestInit): Promise<T> {\r\n const response = await fetch(url, { ...init, credentials: 'same-origin' })\r\n const envelope = await response.json() as ApiEnvelope<T>\r\n if (!response.ok || !envelope.ok) {\r\n throw new Error(envelope.ok ? `Request failed (${response.status})` : envelope.error.message)\r\n }\r\n return envelope.value\r\n}\r\n\r\nexport function parseLoginEvent(event: MessageEvent<string>): LoginEventDto | null {\r\n try {\r\n const value = JSON.parse(event.data) as LoginEventDto\r\n return typeof value === 'object' && value !== null && typeof value.type === 'string' ? value : null\r\n } catch {\r\n return null\r\n }\r\n}\r\n","import { useCallback, useEffect, useRef, useState } from 'react'\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type { CredentialStorageDto, PluginStatusDto, QuotaBucketDto, QuotaWindowDto, SubscriptionPreferencesUpdateDto } from '../shared/contracts.ts'\r\nimport { CODEX_MODEL_CATALOG, CONFIGURABLE_CONTEXT_MODEL_IDS, GPT_56_MAX_CONTEXT_WINDOW, resolveCodexCatalogEntry } from '../shared/model-catalog.ts'\r\nimport { SubscriptionApi, parseLoginEvent } from './api.ts'\r\nimport { NS } from './locales.ts'\r\nimport { quotaWindows } from './quota.ts'\r\n\r\ntype Props = PropsRuntime<'settings.section'> & PropsLocale<typeof NS>\r\ntype BusyAction = 'login' | 'token' | 'quota' | 'test' | 'logout' | 'preferences' | null\r\ntype Translate = Props['t']\r\n\r\nexport function CodexSubscriptionSection({ t }: Props): React.JSX.Element {\r\n const apiRef = useRef(new SubscriptionApi())\r\n const eventSourceRef = useRef<EventSource | null>(null)\r\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\r\n const [busy, setBusy] = useState<BusyAction>(null)\r\n const [error, setError] = useState<string | null>(null)\r\n const [authUrl, setAuthUrl] = useState<string | null>(null)\r\n const [popupBlocked, setPopupBlocked] = useState(false)\r\n const [connection, setConnection] = useState<{ latencyMs: number; checkedAt: number } | null>(null)\r\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\r\n\r\n const load = useCallback(async (quiet = false) => {\r\n if (!quiet) setError(null)\r\n try {\r\n const next = await apiRef.current.status()\r\n setStatus(next)\r\n if (next.error !== undefined) setError(next.error.message)\r\n } catch (cause) {\r\n if (!quiet) setError(messageOf(cause))\r\n }\r\n }, [])\r\n\r\n useEffect(() => {\r\n void load()\r\n const refreshWhenVisible = (): void => {\r\n if (document.visibilityState === 'visible') void load(true)\r\n }\r\n document.addEventListener('visibilitychange', refreshWhenVisible)\r\n const timer = window.setInterval(refreshWhenVisible, 60_000)\r\n return () => {\r\n window.clearInterval(timer)\r\n document.removeEventListener('visibilitychange', refreshWhenVisible)\r\n eventSourceRef.current?.close()\r\n }\r\n }, [load])\r\n\r\n const watchLogin = useCallback((loginId: string) => {\r\n eventSourceRef.current?.close()\r\n const source = apiRef.current.events(loginId)\r\n eventSourceRef.current = source\r\n const finish = async (message?: string): Promise<void> => {\r\n source.close()\r\n eventSourceRef.current = null\r\n setBusy(null)\r\n setAuthUrl(null)\r\n if (message !== undefined) setError(message)\r\n // Preserve the terminal OAuth error while refreshing the account DTO.\r\n await load(true)\r\n }\r\n source.addEventListener('completed', (event) => {\r\n const parsed = parseLoginEvent(event as MessageEvent<string>)\r\n if (parsed?.type === 'completed') void finish()\r\n })\r\n source.addEventListener('cancelled', () => void finish())\r\n source.addEventListener('failed', (event) => {\r\n const parsed = parseLoginEvent(event as MessageEvent<string>)\r\n void finish(parsed?.type === 'failed' ? parsed.error.message : 'ChatGPT sign-in failed.')\r\n })\r\n }, [load])\r\n\r\n useEffect(() => {\r\n const loginId = status?.login.active ? status.login.loginId : null\r\n if (loginId !== null && loginId !== undefined && eventSourceRef.current === null) watchLogin(loginId)\r\n }, [status?.login.active, status?.login.loginId, watchLogin])\r\n\r\n const startLogin = async (): Promise<void> => {\r\n setBusy('login')\r\n setError(null)\r\n setPopupBlocked(false)\r\n const popup = window.open('about:blank', 'dsh-chatgpt-oauth', 'popup,width=560,height=760')\r\n try {\r\n const login = await apiRef.current.startLogin()\r\n setAuthUrl(login.authUrl)\r\n if (popup === null) setPopupBlocked(true)\r\n else popup.location.replace(login.authUrl)\r\n watchLogin(login.loginId)\r\n await load(true)\r\n } catch (cause) {\r\n popup?.close()\r\n setBusy(null)\r\n setError(messageOf(cause))\r\n }\r\n }\r\n\r\n const cancelLogin = async (): Promise<void> => {\r\n const loginId = status?.login.loginId\r\n if (loginId === null || loginId === undefined) return\r\n setBusy('login')\r\n try {\r\n await apiRef.current.cancelLogin(loginId)\r\n eventSourceRef.current?.close()\r\n eventSourceRef.current = null\r\n setAuthUrl(null)\r\n await load()\r\n } catch (cause) {\r\n setError(messageOf(cause))\r\n } finally {\r\n setBusy(null)\r\n }\r\n }\r\n\r\n const refreshToken = async (): Promise<void> => run('token', async () => {\r\n setStatus(await apiRef.current.refresh())\r\n })\r\n\r\n const refreshQuota = async (): Promise<void> => run('quota', async () => {\r\n const quota = await apiRef.current.refreshQuota()\r\n setStatus((current) => current === null ? current : { ...current, quota })\r\n })\r\n\r\n const testConnection = async (): Promise<void> => run('test', async () => {\r\n const result = await apiRef.current.testConnection()\r\n setConnection({ latencyMs: result.latencyMs, checkedAt: result.checkedAt })\r\n })\r\n\r\n const updatePreferences = async (patch: SubscriptionPreferencesUpdateDto): Promise<void> => run('preferences', async () => {\r\n const preferences = await apiRef.current.updatePreferences(patch)\r\n setStatus((current) => current === null ? current : { ...current, preferences })\r\n })\r\n\r\n const updateContextWindow = async (model: (typeof CONFIGURABLE_CONTEXT_MODEL_IDS)[number]): Promise<void> => {\r\n const current = status?.preferences.contextWindowOverrides[model] ?? resolveCodexCatalogEntry(model).contextWindow\r\n const parsed = parseCapacity(contextDrafts[model] ?? String(current))\r\n if (parsed === null) {\r\n setError(t('contextWindowInvalid'))\r\n return\r\n }\r\n await updatePreferences({ contextWindowOverrides: { [model]: parsed } })\r\n setContextDrafts((drafts) => ({ ...drafts, [model]: String(parsed) }))\r\n }\r\n\r\n const logout = async (): Promise<void> => run('logout', async () => {\r\n await apiRef.current.logout()\r\n eventSourceRef.current?.close()\r\n eventSourceRef.current = null\r\n setAuthUrl(null)\r\n setConnection(null)\r\n await load()\r\n })\r\n\r\n const run = async (action: Exclude<BusyAction, null>, task: () => Promise<void>): Promise<void> => {\r\n setBusy(action)\r\n setError(null)\r\n try {\r\n await task()\r\n } catch (cause) {\r\n setError(messageOf(cause))\r\n } finally {\r\n setBusy(null)\r\n }\r\n }\r\n\r\n const account = status?.account\r\n return <section className=\"dsh-codex-page\" aria-labelledby=\"dsh-codex-title\">\r\n <header>\r\n <h2 id=\"dsh-codex-title\" className=\"dsh-codex-title\">{t('title')}</h2>\r\n <p className=\"dsh-codex-intro\">{t('intro')}</p>\r\n </header>\r\n\r\n {error !== null ? <div className=\"dsh-codex-errorbar\" role=\"alert\">\r\n <span>{error}</span>\r\n {status === null ? <Button disabled={busy !== null} onClick={() => load()}>{t('retry')}</Button> : null}\r\n </div> : null}\r\n\r\n {status === null && error === null ? <Skeleton label={t('loading')} /> : <>\r\n <Section title={t('account')}>\r\n <InfoRow label={status?.authenticated ? t('signedIn') : t('signedOut')} value={account?.email ?? '—'} />\r\n {status?.authenticated ? <>\r\n <InfoRow label={t('plan')} value={account?.planType ?? t('unknown')} />\r\n <InfoRow label={t('accountId')} value={account?.accountIdSuffix ?? '—'} />\r\n <InfoRow label={t('expires')} value={formatDate(account?.tokenExpiresAt)} />\r\n </> : null}\r\n <InfoRow label={t('storage')} value={storageLabel(status?.storage, t)} />\r\n <p className=\"dsh-codex-notice\">{storageNotice(status?.storage, t)}</p>\r\n {status?.login.active ? <p className=\"dsh-codex-muted\" role=\"status\">{t('pending')}</p> : null}\r\n {popupBlocked ? <p className=\"dsh-codex-error\">{t('popupBlocked')}</p> : null}\r\n {authUrl !== null ? <a className=\"dsh-codex-link\" href={authUrl} target=\"_blank\" rel=\"noreferrer\">{t('continueLogin')}</a> : null}\r\n <div className=\"dsh-codex-actions\">\r\n {status?.login.active\r\n ? <Button disabled={busy !== null} onClick={cancelLogin}>{t('cancel')}</Button>\r\n : <Button primary disabled={busy !== null || status?.storage.available === false} onClick={startLogin}>{status?.authenticated ? t('signInAgain') : t('signIn')}</Button>}\r\n {status?.authenticated ? <>\r\n <Button disabled={busy !== null} onClick={refreshToken}>{t('refreshToken')}</Button>\r\n <Button disabled={busy !== null} onClick={logout}>{t('signOut')}</Button>\r\n </> : null}\r\n </div>\r\n </Section>\r\n\r\n <Section title={t('connection')}>\r\n <InfoRow label={t('provider')} value=\"Codex(ChatGPT 订阅) · codex-chatgpt\" />\r\n <InfoRow label={t('connectionState')} value={connection === null ? t('untested') : t('connected')} />\r\n {connection !== null ? <InfoRow label={t('latency')} value={`${connection.latencyMs} ms · ${formatDate(connection.checkedAt)}`} /> : null}\r\n <div className=\"dsh-codex-models\" aria-label={t('models')}>\r\n {CODEX_MODEL_CATALOG.map((model) => <code key={model.id} title={model.id}>{model.name}</code>)}\r\n </div>\r\n <div className=\"dsh-codex-actions\">\r\n <Button disabled={!status?.authenticated || busy !== null} onClick={testConnection}>{busy === 'test' ? t('testing') : t('testConnection')}</Button>\r\n </div>\r\n </Section>\r\n\r\n <Section title={t('enhancements')}>\r\n <div className=\"dsh-codex-pref-row\">\r\n <div>\r\n <strong>{t('searchProvider')}</strong>\r\n <p className=\"dsh-codex-muted\">{t('searchProviderHint')}</p>\r\n </div>\r\n <div className=\"dsh-codex-segments\" role=\"radiogroup\" aria-label={t('searchProvider')}>\r\n <label>\r\n <input type=\"radio\" name=\"dsh-codex-search-provider\" checked={status?.preferences.searchProvider === 'dsh'} disabled={busy !== null} onChange={() => updatePreferences({ searchProvider: 'dsh' })} />\r\n <span>{t('searchProviderDsh')}</span>\r\n </label>\r\n <label>\r\n <input type=\"radio\" name=\"dsh-codex-search-provider\" checked={status?.preferences.searchProvider === 'codex'} disabled={busy !== null} onChange={() => updatePreferences({ searchProvider: 'codex' })} />\r\n <span>{t('searchProviderCodex')}</span>\r\n </label>\r\n </div>\r\n </div>\r\n <div className=\"dsh-codex-pref-row\">\r\n <div>\r\n <strong>{t('subagentModel')}</strong>\r\n <p className=\"dsh-codex-muted\">{t('subagentModelHint')}</p>\r\n </div>\r\n <select className=\"dsh-codex-select\" aria-label={t('subagentModel')} value={status?.preferences.subagentModel ?? CODEX_MODEL_CATALOG[0].id} disabled={busy !== null} onChange={(event) => void updatePreferences({ subagentModel: event.currentTarget.value })}>\r\n {CODEX_MODEL_CATALOG.map((model) => <option key={model.id} value={model.id}>{model.name}</option>)}\r\n </select>\r\n </div>\r\n <div className=\"dsh-codex-context-settings\">\r\n <div>\r\n <strong>{t('contextWindows')}</strong>\r\n <p className=\"dsh-codex-muted\">{t('contextWindowsHint')}</p>\r\n </div>\r\n {CONFIGURABLE_CONTEXT_MODEL_IDS.map((model) => {\r\n const fallback = status?.preferences.contextWindowOverrides[model] ?? resolveCodexCatalogEntry(model).contextWindow\r\n return <label className=\"dsh-codex-context-row\" key={model}>\r\n <span>{resolveCodexCatalogEntry(model).name}</span>\r\n <span className=\"dsh-codex-capacity-control\">\r\n <input type=\"text\" inputMode=\"numeric\" value={contextDrafts[model] ?? formatCapacity(fallback)} disabled={busy !== null} aria-label={resolveCodexCatalogEntry(model).name + ' ' + t('contextWindow')} onChange={(event) => setContextDrafts((drafts) => ({ ...drafts, [model]: event.currentTarget.value }))} onBlur={() => void updateContextWindow(model)} onKeyDown={(event) => { if (event.key === 'Enter') event.currentTarget.blur() }} />\r\n <small>{t('tokens')}</small>\r\n </span>\r\n </label>\r\n })}\r\n </div>\r\n <label className=\"dsh-codex-check\">\r\n <input type=\"checkbox\" checked={status?.preferences.quickQuotaVisible === true} disabled={busy !== null} onChange={(event) => updatePreferences({ quickQuotaVisible: event.currentTarget.checked })} />\r\n <span>\r\n <strong>{t('quickQuota')}</strong>\r\n <small>{t('quickQuotaHint')}</small>\r\n </span>\r\n </label>\r\n </Section>\r\n\r\n <Section title={t('quota')} aside={<Button disabled={!status?.authenticated || busy !== null} onClick={refreshQuota}>{busy === 'quota' ? t('refreshing') : t('refreshQuota')}</Button>}>\r\n <p className=\"dsh-codex-muted\">{t('quotaIntro')}</p>\r\n {status?.quota.state === 'signed-out' ? <p className=\"dsh-codex-empty\">{t('quotaSignedOut')}</p> : null}\r\n {status?.quota.buckets.map((bucket) => <QuotaBucket key={bucket.id} bucket={bucket} t={t} />)}\r\n {status?.quota.credits !== null && status?.quota.credits !== undefined ? <QuotaFact label={t('credits')} value={status.quota.credits.unlimited ? t('unlimited') : status.quota.credits.balance ?? (status.quota.credits.hasCredits ? t('available') : t('unavailable'))} /> : null}\r\n {status?.quota.individualLimit !== null && status?.quota.individualLimit !== undefined ? <QuotaFact label={t('monthlySpend')} value={individualLimitLabel(status.quota.individualLimit, t)} /> : null}\r\n {status?.quota.resetCredits !== null && status?.quota.resetCredits !== undefined ? <QuotaFact label={t('resetCredits')} value={String(status.quota.resetCredits.availableCount)} /> : null}\r\n {status?.quota.spendControlReached === true ? <p className=\"dsh-codex-warning\" role=\"status\">{t('spendControlReached')}</p> : null}\r\n {status?.quota.state === 'empty' ? <p className=\"dsh-codex-empty\">{t('noQuota')}</p> : null}\r\n {status?.quota.stale ? <p className=\"dsh-codex-warning\" role=\"status\">{t('stale')}</p> : null}\r\n {status?.quota.error ? <p className=\"dsh-codex-error\" role=\"alert\">{status.quota.error.message}</p> : null}\r\n {status?.quota.fetchedAt ? <p className=\"dsh-codex-timestamp\">{t('updated')}: {formatDate(status.quota.fetchedAt)}</p> : null}\r\n </Section>\r\n </>}\r\n\r\n <span className=\"dsh-codex-sr\" aria-live=\"polite\">{busy === null ? '' : busy}</span>\r\n </section>\r\n}\r\n\r\nfunction Section({ title, aside, children }: { title: string; aside?: React.ReactNode; children: React.ReactNode }): React.JSX.Element {\r\n return <section className=\"dsh-codex-group\">\r\n <div className=\"dsh-codex-grouphead\"><h3>{title}</h3>{aside}</div>\r\n {children}\r\n </section>\r\n}\r\n\r\nfunction Button({ primary = false, disabled, onClick, children }: { primary?: boolean; disabled?: boolean; onClick: () => void | Promise<void>; children: React.ReactNode }): React.JSX.Element {\r\n return <button className={`dsh-codex-button${primary ? ' dsh-codex-button-primary' : ''}`} type=\"button\" disabled={disabled} onClick={() => void onClick()}>{children}</button>\r\n}\r\n\r\nfunction InfoRow({ label, value }: { label: string; value: string }): React.JSX.Element {\r\n return <div className=\"dsh-codex-row\"><span className=\"dsh-codex-label\">{label}</span><span className=\"dsh-codex-value\">{value}</span></div>\r\n}\r\n\r\nexport function storageLabel(storage: CredentialStorageDto | undefined, t: Translate): string {\r\n if (storage === undefined || !storage.available) return t('storageUnavailable')\r\n if (storage.kind === 'windows-dpapi') return t('storageWindows')\r\n if (storage.kind === 'macos-keychain') return t('storageMacKeychain')\r\n if (storage.kind === 'linux-file') return t('storageLinuxFile')\r\n if (storage.kind === 'memory') return t('storageMemory')\r\n return t('storageUnavailable')\r\n}\r\n\r\nexport function storageNotice(storage: CredentialStorageDto | undefined, t: Translate): string {\r\n if (storage === undefined || !storage.available) return t('securityUnavailable')\r\n if (storage.kind === 'windows-dpapi') return t('securityWindows')\r\n if (storage.kind === 'macos-keychain') return t('securityMacKeychain')\r\n if (storage.kind === 'linux-file') return t('securityLinuxFile')\r\n if (storage.kind === 'memory') return t('securityMemory')\r\n return t('securityUnavailable')\r\n}\r\n\r\nfunction QuotaBucket({ bucket, t }: { bucket: QuotaBucketDto; t: Translate }): React.JSX.Element {\r\n const windows = quotaWindows(bucket)\r\n return <article className=\"dsh-codex-quota-card\">\r\n <div className=\"dsh-codex-quota-title\"><strong>{bucket.name}</strong>{bucket.planType ? <span>{bucket.planType}</span> : null}</div>\r\n {windows.map((window, index) => <QuotaBar key={`${window.windowDurationMins ?? 'x'}:${window.resetsAt ?? 'x'}:${index}`} label={windowLabel(window.windowDurationMins, t)} window={window} t={t} />)}\r\n </article>\r\n}\r\n\r\nfunction QuotaFact({ label, value }: { label: string; value: string }): React.JSX.Element {\r\n return <div className=\"dsh-codex-quota-fact\"><span>{label}</span><strong>{value}</strong></div>\r\n}\r\n\r\nexport function QuotaBar({ label, window, t }: { label: string; window: QuotaWindowDto; t: Translate }): React.JSX.Element {\r\n const percent = window.usedPercent\r\n const level = percent >= 95 ? 'danger' : percent >= 80 ? 'warning' : 'normal'\r\n const remaining = Math.max(0, 100 - percent)\r\n return <div className=\"dsh-codex-meter-wrap\">\r\n <div className=\"dsh-codex-meter-label\"><span>{label}</span><strong>{formatPercent(percent)}</strong></div>\r\n <div className={`dsh-codex-meter dsh-codex-meter-${level}`} role=\"progressbar\" aria-label={`${label}: ${formatPercent(percent)} ${t('used')}`} aria-valuemin={0} aria-valuemax={100} aria-valuenow={percent}>\r\n <span style={{ width: `${percent}%` }} />\r\n </div>\r\n <div className=\"dsh-codex-meter-meta\">\r\n <span>{percent >= 100 ? `${t('exhausted')} · ${formatPercent(remaining)} ${t('remaining')}` : `${formatPercent(percent)} ${t('used')} · ${formatPercent(remaining)} ${t('remaining')}`}</span>\r\n <span>{window.resetsAt === null ? '—' : `${t('resets')}: ${formatReset(window.resetsAt)}`}</span>\r\n </div>\r\n </div>\r\n}\r\n\r\nfunction Skeleton({ label }: { label: string }): React.JSX.Element {\r\n return <div className=\"dsh-codex-skeleton\" role=\"status\" aria-label={label}><span /><span /></div>\r\n}\r\n\r\nexport function windowLabel(minutes: number | null, t: Translate): string {\r\n if (minutes === null) return t('limitWindow')\r\n const [value, unit]: [number, Intl.NumberFormatOptions['unit']] = minutes >= 1440 && minutes % 1440 === 0\r\n ? [minutes / 1440, 'day']\r\n : minutes >= 60 && minutes % 60 === 0\r\n ? [minutes / 60, 'hour']\r\n : [Math.round(minutes), 'minute']\r\n return `${new Intl.NumberFormat(undefined, { style: 'unit', unit, unitDisplay: 'long' }).format(value)} ${t('limitWindow')}`\r\n}\r\n\r\nexport function parseCapacity(value: string): number | null {\r\n const normalized = value.trim().toLowerCase().replace(/[,_\\s]/g, '')\r\n const matched = normalized.match(/^(\\d+(?:\\.\\d+)?)(k|m)?$/)\r\n if (matched === null) return null\r\n const multiplier = matched[2] === 'm' ? 1_000_000 : matched[2] === 'k' ? 1_000 : 1\r\n const parsed = Number(matched[1]) * multiplier\r\n return Number.isSafeInteger(parsed) && parsed >= 1 && parsed <= GPT_56_MAX_CONTEXT_WINDOW ? parsed : null\r\n}\r\n\r\nfunction formatCapacity(value: number): string {\r\n if (value % 1_000 === 0) return `${value / 1_000}K`\r\n return String(value)\r\n}\r\n\r\nfunction formatPercent(value: number): string {\r\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value)}%`\r\n}\r\n\r\nfunction individualLimitLabel(limit: NonNullable<PluginStatusDto['quota']['individualLimit']>, t: Translate): string {\r\n const parts = [\r\n limit.remainingPercent !== null ? `${formatPercent(limit.remainingPercent)} ${t('remaining')}` : null,\r\n limit.limit !== null ? `${t('limit')}: ${limit.limit}` : null,\r\n limit.used !== null ? `${t('used')}: ${limit.used}` : null,\r\n limit.resetsAt !== null ? `${t('resets')}: ${formatReset(limit.resetsAt)}` : null,\r\n ].filter((part): part is string => part !== null)\r\n return parts.length > 0 ? parts.join(' · ') : t('unknown')\r\n}\r\n\r\nfunction formatDate(seconds: number | undefined): string {\r\n if (seconds === undefined) return '—'\r\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(seconds * 1000)\r\n}\r\n\r\nexport function formatReset(seconds: number): string {\r\n const absolute = formatDate(seconds)\r\n const diff = seconds * 1000 - Date.now()\r\n const abs = Math.abs(diff)\r\n const [amount, unit]: [number, Intl.RelativeTimeFormatUnit] = abs >= 86_400_000\r\n ? [Math.round(diff / 86_400_000), 'day']\r\n : abs >= 3_600_000\r\n ? [Math.round(diff / 3_600_000), 'hour']\r\n : [Math.round(diff / 60_000), 'minute']\r\n return `${absolute} (${new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' }).format(amount, unit)})`\r\n}\r\n\r\nfunction messageOf(error: unknown): string {\r\n return error instanceof Error ? error.message : String(error)\r\n}\r\n","export const NS = 'dsh-chatgpt-subscription' as const\n\nexport const zh = {\n title: 'Codex 订阅',\n intro: '使用 ChatGPT 账号登录,在 DSH 中使用订阅可用的 Codex 模型。',\n account: '账号',\n signedOut: '尚未登录',\n signedIn: '已登录',\n plan: '套餐',\n accountId: '账号 ID',\n expires: '令牌到期',\n storage: '凭据存储',\n storageWindows: 'Windows DPAPI(当前用户加密)',\n storageMacKeychain: 'macOS 钥匙串(Keychain 加密)',\n storageLinuxFile: 'Linux 用户私有文件(权限 0600)',\n storageMemory: '仅 Host 内存(不持久化)',\n storageUnavailable: '凭据存储不可用',\n securityWindows: '令牌由 Host 使用 Windows CurrentUser DPAPI 加密,不会进入浏览器、settings.yaml 或日志。',\n securityMacKeychain: '令牌由 Host 存入 macOS 登录钥匙串(Keychain),在本机加密保存,不会进入浏览器、settings.yaml 或日志。',\n securityLinuxFile: '令牌仅写入 Host 上当前 Linux 用户可读的 0600 文件,但不会额外加密;同 UID 进程、root、备份和磁盘快照仍可能读取。',\n securityMemory: '令牌仅保留在 Host 内存中,Host 退出后丢失。',\n securityUnavailable: 'Host 无法安全访问凭据存储;请修复文件所有者或权限后重试。',\n signIn: '使用 ChatGPT 登录',\n signInAgain: '重新登录',\n cancel: '取消登录',\n signOut: '注销',\n refreshToken: '刷新凭据',\n pending: '请在浏览器中完成登录。',\n popupBlocked: '浏览器拦截了登录窗口,请使用下面的链接继续。',\n continueLogin: '打开 ChatGPT 登录页',\n loading: '正在读取状态…',\n connection: '连接',\n provider: 'Provider',\n connectionState: '连接状态',\n connected: '可用',\n untested: '尚未测试',\n testConnection: '测试连接',\n testing: '测试中…',\n latency: '最近延迟',\n models: '可用模型',\n enhancements: '增强功能',\n searchProvider: '搜索来源',\n searchProviderHint: '选择 DSH Web 搜索工具使用默认来源,或改用当前 ChatGPT 订阅的 Codex 搜索来源。',\n searchProviderDsh: 'DSH 默认',\n searchProviderCodex: 'Codex 订阅',\n subagentModel: '子代理模型',\n subagentModelHint: '新启动的内置子代理使用此 ChatGPT 订阅模型;父会话的模型选择不受影响。',\n contextWindows: 'GPT-5.6 上下文窗口',\n contextWindowsHint: '默认 272K;可选启用最高 1M。该值用于 DSH 的压缩与溢出判断,可输入 1M、512K 等容量。',\n contextWindow: '上下文窗口',\n contextWindowInvalid: '上下文窗口必须是 1 到 1M 的整数,可使用 K 或 M 后缀。',\n tokens: 'tokens',\n quickQuota: '在输入框旁显示快捷用量',\n quickQuotaHint: '仅在当前会话选中 codex-chatgpt 模型时显示。',\n quota: '用量与限额',\n quotaIntro: '数据来自 ChatGPT Codex 用量服务。页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshing: '刷新中…',\n noQuota: '当前套餐未返回可显示的限额窗口。',\n quotaSignedOut: '登录后可查看订阅限额。',\n stale: '显示的是上次成功获取的数据。',\n updated: '更新时间',\n primary: '主要窗口',\n secondary: '次要窗口',\n limitWindow: '额度',\n used: '已使用',\n remaining: '剩余',\n available: '可用',\n unavailable: '不可用',\n unlimited: '无限',\n credits: 'Credits',\n monthlySpend: '月度消费控制',\n resetCredits: '重置次数',\n spendControlReached: '已触发月度消费控制,新的订阅调用可能被限制。',\n limit: '上限',\n exhausted: '额度已用尽',\n resets: '重置',\n quickQuotaLabel: 'Codex 剩余',\n quickQuotaLoading: '用量…',\n imageToolRunning: '正在生成图片',\n imageToolDone: '已生成图片',\n imageToolFailed: '图片生成失败',\n image: '图片',\n openImage: '打开图片',\n openNamedImage: '打开 {name}',\n imageLoading: '加载图片…',\n imageLoadFailed: '图片加载失败,点击重试',\n imagePreviewClose: '关闭',\n imagePreviewOpenOriginal: '打开原图',\n retry: '重试',\n unknown: '未知',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n title: 'Codex subscription',\n intro: 'Sign in with ChatGPT to use Codex models available to your subscription in DSH.',\n account: 'Account',\n signedOut: 'Not signed in',\n signedIn: 'Signed in',\n plan: 'Plan',\n accountId: 'Account ID',\n expires: 'Token expires',\n storage: 'Credential storage',\n storageWindows: 'Windows DPAPI (current-user encrypted)',\n storageMacKeychain: 'macOS Keychain (encrypted)',\n storageLinuxFile: 'Linux user-private file (mode 0600)',\n storageMemory: 'Host memory only (not persistent)',\n storageUnavailable: 'Credential storage unavailable',\n securityWindows: 'The Host encrypts tokens with Windows CurrentUser DPAPI; they never enter the browser, settings.yaml, or logs.',\n securityMacKeychain: 'The Host stores tokens in the macOS login Keychain, encrypted on this machine; they never enter the browser, settings.yaml, or logs.',\n securityLinuxFile: 'Tokens are stored in a mode-0600 file readable only by the current Linux user, but are not additionally encrypted; same-UID processes, root, backups, and disk snapshots can still read them.',\n securityMemory: 'Tokens remain only in Host memory and are lost when the Host exits.',\n securityUnavailable: 'The Host cannot safely access credential storage. Fix the file owner or permissions and retry.',\n signIn: 'Sign in with ChatGPT',\n signInAgain: 'Sign in again',\n cancel: 'Cancel sign-in',\n signOut: 'Sign out',\n refreshToken: 'Refresh credentials',\n pending: 'Complete sign-in in your browser.',\n popupBlocked: 'The sign-in window was blocked. Use the link below to continue.',\n continueLogin: 'Open ChatGPT sign-in',\n loading: 'Reading status…',\n connection: 'Connection',\n provider: 'Provider',\n connectionState: 'Connection status',\n connected: 'Available',\n untested: 'Not tested',\n testConnection: 'Test connection',\n testing: 'Testing…',\n latency: 'Last latency',\n models: 'Available models',\n enhancements: 'Enhancements',\n searchProvider: 'Search provider',\n searchProviderHint: 'Choose whether DSH web search uses its default provider or the Codex search source from this ChatGPT subscription.',\n searchProviderDsh: 'DSH default',\n searchProviderCodex: 'Codex subscription',\n subagentModel: 'Subagent model',\n subagentModelHint: 'New built-in subagents use this ChatGPT subscription model; the parent session selection is unchanged.',\n contextWindows: 'GPT-5.6 context windows',\n contextWindowsHint: 'Defaults to 272K, with an optional value up to 1M. DSH uses it for compaction and overflow detection; values such as 1M and 512K are accepted.',\n contextWindow: 'Context window',\n contextWindowInvalid: 'The context window must be an integer from 1 to 1M. K and M suffixes are accepted.',\n tokens: 'tokens',\n quickQuota: 'Show quick usage beside the composer',\n quickQuotaHint: 'Shown only when the current session uses a codex-chatgpt model.',\n quota: 'Usage and limits',\n quotaIntro: 'Data comes from the ChatGPT Codex usage service and refreshes at most once per minute while visible.',\n refreshQuota: 'Refresh usage',\n refreshing: 'Refreshing…',\n noQuota: 'Your plan did not return any displayable limit windows.',\n quotaSignedOut: 'Sign in to view subscription limits.',\n stale: 'Showing the last successfully fetched data.',\n updated: 'Updated',\n primary: 'Primary window',\n secondary: 'Secondary window',\n limitWindow: 'limit',\n used: 'used',\n remaining: 'remaining',\n available: 'Available',\n unavailable: 'Unavailable',\n unlimited: 'Unlimited',\n credits: 'Credits',\n monthlySpend: 'Monthly spend control',\n resetCredits: 'Reset credits',\n spendControlReached: 'Monthly spend control has been reached; new subscription calls may be limited.',\n limit: 'Limit',\n exhausted: 'Quota exhausted',\n resets: 'Resets',\n quickQuotaLabel: 'Codex left',\n quickQuotaLoading: 'Usage…',\n imageToolRunning: 'Generating image',\n imageToolDone: 'Generated image',\n imageToolFailed: 'Image generation failed',\n image: 'Image',\n openImage: 'Open image',\n openNamedImage: 'Open {name}',\n imageLoading: 'Loading image…',\n imageLoadFailed: 'Image failed to load. Click to retry',\n imagePreviewClose: 'Close',\n imagePreviewOpenOriginal: 'Open original',\n retry: 'Retry',\n unknown: 'Unknown',\n}\n\nexport type LocaleKey = keyof typeof zh\nexport const dictionaries = { zh, en }\n","const STYLE_ID = '@eddyskywalker/dsh-chatgpt-subscription/main'\r\n\r\nconst CSS = `\r\n.dsh-codex-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}\r\n.dsh-codex-page *{box-sizing:border-box}\r\n.dsh-codex-title{font-size:15px;font-weight:650;line-height:1.4;margin:0 0 5px}\r\n.dsh-codex-intro,.dsh-codex-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}\r\n.dsh-codex-group{border-top:1px solid var(--dsw-alias-border-l2);min-width:0}\r\n.dsh-codex-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}\r\n.dsh-codex-grouphead h3{font-size:14px;font-weight:650;margin:0}\r\n.dsh-codex-row{align-items:center;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}\r\n.dsh-codex-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}\r\n.dsh-codex-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right}\r\n.dsh-codex-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}\r\n.dsh-codex-button{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:1;padding:8px 13px;white-space:nowrap}\r\n.dsh-codex-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\r\n.dsh-codex-button:focus-visible,.dsh-codex-link:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\r\n.dsh-codex-button:disabled{cursor:default;opacity:.5}\r\n.dsh-codex-button-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\r\n.dsh-codex-notice{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55;margin:12px 0 0;padding:10px 12px}\r\n.dsh-codex-error,.dsh-codex-warning{font-size:12px;line-height:1.5;margin:8px 0 0}\r\n.dsh-codex-error{color:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-warning{color:var(--dsw-alias-label-warning,#c77a18)}\r\n.dsh-codex-errorbar{align-items:center;background:color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 9%,transparent);border:1px solid color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 28%,transparent);border-radius:7px;color:var(--dsw-alias-label-danger,#d94b4b);display:flex;font-size:13px;gap:12px;justify-content:space-between;padding:10px 12px}\r\n.dsh-codex-link{color:var(--dsw-alias-label-link,#3278d4);display:inline-block;font-size:13px;margin-top:8px}\r\n.dsh-codex-models{display:flex;flex-wrap:wrap;gap:6px;padding-top:12px}\r\n.dsh-codex-models code{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:5px;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:4px 6px}\r\n.dsh-codex-pref-row{align-items:center;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}\r\n.dsh-codex-pref-row strong,.dsh-codex-check strong{display:block;font-size:13px;font-weight:600;line-height:1.35}\r\n.dsh-codex-segments{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex:none;gap:2px;padding:2px}\r\n.dsh-codex-segments label{cursor:pointer;display:block}\r\n.dsh-codex-segments input{position:absolute;opacity:0;pointer-events:none}\r\n.dsh-codex-segments span{border-radius:6px;color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1;padding:7px 10px;white-space:nowrap}\r\n.dsh-codex-segments input:checked+span{background:var(--dsw-alias-bg-base);box-shadow:0 1px 2px rgba(0,0,0,.08);color:var(--dsw-alias-label-primary)}\r\n.dsh-codex-segments input:focus-visible+span{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\r\n.dsh-codex-segments input:disabled+span{cursor:default;opacity:.5}\r\n.dsh-codex-select,.dsh-codex-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px}\r\n.dsh-codex-select{max-width:210px;min-width:150px}\r\n.dsh-codex-context-settings{border-bottom:1px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}\r\n.dsh-codex-context-settings>div>strong{font-size:13px;font-weight:600}\r\n.dsh-codex-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}\r\n.dsh-codex-capacity-control{align-items:center;display:flex;gap:7px}\r\n.dsh-codex-capacity-control input{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;text-align:right;width:90px}\r\n.dsh-codex-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}\r\n.dsh-codex-check{align-items:flex-start;border-bottom:1px solid var(--dsw-alias-border-l2);cursor:pointer;display:flex;gap:10px;padding:12px 0}\r\n.dsh-codex-check input{flex:none;margin-top:2px}\r\n.dsh-codex-check small{color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1.45;margin-top:2px}\r\n.dsh-codex-quota-card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}\r\n.dsh-codex-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between}\r\n.dsh-codex-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}\r\n.dsh-codex-quota-fact{align-items:flex-start;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;font-size:12px;gap:12px;justify-content:space-between;line-height:1.45;padding:10px 0}\r\n.dsh-codex-quota-fact span{color:var(--dsw-alias-label-secondary);flex:none}\r\n.dsh-codex-quota-fact strong{font-weight:600;min-width:0;overflow-wrap:anywhere;text-align:right}\r\n.dsh-codex-meter-wrap{margin-top:13px}\r\n.dsh-codex-meter-label,.dsh-codex-meter-meta{display:flex;gap:10px;justify-content:space-between}\r\n.dsh-codex-meter-label{font-size:12px;margin-bottom:6px}\r\n.dsh-codex-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}\r\n.dsh-codex-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;height:7px;overflow:hidden;width:100%}\r\n.dsh-codex-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}\r\n.dsh-codex-meter-warning>span{background:var(--dsw-alias-label-warning,#d58a24)}\r\n.dsh-codex-meter-danger>span{background:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-empty{border:1px dashed var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;margin:12px 0 0;padding:16px;text-align:center}\r\n.dsh-codex-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}\r\n.dsh-codex-skeleton{display:grid;gap:9px;padding-top:10px}\r\n.dsh-codex-skeleton span{animation:dsh-codex-pulse 1.4s ease-in-out infinite;background:var(--dsw-alias-bg-layer-2);border-radius:5px;height:42px}\r\n.dsh-codex-skeleton span:nth-child(2){animation-delay:.12s}.dsh-codex-skeleton span:nth-child(3){animation-delay:.24s}\r\n.dsh-codex-sr{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0 0 0 0);white-space:nowrap}\r\n.dsh-codex-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;color:var(--dsw-alias-label-secondary);display:inline-flex;font-size:11px;gap:6px;height:28px;line-height:1;max-width:160px;padding:0 9px;white-space:nowrap}\r\n.dsh-codex-composer-quota strong{color:var(--dsw-alias-label-primary);font-size:11px;font-weight:650}\r\n.dsh-codex-composer-quota[data-level=warning] strong{color:var(--dsw-alias-label-warning,#d58a24)}\r\n.dsh-codex-composer-quota[data-level=danger] strong{color:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-image-tool{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex-direction:column;gap:8px;margin:4px 0 4px 4px;max-width:520px;padding:10px 12px}\r\n.dsh-codex-image-tool-head{align-items:center;display:flex;font-size:13px;gap:8px;min-width:0}\r\n.dsh-codex-image-dot{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:50%;display:inline-block;flex:none;height:8px;width:8px}\r\n.dsh-codex-image-tool[data-state=error] .dsh-codex-image-dot{background:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-image-title{font-weight:600}\r\n.dsh-codex-image-summary{color:var(--dsw-alias-label-tertiary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\r\n.dsh-codex-image-grid{display:flex;flex-wrap:wrap;gap:8px}\r\n.dsh-codex-image-preview{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:block;max-height:260px;max-width:min(100%,360px);object-fit:contain}\r\n.dsh-codex-image-loading,.dsh-codex-image-failed{border:1px dashed var(--dsw-alias-border-l2);border-radius:8px;color:var(--dsw-alias-label-tertiary);display:inline-flex;font-size:12px;line-height:1.4;padding:18px 20px}\r\n.dsh-codex-image-failed{color:var(--dsw-alias-label-danger,#d94b4b)}\r\n@keyframes dsh-codex-pulse{0%,100%{opacity:.55}50%{opacity:1}}\r\n@media(max-width:560px){.dsh-codex-row,.dsh-codex-pref-row,.dsh-codex-quota-fact{align-items:flex-start;flex-direction:column;gap:3px}.dsh-codex-value,.dsh-codex-quota-fact strong{text-align:left}.dsh-codex-actions{justify-content:flex-start}.dsh-codex-grouphead{align-items:flex-start;flex-direction:column;gap:0;padding:12px 0}.dsh-codex-meter-meta{align-items:flex-start;flex-direction:column;gap:2px}.dsh-codex-errorbar{align-items:flex-start;flex-direction:column}.dsh-codex-segments{width:100%}.dsh-codex-select{max-width:none;width:100%}.dsh-codex-context-row{align-items:flex-start;flex-direction:column;gap:5px}.dsh-codex-segments label{flex:1}.dsh-codex-segments span{text-align:center}.dsh-codex-image-tool{max-width:100%;margin-left:0}}\r\n@media(prefers-reduced-motion:reduce){.dsh-codex-meter>span{transition:none}.dsh-codex-skeleton span{animation:none}}\r\n`\r\n\r\nexport function installStyles(): () => void {\r\n if (document.querySelector(`style[data-plugin-css=\"${STYLE_ID}\"]`) !== null) return () => undefined\r\n const element = document.createElement('style')\r\n element.dataset.plugin = '@eddyskywalker/dsh-chatgpt-subscription'\r\n element.dataset.pluginCss = STYLE_ID\r\n element.textContent = CSS\r\n document.head.appendChild(element)\r\n return () => element.remove()\r\n}\r\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-tool/client'\nimport { CODEX_IMAGE_TOOL_NAME } from '../compat.ts'\nimport { CodexComposerQuota } from './CodexComposerQuota.tsx'\nimport { CodexImageToolView, type ImageLoader } from './CodexImageToolView.tsx'\nimport { CodexSubscriptionSection } from './CodexSubscriptionSection.tsx'\nimport { SubscriptionApi } from './api.ts'\nimport { dictionaries, NS, type LocaleKey } from './locales.ts'\nimport { installStyles } from './styles.ts'\n\r\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\r\n interface LocaleNamespaceMap {\r\n 'dsh-chatgpt-subscription': LocaleKey\r\n }\r\n}\r\n\r\nexport const inject = ['slots', 'locale', 'modelDirectories', 'conversation']\n\r\nexport function apply(ctx: ClientContext): void {\r\n ctx.effect(() => ctx.locale.register(NS, dictionaries), 'dsh-chatgpt-subscription: dictionaries')\r\n ctx.effect(() => installStyles(), 'dsh-chatgpt-subscription: styles')\r\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'codex-subscription',\n order: 45,\n label: 'Codex 订阅',\n locale: NS,\n }, CodexSubscriptionSection))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right',\n id: 'codex-subscription-quota',\n order: 35,\n locale: NS,\n inject: (sessionId) => {\n const directory = ctx.modelDirectories.directoryFor(sessionId)\n return {\n api: new SubscriptionApi(),\n directory: directory.store,\n loadModelDirectory: () => {\n void directory.load().catch(() => undefined)\n },\n }\n },\n }, CodexComposerQuota))\n ctx.slots.inject('tool.call.toolview', () => ctx.slots.register({\n name: 'tool.call.toolview',\n key: CODEX_IMAGE_TOOL_NAME,\n locale: NS,\n inject: (sessionId) => ({\n loadImage: imageLoader(ctx, sessionId),\n }),\n }, CodexImageToolView))\n}\n\nfunction imageLoader(ctx: ClientContext, sessionId: string): ImageLoader {\n const conversation = ctx.conversation as unknown as {\n resolveImage(sessionId: string, attachment: ImageAttachmentRef): Promise<string>\n }\n return (attachment) => conversation.resolveImage(sessionId, attachment)\n}\n"],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -41,6 +41,7 @@ const OAUTH_AUTHORIZE_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/authorize`;
|
|
|
41
41
|
const OAUTH_TOKEN_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/token`;
|
|
42
42
|
//#endregion
|
|
43
43
|
//#region src/shared/model-catalog.ts
|
|
44
|
+
const GPT_56_MAX_CONTEXT_WINDOW = 1e6;
|
|
44
45
|
const CODEX_MODEL_CATALOG = [
|
|
45
46
|
{
|
|
46
47
|
id: "gpt-5.6-sol",
|
|
@@ -107,6 +108,17 @@ const CODEX_MODEL_CATALOG = [
|
|
|
107
108
|
}
|
|
108
109
|
];
|
|
109
110
|
const DEFAULT_CODEX_MODEL = CODEX_MODEL_CATALOG[0];
|
|
111
|
+
const CONFIGURABLE_CONTEXT_MODEL_IDS = [
|
|
112
|
+
"gpt-5.6-sol",
|
|
113
|
+
"gpt-5.6-terra",
|
|
114
|
+
"gpt-5.6-luna"
|
|
115
|
+
];
|
|
116
|
+
function isCodexModelId(model) {
|
|
117
|
+
return typeof model === "string" && CODEX_MODEL_CATALOG.some((entry) => entry.id === model);
|
|
118
|
+
}
|
|
119
|
+
function isConfigurableContextModelId(model) {
|
|
120
|
+
return typeof model === "string" && CONFIGURABLE_CONTEXT_MODEL_IDS.some((id) => id === model);
|
|
121
|
+
}
|
|
110
122
|
function resolveCodexCatalogEntry(model) {
|
|
111
123
|
return CODEX_MODEL_CATALOG.find((entry) => entry.id === model) ?? DEFAULT_CODEX_MODEL;
|
|
112
124
|
}
|
|
@@ -139,15 +151,16 @@ function listCodexModels() {
|
|
|
139
151
|
inputModalities: [...entry.inputModalities]
|
|
140
152
|
}));
|
|
141
153
|
}
|
|
142
|
-
function resolveCodexModel(model) {
|
|
154
|
+
function resolveCodexModel(model, preferences) {
|
|
143
155
|
const entry = resolveCodexCatalogEntry(model);
|
|
156
|
+
const configuredContextWindow = isConfigurableContextModelId(model) ? preferences?.status().contextWindowOverrides[model] : void 0;
|
|
144
157
|
const efforts = MODEL_REASONING[entry.reasoningProfile];
|
|
145
158
|
return {
|
|
146
159
|
provider: PROVIDER_ID,
|
|
147
160
|
id: model,
|
|
148
161
|
name: entry.id === model ? entry.name : model,
|
|
149
162
|
inputModalities: [...entry.inputModalities],
|
|
150
|
-
context: { contextWindow: entry.contextWindow },
|
|
163
|
+
context: { contextWindow: configuredContextWindow ?? entry.contextWindow },
|
|
151
164
|
defaultMaxTokens: 32768,
|
|
152
165
|
reasoning: {
|
|
153
166
|
efforts: efforts.map((effort) => ({
|
|
@@ -176,9 +189,11 @@ const RETRY_POLICY = resolveRetryPolicy({
|
|
|
176
189
|
}, "dsh-chatgpt-subscription.retry");
|
|
177
190
|
var CodexChatGptAdapter = class extends LlmAdapter {
|
|
178
191
|
client;
|
|
179
|
-
|
|
192
|
+
preferences;
|
|
193
|
+
constructor(client, preferences) {
|
|
180
194
|
super();
|
|
181
195
|
this.client = client;
|
|
196
|
+
this.preferences = preferences;
|
|
182
197
|
}
|
|
183
198
|
providerInfo(provider) {
|
|
184
199
|
return {
|
|
@@ -193,7 +208,7 @@ var CodexChatGptAdapter = class extends LlmAdapter {
|
|
|
193
208
|
return listCodexModels();
|
|
194
209
|
}
|
|
195
210
|
async resolveModel(_provider, model) {
|
|
196
|
-
return resolveCodexModel(model);
|
|
211
|
+
return resolveCodexModel(model, this.preferences);
|
|
197
212
|
}
|
|
198
213
|
stream(options) {
|
|
199
214
|
return this.client.stream(options);
|
|
@@ -1049,7 +1064,13 @@ async function oauthErrorIdentifier(response) {
|
|
|
1049
1064
|
const PREFERENCES_NAMESPACE = "dsh-chatgpt-subscription";
|
|
1050
1065
|
const DEFAULT_PREFERENCES = {
|
|
1051
1066
|
quickQuotaVisible: false,
|
|
1052
|
-
searchProvider: "dsh"
|
|
1067
|
+
searchProvider: "dsh",
|
|
1068
|
+
subagentModel: "gpt-5.6-sol",
|
|
1069
|
+
contextWindowOverrides: {
|
|
1070
|
+
"gpt-5.6-sol": 272e3,
|
|
1071
|
+
"gpt-5.6-terra": 272e3,
|
|
1072
|
+
"gpt-5.6-luna": 272e3
|
|
1073
|
+
}
|
|
1053
1074
|
};
|
|
1054
1075
|
const SEARCH_PROVIDER_CODEX = "codex";
|
|
1055
1076
|
function isSearchProviderPreference(value) {
|
|
@@ -1060,7 +1081,13 @@ function isSearchProviderPreference(value) {
|
|
|
1060
1081
|
function registerPreferenceStore(settings) {
|
|
1061
1082
|
return new SettingsPreferenceStore(settings.register(settingsNamespace(PREFERENCES_NAMESPACE), z.object({
|
|
1062
1083
|
quickQuotaVisible: z.boolean().default(DEFAULT_PREFERENCES.quickQuotaVisible),
|
|
1063
|
-
searchProvider: z.union([z.const("dsh"), z.const(SEARCH_PROVIDER_CODEX)]).default(DEFAULT_PREFERENCES.searchProvider)
|
|
1084
|
+
searchProvider: z.union([z.const("dsh"), z.const(SEARCH_PROVIDER_CODEX)]).default(DEFAULT_PREFERENCES.searchProvider),
|
|
1085
|
+
subagentModel: z.string().default(DEFAULT_PREFERENCES.subagentModel),
|
|
1086
|
+
contextWindowOverrides: z.object({
|
|
1087
|
+
"gpt-5.6-sol": z.number().step(1).min(1).max(GPT_56_MAX_CONTEXT_WINDOW).default(DEFAULT_PREFERENCES.contextWindowOverrides["gpt-5.6-sol"]),
|
|
1088
|
+
"gpt-5.6-terra": z.number().step(1).min(1).max(GPT_56_MAX_CONTEXT_WINDOW).default(DEFAULT_PREFERENCES.contextWindowOverrides["gpt-5.6-terra"]),
|
|
1089
|
+
"gpt-5.6-luna": z.number().step(1).min(1).max(GPT_56_MAX_CONTEXT_WINDOW).default(DEFAULT_PREFERENCES.contextWindowOverrides["gpt-5.6-luna"])
|
|
1090
|
+
}).default(DEFAULT_PREFERENCES.contextWindowOverrides)
|
|
1064
1091
|
})));
|
|
1065
1092
|
}
|
|
1066
1093
|
var SettingsPreferenceStore = class {
|
|
@@ -1078,6 +1105,11 @@ var SettingsPreferenceStore = class {
|
|
|
1078
1105
|
if (!isSearchProviderPreference(patch.searchProvider)) throw new PreferenceError("Unsupported search provider preference.");
|
|
1079
1106
|
normalized.searchProvider = patch.searchProvider;
|
|
1080
1107
|
}
|
|
1108
|
+
if (patch.subagentModel !== void 0) normalized.subagentModel = patch.subagentModel;
|
|
1109
|
+
if (patch.contextWindowOverrides !== void 0) normalized.contextWindowOverrides = {
|
|
1110
|
+
...this.scope.get().contextWindowOverrides,
|
|
1111
|
+
...patch.contextWindowOverrides
|
|
1112
|
+
};
|
|
1081
1113
|
await this.scope.update(normalized);
|
|
1082
1114
|
return this.status();
|
|
1083
1115
|
}
|
|
@@ -2342,6 +2374,9 @@ function field(value, name) {
|
|
|
2342
2374
|
const candidate = value[name];
|
|
2343
2375
|
return typeof candidate === "string" && candidate !== "" ? candidate : null;
|
|
2344
2376
|
}
|
|
2377
|
+
function isRecord(value) {
|
|
2378
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2379
|
+
}
|
|
2345
2380
|
function readPreferencesUpdate(value) {
|
|
2346
2381
|
const patch = {};
|
|
2347
2382
|
if ("quickQuotaVisible" in value) {
|
|
@@ -2352,6 +2387,20 @@ function readPreferencesUpdate(value) {
|
|
|
2352
2387
|
if (value.searchProvider !== "dsh" && value.searchProvider !== "codex") throw new PreferenceError("searchProvider must be dsh or codex.");
|
|
2353
2388
|
patch.searchProvider = value.searchProvider;
|
|
2354
2389
|
}
|
|
2390
|
+
if ("subagentModel" in value) {
|
|
2391
|
+
if (!isCodexModelId(value.subagentModel)) throw new PreferenceError("subagentModel must be an available Codex model.");
|
|
2392
|
+
patch.subagentModel = value.subagentModel;
|
|
2393
|
+
}
|
|
2394
|
+
if ("contextWindowOverrides" in value) {
|
|
2395
|
+
if (!isRecord(value.contextWindowOverrides)) throw new PreferenceError("contextWindowOverrides must be an object.");
|
|
2396
|
+
const overrides = {};
|
|
2397
|
+
for (const [model, contextWindow] of Object.entries(value.contextWindowOverrides)) {
|
|
2398
|
+
if (!isConfigurableContextModelId(model)) throw new PreferenceError("Only GPT-5.6 context windows can be changed.");
|
|
2399
|
+
if (!Number.isSafeInteger(contextWindow) || contextWindow < 1 || contextWindow > 1e6) throw new PreferenceError(`contextWindowOverrides.${model} must be a positive integer no greater than the provider limit.`);
|
|
2400
|
+
overrides[model] = contextWindow;
|
|
2401
|
+
}
|
|
2402
|
+
patch.contextWindowOverrides = overrides;
|
|
2403
|
+
}
|
|
2355
2404
|
return patch;
|
|
2356
2405
|
}
|
|
2357
2406
|
function json(response, envelope, status = 200) {
|
|
@@ -2748,6 +2797,23 @@ function currentConfig(entry) {
|
|
|
2748
2797
|
return typeof config === "object" && config !== null && !Array.isArray(config) ? config : {};
|
|
2749
2798
|
}
|
|
2750
2799
|
//#endregion
|
|
2800
|
+
//#region src/host/subagent-model-preference.ts
|
|
2801
|
+
/**
|
|
2802
|
+
* Route in-process delegated agents through the configured ChatGPT subscription
|
|
2803
|
+
* model. Root sessions retain their own model selection.
|
|
2804
|
+
*/
|
|
2805
|
+
function installSubagentModelPreference(ctx, preferences) {
|
|
2806
|
+
return ctx.on("agent/request", async (payload, next) => {
|
|
2807
|
+
const resolved = await next();
|
|
2808
|
+
if (payload.agent.session.header.origin !== "subagent") return resolved;
|
|
2809
|
+
return {
|
|
2810
|
+
...resolved,
|
|
2811
|
+
provider: PROVIDER_ID,
|
|
2812
|
+
model: preferences.status().subagentModel
|
|
2813
|
+
};
|
|
2814
|
+
});
|
|
2815
|
+
}
|
|
2816
|
+
//#endregion
|
|
2751
2817
|
//#region src/index.ts
|
|
2752
2818
|
const inject = [
|
|
2753
2819
|
"webServer",
|
|
@@ -2765,7 +2831,7 @@ function apply(ctx) {
|
|
|
2765
2831
|
const adapter = new CodexChatGptAdapter(new ResponsesClient(oauth, ctx.attachments, {
|
|
2766
2832
|
localRawImages: { baseUrl: localWebServerBaseUrl(ctx.webServer.host, ctx.webServer.port) },
|
|
2767
2833
|
onGenerationFinished: () => usage.invalidate()
|
|
2768
|
-
}));
|
|
2834
|
+
}), preferences);
|
|
2769
2835
|
ctx.effect(() => {
|
|
2770
2836
|
const searchSwitcher = new SearchProviderSwitcher(ctx.loader);
|
|
2771
2837
|
const applySearchPreference = (searchProvider = preferences.status().searchProvider) => {
|
|
@@ -2775,12 +2841,14 @@ function apply(ctx) {
|
|
|
2775
2841
|
};
|
|
2776
2842
|
const disposeRoutes = registerRoutes(ctx, oauth, usage, preferences);
|
|
2777
2843
|
const disposeAdapter = ctx.llm.registerAdapter([PROVIDER_ID], adapter);
|
|
2844
|
+
const disposeSubagentModelPreference = installSubagentModelPreference(ctx, preferences);
|
|
2778
2845
|
const disposeImageTool = ctx.tools.register(createCodexImageTool(oauth, ctx.attachments));
|
|
2779
2846
|
const disposeSearchProvider = ctx.web.registerSearchProvider(createCodexSearchProvider(oauth));
|
|
2780
2847
|
const disposePreferenceWatch = preferences.watch((next) => applySearchPreference(next.searchProvider));
|
|
2781
2848
|
applySearchPreference();
|
|
2782
2849
|
return () => {
|
|
2783
2850
|
disposePreferenceWatch();
|
|
2851
|
+
disposeSubagentModelPreference();
|
|
2784
2852
|
disposeSearchProvider();
|
|
2785
2853
|
disposeImageTool();
|
|
2786
2854
|
disposeAdapter();
|
|
@@ -12,6 +12,7 @@ export declare function QuotaBar({ label, window, t }: {
|
|
|
12
12
|
t: Translate;
|
|
13
13
|
}): React.JSX.Element;
|
|
14
14
|
export declare function windowLabel(minutes: number | null, t: Translate): string;
|
|
15
|
+
export declare function parseCapacity(value: string): number | null;
|
|
15
16
|
export declare function formatReset(seconds: number): string;
|
|
16
17
|
export {};
|
|
17
18
|
//# sourceMappingURL=CodexSubscriptionSection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodexSubscriptionSection.d.ts","sourceRoot":"","sources":["../../../src/client/CodexSubscriptionSection.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACjF,OAAO,KAAK,EAAE,oBAAoB,EAAmC,cAAc,EAAoC,MAAM,wBAAwB,CAAA;AAGrJ,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,KAAK,KAAK,GAAG,YAAY,CAAC,kBAAkB,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;AAEtE,KAAK,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;AAE3B,wBAAgB,wBAAwB,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"CodexSubscriptionSection.d.ts","sourceRoot":"","sources":["../../../src/client/CodexSubscriptionSection.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACjF,OAAO,KAAK,EAAE,oBAAoB,EAAmC,cAAc,EAAoC,MAAM,wBAAwB,CAAA;AAGrJ,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,KAAK,KAAK,GAAG,YAAY,CAAC,kBAAkB,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;AAEtE,KAAK,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;AAE3B,wBAAgB,wBAAwB,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA4QxE;AAiBD,wBAAgB,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAO5F;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAO7F;AAcD,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAczH;AAMD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAQxE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO1D;AA0BD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUnD"}
|
|
@@ -42,6 +42,13 @@ export declare const zh: {
|
|
|
42
42
|
readonly searchProviderHint: "选择 DSH Web 搜索工具使用默认来源,或改用当前 ChatGPT 订阅的 Codex 搜索来源。";
|
|
43
43
|
readonly searchProviderDsh: "DSH 默认";
|
|
44
44
|
readonly searchProviderCodex: "Codex 订阅";
|
|
45
|
+
readonly subagentModel: "子代理模型";
|
|
46
|
+
readonly subagentModelHint: "新启动的内置子代理使用此 ChatGPT 订阅模型;父会话的模型选择不受影响。";
|
|
47
|
+
readonly contextWindows: "GPT-5.6 上下文窗口";
|
|
48
|
+
readonly contextWindowsHint: "默认 272K;可选启用最高 1M。该值用于 DSH 的压缩与溢出判断,可输入 1M、512K 等容量。";
|
|
49
|
+
readonly contextWindow: "上下文窗口";
|
|
50
|
+
readonly contextWindowInvalid: "上下文窗口必须是 1 到 1M 的整数,可使用 K 或 M 后缀。";
|
|
51
|
+
readonly tokens: "tokens";
|
|
45
52
|
readonly quickQuota: "在输入框旁显示快捷用量";
|
|
46
53
|
readonly quickQuotaHint: "仅在当前会话选中 codex-chatgpt 模型时显示。";
|
|
47
54
|
readonly quota: "用量与限额";
|
|
@@ -128,6 +135,13 @@ export declare const dictionaries: {
|
|
|
128
135
|
readonly searchProviderHint: "选择 DSH Web 搜索工具使用默认来源,或改用当前 ChatGPT 订阅的 Codex 搜索来源。";
|
|
129
136
|
readonly searchProviderDsh: "DSH 默认";
|
|
130
137
|
readonly searchProviderCodex: "Codex 订阅";
|
|
138
|
+
readonly subagentModel: "子代理模型";
|
|
139
|
+
readonly subagentModelHint: "新启动的内置子代理使用此 ChatGPT 订阅模型;父会话的模型选择不受影响。";
|
|
140
|
+
readonly contextWindows: "GPT-5.6 上下文窗口";
|
|
141
|
+
readonly contextWindowsHint: "默认 272K;可选启用最高 1M。该值用于 DSH 的压缩与溢出判断,可输入 1M、512K 等容量。";
|
|
142
|
+
readonly contextWindow: "上下文窗口";
|
|
143
|
+
readonly contextWindowInvalid: "上下文窗口必须是 1 到 1M 的整数,可使用 K 或 M 后缀。";
|
|
144
|
+
readonly tokens: "tokens";
|
|
131
145
|
readonly quickQuota: "在输入框旁显示快捷用量";
|
|
132
146
|
readonly quickQuotaHint: "仅在当前会话选中 codex-chatgpt 模型时显示。";
|
|
133
147
|
readonly quota: "用量与限额";
|
|
@@ -168,6 +182,6 @@ export declare const dictionaries: {
|
|
|
168
182
|
readonly retry: "重试";
|
|
169
183
|
readonly unknown: "未知";
|
|
170
184
|
};
|
|
171
|
-
en: Record<"
|
|
185
|
+
en: Record<"tokens" | "title" | "intro" | "account" | "signedOut" | "signedIn" | "plan" | "accountId" | "expires" | "storage" | "storageWindows" | "storageMacKeychain" | "storageLinuxFile" | "storageMemory" | "storageUnavailable" | "securityWindows" | "securityMacKeychain" | "securityLinuxFile" | "securityMemory" | "securityUnavailable" | "signIn" | "signInAgain" | "cancel" | "signOut" | "refreshToken" | "pending" | "popupBlocked" | "continueLogin" | "loading" | "connection" | "provider" | "connectionState" | "connected" | "untested" | "testConnection" | "testing" | "latency" | "models" | "enhancements" | "searchProvider" | "searchProviderHint" | "searchProviderDsh" | "searchProviderCodex" | "subagentModel" | "subagentModelHint" | "contextWindows" | "contextWindowsHint" | "contextWindow" | "contextWindowInvalid" | "quickQuota" | "quickQuotaHint" | "quota" | "quotaIntro" | "refreshQuota" | "refreshing" | "noQuota" | "quotaSignedOut" | "stale" | "updated" | "primary" | "secondary" | "limitWindow" | "used" | "remaining" | "available" | "unavailable" | "unlimited" | "credits" | "monthlySpend" | "resetCredits" | "spendControlReached" | "limit" | "exhausted" | "resets" | "quickQuotaLabel" | "quickQuotaLoading" | "imageToolRunning" | "imageToolDone" | "imageToolFailed" | "image" | "openImage" | "openNamedImage" | "imageLoading" | "imageLoadFailed" | "imagePreviewClose" | "imagePreviewOpenOriginal" | "retry" | "unknown", string>;
|
|
172
186
|
};
|
|
173
187
|
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE,EAAG,0BAAmC,CAAA;AAErD,eAAO,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE,EAAG,0BAAmC,CAAA;AAErD,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyFL,CAAA;AAEV,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,OAAO,EAAE,EAAE,MAAM,CAyF9C,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,EAAE,CAAA;AACvC,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAa,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/client/styles.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/client/styles.ts"],"names":[],"mappings":"AAsFA,wBAAgB,aAAa,IAAI,MAAM,IAAI,CAQ1C"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { LlmAdapter, type GenerateOptions, type LlmModelInfo, type LlmProviderInfo, type LlmResolvedModelInfo, type ResolvedRetryPolicy, type StreamChunk } from '@deepseek-ai/dsh-llm';
|
|
2
2
|
import { PROVIDER_ID } from './model-catalog.ts';
|
|
3
3
|
import { ResponsesClient } from './responses-client.ts';
|
|
4
|
+
import type { SubscriptionPreferenceStore } from './preferences.ts';
|
|
4
5
|
export declare class CodexChatGptAdapter extends LlmAdapter {
|
|
5
6
|
private readonly client;
|
|
6
|
-
|
|
7
|
+
private readonly preferences?;
|
|
8
|
+
constructor(client: ResponsesClient, preferences?: SubscriptionPreferenceStore | undefined);
|
|
7
9
|
providerInfo(provider: string): LlmProviderInfo;
|
|
8
10
|
providerRetryPolicy(): ResolvedRetryPolicy;
|
|
9
11
|
listModels(): Promise<readonly LlmModelInfo[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/host/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAEV,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAmB,WAAW,EAAoC,MAAM,oBAAoB,CAAA;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/host/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAEV,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAmB,WAAW,EAAoC,MAAM,oBAAoB,CAAA;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAA;AASnE,qBAAa,mBAAoB,SAAQ,UAAU;IAE/C,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;gBADZ,MAAM,EAAE,eAAe,EACvB,WAAW,CAAC,EAAE,2BAA2B,YAAA;IAK5D,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe;IAI/C,mBAAmB,IAAI,mBAAmB;IAIpC,UAAU,IAAI,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC;IAI9C,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAInF,MAAM,CAAC,OAAO,EAAE,eAAe,GAAG,aAAa,CAAC,WAAW,CAAC;CAG7D;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { LlmModelInfo, LlmResolvedModelInfo } from '@deepseek-ai/dsh-llm';
|
|
2
|
+
import type { SubscriptionPreferenceStore } from './preferences.ts';
|
|
2
3
|
export declare const PROVIDER_ID: "codex-chatgpt";
|
|
3
4
|
export declare const PROVIDER_NAME: "Codex\uFF08ChatGPT \u8BA2\u9605\uFF09";
|
|
4
5
|
export declare function listCodexModels(): LlmModelInfo[];
|
|
5
|
-
export declare function resolveCodexModel(model: string): LlmResolvedModelInfo;
|
|
6
|
+
export declare function resolveCodexModel(model: string, preferences?: SubscriptionPreferenceStore): LlmResolvedModelInfo;
|
|
6
7
|
//# sourceMappingURL=model-catalog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../../../src/host/model-catalog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../../../src/host/model-catalog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAG9E,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAA;AAEnE,eAAO,MAAM,WAAW,iBAA4B,CAAA;AACpD,eAAO,MAAM,aAAa,EAAG,uCAA4B,CAAA;AAUzD,wBAAgB,eAAe,IAAI,YAAY,EAAE,CAOhD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,2BAA2B,GAAG,oBAAoB,CAqBhH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../../../src/host/preferences.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,gBAAgB,EAAsB,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../../../src/host/preferences.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,gBAAgB,EAAsB,MAAM,2BAA2B,CAAA;AAUxG,OAAO,KAAK,EACV,0BAA0B,EAC1B,gCAAgC,EACjC,MAAM,wBAAwB,CAAA;AAE/B,MAAM,WAAW,2BAA2B;IAC1C,MAAM,IAAI,0BAA0B,CAAA;IACpC,MAAM,CAAC,KAAK,EAAE,gCAAgC,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAA;IACpF,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,0BAA0B,EAAE,IAAI,EAAE,0BAA0B,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAA;CAC1H;AAID,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,2BAA2B,CAe/F;AAgCD,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAG5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/host/routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/host/routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAKlD,OAAO,EAAE,YAAY,EAAe,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAmB,KAAK,2BAA2B,EAAE,MAAM,kBAAkB,CAAA;AACpF,OAAO,EAAE,YAAY,EAAqB,MAAM,oBAAoB,CAAA;AAIpE,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,2BAA2B,GAAG,MAAM,IAAI,CA+I3I"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { SubscriptionPreferenceStore } from './preferences.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Route in-process delegated agents through the configured ChatGPT subscription
|
|
5
|
+
* model. Root sessions retain their own model selection.
|
|
6
|
+
*/
|
|
7
|
+
export declare function installSubagentModelPreference(ctx: Context, preferences: SubscriptionPreferenceStore): () => void;
|
|
8
|
+
//# sourceMappingURL=subagent-model-preference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagent-model-preference.d.ts","sourceRoot":"","sources":["../../../src/host/subagent-model-preference.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAIlD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAA;AAEnE;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,2BAA2B,GAAG,MAAM,IAAI,CAUjH"}
|
package/lib/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAqBlD,eAAO,MAAM,MAAM,UAA4E,CAAA;AAE/F,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAkCxC;AAED,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACtF,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAA;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,YAAY,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA"}
|
|
@@ -25,14 +25,23 @@ export interface PluginStatusDto {
|
|
|
25
25
|
}
|
|
26
26
|
export type OAuthStatusDto = Omit<PluginStatusDto, 'quota' | 'preferences'>;
|
|
27
27
|
export type SearchProviderPreference = 'dsh' | 'codex';
|
|
28
|
+
export interface CodexContextWindowOverridesDto {
|
|
29
|
+
'gpt-5.6-sol': number;
|
|
30
|
+
'gpt-5.6-terra': number;
|
|
31
|
+
'gpt-5.6-luna': number;
|
|
32
|
+
}
|
|
28
33
|
export interface SubscriptionPreferencesDto {
|
|
29
34
|
quickQuotaVisible: boolean;
|
|
30
35
|
searchProvider: SearchProviderPreference;
|
|
36
|
+
subagentModel: string;
|
|
37
|
+
contextWindowOverrides: CodexContextWindowOverridesDto;
|
|
31
38
|
writable: boolean;
|
|
32
39
|
}
|
|
33
40
|
export interface SubscriptionPreferencesUpdateDto {
|
|
34
41
|
quickQuotaVisible?: boolean;
|
|
35
42
|
searchProvider?: SearchProviderPreference;
|
|
43
|
+
subagentModel?: string;
|
|
44
|
+
contextWindowOverrides?: Partial<CodexContextWindowOverridesDto>;
|
|
36
45
|
}
|
|
37
46
|
export interface QuotaWindowDto {
|
|
38
47
|
usedPercent: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../src/shared/contracts.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GACf,gBAAgB,GAChB,YAAY,GACZ,QAAQ,CAAA;AAEZ,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,qBAAqB,CAAA;IAC3B,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,OAAO,CAAA;IACtB,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACnC,OAAO,EAAE,oBAAoB,CAAA;IAC7B,KAAK,EAAE;QACL,MAAM,EAAE,OAAO,CAAA;QACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;QACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KACzB,CAAA;IACD,KAAK,EAAE,cAAc,CAAA;IACrB,WAAW,EAAE,0BAA0B,CAAA;IACvC,KAAK,CAAC,EAAE,cAAc,CAAA;CACvB;AAED,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,aAAa,CAAC,CAAA;AAE3E,MAAM,MAAM,wBAAwB,GAAG,KAAK,GAAG,OAAO,CAAA;AAEtD,MAAM,WAAW,0BAA0B;IACzC,iBAAiB,EAAE,OAAO,CAAA;IAC1B,cAAc,EAAE,wBAAwB,CAAA;IACxC,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,gCAAgC;IAC/C,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,cAAc,CAAC,EAAE,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../src/shared/contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type CodexModelModality = 'text' | 'image';
|
|
2
|
+
export declare const GPT_56_MAX_CONTEXT_WINDOW = 1000000;
|
|
2
3
|
export interface CodexModelCatalogEntry {
|
|
3
4
|
id: string;
|
|
4
5
|
name: string;
|
|
@@ -75,6 +76,10 @@ export declare const DEFAULT_CODEX_MODEL: {
|
|
|
75
76
|
readonly reasoningProfile: "gpt-5.6";
|
|
76
77
|
readonly supportsReasoningSummary: true;
|
|
77
78
|
};
|
|
79
|
+
export declare const CONFIGURABLE_CONTEXT_MODEL_IDS: readonly ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"];
|
|
80
|
+
export type ConfigurableContextModelId = typeof CONFIGURABLE_CONTEXT_MODEL_IDS[number];
|
|
81
|
+
export declare function isCodexModelId(model: unknown): model is CodexModelId;
|
|
82
|
+
export declare function isConfigurableContextModelId(model: unknown): model is ConfigurableContextModelId;
|
|
78
83
|
export declare function resolveCodexCatalogEntry(model: string): CodexModelCatalogEntry;
|
|
79
84
|
export declare function codexModelSupportsImageInput(model: string): boolean;
|
|
80
85
|
export declare function codexModelSupportsReasoningSummary(model: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../../../src/shared/model-catalog.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,OAAO,CAAA;AAEjD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,SAAS,kBAAkB,EAAE,CAAA;IAC9C,sBAAsB,EAAE,MAAM,CAAA;IAC9B,gBAAgB,EAAE,UAAU,GAAG,SAAS,CAAA;IACxC,wBAAwB,EAAE,OAAO,CAAA;CAClC;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgEsB,CAAA;AAEtD,MAAM,MAAM,YAAY,GAAG,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAA;AAEnE,eAAO,MAAM,mBAAmB;;;;;;;;CAAyB,CAAA;AAEzD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,sBAAsB,CAE9E;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzE"}
|
|
1
|
+
{"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../../../src/shared/model-catalog.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,OAAO,CAAA;AAEjD,eAAO,MAAM,yBAAyB,UAAY,CAAA;AAElD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,SAAS,kBAAkB,EAAE,CAAA;IAC9C,sBAAsB,EAAE,MAAM,CAAA;IAC9B,gBAAgB,EAAE,UAAU,GAAG,SAAS,CAAA;IACxC,wBAAwB,EAAE,OAAO,CAAA;CAClC;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgEsB,CAAA;AAEtD,MAAM,MAAM,YAAY,GAAG,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAA;AAEnE,eAAO,MAAM,mBAAmB;;;;;;;;CAAyB,CAAA;AAEzD,eAAO,MAAM,8BAA8B,2DAIC,CAAA;AAE5C,MAAM,MAAM,0BAA0B,GAAG,OAAO,8BAA8B,CAAC,MAAM,CAAC,CAAA;AAEtF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,0BAA0B,CAEhG;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,sBAAsB,CAE9E;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../../../src/shared/preferences.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAA;AAE1F,eAAO,MAAM,qBAAqB,6BAA6B,CAAA;AAE/D,eAAO,MAAM,mBAAmB,EAAE,IAAI,CAAC,0BAA0B,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../../../src/shared/preferences.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAA;AAE1F,eAAO,MAAM,qBAAqB,6BAA6B,CAAA;AAE/D,eAAO,MAAM,mBAAmB,EAAE,IAAI,CAAC,0BAA0B,EAAE,UAAU,CAS5E,CAAA;AAED,eAAO,MAAM,mBAAmB,EAAE,wBAAgC,CAAA;AAClE,eAAO,MAAM,qBAAqB,EAAE,wBAAkC,CAAA;AAEtE,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,wBAAwB,CAE5F"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eddyskywalker/dsh-chatgpt-subscription",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "DSH provider plugin for Codex access through a ChatGPT subscription.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "eddyskywalker",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
63
63
|
"@deepseek-ai/cordis-plugin-loader": "^1.0.2",
|
|
64
|
+
"@deepseek-ai/dsh-agent": "^0.1.0-rc.8",
|
|
64
65
|
"@deepseek-ai/dsh-attachment": "^0.1.0-rc.8",
|
|
65
66
|
"@deepseek-ai/dsh-client-connection": "^0.1.0-rc.8",
|
|
66
67
|
"@deepseek-ai/dsh-client-locale": "^0.1.0-rc.8",
|
|
@@ -81,6 +82,7 @@
|
|
|
81
82
|
"devDependencies": {
|
|
82
83
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
83
84
|
"@deepseek-ai/cordis-plugin-loader": "^1.0.2",
|
|
85
|
+
"@deepseek-ai/dsh-agent": "^0.1.0-rc.8",
|
|
84
86
|
"@deepseek-ai/dsh-attachment": "^0.1.0-rc.8",
|
|
85
87
|
"@deepseek-ai/dsh-client-connection": "^0.1.0-rc.8",
|
|
86
88
|
"@deepseek-ai/dsh-client-locale": "^0.1.0-rc.8",
|