dsh-codex-subscription 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +7 -7
- package/README.en.md +13 -13
- package/README.md +13 -13
- package/THIRD_PARTY_NOTICES.md +1 -0
- package/compatibility.json +9 -0
- package/lib/client.js +364 -59
- package/lib/index.js +16 -7
- package/package.json +41 -40
package/AGENTS.md
CHANGED
|
@@ -6,7 +6,7 @@ Use this guide when a user asks an Agent to install, update, verify, or remove
|
|
|
6
6
|
## Safety
|
|
7
7
|
|
|
8
8
|
- Confirm the target DSH installation and profile. Use `web` only when it is the user's target.
|
|
9
|
-
- Use the exact `1.1.
|
|
9
|
+
- Use the exact `1.1.5` package below; do not install a moving branch.
|
|
10
10
|
- Never print OAuth credentials, account IDs, authorization callbacks, or credential-store contents.
|
|
11
11
|
- Preserve the DSH profile, unrelated plugins, sessions, and saved sign-in.
|
|
12
12
|
- Do not start, stop, or restart DSH without explicit permission.
|
|
@@ -38,19 +38,19 @@ For an official DSH installation run through npm, keep the complete `npx` prefix
|
|
|
38
38
|
run command does not create a global `dsh` command:
|
|
39
39
|
|
|
40
40
|
```sh
|
|
41
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
41
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 plugin --profile web add dsh-codex-subscription@1.1.5
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
With an existing global `dsh` command:
|
|
45
45
|
|
|
46
46
|
```sh
|
|
47
|
-
dsh plugin --profile web add dsh-codex-subscription@1.1.
|
|
47
|
+
dsh plugin --profile web add dsh-codex-subscription@1.1.5
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
From a DSH-Portable folder:
|
|
51
51
|
|
|
52
52
|
```powershell
|
|
53
|
-
.\dsh.exe plugin --profile web add dsh-codex-subscription@1.1.
|
|
53
|
+
.\dsh.exe plugin --profile web add dsh-codex-subscription@1.1.5
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
Use the same `add` command to update or repair. This is the complete package-changing operation.
|
|
@@ -68,9 +68,9 @@ dsh --profile web --dump-config
|
|
|
68
68
|
|
|
69
69
|
For DSH-Portable, replace `dsh` with `.\dsh.exe`. Static acceptance requires:
|
|
70
70
|
|
|
71
|
-
For the official npm route, run the same checks with `npx -y @deepseek-ai/dsh@0.1.
|
|
71
|
+
For the official npm route, run the same checks with `npx -y @deepseek-ai/dsh@0.1.1-rc.1` in place of `dsh`.
|
|
72
72
|
|
|
73
|
-
1. `dsh-codex-subscription` version `1.1.
|
|
73
|
+
1. `dsh-codex-subscription` version `1.1.5` appears exactly once.
|
|
74
74
|
2. `codex-subscription` appears exactly once in the composed config.
|
|
75
75
|
3. No unrelated plugin or profile was changed and DSH was not restarted.
|
|
76
76
|
|
|
@@ -94,7 +94,7 @@ For DSH-Portable:
|
|
|
94
94
|
For the official npm route:
|
|
95
95
|
|
|
96
96
|
```sh
|
|
97
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
97
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 plugin --profile web remove dsh-codex-subscription
|
|
98
98
|
```
|
|
99
99
|
|
|
100
100
|
Uninstall removes only this plugin. It must preserve the profile, sessions, other plugins, and saved
|
package/README.en.md
CHANGED
|
@@ -47,7 +47,7 @@ These capabilities reuse the same local ChatGPT sign-in. Subscription routing fa
|
|
|
47
47
|
|
|
48
48
|
## Prepare DSH
|
|
49
49
|
|
|
50
|
-
This plugin is currently compatible through DeepSeek Harness `0.1.
|
|
50
|
+
This plugin is currently compatible through DeepSeek Harness `0.1.1-rc.1` and requires a ChatGPT account that currently has Codex access.
|
|
51
51
|
|
|
52
52
|
- Do not want to configure Node.js? Use the [community DSH-Portable package](https://github.com/WSL043/DSH-Portable).
|
|
53
53
|
- Prefer the official route? Follow the [DeepSeek Harness run guide](https://github.com/deepseek-ai/deepseek-harness#run).
|
|
@@ -74,11 +74,11 @@ Open PowerShell and paste this one line:
|
|
|
74
74
|
irm 'https://github.com/WSL043/dsh-codex-subscription/releases/latest/download/dsh-codex-setup.ps1' | iex
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
The lightweight setup checks the current folder, the system command, common locations, and any running
|
|
77
|
+
The lightweight setup checks the current folder, the system command, common locations, and any running official DSH or
|
|
78
78
|
[DSH-Portable](https://github.com/WSL043/DSH-Portable), then invokes the official `plugin add`
|
|
79
79
|
operation once. It does not recursively scan disks, install pnpm, create a resident command, snapshot a
|
|
80
80
|
profile, or download the plugin twice. It needs no administrator access and never restarts DSH. Only
|
|
81
|
-
when no existing DSH is found does it use the official npm route pinned to `0.1.
|
|
81
|
+
when no existing DSH is found does it use the official npm route pinned to `0.1.1-rc.1`; the setup warns
|
|
82
82
|
that first-time dependency resolution can take a while.
|
|
83
83
|
|
|
84
84
|
<details>
|
|
@@ -87,9 +87,9 @@ that first-time dependency resolution can take a while.
|
|
|
87
87
|
The official `npx @deepseek-ai/dsh web` command does not create a global `dsh` command. Keep the full `npx` prefix when installing the plugin:
|
|
88
88
|
|
|
89
89
|
```sh
|
|
90
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
91
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
92
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
90
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 plugin --profile web add dsh-codex-subscription
|
|
91
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 plugin --profile web list dsh-codex-subscription --depth 0
|
|
92
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 --profile web --dump-config
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
</details>
|
|
@@ -138,8 +138,8 @@ window returned by the service; Spark uses its independent quota. The plugin doe
|
|
|
138
138
|
|
|
139
139
|
### Composer speed (Beta)
|
|
140
140
|
|
|
141
|
-
With a supported Codex model selected,
|
|
142
|
-
|
|
141
|
+
With a supported Codex model selected, open the composer's model menu to choose Standard or Fast.
|
|
142
|
+
Standard adds no icon; only Fast shows a lightning icon before the model name. Spark does not show the speed entry. Fast mode increases speed and uses more Credits;
|
|
143
143
|
see the [OpenAI Codex Speed documentation](https://learn.chatgpt.com/docs/agent-configuration/speed) for the current rules.
|
|
144
144
|
|
|
145
145
|
## Update and uninstall
|
|
@@ -147,10 +147,10 @@ see the [OpenAI Codex Speed documentation](https://learn.chatgpt.com/docs/agent-
|
|
|
147
147
|
On Windows, rerun the one-line setup above to update. For the official npm route, use:
|
|
148
148
|
|
|
149
149
|
```sh
|
|
150
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
151
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
152
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
153
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
150
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 plugin --profile web update dsh-codex-subscription
|
|
151
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 plugin --profile web list dsh-codex-subscription --depth 0
|
|
152
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 --profile web --dump-config
|
|
153
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 plugin --profile web remove dsh-codex-subscription
|
|
154
154
|
```
|
|
155
155
|
|
|
156
156
|
These operations preserve the DSH profile, other plugins, and saved sign-in.
|
|
@@ -171,7 +171,7 @@ From a DSH-Portable folder, replace `dsh` above with `.\dsh.exe`.
|
|
|
171
171
|
|
|
172
172
|
## Troubleshooting
|
|
173
173
|
|
|
174
|
-
- **`dsh` is not recognized:** the official npm route does not create a global `dsh` command; use the complete `npx -y @deepseek-ai/dsh@0.1.
|
|
174
|
+
- **`dsh` is not recognized:** the official npm route does not create a global `dsh` command; use the complete `npx -y @deepseek-ai/dsh@0.1.1-rc.1 ...` command above;
|
|
175
175
|
- **`dsh.exe` is not recognized:** that file is not in the current folder; enter the DSH-Portable folder first or use the one-line Windows setup;
|
|
176
176
|
- **DSH-Portable is not found:** enter its folder and rerun setup, or run `.\dsh.exe plugin --profile web add dsh-codex-subscription` directly;
|
|
177
177
|
- **More than one DSH exists:** the one-line setup combines running copies with Portable folders detected in common locations; enter its number. For an Agent, use the intended folder or pass `-DshPath` explicitly;
|
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
|
|
49
49
|
## 准备 DSH
|
|
50
50
|
|
|
51
|
-
本插件当前适配到 DeepSeek Harness `0.1.
|
|
51
|
+
本插件当前适配到 DeepSeek Harness `0.1.1-rc.1`,并需要一个当前具有 Codex 使用资格的 ChatGPT 账户。
|
|
52
52
|
|
|
53
53
|
- 不想配置 Node.js:使用 [DSH-Portable(社区便携包)](https://github.com/WSL043/DSH-Portable);
|
|
54
54
|
- 想按官方方式运行:查看 [DeepSeek Harness 官方说明](https://github.com/deepseek-ai/deepseek-harness#run)。
|
|
@@ -75,10 +75,10 @@ Agent 文档包含安装、更新、卸载和验收步骤,并要求保留 DSH
|
|
|
75
75
|
irm 'https://github.com/WSL043/dsh-codex-subscription/releases/latest/download/dsh-codex-setup.ps1' | iex
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
这个轻量助手会检查当前目录、系统命令、常见位置以及正在运行的官方 DSH 或
|
|
79
79
|
[DSH-Portable](https://github.com/WSL043/DSH-Portable),然后调用一次官方
|
|
80
80
|
`plugin add`。它不会递归扫盘、安装 pnpm、创建常驻命令、保存 profile 快照或重复下载插件。
|
|
81
|
-
无需管理员权限,也不会擅自重启 DSH。找不到现有 DSH 时才会使用固定为 `0.1.
|
|
81
|
+
无需管理员权限,也不会擅自重启 DSH。找不到现有 DSH 时才会使用固定为 `0.1.1-rc.1`
|
|
82
82
|
的官方 npm 运行方式;首次解析依赖可能较慢,安装器会先明确提示。
|
|
83
83
|
|
|
84
84
|
<details>
|
|
@@ -87,9 +87,9 @@ irm 'https://github.com/WSL043/dsh-codex-subscription/releases/latest/download/d
|
|
|
87
87
|
官方的 `npx @deepseek-ai/dsh web` 不会创建全局 `dsh` 命令,因此安装插件时也要保留完整的 `npx` 前缀:
|
|
88
88
|
|
|
89
89
|
```sh
|
|
90
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
91
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
92
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
90
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 plugin --profile web add dsh-codex-subscription
|
|
91
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 plugin --profile web list dsh-codex-subscription --depth 0
|
|
92
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 --profile web --dump-config
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
</details>
|
|
@@ -137,8 +137,8 @@ Spark 使用独立额度。插件不会写死“5 小时 + 每周”,也不会
|
|
|
137
137
|
|
|
138
138
|
### 输入框速度(Beta)
|
|
139
139
|
|
|
140
|
-
选择支持的 Codex
|
|
141
|
-
Spark
|
|
140
|
+
选择支持的 Codex 模型后,可在输入框的模型菜单中切换标准与高速。标准模式不增加图标,
|
|
141
|
+
只有高速模式会在模型名称左侧显示闪电;Spark 不显示速度入口。高速模式会提高速度,也会消耗更多 Credits;具体规则见
|
|
142
142
|
[OpenAI Codex Speed 文档](https://learn.chatgpt.com/docs/agent-configuration/speed)。
|
|
143
143
|
|
|
144
144
|
## 更新与卸载
|
|
@@ -146,10 +146,10 @@ Spark 不显示这个入口。高速模式会提高速度,也会消耗更多 C
|
|
|
146
146
|
Windows 用户重新运行上面的单行助手即可更新。官方 npm 用户使用:
|
|
147
147
|
|
|
148
148
|
```sh
|
|
149
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
150
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
151
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
152
|
-
npx -y @deepseek-ai/dsh@0.1.
|
|
149
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 plugin --profile web update dsh-codex-subscription
|
|
150
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 plugin --profile web list dsh-codex-subscription --depth 0
|
|
151
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 --profile web --dump-config
|
|
152
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.1 plugin --profile web remove dsh-codex-subscription
|
|
153
153
|
```
|
|
154
154
|
|
|
155
155
|
这些操作会保留 DSH profile、其他插件和登录信息。
|
|
@@ -170,7 +170,7 @@ DSH-Portable 在其目录中把上述 `dsh` 换成 `.\dsh.exe`。
|
|
|
170
170
|
|
|
171
171
|
## 常见问题
|
|
172
172
|
|
|
173
|
-
- **`dsh` 无法识别**:官方 npm 方式本来就不会创建全局 `dsh` 命令,请使用上面的完整 `npx -y @deepseek-ai/dsh@0.1.
|
|
173
|
+
- **`dsh` 无法识别**:官方 npm 方式本来就不会创建全局 `dsh` 命令,请使用上面的完整 `npx -y @deepseek-ai/dsh@0.1.1-rc.1 ...` 命令;
|
|
174
174
|
- **`dsh.exe` 无法识别**:当前目录没有该文件。请先进入 DSH-Portable 目录,或使用 Windows 单行助手;
|
|
175
175
|
- **找不到 DSH-Portable**:进入它的目录后重新执行安装命令,或直接运行 `.\dsh.exe plugin --profile web add dsh-codex-subscription`;
|
|
176
176
|
- **电脑上有多个 DSH**:单行助手会合并正在运行的副本与常用目录内检测到的 Portable,输入对应编号即可;交给 Agent 时让它进入目标目录,或明确传入 `-DshPath`;
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -7,6 +7,7 @@ This project depends on software distributed under its own terms. The dependency
|
|
|
7
7
|
| DeepSeek Harness packages | Plugin host, client slots, credential and LLM interfaces | MIT | https://github.com/deepseek-ai/deepseek-harness |
|
|
8
8
|
| `@earendil-works/pi-ai` 0.82.1 | OpenAI Codex OAuth, model catalog, Responses transport, and WebSocket continuation | MIT | https://github.com/earendil-works/pi |
|
|
9
9
|
| React | DSH settings component runtime | MIT | https://github.com/facebook/react |
|
|
10
|
+
| Heroicons | Composer speed icon | MIT | https://github.com/tailwindlabs/heroicons |
|
|
10
11
|
| tsdown | Development-time bundler | MIT | https://github.com/rolldown/tsdown |
|
|
11
12
|
|
|
12
13
|
No third-party project endorses this community plugin. See each installed package for its complete license text and transitive dependency notices.
|
package/lib/client.js
CHANGED
|
@@ -4,9 +4,50 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
//#region \0rolldown/runtime.js
|
|
8
|
+
var __create = Object.create;
|
|
9
|
+
var __defProp = Object.defineProperty;
|
|
10
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
11
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
12
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
16
|
+
key = keys[i];
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
18
|
+
get: ((k) => from[k]).bind(null, key),
|
|
19
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return to;
|
|
23
|
+
};
|
|
24
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
25
|
+
value: mod,
|
|
26
|
+
enumerable: true
|
|
27
|
+
}) : target, mod));
|
|
28
|
+
//#endregion
|
|
7
29
|
let react = require("react");
|
|
30
|
+
react = __toESM(react, 1);
|
|
8
31
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
9
32
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
33
|
+
//#region node_modules/.pnpm/@heroicons+react@2.2.0_react@18.3.1/node_modules/@heroicons/react/16/solid/esm/BoltIcon.js
|
|
34
|
+
function BoltIcon({ title, titleId, ...props }, svgRef) {
|
|
35
|
+
return /*#__PURE__*/ react.createElement("svg", Object.assign({
|
|
36
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
37
|
+
viewBox: "0 0 16 16",
|
|
38
|
+
fill: "currentColor",
|
|
39
|
+
"aria-hidden": "true",
|
|
40
|
+
"data-slot": "icon",
|
|
41
|
+
ref: svgRef,
|
|
42
|
+
"aria-labelledby": titleId
|
|
43
|
+
}, props), title ? /*#__PURE__*/ react.createElement("title", { id: titleId }, title) : null, /*#__PURE__*/ react.createElement("path", {
|
|
44
|
+
fillRule: "evenodd",
|
|
45
|
+
d: "M9.58 1.077a.75.75 0 0 1 .405.82L9.165 6h4.085a.75.75 0 0 1 .567 1.241l-6.5 7.5a.75.75 0 0 1-1.302-.638L6.835 10H2.75a.75.75 0 0 1-.567-1.241l6.5-7.5a.75.75 0 0 1 .897-.182Z",
|
|
46
|
+
clipRule: "evenodd"
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
const ForwardRef = /*#__PURE__*/ react.forwardRef(BoltIcon);
|
|
50
|
+
//#endregion
|
|
10
51
|
//#region src/settings-contract.js
|
|
11
52
|
const SETTINGS_NAMESPACE = "codex-subscription";
|
|
12
53
|
const QUICK_QUOTA_FIELD = "quickQuotaVisible";
|
|
@@ -46,7 +87,8 @@ window.__ModuleLoader__.load({
|
|
|
46
87
|
"remote",
|
|
47
88
|
"settingsScope",
|
|
48
89
|
"modelDirectories",
|
|
49
|
-
"conversation"
|
|
90
|
+
"conversation",
|
|
91
|
+
"sessions"
|
|
50
92
|
];
|
|
51
93
|
const NS = "settings.codexSubscription";
|
|
52
94
|
const CHANNEL = "/codex-subscription";
|
|
@@ -112,6 +154,17 @@ window.__ModuleLoader__.load({
|
|
|
112
154
|
speedStandardHint: "标准速度",
|
|
113
155
|
speedFast: "高速",
|
|
114
156
|
speedFastHint: "1.5 倍,消耗更多 Credits",
|
|
157
|
+
modelMenuAria: "模型、推理等级与速度",
|
|
158
|
+
modelLabel: "模型",
|
|
159
|
+
effortLabel: "推理等级",
|
|
160
|
+
providerDefault: "Default",
|
|
161
|
+
selectModel: "选择模型",
|
|
162
|
+
modelsLoading: "正在读取模型…",
|
|
163
|
+
modelsEmpty: "没有可用模型。",
|
|
164
|
+
effortsEmpty: "当前模型未提供推理等级。",
|
|
165
|
+
modelRetry: "重试",
|
|
166
|
+
modelFailed: "模型目录加载失败:{value}",
|
|
167
|
+
groupFailed: "{name}:{value}",
|
|
115
168
|
imageGenerate: "生成图片",
|
|
116
169
|
imageGenerating: "正在生成…",
|
|
117
170
|
imageGenerated: "已生成",
|
|
@@ -184,6 +237,17 @@ window.__ModuleLoader__.load({
|
|
|
184
237
|
speedStandardHint: "Standard speed",
|
|
185
238
|
speedFast: "Fast",
|
|
186
239
|
speedFastHint: "1.5x; higher Credits use",
|
|
240
|
+
modelMenuAria: "Model, effort, and speed",
|
|
241
|
+
modelLabel: "Model",
|
|
242
|
+
effortLabel: "Effort",
|
|
243
|
+
providerDefault: "Default",
|
|
244
|
+
selectModel: "Select model",
|
|
245
|
+
modelsLoading: "Loading models…",
|
|
246
|
+
modelsEmpty: "No models available.",
|
|
247
|
+
effortsEmpty: "This model provides no reasoning effort levels.",
|
|
248
|
+
modelRetry: "Retry",
|
|
249
|
+
modelFailed: "Could not load models: {value}",
|
|
250
|
+
groupFailed: "{name}: {value}",
|
|
187
251
|
imageGenerate: "Generate image",
|
|
188
252
|
imageGenerating: "Generating…",
|
|
189
253
|
imageGenerated: "Generated",
|
|
@@ -222,8 +286,10 @@ window.__ModuleLoader__.load({
|
|
|
222
286
|
.codexSubscriptionCreditSection{display:flex;flex-direction:column;gap:7px}.codexSubscriptionCreditNote{font-size:11px;line-height:17px;color:var(--dsw-alias-label-tertiary)}.codexSubscriptionCreditRows{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:8px}.codexSubscriptionCreditBalance,.codexSubscriptionSpendLimit{min-width:0;border-radius:10px;padding:12px 14px;background:var(--dsw-alias-bg-module-platform)}
|
|
223
287
|
.codexSubscriptionCreditBalance{display:flex;flex-direction:column;gap:6px}.codexSubscriptionCreditBalance span,.codexSubscriptionCreditLabel{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}.codexSubscriptionCreditBalance strong{font:600 18px/24px ui-monospace,SFMono-Regular,Consolas,monospace;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
|
|
224
288
|
.codexSubscriptionSpendLimit{display:flex;flex-direction:column;gap:8px}.codexSubscriptionSpendTop{display:flex;align-items:baseline;justify-content:space-between;gap:12px}.codexSubscriptionSpendTop strong{font:600 16px/22px ui-monospace,SFMono-Regular,Consolas,monospace;font-variant-numeric:tabular-nums}.codexSubscriptionSpendLimit progress{width:100%;height:6px;border:0;border-radius:999px;overflow:hidden;background:var(--dsw-alias-border-l3);accent-color:var(--dsw-alias-brand-primary,#3964fe);-webkit-appearance:none;appearance:none}.codexSubscriptionSpendLimit progress::-webkit-progress-bar{background:var(--dsw-alias-border-l3);border-radius:999px}.codexSubscriptionSpendLimit progress::-webkit-progress-value{background:var(--dsw-alias-brand-primary,#3964fe);border-radius:999px}.codexSubscriptionSpendLimit progress::-moz-progress-bar{background:var(--dsw-alias-brand-primary,#3964fe);border-radius:999px}
|
|
225
|
-
.codexComposerQuota{display:inline-flex;align-items:center;flex:0 0 auto;height:28px;box-sizing:border-box;
|
|
226
|
-
.
|
|
289
|
+
.codexComposerQuota{display:inline-flex;align-items:center;flex:0 0 auto;height:28px;box-sizing:border-box;padding:0;color:var(--dsw-alias-label-secondary);font-family:inherit;font-size:12px;line-height:20px;font-weight:500;font-variant-numeric:tabular-nums;white-space:nowrap;user-select:none}
|
|
290
|
+
.codexModelSelect{position:relative;min-width:0}.codexModelSelectTrigger{display:flex;align-items:center;gap:4px;min-width:0;max-width:min(360px,45cqw);height:28px;padding:0 4px 0 8px;border:0;border-radius:24px;outline:0;background:transparent;color:var(--dsw-alias-label-secondary);font-size:13px;font-weight:500;line-height:20px;cursor:pointer}.codexModelSelectTrigger:hover:not(:disabled),.codexModelSelectTrigger[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover)}.codexModelSelectTrigger:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}.codexModelSelectTrigger:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.codexModelSelectBolt{display:block;flex:none;width:14px;height:14px;color:var(--dsw-alias-label-primary)}.codexModelSelectLabel{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.codexModelSelectEffort{flex:none;color:var(--dsw-alias-label-caption)}.codexModelSelectChevron{flex:none;color:var(--dsw-alias-label-caption);transition:transform 120ms}.codexModelSelectTrigger[aria-expanded=true] .codexModelSelectChevron{transform:rotate(180deg)}
|
|
291
|
+
.codexModelSelectMenu,.codexModelSelectSubmenu{position:absolute;z-index:30;box-sizing:border-box;width:max-content;min-width:min(240px,calc(100vw - 32px));max-width:min(420px,calc(100vw - 32px));max-height:min(360px,calc(100vh - 96px));padding:4px;border:1px solid var(--dsw-alias-border-inverted);border-radius:12px;background:var(--dsw-specific-menu);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);overflow:hidden}.codexModelSelectMenu{right:0;bottom:calc(100% + 8px)}.codexModelSelectSubmenu{right:calc(100% + 8px);bottom:0;min-width:min(230px,calc(100vw - 32px))}.codexModelSelectCell{display:flex;align-items:center;gap:8px;width:100%;min-width:100%;height:40px;box-sizing:border-box;padding:0 10px;border:0;border-radius:10px;background:transparent;color:inherit;font-size:14px;line-height:22px;text-align:left;cursor:pointer}.codexModelSelectCell:hover,.codexModelSelectCell:focus-visible,.codexModelSelectCell[data-open=true]{background:var(--dsw-alias-interactive-bg-hover);outline:0}.codexModelSelectCell:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.codexModelSelectCellLabel{flex:none;white-space:nowrap}.codexModelSelectCellValue{flex:auto;min-width:0;overflow:hidden;color:var(--dsw-alias-label-tertiary);text-align:right;text-overflow:ellipsis;white-space:nowrap}.codexModelSelectCellChevron{flex:none;color:var(--dsw-alias-label-tertiary)}.codexModelSelectGroups{min-height:0;max-height:352px;overflow-y:auto}.codexModelSelectGroup+.codexModelSelectGroup{margin-top:4px}.codexModelSelectGroupTitle{position:sticky;top:0;z-index:1;padding:5px 8px 3px;background:var(--dsw-specific-menu);color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:500;line-height:18px}.codexModelSelectOption{display:flex;align-items:center;gap:8px;width:100%;min-width:100%;min-height:38px;box-sizing:border-box;padding:6px 8px;border:0;border-radius:10px;outline:0;background:transparent;color:inherit;text-align:left;cursor:pointer}.codexModelSelectOption:hover:not(:disabled),.codexModelSelectOption:focus-visible{background:var(--dsw-alias-interactive-bg-hover)}.codexModelSelectOption:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.codexModelSelectOptionCopy{display:flex;flex:1;min-width:0;flex-direction:column}.codexModelSelectOptionName{overflow:hidden;color:inherit;font-size:14px;font-weight:500;line-height:20px;text-overflow:ellipsis;white-space:nowrap}.codexModelSelectOptionDescription{overflow:hidden;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;text-overflow:ellipsis;white-space:nowrap}.codexModelSelectCheck{display:grid;place-items:center;flex:0 0 18px;color:var(--dsw-alias-label-primary)}.codexModelSelectStatus,.codexModelSelectEmpty{padding:10px;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:20px}.codexModelSelectError,.codexModelSelectWarning{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;margin-bottom:4px;padding:7px 8px;border-radius:8px;background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}.codexModelSelectWarning{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-state-warn-label)}.codexModelSelectRetry{flex:none;padding:0;border:0;background:transparent;color:inherit;font:inherit;font-weight:600;cursor:pointer}
|
|
292
|
+
.codexModelSelectMenu{overflow:visible}
|
|
227
293
|
.codexImageTool{display:flex;flex-direction:column;gap:8px;margin:4px 0;color:var(--dsw-alias-label-primary)}.codexImageToolRow{display:flex;align-items:center;min-height:24px;gap:8px;font-size:13px;line-height:20px}.codexImageToolIcon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;color:var(--dsw-alias-label-secondary)}.codexImageToolIcon::before{content:'';width:8px;height:8px;border:1.5px solid currentColor;border-radius:3px}.codexImageTool[data-state=running] .codexImageToolIcon::before{border-radius:50%;border-right-color:transparent;animation:codexImageSpin 800ms linear infinite}.codexImageTool[data-state=error] .codexImageToolIcon::before{border-color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-state-error-primary)}.codexImageToolTitle{font-weight:500}.codexImageToolState{color:var(--dsw-alias-label-tertiary)}.codexImageToolError{margin:0 0 0 24px;font-size:12px;line-height:18px;color:var(--dsw-alias-state-error-primary)}.codexImageToolGallery{margin-left:24px}.codexGeneratedImageFrame{display:flex;align-items:center;justify-content:center;width:min(240px,100%);min-height:120px;padding:0;overflow:hidden;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-tertiary);cursor:pointer}.codexGeneratedImageFrame img{display:block;width:100%;max-height:240px;object-fit:contain}.codexGeneratedImageRetry{min-height:36px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);cursor:pointer}.codexGeneratedImageLightbox{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:32px;border:0;background:rgba(0,0,0,.72)}.codexGeneratedImageLightbox img{display:block;max-width:min(1100px,calc(100vw - 64px));max-height:calc(100vh - 64px);object-fit:contain}.codexGeneratedImageClose{position:absolute;top:16px;right:16px;width:36px;height:36px;border:1px solid rgba(255,255,255,.35);border-radius:50%;background:rgba(0,0,0,.48);color:#fff;font-size:20px;line-height:1;cursor:pointer}@keyframes codexImageSpin{to{transform:rotate(360deg)}}
|
|
228
294
|
@container (max-width:560px){.codexSubscriptionCreditRows{grid-template-columns:1fr}}
|
|
229
295
|
@container (max-width:480px){.codexSubscriptionAccountRow,.codexSubscriptionSectionHead{align-items:flex-start;flex-direction:column}.codexSubscriptionActions{width:100%}.codexSubscriptionSearchChoices{grid-template-columns:1fr}}
|
|
@@ -622,68 +688,288 @@ window.__ModuleLoader__.load({
|
|
|
622
688
|
]
|
|
623
689
|
});
|
|
624
690
|
}
|
|
625
|
-
function
|
|
626
|
-
const [speedOpen, setSpeedOpen] = (0, react.useState)(false);
|
|
691
|
+
function CodexComposerQuota({ preference, rpc, t, directory }) {
|
|
627
692
|
const preferenceSnapshot = usePreferenceSnapshot(preference);
|
|
628
693
|
const current = (0, react.useSyncExternalStore)((listener) => directory.subscribe(listener), () => directory.getSnapshot()).current;
|
|
629
694
|
const codex = current?.provider === "openai-codex";
|
|
630
|
-
const speedSupported = codex && supportsCodexFastMode(current?.model);
|
|
631
|
-
const speedWritable = preferenceSnapshot.status === "ready" && preferenceSnapshot.writable === true;
|
|
632
|
-
const fast = preferenceSnapshot.speedMode === SPEED_MODE_FAST;
|
|
633
695
|
const quotaEnabled = preferenceSnapshot.status === "ready" && preferenceSnapshot.visible && codex;
|
|
634
696
|
const quota = useQuickQuota(rpc, quotaEnabled, current?.model);
|
|
635
|
-
if (!
|
|
636
|
-
const
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
const
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
697
|
+
if (!quotaEnabled || quota === void 0) return null;
|
|
698
|
+
const value = percent(quota.remainingPercent);
|
|
699
|
+
const label = fill(t("quickQuotaStatus"), { value });
|
|
700
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
701
|
+
className: "codexComposerQuota",
|
|
702
|
+
role: "status",
|
|
703
|
+
"aria-label": label,
|
|
704
|
+
title: label,
|
|
705
|
+
children: [value, "%"]
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
function CodexModelSelect({ locked, available, directory, load, select, preference, t }) {
|
|
709
|
+
const state = (0, react.useSyncExternalStore)(directory.subscribe, directory.getSnapshot);
|
|
710
|
+
const preferenceSnapshot = usePreferenceSnapshot(preference);
|
|
711
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
712
|
+
const [pane, setPane] = (0, react.useState)("root");
|
|
713
|
+
const rootRef = (0, react.useRef)(null);
|
|
714
|
+
const triggerRef = (0, react.useRef)(null);
|
|
715
|
+
const id = (0, react.useId)();
|
|
716
|
+
const choices = (0, react.useMemo)(() => state.groups.flatMap((group) => group.models.map((model) => ({
|
|
717
|
+
group,
|
|
718
|
+
model,
|
|
719
|
+
selection: {
|
|
720
|
+
provider: group.id,
|
|
721
|
+
model: model.id,
|
|
722
|
+
...model.reasoning?.defaultEffort === void 0 ? {} : { reasoningEffort: model.reasoning.defaultEffort }
|
|
723
|
+
}
|
|
724
|
+
}))), [state.groups]);
|
|
725
|
+
const currentChoice = choices.find((choice) => choice.selection.provider === state.current?.provider && choice.selection.model === state.current?.model);
|
|
726
|
+
const reasoning = currentChoice?.model.reasoning;
|
|
727
|
+
const effectiveEffort = state.current?.reasoningEffort ?? reasoning?.defaultEffort;
|
|
728
|
+
const effortLabel = reasoning === void 0 ? void 0 : effectiveEffort === void 0 ? t("providerDefault") : reasoning.efforts.find((level) => level.id === effectiveEffort)?.name ?? effectiveEffort;
|
|
729
|
+
const effortChoices = (0, react.useMemo)(() => reasoning === void 0 ? [] : [...reasoning.defaultEffort === void 0 ? [{
|
|
730
|
+
key: "provider-default",
|
|
731
|
+
effort: void 0,
|
|
732
|
+
label: t("providerDefault")
|
|
733
|
+
}] : [], ...reasoning.efforts.map((effort) => ({
|
|
734
|
+
key: `effort:${effort.id}`,
|
|
735
|
+
effort: effort.id,
|
|
736
|
+
label: effort.name,
|
|
737
|
+
...effort.description === void 0 ? {} : { description: effort.description }
|
|
738
|
+
}))], [reasoning, t]);
|
|
739
|
+
const modelLabel = currentChoice?.model.name ?? t("selectModel");
|
|
740
|
+
const speedSupported = state.current?.provider === "openai-codex" && supportsCodexFastMode(state.current?.model);
|
|
741
|
+
const speedWritable = preferenceSnapshot.status === "ready" && preferenceSnapshot.writable === true;
|
|
742
|
+
const fast = speedSupported && preferenceSnapshot.speedMode === "fast";
|
|
743
|
+
const busy = state.status === "selecting";
|
|
744
|
+
(0, react.useEffect)(() => {
|
|
745
|
+
if (available) load();
|
|
746
|
+
}, [available, load]);
|
|
747
|
+
(0, react.useEffect)(() => {
|
|
748
|
+
if (!open) return void 0;
|
|
749
|
+
const closeOutside = (event) => {
|
|
750
|
+
if (!rootRef.current?.contains(event.target)) {
|
|
751
|
+
setOpen(false);
|
|
752
|
+
setPane("root");
|
|
753
|
+
}
|
|
754
|
+
};
|
|
755
|
+
document.addEventListener("mousedown", closeOutside);
|
|
756
|
+
return () => document.removeEventListener("mousedown", closeOutside);
|
|
757
|
+
}, [open]);
|
|
758
|
+
(0, react.useEffect)(() => {
|
|
759
|
+
if (!speedSupported && pane === "speed") setPane("root");
|
|
760
|
+
}, [pane, speedSupported]);
|
|
761
|
+
if (!available) return null;
|
|
762
|
+
const close = (restoreFocus = false) => {
|
|
763
|
+
setOpen(false);
|
|
764
|
+
setPane("root");
|
|
765
|
+
if (restoreFocus) queueMicrotask(() => triggerRef.current?.focus());
|
|
766
|
+
};
|
|
767
|
+
const settleSelection = (accepted) => {
|
|
768
|
+
if (accepted) close(true);
|
|
769
|
+
};
|
|
770
|
+
const chooseModel = (selection) => {
|
|
771
|
+
if (state.current?.provider === selection.provider && state.current.model === selection.model) {
|
|
772
|
+
close(true);
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
select(selection).then(settleSelection);
|
|
776
|
+
};
|
|
777
|
+
const chooseEffort = (effort) => {
|
|
778
|
+
if (state.current === null) return;
|
|
779
|
+
if (effectiveEffort === effort) {
|
|
780
|
+
close(true);
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
select({
|
|
784
|
+
provider: state.current.provider,
|
|
785
|
+
model: state.current.model,
|
|
786
|
+
...effort === void 0 ? {} : { reasoningEffort: effort }
|
|
787
|
+
}).then(settleSelection);
|
|
788
|
+
};
|
|
789
|
+
const chooseSpeed = (speedMode) => {
|
|
790
|
+
close(true);
|
|
791
|
+
preference.set({ [SPEED_MODE_FIELD]: speedMode });
|
|
792
|
+
};
|
|
793
|
+
const option = ({ key, label, description, selected, disabled, onClick }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
794
|
+
type: "button",
|
|
795
|
+
role: "menuitemradio",
|
|
796
|
+
"aria-checked": selected,
|
|
797
|
+
className: "codexModelSelectOption",
|
|
798
|
+
disabled,
|
|
799
|
+
onClick,
|
|
800
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
801
|
+
className: "codexModelSelectOptionCopy",
|
|
802
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
803
|
+
className: "codexModelSelectOptionName",
|
|
804
|
+
children: label
|
|
805
|
+
}), description === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
806
|
+
className: "codexModelSelectOptionDescription",
|
|
807
|
+
children: description
|
|
808
|
+
})]
|
|
809
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
810
|
+
className: "codexModelSelectCheck",
|
|
811
|
+
children: selected ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16, {}) : null
|
|
812
|
+
})]
|
|
813
|
+
}, key);
|
|
814
|
+
const cell = (target, label, value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
815
|
+
type: "button",
|
|
816
|
+
role: "menuitem",
|
|
817
|
+
className: "codexModelSelectCell",
|
|
818
|
+
"data-open": pane === target,
|
|
819
|
+
"aria-haspopup": "menu",
|
|
820
|
+
"aria-expanded": pane === target,
|
|
821
|
+
onClick: () => setPane((current) => current === target ? "root" : target),
|
|
822
|
+
children: [
|
|
823
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
824
|
+
className: "codexModelSelectCellLabel",
|
|
825
|
+
children: label
|
|
826
|
+
}),
|
|
827
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
828
|
+
className: "codexModelSelectCellValue",
|
|
829
|
+
children: value
|
|
830
|
+
}),
|
|
831
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, { className: "codexModelSelectCellChevron" })
|
|
832
|
+
]
|
|
833
|
+
});
|
|
834
|
+
let submenu = null;
|
|
835
|
+
if (pane === "model") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
836
|
+
className: "codexModelSelectSubmenu",
|
|
837
|
+
role: "menu",
|
|
838
|
+
"aria-label": t("modelLabel"),
|
|
839
|
+
children: [
|
|
840
|
+
state.status === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
841
|
+
className: "codexModelSelectStatus",
|
|
842
|
+
children: t("modelsLoading")
|
|
843
|
+
}) : null,
|
|
844
|
+
state.error === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
845
|
+
className: "codexModelSelectError",
|
|
846
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: fill(t("modelFailed"), { value: state.error }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
847
|
+
className: "codexModelSelectRetry",
|
|
848
|
+
type: "button",
|
|
849
|
+
onClick: load,
|
|
850
|
+
children: t("modelRetry")
|
|
851
|
+
})]
|
|
852
|
+
}),
|
|
853
|
+
state.failures.map((failure) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
854
|
+
className: "codexModelSelectWarning",
|
|
855
|
+
children: fill(t("groupFailed"), {
|
|
856
|
+
name: failure.name,
|
|
857
|
+
value: failure.message
|
|
858
|
+
})
|
|
859
|
+
}, failure.id)),
|
|
860
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
861
|
+
className: "codexModelSelectGroups scrollable",
|
|
862
|
+
children: state.groups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
863
|
+
className: "codexModelSelectGroup",
|
|
864
|
+
role: "group",
|
|
865
|
+
"aria-labelledby": `${id}-${group.id}`,
|
|
866
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
867
|
+
className: "codexModelSelectGroupTitle",
|
|
868
|
+
id: `${id}-${group.id}`,
|
|
869
|
+
children: group.name
|
|
870
|
+
}), group.models.map((model) => option({
|
|
871
|
+
key: model.id,
|
|
872
|
+
label: model.name,
|
|
873
|
+
description: model.description,
|
|
874
|
+
selected: state.current?.provider === group.id && state.current.model === model.id,
|
|
875
|
+
disabled: busy,
|
|
876
|
+
onClick: () => chooseModel({
|
|
877
|
+
provider: group.id,
|
|
878
|
+
model: model.id
|
|
879
|
+
})
|
|
880
|
+
}))]
|
|
881
|
+
}, group.id))
|
|
882
|
+
}),
|
|
883
|
+
state.status === "ready" && choices.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
884
|
+
className: "codexModelSelectEmpty",
|
|
885
|
+
children: t("modelsEmpty")
|
|
886
|
+
}) : null
|
|
887
|
+
]
|
|
888
|
+
});
|
|
889
|
+
else if (pane === "effort") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
890
|
+
className: "codexModelSelectSubmenu",
|
|
891
|
+
role: "menu",
|
|
892
|
+
"aria-label": t("effortLabel"),
|
|
893
|
+
children: effortChoices.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
894
|
+
className: "codexModelSelectEmpty",
|
|
895
|
+
children: t("effortsEmpty")
|
|
896
|
+
}) : effortChoices.map((level) => option({
|
|
897
|
+
key: level.key,
|
|
898
|
+
label: level.label,
|
|
899
|
+
description: level.description,
|
|
900
|
+
selected: effectiveEffort === level.effort,
|
|
901
|
+
disabled: busy,
|
|
902
|
+
onClick: () => chooseEffort(level.effort)
|
|
903
|
+
}))
|
|
904
|
+
});
|
|
905
|
+
else if (pane === "speed") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
906
|
+
className: "codexModelSelectSubmenu",
|
|
907
|
+
role: "menu",
|
|
908
|
+
"aria-label": t("speedTitle"),
|
|
909
|
+
children: [option({
|
|
910
|
+
key: SPEED_MODE_STANDARD,
|
|
911
|
+
label: t("speedStandard"),
|
|
912
|
+
description: t("speedStandardHint"),
|
|
913
|
+
selected: !fast,
|
|
656
914
|
disabled: !speedWritable,
|
|
657
|
-
onClick: () =>
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
915
|
+
onClick: () => chooseSpeed(SPEED_MODE_STANDARD)
|
|
916
|
+
}), option({
|
|
917
|
+
key: SPEED_MODE_FAST,
|
|
918
|
+
label: t("speedFast"),
|
|
919
|
+
description: t("speedFastHint"),
|
|
920
|
+
selected: fast,
|
|
921
|
+
disabled: !speedWritable,
|
|
922
|
+
onClick: () => chooseSpeed(SPEED_MODE_FAST)
|
|
923
|
+
})]
|
|
924
|
+
});
|
|
925
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
926
|
+
className: "codexModelSelect",
|
|
927
|
+
ref: rootRef,
|
|
928
|
+
onKeyDown: (event) => {
|
|
929
|
+
if (event.key !== "Escape" || !open) return;
|
|
930
|
+
event.preventDefault();
|
|
931
|
+
if (pane === "root") close(true);
|
|
932
|
+
else setPane("root");
|
|
665
933
|
},
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
934
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
935
|
+
ref: triggerRef,
|
|
936
|
+
type: "button",
|
|
937
|
+
className: "codexModelSelectTrigger",
|
|
938
|
+
"aria-label": modelLabel,
|
|
939
|
+
"aria-haspopup": "menu",
|
|
940
|
+
"aria-expanded": open,
|
|
941
|
+
"aria-controls": open ? `${id}-menu` : void 0,
|
|
942
|
+
title: modelLabel,
|
|
943
|
+
disabled: locked,
|
|
944
|
+
onClick: () => open ? close() : (setPane("root"), setOpen(true), load()),
|
|
945
|
+
children: [
|
|
946
|
+
fast && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ForwardRef, {
|
|
947
|
+
className: "codexModelSelectBolt",
|
|
948
|
+
"aria-hidden": "true"
|
|
949
|
+
}),
|
|
950
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
951
|
+
className: "codexModelSelectLabel",
|
|
952
|
+
children: modelLabel
|
|
953
|
+
}),
|
|
954
|
+
effortLabel === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
955
|
+
className: "codexModelSelectEffort",
|
|
956
|
+
children: effortLabel
|
|
957
|
+
}),
|
|
958
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: "codexModelSelectChevron" })
|
|
959
|
+
]
|
|
960
|
+
}), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
961
|
+
className: "codexModelSelectMenu",
|
|
962
|
+
id: `${id}-menu`,
|
|
963
|
+
role: "menu",
|
|
964
|
+
"aria-label": t("modelMenuAria"),
|
|
965
|
+
"aria-busy": state.status === "loading" || busy,
|
|
966
|
+
children: [
|
|
967
|
+
cell("model", t("modelLabel"), modelLabel),
|
|
968
|
+
reasoning === void 0 ? null : cell("effort", t("effortLabel"), effortLabel),
|
|
969
|
+
speedSupported && cell("speed", t("speedTitle"), t(fast ? "speedFast" : "speedStandard")),
|
|
970
|
+
submenu
|
|
971
|
+
]
|
|
972
|
+
}) : null]
|
|
687
973
|
});
|
|
688
974
|
}
|
|
689
975
|
function AccountCard({ rpc, t, account, setAccount, onSignedOut }) {
|
|
@@ -1149,7 +1435,26 @@ window.__ModuleLoader__.load({
|
|
|
1149
1435
|
t,
|
|
1150
1436
|
directory: ctx.modelDirectories.directoryFor(sessionId).store
|
|
1151
1437
|
})
|
|
1152
|
-
},
|
|
1438
|
+
}, CodexComposerQuota));
|
|
1439
|
+
const sessions = ctx.get("sessions");
|
|
1440
|
+
ctx.slots.inject("conversation.input.model", () => ctx.slots.register({
|
|
1441
|
+
name: "conversation.input.model",
|
|
1442
|
+
priority: -10,
|
|
1443
|
+
locale: NS,
|
|
1444
|
+
inject: (sessionId) => {
|
|
1445
|
+
const directory = ctx.modelDirectories.directoryFor(sessionId);
|
|
1446
|
+
const available = sessions.subagentAddress(sessionId) === void 0;
|
|
1447
|
+
return {
|
|
1448
|
+
available,
|
|
1449
|
+
directory: directory.store,
|
|
1450
|
+
load: () => {
|
|
1451
|
+
if (available) directory.load();
|
|
1452
|
+
},
|
|
1453
|
+
select: (selection) => available ? directory.select(selection).then(() => true, () => false) : Promise.resolve(false),
|
|
1454
|
+
preference
|
|
1455
|
+
};
|
|
1456
|
+
}
|
|
1457
|
+
}, CodexModelSelect));
|
|
1153
1458
|
const conversation = ctx.get("conversation");
|
|
1154
1459
|
ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
|
|
1155
1460
|
name: "tool.call.toolview",
|
package/lib/index.js
CHANGED
|
@@ -446,12 +446,13 @@ const supportsCodexFastMode = (modelId) => typeof modelId === "string" && (/^gpt
|
|
|
446
446
|
* Preserve pi-ai's native Codex OAuth provider while allowing DSH's generic
|
|
447
447
|
* PiAiAdapter to pass the access token resolved by the host credential store.
|
|
448
448
|
*
|
|
449
|
-
* PiAiAdapter owns a request-local Models collection
|
|
450
|
-
* store. A pure OAuth provider ignores its
|
|
451
|
-
* before dispatch with "Provider
|
|
452
|
-
* bridge teaches that collection how
|
|
453
|
-
* token for this request; login, refresh,
|
|
454
|
-
* model behavior remain owned by the
|
|
449
|
+
* PiAiAdapter owns a request-local Models collection backed by the same DSH
|
|
450
|
+
* credential store as this provider. A pure OAuth provider ignores its
|
|
451
|
+
* `apiKey` request override and otherwise fails before dispatch with "Provider
|
|
452
|
+
* is not configured". This non-interactive bridge teaches that collection how
|
|
453
|
+
* to consume only the already-refreshed token for this request; login, refresh,
|
|
454
|
+
* persistence, headers, transport, and model behavior remain owned by the
|
|
455
|
+
* original provider.
|
|
455
456
|
*/
|
|
456
457
|
function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0 } = {}) {
|
|
457
458
|
const provider = createOpenAICodexProvider();
|
|
@@ -494,7 +495,7 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0 } = {
|
|
|
494
495
|
streamSimple: (model, context, options) => provider.streamSimple(model, context, withSpeed(model, options))
|
|
495
496
|
});
|
|
496
497
|
}
|
|
497
|
-
const USER_AGENT = `dsh-codex-subscription/1.1.
|
|
498
|
+
const USER_AGENT = `dsh-codex-subscription/1.1.5`;
|
|
498
499
|
//#endregion
|
|
499
500
|
//#region src/codex-search.js
|
|
500
501
|
const CODEX_SEARCH_PROVIDER_ID = "codex-subscription";
|
|
@@ -1120,6 +1121,13 @@ function apply(ctx) {
|
|
|
1120
1121
|
});
|
|
1121
1122
|
const profiles = /* @__PURE__ */ new Map([[PROVIDER, profile]]);
|
|
1122
1123
|
const resolveAuth = () => authModels.getAuth(PROVIDER);
|
|
1124
|
+
const adapterAuth = Object.freeze({
|
|
1125
|
+
credentials: store,
|
|
1126
|
+
authContext: Object.freeze({
|
|
1127
|
+
env: async () => void 0,
|
|
1128
|
+
fileExists: async () => false
|
|
1129
|
+
})
|
|
1130
|
+
});
|
|
1123
1131
|
ctx.tools.register(createCodexImageTool({
|
|
1124
1132
|
getAuth: resolveAuth,
|
|
1125
1133
|
readCredential: (options) => store.read(PROVIDER, options),
|
|
@@ -1137,6 +1145,7 @@ function apply(ctx) {
|
|
|
1137
1145
|
if (typeof resolved?.auth.apiKey !== "string" || resolved.auth.apiKey.length === 0) throw new LlmError("ChatGPT subscription is not signed in", "MISSING_CREDENTIAL");
|
|
1138
1146
|
return resolved.auth.apiKey;
|
|
1139
1147
|
},
|
|
1148
|
+
auth: adapterAuth,
|
|
1140
1149
|
resolveAttachments: () => ctx.get?.("attachments")
|
|
1141
1150
|
});
|
|
1142
1151
|
ctx.llm.registerAdapter([PROVIDER], adapter);
|
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-codex-subscription",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"packageManager": "pnpm@11.19.0",
|
|
3
|
+
"version": "1.1.5",
|
|
5
4
|
"description": "ChatGPT and Codex subscriptions for DeepSeek Harness with OAuth login, image generation, quota, and subscription web search",
|
|
6
5
|
"type": "module",
|
|
7
6
|
"main": "./lib/index.js",
|
|
@@ -17,6 +16,7 @@
|
|
|
17
16
|
"README.md",
|
|
18
17
|
"README.en.md",
|
|
19
18
|
"AGENTS.md",
|
|
19
|
+
"compatibility.json",
|
|
20
20
|
"LICENSE",
|
|
21
21
|
"SECURITY.md",
|
|
22
22
|
"THIRD_PARTY_NOTICES.md",
|
|
@@ -40,11 +40,6 @@
|
|
|
40
40
|
"platform": "web"
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
|
-
"scripts": {
|
|
44
|
-
"build": "tsdown --config tsdown.config.mjs",
|
|
45
|
-
"test": "node --test tests/*.test.mjs",
|
|
46
|
-
"check": "pnpm run test && pnpm run build && pnpm pack --pack-destination .artifacts"
|
|
47
|
-
},
|
|
48
43
|
"keywords": [
|
|
49
44
|
"dsh-plugin",
|
|
50
45
|
"deepseek",
|
|
@@ -79,47 +74,53 @@
|
|
|
79
74
|
},
|
|
80
75
|
"peerDependencies": {
|
|
81
76
|
"@deepseek-ai/cordis": "4.0.1",
|
|
82
|
-
"@deepseek-ai/dsh-api-remotes": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
83
|
-
"@deepseek-ai/dsh-client-connection": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
84
|
-
"@deepseek-ai/dsh-client-locale": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
85
|
-
"@deepseek-ai/dsh-client-runtime": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
86
|
-
"@deepseek-ai/dsh-client-ui-conversation": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
87
|
-
"@deepseek-ai/dsh-client-ui-model-selection": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
88
|
-
"@deepseek-ai/dsh-client-ui-primitives": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
89
|
-
"@deepseek-ai/dsh-client-ui-settings": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
90
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
91
|
-
"@deepseek-ai/dsh-client-ui-tool": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
92
|
-
"@deepseek-ai/dsh-credentials": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
93
|
-
"@deepseek-ai/dsh-llm": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
94
|
-
"@deepseek-ai/dsh-llm-pi-ai": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
95
|
-
"@deepseek-ai/dsh-settings": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
96
|
-
"@deepseek-ai/dsh-tools": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
97
|
-
"@deepseek-ai/dsh-web": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8",
|
|
77
|
+
"@deepseek-ai/dsh-api-remotes": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
78
|
+
"@deepseek-ai/dsh-client-connection": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
79
|
+
"@deepseek-ai/dsh-client-locale": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
80
|
+
"@deepseek-ai/dsh-client-runtime": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
81
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
82
|
+
"@deepseek-ai/dsh-client-ui-model-selection": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
83
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
84
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
85
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
86
|
+
"@deepseek-ai/dsh-client-ui-tool": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
87
|
+
"@deepseek-ai/dsh-credentials": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
88
|
+
"@deepseek-ai/dsh-llm": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
89
|
+
"@deepseek-ai/dsh-llm-pi-ai": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
90
|
+
"@deepseek-ai/dsh-settings": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
91
|
+
"@deepseek-ai/dsh-tools": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
92
|
+
"@deepseek-ai/dsh-web": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1",
|
|
98
93
|
"@deepseek-ai/schemastery": "3.18.1",
|
|
99
94
|
"@earendil-works/pi-ai": "0.82.1",
|
|
100
95
|
"react": "^18.2.0"
|
|
101
96
|
},
|
|
102
97
|
"devDependencies": {
|
|
103
98
|
"@deepseek-ai/cordis": "4.0.1",
|
|
104
|
-
"@deepseek-ai/dsh-api-remotes": "0.1.
|
|
105
|
-
"@deepseek-ai/dsh-client-connection": "0.1.
|
|
106
|
-
"@deepseek-ai/dsh-client-locale": "0.1.
|
|
107
|
-
"@deepseek-ai/dsh-client-runtime": "0.1.
|
|
108
|
-
"@deepseek-ai/dsh-client-ui-conversation": "0.1.
|
|
109
|
-
"@deepseek-ai/dsh-client-ui-model-selection": "0.1.
|
|
110
|
-
"@deepseek-ai/dsh-client-ui-primitives": "0.1.
|
|
111
|
-
"@deepseek-ai/dsh-client-ui-settings": "0.1.
|
|
112
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.
|
|
113
|
-
"@deepseek-ai/dsh-client-ui-tool": "0.1.
|
|
114
|
-
"@deepseek-ai/dsh-credentials": "0.1.
|
|
115
|
-
"@deepseek-ai/dsh-llm": "0.1.
|
|
116
|
-
"@deepseek-ai/dsh-llm-pi-ai": "0.1.
|
|
117
|
-
"@deepseek-ai/dsh-settings": "0.1.
|
|
118
|
-
"@deepseek-ai/dsh-tools": "0.1.
|
|
119
|
-
"@deepseek-ai/dsh-web": "0.1.
|
|
99
|
+
"@deepseek-ai/dsh-api-remotes": "0.1.1-rc.1",
|
|
100
|
+
"@deepseek-ai/dsh-client-connection": "0.1.1-rc.1",
|
|
101
|
+
"@deepseek-ai/dsh-client-locale": "0.1.1-rc.1",
|
|
102
|
+
"@deepseek-ai/dsh-client-runtime": "0.1.1-rc.1",
|
|
103
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.1-rc.1",
|
|
104
|
+
"@deepseek-ai/dsh-client-ui-model-selection": "0.1.1-rc.1",
|
|
105
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.1-rc.1",
|
|
106
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.1-rc.1",
|
|
107
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.1",
|
|
108
|
+
"@deepseek-ai/dsh-client-ui-tool": "0.1.1-rc.1",
|
|
109
|
+
"@deepseek-ai/dsh-credentials": "0.1.1-rc.1",
|
|
110
|
+
"@deepseek-ai/dsh-llm": "0.1.1-rc.1",
|
|
111
|
+
"@deepseek-ai/dsh-llm-pi-ai": "0.1.1-rc.1",
|
|
112
|
+
"@deepseek-ai/dsh-settings": "0.1.1-rc.1",
|
|
113
|
+
"@deepseek-ai/dsh-tools": "0.1.1-rc.1",
|
|
114
|
+
"@deepseek-ai/dsh-web": "0.1.1-rc.1",
|
|
120
115
|
"@deepseek-ai/schemastery": "3.18.1",
|
|
121
116
|
"@earendil-works/pi-ai": "0.82.1",
|
|
117
|
+
"@heroicons/react": "2.2.0",
|
|
122
118
|
"react": "18.3.1",
|
|
123
119
|
"tsdown": "0.22.2"
|
|
120
|
+
},
|
|
121
|
+
"scripts": {
|
|
122
|
+
"build": "tsdown --config tsdown.config.mjs",
|
|
123
|
+
"test": "node --test tests/*.test.mjs",
|
|
124
|
+
"check": "pnpm run test && pnpm run build && pnpm pack --pack-destination .artifacts"
|
|
124
125
|
}
|
|
125
|
-
}
|
|
126
|
+
}
|