dsh-codex-connect 0.1.0-alpha.4.44 → 0.1.0-alpha.4.46
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 +4 -4
- package/README.i18n.yaml +2 -2
- package/README.md +4 -4
- package/docs/README.zh.md +4 -4
- package/docs/agent-notes/image-results-visible-answer.md +7 -0
- package/docs/agent-notes/windows-proxy-compressed-fetch.md +7 -0
- package/docs/design.md +2 -0
- package/docs/release-notes/alpha-4.45.md +21 -0
- package/docs/release-notes/alpha-4.46.md +21 -0
- package/lib/bin.js +1 -1
- package/lib/client.js +110 -27
- package/lib/index.js +37 -1
- package/package.json +4 -1
package/INSTALL.md
CHANGED
|
@@ -4,7 +4,7 @@ Published Alpha 4.43 is verified with the exact DSH `0.1.7-rc.1` model-runtime p
|
|
|
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
|
|
|
7
|
-
Channel snapshot on 2026-09-24: npm `alpha`
|
|
7
|
+
Channel snapshot on 2026-09-24: npm `alpha` and `latest` both point to `0.1.0-alpha.4.45`. Use the exact-version command for the installed DSH version. Publishing an Alpha and promoting the default installation channel are separate actions.
|
|
8
8
|
|
|
9
9
|
## Safety requirements
|
|
10
10
|
|
|
@@ -30,7 +30,7 @@ Check `dsh --version` before changing the requested profile. Use `dsh --help` to
|
|
|
30
30
|
| `0.1.5-alpha.1` | `0.1.0-alpha.4.41` |
|
|
31
31
|
| `0.1.5-rc.1` | `0.1.0-alpha.4.41` |
|
|
32
32
|
| `0.1.5-rc.2` | `0.1.0-alpha.4.41` |
|
|
33
|
-
| `0.1.7-rc.1` | `0.1.0-alpha.4.
|
|
33
|
+
| `0.1.7-rc.1` | `0.1.0-alpha.4.45` |
|
|
34
34
|
|
|
35
35
|
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.
|
|
36
36
|
|
|
@@ -76,7 +76,7 @@ Alpha 4.33 omits the `modelErrors` profile field required by RC model packages,
|
|
|
76
76
|
For the exact DSH `0.1.7-rc.1` pairing, use Alpha 4.43:
|
|
77
77
|
|
|
78
78
|
```sh
|
|
79
|
-
dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.
|
|
79
|
+
dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.45
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
For DSH `0.1.2-alpha.5`, use Alpha 4.25:
|
|
@@ -85,7 +85,7 @@ Alpha 4.33 omits the `modelErrors` profile field required by RC model packages,
|
|
|
85
85
|
dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.25
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
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, `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.41'` only for the DSH `0.1.2-rc.1`, `0.1.5-alpha.1`, `0.1.5-rc.1`, and `0.1.5-rc.2` combinations, or `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.
|
|
88
|
+
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, `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.41'` only for the DSH `0.1.2-rc.1`, `0.1.5-alpha.1`, `0.1.5-rc.1`, and `0.1.5-rc.2` combinations, or `dsh plugin --profile web add 'github:franksong2702/dsh-codex-connect#v0.1.0-alpha.4.45'` only for DSH `0.1.7-rc.1`.
|
|
89
89
|
|
|
90
90
|
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.
|
|
91
91
|
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:
|
|
6
|
-
docs/README.zh.md:
|
|
5
|
+
README.md: 3dd09c3af313022796d95809cad3b53130eb6a1a
|
|
6
|
+
docs/README.zh.md: 3c5b9bf71227a795131522821424574b72d24088
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ This guide describes the published pairing below. Check `dsh --version` first an
|
|
|
16
16
|
|
|
17
17
|
| Requirement | Verified pairing |
|
|
18
18
|
|---|---|
|
|
19
|
-
| Codex Connect | `0.1.0-alpha.4.
|
|
19
|
+
| Codex Connect | `0.1.0-alpha.4.45` |
|
|
20
20
|
| DeepSeek Harness | `0.1.7-rc.1` |
|
|
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 |
|
|
@@ -28,7 +28,7 @@ On stock DSH `0.1.7-rc.1`, ordinary Composer works, but Task controls remain pau
|
|
|
28
28
|
### 1. Install
|
|
29
29
|
|
|
30
30
|
```sh
|
|
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.45
|
|
32
32
|
dsh web
|
|
33
33
|
```
|
|
34
34
|
|
|
@@ -75,7 +75,7 @@ All options below are off on a fresh installation. Edit them in **Settings → P
|
|
|
75
75
|
|
|
76
76
|
| Capability | Enable with | Important behavior |
|
|
77
77
|
|---|---|---|
|
|
78
|
-
| Proxy | `enableProxy` | Credential-free HTTP(S), scoped to this plugin's traffic. A failed proxy request does not silently retry directly. |
|
|
78
|
+
| Proxy | `enableProxy` | Credential-free HTTP(S), scoped to this plugin's traffic, including compressed OAuth and quota responses. Unrelated Fetch calls retain the host's original transport. A failed proxy request does not silently retry directly. |
|
|
79
79
|
| Codex Search | `enableSearch` | Selects Codex for the entire profile's search route; disabling restores the previously active route. |
|
|
80
80
|
| 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`. |
|
|
81
81
|
| Image viewing | `enableImageTool` | Adds `view_image` to vision-capable models for local files and validated public HTTP(S) images. |
|
|
@@ -86,7 +86,7 @@ All options below are off on a fresh installation. Edit them in **Settings → P
|
|
|
86
86
|
|
|
87
87
|
With `enableReserveFallback: true`, the account UI and agent routing share one identity-bound quota state. Background refresh follows the returned quota windows while recently in use; fresh state is reused across agent steps. Ordinary quota reads also share the cache, even with Reserve disabled. 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.
|
|
88
88
|
|
|
89
|
-
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.
|
|
89
|
+
Use the image generation capability included with your current GPT subscription. Successful images appear below the conversation answer without opening its processing details; the original tool card remains available there. 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.
|
|
90
90
|
|
|
91
91
|
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.
|
|
92
92
|
|
package/docs/README.zh.md
CHANGED
|
@@ -16,7 +16,7 @@ Codex Connect 为标准 Harness agent loop 添加 `openai-codex` 模型提供方
|
|
|
16
16
|
|
|
17
17
|
| 要求 | 已验证组合 |
|
|
18
18
|
|---|---|
|
|
19
|
-
| Codex Connect | `0.1.0-alpha.4.
|
|
19
|
+
| Codex Connect | `0.1.0-alpha.4.45` |
|
|
20
20
|
| DeepSeek Harness | `0.1.7-rc.1` |
|
|
21
21
|
| Node.js | `^22.19.0 \|\| >=24.0.0` |
|
|
22
22
|
| 账户 | 通过 ChatGPT OAuth 使用所请求的 Codex 模型;可用性由 OpenAI 决定 |
|
|
@@ -28,7 +28,7 @@ Codex Connect 为标准 Harness agent loop 添加 `openai-codex` 模型提供方
|
|
|
28
28
|
### 1. 安装
|
|
29
29
|
|
|
30
30
|
```sh
|
|
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.45
|
|
32
32
|
dsh web
|
|
33
33
|
```
|
|
34
34
|
|
|
@@ -75,7 +75,7 @@ Alpha 4.40 还会在旧提供方目录缺失时补充 `gpt-6-sol` 和 `gpt-6-lun
|
|
|
75
75
|
|
|
76
76
|
| 能力 | 启用字段 | 重要行为 |
|
|
77
77
|
|---|---|---|
|
|
78
|
-
| 代理 | `enableProxy` | 不带凭据的 HTTP(S)
|
|
78
|
+
| 代理 | `enableProxy` | 不带凭据的 HTTP(S),只作用于本插件流量,包括压缩的 OAuth 和额度响应;无关的 Fetch 请求仍使用宿主原来的传输方式。代理请求失败不会静默改走直连。 |
|
|
79
79
|
| Codex 搜索 | `enableSearch` | 将整个 profile 的搜索路由切换为 Codex;关闭后恢复之前的路由。 |
|
|
80
80
|
| Luna Reserve | `enableReserveFallback` | 只在服务端为当前已固定账户明确授权时使用隐藏的 Reserve 路由;不修改全局默认模型,也不因普通 `429` 重试。 |
|
|
81
81
|
| 图片查看 | `enableImageTool` | 为视觉模型添加 `view_image`,读取本地文件和经过校验的公网 HTTP(S) 图片。 |
|
|
@@ -86,7 +86,7 @@ Alpha 4.40 还会在旧提供方目录缺失时补充 `gpt-6-sol` 和 `gpt-6-lun
|
|
|
86
86
|
|
|
87
87
|
启用 `enableReserveFallback: true` 后,账户 UI 和 agent 路由共用一份绑定身份的额度状态,最近有使用需求时按服务端返回的额度窗口后台刷新;有效状态可跨 agent step 复用。普通额度读取也共用缓存,即使 Reserve 已关闭。只有身份完整、非 FedRAMP 且服务端授权时,插件才进入 `gpt-reserve`;普通额度确认恢复后,切回该会话先前的模型和推理强度。Reserve 有自己的额度,不出现在模型选择器中,也不是无限额度。资格由服务端决定,重置时间本身不授权切换。当前版本只支持已知的 `gpt-5.6-luna` 元数据。刷新、身份和验证限制见 [Luna Reserve 回退](reference.zh.md#luna-reserve-回退)。
|
|
88
88
|
|
|
89
|
-
使用你当前 GPT
|
|
89
|
+
使用你当前 GPT 订阅计划提供的图片生成能力。成功生成的图片会显示在对话回复下方,无需展开处理过程;原工具卡片仍保留在处理过程里。生成原文件与附件预览分开保存;关闭能力或卸载插件不会删除这些文件。存储和访问规则见[配置与恢复](reference.zh.md#搜索与图片工具)。
|
|
90
90
|
|
|
91
91
|
自动审查在 Harness 策略判定需要审批后执行,不会绕过该策略。启用前请阅读[自动审查行为](auto-review.zh.md)。
|
|
92
92
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Image results in the answer
|
|
2
|
+
|
|
3
|
+
DSH 0.1.7-rc.1 groups Tool calls inside a completed Turn's collapsed processing disclosure. Codex Connect rendered generated images only through its keyed Tool view, so a successful image could remain invisible until the reader expanded that disclosure. The final Assistant message contains text rather than a second image block; the image bytes and preview reference were not missing.
|
|
4
|
+
|
|
5
|
+
The browser plugin now adds a `conversation.chat.turnTail` entry. That Host-owned location is independent of the processing disclosure. It observes only the current Turn's Tool rows, including nested PTC results and result-only history windows, and reuses the same validated image presentation and complete result card. The original Tool view remains in processing details. The plugin does not write a duplicate Assistant message or copy image bytes into the Session log.
|
|
6
|
+
|
|
7
|
+
The regression test first failed because the completed Turn had no visible gallery. It now checks direct and nested successful results, filtering of failed and unrelated calls, closing-sequence exclusion, and the visible gallery with no expanded processing state. A headless Chromium check confirms the image and download action are visible outside any hidden processing content. Acceptance on an isolated live DSH instance remains separate from these synthetic tests.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Keep compressed Fetch responses decodable through the Codex proxy
|
|
2
|
+
|
|
3
|
+
On Windows with Node 24, the plugin's npm Undici 8 `ProxyAgent` can serve Node's built-in Fetch through its legacy v1 dispatcher bridge, but the returned response may lose `content-encoding` while retaining gzip bytes. The resulting HTTP 200 fails JSON parsing during OAuth exchange or quota refresh. A credential-free Windows probe reproduced `content-encoding: null` and the gzip magic bytes with the published Alpha 4.45 package. The equivalent macOS probe succeeded; local macOS tests alone do not prove the Windows path.
|
|
4
|
+
|
|
5
|
+
The proxy manager now routes Fetch calls made inside its `AsyncLocalStorage` scope through the same npm Undici runtime that owns its proxy agent. Outside that scope, the original host Fetch remains the fallback. The wrapper is installed only while a proxy manager owns it, follows a third-party Fetch replacement on the next acquisition, and restores the previous function on final disposal if still owned. Native `Request` instances are converted into their URL and request options because npm Undici's separate `Request` class does not accept them directly. The existing legacy dispatcher bridge remains for other Node HTTP clients; this fix does not alter direct requests or retry a failed proxy request without the proxy.
|
|
6
|
+
|
|
7
|
+
The keyless test serves gzip JSON through a local CONNECT proxy, checks both URL and native `Request` inputs, confirms the proxy was used, and checks Fetch restoration. PR CI runs that test on Windows Node 24.15.0 in addition to Ubuntu. It does not use real OAuth credentials or prove a browser login until the patched plugin is installed and exercised there.
|
package/docs/design.md
CHANGED
|
@@ -40,6 +40,8 @@ When `enableImageTool: true`, `view_image` is registered only after tools, files
|
|
|
40
40
|
|
|
41
41
|
Each remote-image redirect hop has one 30-second deadline covering DNS, connection, and body consumption. Cancellation settles the caller's wait immediately; an operating-system DNS lookup may still finish later, but its result cannot start a new HTTP request after cancellation or timeout.
|
|
42
42
|
|
|
43
|
+
Successful Codex image-generation Tool results also render in the independent completed-Turn tail. DSH groups Tool calls into a collapsed processing disclosure, so the keyed Tool card alone cannot make generated images visible with the answer. The tail reads only this Turn's settled Tool rows, including nested PTC calls and restored history, and uses the same validated result metadata, session-bound preview loader, Lightbox, and download controls as the Tool card. Failed, malformed, unrelated, or post-answer results do not enter the visible image row. The Tool card remains available in processing details.
|
|
44
|
+
|
|
43
45
|
## Conflicts and diagnostics
|
|
44
46
|
|
|
45
47
|
Before registration the plugin checks current provider ids. An existing `openai-codex` adapter produces a focused message naming the likely legacy-bundle or manual-provider cause. The boot-free CLI `doctor` reports package/runtime version, OAuth path metadata, capability defaults, and safe conflict guidance without returning auth content.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Codex Connect Alpha 4.45 — generated images visible in answers
|
|
2
|
+
|
|
3
|
+
## English
|
|
4
|
+
|
|
5
|
+
Generated images now appear below a completed answer without opening the collapsed processing details. The existing Tool result remains available inside those details, including its original-image download and follow-up controls. The answer view uses the same validated image result and attachment access; it does not generate a second image, alter the provider request, or duplicate image bytes in the Session log.
|
|
6
|
+
|
|
7
|
+
This release targets DeepSeek Harness `0.1.7-rc.1`. The fix passed local unit and Chromium tests, and the reporter confirmed the visible result on an isolated 3081 instance. That review did not send a new image-generation request or validate other DSH versions. Preparing this package does not upgrade existing installations; publication and the npm `latest` promotion are separately verified steps.
|
|
8
|
+
|
|
9
|
+
After npm publication is confirmed, install the exact version with:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.45
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 中文
|
|
16
|
+
|
|
17
|
+
生成的图片现在会显示在已完成回复的下方,不必展开折叠的“处理过程”。原有 Tool 结果仍保留在处理详情中,包括原图下载和后续操作。回复区域复用同一份已验证的图片结果与附件访问,不会再次生图、改变 Provider 请求,也不会在 Session 日志中复制图片数据。
|
|
18
|
+
|
|
19
|
+
本版针对 DeepSeek Harness `0.1.7-rc.1`。修复已通过本地单元测试和 Chromium 测试,并由报告者在隔离的 3081 实例上确认图片可见。该次验收没有发起新的真实生图请求,也不代表验证了其他 DSH 版本。准备安装包不会升级现有实例;发布和 npm `latest` 提升分别核验。
|
|
20
|
+
|
|
21
|
+
确认 npm 发布后,可使用上面的精确版本命令安装。
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Codex Connect Alpha 4.46 — Windows proxy response decoding
|
|
2
|
+
|
|
3
|
+
## English
|
|
4
|
+
|
|
5
|
+
When the optional Codex proxy is enabled on Windows, Alpha 4.45 can receive a successful compressed response but expose its gzip bytes without the encoding header. OAuth token exchange or quota refresh can then fail while parsing JSON. Alpha 4.46 routes Fetch calls inside the plugin's proxy scope through the same Undici runtime as its proxy agent; unrelated Fetch calls keep the host's original transport. A failed proxy request still does not retry directly.
|
|
6
|
+
|
|
7
|
+
This release targets DeepSeek Harness `0.1.7-rc.1`. The published 4.45 failure was reproduced without credentials on a Windows PC. The fix passed keyless Windows CI, including compressed JSON and proxy ownership checks. Real Chrome OAuth and quota refresh with the patched package on that PC remain unverified. This release does not address the separate, still-unconfirmed message-source report in Issue #261. Publishing to `alpha` does not promote npm `latest` or install the plugin in an existing profile.
|
|
8
|
+
|
|
9
|
+
After npm publication is independently confirmed, install this exact version with:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
dsh plugin --profile web add dsh-codex-connect@0.1.0-alpha.4.46
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 中文
|
|
16
|
+
|
|
17
|
+
在 Windows 上启用可选的 Codex 代理时,Alpha 4.45 可能收到成功的压缩响应,却丢失编码标头、把 gzip 原始字节交给调用方,导致 OAuth 换取凭据或额度刷新在解析 JSON 时失败。Alpha 4.46 让插件代理作用域内的 Fetch 使用与代理组件相同的 Undici 运行时;无关的 Fetch 仍使用宿主原有传输方式。代理请求失败时仍不会静默改走直连。
|
|
18
|
+
|
|
19
|
+
本版针对 DeepSeek Harness `0.1.7-rc.1`。已在 Windows PC 上不使用凭据复现发布版 4.45 的故障;修复通过了无凭据的 Windows CI,包括压缩 JSON 和代理所有权测试。该 PC 上安装修复包后的真实 Chrome OAuth 与额度刷新仍未验收。本版不处理 Issue #261 尚未确认的消息来源报告。发布到 `alpha` 不会同步提升 npm `latest`,也不会自动安装到现有 profile。
|
|
20
|
+
|
|
21
|
+
独立确认 npm 发布后,可使用上面的精确版本命令安装。
|
package/lib/bin.js
CHANGED
|
@@ -765,7 +765,7 @@ async function detectCompatibility(options = {}) {
|
|
|
765
765
|
}
|
|
766
766
|
//#endregion
|
|
767
767
|
//#region src/version.ts
|
|
768
|
-
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.
|
|
768
|
+
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.46";
|
|
769
769
|
//#endregion
|
|
770
770
|
//#region src/doctor.ts
|
|
771
771
|
/** Secret-free diagnostics and duplicate-provider guidance. */
|
package/lib/client.js
CHANGED
|
@@ -5376,6 +5376,35 @@ window.__ModuleLoader__.load({
|
|
|
5376
5376
|
};
|
|
5377
5377
|
}
|
|
5378
5378
|
//#endregion
|
|
5379
|
+
//#region src/client/image-result-presentation.ts
|
|
5380
|
+
const IMAGE_TOOL = "codex_connect_image_generate";
|
|
5381
|
+
function promptFromArgs(raw) {
|
|
5382
|
+
try {
|
|
5383
|
+
const value = JSON.parse(raw);
|
|
5384
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
5385
|
+
const prompt = value.prompt;
|
|
5386
|
+
if (typeof prompt !== "string") return void 0;
|
|
5387
|
+
const trimmed = prompt.trim();
|
|
5388
|
+
return trimmed.length > 0 && trimmed.length <= 32e3 ? trimmed : void 0;
|
|
5389
|
+
} catch {
|
|
5390
|
+
return;
|
|
5391
|
+
}
|
|
5392
|
+
}
|
|
5393
|
+
/** Return the bounded prompt that belongs to this image Tool row. */
|
|
5394
|
+
function promptForImageToolBlock(block) {
|
|
5395
|
+
if (!("kind" in block)) return block.phase === "start" ? promptFromArgs(block.argsRaw) : void 0;
|
|
5396
|
+
const decoded = decodeImagePresentationMeta(block.meta);
|
|
5397
|
+
if (decoded !== void 0) return decoded.prompt;
|
|
5398
|
+
return block.call === null ? void 0 : promptFromArgs(block.call.argsRaw);
|
|
5399
|
+
}
|
|
5400
|
+
/** Only a successful image Tool result can enter the visible answer gallery. */
|
|
5401
|
+
function imagePresentationForResult(block) {
|
|
5402
|
+
if (block.isError || block.call !== null && block.call.name !== IMAGE_TOOL) return void 0;
|
|
5403
|
+
if (block.meta !== void 0) return decodeImagePresentationMeta(block.meta);
|
|
5404
|
+
const prompt = promptForImageToolBlock(block);
|
|
5405
|
+
return prompt === void 0 ? void 0 : decodeImageResultContent(block.content, prompt);
|
|
5406
|
+
}
|
|
5407
|
+
//#endregion
|
|
5379
5408
|
//#region src/client/CodexImageGallery.tsx
|
|
5380
5409
|
/** Self-contained result-image gallery for the tool-call view.
|
|
5381
5410
|
*
|
|
@@ -5887,30 +5916,6 @@ window.__ModuleLoader__.load({
|
|
|
5887
5916
|
function contentText(content) {
|
|
5888
5917
|
for (const block of content) if (typeof block === "object" && block !== null && block.type === "text" && typeof block.text === "string") return block.text;
|
|
5889
5918
|
}
|
|
5890
|
-
function presentation(block) {
|
|
5891
|
-
if (!("kind" in block) || block.kind !== "tool-result" || block.isError) return void 0;
|
|
5892
|
-
if (block.meta !== void 0) return decodeImagePresentationMeta(block.meta);
|
|
5893
|
-
const prompt = promptFor(block);
|
|
5894
|
-
return prompt === void 0 ? void 0 : decodeImageResultContent(block.content, prompt);
|
|
5895
|
-
}
|
|
5896
|
-
function promptFromArgs(raw) {
|
|
5897
|
-
try {
|
|
5898
|
-
const value = JSON.parse(raw);
|
|
5899
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
5900
|
-
const prompt = value.prompt;
|
|
5901
|
-
if (typeof prompt !== "string") return void 0;
|
|
5902
|
-
const trimmed = prompt.trim();
|
|
5903
|
-
return trimmed.length > 0 && trimmed.length <= 32e3 ? trimmed : void 0;
|
|
5904
|
-
} catch {
|
|
5905
|
-
return;
|
|
5906
|
-
}
|
|
5907
|
-
}
|
|
5908
|
-
function promptFor(block) {
|
|
5909
|
-
if (!("kind" in block)) return promptFromArgs(block.argsRaw);
|
|
5910
|
-
const decoded = decodeImagePresentationMeta(block.meta);
|
|
5911
|
-
if (decoded !== void 0) return decoded.prompt;
|
|
5912
|
-
return block.call === null ? void 0 : promptFromArgs(block.call.argsRaw);
|
|
5913
|
-
}
|
|
5914
5919
|
function useSessionActions(sessionId, sessions) {
|
|
5915
5920
|
const [pending, setPending] = (0, react.useState)(null);
|
|
5916
5921
|
const [failed, setFailed] = (0, react.useState)(false);
|
|
@@ -6246,8 +6251,8 @@ window.__ModuleLoader__.load({
|
|
|
6246
6251
|
const load = useImageLoader(sessionId, sessions);
|
|
6247
6252
|
const sessionActions = useSessionActions(sessionId, sessions);
|
|
6248
6253
|
const galleryLabels = (0, react.useMemo)(() => labels(t), [t]);
|
|
6249
|
-
const prompt =
|
|
6250
|
-
const decoded = (0, react.useMemo)(() =>
|
|
6254
|
+
const prompt = promptForImageToolBlock(block);
|
|
6255
|
+
const decoded = (0, react.useMemo)(() => "kind" in block ? imagePresentationForResult(block) : void 0, [block]);
|
|
6251
6256
|
if (!("kind" in block)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResponsiveCard, {
|
|
6252
6257
|
label: t("generating"),
|
|
6253
6258
|
visual: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -6339,6 +6344,32 @@ window.__ModuleLoader__.load({
|
|
|
6339
6344
|
children: t("unknownResult")
|
|
6340
6345
|
})]
|
|
6341
6346
|
});
|
|
6347
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImageResultCard, {
|
|
6348
|
+
decoded,
|
|
6349
|
+
sessionId,
|
|
6350
|
+
load,
|
|
6351
|
+
sessionActions,
|
|
6352
|
+
galleryLabels,
|
|
6353
|
+
t
|
|
6354
|
+
});
|
|
6355
|
+
}
|
|
6356
|
+
/** Render the same complete result controls in the independent answer tail. */
|
|
6357
|
+
function CodexImageTurnResult({ block, sessionId, sessions, t }) {
|
|
6358
|
+
const load = useImageLoader(sessionId, sessions);
|
|
6359
|
+
const sessionActions = useSessionActions(sessionId, sessions);
|
|
6360
|
+
const galleryLabels = (0, react.useMemo)(() => labels(t), [t]);
|
|
6361
|
+
const decoded = (0, react.useMemo)(() => imagePresentationForResult(block), [block]);
|
|
6362
|
+
if (decoded === void 0) return null;
|
|
6363
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImageResultCard, {
|
|
6364
|
+
decoded,
|
|
6365
|
+
sessionId,
|
|
6366
|
+
load,
|
|
6367
|
+
sessionActions,
|
|
6368
|
+
galleryLabels,
|
|
6369
|
+
t
|
|
6370
|
+
});
|
|
6371
|
+
}
|
|
6372
|
+
function ImageResultCard({ decoded, sessionId, load, sessionActions, galleryLabels, t }) {
|
|
6342
6373
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResponsiveCard, {
|
|
6343
6374
|
label: t("completed"),
|
|
6344
6375
|
visual: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -6449,8 +6480,53 @@ window.__ModuleLoader__.load({
|
|
|
6449
6480
|
});
|
|
6450
6481
|
}
|
|
6451
6482
|
//#endregion
|
|
6483
|
+
//#region src/client/CodexImageTurnTail.tsx
|
|
6484
|
+
/** Visible generated-image results after a completed conversation turn. */
|
|
6485
|
+
const resultStack = {
|
|
6486
|
+
display: "grid",
|
|
6487
|
+
gap: 12,
|
|
6488
|
+
minWidth: 0
|
|
6489
|
+
};
|
|
6490
|
+
/** Keep successful image results from this turn, including nested PTC calls. */
|
|
6491
|
+
function selectTurnImageResults(rows, closingSeq) {
|
|
6492
|
+
const images = [];
|
|
6493
|
+
for (const row of rows) {
|
|
6494
|
+
const pending = [row.root];
|
|
6495
|
+
const visited = /* @__PURE__ */ new Set();
|
|
6496
|
+
while (pending.length > 0) {
|
|
6497
|
+
const block = pending.pop();
|
|
6498
|
+
if (block === void 0 || visited.has(block.callId)) continue;
|
|
6499
|
+
visited.add(block.callId);
|
|
6500
|
+
if ("kind" in block && block.seq <= closingSeq && imagePresentationForResult(block) !== void 0) images.push(block);
|
|
6501
|
+
for (let index = block.subCalls.length - 1; index >= 0; index--) {
|
|
6502
|
+
const child = block.subCalls[index];
|
|
6503
|
+
if (child !== void 0) pending.push(child);
|
|
6504
|
+
}
|
|
6505
|
+
}
|
|
6506
|
+
}
|
|
6507
|
+
return images.sort((left, right) => left.seq - right.seq);
|
|
6508
|
+
}
|
|
6509
|
+
/** Put generated images in the independent answer tail, outside Turn-process disclosure. */
|
|
6510
|
+
function CodexImageTurnTail({ turn, seq, sessionId, useChat, sessions, t }) {
|
|
6511
|
+
const source = useChat((chat) => chat.nodes.turnDataSource(turn.turn, "tool-call"));
|
|
6512
|
+
const rows = (0, react.useSyncExternalStore)(source.subscribe, source.getSnapshot, source.getSnapshot);
|
|
6513
|
+
const results = (0, react.useMemo)(() => selectTurnImageResults(rows, seq), [rows, seq]);
|
|
6514
|
+
if (results.length === 0) return null;
|
|
6515
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
6516
|
+
"data-turn-image-results": "",
|
|
6517
|
+
"aria-label": t("completed"),
|
|
6518
|
+
style: resultStack,
|
|
6519
|
+
children: results.map((block) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodexImageTurnResult, {
|
|
6520
|
+
block,
|
|
6521
|
+
sessionId,
|
|
6522
|
+
sessions,
|
|
6523
|
+
t
|
|
6524
|
+
}, block.callId))
|
|
6525
|
+
});
|
|
6526
|
+
}
|
|
6527
|
+
//#endregion
|
|
6452
6528
|
//#region src/version.ts
|
|
6453
|
-
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.
|
|
6529
|
+
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.46";
|
|
6454
6530
|
//#endregion
|
|
6455
6531
|
//#region src/client/OpenAICodexModelsCard.tsx
|
|
6456
6532
|
/** Compact Models account entry with quota disclosure and shared configuration. */
|
|
@@ -7120,6 +7196,13 @@ window.__ModuleLoader__.load({
|
|
|
7120
7196
|
locale: namespace,
|
|
7121
7197
|
inject: () => ({ sessions: ctx.sessions })
|
|
7122
7198
|
}, CodexImageToolView));
|
|
7199
|
+
ctx.slots.inject("conversation.chat.turnTail", () => ctx.slots.register({
|
|
7200
|
+
name: "conversation.chat.turnTail",
|
|
7201
|
+
id: "codex-connect-generated-images",
|
|
7202
|
+
order: 20,
|
|
7203
|
+
locale: namespace,
|
|
7204
|
+
inject: () => ({ sessions: ctx.sessions })
|
|
7205
|
+
}, CodexImageTurnTail));
|
|
7123
7206
|
ctx.inject(["slots", "modelDirectories"], (scope) => {
|
|
7124
7207
|
scope.slots.inject("conversation.input.right", () => scope.slots.register({
|
|
7125
7208
|
name: "conversation.input.right",
|
package/lib/index.js
CHANGED
|
@@ -4184,6 +4184,37 @@ let previousDispatcher;
|
|
|
4184
4184
|
const legacySymbol = Symbol.for("undici.globalDispatcher.1");
|
|
4185
4185
|
let installedLegacy;
|
|
4186
4186
|
let previousLegacy;
|
|
4187
|
+
let installedFetch;
|
|
4188
|
+
let previousFetch;
|
|
4189
|
+
const scopedUndiciFetch = fetch$1;
|
|
4190
|
+
function installScopedFetch(fallback) {
|
|
4191
|
+
previousFetch = fallback;
|
|
4192
|
+
installedFetch = (input, init) => {
|
|
4193
|
+
if (proxyScope.getStore() === void 0) return fallback(input, init);
|
|
4194
|
+
if (input instanceof Request) {
|
|
4195
|
+
const request = new Request(input, init);
|
|
4196
|
+
return scopedUndiciFetch(request.url, {
|
|
4197
|
+
method: request.method,
|
|
4198
|
+
headers: request.headers,
|
|
4199
|
+
signal: request.signal,
|
|
4200
|
+
redirect: request.redirect,
|
|
4201
|
+
cache: request.cache,
|
|
4202
|
+
credentials: request.credentials,
|
|
4203
|
+
integrity: request.integrity,
|
|
4204
|
+
keepalive: request.keepalive,
|
|
4205
|
+
mode: request.mode,
|
|
4206
|
+
referrer: request.referrer,
|
|
4207
|
+
referrerPolicy: request.referrerPolicy,
|
|
4208
|
+
...request.body === null ? {} : {
|
|
4209
|
+
body: request.body,
|
|
4210
|
+
duplex: "half"
|
|
4211
|
+
}
|
|
4212
|
+
});
|
|
4213
|
+
}
|
|
4214
|
+
return scopedUndiciFetch(input, init);
|
|
4215
|
+
};
|
|
4216
|
+
globalThis.fetch = installedFetch;
|
|
4217
|
+
}
|
|
4187
4218
|
function installLegacy(fallback, bridge) {
|
|
4188
4219
|
previousLegacy = fallback;
|
|
4189
4220
|
installedLegacy = { dispatch: (...args) => {
|
|
@@ -4199,6 +4230,7 @@ function ensureInstalled(owner) {
|
|
|
4199
4230
|
installedDispatcher = new ScopedProxyDispatcher(current);
|
|
4200
4231
|
setGlobalDispatcher(installedDispatcher);
|
|
4201
4232
|
installLegacy(legacy, Reflect.get(globalThis, legacySymbol));
|
|
4233
|
+
installScopedFetch(globalThis.fetch);
|
|
4202
4234
|
} else if (current !== installedDispatcher) {
|
|
4203
4235
|
installedDispatcher = new ScopedProxyDispatcher(current);
|
|
4204
4236
|
previousDispatcher = current;
|
|
@@ -4208,6 +4240,7 @@ function ensureInstalled(owner) {
|
|
|
4208
4240
|
setGlobalDispatcher(installedDispatcher);
|
|
4209
4241
|
installLegacy(legacy, Reflect.get(globalThis, legacySymbol));
|
|
4210
4242
|
}
|
|
4243
|
+
if (globalThis.fetch !== installedFetch) installScopedFetch(globalThis.fetch);
|
|
4211
4244
|
activeOwners.add(owner);
|
|
4212
4245
|
}
|
|
4213
4246
|
function removeOwner(owner) {
|
|
@@ -4221,8 +4254,11 @@ function removeOwner(owner) {
|
|
|
4221
4254
|
previousDispatcher = void 0;
|
|
4222
4255
|
if (getGlobalDispatcher() === installed && previous !== void 0) setGlobalDispatcher(previous);
|
|
4223
4256
|
if (restoreLegacy !== void 0) Reflect.set(globalThis, legacySymbol, restoreLegacy);
|
|
4257
|
+
if (globalThis.fetch === installedFetch && previousFetch !== void 0) globalThis.fetch = previousFetch;
|
|
4224
4258
|
installedLegacy = void 0;
|
|
4225
4259
|
previousLegacy = void 0;
|
|
4260
|
+
installedFetch = void 0;
|
|
4261
|
+
previousFetch = void 0;
|
|
4226
4262
|
}
|
|
4227
4263
|
function isPromiseLike(value) {
|
|
4228
4264
|
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
@@ -5294,7 +5330,7 @@ function registerOpenAICodexOriginalImageRoute(ctx, trustedOrigins, assets) {
|
|
|
5294
5330
|
}
|
|
5295
5331
|
//#endregion
|
|
5296
5332
|
//#region src/version.ts
|
|
5297
|
-
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.
|
|
5333
|
+
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.46";
|
|
5298
5334
|
//#endregion
|
|
5299
5335
|
//#region src/doctor.ts
|
|
5300
5336
|
/** Secret-free diagnostics and duplicate-provider guidance. */
|
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.46",
|
|
6
6
|
"author": "Frank Song",
|
|
7
7
|
"contributors": [
|
|
8
8
|
"Yan-Zero (original dsh-codex author)"
|
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
"@deepseek-ai/dsh-api-session-controller",
|
|
98
98
|
"@deepseek-ai/dsh-client-ui-layout",
|
|
99
99
|
"@deepseek-ai/dsh-client-ui-conversation",
|
|
100
|
+
"@deepseek-ai/dsh-client-ui-chat",
|
|
100
101
|
"@deepseek-ai/dsh-client-ui-model-selection",
|
|
101
102
|
"@deepseek-ai/dsh-client-ui-settings",
|
|
102
103
|
"@deepseek-ai/dsh-client-ui-settings-plugins",
|
|
@@ -111,6 +112,7 @@
|
|
|
111
112
|
"@deepseek-ai/dsh-agent": "0.1.7-rc.1",
|
|
112
113
|
"@deepseek-ai/dsh-atomic-write": "0.1.7-rc.1",
|
|
113
114
|
"@deepseek-ai/dsh-attachment": "0.1.7-rc.1",
|
|
115
|
+
"@deepseek-ai/dsh-client-ui-chat": "0.1.7-rc.1",
|
|
114
116
|
"@deepseek-ai/dsh-client-ui-layout": "0.1.7-rc.1",
|
|
115
117
|
"@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.1",
|
|
116
118
|
"@deepseek-ai/dsh-client-ui-tool": "0.1.7-rc.1",
|
|
@@ -153,6 +155,7 @@
|
|
|
153
155
|
"@deepseek-ai/dsh-client-connection": "0.1.7-rc.1",
|
|
154
156
|
"@deepseek-ai/dsh-client-locale": "0.1.7-rc.1",
|
|
155
157
|
"@deepseek-ai/dsh-client-store": "0.1.7-rc.1",
|
|
158
|
+
"@deepseek-ai/dsh-client-ui-chat": "0.1.7-rc.1",
|
|
156
159
|
"@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.1",
|
|
157
160
|
"@deepseek-ai/dsh-client-ui-layout": "0.1.7-rc.1",
|
|
158
161
|
"@deepseek-ai/dsh-client-ui-model-selection": "0.1.7-rc.1",
|