dsh-lcx-codex 0.4.3 → 0.5.0-pre.1

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/README.md CHANGED
@@ -4,120 +4,155 @@
4
4
 
5
5
  # LCX Codex
6
6
 
7
- **让 DeepSeek Harness 里的 GPT 与 Grok 更适合长任务、联网搜索和连续工作。**
7
+ **给 DeepSeek Harness 里的 GPT 和 Grok 加上联网搜索和长对话自动压缩。**
8
8
 
9
- [![npm](https://img.shields.io/npm/v/dsh-lcx-codex?label=latest)](https://www.npmjs.com/package/dsh-lcx-codex)
10
- [![DSH](https://img.shields.io/badge/DSH-0.1.5--rc.1-16803c)](#安装)
9
+ [![npm latest](https://img.shields.io/npm/v/dsh-lcx-codex/latest?label=latest)](https://www.npmjs.com/package/dsh-lcx-codex)
10
+ [![npm prelatest](https://img.shields.io/npm/v/dsh-lcx-codex/prelatest?label=prelatest&color=orange)](https://www.npmjs.com/package/dsh-lcx-codex?activeTab=versions)
11
11
  [![License](https://img.shields.io/badge/license-MIT-555)](LICENSE)
12
12
 
13
13
  **简体中文** · [English](README_EN.md) · [更新日志](CHANGELOG.md) · [问题反馈](https://github.com/kk3ya03-star/dsh-lcx-codex/issues)
14
14
 
15
15
  </div>
16
16
 
17
- LCX Codex 是 [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness)(DSH)的社区插件。
17
+ LCX Codex 是 [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness)(DSH)的社区插件。装上之后,你在 DSH 里用的 GPT 和 Grok 可以:
18
18
 
19
- 它不会替代 DSH,也不需要你重新配置模型、接口或 API Key。模型、凭据、会话和工具仍由 DSH 管理;LCX 只在需要时为 GPT 和 Grok 增加额外能力。
19
+ - **联网搜索**:GPT 使用 Responses 服务端搜索(Hosted Search),Grok 使用 xAI 原生 Web Search 和 X Search;
20
+ - **长任务不中断**:对话接近上下文上限时自动压缩并继续,不用手动开新会话;
21
+ - **直接看到图片和视频**:搜索返回的图片、回答里的图片直链排成一行显示在回答下方,点击用 DSH 自带的看图器放大;视频直链显示为卡片,点击后在回答里直接播放。
20
22
 
21
- ## 你可以用它做什么
23
+ 模型、API Key、会话和其他工具仍由 DSH 管理,不需要额外配置。其他模型(如 DeepSeek)照常走 DSH 自己的逻辑,不受影响。
22
24
 
23
- | 能力 | 适合场景 |
24
- | --- | --- |
25
- | GPT 联网搜索 | 让 GPT 直接通过 DSH 的 `web_search` 查询网页。 |
26
- | GPT 高级搜索 | 搜图片、限定网站、加入位置等额外搜索条件。 |
27
- | Grok 原生 Web / X Search | 直接使用 xAI Responses 的 Web Search 和 X Search。 |
28
- | 长对话压缩 | GPT 长任务接近上下文上限时自动尝试远程压缩,并继续当前会话。 |
29
- | 搜索媒体预览 | 在回答下方直接预览可用的图片和视频链接。 |
30
- | Alpha 网页操作 | 实验性连续网页阅读能力,适合需要进一步打开、查找页面内容的任务。 |
25
+ ## 使用前提
26
+
27
+ - 已安装 DSH,并在 DSH 中配置好 **GPT 或 Grok 的 Responses API 路由**(官方 API 或兼容网关均可)。
28
+ - Node.js `^22.19.0` 或 `>=24.0.0`。
31
29
 
32
- 其他模型继续使用 DSH 原生路径,不会因为安装 LCX 而被接管。
30
+ > 搜索和压缩依赖服务端能力。你的网关能正常聊天,不代表它一定支持这些功能,详见[已知限制](#已知限制)。
33
31
 
34
32
  ## 安装
35
33
 
36
- 当前稳定版:**`dsh-lcx-codex@0.4.3`**
34
+ ### 1. 按 DSH 版本选择插件版本
35
+
36
+ 先运行 `dsh --version` 查看 DSH 版本,再按下表选择:
37
+
38
+ | 你的 DSH 版本 | 安装的 LCX 版本 | 安装命令中的标签 |
39
+ | --- | --- | --- |
40
+ | `0.2.0` 系列(`0.2.0-rc.2` 及以后,低于 `0.2.1`) | `0.5.0-pre.1`(预发布版) | `@prelatest` |
41
+ | `0.1.6` 系列(`0.1.6-alpha.2` 及以后) | `0.4.4-pre.1`(旧预发布版) | `@0.4.4-pre.1` |
42
+ | `0.1.5` 系列(`0.1.5-rc.1` 及以后) | `0.4.3`(稳定版) | `@latest` |
43
+
44
+ 请务必按表格选择:三个版本互不兼容,装错版本时安装命令可能只给出依赖警告,但插件可能无法正常工作。`0.5.0-pre.1` 是预发布版,本次预发布的验收基线为 DSH `0.2.0-rc.2`(host / plugin Pi `0.87.1`)。
37
45
 
38
- 兼容环境:
46
+ ### 2. 安装并启动
39
47
 
40
- - DSH `0.1.5-rc.1` 起的 `0.1.5` 系列(当前完整验证基线:`0.1.5-rc.1`)
41
- - Node.js `^22.19.0 || >=24.0.0`
48
+ DSH `0.2.0` 系列:
49
+
50
+ ```sh
51
+ dsh plugin --profile web add dsh-lcx-codex@prelatest
52
+ dsh web
53
+ ```
42
54
 
43
- 安装:
55
+ DSH `0.1.6` 系列:
44
56
 
45
57
  ```sh
46
- dsh plugin --profile web add dsh-lcx-codex@0.4.3
58
+ dsh plugin --profile web add dsh-lcx-codex@0.4.4-pre.1
47
59
  dsh web
48
60
  ```
49
61
 
50
- 后续稳定版更新可以使用:
62
+ DSH `0.1.5` 系列:
51
63
 
52
64
  ```sh
53
65
  dsh plugin --profile web add dsh-lcx-codex@latest
66
+ dsh web
54
67
  ```
55
68
 
56
- 不指定版本或使用 `@latest` 都会安装当前稳定版。需要预发布版本时可使用 `@prelatest`;`0.4.3-pre.13` 作为本次正式版之前的已验证预发布历史继续保留。
69
+ 以后更新插件,重新运行同一条 `add` 命令即可。
70
+
71
+ ### 3. 打开功能开关
72
+
73
+ 打开 DSH Web 的插件页面,在 LCX 的配置卡片 **Responses / Codex 能力** 中按需打开下列开关,然后点击 **保存**。
74
+
75
+ <img src="https://raw.githubusercontent.com/kk3ya03-star/dsh-lcx-codex/main/assets/settings-card.png" alt="LCX 插件配置卡片" width="720" />
57
76
 
58
- 本版已在官方 DSH `0.1.5-rc.1` 完整验证。后续同一 `0.1.5` 系列版本可以直接安装并进行兼容评估,不再需要仅因为 RC 版本号变化而发布新的 LCX 版本。
77
+ **GPT**
59
78
 
60
- ## 启用功能
79
+ | 开关 | 作用 | 建议 |
80
+ | --- | --- | --- |
81
+ | **启用 LCX** | GPT 功能的总开关,包括长对话自动压缩 | 用 GPT 时打开 |
82
+ | **使用 GPT Hosted Search 作为 DSH web_search 后端** | GPT 联网搜索 | 需要联网时打开 |
83
+ | **启用高级 Hosted 工具** | 图片搜索、限定网站、指定位置等(需先打开上一项) | 按需 |
84
+ | **启用 Alpha command** | 实验功能:让 GPT 继续打开、查找搜索结果中的页面 | 日常不需要 |
61
85
 
62
- 打开 DSH Web 的插件设置,找到 **Responses / Codex 能力**。
86
+ **Grok 原生搜索**(与“启用 LCX”相互独立)
63
87
 
64
- ### 使用 GPT
88
+ | 开关 | 作用 |
89
+ | --- | --- |
90
+ | **启用原生 Web Search** | Grok 搜索网页 |
91
+ | **启用原生 X Search** | Grok 搜索 X 内容 |
65
92
 
66
- 通常打开:
93
+ 开启任一项后,Grok 改用 xAI 原生搜索;网页读取和其他 DSH / MCP 工具仍可正常使用。
67
94
 
68
- 1. **启用 LCX**
69
- 2. **GPT Hosted Search**(需要联网时)
95
+ **显示**
70
96
 
71
- 按需再打开:
97
+ | 开关 | 作用 |
98
+ | --- | --- |
99
+ | **搜索媒体预览** | 在回答下方显示搜索返回的图片、回答里的图片直链和可直接播放的视频直链;图片横排显示、点击放大,视频点击后在回答里播放。回答里用 Markdown 写的图片由 DSH 原生显示,不会重复;普通网页链接保持为链接。只改变界面显示,不影响发给模型的内容 |
72
100
 
73
- - **高级 Hosted 工具**:需要图片搜索、限定域名、位置等高级搜索条件时使用;它依赖 GPT Hosted Search。
74
- - **Alpha**:实验性网页连续操作。日常联网搜索不需要开启。
101
+ ## 怎么用
75
102
 
76
- ### 使用 Grok
103
+ 像平时一样和模型说话即可,不需要写任何工具参数:
77
104
 
78
- Grok 原生搜索与 GPT 的 LCX 主开关相互独立:
105
+ > 搜索 Python 官方文档,告诉我 `asyncio.TaskGroup` 应该怎么用。
79
106
 
80
- - **Grok 原生 Web Search**:搜索网页。
81
- - **Grok 原生 X Search**:搜索 X 内容。
107
+ > 搜几张金门大桥的照片,显示一张,并附上来源网页。
82
108
 
83
- 开启 Grok 原生搜索后,LCX 会使用 xAI 的服务端搜索能力,同时保留页面读取和其他 DSH / MCP 工具。
109
+ > 用 Grok 看看 X 上最近关于这个项目的讨论。
84
110
 
85
- ### 搜索媒体预览
111
+ 长对话会在接近上限时自动压缩;你也可以随时输入 `/compact` 手动压缩。
86
112
 
87
- **搜索媒体预览**可以独立开启。它只改变回答的显示方式,不会修改模型提示词、搜索请求、聊天历史或缓存。
113
+ ## 从旧版本升级
88
114
 
89
- 可识别的图片会显示缩略图并支持放大;直接视频链接可以点击播放。媒体加载失败时,原来的文字和链接仍会保留。
115
+ - **DSH 升级到 `0.2.0` 系列**:把插件换成 `@prelatest`(`0.5.0-pre.1`),旧版 `0.4.x` 不支持 DSH `0.2`。
116
+ - **DSH `0.1.6` 系列**:继续使用 `@0.4.4-pre.1`;`@prelatest` 现在指向支持 DSH `0.2` 的 `0.5.0-pre.1`。
117
+ - **升级后建议新建会话**:旧版本保存的压缩状态不保证兼容。DSH `0.2` 迁移过的旧长会话如果带有旧版 LCX 压缩检查点,LCX 会提示 `LCX_CHECKPOINT_UNSUPPORTED`,新建会话即可;其他模型不受影响。
90
118
 
91
- ## 常见用法
119
+ ## 停用与卸载
92
120
 
93
- 直接像平时一样和模型说话,不需要手写工具参数。例如:
121
+ - **临时停用**:在配置卡片中关闭 **启用 LCX** 和 Grok 原生搜索开关并保存,GPT 和 Grok 即恢复 DSH 原生行为。
122
+ - **卸载**:
94
123
 
95
- > 搜索 Python 官方文档,告诉我 `asyncio.TaskGroup` 应该怎么用。
124
+ ```sh
125
+ dsh plugin --profile web remove dsh-lcx-codex
126
+ ```
96
127
 
97
- > 搜索几张金门大桥的照片,显示一张,并给我来源网页。
128
+ ## 已知限制
98
129
 
99
- > 用 Grok 搜一下 X 上最近关于这个项目的讨论。
130
+ - **网关能力因人而异**:搜索、压缩、Alpha 都依赖对应的服务端能力,不同网关支持程度不同。
131
+ - **Grok**:支持 API Key / API 网关路由,不支持 xAI OAuth / SuperGrok 登录。原生 X Search 目前只在 `grok-4.6` 上验证过。
132
+ - **Grok 长对话压力**:xAI 的智能体调用会把多次内部请求的用量累加计费。`0.5.0-pre.1` 在服务端返回完整的实时上下文数据时,用它来判断何时压缩,缺失时退回估算;计费数字本身保持不变。
133
+ - **Alpha 仍是实验功能**:连续打开/查找页面在已测试的 OAuth 类上游上可用;API Key 类上游账号不在支持范围内。目标页面抓取失败时会提示 `LCX_ALPHA_PAGE_FETCH_FAILED`,模型可以换一个结果继续。
134
+ - **Markdown 图片换行**:为避免 DSH `0.2` 中图片后的文字挤到图片右侧,LCX 会让回答里的 Markdown 图片单独占一行,这一点与“搜索媒体预览”开关无关;句中的小图也会因此换行。
135
+ - **DSH `0.1.5` + LCX `0.4.3`**:在插件设置中启用或停用 LCX 后,已打开的浏览器页面可能需要刷新。
136
+ - **验证范围**:`0.5.0-pre.1` 的验收基线为 DSH `0.2.0-rc.2`(预发布);`0.4.4-pre.1` 在 DSH `0.1.6-alpha.2` 上完整验证;`0.4.3` 的稳定发布基线是 DSH `0.1.5-rc.1`,并已另外验证 DSH `0.1.5-rc.2`。同一安装范围内其他后续版本仍需单独评估,遇到问题欢迎反馈。
100
137
 
101
- 长任务也不需要自己盯着上下文。启用 LCX 后,兼容的 GPT 路由会在对话变得很长时自动尝试远程压缩并继续工作;你也可以使用 `/compact` 手动压缩。
138
+ ## 常见问题
102
139
 
103
- ## 兼容性与已知限制
140
+ **装完没有变化?**
141
+ 确认安装命令和启动命令用的是同一个 profile(上面的示例都是 `web`),并检查插件设置里的开关已经保存。
104
142
 
105
- - `0.4.3` 的当前完整验证基线是 DSH `0.1.5-rc.1`。同一 `0.1.5` 系列后续版本处于可安装、可评估范围,但仍会单独记录兼容验证结果;`0.1.6` 及更高版本不会自动视为兼容。
106
- - 从较旧的 LCX / DSH 版本升级时,建议新建会话;旧版保存的压缩状态不保证兼容。
107
- - Grok 原生搜索支持 API Key / API 网关路由;xAI OAuth / SuperGrok 登录不在当前范围。
108
- - Alpha 仍是实验功能。搜索可以正常使用,但连续 `open / find` 等操作在部分路由上仍可能失败;截图也不保证能作为可显示图片返回。
109
- - 修改 DSH profile 中的插件启用状态后,已经打开的浏览器页面可能需要刷新。
110
- - 不同 API 网关支持的能力可能不同。普通聊天可用,不代表搜索、长对话压缩或 Alpha 等功能也一定可用。
143
+ **能正常聊天,但搜索或压缩失败?**
144
+ 大概率是当前 GPT / Grok 路由没有提供对应的服务端能力。可以换官方 API 或其他网关对比一下。
111
145
 
112
- ## 遇到问题
146
+ **安装时出现依赖版本警告,或插件加载失败?**
147
+ 通常是 DSH 版本和插件版本不匹配,按[上面的表格](#1-按-dsh-版本选择插件版本)重新选择。
113
148
 
114
- **安装后看不到变化**:确认安装和启动使用的是同一个 `web` profile,并检查对应功能开关是否已经保存。
149
+ ## 反馈问题
115
150
 
116
- **对话正常,但搜索或压缩失败**:先确认当前 GPT / Grok Responses 路由确实提供对应服务端能力。网关名称本身不代表一定支持所有功能。
151
+ 请在 [Issues](https://github.com/kk3ya03-star/dsh-lcx-codex/issues) 中附上:插件版本、DSH 版本、Node.js 版本、使用的模型/网关类型和复现步骤。
117
152
 
118
- 提交 [Issue](https://github.com/kk3ya03-star/dsh-lcx-codex/issues) 时,请附上插件版本、DSH 版本、Node.js 版本和复现步骤。不要上传 API Key、完整请求或未脱敏的会话日志。
153
+ **请不要上传 API Key、完整请求内容或未脱敏的会话日志。**
119
154
 
120
- ## 更多信息
155
+ ## 更多
121
156
 
122
157
  - [更新日志](CHANGELOG.md)
123
158
  - [架构说明](ARCHITECTURE.md)
@@ -125,4 +160,4 @@ Grok 原生搜索与 GPT 的 LCX 主开关相互独立:
125
160
 
126
161
  ## 许可证
127
162
 
128
- [MIT](LICENSE)。独立社区插件,与 OpenAI、DeepSeek、Sub2API、NewAPI 无隶属或官方背书关系。
163
+ [MIT](LICENSE)。独立社区插件,与 OpenAI、xAI、DeepSeek、Sub2API、NewAPI 无隶属关系,也未获得其官方背书。
@@ -0,0 +1,47 @@
1
+ // @ts-check
2
+ const ABORT_MESSAGE = "The operation was aborted";
3
+ function abortInstance() {
4
+ if (typeof DOMException === "function")
5
+ return new DOMException(ABORT_MESSAGE, "AbortError");
6
+ const error = new Error(ABORT_MESSAGE);
7
+ error.name = "AbortError";
8
+ return error;
9
+ }
10
+ // `DOMException.prototype.code` is a getter-only accessor, so own properties are
11
+ // defined rather than assigned. Both stay non-enumerable, like a native `cause`.
12
+ function define(target, key, value) {
13
+ try {
14
+ Object.defineProperty(target, key, {
15
+ value,
16
+ configurable: true,
17
+ writable: true,
18
+ enumerable: false,
19
+ });
20
+ }
21
+ catch { }
22
+ }
23
+ function synthesize(reason) {
24
+ const error = abortInstance();
25
+ define(error, "code", "LCX_ABORTED");
26
+ if (reason !== undefined && reason !== null)
27
+ define(error, "cause", reason);
28
+ return error;
29
+ }
30
+ /**
31
+ * Normalize an abort reason into something safe to throw. `fallback` is used only when
32
+ * the reason is absent, preserving the older `signal.reason ?? error` behaviour.
33
+ */
34
+ export function normalizeAbortReason(reason, fallback) {
35
+ if (reason instanceof Error)
36
+ return reason;
37
+ if (reason === undefined || reason === null) {
38
+ if (fallback instanceof Error)
39
+ return fallback;
40
+ return synthesize(undefined);
41
+ }
42
+ return synthesize(reason);
43
+ }
44
+ /** The error to throw for `signal`'s cancellation. */
45
+ export function abortError(signal, fallback) {
46
+ return normalizeAbortReason(signal?.reason, fallback);
47
+ }