dsh-codex-connect 0.1.0-alpha.4.18 → 0.1.0-alpha.4.19
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/INSTALL.md +2 -2
- package/README.i18n.yaml +2 -2
- package/README.md +19 -2
- package/docs/README.zh.md +19 -2
- package/lib/bin.js +1 -1
- package/lib/client.js +160 -18
- package/lib/index.d.ts +5 -1
- package/lib/index.js +1 -1
- package/lib/{src-DY3uYj_g.js → src-CiOi4nFr.js} +81 -30
- package/package.json +1 -1
package/INSTALL.md
CHANGED
|
@@ -12,7 +12,7 @@ Install `dsh-codex-connect` into one requested DeepSeek Harness profile without
|
|
|
12
12
|
|
|
13
13
|
## Install and validate
|
|
14
14
|
|
|
15
|
-
The only verified combination is DSH plugin API packages `0.1.1-rc.2`, `@earendil-works/pi-ai` `0.82.1`, and Node.js `^22.19.0 || >=24.0.0`. Alpha 4.
|
|
15
|
+
The only verified combination is DSH plugin API packages `0.1.1-rc.2`, `@earendil-works/pi-ai` `0.82.1`, and Node.js `^22.19.0 || >=24.0.0`. Alpha 4.19 uses the rc.2 keyed Plugin configuration slot; users of older DSH API packages should upgrade the DSH API packages and pi-ai together, then rerun `dsh-codex-connect doctor --json` and `pnpm --silent run check:compatibility`; the contract does not make claims about future versions.
|
|
16
16
|
|
|
17
17
|
1. Check `dsh --version` or `dsh --help`. From a Harness checkout use `pnpm dsh`.
|
|
18
18
|
2. Install the package:
|
|
@@ -21,7 +21,7 @@ The only verified combination is DSH plugin API packages `0.1.1-rc.2`, `@earendi
|
|
|
21
21
|
dsh plugin --profile web add dsh-codex-connect@alpha
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
After `0.1.0-alpha.4.
|
|
24
|
+
After `0.1.0-alpha.4.19` is published, pin it exactly with `dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.19`. If npm is unavailable after its matching GitHub prerelease is created, use `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.19'`.
|
|
25
25
|
|
|
26
26
|
3. Run `dsh --profile web --dump-config` and require exactly one `llm-openai-codex` row loading `dsh-codex-connect`.
|
|
27
27
|
4. Confirm the effective `agent-default-model` and `web.searchProvider` values are unchanged from before installation.
|
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# git hash-object README.md docs/README.zh.md
|
|
5
|
-
README.md:
|
|
6
|
-
docs/README.zh.md:
|
|
5
|
+
README.md: ecad858eb993cfc54b97eb8d8d0518feb0b23f17
|
|
6
|
+
docs/README.zh.md: 2d61465cfd3fde855d912ed39363563b46730a23
|
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ dsh plugin --profile web add dsh-codex-connect@alpha
|
|
|
28
28
|
|
|
29
29
|
Expected result: the package is added to that profile. This does not change the profile's default model or global search route.
|
|
30
30
|
|
|
31
|
-
To reproduce this release exactly, use `dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.
|
|
31
|
+
To reproduce this release exactly, use `dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.19`. If npm is unavailable after the matching GitHub prerelease exists, use `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.19'`. A local checkout can be installed as `link:/absolute/path/to/dsh-codex-connect`.
|
|
32
32
|
|
|
33
33
|
### Version updates
|
|
34
34
|
|
|
@@ -84,6 +84,21 @@ Open Harness's normal model picker and select an `openai-codex` model for the ag
|
|
|
84
84
|
|
|
85
85
|
The picker groups the available entries under **OpenAI Codex**. Model identifiers such as `GPT-5.6 Luna` are canonical names, so they intentionally remain un-translated.
|
|
86
86
|
|
|
87
|
+
To shorten that list, open **Settings → Plugins → Plugin configuration → Codex Connect**, uncheck the models you do not want to see, and select **Save changes**. This controls discovery only: a hidden model already stored in an existing conversation or supplied by its exact id remains usable. A fresh installation shows the complete catalog.
|
|
88
|
+
|
|
89
|
+
Profiles may also seed the visible subset with `models`; provider order is preserved regardless of the order written here:
|
|
90
|
+
|
|
91
|
+
```yaml
|
|
92
|
+
- id: llm-openai-codex
|
|
93
|
+
config:
|
|
94
|
+
models:
|
|
95
|
+
- gpt-5.6-luna
|
|
96
|
+
- gpt-5.6-sol
|
|
97
|
+
- gpt-5.6-terra
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Omit `models` to show the full catalog. An empty list hides every Codex model from selectors without disabling exact-id routing.
|
|
101
|
+
|
|
87
102
|
<p align="center">
|
|
88
103
|
<img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/en/model-selector.jpg" alt="OpenAI Codex model group in the English-localized DeepSeek Harness model picker" width="360">
|
|
89
104
|
</p>
|
|
@@ -194,6 +209,7 @@ Selecting Codex as the profile's global search route is another explicit change:
|
|
|
194
209
|
|
|
195
210
|
| Field | Default | Values |
|
|
196
211
|
|---|---:|---|
|
|
212
|
+
| `models` | full catalog | Codex model id array; empty hides all entries |
|
|
197
213
|
| `enableSearch` | `false` | boolean |
|
|
198
214
|
| `enableImageTool` | `false` | boolean |
|
|
199
215
|
| `enableImageGeneration` | `false` | boolean |
|
|
@@ -223,8 +239,9 @@ Selecting Codex as the profile's global search route is another explicit change:
|
|
|
223
239
|
|
|
224
240
|
## Compatibility and security boundary
|
|
225
241
|
|
|
226
|
-
- The only verified compatibility combination is DSH plugin API packages `0.1.1-rc.2`, `@earendil-works/pi-ai` `0.82.1`, and Node.js `^22.19.0 || >=24.0.0`; see [compatibility.json](compatibility.json). Alpha 4.
|
|
242
|
+
- The only verified compatibility combination is DSH plugin API packages `0.1.1-rc.2`, `@earendil-works/pi-ai` `0.82.1`, and Node.js `^22.19.0 || >=24.0.0`; see [compatibility.json](compatibility.json). Alpha 4.19 uses the rc.2 keyed Plugin configuration slot; users of older DSH API packages should upgrade to the rc.2 API packages.
|
|
227
243
|
- Upgrade the DSH plugin API packages and `@earendil-works/pi-ai` as one group, then run `dsh-codex-connect doctor --json` and the compatibility check again. This contract does not make claims about future versions.
|
|
244
|
+
- When the daily upstream check finds a new `latest` or `next` DSH candidate, it installs Codex Connect into an isolated profile, boots the installed model runtime without OAuth credentials, verifies model and reasoning-effort discovery, and confirms provider disposal. Live sign-in, quota, and model requests still require manual validation in the test profile.
|
|
228
245
|
- ChatGPT plan eligibility, model access, quotas, and backend behavior are controlled by OpenAI and may change.
|
|
229
246
|
- The Codex endpoint does not enforce the ordinary Responses `max_output_tokens` field. Harness compaction still works, but that summary cap cannot be imposed server-side on this route.
|
|
230
247
|
- Shell, filesystem, skills, MCP, subagents, approvals, permissions, attachments, session persistence, compaction, and recovery continue to come from the active Harness profile.
|
package/docs/README.zh.md
CHANGED
|
@@ -28,7 +28,7 @@ dsh plugin --profile web add dsh-codex-connect@alpha
|
|
|
28
28
|
|
|
29
29
|
预期结果:包被加入该 profile。这个动作不会更改 profile 的默认模型或全局搜索路由。
|
|
30
30
|
|
|
31
|
-
如需精确复现这个版本,使用 `dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.
|
|
31
|
+
如需精确复现这个版本,使用 `dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.19`。对应 GitHub prerelease 已创建但 npm 不可用时,可使用 `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.19'`。本地 checkout 可安装为 `link:/absolute/path/to/dsh-codex-connect`。
|
|
32
32
|
|
|
33
33
|
### 版本更新提醒
|
|
34
34
|
|
|
@@ -84,6 +84,21 @@ dsh web
|
|
|
84
84
|
|
|
85
85
|
选择器会把可用项归在 **OpenAI Codex** 下。`GPT-5.6 Luna` 一类模型标识是规范名称,因此会保留原样,不翻译。
|
|
86
86
|
|
|
87
|
+
如需缩短这个列表,打开 **设置 → 插件 → 插件配置 → Codex Connect**,取消勾选不想显示的模型,然后点击 **保存更改**。这个设置只控制模型发现:已有会话中保存的隐藏模型,或通过精确模型 ID 指定的隐藏模型,仍可继续使用。全新安装默认显示完整目录。
|
|
88
|
+
|
|
89
|
+
也可以在 profile 中通过 `models` 设置初始显示子集;无论这里如何排列,选择器仍保持提供方的原始顺序:
|
|
90
|
+
|
|
91
|
+
```yaml
|
|
92
|
+
- id: llm-openai-codex
|
|
93
|
+
config:
|
|
94
|
+
models:
|
|
95
|
+
- gpt-5.6-luna
|
|
96
|
+
- gpt-5.6-sol
|
|
97
|
+
- gpt-5.6-terra
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
省略 `models` 时显示完整目录;空列表会在选择器中隐藏全部 Codex 模型,但不会禁用精确模型 ID 路由。
|
|
101
|
+
|
|
87
102
|
<p align="center">
|
|
88
103
|
<img src="https://raw.githubusercontent.com/franksong2702/dsh-codex-connect/main/docs/assets/zh/model-selector.jpg" alt="中文 DeepSeek Harness 模型选择器中的 OpenAI Codex 模型分组" width="360">
|
|
89
104
|
</p>
|
|
@@ -194,6 +209,7 @@ dsh plugin --profile web exec dsh-codex-connect doctor --json
|
|
|
194
209
|
|
|
195
210
|
| 字段 | 默认值 | 可选值 |
|
|
196
211
|
|---|---:|---|
|
|
212
|
+
| `models` | 完整目录 | Codex model id 数组;空数组隐藏全部条目 |
|
|
197
213
|
| `enableSearch` | `false` | boolean |
|
|
198
214
|
| `enableImageTool` | `false` | boolean |
|
|
199
215
|
| `enableImageGeneration` | `false` | boolean |
|
|
@@ -223,8 +239,9 @@ dsh plugin --profile web exec dsh-codex-connect doctor --json
|
|
|
223
239
|
|
|
224
240
|
## 兼容性与安全边界
|
|
225
241
|
|
|
226
|
-
- 当前唯一已验证的兼容组合是 DSH 插件 API packages `0.1.1-rc.2`、`@earendil-works/pi-ai` `0.82.1` 和 Node.js `^22.19.0 || >=24.0.0`;详见 [compatibility.json](../compatibility.json)。Alpha 4.
|
|
242
|
+
- 当前唯一已验证的兼容组合是 DSH 插件 API packages `0.1.1-rc.2`、`@earendil-works/pi-ai` `0.82.1` 和 Node.js `^22.19.0 || >=24.0.0`;详见 [compatibility.json](../compatibility.json)。Alpha 4.19 使用 rc.2 的 keyed 插件配置 slot;旧版 DSH API packages 用户应升级到 rc.2 API packages。
|
|
227
243
|
- 升级时请将 DSH 插件 API packages 与 `@earendil-works/pi-ai` 作为一组升级,再运行 `dsh-codex-connect doctor --json` 和兼容性检查。本契约不对未来版本作判断。
|
|
244
|
+
- 每日上游检查发现新的 DSH `latest` 或 `next` 候选版本时,会把 Codex Connect 安装到隔离 Profile 中,在没有 OAuth 凭据的情况下启动已安装的模型运行时,验证模型与推理强度发现,并确认提供方可被正确卸载。真实登录、额度和模型请求仍需在测试 Profile 中人工验证。
|
|
228
245
|
- ChatGPT 套餐资格、模型权限、额度和后端行为由 OpenAI 控制,可能变化。
|
|
229
246
|
- Codex 端点不会强制普通 Responses 的 `max_output_tokens` 字段。Harness 压缩仍可工作,但这个摘要上限不能由服务端在该路由上强制。
|
|
230
247
|
- shell、文件系统、skills、MCP、subagents、审批、权限、附件、会话持久化、压缩与恢复继续由当前 Harness profile 提供。
|
package/lib/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { L as diagnoseOpenAICodex, c as migrateOpenAICodexSearchHistory, ct as normalizeTrustedOrigin, ft as loginOpenAICodex, mt as openAICodexAuthStatus, pt as logoutOpenAICodex, st as OpenAICodexTrustedOriginsStore, vt as openAICodexAuthPath, z as CODEX_CONNECT_VERSION } from "./src-
|
|
2
|
+
import { L as diagnoseOpenAICodex, c as migrateOpenAICodexSearchHistory, ct as normalizeTrustedOrigin, ft as loginOpenAICodex, mt as openAICodexAuthStatus, pt as logoutOpenAICodex, st as OpenAICodexTrustedOriginsStore, vt as openAICodexAuthPath, z as CODEX_CONNECT_VERSION } from "./src-CiOi4nFr.js";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { realpathSync } from "node:fs";
|
|
5
5
|
import { spawn } from "node:child_process";
|
package/lib/client.js
CHANGED
|
@@ -12,6 +12,7 @@ window.__ModuleLoader__.load({
|
|
|
12
12
|
/** Stable Harness settings namespace owned by this plugin. */
|
|
13
13
|
const OPENAI_CODEX_SETTINGS_NAMESPACE = "llm-openai-codex";
|
|
14
14
|
Object.freeze({
|
|
15
|
+
models: void 0,
|
|
15
16
|
enableSearch: false,
|
|
16
17
|
enableImageTool: false,
|
|
17
18
|
enableImageGeneration: false,
|
|
@@ -26,6 +27,7 @@ window.__ModuleLoader__.load({
|
|
|
26
27
|
/** Narrow the redacted settings wire payload before it enters React state. */
|
|
27
28
|
function decodeOpenAICodexSettings(value) {
|
|
28
29
|
if (!isRecord$2(value)) return void 0;
|
|
30
|
+
const models = value["models"];
|
|
29
31
|
const enableSearch = value["enableSearch"];
|
|
30
32
|
const enableImageTool = value["enableImageTool"];
|
|
31
33
|
const enableImageGeneration = value["enableImageGeneration"];
|
|
@@ -33,6 +35,7 @@ window.__ModuleLoader__.load({
|
|
|
33
35
|
const searchMode = value["searchMode"];
|
|
34
36
|
const searchContextSize = value["searchContextSize"];
|
|
35
37
|
const searchMaxOutputTokens = value["searchMaxOutputTokens"];
|
|
38
|
+
if (models !== void 0 && (!Array.isArray(models) || models.some((model) => typeof model !== "string"))) return void 0;
|
|
36
39
|
if (typeof enableSearch !== "boolean" || typeof enableImageTool !== "boolean") return void 0;
|
|
37
40
|
if (enableImageGeneration !== void 0 && typeof enableImageGeneration !== "boolean") return void 0;
|
|
38
41
|
if (typeof searchModel !== "string" || searchModel.trim().length === 0) return void 0;
|
|
@@ -40,6 +43,7 @@ window.__ModuleLoader__.load({
|
|
|
40
43
|
if (searchContextSize !== "low" && searchContextSize !== "medium" && searchContextSize !== "high") return void 0;
|
|
41
44
|
if (typeof searchMaxOutputTokens !== "number" || !Number.isInteger(searchMaxOutputTokens) || searchMaxOutputTokens < 1) return void 0;
|
|
42
45
|
return {
|
|
46
|
+
models: models === void 0 ? void 0 : [...new Set(models)],
|
|
43
47
|
enableSearch,
|
|
44
48
|
enableImageTool,
|
|
45
49
|
enableImageGeneration: enableImageGeneration ?? false,
|
|
@@ -59,6 +63,30 @@ window.__ModuleLoader__.load({
|
|
|
59
63
|
/** Plugin-owned logout endpoint consumed by its browser half. */
|
|
60
64
|
const OPENAI_CODEX_AUTH_LOGOUT_PATH = "/plugins/dsh-openai-codex/auth/logout";
|
|
61
65
|
//#endregion
|
|
66
|
+
//#region src/model-contract.ts
|
|
67
|
+
/** Node-free model catalog contract shared by the Host route and browser card. */
|
|
68
|
+
/** Same-origin endpoint exposing the complete Codex model catalog. */
|
|
69
|
+
const OPENAI_CODEX_MODEL_CATALOG_PATH = "/plugins/dsh-codex-connect/models";
|
|
70
|
+
/** Validate the model catalog before it enters React state. */
|
|
71
|
+
function decodeOpenAICodexModelCatalog(value) {
|
|
72
|
+
if (!Array.isArray(value)) return void 0;
|
|
73
|
+
const catalog = [];
|
|
74
|
+
const ids = /* @__PURE__ */ new Set();
|
|
75
|
+
for (const entry of value) {
|
|
76
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) return void 0;
|
|
77
|
+
const record = entry;
|
|
78
|
+
const id = record["id"];
|
|
79
|
+
const name = record["name"];
|
|
80
|
+
if (typeof id !== "string" || id.length === 0 || typeof name !== "string" || name.length === 0 || ids.has(id)) return void 0;
|
|
81
|
+
ids.add(id);
|
|
82
|
+
catalog.push({
|
|
83
|
+
id,
|
|
84
|
+
name
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return catalog;
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
62
90
|
//#region src/client/OpenAICodexConfiguration.tsx
|
|
63
91
|
/** Staged optional-capability editor inside the OpenAI Codex plugin card. */
|
|
64
92
|
const sectionStyle$1 = {
|
|
@@ -89,6 +117,25 @@ window.__ModuleLoader__.load({
|
|
|
89
117
|
padding: 0,
|
|
90
118
|
border: 0
|
|
91
119
|
};
|
|
120
|
+
const modelListStyle = {
|
|
121
|
+
display: "grid",
|
|
122
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(210px, 1fr))",
|
|
123
|
+
gap: 10
|
|
124
|
+
};
|
|
125
|
+
const modelRowStyle = {
|
|
126
|
+
display: "flex",
|
|
127
|
+
alignItems: "center",
|
|
128
|
+
gap: 9,
|
|
129
|
+
minHeight: 30,
|
|
130
|
+
fontSize: 13,
|
|
131
|
+
color: "var(--dsw-alias-label-primary)",
|
|
132
|
+
cursor: "pointer"
|
|
133
|
+
};
|
|
134
|
+
const modelIdStyle = {
|
|
135
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
136
|
+
fontSize: 12,
|
|
137
|
+
color: "var(--dsw-alias-label-secondary)"
|
|
138
|
+
};
|
|
92
139
|
const toggleRowStyle = {
|
|
93
140
|
display: "flex",
|
|
94
141
|
alignItems: "flex-start",
|
|
@@ -175,6 +222,7 @@ window.__ModuleLoader__.load({
|
|
|
175
222
|
mode: "memory"
|
|
176
223
|
};
|
|
177
224
|
const CONFIG_FIELDS = [
|
|
225
|
+
"models",
|
|
178
226
|
"enableSearch",
|
|
179
227
|
"enableImageTool",
|
|
180
228
|
"enableImageGeneration",
|
|
@@ -183,8 +231,13 @@ window.__ModuleLoader__.load({
|
|
|
183
231
|
"searchContextSize",
|
|
184
232
|
"searchMaxOutputTokens"
|
|
185
233
|
];
|
|
234
|
+
function sameField(field, left, right) {
|
|
235
|
+
if (field !== "models") return left === right;
|
|
236
|
+
if (left === void 0 || right === void 0) return left === right;
|
|
237
|
+
return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((model, index) => model === right[index]);
|
|
238
|
+
}
|
|
186
239
|
function sameConfig(left, right) {
|
|
187
|
-
return left !== void 0 && right !== void 0 && CONFIG_FIELDS.every((field) => left[field]
|
|
240
|
+
return left !== void 0 && right !== void 0 && CONFIG_FIELDS.every((field) => sameField(field, left[field], right[field]));
|
|
188
241
|
}
|
|
189
242
|
/** Edit the Host-owned llm-openai-codex settings section with Save/Discard staging. */
|
|
190
243
|
function OpenAICodexConfiguration({ scope, t }) {
|
|
@@ -195,6 +248,29 @@ window.__ModuleLoader__.load({
|
|
|
195
248
|
const [dirty, setDirty] = (0, react.useState)(false);
|
|
196
249
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
197
250
|
const [feedback, setFeedback] = (0, react.useState)("idle");
|
|
251
|
+
const [modelCatalog, setModelCatalog] = (0, react.useState)();
|
|
252
|
+
const [modelCatalogError, setModelCatalogError] = (0, react.useState)(false);
|
|
253
|
+
(0, react.useEffect)(() => {
|
|
254
|
+
if (scope === void 0) return;
|
|
255
|
+
const controller = new AbortController();
|
|
256
|
+
fetch(OPENAI_CODEX_MODEL_CATALOG_PATH, {
|
|
257
|
+
method: "GET",
|
|
258
|
+
credentials: "same-origin",
|
|
259
|
+
headers: { accept: "application/json" },
|
|
260
|
+
signal: controller.signal
|
|
261
|
+
}).then(async (response) => {
|
|
262
|
+
if (!response.ok) throw new Error(`model catalog request failed: ${String(response.status)}`);
|
|
263
|
+
const catalog = decodeOpenAICodexModelCatalog(await response.json());
|
|
264
|
+
if (catalog === void 0) throw new Error("model catalog response was invalid");
|
|
265
|
+
setModelCatalog(catalog);
|
|
266
|
+
setModelCatalogError(false);
|
|
267
|
+
}).catch(() => {
|
|
268
|
+
if (!controller.signal.aborted) setModelCatalogError(true);
|
|
269
|
+
});
|
|
270
|
+
return () => {
|
|
271
|
+
controller.abort();
|
|
272
|
+
};
|
|
273
|
+
}, [scope]);
|
|
198
274
|
(0, react.useEffect)(() => {
|
|
199
275
|
if (!dirty && !busy) setDraft(snapshot.value);
|
|
200
276
|
}, [
|
|
@@ -229,9 +305,11 @@ window.__ModuleLoader__.load({
|
|
|
229
305
|
setFeedback("idle");
|
|
230
306
|
try {
|
|
231
307
|
for (const field of CONFIG_FIELDS) {
|
|
232
|
-
|
|
308
|
+
const accepted = scope.getSnapshot().value;
|
|
309
|
+
if (accepted !== void 0 && sameField(field, accepted[field], desired[field])) continue;
|
|
233
310
|
await scope.set(field, desired[field]);
|
|
234
|
-
|
|
311
|
+
const committed = scope.getSnapshot().value;
|
|
312
|
+
if (committed === void 0 || !sameField(field, committed[field], desired[field])) throw new Error(`Host refused ${field}`);
|
|
235
313
|
}
|
|
236
314
|
const accepted = scope.getSnapshot().value;
|
|
237
315
|
if (!sameConfig(accepted, desired)) throw new Error("Host returned a different configuration");
|
|
@@ -251,19 +329,8 @@ window.__ModuleLoader__.load({
|
|
|
251
329
|
const searchDisabled = !editable || draft?.enableSearch !== true;
|
|
252
330
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
253
331
|
style: sectionStyle$1,
|
|
254
|
-
"aria-
|
|
332
|
+
"aria-label": t("configurationHeading"),
|
|
255
333
|
children: [
|
|
256
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
257
|
-
id: "openai-codex-capabilities-title",
|
|
258
|
-
style: headingStyle,
|
|
259
|
-
children: t("capabilitiesHeading")
|
|
260
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
261
|
-
style: {
|
|
262
|
-
...bodyStyle$2,
|
|
263
|
-
marginTop: 4
|
|
264
|
-
},
|
|
265
|
-
children: t("capabilitiesIntro")
|
|
266
|
-
})] }),
|
|
267
334
|
loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
268
335
|
style: bodyStyle$2,
|
|
269
336
|
role: "status",
|
|
@@ -283,6 +350,67 @@ window.__ModuleLoader__.load({
|
|
|
283
350
|
style: fieldsetStyle,
|
|
284
351
|
disabled: !editable,
|
|
285
352
|
children: [
|
|
353
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
354
|
+
style: headingStyle,
|
|
355
|
+
children: t("modelCatalog")
|
|
356
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
357
|
+
style: {
|
|
358
|
+
...bodyStyle$2,
|
|
359
|
+
marginTop: 4
|
|
360
|
+
},
|
|
361
|
+
children: t("modelCatalogIntro")
|
|
362
|
+
})] }),
|
|
363
|
+
modelCatalog === void 0 && !modelCatalogError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
364
|
+
style: bodyStyle$2,
|
|
365
|
+
role: "status",
|
|
366
|
+
children: t("modelCatalogLoading")
|
|
367
|
+
}) : null,
|
|
368
|
+
modelCatalogError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
369
|
+
style: errorStyle$2,
|
|
370
|
+
role: "alert",
|
|
371
|
+
children: t("modelCatalogFailed")
|
|
372
|
+
}) : null,
|
|
373
|
+
modelCatalog === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
374
|
+
style: modelListStyle,
|
|
375
|
+
role: "group",
|
|
376
|
+
"aria-label": t("modelCatalog"),
|
|
377
|
+
children: modelCatalog.map((model) => {
|
|
378
|
+
const selected = draft.models === void 0 || draft.models.includes(model.id);
|
|
379
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
380
|
+
style: modelRowStyle,
|
|
381
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
382
|
+
type: "checkbox",
|
|
383
|
+
checked: selected,
|
|
384
|
+
onChange: (event) => {
|
|
385
|
+
const visible = new Set(draft.models ?? modelCatalog.map((entry) => entry.id));
|
|
386
|
+
if (event.currentTarget.checked) visible.add(model.id);
|
|
387
|
+
else visible.delete(model.id);
|
|
388
|
+
update("models", modelCatalog.filter((entry) => visible.has(entry.id)).map((entry) => entry.id));
|
|
389
|
+
}
|
|
390
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model.name }), model.name === model.id ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
391
|
+
style: modelIdStyle,
|
|
392
|
+
children: [
|
|
393
|
+
" (",
|
|
394
|
+
model.id,
|
|
395
|
+
")"
|
|
396
|
+
]
|
|
397
|
+
})] })]
|
|
398
|
+
}, model.id);
|
|
399
|
+
})
|
|
400
|
+
}),
|
|
401
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
402
|
+
style: { paddingTop: 4 },
|
|
403
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
404
|
+
style: headingStyle,
|
|
405
|
+
children: t("capabilitiesHeading")
|
|
406
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
407
|
+
style: {
|
|
408
|
+
...bodyStyle$2,
|
|
409
|
+
marginTop: 4
|
|
410
|
+
},
|
|
411
|
+
children: t("capabilitiesIntro")
|
|
412
|
+
})]
|
|
413
|
+
}),
|
|
286
414
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
287
415
|
style: toggleRowStyle,
|
|
288
416
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -492,7 +620,8 @@ window.__ModuleLoader__.load({
|
|
|
492
620
|
"dsh-rc7",
|
|
493
621
|
"search-stability",
|
|
494
622
|
"image-generation",
|
|
495
|
-
"oauth-history"
|
|
623
|
+
"oauth-history",
|
|
624
|
+
"model-visibility"
|
|
496
625
|
];
|
|
497
626
|
function isHighlightKind(value) {
|
|
498
627
|
return typeof value === "string" && HIGHLIGHT_KINDS.includes(value);
|
|
@@ -995,7 +1124,8 @@ window.__ModuleLoader__.load({
|
|
|
995
1124
|
"dsh-rc7": "updateHighlightDshRc7",
|
|
996
1125
|
"search-stability": "updateHighlightSearchStability",
|
|
997
1126
|
"image-generation": "updateHighlightImageGeneration",
|
|
998
|
-
"oauth-history": "updateHighlightOauthHistory"
|
|
1127
|
+
"oauth-history": "updateHighlightOauthHistory",
|
|
1128
|
+
"model-visibility": "updateHighlightModelVisibility"
|
|
999
1129
|
};
|
|
1000
1130
|
const compatibilityTitleKeys = {
|
|
1001
1131
|
compatible: "compatibilityCompatibleTitle",
|
|
@@ -2430,6 +2560,11 @@ window.__ModuleLoader__.load({
|
|
|
2430
2560
|
remoteOriginCopy: "Copy trust command",
|
|
2431
2561
|
remoteOriginCopied: "Copied",
|
|
2432
2562
|
remoteOriginCopyFailed: "Copy was unavailable. Copy the command manually.",
|
|
2563
|
+
configurationHeading: "Codex Connect configuration",
|
|
2564
|
+
modelCatalog: "Models shown in the selector",
|
|
2565
|
+
modelCatalogIntro: "Choose which Codex models appear in model selectors. Existing conversations can continue using a hidden model.",
|
|
2566
|
+
modelCatalogLoading: "Loading available models…",
|
|
2567
|
+
modelCatalogFailed: "Available models could not be loaded.",
|
|
2433
2568
|
capabilitiesHeading: "Optional capabilities",
|
|
2434
2569
|
capabilitiesIntro: "Choose which extra Codex capabilities this dsh profile may register.",
|
|
2435
2570
|
enableSearch: "Enable Codex search provider",
|
|
@@ -2539,6 +2674,7 @@ window.__ModuleLoader__.load({
|
|
|
2539
2674
|
updateHighlightSearchStability: "Improved search-session stability so new search records remain readable after restarts.",
|
|
2540
2675
|
updateHighlightImageGeneration: "Added optional GPT Image generation in the Codex Connect settings and a preview card in the conversation.",
|
|
2541
2676
|
updateHighlightOauthHistory: "Added safer session-history migration and a sign-in fallback when the account needs to reconnect.",
|
|
2677
|
+
updateHighlightModelVisibility: "You can now choose which Codex models appear in model selectors.",
|
|
2542
2678
|
viewTechnicalDetails: "View technical details",
|
|
2543
2679
|
hideTechnicalDetails: "Hide technical details",
|
|
2544
2680
|
technicalDetailsHeading: "Technical changes",
|
|
@@ -2608,6 +2744,11 @@ window.__ModuleLoader__.load({
|
|
|
2608
2744
|
remoteOriginCopy: "复制授权命令",
|
|
2609
2745
|
remoteOriginCopied: "已复制",
|
|
2610
2746
|
remoteOriginCopyFailed: "当前无法访问剪贴板,请手动复制命令。",
|
|
2747
|
+
configurationHeading: "Codex Connect 配置",
|
|
2748
|
+
modelCatalog: "模型选择器中显示的模型",
|
|
2749
|
+
modelCatalogIntro: "选择要在模型选择器中显示的 Codex 模型;隐藏模型后,已有会话仍可继续使用。",
|
|
2750
|
+
modelCatalogLoading: "正在加载可用模型…",
|
|
2751
|
+
modelCatalogFailed: "无法加载可用模型。",
|
|
2611
2752
|
capabilitiesHeading: "可选能力",
|
|
2612
2753
|
capabilitiesIntro: "选择允许此 dsh profile 注册哪些额外的 Codex 能力。",
|
|
2613
2754
|
enableSearch: "启用 Codex 搜索提供方",
|
|
@@ -2717,6 +2858,7 @@ window.__ModuleLoader__.load({
|
|
|
2717
2858
|
updateHighlightSearchStability: "改进搜索会话稳定性,重启后新写入的搜索记录仍能正常读取。",
|
|
2718
2859
|
updateHighlightImageGeneration: "在 Codex Connect 设置中加入可选的 GPT Image 生图,并在对话里展示生成结果卡片。",
|
|
2719
2860
|
updateHighlightOauthHistory: "增加更安全的会话历史迁移,并在账号需要重新登录时提供备用登录路径。",
|
|
2861
|
+
updateHighlightModelVisibility: "现在可以选择哪些 Codex 模型显示在模型选择菜单中。",
|
|
2720
2862
|
viewTechnicalDetails: "查看完整技术说明",
|
|
2721
2863
|
hideTechnicalDetails: "收起技术说明",
|
|
2722
2864
|
technicalDetailsHeading: "技术变更",
|
|
@@ -3805,7 +3947,7 @@ window.__ModuleLoader__.load({
|
|
|
3805
3947
|
}
|
|
3806
3948
|
//#endregion
|
|
3807
3949
|
//#region src/version.ts
|
|
3808
|
-
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.
|
|
3950
|
+
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.19";
|
|
3809
3951
|
//#endregion
|
|
3810
3952
|
//#region src/client/index.tsx
|
|
3811
3953
|
/** Stable browser-plugin name. */
|
package/lib/index.d.ts
CHANGED
|
@@ -311,6 +311,8 @@ declare const DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE: OpenAICodexSearchContext
|
|
|
311
311
|
declare const DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS = 10000;
|
|
312
312
|
/** Fully resolved user-editable section presented by Plugin configuration. */
|
|
313
313
|
interface OpenAICodexSettingsConfig {
|
|
314
|
+
/** Model ids advertised in selectors; undefined advertises the full catalog. */
|
|
315
|
+
models: string[] | undefined;
|
|
314
316
|
enableSearch: boolean;
|
|
315
317
|
enableImageTool: boolean;
|
|
316
318
|
enableImageGeneration: boolean;
|
|
@@ -476,7 +478,7 @@ declare const OPENAI_CODEX_FAST_MODE_PATH = "/plugins/dsh-openai-codex/fast-mode
|
|
|
476
478
|
declare const OPENAI_CODEX_UPDATE_PATH = "/openai-codex/update";
|
|
477
479
|
//#endregion
|
|
478
480
|
//#region src/update.d.ts
|
|
479
|
-
type OpenAICodexUpdateHighlightKind = 'trusted-origins' | 'runtime-compatibility' | 'quota-fast-mode' | 'dsh-rc7' | 'search-stability' | 'image-generation' | 'oauth-history';
|
|
481
|
+
type OpenAICodexUpdateHighlightKind = 'trusted-origins' | 'runtime-compatibility' | 'quota-fast-mode' | 'dsh-rc7' | 'search-stability' | 'image-generation' | 'oauth-history' | 'model-visibility';
|
|
480
482
|
interface OpenAICodexUpdateHighlight {
|
|
481
483
|
version: string;
|
|
482
484
|
kind: OpenAICodexUpdateHighlightKind;
|
|
@@ -583,6 +585,8 @@ declare const inject: string[];
|
|
|
583
585
|
declare const OPENAI_CODEX_SETTINGS_NS: import("@deepseek-ai/dsh-settings").SettingsNamespace;
|
|
584
586
|
/** Composite model and standalone-search configuration. */
|
|
585
587
|
interface Config {
|
|
588
|
+
/** Model ids advertised in selectors; omitted to advertise the full catalog. */
|
|
589
|
+
models?: string[] | undefined;
|
|
586
590
|
/** Register the optional standalone Codex search provider. */
|
|
587
591
|
enableSearch?: boolean;
|
|
588
592
|
/** Register the optional image-loading tool. */
|
package/lib/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as assessCompatibility, A as OPENAI_CODEX_TRANSPORT_SERVICE, B as OPENAI_CODEX_UPDATE_PATH, C as OPENAI_CODEX_IMAGE_MAX_COUNT, D as OPENAI_CODEX_IMAGE_REQUEST_TIMEOUT_MS, E as OPENAI_CODEX_IMAGE_PROMPT_MAX_LENGTH, F as IMAGE_GENERATE_TOOL_NAME, G as COMPATIBILITY_CONTRACT, H as compareOpenAICodexVersions, I as assertNoOpenAICodexProviderConflict, J as DSH_PLUGIN_API_PACKAGES, K as COMPATIBILITY_PACKAGES, L as diagnoseOpenAICodex, M as OpenAICodexTransportError, N as isOpenAICodexTransportError, O as OPENAI_CODEX_TRANSPORT_API_VERSION, P as VIEW_IMAGE_TOOL_NAME, Q as SUPPORTED_PI_AI_VERSION, R as openAICodexConflictMessage, S as OPENAI_CODEX_IMAGE_GENERATION_URL, T as OPENAI_CODEX_IMAGE_MAX_RESPONSE_BYTES, U as parseOpenAICodexUpdateResult, V as checkForOpenAICodexUpdate, W as parseOpenAICodexVersion, X as SUPPORTED_DSH_PLUGIN_API_VERSION, Y as PI_AI_PACKAGE, Z as SUPPORTED_NODE_RANGE, _ as DEFAULT_OPENAI_CODEX_SEARCH_MODEL, _t as OpenAICodexCredentialStore, a as name, at as OPENAI_CODEX_FAST_MODE_MAX_SESSION_ID_LENGTH, b as decodeOpenAICodexSettings, c as migrateOpenAICodexSearchHistory, d as OPENAI_CODEX_SEARCH_URL, dt as readOpenAICodexRateLimits, et as detectCompatibility, f as OpenAICodexSearchProvider, ft as loginOpenAICodex, g as DEFAULT_OPENAI_CODEX_SEARCH_MODE, gt as OPENAI_CODEX_PROVIDER, h as DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS, ht as OPENAI_CODEX_AUTH_FILENAME, i as inject, it as OPENAI_CODEX_FAST_MODE_MAX_SESSIONS, j as OpenAICodexTransport, k as OPENAI_CODEX_TRANSPORT_ERROR_CODES, l as OPENAI_CODEX_BASE_URL, lt as OPENAI_CODEX_USAGE_URL, m as DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE, mt as openAICodexAuthStatus, n as OPENAI_CODEX_SETTINGS_NS, nt as OPENAI_CODEX_FAST_MODE_PATH, o as OPENAI_CODEX_HISTORY_BACKUP_SUFFIX, ot as isFastModeSessionId, p as mapOpenAICodexSearchResponse, pt as logoutOpenAICodex, q as COMPATIBILITY_SCHEMA_VERSION, r as apply, rt as FastModeRegistry, s as OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT, t as Config, tt as evaluateCompatibility, u as OPENAI_CODEX_SEARCH_PROVIDER, ut as parseOpenAICodexUsage, v as DEFAULT_OPENAI_CODEX_SETTINGS, vt as openAICodexAuthPath, w as OPENAI_CODEX_IMAGE_MAX_ERROR_BYTES, x as resolveOpenAICodexSettings, y as OPENAI_CODEX_SETTINGS_NAMESPACE } from "./src-
|
|
1
|
+
import { $ as assessCompatibility, A as OPENAI_CODEX_TRANSPORT_SERVICE, B as OPENAI_CODEX_UPDATE_PATH, C as OPENAI_CODEX_IMAGE_MAX_COUNT, D as OPENAI_CODEX_IMAGE_REQUEST_TIMEOUT_MS, E as OPENAI_CODEX_IMAGE_PROMPT_MAX_LENGTH, F as IMAGE_GENERATE_TOOL_NAME, G as COMPATIBILITY_CONTRACT, H as compareOpenAICodexVersions, I as assertNoOpenAICodexProviderConflict, J as DSH_PLUGIN_API_PACKAGES, K as COMPATIBILITY_PACKAGES, L as diagnoseOpenAICodex, M as OpenAICodexTransportError, N as isOpenAICodexTransportError, O as OPENAI_CODEX_TRANSPORT_API_VERSION, P as VIEW_IMAGE_TOOL_NAME, Q as SUPPORTED_PI_AI_VERSION, R as openAICodexConflictMessage, S as OPENAI_CODEX_IMAGE_GENERATION_URL, T as OPENAI_CODEX_IMAGE_MAX_RESPONSE_BYTES, U as parseOpenAICodexUpdateResult, V as checkForOpenAICodexUpdate, W as parseOpenAICodexVersion, X as SUPPORTED_DSH_PLUGIN_API_VERSION, Y as PI_AI_PACKAGE, Z as SUPPORTED_NODE_RANGE, _ as DEFAULT_OPENAI_CODEX_SEARCH_MODEL, _t as OpenAICodexCredentialStore, a as name, at as OPENAI_CODEX_FAST_MODE_MAX_SESSION_ID_LENGTH, b as decodeOpenAICodexSettings, c as migrateOpenAICodexSearchHistory, d as OPENAI_CODEX_SEARCH_URL, dt as readOpenAICodexRateLimits, et as detectCompatibility, f as OpenAICodexSearchProvider, ft as loginOpenAICodex, g as DEFAULT_OPENAI_CODEX_SEARCH_MODE, gt as OPENAI_CODEX_PROVIDER, h as DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS, ht as OPENAI_CODEX_AUTH_FILENAME, i as inject, it as OPENAI_CODEX_FAST_MODE_MAX_SESSIONS, j as OpenAICodexTransport, k as OPENAI_CODEX_TRANSPORT_ERROR_CODES, l as OPENAI_CODEX_BASE_URL, lt as OPENAI_CODEX_USAGE_URL, m as DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE, mt as openAICodexAuthStatus, n as OPENAI_CODEX_SETTINGS_NS, nt as OPENAI_CODEX_FAST_MODE_PATH, o as OPENAI_CODEX_HISTORY_BACKUP_SUFFIX, ot as isFastModeSessionId, p as mapOpenAICodexSearchResponse, pt as logoutOpenAICodex, q as COMPATIBILITY_SCHEMA_VERSION, r as apply, rt as FastModeRegistry, s as OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT, t as Config, tt as evaluateCompatibility, u as OPENAI_CODEX_SEARCH_PROVIDER, ut as parseOpenAICodexUsage, v as DEFAULT_OPENAI_CODEX_SETTINGS, vt as openAICodexAuthPath, w as OPENAI_CODEX_IMAGE_MAX_ERROR_BYTES, x as resolveOpenAICodexSettings, y as OPENAI_CODEX_SETTINGS_NAMESPACE } from "./src-CiOi4nFr.js";
|
|
2
2
|
export { COMPATIBILITY_CONTRACT, COMPATIBILITY_PACKAGES, COMPATIBILITY_SCHEMA_VERSION, Config, DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE, DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS, DEFAULT_OPENAI_CODEX_SEARCH_MODE, DEFAULT_OPENAI_CODEX_SEARCH_MODEL, DEFAULT_OPENAI_CODEX_SETTINGS, DSH_PLUGIN_API_PACKAGES, FastModeRegistry, FastModeRegistry as OpenAICodexFastModeRegistry, IMAGE_GENERATE_TOOL_NAME, OPENAI_CODEX_AUTH_FILENAME, OPENAI_CODEX_BASE_URL, OPENAI_CODEX_FAST_MODE_MAX_SESSIONS, OPENAI_CODEX_FAST_MODE_MAX_SESSION_ID_LENGTH, OPENAI_CODEX_FAST_MODE_PATH, OPENAI_CODEX_HISTORY_BACKUP_SUFFIX, OPENAI_CODEX_IMAGE_GENERATION_URL, OPENAI_CODEX_IMAGE_MAX_COUNT, OPENAI_CODEX_IMAGE_MAX_ERROR_BYTES, OPENAI_CODEX_IMAGE_MAX_RESPONSE_BYTES, OPENAI_CODEX_IMAGE_PROMPT_MAX_LENGTH, OPENAI_CODEX_IMAGE_REQUEST_TIMEOUT_MS, OPENAI_CODEX_PROVIDER, OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT, OPENAI_CODEX_SEARCH_PROVIDER, OPENAI_CODEX_SEARCH_URL, OPENAI_CODEX_SETTINGS_NAMESPACE, OPENAI_CODEX_SETTINGS_NS, OPENAI_CODEX_TRANSPORT_API_VERSION, OPENAI_CODEX_TRANSPORT_ERROR_CODES, OPENAI_CODEX_TRANSPORT_SERVICE, OPENAI_CODEX_UPDATE_PATH, OPENAI_CODEX_USAGE_URL, OpenAICodexCredentialStore, OpenAICodexSearchProvider, OpenAICodexTransport, OpenAICodexTransportError, PI_AI_PACKAGE, SUPPORTED_DSH_PLUGIN_API_VERSION, SUPPORTED_NODE_RANGE, SUPPORTED_PI_AI_VERSION, VIEW_IMAGE_TOOL_NAME, apply, assertNoOpenAICodexProviderConflict, assessCompatibility, checkForOpenAICodexUpdate, compareOpenAICodexVersions, decodeOpenAICodexSettings, detectCompatibility, diagnoseOpenAICodex, evaluateCompatibility, inject, isFastModeSessionId, isOpenAICodexTransportError, loginOpenAICodex, logoutOpenAICodex, mapOpenAICodexSearchResponse, migrateOpenAICodexSearchHistory, name, openAICodexAuthPath, openAICodexAuthStatus, openAICodexConflictMessage, parseOpenAICodexUpdateResult, parseOpenAICodexUsage, parseOpenAICodexVersion, readOpenAICodexRateLimits, resolveOpenAICodexSettings };
|
|
@@ -164,6 +164,13 @@ var OpenAICodexCredentialStore = class {
|
|
|
164
164
|
//#endregion
|
|
165
165
|
//#region src/adapter.ts
|
|
166
166
|
/** OpenAI Codex adapter assembled from public dsh-llm-pi-ai extension points. */
|
|
167
|
+
/** Return a detached copy of the complete pi-ai Codex model catalog. */
|
|
168
|
+
function openAICodexModelCatalog() {
|
|
169
|
+
return openaiCodexProvider().getModels().map((model) => ({
|
|
170
|
+
id: model.id,
|
|
171
|
+
name: model.name
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
167
174
|
/** Provider idle ceiling used by the composite route. */
|
|
168
175
|
const OPENAI_CODEX_STREAM_IDLE_TIMEOUT_MS = 3e5;
|
|
169
176
|
/** rc.2 default maximum base64 image payload retained in one request. */
|
|
@@ -243,12 +250,21 @@ function createOpenAICodexProfile(provider, fastMode) {
|
|
|
243
250
|
* resolution, streaming, reasoning metadata, and compaction behavior; this
|
|
244
251
|
* plugin supplies its provider-native OAuth token for each request.
|
|
245
252
|
*/
|
|
246
|
-
function createOpenAICodexAdapter(credentials, resolveAttachments, fastMode) {
|
|
253
|
+
function createOpenAICodexAdapter(credentials, resolveAttachments, fastMode, visibleModelIds) {
|
|
247
254
|
const provider = openaiCodexProvider();
|
|
248
255
|
const profiles = /* @__PURE__ */ new Map([[OPENAI_CODEX_PROVIDER, createOpenAICodexProfile(provider, fastMode)]]);
|
|
249
256
|
const models = createModels({ credentials });
|
|
250
257
|
models.setProvider(provider);
|
|
251
|
-
|
|
258
|
+
class OpenAICodexAdapter extends PiAiAdapter {
|
|
259
|
+
async listModels(providerId) {
|
|
260
|
+
const catalog = await super.listModels(providerId);
|
|
261
|
+
const configured = visibleModelIds?.();
|
|
262
|
+
if (configured === void 0) return catalog;
|
|
263
|
+
const visible = new Set(configured);
|
|
264
|
+
return catalog.filter((model) => visible.has(model.id));
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return new OpenAICodexAdapter({
|
|
252
268
|
profiles: () => profiles,
|
|
253
269
|
resolveApiKey: async () => (await models.getAuth(OPENAI_CODEX_PROVIDER))?.auth.apiKey,
|
|
254
270
|
auth: {
|
|
@@ -928,7 +944,7 @@ async function trustedRequestDecision(req, trustedOrigins = new OpenAICodexTrust
|
|
|
928
944
|
error: REMOTE_WEB_ORIGIN_NOT_TRUSTED
|
|
929
945
|
};
|
|
930
946
|
}
|
|
931
|
-
function json$
|
|
947
|
+
function json$2(res, status, value) {
|
|
932
948
|
res.writeHead(status, {
|
|
933
949
|
"content-type": "application/json; charset=utf-8",
|
|
934
950
|
"cache-control": "no-store",
|
|
@@ -1018,7 +1034,7 @@ function registerOpenAICodexAuthRoutes(ctx, store, trustedOriginsOverride, fastM
|
|
|
1018
1034
|
const authorize = async (req, res) => {
|
|
1019
1035
|
const decision = await trustedRequestDecision(req, trustedOrigins);
|
|
1020
1036
|
if (decision.trusted) return true;
|
|
1021
|
-
json$
|
|
1037
|
+
json$2(res, 403, { error: decision.error });
|
|
1022
1038
|
return false;
|
|
1023
1039
|
};
|
|
1024
1040
|
const routes = [
|
|
@@ -1026,21 +1042,21 @@ function registerOpenAICodexAuthRoutes(ctx, store, trustedOriginsOverride, fastM
|
|
|
1026
1042
|
kind: "exact",
|
|
1027
1043
|
path: OPENAI_CODEX_AUTH_STATUS_PATH,
|
|
1028
1044
|
handler: async (req, res) => {
|
|
1029
|
-
if (req.method !== "GET") return json$
|
|
1045
|
+
if (req.method !== "GET") return json$2(res, 405, { error: "method not allowed" });
|
|
1030
1046
|
if (!await authorize(req, res)) return;
|
|
1031
|
-
json$
|
|
1047
|
+
json$2(res, 200, await auth.status());
|
|
1032
1048
|
}
|
|
1033
1049
|
}),
|
|
1034
1050
|
ctx.webServer.register({
|
|
1035
1051
|
kind: "exact",
|
|
1036
1052
|
path: OPENAI_CODEX_AUTH_LOGIN_PATH,
|
|
1037
1053
|
handler: async (req, res) => {
|
|
1038
|
-
if (req.method !== "POST") return json$
|
|
1054
|
+
if (req.method !== "POST") return json$2(res, 405, { error: "method not allowed" });
|
|
1039
1055
|
if (!await authorize(req, res)) return;
|
|
1040
1056
|
try {
|
|
1041
|
-
json$
|
|
1057
|
+
json$2(res, 200, await auth.signIn());
|
|
1042
1058
|
} catch (error) {
|
|
1043
|
-
json$
|
|
1059
|
+
json$2(res, 500, { error: safeMessage(error) });
|
|
1044
1060
|
}
|
|
1045
1061
|
}
|
|
1046
1062
|
}),
|
|
@@ -1048,13 +1064,13 @@ function registerOpenAICodexAuthRoutes(ctx, store, trustedOriginsOverride, fastM
|
|
|
1048
1064
|
kind: "exact",
|
|
1049
1065
|
path: OPENAI_CODEX_AUTH_LOGOUT_PATH,
|
|
1050
1066
|
handler: async (req, res) => {
|
|
1051
|
-
if (req.method !== "POST") return json$
|
|
1067
|
+
if (req.method !== "POST") return json$2(res, 405, { error: "method not allowed" });
|
|
1052
1068
|
if (!await authorize(req, res)) return;
|
|
1053
1069
|
try {
|
|
1054
1070
|
await auth.signOut();
|
|
1055
|
-
json$
|
|
1071
|
+
json$2(res, 200, { ok: true });
|
|
1056
1072
|
} catch (error) {
|
|
1057
|
-
json$
|
|
1073
|
+
json$2(res, 500, { error: safeMessage(error) });
|
|
1058
1074
|
}
|
|
1059
1075
|
}
|
|
1060
1076
|
}),
|
|
@@ -1062,22 +1078,22 @@ function registerOpenAICodexAuthRoutes(ctx, store, trustedOriginsOverride, fastM
|
|
|
1062
1078
|
kind: "exact",
|
|
1063
1079
|
path: OPENAI_CODEX_FAST_MODE_PATH,
|
|
1064
1080
|
handler: async (req, res) => {
|
|
1065
|
-
if (req.method !== "GET" && req.method !== "POST") return json$
|
|
1081
|
+
if (req.method !== "GET" && req.method !== "POST") return json$2(res, 405, { error: "method not allowed" });
|
|
1066
1082
|
if (!await authorize(req, res)) return;
|
|
1067
1083
|
if (req.method === "GET") {
|
|
1068
1084
|
const sessionId = fastModeSessionIdFromQuery(req);
|
|
1069
|
-
if (sessionId === void 0) return json$
|
|
1070
|
-
return json$
|
|
1085
|
+
if (sessionId === void 0) return json$2(res, 400, { error: "invalid input" });
|
|
1086
|
+
return json$2(res, 200, { enabled: fastMode.isEnabled(sessionId) });
|
|
1071
1087
|
}
|
|
1072
1088
|
const type = header(req, "content-type");
|
|
1073
|
-
if (type === void 0 || !/^application\/json(?:\s*;|$)/iu.test(type.trim())) return json$
|
|
1089
|
+
if (type === void 0 || !/^application\/json(?:\s*;|$)/iu.test(type.trim())) return json$2(res, 415, { error: "unsupported content type" });
|
|
1074
1090
|
try {
|
|
1075
1091
|
const body = fastModeBody(await readFastModeBody(req));
|
|
1076
|
-
if (body === void 0) return json$
|
|
1092
|
+
if (body === void 0) return json$2(res, 400, { error: "invalid input" });
|
|
1077
1093
|
fastMode.set(body.sessionId, body.enabled);
|
|
1078
|
-
return json$
|
|
1094
|
+
return json$2(res, 200, { enabled: fastMode.isEnabled(body.sessionId) });
|
|
1079
1095
|
} catch (error) {
|
|
1080
|
-
return json$
|
|
1096
|
+
return json$2(res, error instanceof RangeError ? 413 : 400, { error: error instanceof RangeError ? "request body too large" : "invalid input" });
|
|
1081
1097
|
}
|
|
1082
1098
|
}
|
|
1083
1099
|
})
|
|
@@ -1242,7 +1258,8 @@ const HIGHLIGHT_KINDS = [
|
|
|
1242
1258
|
"dsh-rc7",
|
|
1243
1259
|
"search-stability",
|
|
1244
1260
|
"image-generation",
|
|
1245
|
-
"oauth-history"
|
|
1261
|
+
"oauth-history",
|
|
1262
|
+
"model-visibility"
|
|
1246
1263
|
];
|
|
1247
1264
|
function isHighlightKind(value) {
|
|
1248
1265
|
return typeof value === "string" && HIGHLIGHT_KINDS.includes(value);
|
|
@@ -1671,7 +1688,7 @@ async function detectCurrentDshVersion() {
|
|
|
1671
1688
|
const adapter = report.packages["@deepseek-ai/dsh-llm-pi-ai"].installed;
|
|
1672
1689
|
return llm !== null && llm === adapter ? llm : void 0;
|
|
1673
1690
|
}
|
|
1674
|
-
function json(res, status, value) {
|
|
1691
|
+
function json$1(res, status, value) {
|
|
1675
1692
|
res.writeHead(status, {
|
|
1676
1693
|
"content-type": "application/json; charset=utf-8",
|
|
1677
1694
|
"cache-control": "no-store",
|
|
@@ -1686,14 +1703,14 @@ function registerOpenAICodexUpdateRoutes(ctx, options, trustedOrigins) {
|
|
|
1686
1703
|
kind: "exact",
|
|
1687
1704
|
path: OPENAI_CODEX_RUNTIME_PATH,
|
|
1688
1705
|
handler: async (req, res) => {
|
|
1689
|
-
if (req.method !== "GET") return json(res, 405, { error: "method not allowed" });
|
|
1706
|
+
if (req.method !== "GET") return json$1(res, 405, { error: "method not allowed" });
|
|
1690
1707
|
const decision = await trustedRequestDecision(req, trustedOrigins);
|
|
1691
|
-
if (!decision.trusted) return json(res, 403, { error: decision.error });
|
|
1708
|
+
if (!decision.trusted) return json$1(res, 403, { error: decision.error });
|
|
1692
1709
|
try {
|
|
1693
1710
|
const currentDshVersion = await (options.resolveCurrentDshVersion ?? detectCurrentDshVersion)();
|
|
1694
|
-
return json(res, 200, currentDshVersion === void 0 ? {} : { currentDshVersion });
|
|
1711
|
+
return json$1(res, 200, currentDshVersion === void 0 ? {} : { currentDshVersion });
|
|
1695
1712
|
} catch {
|
|
1696
|
-
return json(res, 200, {});
|
|
1713
|
+
return json$1(res, 200, {});
|
|
1697
1714
|
}
|
|
1698
1715
|
}
|
|
1699
1716
|
});
|
|
@@ -1701,9 +1718,9 @@ function registerOpenAICodexUpdateRoutes(ctx, options, trustedOrigins) {
|
|
|
1701
1718
|
kind: "exact",
|
|
1702
1719
|
path: OPENAI_CODEX_UPDATE_PATH,
|
|
1703
1720
|
handler: async (req, res) => {
|
|
1704
|
-
if (req.method !== "GET") return json(res, 405, { error: "method not allowed" });
|
|
1721
|
+
if (req.method !== "GET") return json$1(res, 405, { error: "method not allowed" });
|
|
1705
1722
|
const decision = await trustedRequestDecision(req, trustedOrigins);
|
|
1706
|
-
if (!decision.trusted) return json(res, 403, { error: decision.error });
|
|
1723
|
+
if (!decision.trusted) return json$1(res, 403, { error: decision.error });
|
|
1707
1724
|
let result;
|
|
1708
1725
|
let currentDshVersion;
|
|
1709
1726
|
try {
|
|
@@ -1726,7 +1743,7 @@ function registerOpenAICodexUpdateRoutes(ctx, options, trustedOrigins) {
|
|
|
1726
1743
|
reason: "registry-unavailable"
|
|
1727
1744
|
};
|
|
1728
1745
|
}
|
|
1729
|
-
return json(res, 200, result);
|
|
1746
|
+
return json$1(res, 200, result);
|
|
1730
1747
|
}
|
|
1731
1748
|
});
|
|
1732
1749
|
return () => {
|
|
@@ -1736,8 +1753,36 @@ function registerOpenAICodexUpdateRoutes(ctx, options, trustedOrigins) {
|
|
|
1736
1753
|
}, "dsh-codex-connect: update route");
|
|
1737
1754
|
}
|
|
1738
1755
|
//#endregion
|
|
1756
|
+
//#region src/model-contract.ts
|
|
1757
|
+
/** Node-free model catalog contract shared by the Host route and browser card. */
|
|
1758
|
+
/** Same-origin endpoint exposing the complete Codex model catalog. */
|
|
1759
|
+
const OPENAI_CODEX_MODEL_CATALOG_PATH = "/plugins/dsh-codex-connect/models";
|
|
1760
|
+
//#endregion
|
|
1761
|
+
//#region src/model-routes.ts
|
|
1762
|
+
function json(res, status, value) {
|
|
1763
|
+
res.writeHead(status, {
|
|
1764
|
+
"content-type": "application/json; charset=utf-8",
|
|
1765
|
+
"cache-control": "no-store",
|
|
1766
|
+
"x-content-type-options": "nosniff"
|
|
1767
|
+
});
|
|
1768
|
+
res.end(JSON.stringify(value));
|
|
1769
|
+
}
|
|
1770
|
+
/** Register the read-only catalog route consumed by Plugin configuration. */
|
|
1771
|
+
function registerOpenAICodexModelCatalogRoute(ctx, resolveCatalog, trustedOrigins) {
|
|
1772
|
+
ctx.effect(() => ctx.webServer.register({
|
|
1773
|
+
kind: "exact",
|
|
1774
|
+
path: OPENAI_CODEX_MODEL_CATALOG_PATH,
|
|
1775
|
+
handler: async (req, res) => {
|
|
1776
|
+
if (req.method !== "GET") return json(res, 405, { error: "method not allowed" });
|
|
1777
|
+
const decision = await trustedRequestDecision(req, trustedOrigins);
|
|
1778
|
+
if (!decision.trusted) return json(res, 403, { error: decision.error });
|
|
1779
|
+
return json(res, 200, resolveCatalog());
|
|
1780
|
+
}
|
|
1781
|
+
}), "dsh-codex-connect: model catalog route");
|
|
1782
|
+
}
|
|
1783
|
+
//#endregion
|
|
1739
1784
|
//#region src/version.ts
|
|
1740
|
-
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.
|
|
1785
|
+
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.19";
|
|
1741
1786
|
//#endregion
|
|
1742
1787
|
//#region src/doctor.ts
|
|
1743
1788
|
/** Secret-free diagnostics and duplicate-provider guidance. */
|
|
@@ -2739,6 +2784,7 @@ const DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE = "medium";
|
|
|
2739
2784
|
/** Default output budget for the standalone search response. */
|
|
2740
2785
|
const DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS = 1e4;
|
|
2741
2786
|
const DEFAULT_OPENAI_CODEX_SETTINGS = Object.freeze({
|
|
2787
|
+
models: void 0,
|
|
2742
2788
|
enableSearch: false,
|
|
2743
2789
|
enableImageTool: false,
|
|
2744
2790
|
enableImageGeneration: false,
|
|
@@ -2760,6 +2806,7 @@ function isRecord$1(value) {
|
|
|
2760
2806
|
/** Narrow the redacted settings wire payload before it enters React state. */
|
|
2761
2807
|
function decodeOpenAICodexSettings(value) {
|
|
2762
2808
|
if (!isRecord$1(value)) return void 0;
|
|
2809
|
+
const models = value["models"];
|
|
2763
2810
|
const enableSearch = value["enableSearch"];
|
|
2764
2811
|
const enableImageTool = value["enableImageTool"];
|
|
2765
2812
|
const enableImageGeneration = value["enableImageGeneration"];
|
|
@@ -2767,6 +2814,7 @@ function decodeOpenAICodexSettings(value) {
|
|
|
2767
2814
|
const searchMode = value["searchMode"];
|
|
2768
2815
|
const searchContextSize = value["searchContextSize"];
|
|
2769
2816
|
const searchMaxOutputTokens = value["searchMaxOutputTokens"];
|
|
2817
|
+
if (models !== void 0 && (!Array.isArray(models) || models.some((model) => typeof model !== "string"))) return void 0;
|
|
2770
2818
|
if (typeof enableSearch !== "boolean" || typeof enableImageTool !== "boolean") return void 0;
|
|
2771
2819
|
if (enableImageGeneration !== void 0 && typeof enableImageGeneration !== "boolean") return void 0;
|
|
2772
2820
|
if (typeof searchModel !== "string" || searchModel.trim().length === 0) return void 0;
|
|
@@ -2774,6 +2822,7 @@ function decodeOpenAICodexSettings(value) {
|
|
|
2774
2822
|
if (searchContextSize !== "low" && searchContextSize !== "medium" && searchContextSize !== "high") return void 0;
|
|
2775
2823
|
if (typeof searchMaxOutputTokens !== "number" || !Number.isInteger(searchMaxOutputTokens) || searchMaxOutputTokens < 1) return void 0;
|
|
2776
2824
|
return {
|
|
2825
|
+
models: models === void 0 ? void 0 : [...new Set(models)],
|
|
2777
2826
|
enableSearch,
|
|
2778
2827
|
enableImageTool,
|
|
2779
2828
|
enableImageGeneration: enableImageGeneration ?? false,
|
|
@@ -3269,6 +3318,7 @@ const inject = ["llm"];
|
|
|
3269
3318
|
/** Branded Host settings namespace for Codex Connect capability configuration. */
|
|
3270
3319
|
const OPENAI_CODEX_SETTINGS_NS = settingsNamespace(OPENAI_CODEX_SETTINGS_NAMESPACE);
|
|
3271
3320
|
const Config = z.object({
|
|
3321
|
+
models: z.union([z.const(void 0), z.array(z.string())]),
|
|
3272
3322
|
enableSearch: z.boolean().default(false),
|
|
3273
3323
|
enableImageTool: z.boolean().default(false),
|
|
3274
3324
|
enableImageGeneration: z.boolean().default(false),
|
|
@@ -3299,10 +3349,11 @@ function apply(ctx, config) {
|
|
|
3299
3349
|
const fastMode = new FastModeRegistry();
|
|
3300
3350
|
assertNoOpenAICodexProviderConflict(ctx.llm.listProviders().map((provider) => provider.id));
|
|
3301
3351
|
new OpenAICodexTransport(ctx, credentials);
|
|
3302
|
-
ctx.llm.registerAdapter([OPENAI_CODEX_PROVIDER], createOpenAICodexAdapter(credentials, () => ctx.get("attachments"), fastMode));
|
|
3352
|
+
ctx.llm.registerAdapter([OPENAI_CODEX_PROVIDER], createOpenAICodexAdapter(credentials, () => ctx.get("attachments"), fastMode, () => resolveOpenAICodexSettings(current()).models));
|
|
3303
3353
|
ctx.inject(["webServer"], (webCtx) => {
|
|
3304
3354
|
registerOpenAICodexAuthRoutes(webCtx, credentials, trustedOrigins, fastMode);
|
|
3305
3355
|
registerOpenAICodexUpdateRoutes(webCtx, { currentVersion: CODEX_CONNECT_VERSION }, trustedOrigins);
|
|
3356
|
+
registerOpenAICodexModelCatalogRoute(webCtx, openAICodexModelCatalog, trustedOrigins);
|
|
3306
3357
|
});
|
|
3307
3358
|
let stopped = false;
|
|
3308
3359
|
let searchFiber;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dsh-codex-connect",
|
|
3
3
|
"displayName": "Codex Connect",
|
|
4
4
|
"description": "ChatGPT OAuth and Codex models for DeepSeek Harness.",
|
|
5
|
-
"version": "0.1.0-alpha.4.
|
|
5
|
+
"version": "0.1.0-alpha.4.19",
|
|
6
6
|
"author": "Frank Song",
|
|
7
7
|
"contributors": [
|
|
8
8
|
"Yan-Zero (original dsh-codex author)"
|