dsh-packycode-api 1.3.5 → 1.3.6

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
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.3.6
4
+
5
+ - **DeepSeek Flash runs over Responses.** `deepseek-flash` moves from `openai-completions` to `openai-responses`; the base URL stays `https://cf.api.fan/v1`, so requests now go to `/v1/responses` instead of `/v1/chat/completions`. PackyCode's `/api/pricing` lists `openai-response` among the model's endpoints, for the same groups (`deepseek-officially`, `deepseek-sale`). The effort levels are unchanged (`off`, `low`, `high`, `max`), and so is `thinkingLevelMap`: `off` now sends `reasoning.effort: "none"`, which the gateway answers with no reasoning item and zero reasoning tokens. The Chat Completions dialect (`thinkingFormat: 'deepseek'`, `max_tokens`, reasoning content on assistant messages) is gone with it; reasoning comes back as `reasoning_text` items, which pi-ai streams as thinking and sends back with the turn's tool calls. Like Grok, DeepSeek omits `prompt_cache_key`: the gateway accepts the field, but its prefix cache already hits without it. Image input is sent as `input_image`. The 384,000-token output ceiling stays under the gateway's Responses limit of 393,216. No catalog model uses Chat Completions any more, so the provider no longer registers that API; the group probe still uses `/v1/chat/completions`, which needs no model. A session that ran on Chat Completions continues over Responses: pi-ai sends its earlier thinking as text and keeps its tool calls.
6
+ - Validation, 2026-10-19: 461 offline tests (new: DeepSeek's Responses efforts and `off` → `none` without a cache key, reasoning streamed as thinking and replayed with its tool call, the vision payload as `input_image`, and the key-choice gateway answering on Responses), both rebuilt bundles and the versioned tarball. Live against the gateway with a `deepseek-officially` key: direct `/v1/responses` requests for `deepseek-flash` returned 200 at `none`, `minimal`, `low`, `medium`, `high`, `xhigh` and `max`, with no reasoning item at `none`; `max_output_tokens` up to 393,216 was accepted and 500,000 refused. Through the plugin's provider, four-turn tool conversations passed at `high`, `max`, `off`, mixed efforts, and with replayed reasoning items (up to three in one request); the prefix cache hit without `prompt_cache_key`; a conversation started over Chat Completions continued over Responses. `scripts/live-check.mjs` passed for all ten models, key rotation (an invalid key on `deepseek-flash` was disabled and the real key answered) and the RPC projections, and `--model deepseek-flash --with-vision` named both color fixtures. Not checked in DeepSeek Harness itself; no DSH restart.
7
+
3
8
  ## 1.3.5
4
9
 
5
10
  - **An outdated Claude Code CLI is caught before the request, and the CLI card updates it.** 1.3.4 always passes `--permission-prompts none`, which Claude Code added in 2.1.259 (2026-09-02). A colleague's CLI from the official installer was 2.1.223 (2026-08-05): it rejected the option at start-up, every `cc` Claude turn failed with "the installed Claude Code CLI is too old", and the card still showed it as installed. The plugin now requires 2.1.259 or later. An older detected CLI is refused before it is started, with the detected and required versions; a cached detection that looks outdated is probed again first, so a CLI updated in a terminal is used at once. The card marks such a CLI **too old** and offers **Update Claude Code CLI**. A CLI from the official installer (or any install that is not npm's) is updated with `claude update`, run with the plugin's own CLI home and without the user's `ANTHROPIC_*` / `CLAUDE_*` / `DISABLE_*` variables. An npm global install is updated by npm itself — the npm beside the CLI, which owns its prefix — with `npm install -g @anthropic-ai/claude-code@latest --allow-scripts=@anthropic-ai/claude-code`. The update succeeds only when the CLI detected afterwards is new enough; otherwise the card says whether it stayed old (for example a Homebrew install), stopped running, or could not download, with the command's output. The CLI's flags and environment for requests are unchanged.
package/README.en.md CHANGED
@@ -47,10 +47,10 @@ You need **DeepSeek Harness** and a **PackyCode (PackyAPI) API key**. For DSH se
47
47
  Open the desktop application's **Plugins** page, click **Add plugin**, and enter the package name **with a version** as the **package name or address**:
48
48
 
49
49
  ```text
50
- dsh-packycode-api@1.3.5
50
+ dsh-packycode-api@1.3.6
51
51
  ```
52
52
 
53
- Choose the **official** install source, then click **Install**. `1.3.5` was the latest release when this was written; the [npm page](https://www.npmjs.com/package/dsh-packycode-api) shows the current one.
53
+ Choose the **official** install source, then click **Install**. `1.3.6` was the latest release when this was written; the [npm page](https://www.npmjs.com/package/dsh-packycode-api) shows the current one.
54
54
 
55
55
  > **Always include the version.** With a bare `dsh-packycode-api`, the install prompt shows the newest version on npm, but DSH's bundled pnpm by default installs only versions published at least 24 hours ago, so you can end up several releases behind with no sign of it in the prompt. With an exact version, pnpm installs that version and adds it to the profile's `minimumReleaseAgeExclude` itself. Afterwards, check **Current version** under **Settings → PackyCode → Plugin version**.
56
56
 
@@ -71,7 +71,7 @@ Choose a model from the `PackyCode` group. All ten models use the plugin’s HTT
71
71
 
72
72
  The **Plugins** page shows the installed state and version, and is also where you enable, disable, or uninstall.
73
73
 
74
- **For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.3.5`. Do not use it for `desktop` — the CLI refuses it (`profile "desktop" is managed exclusively by the Electron application`).
74
+ **For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.3.6`. Do not use it for `desktop` — the CLI refuses it (`profile "desktop" is managed exclusively by the Electron application`).
75
75
 
76
76
  For a local checkout, keep the `link:` prefix: `dsh plugin --profile <name> add link:/path/to/dsh-packycode-api`. **Do not pass a bare path or `file:`** — that install copies the whole checkout, `node_modules` included, into the profile, where it then shadows the packages the DSH installation itself provides and the plugin looks uninstalled; see the FAQ. If you already installed that way, uninstall first and reinstall as above.
77
77
 
@@ -170,7 +170,7 @@ Live checks on 2026-10-15 passed generation and editing at `low` on all three en
170
170
 
171
171
  | Model | How it runs | Effort | Token group |
172
172
  | --- | --- | --- | --- |
173
- | `deepseek-flash` | HTTP, chat/completions, images allowed | Can be off; `low` / `high` / `max` | `deepseek-officially`, `deepseek-sale` |
173
+ | `deepseek-flash` | HTTP, Responses, images allowed | Can be off; `low` / `high` / `max` | `deepseek-officially`, `deepseek-sale` |
174
174
  | `gpt-6.1-sol` | HTTP, Responses, images allowed | Cannot be off; `low` / `medium` / `high` / `xhigh` / `max` | `codex`, `codex-sale` |
175
175
  | `gpt-6-astra` | Same | Same | Same |
176
176
  | `gpt-5.6-sol` | Same | Same | Same |
@@ -183,7 +183,7 @@ Live checks on 2026-10-15 passed generation and editing at `low` on all three en
183
183
 
184
184
  A model in the list does not mean the current token group allows it. When changing groups, do not drop the group that serves the model you still want.
185
185
 
186
- All ten models in the current catalog declare text and image input. DeepSeek Flash follows the [official vision guide](https://api-docs.deepseek.com/guides/vision/); images are read through DSH's attachment service and sent with the Chat Completions request.
186
+ All ten models in the current catalog declare text and image input. DeepSeek Flash follows the [official vision guide](https://api-docs.deepseek.com/guides/vision/); images are read through DSH's attachment service and sent with the Responses request.
187
187
 
188
188
  Gemini capabilities and limits follow Google's model pages: [Gemini 4 Argon](https://ai.google.dev/gemini-api/docs/models/gemini-4-argon), [Gemini 3.8 Flash](https://ai.google.dev/gemini-api/docs/models/gemini-3.8-flash). Both models use the native Gemini protocol through `/v1beta/models/{model}:streamGenerateContent`, streaming text, thinking and tool calls; images are read through DSH's attachment service. Thinking levels are sent with `thinkingLevel`. Both routes use the single-stream output limit without automatic continuation beyond 65,536 tokens. Available endpoints and groups follow the [PackyAPI live model catalog](https://www.packyapi.com/api/pricing).
189
189
 
@@ -191,7 +191,9 @@ Gemini capabilities and limits follow Google's model pages: [Gemini 4 Argon](htt
191
191
 
192
192
  Grok 4.7's context and reasoning levels follow the [official guide](https://docs.x.ai/developers/grok-4-7). There is no separate text-output limit; the plugin uses the context size as its numeric output ceiling, bounded by the remaining context per request.
193
193
 
194
- Only GPT Responses requests keep `prompt_cache_key`; other Responses models omit it by default. This gateway's Grok route reports a misleading `Incorrect API key provided` error when the field is present.
194
+ Only GPT Responses requests keep `prompt_cache_key`; other Responses models omit it by default. This gateway's Grok route reports a misleading `Incorrect API key provided` error when the field is present, and DeepSeek Flash hits its prefix cache without it.
195
+
196
+ DeepSeek Flash uses the gateway's Responses endpoint (`/api/pricing` lists `openai-response`). With effort off it sends `reasoning.effort: "none"`, and the gateway answers without reasoning; otherwise reasoning comes back as `reasoning_text` and is sent back with the same turn's tool calls.
195
197
 
196
198
  <details>
197
199
  <summary>Protocol, group and client compatibility</summary>
@@ -214,9 +216,9 @@ Only GPT Responses requests keep `prompt_cache_key`; other Responses models omit
214
216
 
215
217
  ## Update and uninstall
216
218
 
217
- > **Upgrading from 1.3.2 or earlier:** install `dsh-packycode-api@1.3.5` on the Plugins page instead of clicking **Update plugin** in the old settings card. The old button bypasses pnpm's release-age policy: if the version it installs is less than 24 hours old, the profile refuses every other plugin install until that version is 24 hours old. After the install and a restart, the button is the fixed one, and later updates can use it.
219
+ > **Upgrading from 1.3.2 or earlier:** install `dsh-packycode-api@1.3.6` on the Plugins page instead of clicking **Update plugin** in the old settings card. The old button bypasses pnpm's release-age policy: if the version it installs is less than 24 hours old, the profile refuses every other plugin install until that version is 24 hours old. After the install and a restart, the button is the fixed one, and later updates can use it.
218
220
 
219
- **Update:** open **Settings → PackyCode** and, when a newer version is listed, click **Update plugin**. It installs that exact version into the owning profile with DSH's bundled pnpm and reads `package.json` back before reporting success. The install keeps pnpm's release-age policy instead of overriding it: by default pnpm installs the version at once and records it in the profile's `minimumReleaseAgeExclude`; under a stricter pnpm policy the button says when the update can run. A local `link:` checkout does not get the button. Then quit and reopen the desktop application. A page refresh does not reload the Host. Reinstalling from the **Plugins** page works too, again with the version in the package name (for example `dsh-packycode-api@1.3.5`); without it you may get a version that is merely the newest one published at least 24 hours ago.
221
+ **Update:** open **Settings → PackyCode** and, when a newer version is listed, click **Update plugin**. It installs that exact version into the owning profile with DSH's bundled pnpm and reads `package.json` back before reporting success. The install keeps pnpm's release-age policy instead of overriding it: by default pnpm installs the version at once and records it in the profile's `minimumReleaseAgeExclude`; under a stricter pnpm policy the button says when the update can run. A local `link:` checkout does not get the button. Then quit and reopen the desktop application. A page refresh does not reload the Host. Reinstalling from the **Plugins** page works too, again with the version in the package name (for example `dsh-packycode-api@1.3.6`); without it you may get a version that is merely the newest one published at least 24 hours ago.
220
222
 
221
223
  **Coming back from a local-path install, uninstall first.** An update is a `pnpm add`: it rewrites the files inside the package directory and leaves a `node_modules` that an earlier local-path install left there. That older tree keeps shadowing the packages the DSH installation provides, so the plugin row fails to load with no visible reason. **Uninstall** runs `pnpm remove`, which deletes the package directory outright — only a reinstall after that is clean. `node scripts/install-check.mjs` reports whether a profile is in that state.
222
224
 
@@ -232,7 +234,7 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
232
234
 
233
235
  Output means a leftover tree: a registry install ships no `node_modules`, so this one usually comes from an earlier local-path install (`file:`, or a bare path instead of `link:`). It sits inside the profile directory, and DSH resolves a plugin's imports from inside the profile first, so the plugin gets those old copies — for example `@deepseek-ai/schemastery` 3.18.2, which has no `Schema.volatile()`, so the module throws while it is imported. When an import fails the Loader creates no fiber for that row and no client bundle is composed either, so the model route, the RPC channel, and the settings panel all stay absent.
234
236
 
235
- Recovery: **uninstall** the plugin on the **Plugins** page, **install** it again with the version in the package name (for example `dsh-packycode-api@1.3.5`), then quit and reopen the desktop application. Uninstall runs `pnpm remove` and deletes the whole package directory; reinstalling or clicking **Update** only rewrites files and keeps the leftover tree. Deleting that `node_modules` by hand and restarting works too.
237
+ Recovery: **uninstall** the plugin on the **Plugins** page, **install** it again with the version in the package name (for example `dsh-packycode-api@1.3.6`), then quit and reopen the desktop application. Uninstall runs `pnpm remove` and deletes the whole package directory; reinstalling or clicking **Update** only rewrites files and keeps the leftover tree. Deleting that `node_modules` by hand and restarting works too.
236
238
 
237
239
  **Right after a first install, every card in Settings shows `transport failure for /packycode-api/…: HTTP 405`?** The installed version is 1.1.6 or earlier, usually because only the bare package name was entered: the install prompt shows the newest version, but pnpm installs the newest one published at least 24 hours ago (see **Install the plugin**). Those older versions can register their settings channel only after DSH restarts and rebuilds its `connection` service. So right after a first install `/packycode-api` does not exist yet, requests fall through to the static page, and it answers 405; the model route and the settings panel itself load normally. From 1.1.7 on, a first install needs no restart. Check which version was installed:
238
240
 
package/README.md CHANGED
@@ -47,10 +47,10 @@
47
47
  打开桌面应用的**插件**页,点击**添加插件**,在**包名或地址**中填入**带版本号**的包名:
48
48
 
49
49
  ```text
50
- dsh-packycode-api@1.3.5
50
+ dsh-packycode-api@1.3.6
51
51
  ```
52
52
 
53
- 在**安装源**中选择**官方源**,然后点击**安装**。`1.3.5` 是写这份说明时的最新版,当前最新版本号以 [npm 页面](https://www.npmjs.com/package/dsh-packycode-api) 为准。
53
+ 在**安装源**中选择**官方源**,然后点击**安装**。`1.3.6` 是写这份说明时的最新版,当前最新版本号以 [npm 页面](https://www.npmjs.com/package/dsh-packycode-api) 为准。
54
54
 
55
55
  > **一定要带版本号。** 只填 `dsh-packycode-api` 时,安装前的提示显示的是 npm 上的最新版,但 DSH 自带的 pnpm 默认只安装发布满 24 小时的版本,实际装上的可能是好几个版本之前的旧版,而安装提示里看不出这一点。填写精确版本时,pnpm 会直接安装这个版本,并自动把它加入 profile 的 `minimumReleaseAgeExclude`。装好后可以在 **设置 → PackyCode → 插件版本** 核对「当前版本」。
56
56
 
@@ -71,7 +71,7 @@ dsh-packycode-api@1.3.5
71
71
 
72
72
  桌面应用的**插件**页可以看到已安装状态与版本,也可以在那里启用、停用或卸载。
73
73
 
74
- **仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.3.5`。不要对 `desktop` 使用它 —— CLI 会直接拒绝(`profile "desktop" is managed exclusively by the Electron application`)。
74
+ **仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.3.6`。不要对 `desktop` 使用它 —— CLI 会直接拒绝(`profile "desktop" is managed exclusively by the Electron application`)。
75
75
 
76
76
  本地开发要加 `link:` 前缀:`dsh plugin --profile <name> add link:/path/to/dsh-packycode-api`。**不要直接写路径(或 `file:`)** —— 那样的安装会把整个仓库目录(连同 `node_modules`)复制进 profile,之后它会在 profile 内部挡住 DSH 自带的包,插件看起来像没装,见「常见问题」。已经那样装过的话,先卸载再按上面的方式重装。
77
77
 
@@ -170,7 +170,7 @@ Claude 与其它模型一样,通过 DSH 的 `packycode_image_generate` 工具
170
170
 
171
171
  | 模型 | 怎么调用 | 推理档位 | 适合的令牌分组 |
172
172
  | --- | --- | --- | --- |
173
- | `deepseek-flash` | HTTP,chat/completions,可带图 | 可关;`low` / `high` / `max` | `deepseek-officially`、`deepseek-sale` |
173
+ | `deepseek-flash` | HTTP,Responses,可带图 | 可关;`low` / `high` / `max` | `deepseek-officially`、`deepseek-sale` |
174
174
  | `gpt-6.1-sol` | HTTP,Responses,可带图 | 不能关;`low` / `medium` / `high` / `xhigh` / `max` | `codex`、`codex-sale` |
175
175
  | `gpt-6-astra` | 同上 | 同上 | 同上 |
176
176
  | `gpt-5.6-sol` | 同上 | 同上 | 同上 |
@@ -183,7 +183,7 @@ Claude 与其它模型一样,通过 DSH 的 `packycode_image_generate` 工具
183
183
 
184
184
  列表里看得到模型,不代表当前令牌分组一定放行。换分组时不要把对应分组一起去掉。
185
185
 
186
- 当前目录中的 10 个模型都声明了文字和图像输入。DeepSeek Flash 的识图能力按 [官方图像理解文档](https://api-docs.deepseek.com/zh-cn/guides/vision/) 配置;图片通过 DSH 附件服务读取,再随 chat/completions 请求发送。
186
+ 当前目录中的 10 个模型都声明了文字和图像输入。DeepSeek Flash 的识图能力按 [官方图像理解文档](https://api-docs.deepseek.com/zh-cn/guides/vision/) 配置;图片通过 DSH 附件服务读取,再随 Responses 请求发送。
187
187
 
188
188
  Gemini 的能力与限制来自 Google 官方模型页:[Gemini 4 Argon](https://ai.google.dev/gemini-api/docs/models/gemini-4-argon)、[Gemini 3.8 Flash](https://ai.google.dev/gemini-api/docs/models/gemini-3.8-flash)。两款模型统一使用 Gemini 原生协议,通过 `/v1beta/models/{model}:streamGenerateContent` 流式返回文字、思考和工具调用,图片仍由 DSH 附件服务读取。思考档位通过 `thinkingLevel` 传入。两者均使用单次流式输出上限,不执行超过 65,536 token 的自动续写。可用端点与分组以 [PackyAPI 实时模型目录](https://www.packyapi.com/api/pricing) 为准。
189
189
 
@@ -191,7 +191,9 @@ Gemini 的能力与限制来自 Google 官方模型页:[Gemini 4 Argon](https:
191
191
 
192
192
  Grok 4.7 的上下文与推理档位来自 [官方文档](https://docs.x.ai/developers/grok-4-7)。官方没有单独限制文字输出长度;插件将输出上限设为上下文大小,并按每次请求的剩余上下文收紧。
193
193
 
194
- Responses 请求只有 GPT 模型保留 `prompt_cache_key`,其他 Responses 模型默认省略。当前网关的 Grok 路由会将这个字段误报成 `Incorrect API key provided`。
194
+ Responses 请求只有 GPT 模型保留 `prompt_cache_key`,其他 Responses 模型默认省略。当前网关的 Grok 路由会将这个字段误报成 `Incorrect API key provided`;DeepSeek Flash 不带它也能命中前缀缓存。
195
+
196
+ DeepSeek Flash 走网关的 Responses 接口(`/api/pricing` 列出 `openai-response`)。关闭推理时发送 `reasoning.effort: "none"`,网关返回时不带思考;开启时思考内容以 `reasoning_text` 返回,并随同一轮的工具调用一起回传。
195
197
 
196
198
  <details>
197
199
  <summary>协议、分组与客户端兼容性</summary>
@@ -214,9 +216,9 @@ Responses 请求只有 GPT 模型保留 `prompt_cache_key`,其他 Responses
214
216
 
215
217
  ## 更新与卸载
216
218
 
217
- > **从 1.3.2 或更早版本升级:** 请在插件页填写 `dsh-packycode-api@1.3.5` 安装,不要点旧版设置页里的「更新插件」。旧按钮安装时会绕过 pnpm 的发布冷却期:装到的版本如果发布还不满 24 小时,这个 profile 在它满 24 小时之前就装不了其他插件。装好并重启后,按钮就换成了修好的版本,以后直接点即可。
219
+ > **从 1.3.2 或更早版本升级:** 请在插件页填写 `dsh-packycode-api@1.3.6` 安装,不要点旧版设置页里的「更新插件」。旧按钮安装时会绕过 pnpm 的发布冷却期:装到的版本如果发布还不满 24 小时,这个 profile 在它满 24 小时之前就装不了其他插件。装好并重启后,按钮就换成了修好的版本,以后直接点即可。
218
220
 
219
- **更新:** 打开 **设置 → PackyCode**,有新版本时点「更新插件」。它会在当前 profile 目录里用 DSH 自带的 pnpm 安装精确版本,并读回 `package.json` 确认版本落地。安装遵守 pnpm 的发布冷却策略,不会绕过它:默认情况下 pnpm 会直接装上这个版本,并把它记进 profile 的 `minimumReleaseAgeExclude`;如果你给 pnpm 配了更严格的策略,按钮会提示什么时候可以更新。本地 `link:` 开发安装不会出现这个按钮。完成后完全退出并重新打开桌面应用。只刷新页面不会重载 Host。也可以在**插件**页重新安装,同样要填写带版本号的包名(例如 `dsh-packycode-api@1.3.5`),否则装上的可能是发布满 24 小时的旧版。
221
+ **更新:** 打开 **设置 → PackyCode**,有新版本时点「更新插件」。它会在当前 profile 目录里用 DSH 自带的 pnpm 安装精确版本,并读回 `package.json` 确认版本落地。安装遵守 pnpm 的发布冷却策略,不会绕过它:默认情况下 pnpm 会直接装上这个版本,并把它记进 profile 的 `minimumReleaseAgeExclude`;如果你给 pnpm 配了更严格的策略,按钮会提示什么时候可以更新。本地 `link:` 开发安装不会出现这个按钮。完成后完全退出并重新打开桌面应用。只刷新页面不会重载 Host。也可以在**插件**页重新安装,同样要填写带版本号的包名(例如 `dsh-packycode-api@1.3.6`),否则装上的可能是发布满 24 小时的旧版。
220
222
 
221
223
  **从本地路径安装切回官方源时,必须先卸载。** 「更新」是 `pnpm add`,它只重写包目录里的文件,不会删除更早一次本地路径安装留在包目录内的 `node_modules`;那份旧依赖会继续挡住 DSH 自带的包,插件行加载失败且看不出原因。「卸载」执行的是 `pnpm remove`,会删掉整个包目录,重装才是干净的。用 `node scripts/install-check.mjs` 可以确认当前 profile 是否处于这个状态。
222
224
 
@@ -232,7 +234,7 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
232
234
 
233
235
  有输出就是残留:从 npm 安装的包不会自带 `node_modules`,这一份通常来自更早一次「本地路径」安装(`file:` 或直接写路径,而不是 `link:`)。它位于 profile 目录内部,而 DSH 解析插件导入时优先使用 profile 内的副本,所以插件拿到的仍是那份旧依赖 —— 例如 `@deepseek-ai/schemastery` 3.18.2 没有 `Schema.volatile()`,模块在导入阶段就抛错。导入失败时 Loader 不会为这一行创建 fiber,客户端 bundle 也不会被组合,于是模型路由、RPC 通道和设置页全都不会出现。
234
236
 
235
- 修复:到**插件**页**卸载**本插件,再用带版本号的包名重新**安装**(例如 `dsh-packycode-api@1.3.5`),然后完全退出并重新打开桌面应用。卸载执行的是 `pnpm remove`,会删掉整个包目录;直接重装或点「更新」只重写文件,不会清掉这份残留。也可以手动删掉上面那个 `node_modules` 再重启。
237
+ 修复:到**插件**页**卸载**本插件,再用带版本号的包名重新**安装**(例如 `dsh-packycode-api@1.3.6`),然后完全退出并重新打开桌面应用。卸载执行的是 `pnpm remove`,会删掉整个包目录;直接重装或点「更新」只重写文件,不会清掉这份残留。也可以手动删掉上面那个 `node_modules` 再重启。
236
238
 
237
239
  **首次安装后,设置页每张卡片都显示 `transport failure for /packycode-api/…: HTTP 405`?** 实际装上的是 1.1.6 或更早的版本,通常是因为安装时只填了包名:安装提示显示的是最新版,pnpm 实际装的却是发布满 24 小时的旧版(见「安装插件」)。这些旧版要等 DSH 重启、重建它的 `connection` 服务之后,才能注册设置通道。所以首次安装后 `/packycode-api` 通道还不存在,请求落到静态页面,返回 405;模型路由和设置页本身照常加载。1.1.7 起首次安装不需要重启。先确认装上的版本:
238
240
 
package/lib/index.js CHANGED
@@ -14,7 +14,6 @@ import { PiAiAdapter } from "@deepseek-ai/dsh-llm-pi-ai";
14
14
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
15
15
  import { lazyStream } from "@earendil-works/pi-ai/api/lazy";
16
16
  import { clampThinkingLevel, createProvider } from "@earendil-works/pi-ai";
17
- import { openAICompletionsApi } from "@earendil-works/pi-ai/api/openai-completions.lazy";
18
17
  import { openAIResponsesApi } from "@earendil-works/pi-ai/api/openai-responses.lazy";
19
18
  import { anthropicMessagesApi } from "@earendil-works/pi-ai/api/anthropic-messages.lazy";
20
19
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -3251,8 +3250,8 @@ function createDiagnostics({ sessionQuery, readEvents, ring, groups, secrets = a
3251
3250
  *
3252
3251
  * The gateway's own guidance for these routes, which the base URLs and pinned
3253
3252
  * protocols below exist to satisfy:
3254
- * - OpenAI/Codex traffic takes `/v1` in the base URL and never an endpoint
3255
- * path — the SDK appends `/responses` or `/chat/completions` itself.
3253
+ * - OpenAI-protocol traffic takes `/v1` in the base URL and never an endpoint
3254
+ * path — the SDK appends `/responses` itself.
3256
3255
  * - Anthropic traffic takes `https://cf.api.fan` with **no** `/v1`: the
3257
3256
  * Anthropic client appends `/v1/messages` itself.
3258
3257
  * - A model asked over the wrong protocol does not fail cleanly; the stream
@@ -3262,7 +3261,7 @@ function createDiagnostics({ sessionQuery, readEvents, ring, groups, secrets = a
3262
3261
  * model does not support is refused before the request is sent: Claude Opus
3263
3262
  * 5.5 (platform.claude.com effort docs), GPT-6.1 Sol, GPT-6 Astra and GPT-5.6
3264
3263
  * Sol `reasoning.effort` (developers.openai.com model pages), DeepSeek
3265
- * thinking mode (`thinking` toggle plus `low|high|max` effort), Grok 4.7
3264
+ * thinking mode (`low|high|max` effort, or off), Grok 4.7
3266
3265
  * (docs.x.ai/developers/grok-4-7), and Gemini 4 Argon
3267
3266
  * (ai.google.dev/gemini-api/docs/models/gemini-4-argon and docs/openai).
3268
3267
  *
@@ -3275,15 +3274,14 @@ const NO_COST = Object.freeze({
3275
3274
  cacheRead: 0,
3276
3275
  cacheWrite: 0
3277
3276
  });
3278
- const COMPLETIONS_BASE = `${DEFAULT_API_HOST}/v1`;
3279
3277
  const RESPONSES_BASE = `${DEFAULT_API_HOST}/v1`;
3280
3278
  const MESSAGES_BASE = DEFAULT_API_HOST;
3281
3279
  const GEMINI_BASE = `${DEFAULT_API_HOST}/v1beta`;
3282
3280
  /**
3283
3281
  * pi-ai thinking-level maps. A level pinned to `null` is unsupported; an
3284
3282
  * absent key keeps pi-ai's own default for that level, which is how `off`
3285
- * stays available for DeepSeek (`off` sends nothing and the deepseek dialect
3286
- * then emits `thinking: disabled`).
3283
+ * stays available for DeepSeek: pi-ai's Responses API then sends
3284
+ * `reasoning.effort: "none"`, which the gateway answers without reasoning.
3287
3285
  */
3288
3286
  const DEEPSEEK_LEVELS = Object.freeze({
3289
3287
  minimal: null,
@@ -3322,21 +3320,15 @@ const PACKYCODE_MODELS = Object.freeze([
3322
3320
  Object.freeze({
3323
3321
  id: "deepseek-flash",
3324
3322
  name: "DeepSeek Flash",
3325
- api: "openai-completions",
3323
+ api: "openai-responses",
3326
3324
  provider: PROVIDER,
3327
- baseUrl: COMPLETIONS_BASE,
3325
+ baseUrl: RESPONSES_BASE,
3328
3326
  reasoning: true,
3329
3327
  input: Object.freeze(["text", "image"]),
3330
3328
  cost: NO_COST,
3331
3329
  contextWindow: 1e6,
3332
3330
  maxTokens: 384e3,
3333
- thinkingLevelMap: DEEPSEEK_LEVELS,
3334
- compat: Object.freeze({
3335
- thinkingFormat: "deepseek",
3336
- maxTokensField: "max_tokens",
3337
- requiresReasoningContentOnAssistantMessages: true,
3338
- supportsDeveloperRole: false
3339
- })
3331
+ thinkingLevelMap: DEEPSEEK_LEVELS
3340
3332
  }),
3341
3333
  Object.freeze({
3342
3334
  id: "gpt-6.1-sol",
@@ -5829,8 +5821,8 @@ function createGeminiApi() {
5829
5821
  * The PackyCode pi-ai provider, built in code so the user configures no route.
5830
5822
  *
5831
5823
  * `createProvider` dispatches on `model.api`, which is what lets one route
5832
- * carry Chat Completions, Responses, Anthropic Messages and native Gemini
5833
- * models — the gateway refuses some of them over other protocols.
5824
+ * carry Responses, Anthropic Messages and native Gemini models — the gateway
5825
+ * refuses some of them over other protocols.
5834
5826
  *
5835
5827
  * @module dsh-packycode-api/provider
5836
5828
  */
@@ -5874,7 +5866,6 @@ function createPackyCodeProvider({ claudeCli } = {}) {
5874
5866
  auth: keyRingAuth(),
5875
5867
  models: PACKYCODE_MODELS,
5876
5868
  api: {
5877
- "openai-completions": openAICompletionsApi(),
5878
5869
  "openai-responses": openAIResponsesApi(),
5879
5870
  "anthropic-messages": createClaudeApi({ cli: claudeCli }),
5880
5871
  "google-generative-ai": createGeminiApi()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-packycode-api",
3
- "version": "1.3.5",
3
+ "version": "1.3.6",
4
4
  "description": "Use PackyCode API keys in DeepSeek Harness with multi-protocol models, image generation and editing, separate key rings, and balance display",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",