dsh-codex-connect 0.1.0-alpha.4.33 → 0.1.0-alpha.4.35

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Installation Runbook for CLI Agents
2
2
 
3
- Alpha 4.32 is verified with DSH `0.1.2-rc.1` and its declared pi-ai range `^0.84.2`.
3
+ Published Alpha 4.34 is verified with DSH `0.1.2-rc.1` and pi-ai `0.84.4` within `^0.84.2`, and with each exact DSH `0.1.5-alpha.1`, `0.1.5-rc.1`, and `0.1.5-rc.2` model-runtime pairing using pi-ai `0.85.1`.
4
4
 
5
5
  Install `dsh-codex-connect` into one requested DeepSeek Harness profile without changing its current default model, search route, global configuration, or OAuth state.
6
6
 
@@ -16,21 +16,26 @@ Install `dsh-codex-connect` into one requested DeepSeek Harness profile without
16
16
 
17
17
  ### Select an exact version before installation
18
18
 
19
- Check `dsh --version` before changing the requested profile. Use `dsh --help` to locate the CLI if needed; from a Harness checkout use `pnpm dsh --version`. Select an exact pair from [verified-compatibility.json](verified-compatibility.json):
19
+ Check `dsh --version` before changing the requested profile. Use `dsh --help` to locate the CLI if needed; from a Harness checkout use `pnpm dsh --version`. The CLI string alone does not identify every installed model-runtime package: a CLI reporting `0.1.5-rc.1` can resolve `0.1.5-rc.2` packages. When the plugin is already installed, also run `dsh plugin --profile web exec dsh-codex-connect doctor --json` and inspect the installed `@deepseek-ai/dsh-llm`, `@deepseek-ai/dsh-llm-pi-ai`, and pi-ai versions. Substitute the requested profile. Select an exact pair from [verified-compatibility.json](verified-compatibility.json):
20
20
 
21
21
  | Installed DSH version | Codex Connect version to pin |
22
22
  | --- | --- |
23
23
  | `0.1.0-rc.7` | `0.1.0-alpha.4.14` |
24
24
  | `0.1.1-rc.2` | `0.1.0-alpha.4.21` |
25
25
  | `0.1.2-alpha.2` | `0.1.0-alpha.4.23` |
26
- | `0.1.2-rc.1` | `0.1.0-alpha.4.32` |
26
+ | `0.1.2-rc.1` | `0.1.0-alpha.4.34` |
27
27
  | `0.1.2-alpha.5` | `0.1.0-alpha.4.25` |
28
+ | `0.1.5-alpha.1` | `0.1.0-alpha.4.34` |
29
+ | `0.1.5-rc.1` | `0.1.0-alpha.4.34` |
30
+ | `0.1.5-rc.2` | `0.1.0-alpha.4.34` |
28
31
 
29
32
  If your exact DSH version is unknown or not listed, preserve the installed host, report that the combination is unverified, and verify it before making installation changes. A missing record does not prove incompatibility, and the catalog's latest verified DSH version is not the latest upstream release. Do not recommend upgrading or downgrading DSH merely to match a row. Investigate any specific failure and seek verification of the installed combination. Do not blindly install `dsh-codex-connect@alpha`: `alpha` is a moving tag, not a compatibility guarantee. Do not infer support for newer DSH versions from these rows.
30
33
 
31
- Alpha 4.32's verified contract is DSH plugin API packages `0.1.2-rc.1`, `@earendil-works/pi-ai` `^0.84.2`, and Node.js `^22.19.0 || >=24.0.0`. Alpha 4.25 remains the verified choice for DSH `0.1.2-alpha.5`, Alpha 4.23 remains the verified choice for DSH `0.1.2-alpha.2`, Alpha 4.21 remains the verified choice for DSH `0.1.1-rc.2`, and staying on DSH `0.1.0-rc.7` means selecting Alpha 4.14. Changing DSH is a separate operation requiring the user's explicit request; a plugin update request does not authorize it. The repository's `pnpm --silent run check:compatibility` remains a strict development/release dependency gate, not a recommendation to change a user's host.
34
+ Alpha 4.34 requires one consistent DSH plugin API version: `0.1.2-rc.1` with `@earendil-works/pi-ai` `^0.84.2`, or one of `0.1.5-alpha.1`, `0.1.5-rc.1`, and `0.1.5-rc.2` with pi-ai `0.85.1`; Node.js remains `^22.19.0 || >=24.0.0`. Mixed host versions and other DSH/pi-ai combinations remain unverified. Alpha 4.25 remains the verified choice for DSH `0.1.2-alpha.5`, Alpha 4.23 remains the verified choice for DSH `0.1.2-alpha.2`, Alpha 4.21 remains the verified choice for DSH `0.1.1-rc.2`, and staying on DSH `0.1.0-rc.7` means selecting Alpha 4.14. Changing DSH is a separate operation requiring the user's explicit request; a plugin update request does not authorize it. The repository's `pnpm --silent run check:compatibility` remains a strict development/release dependency gate, not a recommendation to change a user's host.
32
35
 
33
- The Alpha 4.32 row reflects a fresh isolated installation and runtime probe. Historical rows remain the repository's existing verification record. This guidance does not change upstream DSH behavior or resolve [Issue #64](https://github.com/franksong2702/dsh-codex-connect/issues/64).
36
+ The Alpha 4.34 rows reflect same-artifact isolated installation and model-runtime checks on both configured Node versions, browser regression, Windows canary contracts, and independent verification of the published npm artifact. All eight advertised models resolved and prepared, defaults were unchanged, and provider disposal succeeded. These are not fresh real OAuth, live model/tool/image, or full Windows application acceptance. See [.github/ALPHA_434_RELEASE_READINESS.md](https://github.com/franksong2702/dsh-codex-connect/blob/main/.github/ALPHA_434_RELEASE_READINESS.md) for release recovery, upgrade evidence, and verification limits. Historical rows remain the repository's existing verification record. This guidance does not change upstream DSH behavior or resolve [Issue #64](https://github.com/franksong2702/dsh-codex-connect/issues/64).
37
+
38
+ Alpha 4.33 omits the `modelErrors` profile field required by RC model packages, producing `Cannot read properties of undefined (reading 'get')`. Alpha 4.34 contains the fix. Reauthorization or repeated model-list retries do not add a missing profile field. Pin the corrected plugin version for a verified host combination; do not delete credentials or change DSH merely to work around this failure. DSH `0.1.5-alpha.2` remains unverified.
34
39
 
35
40
  ### Install the selected version and validate
36
41
 
@@ -53,10 +58,10 @@ The Alpha 4.32 row reflects a fresh isolated installation and runtime probe. His
53
58
  dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.23
54
59
  ```
55
60
 
56
- For DSH `0.1.2-rc.1`, use Alpha 4.32:
61
+ For DSH `0.1.2-rc.1`, `0.1.5-alpha.1`, `0.1.5-rc.1`, or `0.1.5-rc.2`, use Alpha 4.34:
57
62
 
58
63
  ```sh
59
- dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.32
64
+ dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.34
60
65
  ```
61
66
 
62
67
  For DSH `0.1.2-alpha.5`, use Alpha 4.25:
@@ -65,7 +70,7 @@ The Alpha 4.32 row reflects a fresh isolated installation and runtime probe. His
65
70
  dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.25
66
71
  ```
67
72
 
68
- If npm is unavailable after the matching GitHub prerelease is created, use `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.21'` only for the DSH `0.1.1-rc.2` combination, `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.23'` only for the DSH `0.1.2-alpha.2` combination, `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.25'` only for the DSH `0.1.2-alpha.5` combination, or `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.32'` only for the DSH `0.1.2-rc.1` combination.
73
+ If npm is unavailable after the matching GitHub prerelease is created, use `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.21'` only for the DSH `0.1.1-rc.2` combination, `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.23'` only for the DSH `0.1.2-alpha.2` combination, `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.25'` only for the DSH `0.1.2-alpha.5` combination, or `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.34'` only for the DSH `0.1.2-rc.1`, `0.1.5-alpha.1`, `0.1.5-rc.1`, or `0.1.5-rc.2` combinations.
69
74
 
70
75
  3. Run `dsh web --help` once to compose the installed profile without starting the server. DSH `0.1.2-rc.1` prepares profile plugin dependency fallback during this step.
71
76
  4. Run `dsh --profile web --dump-config` and require exactly one `llm-openai-codex` row loading `dsh-codex-connect`.
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: 9649515aed66c70b4f61b24a6f7ec5f4e53860ae
6
- docs/README.zh.md: 412bb75fd63144cd7fa9137e8efcd588ea9efe1b
5
+ README.md: 9016a882858e604aba551f61baadfe352e69e8e2
6
+ docs/README.zh.md: 8d7d386608a125e6c381df3b7138fe787eba01f5
package/README.md CHANGED
@@ -12,19 +12,19 @@ Codex Connect adds the `openai-codex` model provider to the normal Harness agent
12
12
 
13
13
  ## Quick start
14
14
 
15
- This guide describes the published pairing below. Check `dsh --version` first; for another DSH version, use [Installation and upgrades](INSTALL.md). A moving npm tag such as `alpha` is not a compatibility guarantee.
15
+ This guide describes the published pairings below. Check `dsh --version` first and use `doctor --json` to inspect the installed model-runtime packages: an rc.1 CLI can resolve rc.2 packages. For other versions, use [Installation and upgrades](INSTALL.md). A moving npm tag such as `alpha` is not a compatibility guarantee.
16
16
 
17
17
  | Requirement | Verified pairing |
18
18
  |---|---|
19
- | Codex Connect | `0.1.0-alpha.4.32` |
20
- | DeepSeek Harness | `0.1.2-rc.1` |
19
+ | Codex Connect | `0.1.0-alpha.4.34` |
20
+ | DeepSeek Harness | `0.1.2-rc.1`, `0.1.5-alpha.1`, `0.1.5-rc.1`, or `0.1.5-rc.2` |
21
21
  | Node.js | `^22.19.0 \|\| >=24.0.0` |
22
22
  | Account | ChatGPT OAuth with access to the requested Codex model; availability is decided by OpenAI |
23
23
 
24
24
  ### 1. Install
25
25
 
26
26
  ```sh
27
- dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.32
27
+ dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.34
28
28
  dsh web
29
29
  ```
30
30
 
@@ -69,10 +69,15 @@ All options below are off on a fresh installation. Edit them in **Settings → P
69
69
  |---|---|---|
70
70
  | Proxy | `enableProxy` | Credential-free HTTP(S), scoped to this plugin's traffic. A failed proxy request does not silently retry directly. |
71
71
  | Codex Search | `enableSearch` | Selects Codex for the entire profile's search route; disabling restores the previously active route. |
72
+ | Luna Reserve | `enableReserveFallback` | Uses the hidden Reserve route only when the backend explicitly authorizes it for the captured account; never changes global defaults or retries a generic `429`. |
72
73
  | Image viewing | `enableImageTool` | Adds `view_image` to vision-capable models for local files and validated public HTTP(S) images. |
73
74
  | GPT Image generation | `enableImageGeneration` | Prompt-only generation; availability, dimensions, and quota remain account- and service-controlled. |
74
75
  | Auto-review | `enableAutoReview` | Sends bounded approval context, tool arguments, working directory, and the planned action to `chatgpt.com`, with confirmation on first enablement. Failures return to human approval. |
75
76
 
77
+ **Unreleased experiment:** Luna Reserve fallback is not included in published Alpha 4.34. It remains disabled by default in this development build; real-account Reserve entry and recovery have not been verified.
78
+
79
+ With `enableReserveFallback: true`, the account UI and agent routing share one identity-bound quota state. Background refresh follows the returned quota windows; fresh state is reused across agent steps. The plugin enters `gpt-reserve` only with complete, non-FedRAMP account/user identity and backend Luna Reserve authorization, then restores the session's previous model and reasoning effort after confirmed ordinary-usage recovery. Reserve has its own allowance, is hidden from the model picker, and is not unlimited. The backend decides eligibility; reset times alone do not authorize a switch. This version supports known `gpt-5.6-luna` metadata only. See [Luna Reserve fallback](docs/reference.md#luna-reserve-fallback) for refresh, identity, and verification limits.
80
+
76
81
  Use the image generation capability included with your current GPT subscription. Generated originals are stored separately from attachment previews; disabling the capability or uninstalling the plugin does not delete them. See [Configuration and recovery](docs/reference.md#search-and-image-tools) for storage and access rules.
77
82
 
78
83
  Auto-review operates after Harness policy requires approval; it does not bypass that policy. See [Auto-review behavior](docs/auto-review.md) before enabling it.
@@ -5,7 +5,7 @@
5
5
  },
6
6
  "dshPluginApi": {
7
7
  "version": "0.1.2-rc.1",
8
- "versions": ["0.1.2-rc.1", "0.1.5-alpha.1"],
8
+ "versions": ["0.1.2-rc.1", "0.1.5-alpha.1", "0.1.5-rc.1", "0.1.5-rc.2"],
9
9
  "packages": [
10
10
  "@deepseek-ai/dsh-agent",
11
11
  "@deepseek-ai/dsh-atomic-write",
package/cordis.patch.yml CHANGED
@@ -6,6 +6,7 @@
6
6
  config:
7
7
  enableProxy: false
8
8
  enableSearch: false
9
+ enableReserveFallback: false
9
10
  enableImageTool: false
10
11
  enableImageGeneration: false
11
12
  enableAutoReview: false
package/docs/README.zh.md CHANGED
@@ -12,19 +12,19 @@ Codex Connect 为标准 Harness agent loop 添加 `openai-codex` 模型提供方
12
12
 
13
13
  ## 快速开始
14
14
 
15
- 本指南介绍下方已发布的组合。请先运行 `dsh --version`;其他 DSH 版本请查阅[安装与升级](../INSTALL.md)。`alpha` 等会移动的 npm tag 不代表兼容性保证。
15
+ 本指南介绍下方已发布的组合。请先运行 `dsh --version`,并用 `doctor --json` 检查实际安装的模型运行库:rc.1 CLI 可能解析到 rc.2 包。其他版本请查阅[安装与升级](../INSTALL.md)。`alpha` 等会移动的 npm tag 不代表兼容性保证。
16
16
 
17
17
  | 要求 | 已验证组合 |
18
18
  |---|---|
19
- | Codex Connect | `0.1.0-alpha.4.32` |
20
- | DeepSeek Harness | `0.1.2-rc.1` |
19
+ | Codex Connect | `0.1.0-alpha.4.34` |
20
+ | DeepSeek Harness | `0.1.2-rc.1`、`0.1.5-alpha.1`、`0.1.5-rc.1` 或 `0.1.5-rc.2` |
21
21
  | Node.js | `^22.19.0 \|\| >=24.0.0` |
22
22
  | 账户 | 通过 ChatGPT OAuth 使用所请求的 Codex 模型;可用性由 OpenAI 决定 |
23
23
 
24
24
  ### 1. 安装
25
25
 
26
26
  ```sh
27
- dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.32
27
+ dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.34
28
28
  dsh web
29
29
  ```
30
30
 
@@ -69,10 +69,15 @@ dsh plugin --profile web exec dsh-codex-connect doctor --json
69
69
  |---|---|---|
70
70
  | 代理 | `enableProxy` | 不带凭据的 HTTP(S),只作用于本插件流量。代理请求失败不会静默改走直连。 |
71
71
  | Codex 搜索 | `enableSearch` | 将整个 profile 的搜索路由切换为 Codex;关闭后恢复之前的路由。 |
72
+ | Luna Reserve | `enableReserveFallback` | 只在服务端为当前已固定账户明确授权时使用隐藏的 Reserve 路由;不修改全局默认模型,也不因普通 `429` 重试。 |
72
73
  | 图片查看 | `enableImageTool` | 为视觉模型添加 `view_image`,读取本地文件和经过校验的公网 HTTP(S) 图片。 |
73
74
  | GPT Image 图片生成 | `enableImageGeneration` | 只接受提示词;可用性、尺寸和额度仍由账户及服务端控制。 |
74
75
  | 自动审查 | `enableAutoReview` | 将有界的审批上下文、工具参数、工作目录和待执行动作发送到 `chatgpt.com`,首次启用需要确认。失败时交还人工审批。 |
75
76
 
77
+ **尚未发布的实验功能:** 已发布的 Alpha 4.34 不包含 Luna Reserve 回退。此开发版本仍默认关闭该功能,尚未完成真实账户进入 Reserve 及恢复普通模型的验证。
78
+
79
+ 启用 `enableReserveFallback: true` 后,账户 UI 和 agent 路由共用一份绑定身份的额度状态,按服务端返回的额度窗口后台刷新;有效状态可跨 agent step 复用。只有身份完整、非 FedRAMP 且服务端授权时,插件才进入 `gpt-reserve`;普通额度确认恢复后,切回该会话先前的模型和推理强度。Reserve 有自己的额度,不出现在模型选择器中,也不是无限额度。资格由服务端决定,重置时间本身不授权切换。当前版本只支持已知的 `gpt-5.6-luna` 元数据。刷新、身份和验证限制见 [Luna Reserve fallback](reference.md#luna-reserve-fallback)。
80
+
76
81
  使用你当前 GPT 订阅计划提供的图片生成能力。生成原文件与附件预览分开保存;关闭能力或卸载插件不会删除这些文件。存储和访问规则见[配置与恢复](reference.zh.md#搜索与图片工具)。
77
82
 
78
83
  自动审查在 Harness 策略判定需要审批后执行,不会绕过该策略。启用前请阅读[自动审查行为](auto-review.zh.md)。
@@ -0,0 +1,9 @@
1
+ # Shared Luna Reserve quota state
2
+
3
+ One plugin-owned quota service supplies both the account UI and Reserve routing. It coalesces concurrent usage GETs and schedules adaptive refresh from the last successful completion. Repeated reads preserve that deadline. Reset times accelerate observation without granting permission; only an identity-matched backend response authorizes Reserve or ordinary-usage recovery.
4
+
5
+ The in-memory cache holds at most sixteen account/user entries. Account mutations, configuration changes, and disposal revoke the epoch signal carried by undispatched local permits. Each entry also owns a snapshot signal: starting a refresh (successful or failed) or evicting that entry revokes its old undispatched permits without revoking other identities. Return-target reads and writes recheck this combined authority before changing routes, including recovery to an ordinary model. Caller cancellation detaches its waiter without cancelling shared transport. Disposal aborts the epoch and awaits authentication and transport operations before closing the proxy manager. Failed responses remove cached decisions and receive a five-second retry deadline; raw provider failures are not retained in public errors.
6
+
7
+ Ordinary and Reserve allowances are distinct. Explicit exhaustion of both stops routing. A typed account-quota failure invalidates stale state and permits at most one fresh, authorized transition per turn; generic request-rate failures do not enter this path. Return selections remain session/account-bound private files. Reserve model calls use Luna defaults and the existing context-window restriction remains unchanged.
8
+
9
+ Verification uses synthetic credentials and HTTP responses through the quota service, account API, assembled agent loop, and installed host matrix. It does not establish actual account eligibility or production quota availability.
@@ -1,4 +1,4 @@
1
1
  # Bilingual-pair consistency record for the operational reference. Re-record with:
2
2
  # git hash-object docs/reference.md docs/reference.zh.md
3
- docs/reference.md: a91c7af5295352e2a391da6346471894f8a32712
4
- docs/reference.zh.md: fcbeef287ace393761d5fc91e8b70e79ba3876d4
3
+ docs/reference.md: 114ff306f7edffbec3f7faf97da0a4dbb9793c7e
4
+ docs/reference.zh.md: 875352186b206b4f0fe29e5671972e781986a713
package/docs/reference.md CHANGED
@@ -10,7 +10,7 @@ OAuth credentials are stored on the DSH host and used there to authenticate and
10
10
 
11
11
  Choose an `openai-codex` model in the normal Harness model picker. Model names remain canonical in every UI language. **More settings → Models** controls which models appear in discovery; hiding a model does not disable routing by its exact id.
12
12
 
13
- The Codex catalog comes from the installed `@earendil-works/pi-ai` package, not a live query of the account's available models. DSH `0.1.2-rc.1` uses pi-ai `^0.84.2`, which lacks `gpt-6-astra`; Codex Connect supplies that definition. The Alpha 4.33 candidate also targets DSH `0.1.5-alpha.1` with pi-ai `0.85.1`. Mixed host package versions and other DSH/pi-ai combinations remain unverified. With a native Astra entry, the plugin preserves its metadata and retains Low, Medium, High, Xhigh, and Max reasoning choices without modifying the installed catalog. Users do not need to upgrade pi-ai separately to select Astra. Dependency declarations identify intended support, not completed release acceptance; the public installation recommendation remains on a published, verified pair until the candidate passes validation. Neither catalog source proves account access.
13
+ The Codex catalog comes from the installed `@earendil-works/pi-ai` package, not a live query of the account's available models. DSH `0.1.2-rc.1` uses pi-ai `^0.84.2`, which lacks `gpt-6-astra`; Codex Connect supplies that definition. Alpha 4.33 is also verified with DSH `0.1.5-alpha.1` and pi-ai `0.85.1`. Mixed host package versions and other DSH/pi-ai combinations remain unverified. With a native Astra entry, the plugin preserves its metadata and retains Low, Medium, High, Xhigh, and Max reasoning choices without modifying the installed catalog. Users do not need to upgrade pi-ai separately to select Astra. The exact verified pairs and acceptance limits are recorded in the release notes; dependency declarations alone do not establish verification. Neither catalog source proves account access.
14
14
 
15
15
  - Adding an account leaves the current account usable while authorization is pending.
16
16
  - Cancelling or timing out a new authorization preserves every existing account and closes accepted callback connections, including incomplete HTTP requests. After cancellation, the browser reads account labels and quota together before updating the view. Pending authorization expires after 10 minutes by default; `oauthTimeoutMs` accepts 1,000–1,800,000 milliseconds and is applied when the plugin loads.
@@ -43,6 +43,7 @@ Fresh installations register the model provider and leave every additional capab
43
43
  config:
44
44
  enableProxy: false
45
45
  enableSearch: false
46
+ enableReserveFallback: false
46
47
  enableImageTool: false
47
48
  enableImageGeneration: false
48
49
  enableAutoReview: false
@@ -56,12 +57,33 @@ Disabling the proxy or unloading the plugin gives active proxy operations one se
56
57
 
57
58
  Direct connection is the default. An enabled credential-free HTTP(S) proxy applies only to this plugin's model, OAuth, refresh, quota, search, image, and Auto-review traffic. Detection checks standard proxy environment variables and documented loopback candidates without making a model call, consuming quota, or saving settings. A failed proxy request never silently retries through a direct connection. Loading Codex Connect does not replace Node's environment-proxy dispatcher, so unrelated Harness requests continue using the process's existing proxy policy.
58
59
 
60
+ ### Luna Reserve fallback
61
+
62
+ This is an unreleased, default-off experiment; published Alpha 4.34 does not include it. Real-account Reserve entry and recovery remain unverified.
63
+
64
+ `enableReserveFallback: true` opts agent requests into backend-authorized Luna Reserve fallback. The account UI and routing share an in-memory account/user-bound quota snapshot; concurrent reads coalesce and fresh reads do not issue another quota `GET`. A cold or stale read waits for refresh. After a successful fetch, background refresh runs at 60/30/15/5 seconds for usage below 75%, at least 75%, at least 90%, and at least 99%, using the highest consumption across ordinary and relevant model windows. Future reset times shorten the next refresh to reset plus one second; they never establish recovery. Cache reads do not postpone that deadline. Failed fetches discard cached decisions and retry after five seconds. Account mutations, settings changes, and plugin disposal invalidate the state; UI receives only the public quota projection.
65
+
66
+ A valid shared decision issues a private one-shot permit for the next `gpt-reserve` dispatch in that session/account. This local dispatch guard is not a server-side per-call authorization requirement. Cancellation, replacement, an agent error, turn stopping, quota invalidation, snapshot refresh, or cache eviction revokes an unused permit. Return-target I/O rechecks that authority before restoring an ordinary model. Direct and auxiliary Reserve calls fail before a model request. With fallback disabled, ordinary agent steps do not query quota, account UI reads remain passive, and there is no background quota poller. An already-Reserve session requires an explicitly selected ordinary model.
67
+
68
+ The access token must contain non-empty `chatgpt_account_id` and `chatgpt_user_id` (or `user_id`) claims under `https://api.openai.com/auth`, and `chatgpt_account_is_fedramp` must be absent or `false`. Missing, partial, FedRAMP, changed, or response-mismatched identity disables fallback for that step. The plugin does not guess identity from an email address or subscription plan.
69
+
70
+ The plugin routes to the hidden model only when the quota response matches both the captured account and user and supplies a valid Luna Reserve authorization banner for the applicable model. A generic HTTP `429`, a rounded quota percentage, a reset time, or a Reserve model name is not authorization and is never retried as Reserve. This version accepts only the known `gpt-5.6-luna` Reserve metadata; other metadata is not inferred. The server decides eligibility and whether `5h`, weekly, or another backend limit causes Reserve authorization.
71
+
72
+ Before entering Reserve, the plugin atomically saves the session's ordinary model request controls in a private `codex-connect-reserve/<SHA-256 of session id>.json` file beside the Codex credential file. The record contains a hash of the account/user pair and the ordinary model, reasoning effort, temperature, output limit, and stop sequences; it does not contain a bearer token or raw account and user ids. The Reserve request omits those ordinary controls and uses Luna's own defaults. A later identity-matched quota response must explicitly allow ordinary usage before the complete saved request configuration is restored. A missing, corrupt, oversized, wrong-account, or fork-without-its-own return record is never guessed or inherited: select an ordinary model explicitly to continue.
73
+
74
+ Reserve is not exposed in model discovery and does not modify profile-wide defaults. Its allowance is separate from ordinary usage, not unlimited. When both are explicitly exhausted, routing stops with a usage-exhausted message. If a model request reports Harness's typed account-quota failure, the plugin invalidates cached state and allows at most one fresh, authorized entry or recovery retry per turn. Generic rate-limit failures never trigger this path.
75
+
76
+ Reserve uses Luna's 272,000-token catalog context window, not the previous model's larger window. This release does not authorize automatic or manual compaction calls through Reserve. Switching a long conversation can therefore exceed Luna's context limit; compact before ordinary usage runs out or configure a separate, available summarization model. The plugin does not claim a cross-host exact token preflight or automatic long-context recovery.
77
+
78
+ Automated coverage uses synthetic tokens and quota responses. It verifies local routing and restoration rules without contacting a real account, and therefore does not establish live account eligibility, available quota, or current server policy.
79
+
59
80
  ### Search and image tools
60
81
 
61
82
  - `enableSearch: true` registers Codex as an available search provider and selects it for profile-wide searches. Disabling it unregisters the provider and restores the route that was active before Codex Search was enabled.
62
83
  - Search has a 30-second total deadline covering authentication, response headers and body reading. Responses larger than 1 MiB are rejected, and unfinished response bodies are cancelled on failure. Caller cancellation can end a search sooner.
63
84
  - `enableImageTool: true` registers `view_image` on vision-capable models. Remote reads accept credential-free public HTTP(S) only and revalidate DNS and redirects.
64
85
  - `enableImageGeneration: true` registers prompt-only GPT Image generation. Use the image generation capability included with your current GPT subscription. Availability, dimensions, and quota remain account- and service-controlled.
86
+ - `imageModelHint` is an optional profile-scoped setting in Plugin configuration or the profile config. Empty uses `gpt-image-2`; a custom value accepts 1–128 ASCII letters, digits, dots, underscores, or hyphens and must start with a letter or digit. Saving changes the `model` field of subsequent image requests to the same fixed endpoint; clearing restores the default. The tool still accepts only `prompt`. This is an unverified route hint: the service may ignore or reject it, and it does not guarantee the returned model.
65
87
 
66
88
  Generated originals are stored under `$DSH_HOME/dsh-codex-connect/images/v1`; the conversation receives a separate DSH attachment preview. The result card reports dimensions and file sizes and can download either representation. Originals are owner-only, integrity-checked, and available only to the creating session and forks that inherited the result. Disabling or uninstalling the plugin does not delete those files automatically.
67
89
 
@@ -100,8 +122,10 @@ The main plugin options are:
100
122
  | `proxyUrl` | `http://127.0.0.1:7890` | Credential-free HTTP(S) proxy origin; inactive until enabled |
101
123
  | `contextWindowOverrides` | none | Per-model client context-budget overrides |
102
124
  | `enableSearch` | `false` | Register Codex search and select it when the setting is saved |
125
+ | `enableReserveFallback` | `false` | Follow identity-matched, backend-authorized Luna Reserve transitions for agent requests |
103
126
  | `enableImageTool` | `false` | Register `view_image` |
104
127
  | `enableImageGeneration` | `false` | Register GPT Image generation |
128
+ | `imageModelHint` | empty | Optional unverified image route hint; empty keeps the default request |
105
129
  | `enableAutoReview` | `false` | Review eligible approval requests with Codex |
106
130
  | `searchModel` | `gpt-5.6-sol` | Model used by standalone search |
107
131
  | `searchMode` | `cached` | `cached`, `indexed`, or `live` |
@@ -114,6 +138,8 @@ The main plugin options are:
114
138
 
115
139
  ### Local installation diagnostics
116
140
 
141
+ Published Alpha 4.33 can fail to list or prepare Codex models on DSH `0.1.5-rc.1` with `Cannot read properties of undefined (reading 'get')`. That host requires a per-model error index absent from the older plugin profile. Builds containing [the Issue #178 fix](https://github.com/franksong2702/dsh-codex-connect/issues/178) initialize the index; re-authorizing does not supply it. Choose an exact plugin release verified with your host version, not merely one with the same Alpha series.
142
+
117
143
  Run `dsh plugin --profile web exec dsh-codex-connect doctor --json` to inspect local installation metadata without a network request. Compatibility statuses mean: `compatible` matches the declared version requirements, not a behavioral test; `unverified` identifies package versions outside the declared support set; `unknown` means required version metadata is missing or unreadable; `incompatible` identifies a Node version outside the declared engine requirement. The aggregate prioritizes `incompatible`, then `unknown`, then `unverified`. Doctor exits `1` for any non-compatible result or unsafe credential-file metadata; this does not authorize or recommend changing DSH.
118
144
 
119
145
  The normal update card checks only Codex Connect releases. It reuses successful plugin-version checks for up to 24 hours and retries unavailable checks every five minutes while mounted; a manual check bypasses the cache. It neither queries host compatibility nor recommends host upgrades or downgrades. An unlisted DSH/plugin combination requires verification, not an assumption of failure.
@@ -10,7 +10,7 @@ OAuth 凭据保存在运行 DSH 的主机上,由该主机用于向 OpenAI 认
10
10
 
11
11
  在 Harness 的常规模型选择器中选择一个 `openai-codex` 模型。所有界面语言均保留模型的规范名称。**更多设置 → 模型** 控制发现列表中显示哪些模型;隐藏模型不会禁用按精确 ID 路由。
12
12
 
13
- Codex 目录来自已安装的 `@earendil-works/pi-ai` 包,不是实时查询账户可用模型的结果。DSH `0.1.2-rc.1` 使用 pi-ai `^0.84.2`,其中尚无 `gpt-6-astra`,因此由 Codex Connect 补充定义。Alpha 4.33 候选还以 DSH `0.1.5-alpha.1` 与 pi-ai `0.85.1` 为目标;混装的宿主包以及其他 DSH/pi-ai 组合仍属未验证。遇到原生 Astra 条目时,插件保留其元数据,并维持 Low、Medium、High、Xhigh 和 Max 推理选择,不修改已安装的目录。用户无需单独升级 pi-ai 即可选择 Astra。依赖声明表示预期支持,不代表发布验收已完成;候选通过验证前,公开安装推荐仍使用已发布、已验证的组合。两种来源的目录条目都不能证明账户具有调用权限。
13
+ Codex 目录来自已安装的 `@earendil-works/pi-ai` 包,不是实时查询账户可用模型的结果。DSH `0.1.2-rc.1` 使用 pi-ai `^0.84.2`,其中尚无 `gpt-6-astra`,因此由 Codex Connect 补充定义。Alpha 4.33 也已验证 DSH `0.1.5-alpha.1` 与 pi-ai `0.85.1` 的组合;混装的宿主包以及其他 DSH/pi-ai 组合仍属未验证。遇到原生 Astra 条目时,插件保留其元数据,并维持 Low、Medium、High、Xhigh 和 Max 推理选择,不修改已安装的目录。用户无需单独升级 pi-ai 即可选择 Astra。发布说明记录了准确的已验证组合和验收限制;依赖声明本身不代表已验证。两种来源的目录条目都不能证明账户具有调用权限。
14
14
 
15
15
  - 添加账户期间,当前账户仍可继续使用。
16
16
  - 取消新的授权或等待超时,不会删除任何已有账户,并会关闭已接受的回调连接,包括未完成的 HTTP 请求。取消后,浏览器会一起读取账户标签与额度,再更新显示。待处理授权默认 10 分钟后过期;`oauthTimeoutMs` 接受 1,000–1,800,000 毫秒,并在插件加载时应用。
@@ -43,6 +43,7 @@ GPT Codex 对话的 Composer 会显示 Fast Mode 与额度:
43
43
  config:
44
44
  enableProxy: false
45
45
  enableSearch: false
46
+ enableReserveFallback: false
46
47
  enableImageTool: false
47
48
  enableImageGeneration: false
48
49
  enableAutoReview: false
@@ -56,12 +57,33 @@ GPT Codex 对话的 Composer 会显示 Fast Mode 与额度:
56
57
 
57
58
  默认使用直连。启用后,不带凭据的 HTTP(S) proxy 只应用于本插件的模型、OAuth、刷新、额度、搜索、图片和自动审查流量。检测只检查标准代理环境变量和文档列出的 loopback 候选地址,不调用模型、不消耗额度,也不保存设置。代理请求失败时,绝不会静默改走直连。加载 Codex Connect 不会替换 Node 的环境代理 dispatcher,因此其他 Harness 请求会继续使用进程已有的代理策略。
58
59
 
60
+ ### Luna Reserve 回退
61
+
62
+ 这是尚未发布、默认关闭的实验功能;已发布的 Alpha 4.34 不包含该功能。真实账户进入 Reserve 及恢复普通模型的过程仍未完成验证。
63
+
64
+ `enableReserveFallback: true` 为 agent 请求启用由后端授权的 Luna Reserve 回退。账户 UI 和路由共用绑定账户与用户的内存额度快照;并发读取合并,有效状态不再发起额度 `GET`。首次或过期读取等待刷新。查询成功后,根据普通额度和相关模型窗口中的最高消耗,低于 75%、达到 75%、达到 90%、达到 99% 时,分别每 60/30/15/5 秒后台刷新。未来重置时间可将下次刷新提前到重置后一秒,但不证明额度恢复。缓存读取不会推迟刷新期限。查询失败会清除缓存决策,五秒后重试。账户修改、设置变更和插件卸载会使状态失效;UI 只接收公开额度投影。
65
+
66
+ 有效的共享决策为该会话和账户的下一次 `gpt-reserve` 调用签发私有一次性许可。这是本地调用保护,不代表服务端要求每次调用单独认证额度。取消、替换请求、agent 出错、回合停止、额度状态失效、快照刷新或缓存淘汰都会撤销未使用的许可。恢复普通模型前,返回记录的读取也会重新检查该授权是否有效。直接和辅助 Reserve 调用会在发送前失败。关闭回退时,普通 agent 步骤不查询额度,账户 UI 保持被动读取,也不创建后台额度轮询;已处于 Reserve 的会话需要显式选择普通模型.
67
+
68
+ Access token 的 `https://api.openai.com/auth` 中必须包含非空的 `chatgpt_account_id` 和 `chatgpt_user_id`(或 `user_id`),且 `chatgpt_account_is_fedramp` 必须缺省或为 `false`。身份缺失、不完整、属于 FedRAMP、发生变化或与额度响应不匹配时,该步骤不会启用回退。插件不会从邮箱地址或订阅套餐推测身份。
69
+
70
+ 只有额度响应同时匹配固定的账户与用户,并包含适用于当前模型的有效 Luna Reserve 授权 banner,插件才会路由到隐藏模型。普通 HTTP `429`、四舍五入后的额度百分比、重置时间或 Reserve 模型名称都不是授权,也不会触发 Reserve 重试。当前版本只接受已知的 `gpt-5.6-luna` Reserve 元数据,不推测其他模型。能否使用 Reserve,以及触发授权的是 `5h`、周额度还是其他后端限制,都由服务端决定。
71
+
72
+ 进入 Reserve 前,插件会将会话的普通模型请求参数原子保存到 Codex 凭据文件旁的私有 `codex-connect-reserve/<会话 id 的 SHA-256>.json` 文件中。记录包含账户与用户组合的哈希,以及普通模型、推理强度、温度、输出上限和停止序列,不包含 bearer token 或原始账户与用户 id。Reserve 请求不继承这些普通模型参数,而是使用 Luna 自身的默认值。后续身份匹配的额度响应必须明确允许普通额度,插件才会恢复完整的已保存请求配置。返回记录缺失、损坏、过大、属于其他账户,或 fork 没有自己的记录时,插件都不会猜测或继承目标;请显式选择普通模型后继续。
73
+
74
+ Reserve 不出现在模型发现列表,也不修改整个 profile 的默认模型。它有独立于普通额度的限额,并非无限可用。两者明确耗尽时,路由停止并提示额度用尽。如果模型请求报告宿主明确分类的账户额度耗尽,插件使缓存失效,每回合至多按新授权进行一次进入或恢复重试;普通请求限流不触发此路径。
75
+
76
+ Reserve 使用 Luna 目录中的 272,000 token 上下文窗口,不沿用原模型更大的窗口。当前版本不授权通过 Reserve 进行自动或手动上下文压缩。因此,长会话切换后可能超过 Luna 的上下文限制;请在普通额度耗尽前压缩,或配置另一个仍可用的摘要模型。插件不保证跨宿主的精确 token 预检或自动长上下文恢复。
77
+
78
+ 自动化覆盖使用合成 token 和额度响应,验证本地路由与恢复规则,不连接真实账户,因此不能证明实际账户资格、可用额度或当前服务端策略。
79
+
59
80
  ### 搜索与图片工具
60
81
 
61
82
  - `enableSearch: true` 将 Codex 注册为可用搜索提供方,并用于整个 profile 的搜索。关闭时会注销该提供方,并恢复启用 Codex 搜索之前的路由。
62
83
  - 搜索从认证开始到读完响应共用 30 秒总期限。超过 1 MiB 的响应会被拒绝,失败时会取消尚未读完的响应体。调用方也可以提前取消搜索。
63
84
  - `enableImageTool: true` 为具备视觉能力的模型注册 `view_image`。远程读取只接受不带凭据的公网 HTTP(S),并重新检查 DNS 与重定向。
64
85
  - `enableImageGeneration: true` 注册只接受提示词的 GPT Image 图片生成。使用你当前 GPT 订阅计划提供的图片生成能力。可用性、尺寸和额度仍由账户及服务端控制。
86
+ - `imageModelHint` 是“插件配置”或 profile config 中的可选设置,按 profile 保存。留空使用 `gpt-image-2`;自定义值接受 1–128 个 ASCII 字母、数字、点、下划线或连字符,且必须以字母或数字开头。保存后会修改后续图片请求的 `model` 字段,仍使用同一固定端点;清空可恢复默认值。工具仍只接受 `prompt`。这是未经验证的路由提示:服务端可能忽略或拒绝,也不保证返回指定模型。
65
87
 
66
88
  生成的原文件保存在 `$DSH_HOME/dsh-codex-connect/images/v1`;对话会收到另一份 DSH 附件预览。结果卡片会报告尺寸和文件大小,并可下载任一版本。原文件仅允许所有者访问,下载前会校验完整性,并且只对创建会话及继承了该结果的 fork 开放。关闭能力或卸载插件不会自动删除这些文件。
67
89
 
@@ -100,8 +122,10 @@ GPT Codex 对话的 Composer 会显示 Fast Mode 与额度:
100
122
  | `proxyUrl` | `http://127.0.0.1:7890` | 不带凭据的 HTTP(S) proxy origin;启用前不生效 |
101
123
  | `contextWindowOverrides` | 无 | 按模型设置客户端上下文预算 |
102
124
  | `enableSearch` | `false` | 注册 Codex 搜索,并在保存时将它选为搜索提供方 |
125
+ | `enableReserveFallback` | `false` | 为 agent 请求执行身份匹配、后端授权的 Luna Reserve 切换 |
103
126
  | `enableImageTool` | `false` | 注册 `view_image` |
104
127
  | `enableImageGeneration` | `false` | 注册 GPT Image 图片生成 |
128
+ | `imageModelHint` | 空字符串 | 可选的未验证图片路由提示;留空保持默认请求 |
105
129
  | `enableAutoReview` | `false` | 使用 Codex 审查符合条件的审批请求 |
106
130
  | `searchModel` | `gpt-5.6-sol` | 独立搜索使用的模型 |
107
131
  | `searchMode` | `cached` | `cached`、`indexed` 或 `live` |
@@ -114,6 +138,8 @@ GPT Codex 对话的 Composer 会显示 Fast Mode 与额度:
114
138
 
115
139
  ### 本地安装诊断
116
140
 
141
+ 已发布的 Alpha 4.33 在 DSH `0.1.5-rc.1` 上列出或准备 Codex 模型时,可能报 `Cannot read properties of undefined (reading 'get')`。新宿主要求按模型记录错误的索引,旧插件 profile 没有提供。包含 [Issue #178 修复](https://github.com/franksong2702/dsh-codex-connect/issues/178)的构建会初始化该索引;重新授权不能补齐这个字段。请选择与宿主版本完成验证的精确插件版本,不能仅凭属于同一 Alpha 系列判断。
142
+
117
143
  运行 `dsh plugin --profile web exec dsh-codex-connect doctor --json` 可检查本地安装元数据,不会联网。兼容性状态含义:`compatible` 表示符合声明的版本要求,不是行为测试通过;`unverified` 表示包版本超出声明的支持集合;`unknown` 表示缺少必要版本元数据或无法读取;`incompatible` 表示 Node 版本不满足声明的 engine 要求。汇总状态依次优先采用 `incompatible`、`unknown`、`unverified`。任何非 compatible 结果或不安全的凭据文件元数据都会让 doctor 返回 `1`,但这并不授权或建议更改 DSH。
118
144
 
119
145
  常规更新卡片只检查 Codex Connect 发布版本。插件版本检查成功后最多缓存 24 小时,页面挂载期间每五分钟重试不可用的检查;手动检查会绕过缓存。它不会查询宿主兼容性,也不会建议升级或降级宿主。未列入记录的 DSH/plugin 组合需要验证,不能据此认定无法运行。
package/lib/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { $ as readInstalledPackageVersion, Dt as OpenAICodexTrustedOriginsStore, Ft as openAICodexAuthStatus, H as DSH_PLUGIN_API_PACKAGES, Ht as OpenAICodexCredentialStore, It as publicAuthError, Mt as openAICodexModelCatalog, N as CODEX_CONNECT_VERSION, Nt as loginOpenAICodex, Ot as normalizeTrustedOrigin, Pt as logoutOpenAICodex, Q as isSupportedDshPluginApiVersion, Ut as openAICodexAuthPath, Vt as OPENAI_CODEX_PROVIDER, Z as evaluateCompatibility, c as migrateOpenAICodexSearchHistory, d as OPENAI_CODEX_BASE_URL, j as diagnoseOpenAICodex, l as CODEX_AUTO_REVIEW_MODEL, u as probeCodexAutoReview, yt as normalizeOpenAICodexProxyUrl } from "./src-Dc-mRwDj.js";
2
+ import { A as DSH_PLUGIN_API_PACKAGES, B as isSupportedDshPluginApiVersion, Ft as loginOpenAICodex, Gt as openAICodexAuthPath, It as logoutOpenAICodex, Lt as openAICodexAuthStatus, Pt as openAICodexModelCatalog, Rt as publicAuthError, Ut as OPENAI_CODEX_PROVIDER, V as readInstalledPackageVersion, Wt as OpenAICodexCredentialStore, c as migrateOpenAICodexSearchHistory, d as OPENAI_CODEX_BASE_URL, jt as normalizeOpenAICodexProxyUrl, l as CODEX_AUTO_REVIEW_MODEL, nt as OpenAICodexTrustedOriginsStore, rt as normalizeTrustedOrigin, u as probeCodexAutoReview, x as CODEX_CONNECT_VERSION, y as diagnoseOpenAICodex, z as evaluateCompatibility } from "./src-BTr7qkL_.js";
3
3
  import { i as fetch, r as ProxyAgent, t as Agent } from "./undici-runtime-H2uktiw6.js";
4
4
  import { createHash } from "node:crypto";
5
5
  import { realpathSync } from "node:fs";
package/lib/client.js CHANGED
@@ -13,6 +13,10 @@ window.__ModuleLoader__.load({
13
13
  const OPENAI_CODEX_SETTINGS_NAMESPACE = "llm-openai-codex";
14
14
  /** Suggested local HTTP proxy shown by the settings UI; it is never enabled by default. */
15
15
  const DEFAULT_OPENAI_CODEX_PROXY_URL = "http://127.0.0.1:7890";
16
+ /** Validate an optional bounded ASCII image route model hint. */
17
+ function isValidOpenAICodexImageModelHint(value) {
18
+ return typeof value === "string" && (value === "" || /^(?=.{1,128}$)[A-Za-z0-9][A-Za-z0-9._-]*$/u.test(value));
19
+ }
16
20
  /**
17
21
  * Normalize the credential-free HTTP proxy URL accepted by Codex Connect.
18
22
  * Paths, query strings, fragments, and embedded credentials are rejected so
@@ -66,8 +70,10 @@ window.__ModuleLoader__.load({
66
70
  proxyUrl: DEFAULT_OPENAI_CODEX_PROXY_URL,
67
71
  contextWindowOverrides: void 0,
68
72
  enableSearch: false,
73
+ enableReserveFallback: false,
69
74
  enableImageTool: false,
70
75
  enableImageGeneration: false,
76
+ imageModelHint: "",
71
77
  autoReviewDisclosureAcknowledged: false,
72
78
  enableAutoReview: false,
73
79
  searchModel: "gpt-5.6-sol",
@@ -86,8 +92,10 @@ window.__ModuleLoader__.load({
86
92
  const proxyUrl = value["proxyUrl"];
87
93
  const contextWindowOverrides = value["contextWindowOverrides"];
88
94
  const enableSearch = value["enableSearch"];
95
+ const enableReserveFallback = value["enableReserveFallback"];
89
96
  const enableImageTool = value["enableImageTool"];
90
97
  const enableImageGeneration = value["enableImageGeneration"];
98
+ const imageModelHint = value["imageModelHint"];
91
99
  const autoReviewDisclosureAcknowledged = value["autoReviewDisclosureAcknowledged"];
92
100
  const enableAutoReview = value["enableAutoReview"];
93
101
  const searchModel = value["searchModel"];
@@ -99,7 +107,9 @@ window.__ModuleLoader__.load({
99
107
  if (proxyUrl !== void 0 && (typeof proxyUrl !== "string" || !isValidOpenAICodexProxyUrl(proxyUrl))) return void 0;
100
108
  if (contextWindowOverrides !== void 0 && contextWindowOverrides !== null && !isValidOpenAICodexContextWindowOverrides(contextWindowOverrides)) return void 0;
101
109
  if (typeof enableSearch !== "boolean" || typeof enableImageTool !== "boolean") return void 0;
110
+ if (enableReserveFallback !== void 0 && typeof enableReserveFallback !== "boolean") return void 0;
102
111
  if (enableImageGeneration !== void 0 && typeof enableImageGeneration !== "boolean") return void 0;
112
+ if (imageModelHint !== void 0 && !isValidOpenAICodexImageModelHint(imageModelHint)) return void 0;
103
113
  if (autoReviewDisclosureAcknowledged !== void 0 && typeof autoReviewDisclosureAcknowledged !== "boolean") return void 0;
104
114
  if (enableAutoReview !== void 0 && typeof enableAutoReview !== "boolean") return void 0;
105
115
  if (typeof searchModel !== "string" || searchModel.trim().length === 0) return void 0;
@@ -113,8 +123,10 @@ window.__ModuleLoader__.load({
113
123
  proxyUrl: proxyUrl === void 0 ? DEFAULT_OPENAI_CODEX_PROXY_URL : normalizeOpenAICodexProxyUrl(proxyUrl),
114
124
  contextWindowOverrides: overrides === void 0 ? void 0 : Object.freeze(overrides),
115
125
  enableSearch,
126
+ enableReserveFallback: enableReserveFallback ?? false,
116
127
  enableImageTool,
117
128
  enableImageGeneration: enableImageGeneration ?? false,
129
+ imageModelHint: imageModelHint ?? "",
118
130
  autoReviewDisclosureAcknowledged: autoReviewDisclosureAcknowledged ?? false,
119
131
  enableAutoReview: enableAutoReview ?? false,
120
132
  searchModel,
@@ -904,9 +916,11 @@ window.__ModuleLoader__.load({
904
916
  "models",
905
917
  "contextWindowOverrides",
906
918
  "enableProxy",
919
+ "enableReserveFallback",
907
920
  "proxyUrl",
908
921
  "enableImageTool",
909
922
  "enableImageGeneration",
923
+ "imageModelHint",
910
924
  "autoReviewDisclosureAcknowledged",
911
925
  "enableAutoReview",
912
926
  "searchModel",
@@ -1224,6 +1238,7 @@ window.__ModuleLoader__.load({
1224
1238
  const validModel = draft !== void 0 && draft.searchModel.trim().length > 0;
1225
1239
  const validTokens = draft !== void 0 && Number.isInteger(draft.searchMaxOutputTokens) && draft.searchMaxOutputTokens > 0;
1226
1240
  const validProxy = draft !== void 0 && isValidOpenAICodexProxyUrl(draft.proxyUrl);
1241
+ const validImageModelHint = draft !== void 0 && isValidOpenAICodexImageModelHint(draft.imageModelHint);
1227
1242
  const normalizedManualProxy = normalizeOpenAICodexProxyUrl(manualProxyUrl);
1228
1243
  const manualProxyEntered = manualProxyUrl.trim().length > 0;
1229
1244
  const testedManualProxy = normalizedManualProxy !== void 0 && manualProbe?.reachable === true && manualProbe.proxyUrl === normalizedManualProxy;
@@ -1234,7 +1249,7 @@ window.__ModuleLoader__.load({
1234
1249
  const model = modelCatalog?.find((entry) => entry.id === id);
1235
1250
  return model !== void 0 && isValidOpenAICodexContextBudget(budget, model.maxContextWindow);
1236
1251
  });
1237
- const valid = validModel && validTokens && validProxy && validContexts && validProxySelection;
1252
+ const valid = validModel && validTokens && validProxy && validImageModelHint && validContexts && validProxySelection;
1238
1253
  const save = async () => {
1239
1254
  if (scope === void 0 || draft === void 0 || !snapshot.writable || !valid) return;
1240
1255
  const desired = {
@@ -2053,6 +2068,25 @@ window.__ModuleLoader__.load({
2053
2068
  })
2054
2069
  ]
2055
2070
  }),
2071
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2072
+ style: toggleRowStyle,
2073
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2074
+ type: "checkbox",
2075
+ checked: draft.enableReserveFallback,
2076
+ onChange: (event) => {
2077
+ update("enableReserveFallback", event.currentTarget.checked);
2078
+ }
2079
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2080
+ style: toggleCopyStyle,
2081
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2082
+ style: labelStyle,
2083
+ children: t("enableReserveFallback")
2084
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2085
+ style: bodyStyle$2,
2086
+ children: t("enableReserveFallbackHelp")
2087
+ })]
2088
+ })]
2089
+ }),
2056
2090
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2057
2091
  style: toggleRowStyle,
2058
2092
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
@@ -2091,6 +2125,28 @@ window.__ModuleLoader__.load({
2091
2125
  })]
2092
2126
  })]
2093
2127
  }),
2128
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2129
+ style: formFieldStyle,
2130
+ children: [
2131
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2132
+ style: labelStyle,
2133
+ children: t("imageModelHint")
2134
+ }),
2135
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2136
+ style: controlStyle,
2137
+ value: draft.imageModelHint,
2138
+ placeholder: t("imageModelHintDefault"),
2139
+ "aria-invalid": !validImageModelHint,
2140
+ onChange: (event) => {
2141
+ update("imageModelHint", event.currentTarget.value);
2142
+ }
2143
+ }),
2144
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2145
+ style: bodyStyle$2,
2146
+ children: t("imageModelHintHelp")
2147
+ })
2148
+ ]
2149
+ }),
2094
2150
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2095
2151
  style: toggleRowStyle,
2096
2152
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
@@ -2192,6 +2248,11 @@ window.__ModuleLoader__.load({
2192
2248
  role: "alert",
2193
2249
  children: t("invalidProxyUrl")
2194
2250
  }) : null,
2251
+ visibleModule === "capabilities" && !validImageModelHint && draft !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2252
+ style: errorStyle$2,
2253
+ role: "alert",
2254
+ children: t("invalidImageModelHint")
2255
+ }) : null,
2195
2256
  visibleModule === "capabilities" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2196
2257
  style: bodyStyle$2,
2197
2258
  children: t("routingNote")
@@ -2259,7 +2320,9 @@ window.__ModuleLoader__.load({
2259
2320
  "auto-review",
2260
2321
  "astra-compatibility",
2261
2322
  "multi-account",
2262
- "search-route"
2323
+ "search-route",
2324
+ "image-model-hint",
2325
+ "luna-reserve"
2263
2326
  ];
2264
2327
  function isHighlightKind(value) {
2265
2328
  return typeof value === "string" && HIGHLIGHT_KINDS.includes(value);
@@ -2728,7 +2791,9 @@ window.__ModuleLoader__.load({
2728
2791
  "auto-review": "updateHighlightAutoReview",
2729
2792
  "astra-compatibility": "updateHighlightAstraCompatibility",
2730
2793
  "multi-account": "updateHighlightMultiAccount",
2731
- "search-route": "updateHighlightSearchRoute"
2794
+ "search-route": "updateHighlightSearchRoute",
2795
+ "image-model-hint": "updateHighlightImageModelHint",
2796
+ "luna-reserve": "updateHighlightLunaReserve"
2732
2797
  };
2733
2798
  function pluginVersionSummary(current, latest, t) {
2734
2799
  if (latest === void 0) return t("compatibilityPluginCurrentOnly", { current });
@@ -4695,6 +4760,12 @@ window.__ModuleLoader__.load({
4695
4760
  enableImageToolHelp: "Allows approved local reads and public-network image fetches for vision-capable models.",
4696
4761
  enableImageGeneration: "Enable GPT Image generation",
4697
4762
  enableImageGenerationHelp: "Let GPT models use GPT Image to generate images in conversations.",
4763
+ enableReserveFallback: "Automatic Luna Reserve",
4764
+ enableReserveFallbackHelp: "Use Luna Reserve only when the server explicitly authorizes it after ordinary usage is exhausted. Restore this conversation’s previous model when ordinary usage recovers. Adds quota checks; does not change global defaults or grant extra quota.",
4765
+ imageModelHint: "Image route model hint",
4766
+ imageModelHintDefault: "Default: gpt-image-2; clear to restore",
4767
+ imageModelHintHelp: "Optional unverified route hint; it may be ignored or rejected and does not guarantee the returned model.",
4768
+ invalidImageModelHint: "Use an empty value or 1–128 ASCII letters, digits, dots, underscores, or hyphens, starting with a letter or digit.",
4698
4769
  enableAutoReview: "Codex Auto-review (Approve for me)",
4699
4770
  enableAutoReviewHelp: "Send eligible approval requests from OpenAI-Codex sessions to a separate Codex reviewer. This changes who reviews; it does not expand DSH file, network, or tool permissions.",
4700
4771
  autoReviewOfficialBadge: "Official Codex capability",
@@ -4794,6 +4865,8 @@ window.__ModuleLoader__.load({
4794
4865
  updateHighlightAstraCompatibility: "Added GPT-6-Astra compatibility metadata when the installed upstream catalog does not provide the model.",
4795
4866
  updateHighlightMultiAccount: "Added management for multiple ChatGPT accounts; starting or cancelling authorization preserves existing accounts.",
4796
4867
  updateHighlightSearchRoute: "Enabling Codex Search now selects the profile-wide search route; disabling it restores the previous provider.",
4868
+ updateHighlightImageModelHint: "Added an optional profile-scoped image route model hint. It is unverified, may be ignored or rejected, and does not guarantee the returned model.",
4869
+ updateHighlightLunaReserve: "Added an optional Luna Reserve fallback for agent requests. It stays off by default and switches only when the backend explicitly authorizes Reserve for the current account.",
4797
4870
  viewTechnicalDetails: "View technical details",
4798
4871
  hideTechnicalDetails: "Hide technical details",
4799
4872
  technicalDetailsHeading: "Technical changes",
@@ -4999,6 +5072,12 @@ window.__ModuleLoader__.load({
4999
5072
  enableImageToolHelp: "允许具备视觉能力的模型在审批后读取本地图片或获取公网图片。",
5000
5073
  enableImageGeneration: "启用 GPT Image 图片生成",
5001
5074
  enableImageGenerationHelp: "启用后,GPT 模型可以在对话中调用 GPT Image 生成图片。",
5075
+ enableReserveFallback: "自动使用 Luna Reserve",
5076
+ enableReserveFallbackHelp: "仅在普通额度耗尽且服务端明确授权时使用 Luna Reserve;普通额度恢复后切回本会话原来的模型。会增加额度查询,不修改全局默认模型,也不会获得额外额度。",
5077
+ imageModelHint: "图片路由模型提示",
5078
+ imageModelHintDefault: "默认:gpt-image-2;清空可恢复",
5079
+ imageModelHintHelp: "可选的未验证路由提示;服务端可能忽略或拒绝,不能保证返回的模型。",
5080
+ invalidImageModelHint: "请输入空值,或输入 1–128 个 ASCII 字母、数字、点、下划线或连字符,且必须以字母或数字开头。",
5002
5081
  enableAutoReview: "Codex 自动审查(代我审批)",
5003
5082
  enableAutoReviewHelp: "将 OpenAI-Codex 会话中原本需要你确认的部分操作交给独立的 Codex 审查器。它只更换审批者,不会扩大 DSH 的文件、网络或工具权限。",
5004
5083
  autoReviewOfficialBadge: "Codex 官方能力",
@@ -5098,6 +5177,8 @@ window.__ModuleLoader__.load({
5098
5177
  updateHighlightAstraCompatibility: "当已安装的上游模型目录尚未提供 GPT-6-Astra 时,补充该模型的兼容元数据。",
5099
5178
  updateHighlightMultiAccount: "增加多个 ChatGPT 账户的管理能力;开始或取消授权时会保留已有账户。",
5100
5179
  updateHighlightSearchRoute: "启用 Codex 搜索时,现在会选中整个 profile 的搜索路由;关闭时恢复此前的提供方。",
5180
+ updateHighlightImageModelHint: "增加可选的 profile 图片路由模型提示。该提示未经验证,服务端可能忽略或拒绝,也不保证返回指定模型。",
5181
+ updateHighlightLunaReserve: "增加可选的 Luna Reserve 回退,仅用于 agent 请求。该能力默认关闭,只有服务端为当前账户明确授权 Reserve 时才会切换。",
5101
5182
  viewTechnicalDetails: "查看完整技术说明",
5102
5183
  hideTechnicalDetails: "收起技术说明",
5103
5184
  technicalDetailsHeading: "技术变更",
@@ -6283,7 +6364,7 @@ window.__ModuleLoader__.load({
6283
6364
  }
6284
6365
  //#endregion
6285
6366
  //#region src/version.ts
6286
- const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.33";
6367
+ const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.35";
6287
6368
  //#endregion
6288
6369
  //#region src/client/OpenAICodexModelsCard.tsx
6289
6370
  /** Compact Models account entry with quota disclosure and shared configuration. */