dsh-lcx-codex 0.3.0 → 0.3.2

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/CHANGELOG.md CHANGED
@@ -4,13 +4,22 @@
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.3.2 - 2026-08-21
8
+
7
9
  ### Fixed
8
10
 
9
- - Hosted Search Alpha Search 现在和 Native V2 Compact 一样,复用 DSH 已添加的 `openai-responses` provider 路由、凭据引用、headers retry policy;不再要求用户为插件重复配置 `LCX_API_KEY`。
10
- - README 将插件运行时凭据与运行在 DSH 外的 Alpha 探针/E2E 测试凭据明确分开。
11
- - README 改为简短的用户手册,以 npm 安装为主;Alpha 提示前置,并按 NewAPI 当前源码区分 4 种中转渠道类型与 Sub2API 直连,共 5 种部署路径。
11
+ - Native V2 compact 与同路由 replay 现在和 DSH/Pi 普通 Responses 请求复用相同的 session `prompt_cache_key`、缓存 retention 与会话 header,避免压缩边界额外切换 NewAPI/Sub2API 的缓存和账号粘性域;`cacheRetention: none` 时同时省略这些缓存信号。
12
+ - 移除未被插件直接导入或注入的 `@deepseek-ai/dsh-compaction-basic` peer 声明,避免 DSH/pnpm 安装时出现误导性的宿主依赖警告;Basic fallback 继续通过 DSH `llm/stream` 的 `next()` 链调用宿主实现。
13
+
14
+ ## 0.3.1 - 2026-08-21
12
15
 
13
- ## 0.3.0 - 2026-08-20
16
+ ### Fixed
17
+
18
+ - 删除未被 DSH 官方识别、且错误写死旧域名与 `LCX_API_KEY` 的 `dshhub` 权限块;README 改为声明网络目标和凭据由当前 `openai-responses` provider 动态决定。
19
+ - 添加 npm 与 DSH 社区检索使用的标准关键词,其中包括 `dsh-plugin` GitHub topic 对应关键词。
20
+ - 新增独立英文用户文档 `README_EN.md`,并与中文 README 互相链接。
21
+
22
+ ## 0.3.0 - 2026-08-21
14
23
 
15
24
  ### Changed
16
25
 
@@ -27,6 +36,9 @@
27
36
 
28
37
  ### Fixed
29
38
 
39
+ - Hosted Search 与 Alpha Search 现在和 Native V2 Compact 一样,复用 DSH 已添加的 `openai-responses` provider 路由、凭据引用、headers 与 retry policy;不再要求用户为插件重复配置 `LCX_API_KEY`。
40
+ - README 将插件运行时凭据与运行在 DSH 外的 Alpha 探针/E2E 测试凭据明确分开。
41
+ - README 改为简短的用户手册,以 npm 安装为主;Alpha 提示前置,并按 NewAPI 当前源码区分 4 种中转渠道类型与 Sub2API 直连,共 5 种部署路径。
30
42
  - Native replay and portable migration no longer depend on the nonexistent `GenerateOptions.branchId`; fork safety uses public session ancestry and derived marker history while preserving existing v3 fingerprint compatibility.
31
43
  - README 的本地 link 安装示例不再包含开发机绝对路径。
32
44
  - Alpha 从 rc.8 公共 `session.requestContext()` 读取 active route,避免模型切换后的 capability 误判。
package/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # dsh-lcx-codex
2
2
 
3
+ **简体中文** | [English](README_EN.md)
4
+
5
+ [![npm version](https://img.shields.io/npm/v/dsh-lcx-codex.svg)](https://www.npmjs.com/package/dsh-lcx-codex)
6
+ [![license](https://img.shields.io/npm/l/dsh-lcx-codex.svg)](LICENSE)
7
+
3
8
  社区维护的 DSH 插件,为兼容 OpenAI Responses/Codex 协议的 GPT 模型增加 Hosted Web Search、Alpha Search 和 Native V2 远程压缩。
4
9
 
5
10
  > [!IMPORTANT]
@@ -12,9 +17,42 @@
12
17
  - 直接使用 Sub2API 反代的 GPT 模型。
13
18
  - 使用 NewAPI 中转的 GPT 模型(也就是第三方中转);NewAPI 的上游渠道连接 Sub2API。
14
19
 
15
- ```text
16
- DSH -> Sub2API -> OpenAI Responses/Codex-compatible upstream
17
- DSH -> NewAPI -> Sub2API/compatible channel -> OpenAI Responses/Codex-compatible upstream
20
+ ```mermaid
21
+ flowchart LR
22
+ accTitle: dsh-lcx-codex 技术路线
23
+ accDescr: 插件复用当前 DSH openai-responses 模型的路由和凭据,将 Hosted Search、capability-gated Alpha Search 与 Native V2 Compact 请求经受控传输发送到 Sub2API 直连或 NewAPI 中转部署。
24
+
25
+ dsh_session([DSH GPT 会话]) --> resolve_route[复用 provider、model、baseURL 和凭据]
26
+
27
+ subgraph plugin_capabilities ["dsh-lcx-codex"]
28
+ hosted_search[Hosted Search<br/>POST /responses + web_search]
29
+ alpha_gate{Alpha capability 匹配?}
30
+ alpha_search[Alpha Search<br/>POST /alpha/search]
31
+ alpha_disabled([Alpha 不注册])
32
+ native_compact[Native V2 Compact<br/>stream + compaction_trigger]
33
+ end
34
+
35
+ resolve_route --> hosted_search
36
+ resolve_route --> alpha_gate
37
+ resolve_route --> native_compact
38
+ alpha_gate -->|是| alpha_search
39
+ alpha_gate -->|否| alpha_disabled
40
+
41
+ hosted_search --> transport[受控鉴权、超时、重试和响应大小]
42
+ alpha_search --> transport
43
+ native_compact --> transport
44
+
45
+ transport --> deployment{部署路径}
46
+ deployment -->|直连| sub2api[Sub2API]
47
+ deployment -->|中转| newapi[NewAPI 兼容渠道]
48
+ sub2api --> upstream([OpenAI Responses/Codex-compatible upstream])
49
+ newapi --> upstream
50
+
51
+ upstream -.->|compaction output| checkpoint[(Checkpoint v3)]
52
+ checkpoint -->|同路由| opaque_replay[Opaque native replay]
53
+ checkpoint -->|路由或模型变化| portable_migration[Portable migration]
54
+ opaque_replay --> transport
55
+ portable_migration --> transport
18
56
  ```
19
57
 
20
58
  本项目不隶属于 OpenAI,也不是 OpenAI 官方发布的插件或 OAuth 客户端。
@@ -31,7 +69,7 @@ Alpha 只有在 capability 记录与当前 endpoint、provider、model 和 schem
31
69
 
32
70
  ## 安装
33
71
 
34
- 发布到 npm 后,推荐直接安装包名:
72
+ 推荐从 npm 安装:
35
73
 
36
74
  ```powershell
37
75
  dsh plugin --profile web add dsh-lcx-codex
@@ -40,7 +78,7 @@ dsh plugin --profile web add dsh-lcx-codex
40
78
  也可以下载 GitHub Release 中的 `.tgz` 安装指定版本:
41
79
 
42
80
  ```powershell
43
- dsh plugin --profile web add .\dsh-lcx-codex-0.3.0.tgz
81
+ dsh plugin --profile web add .\dsh-lcx-codex-0.3.2.tgz
44
82
  ```
45
83
 
46
84
  安装后启动 DSH:
@@ -86,6 +124,8 @@ node (Join-Path $dshHome 'profiles\web\node_modules\dsh-lcx-codex\scripts\probe-
86
124
 
87
125
  ## 数据与限制
88
126
 
127
+ - 网络目标由当前活动 DSH `openai-responses` provider 的 `baseURL` 决定,不固定到 LCX 或其他域名;插件只在该地址下调用 `/responses` 和 `/alpha/search`
128
+ - 凭据名称取自同一 provider 的 `apiKeyEnv`,并由 DSH credentials service 解析;插件不会自行保存 API key
89
129
  - Checkpoint:`$DSH_HOME/storages/lcx-codex/checkpoints-v3.json`
90
130
  - Alpha capability:`$DSH_HOME/storages/lcx-codex/web-alpha-capabilities.json`
91
131
  - Alpha refs:`$DSH_HOME/storages/lcx-codex/web-alpha-refs.json`
package/README_EN.md ADDED
@@ -0,0 +1,160 @@
1
+ # dsh-lcx-codex
2
+
3
+ [Chinese](README.md) | **English**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/dsh-lcx-codex.svg)](https://www.npmjs.com/package/dsh-lcx-codex)
6
+ [![license](https://img.shields.io/npm/l/dsh-lcx-codex.svg)](LICENSE)
7
+
8
+ A community-maintained DSH plugin that adds Hosted Web Search, Alpha Search, and Native V2 remote compaction to GPT models served through an OpenAI Responses/Codex-compatible API.
9
+
10
+ > [!IMPORTANT]
11
+ > Alpha Search currently has five supported deployment paths: a direct Sub2API connection, or one of four NewAPI channel types: `Sub2API`, `New API`, `ChatGPT Subscription (Codex)`, and `Advanced Custom`. A regular `OpenAI` channel does not support `/v1/alpha/search` and is rejected by NewAPI.
12
+
13
+ This list comes from NewAPI's current [`AlphaSearchHelper`](https://github.com/QuantumNous/new-api/blob/f116414284162ad15d8925f7bca494c109b83e93/relay/alpha_search_handler.go). Other NewAPI versions may differ, so the capability probe remains authoritative for a specific deployment.
14
+
15
+ `LCX` is only the plugin name. It is not a service provider or protocol. The plugin supports GPT models served through:
16
+
17
+ - A direct Sub2API reverse proxy.
18
+ - A NewAPI relay, meaning a third-party relay whose upstream channel connects to Sub2API.
19
+
20
+ ```mermaid
21
+ flowchart LR
22
+ accTitle: dsh-lcx-codex architecture
23
+ accDescr: The plugin reuses the active DSH openai-responses model route and credential, then sends Hosted Search, capability-gated Alpha Search, and Native V2 Compact requests through a controlled transport to a direct Sub2API or NewAPI relay deployment.
24
+
25
+ dsh_session([DSH GPT session]) --> resolve_route[Reuse provider, model, baseURL, and credential]
26
+
27
+ subgraph plugin_capabilities ["dsh-lcx-codex"]
28
+ hosted_search[Hosted Search<br/>POST /responses + web_search]
29
+ alpha_gate{Alpha capability matches?}
30
+ alpha_search[Alpha Search<br/>POST /alpha/search]
31
+ alpha_disabled([Alpha is not registered])
32
+ native_compact[Native V2 Compact<br/>stream + compaction_trigger]
33
+ end
34
+
35
+ resolve_route --> hosted_search
36
+ resolve_route --> alpha_gate
37
+ resolve_route --> native_compact
38
+ alpha_gate -->|Yes| alpha_search
39
+ alpha_gate -->|No| alpha_disabled
40
+
41
+ hosted_search --> transport[Controlled authentication, timeout, retry, and response size]
42
+ alpha_search --> transport
43
+ native_compact --> transport
44
+
45
+ transport --> deployment{Deployment path}
46
+ deployment -->|Direct| sub2api[Sub2API]
47
+ deployment -->|Relay| newapi[Compatible NewAPI channel]
48
+ sub2api --> upstream([OpenAI Responses/Codex-compatible upstream])
49
+ newapi --> upstream
50
+
51
+ upstream -.->|Compaction output| checkpoint[(Checkpoint v3)]
52
+ checkpoint -->|Same route| opaque_replay[Opaque native replay]
53
+ checkpoint -->|Route or model changed| portable_migration[Portable migration]
54
+ opaque_replay --> transport
55
+ portable_migration --> transport
56
+ ```
57
+
58
+ This project is not affiliated with OpenAI and is not an official OpenAI plugin or OAuth client.
59
+
60
+ ## Features
61
+
62
+ | Feature | Tool or protocol | Behavior |
63
+ |---|---|---|
64
+ | Hosted Web Search | `websearch_gpt` | Uses `/responses` with `web_search` and returns text, direct sources, and citations |
65
+ | Alpha Search | `websearch_alpha` | Uses `/alpha/search` for search, image, open/find/click, PDF screenshot, finance, weather, sports, and time actions |
66
+ | Native V2 Compact | `/responses` with `compaction_trigger` | Stores checkpoint v3 and supports same-route replay, model migration, fork/tree sessions, restart recovery, and image attachments |
67
+
68
+ Alpha is enabled only when a capability record matches the current endpoint, provider, model, and schema. Hosted and Alpha are separate protocols and never silently fall back to each other.
69
+
70
+ ## Installation
71
+
72
+ Install from npm:
73
+
74
+ ```powershell
75
+ dsh plugin --profile web add dsh-lcx-codex
76
+ ```
77
+
78
+ You can also install a specific `.tgz` file from a GitHub Release:
79
+
80
+ ```powershell
81
+ dsh plugin --profile web add .\dsh-lcx-codex-0.3.2.tgz
82
+ ```
83
+
84
+ Start DSH after installation:
85
+
86
+ ```powershell
87
+ dsh web
88
+ ```
89
+
90
+ Open `Settings -> Plugins -> LCX / Codex capabilities` and enable Hosted, Alpha, or Native Compact as needed. The plugin is disabled by default.
91
+
92
+ ## Requirements
93
+
94
+ - Node.js 20 or later
95
+ - DSH `0.1.0-rc.8` or a compatible release
96
+ - A GPT model already added to DSH and working in a normal conversation
97
+ - The model must use the `openai-responses` provider from `llm-pi-ai`
98
+
99
+ The plugin reuses the active DSH model's provider, model, Responses URL, credential reference, headers, and retry policy. Normal plugin operation does not require a second `LCX_API_KEY` configuration.
100
+
101
+ The endpoint and model fields in the plugin UI are defaults for cases without an active session route and for compatibility with the older direct-route configuration. An existing DSH provider configuration takes precedence.
102
+
103
+ ## Alpha Probe
104
+
105
+ Alpha capability is classified as `native`, `command-capable`, `emulated-search-only`, `unsupported`, or `unknown`. An HTTP 200 response alone does not prove that an action is native.
106
+
107
+ The probe is a standalone Node.js script outside the DSH runtime, so it cannot use the DSH credentials service. It requires a local key file; normal plugin operation does not.
108
+
109
+ ```powershell
110
+ $dshHome = if ($env:DSH_HOME) { $env:DSH_HOME } else { Join-Path $env:USERPROFILE '.dsh' }
111
+ $env:LCX_API_KEY_FILE = 'C:\path\to\local-key.txt'
112
+ $env:LCX_MODEL = 'the-exact-model-name'
113
+ node (Join-Path $dshHome 'profiles\web\node_modules\dsh-lcx-codex\scripts\probe-alpha.mjs')
114
+ ```
115
+
116
+ To also probe image, finance, weather, sports, and time actions:
117
+
118
+ ```powershell
119
+ $env:LCX_ALPHA_PROBE_STRUCTURED = '1'
120
+ node (Join-Path $dshHome 'profiles\web\node_modules\dsh-lcx-codex\scripts\probe-alpha.mjs')
121
+ ```
122
+
123
+ The probe does not print the key or full response bodies. Restart DSH, or disable and re-enable Alpha, after the probe completes.
124
+
125
+ ## Data and Limits
126
+
127
+ - The runtime network target is determined by the active DSH `openai-responses` provider's `baseURL`; it is not fixed to LCX or any other domain. The plugin only calls `/responses` and `/alpha/search` under that address.
128
+ - The credential name comes from the same provider's `apiKeyEnv` and is resolved by the DSH credentials service. The plugin does not store API keys.
129
+ - Checkpoints: `$DSH_HOME/storages/lcx-codex/checkpoints-v3.json`
130
+ - Alpha capabilities: `$DSH_HOME/storages/lcx-codex/web-alpha-capabilities.json`
131
+ - Alpha references: `$DSH_HOME/storages/lcx-codex/web-alpha-refs.json`
132
+ - Only Native remote-compaction V2 is supported; `/responses/compact` is never called.
133
+ - Checkpoints never store raw image bytes or data URLs.
134
+ - Opaque checkpoints are not replayed across an incompatible provider, model, base URL, session, or lineage.
135
+ - Image generation is not included.
136
+
137
+ Never commit API keys, OAuth tokens, Authorization headers, account IDs, session cookies, or runtime sidecars to GitHub.
138
+
139
+ ## Update and Removal
140
+
141
+ ```powershell
142
+ dsh plugin --profile web update dsh-lcx-codex
143
+ dsh plugin --profile web remove dsh-lcx-codex
144
+ ```
145
+
146
+ Removal does not delete `$DSH_HOME/storages/lcx-codex/`. Do not delete a checkpoint sidecar by itself while a session still references its marker.
147
+
148
+ ## Development
149
+
150
+ ```powershell
151
+ npm install
152
+ npm test
153
+ npm run test:schema
154
+ ```
155
+
156
+ Real E2E tests and the Alpha probe must read test credentials only from ignored local files or environment variables.
157
+
158
+ ## License
159
+
160
+ [MIT](LICENSE)
package/lib/compact-v2.js CHANGED
@@ -156,7 +156,7 @@ export function mergeFeatureHeader(headers) {
156
156
  return result
157
157
  }
158
158
 
159
- export function buildNativeCompactionBody({ model, input, instructions, promptCacheKey, tools }) {
159
+ export function buildNativeCompactionBody({ model, input, instructions, promptCacheKey, promptCacheRetention, tools }) {
160
160
  if (!Array.isArray(input)) throw protocolError('Native compaction input must be an array', 'LCX_COMPACT_INVALID_INPUT')
161
161
  if (input.some((item) => isObject(item) && item.type === 'compaction_trigger')) {
162
162
  throw protocolError('Native compaction input already contains compaction_trigger', 'LCX_COMPACT_DUPLICATE_TRIGGER')
@@ -170,6 +170,7 @@ export function buildNativeCompactionBody({ model, input, instructions, promptCa
170
170
  ...(nativeTools !== undefined ? { tools: nativeTools } : {}),
171
171
  ...(instructions !== undefined ? { instructions: structuredClone(instructions) } : {}),
172
172
  ...(promptCacheKey !== undefined && promptCacheKey !== null ? { prompt_cache_key: String(promptCacheKey) } : {}),
173
+ ...(promptCacheRetention !== undefined && promptCacheRetention !== null ? { prompt_cache_retention: String(promptCacheRetention) } : {}),
173
174
  }
174
175
  }
175
176
 
@@ -273,6 +274,7 @@ export async function requestNativeCompaction({
273
274
  input,
274
275
  instructions,
275
276
  promptCacheKey,
277
+ promptCacheRetention,
276
278
  idempotencyKey,
277
279
  tools,
278
280
  headers,
@@ -281,7 +283,7 @@ export async function requestNativeCompaction({
281
283
  maxAttempts,
282
284
  maxResponseBytes,
283
285
  }) {
284
- const body = buildNativeCompactionBody({ model, input, instructions, promptCacheKey, tools })
286
+ const body = buildNativeCompactionBody({ model, input, instructions, promptCacheKey, promptCacheRetention, tools })
285
287
  const requestHeaders = { ...(headers ?? {}) }
286
288
  if (idempotencyKey !== undefined && idempotencyKey !== null && !Object.keys(requestHeaders).some((name) => name.toLowerCase() === 'idempotency-key')) {
287
289
  requestHeaders['idempotency-key'] = String(idempotencyKey)
package/lib/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import z from '@deepseek-ai/schemastery'
2
2
  import { attributionHeaders, resolveRetryPolicy } from '@deepseek-ai/dsh-llm'
3
3
  import { settingsNamespace } from '@deepseek-ai/dsh-settings'
4
+ import { clampOpenAIPromptCacheKey } from '@earendil-works/pi-ai/api/openai-prompt-cache'
4
5
  import { randomUUID } from 'node:crypto'
5
6
  import { homedir } from 'node:os'
6
7
  import { join } from 'node:path'
@@ -135,6 +136,7 @@ function normalizeCompactTransport(value) {
135
136
  }
136
137
 
137
138
  function normalizeConfig(input = {}) {
139
+ const cacheRetention = ['none', 'short', 'long'].includes(input.cacheRetention) ? input.cacheRetention : 'short'
138
140
  return {
139
141
  provider: input.provider || 'lcx',
140
142
  baseURL: String(input.baseURL || 'https://api.lcxbot.com/v1').replace(/\/+$/u, ''),
@@ -142,6 +144,8 @@ function normalizeConfig(input = {}) {
142
144
  model: input.model || 'gpt-5.6-sol',
143
145
  compactTransport: normalizeCompactTransport(input.compactTransport),
144
146
  headers: input.headers && typeof input.headers === 'object' ? { ...input.headers } : {},
147
+ cacheRetention,
148
+ supportsLongCacheRetention: input.supportsLongCacheRetention !== false,
145
149
  checkpointPath: input.checkpointPath || defaultCheckpointPath(),
146
150
  portableCheckpointPath: input.portableCheckpointPath || portableCheckpointPath(input.checkpointPath || defaultCheckpointPath()),
147
151
  alphaCapabilityPath: input.alphaCapabilityPath || defaultAlphaCapabilityPath(),
@@ -186,6 +190,8 @@ function resolveResponsesRouteConfig(ctx, options, fallbackConfig) {
186
190
  baseURL,
187
191
  apiKeyEnv,
188
192
  headers: profile.headers ?? fallbackConfig.headers,
193
+ cacheRetention: profile.cacheRetention ?? fallbackConfig.cacheRetention,
194
+ supportsLongCacheRetention: profile.compat?.supportsLongCacheRetention ?? fallbackConfig.supportsLongCacheRetention,
189
195
  model: options.model,
190
196
  compactTransport: profile.compactTransport ?? fallbackConfig.compactTransport,
191
197
  timeoutMs: profile.timeoutMs ?? fallbackConfig.timeoutMs,
@@ -301,7 +307,7 @@ async function authenticatedHeaders(ctx, config, sessionId, clientRequestId) {
301
307
  ...config.headers,
302
308
  ...attributionHeaders(),
303
309
  authorization: `Bearer ${await resolveApiKey(ctx, config)}`,
304
- 'x-client-request-id': clientRequestId ?? randomUUID(),
310
+ ...(clientRequestId === null ? {} : { 'x-client-request-id': clientRequestId ?? (sessionId ? String(sessionId) : randomUUID()) }),
305
311
  ...(sessionId ? { 'session-id': String(sessionId) } : {}),
306
312
  }
307
313
  }
@@ -361,19 +367,35 @@ function routeWithSessionAncestry(ctx, route) {
361
367
  return { ...route, ancestorSessionIds: sessionAncestry(ctx, route.sessionId) }
362
368
  }
363
369
 
364
- function promptCacheKey(route) {
365
- return route?.sessionId ? routeFingerprint(route) : undefined
370
+ function promptCacheSessionId(route, config) {
371
+ if (config?.cacheRetention === 'none') return undefined
372
+ return route?.sessionId ? String(route.sessionId) : undefined
373
+ }
374
+
375
+ function promptCacheKey(route, config) {
376
+ const sessionId = promptCacheSessionId(route, config)
377
+ return sessionId ? clampOpenAIPromptCacheKey(sessionId) : undefined
378
+ }
379
+
380
+ function promptCacheRetention(config) {
381
+ return config?.cacheRetention === 'long' && config.supportsLongCacheRetention !== false ? '24h' : undefined
382
+ }
383
+
384
+ function promptCacheHeaders(ctx, config, route) {
385
+ const sessionId = promptCacheSessionId(route, config)
386
+ return authenticatedHeaders(ctx, config, sessionId, sessionId === undefined ? null : undefined)
366
387
  }
367
388
 
368
389
  async function requestRemoteCompaction(options, input, config, signal, ctx, route, preflightHeaders) {
369
390
  try {
370
- const headers = preflightHeaders ?? await authenticatedHeaders(ctx, config, options.sessionId)
391
+ const headers = preflightHeaders ?? await promptCacheHeaders(ctx, config, route)
371
392
  return await requestNativeCompaction({
372
393
  baseURL: config.baseURL,
373
394
  model: options.model,
374
395
  input,
375
396
  instructions: options.system,
376
- promptCacheKey: promptCacheKey(route),
397
+ promptCacheKey: promptCacheKey(route, config),
398
+ promptCacheRetention: promptCacheRetention(config),
377
399
  idempotencyKey: randomUUID(),
378
400
  tools: options.tools,
379
401
  headers,
@@ -731,7 +753,7 @@ function checkpointReplayRecord(messages, store) {
731
753
  return { marker, record }
732
754
  }
733
755
 
734
- function nativeReplayBody(options, route, nativeOutput, tailInput) {
756
+ function nativeReplayBody(options, route, config, nativeOutput, tailInput) {
735
757
  return {
736
758
  model: options.model,
737
759
  input: [...structuredClone(nativeOutput), ...structuredClone(tailInput)],
@@ -739,7 +761,8 @@ function nativeReplayBody(options, route, nativeOutput, tailInput) {
739
761
  store: false,
740
762
  ...(options.tools !== undefined ? { tools: responsesTools(options.tools) } : {}),
741
763
  ...(options.system !== undefined ? { instructions: options.system } : {}),
742
- ...(promptCacheKey(route) ? { prompt_cache_key: promptCacheKey(route) } : {}),
764
+ ...(promptCacheKey(route, config) ? { prompt_cache_key: promptCacheKey(route, config) } : {}),
765
+ ...(promptCacheRetention(config) ? { prompt_cache_retention: promptCacheRetention(config) } : {}),
743
766
  }
744
767
  }
745
768
 
@@ -762,8 +785,8 @@ async function* nativeCheckpointReplayStream(options, config, portableStore, ctx
762
785
  try {
763
786
  const response = await fetchSse(
764
787
  `${config.baseURL}/responses`,
765
- nativeReplayBody(options, route, nativeOutput, tailInput),
766
- mergeFeatureHeader(await authenticatedHeaders(ctx, config, options.sessionId)),
788
+ nativeReplayBody(options, route, config, nativeOutput, tailInput),
789
+ mergeFeatureHeader(await promptCacheHeaders(ctx, config, route)),
767
790
  replaySignals.signal,
768
791
  config.timeoutMs + 1000,
769
792
  { maxResponseBytes: config.maxResponseBytes },
@@ -822,7 +845,7 @@ async function prepareRemoteCompaction(options, config, portableStore, ctx, sess
822
845
  const route = currentRoute(options, config)
823
846
  const lease = sessionTracker?.capture(route.sessionId)
824
847
  lease?.assert('request-start')
825
- const headers = await authenticatedHeaders(ctx, config, options.sessionId)
848
+ const headers = await promptCacheHeaders(ctx, config, route)
826
849
  responsesTools(options.tools)
827
850
  const llm = ctx?.llm ?? ctx?.get?.('llm')
828
851
  const imageSupport = typeof llm?.resolveModelInfo === 'function'
package/package.json CHANGED
@@ -1,7 +1,26 @@
1
1
  {
2
2
  "name": "dsh-lcx-codex",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "DSH web search and Responses native V2 compaction for Sub2API-proxied or NewAPI-relayed GPT models",
5
+ "keywords": [
6
+ "deepseek-harness",
7
+ "dsh",
8
+ "dsh-plugin",
9
+ "plugin",
10
+ "web-search",
11
+ "openai-responses",
12
+ "sub2api",
13
+ "newapi",
14
+ "compaction"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/kk3ya03-star/dsh-lcx-codex.git"
19
+ },
20
+ "homepage": "https://github.com/kk3ya03-star/dsh-lcx-codex#readme",
21
+ "bugs": {
22
+ "url": "https://github.com/kk3ya03-star/dsh-lcx-codex/issues"
23
+ },
5
24
  "type": "module",
6
25
  "main": "lib/index.js",
7
26
  "exports": {
@@ -20,6 +39,7 @@
20
39
  "cordis.patch.yml",
21
40
  "LICENSE",
22
41
  "README.md",
42
+ "README_EN.md",
23
43
  "CHANGELOG.md"
24
44
  ],
25
45
  "dsh": {
@@ -30,39 +50,6 @@
30
50
  "platform": "web"
31
51
  }
32
52
  },
33
- "dshhub": {
34
- "schemaVersion": 1,
35
- "displayName": "dsh-lcx-codex",
36
- "summary": "Sub2API/NewAPI GPT web search, capability-gated Alpha, and Responses native V2 compact",
37
- "surfaces": [
38
- "host",
39
- "web"
40
- ],
41
- "capabilities": {
42
- "provides": [
43
- "hosted-web-search",
44
- "capability-gated-alpha-search",
45
- "native-responses-compaction"
46
- ]
47
- },
48
- "compatibility": {
49
- "dsh": ">=0.1.0-rc.8",
50
- "node": ">=20"
51
- },
52
- "permissions": {
53
- "network": [
54
- "https://api.lcxbot.com"
55
- ],
56
- "credentials": [
57
- "LCX_API_KEY"
58
- ],
59
- "storage": [
60
- "$DSH_HOME/storages/lcx-codex/checkpoints-v3.json",
61
- "$DSH_HOME/storages/lcx-codex/web-alpha-capabilities.json",
62
- "$DSH_HOME/storages/lcx-codex/web-alpha-refs.json"
63
- ]
64
- }
65
- },
66
53
  "dependencies": {
67
54
  "@earendil-works/pi-ai": "0.82.1"
68
55
  },
@@ -75,7 +62,6 @@
75
62
  "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.8",
76
63
  "@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.8",
77
64
  "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.8",
78
- "@deepseek-ai/dsh-compaction-basic": "^0.1.0-rc.8",
79
65
  "@deepseek-ai/dsh-credentials": "^0.1.0-rc.8",
80
66
  "@deepseek-ai/dsh-llm": "^0.1.0-rc.8",
81
67
  "@deepseek-ai/dsh-settings": "^0.1.0-rc.8",