dsh-packycode-api 1.4.11 → 1.4.13

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,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.4.13
4
+
5
+ - **Claude Code history rebuilds use the gateway compatibility setting.** With Claude Code 2.1.325, resuming a transcript rebuilt from DSH's history can add a `role: "system", content: []` control message carrying `output_config.effort` and the `per-turn-control-2026-07-01` beta. A gateway that cannot pass through the pair rejects it with `messages.1: system content must contain at least one block`; even one previous user/assistant exchange can trigger the shape. The CLI child environment now sets `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1` directly, so no isolated-settings workaround is needed. Inherited Claude environment variables are still filtered, and neither personal nor project configuration is changed.
6
+ - **The compatibility scope is explicit.** The [official setting](https://code.claude.com/docs/en/llm-gateway-protocol#disable-pre-release-capabilities) removes pre-release headers and paired fields, including per-turn effort, experimental context management, structured-output format, task budget, some tool-schema fields and MCP tool search. Top-level effort, adaptive thinking and nonempty mid-conversation system messages remain. Both READMEs explain this tradeoff; group-based routing, the CLI's own prompt and tools, and DSH's permission, plan and question bridges are unchanged.
7
+ - Validation, 2026-11-15:
8
+ - **Offline:** 582 tests, both rebuilt bundles and the versioned tarball. A regression test requires the child compatibility setting for fresh and continued turns even when the parent sets it to `0`; transport tests check the actual fresh, resumed and rebuilt process environments. With the real Claude Code 2.1.325 and a loopback endpoint that rejects empty system entries, fresh, resumed, short rebuilt and 743-message rebuilt histories all passed under the default configuration and with the old isolated-settings workaround. No per-turn beta, message-level effort or empty control entry remained; top-level `max` and adaptive thinking stayed. Before the fix, both rebuild cases returned the same 400 in this harness.
9
+ - **Live, stored `cc` key and Claude Code 2.1.325:** `scripts/claude-check.mjs --transport cli` ran read, approved edit, denied deletion, plan review, question, image and title scenarios on Fable 5.2, Opus 5.5, Sonnet 5.5 and Haiku 5.5. Of 28 scenarios, 22 passed first time; six hit `ECONNRESET` (56 transport requests overall). Re-running only those six passed all of them in 15 transport requests. Both summaries counted zero client-anomaly and anti-abuse refusals. Separately, Opus 5.5 at `max` answered an inventory calculation correctly on a fresh session, after restarting and resuming it, and after rebuilding a short DSH history; all three returned 200 without the empty-system error. All checks used scratch workspaces and isolated CLI directories.
10
+ - **Not checked:** the original private long conversation or the desktop app's GUI. The real gateway's internal handling of per-turn controls was not inspected. Personal Claude settings, existing DSH sessions and credentials were not modified.
11
+
12
+ ## 1.4.12
13
+
14
+ - **Gemini 4 Carbon joins the catalog.** The plugin's stored key lists `gemini-4-carbon` in PackyCode's `/v1/models` with only the native `gemini` endpoint. The model uses `google-generative-ai` at `https://cf.api.fan/v1beta`, with text/image input, 1,048,576 context and 65,536 output per stream, following [Google's model page](https://aistudio.google.com/docs/models/gemini-4-carbon). Its thinking map offers `low` / `medium` / `high`, with no off, and the native SDK defaults to `medium`, following [Google's migration guide](https://aistudio.google.com/docs/whats-new-gemini-4-carbon). Longer output requires a separate continuation flow that this route does not implement.
15
+ - **Carbon uses the existing Gemini integration.** It appears before Argon, is selected by default with existing model preferences, and participates in the settings page's Gemini coverage indicator. Its requests use the same thinking-level normalization and documented signature-skip value as the other Gemini models, while DSH retains returned signatures for replay. Coverage still follows the key's live model list and the gateway's pricing data; no group is guessed from the model name.
16
+ - Validation, 2026-11-14:
17
+ - **Offline:** 581 tests, both rebuilt bundles and the versioned tarball. Carbon's three thinking levels, default level, image input, signed tool replay, host metadata, default selection, group coverage and built settings indicator are covered.
18
+ - **Live:** `scripts/live-check.mjs --model gemini-4-carbon --with-vision` returned `ok` at `high` and identified red and blue images at `low`. `scripts/gemini-tool-check.mjs --model gemini-4-carbon --reasoning medium` completed a tool call and its durable DSH continuation, with one HTTP 200 continuation request and the final answer `ok`. Both scripts used only a key already stored by this plugin.
19
+ - **Not checked:** the desktop app's own model picker and conversation flow; unrelated models were not re-probed for this catalog addition.
20
+
3
21
  ## 1.4.11
4
22
 
5
23
  - **QQ community at the bottom of the README and settings.** Both README languages now end with the plugin community's QR code. The PackyCode settings page ends with a localized Community and feedback card after Diagnostics, with the same original image scaled to fit the available width.
package/README.en.md CHANGED
@@ -48,10 +48,10 @@ You need **DeepSeek Harness** and a **PackyCode (PackyAPI) API key**. For DSH se
48
48
  Open the desktop application's **Plugins** page, click **Add plugin**, and enter the package name **with a version** as the **package name or address**:
49
49
 
50
50
  ```text
51
- dsh-packycode-api@1.4.11
51
+ dsh-packycode-api@1.4.13
52
52
  ```
53
53
 
54
- Choose the **official** install source, then click **Install**. `1.4.11` was the latest release when this was written; the [npm page](https://www.npmjs.com/package/dsh-packycode-api) shows the current one.
54
+ Choose the **official** install source, then click **Install**. `1.4.13` was the latest release when this was written; the [npm page](https://www.npmjs.com/package/dsh-packycode-api) shows the current one.
55
55
 
56
56
  > **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**.
57
57
 
@@ -65,14 +65,14 @@ Open **Settings → PackyCode**. Paste the API key under **Add a key**. A label
65
65
 
66
66
  ### 3. Select a model
67
67
 
68
- Choose a model from the `PackyCode` group. Of the thirteen models, Claude runs through this device's Claude Code CLI on `cc` keys; everything else uses the plugin’s HTTP route. Your key’s groups must cover the selected model.
68
+ Choose a model from the `PackyCode` group. Of the fifteen models, Claude runs through this device's Claude Code CLI on `cc` keys; everything else uses the plugin’s HTTP route. Your key’s groups must cover the selected model.
69
69
 
70
70
  <details>
71
71
  <summary>Verify the install / other profiles / a local checkout</summary>
72
72
 
73
73
  The **Plugins** page shows the installed state and version, and is also where you enable, disable, or uninstall.
74
74
 
75
- **For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.4.11`. Do not use it for `desktop` — the CLI refuses it (`profile "desktop" is managed exclusively by the Electron application`).
75
+ **For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.4.13`. Do not use it for `desktop` — the CLI refuses it (`profile "desktop" is managed exclusively by the Electron application`).
76
76
 
77
77
  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.
78
78
 
@@ -142,6 +142,7 @@ PackyCode's `cc` group (“claude code专用”) only serves the official Claude
142
142
  - **Plan mode and questions happen in DSH.** After `/plan`, Claude Code enters its own plan mode, writes the plan to a file and submits it; DSH shows it in its own plan review, approval continues under the preset, and “keep planning” sends your feedback back for revision. Claude Code's questions appear in DSH's question UI.
143
143
  - **One Claude Code session per DSH session.** A DSH session keeps one long-lived CLI process; after it idles out (20 minutes), DSH restarts, or the model or key changes, the next request resumes Claude Code's own saved session. After an edited message, a fork, or a switch from another model, a new Claude Code session starts from DSH's history. When you add a note while Claude Code is working, the plugin stops its current request and gives it the note as its next message. Compaction DSH starts is answered with a local summary; Claude Code compacts its own context itself.
144
144
  - **Isolated from your own Claude Code.** It runs with its own config home, `~/.dsh/packycode-claude-cli`, and reads neither `~/.claude` settings and logins nor a project's `.claude/settings.json`, hooks or `.mcp.json`; only the key stored in the plugin is passed to the child. Auto-update, telemetry, auto-memory, background tasks and model fallback are off, and retries are left to DSH's retry policy, which rotates keys.
145
+ - **Gateway compatibility is enabled by default.** The plugin sets `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1` in the CLI child process so rebuilding conversation history does not send empty per-turn effort control messages that the gateway rejects with `system content must contain at least one block`. No manual configuration is needed. This [official compatibility setting](https://code.claude.com/docs/en/llm-gateway-protocol#disable-pre-release-capabilities) also disables experimental context management, structured-output format, task budget, some tool-schema fields and MCP tool search; top-level effort, adaptive thinking and ordinary nonempty system messages remain. It affects only Claude Code processes started by the plugin, without changing your Claude settings or other models' HTTP requests.
145
146
  - **An outdated CLI is one click away from current.** The plugin needs Claude Code 2.1.259 or later (tested from that release on with the permission prompts and mode switches the plugin uses). An older CLI is stopped before the request with an explanation, and the CLI card marks it too old and offers **Update Claude Code CLI**: an install from the official installer (`~/.local/bin/claude`) runs `claude update`; an npm global install runs `npm install -g @anthropic-ai/claude-code@latest --allow-scripts=@anthropic-ai/claude-code`, because npm 12 skips install scripts by default and `claude update` does not allow them on an npm install, which leaves a CLI that cannot run. When the CLI works but is not the latest release, the card names the new version and offers the same button: the plugin reads `latest` of `@anthropic-ai/claude-code` from npm on this device (the same version as the native installer's `latest` channel), at most once every 30 minutes, and again when you click Check again; without an answer it offers nothing. Your Claude Code is only updated when you click that button.
146
147
  - **Failures say why.** A missing CLI, an outdated CLI, and a request the gateway still refuses as a client anomaly each get their own explanation; nothing switches to another route or provider, and no key is disabled.
147
148
 
@@ -234,6 +235,7 @@ The card shows whether DSH's plugin is on, how many reviews this plugin answered
234
235
  | `gpt-5.6-sol` | Same | Same | Same |
235
236
  | `grok-4.7` (Grok 4.7) | HTTP, Responses, text/image input; 500K context | Cannot be off; `low` / `medium` / `high` / `xhigh` | The Grok coverage read from the gateway in Settings |
236
237
  | `hy4` (Hy4, Tencent Hunyuan) | HTTP, Responses, text/image input; 1024K context (at most 960K input), 64K output | Can be off; `high` only | `hunyuan-officially` |
238
+ | `gemini-4-carbon` (Gemini 4 Carbon) | HTTP, native Gemini streaming, text/image input; 1,048,576 context, 65,536 output | Cannot be off; `low` / `medium` / `high` | See the key's live model list |
237
239
  | `gemini-4-argon` (Gemini 4 Argon) | HTTP, native Gemini streaming, text/image input; 1,048,576 context, 65,536 output | Cannot be off; `low` / `medium` / `high` | `gemini-slb` |
238
240
  | `gemini-3.8-flash` (Gemini 3.8 Flash) | HTTP, native Gemini streaming, text/image input; 1,048,576 input, 65,536 output | Cannot be off; `low` / `medium` / `high` | `gemini-slb` |
239
241
  | `claude-fable-5-2` (Claude Fable 5.2) | Anthropic Messages, images and native tools: this device's Claude Code CLI as the agent for `cc` keys, HTTP otherwise; 1M context, 128K output | Cannot be off; `low` / `medium` / `high` / `xhigh` / `max` | Claude-group coverage reported in Settings |
@@ -245,11 +247,11 @@ A model in the list does not mean the current token group allows it. When changi
245
247
 
246
248
  `jev-1.14.0` (TypeSafe Jev) is not in the model picker: it is a decision model that answers classification questions and cannot hold a conversation, so it only serves [Auto review](#auto-review). PackyCode lists it by version and no longer offers the `jev-latest` alias, so the plugin sends `jev-1.14.0` itself. It calls `/v1/systemone` host-side and needs a key in the `typesafe-officially` group; each key's Jev entry under Accounts and keys shows whether it can.
247
249
 
248
- Of the thirteen models in the current catalog, all but DeepSeek V4 Pro 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. DeepSeek V4 Pro takes text only, per DeepSeek's [models and pricing page](https://api-docs.deepseek.com/quick_start/pricing/): DSH does not let you attach an image to it, and an image already in the session (say, one switched over from Flash) is sent as a one-line "image omitted" note. PackyCode's gateway does not refuse an image sent to V4 Pro; it drops it.
250
+ Of the fifteen models in the current catalog, all but DeepSeek V4 Pro 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. DeepSeek V4 Pro takes text only, per DeepSeek's [models and pricing page](https://api-docs.deepseek.com/quick_start/pricing/): DSH does not let you attach an image to it, and an image already in the session (say, one switched over from Flash) is sent as a one-line "image omitted" note. PackyCode's gateway does not refuse an image sent to V4 Pro; it drops it.
249
251
 
250
- 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).
252
+ Gemini capabilities and limits follow Google's model pages: [Gemini 4 Carbon](https://aistudio.google.com/docs/models/gemini-4-carbon), [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). All three 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`. All three 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).
251
253
 
252
- **Gemini tool continuation and thought signatures:** PackyCode's native Gemini route does not handle thought signatures in tool calls correctly. It answers HTTP 400 `Invalid thought signature` / `Corrupted thought signature`, and resending the same request does not help (PackyCode support's answer). For Gemini 4 Argon and Gemini 3.8 Flash the plugin therefore sends none of the signatures the model returned. Wherever a signature is required, it sends Google's documented validator-skip value `skip_thought_signature_validator` ([Google's guide](https://ai.google.dev/gemini-api/docs/thought-signatures)). The protocol, endpoint and model stay the same, and DSH's replay record keeps the original signatures. Google notes that skipped signatures can weaken reasoning continuity across tool steps. Flash keeps its earlier safeguard: after an HTTP 400 signature refusal before any stream event, it waits one second and resends once. Such a 400 is never treated as a failed key.
254
+ **Gemini tool continuation and thought signatures:** PackyCode's native Gemini route does not handle thought signatures in tool calls correctly. It answers HTTP 400 `Invalid thought signature` / `Corrupted thought signature`, and resending the same request does not help (PackyCode support's answer). For Gemini 4 Carbon, Gemini 4 Argon and Gemini 3.8 Flash the plugin therefore sends none of the signatures the model returned. Wherever a signature is required, it sends Google's documented validator-skip value `skip_thought_signature_validator` ([Google's guide](https://ai.google.dev/gemini-api/docs/thought-signatures)). The protocol, endpoint and model stay the same, and DSH's replay record keeps the original signatures. Google notes that skipped signatures can weaken reasoning continuity across tool steps. Flash keeps its earlier safeguard: after an HTTP 400 signature refusal before any stream event, it waits one second and resends once. Such a 400 is never treated as a failed key.
253
255
 
254
256
  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.
255
257
 
@@ -282,9 +284,9 @@ DeepSeek Flash uses the gateway's Responses endpoint (`/api/pricing` lists `open
282
284
 
283
285
  ## Update and uninstall
284
286
 
285
- > **Upgrading from 1.3.2 or earlier:** install `dsh-packycode-api@1.4.11` 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.
287
+ > **Upgrading from 1.3.2 or earlier:** install `dsh-packycode-api@1.4.13` 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.
286
288
 
287
- **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. The newer version is read from npm, while pnpm downloads it from the profile's own install source: right after a release that source (a regional mirror in particular) may not have it yet, and the button asks you to update again in a few minutes; when the source cannot be reached, it asks you to check the network or proxy. 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.4.11`); without it you may get a version that is merely the newest one published at least 24 hours ago.
289
+ **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. The newer version is read from npm, while pnpm downloads it from the profile's own install source: right after a release that source (a regional mirror in particular) may not have it yet, and the button asks you to update again in a few minutes; when the source cannot be reached, it asks you to check the network or proxy. 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.4.13`); without it you may get a version that is merely the newest one published at least 24 hours ago.
288
290
 
289
291
  **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.
290
292
 
@@ -300,7 +302,7 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
300
302
 
301
303
  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.
302
304
 
303
- Recovery: **uninstall** the plugin on the **Plugins** page, **install** it again with the version in the package name (for example `dsh-packycode-api@1.4.11`), 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.
305
+ Recovery: **uninstall** the plugin on the **Plugins** page, **install** it again with the version in the package name (for example `dsh-packycode-api@1.4.13`), 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.
304
306
 
305
307
  **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:
306
308
 
package/README.md CHANGED
@@ -48,10 +48,10 @@
48
48
  打开桌面应用的**插件**页,点击**添加插件**,在**包名或地址**中填入**带版本号**的包名:
49
49
 
50
50
  ```text
51
- dsh-packycode-api@1.4.11
51
+ dsh-packycode-api@1.4.13
52
52
  ```
53
53
 
54
- 在**安装源**中选择**官方源**,然后点击**安装**。`1.4.11` 是写这份说明时的最新版,当前最新版本号以 [npm 页面](https://www.npmjs.com/package/dsh-packycode-api) 为准。
54
+ 在**安装源**中选择**官方源**,然后点击**安装**。`1.4.13` 是写这份说明时的最新版,当前最新版本号以 [npm 页面](https://www.npmjs.com/package/dsh-packycode-api) 为准。
55
55
 
56
56
  > **一定要带版本号。** 只填 `dsh-packycode-api` 时,安装前的提示显示的是 npm 上的最新版,但 DSH 自带的 pnpm 默认只安装发布满 24 小时的版本,实际装上的可能是好几个版本之前的旧版,而安装提示里看不出这一点。填写精确版本时,pnpm 会直接安装这个版本,并自动把它加入 profile 的 `minimumReleaseAgeExclude`。装好后可以在 **设置 → PackyCode → 插件版本** 核对「当前版本」。
57
57
 
@@ -65,14 +65,14 @@ dsh-packycode-api@1.4.11
65
65
 
66
66
  ### 3. 选择模型
67
67
 
68
- 回到对话,在模型选择器里选 `PackyCode` 分组下的模型。十三个模型里,Claude 在 `cc` 分组的 Key 上由本机 Claude Code CLI 执行,其余都通过插件内 HTTP 调用;Key 的分组必须覆盖所选模型。
68
+ 回到对话,在模型选择器里选 `PackyCode` 分组下的模型。十五个模型里,Claude 在 `cc` 分组的 Key 上由本机 Claude Code CLI 执行,其余都通过插件内 HTTP 调用;Key 的分组必须覆盖所选模型。
69
69
 
70
70
  <details>
71
71
  <summary>检查安装 / 其它 profile / 本地目录</summary>
72
72
 
73
73
  桌面应用的**插件**页可以看到已安装状态与版本,也可以在那里启用、停用或卸载。
74
74
 
75
- **仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.4.11`。不要对 `desktop` 使用它 —— CLI 会直接拒绝(`profile "desktop" is managed exclusively by the Electron application`)。
75
+ **仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.4.13`。不要对 `desktop` 使用它 —— CLI 会直接拒绝(`profile "desktop" is managed exclusively by the Electron application`)。
76
76
 
77
77
  本地开发要加 `link:` 前缀:`dsh plugin --profile <name> add link:/path/to/dsh-packycode-api`。**不要直接写路径(或 `file:`)** —— 那样的安装会把整个仓库目录(连同 `node_modules`)复制进 profile,之后它会在 profile 内部挡住 DSH 自带的包,插件看起来像没装,见「常见问题」。已经那样装过的话,先卸载再按上面的方式重装。
78
78
 
@@ -142,6 +142,7 @@ PackyCode 的 `cc` 分组(「claude code专用」)只接受官方 Claude Cod
142
142
  - **计划模式和提问也在 DSH 里完成。** `/plan` 后 Claude Code 进入它自己的计划模式,把计划写成文件再提交;DSH 用自己的计划审阅界面展示,批准后按预设继续,选「继续规划」时你的反馈会交给它修改。Claude Code 向你提问时,问题出现在 DSH 的提问界面。
143
143
  - **一个 DSH 会话对应一个 Claude Code 会话。** 同一个 DSH 会话复用一个常驻 CLI 进程;进程空闲 20 分钟结束、DSH 重启、换模型或换 Key 后,用 Claude Code 自己保存的会话记录续接。编辑过历史消息、分叉会话或从别的模型切过来时,用 DSH 的历史新开一个 Claude Code 会话。你在 Claude Code 工作时插话,插件会停下它当前的请求,把这句话作为下一条消息交给它。DSH 发起的历史压缩在本地生成摘要,Claude Code 自己的上下文由它自己压缩。
144
144
  - **与你自己的 Claude Code 隔离。** 使用独立配置目录 `~/.dsh/packycode-claude-cli`,不读取 `~/.claude` 的设置和登录状态,也不读项目里的 `.claude/settings.json`、hooks 和 `.mcp.json`;只把插件保存的 Key 交给子进程。自动更新、遥测、自动记忆、后台任务和模型回退都关闭,失败重试交还给 DSH 的重试策略(会按 Key 轮换)。
145
+ - **默认启用网关兼容设置。** 插件在 CLI 子进程中设置 `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1`,避免重建会话历史时,逐轮 effort 产生的空 `system` 控制消息被网关以 `system content must contain at least one block` 拒绝,无需手动编辑配置。这个[官方兼容开关](https://code.claude.com/docs/en/llm-gateway-protocol#disable-pre-release-capabilities)也会关闭实验性 context management、结构化输出格式、task budget、部分工具 schema 字段及 MCP 工具搜索;顶层 effort、adaptive thinking 和普通非空 system 消息保留。它只影响插件启动的 Claude Code,不修改你的 Claude 设置或其它模型的 HTTP 请求。
145
146
  - **版本过低一键更新。** 插件需要 Claude Code 2.1.259 或更新版本(实测从这一版起支持插件用到的授权请求和权限模式切换)。更旧的 CLI 在请求发出前就被拦下并说明原因,CLI 卡片标出「版本过低」并提供「更新 Claude Code CLI」:官方安装器(`~/.local/bin/claude`)装的执行 `claude update`;npm 全局安装的执行 `npm install -g @anthropic-ai/claude-code@latest --allow-scripts=@anthropic-ai/claude-code`,因为 npm 12 默认不运行安装脚本,而 `claude update` 在 npm 安装上不会放行脚本,会留下一个无法运行的 CLI。CLI 能用但不是最新版时,卡片也会提示新版本并提供同一个按钮:插件在本机读取 npm 上 `@anthropic-ai/claude-code` 的 `latest`(与官方安装器的 `latest` 通道是同一版本),30 分钟内最多读一次,点「重新检测」立即重读;读不到时不提示。只有点这个按钮时才会更新你的 Claude Code。
146
147
  - **出错会说清原因。** 未安装 CLI、CLI 版本过旧、请求仍被网关判为客户端异常,分别给出说明和下一步,不会改走其它通道或提供商,也不会停用 Key。
147
148
 
@@ -234,6 +235,7 @@ DSH 自带一个实验性插件「自动授权审查」,默认关闭。开启
234
235
  | `gpt-5.6-sol` | 同上 | 同上 | 同上 |
235
236
  | `grok-4.7`(Grok 4.7) | HTTP,Responses,可带图;500k 上下文 | 不能关;`low` / `medium` / `high` / `xhigh` | 以设置页从网关读取的 Grok 分组覆盖为准 |
236
237
  | `hy4`(Hy4,腾讯混元) | HTTP,Responses,可带图;1024K 上下文(输入最多 960K),64K 输出 | 可关;只有 `high` | `hunyuan-officially` |
238
+ | `gemini-4-carbon`(Gemini 4 Carbon) | HTTP,Gemini 原生流式,可带图;1,048,576 上下文,65,536 输出 | 不能关;`low` / `medium` / `high` | 以 Key 的实时模型列表为准 |
237
239
  | `gemini-4-argon`(Gemini 4 Argon) | HTTP,Gemini 原生流式,可带图;1,048,576 上下文,65,536 输出 | 不能关;`low` / `medium` / `high` | `gemini-slb` |
238
240
  | `gemini-3.8-flash`(Gemini 3.8 Flash) | HTTP,Gemini 原生流式,可带图;1,048,576 输入,65,536 输出 | 不能关;`low` / `medium` / `high` | `gemini-slb` |
239
241
  | `claude-fable-5-2`(Claude Fable 5.2) | Anthropic Messages,可带图和原生工具:`cc` 分组由本机 Claude Code CLI 当 agent,其它分组走 HTTP;1M 上下文,128K 输出 | 不能关;`low` / `medium` / `high` / `xhigh` / `max` | 以设置页读取的 Claude 分组覆盖为准 |
@@ -245,11 +247,11 @@ DSH 自带一个实验性插件「自动授权审查」,默认关闭。开启
245
247
 
246
248
  `jev-1.14.0`(TypeSafe Jev)不在模型选择器里:它是只回答分类问题的决策模型,不能对话,只用于[自动审查](#自动审查)。PackyCode 按版本号列出它,不再提供 `jev-latest` 别名,所以插件直接发送 `jev-1.14.0`。插件在宿主侧直接调用 `/v1/systemone`,需要 Key 在 `typesafe-officially` 分组;「账户与 Key」里每个 Key 的「Jev」一项会显示能否使用。
247
249
 
248
- 当前目录的 13 个模型中,除 DeepSeek V4 Pro 外都声明了文字和图像输入。DeepSeek Flash 的识图能力按 [官方图像理解文档](https://api-docs.deepseek.com/zh-cn/guides/vision/) 配置;图片通过 DSH 附件服务读取,再随 Responses 请求发送。DeepSeek V4 Pro 按 [官方模型与价格页](https://api-docs.deepseek.com/zh-cn/quick_start/pricing/) 只收文字:DSH 不让给它附图,会话里已有的图片(比如从 Flash 切过来的会话)会换成一行「图片已省略」的说明再发送。PackyCode 网关收到发给 V4 Pro 的图片不报错,而是直接丢掉。
250
+ 当前目录的 15 个模型中,除 DeepSeek V4 Pro 外都声明了文字和图像输入。DeepSeek Flash 的识图能力按 [官方图像理解文档](https://api-docs.deepseek.com/zh-cn/guides/vision/) 配置;图片通过 DSH 附件服务读取,再随 Responses 请求发送。DeepSeek V4 Pro 按 [官方模型与价格页](https://api-docs.deepseek.com/zh-cn/quick_start/pricing/) 只收文字:DSH 不让给它附图,会话里已有的图片(比如从 Flash 切过来的会话)会换成一行「图片已省略」的说明再发送。PackyCode 网关收到发给 V4 Pro 的图片不报错,而是直接丢掉。
249
251
 
250
- 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) 为准。
252
+ Gemini 的能力与限制来自 Google 官方模型页:[Gemini 4 Carbon](https://aistudio.google.com/docs/models/gemini-4-carbon)、[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) 为准。
251
253
 
252
- **Gemini 工具续聊的思维签名:** PackyCode 的 Gemini 原生通道在工具调用场景下不能正确处理思维签名,会返回 HTTP 400 `Invalid thought signature` / `Corrupted thought signature`,原样重发也无济于事(PackyCode 客服的答复)。因此插件对 Gemini 4 Argon 和 Gemini 3.8 Flash 不再回传模型返回的签名,而是按 [Google 文档](https://ai.google.dev/gemini-api/docs/thought-signatures) 在需要签名的位置填入跳过校验的值 `skip_thought_signature_validator`。协议、端点和模型都不变,DSH 的回放记录仍保留原始签名。Google 提示跳过签名可能削弱多步工具调用之间的推理连贯性。Flash 仍保留原有兜底:HTTP 400 签名拒绝且尚未输出任何流事件时,等待 1 秒原样重发一次。这类 400 不会被当作 Key 失效。
254
+ **Gemini 工具续聊的思维签名:** PackyCode 的 Gemini 原生通道在工具调用场景下不能正确处理思维签名,会返回 HTTP 400 `Invalid thought signature` / `Corrupted thought signature`,原样重发也无济于事(PackyCode 客服的答复)。因此插件对 Gemini 4 Carbon、Gemini 4 Argon 和 Gemini 3.8 Flash 不再回传模型返回的签名,而是按 [Google 文档](https://ai.google.dev/gemini-api/docs/thought-signatures) 在需要签名的位置填入跳过校验的值 `skip_thought_signature_validator`。协议、端点和模型都不变,DSH 的回放记录仍保留原始签名。Google 提示跳过签名可能削弱多步工具调用之间的推理连贯性。Flash 仍保留原有兜底:HTTP 400 签名拒绝且尚未输出任何流事件时,等待 1 秒原样重发一次。这类 400 不会被当作 Key 失效。
253
255
 
254
256
  Grok 4.7 的上下文与推理档位来自 [官方文档](https://docs.x.ai/developers/grok-4-7)。官方没有单独限制文字输出长度;插件将输出上限设为上下文大小,并按每次请求的剩余上下文收紧。
255
257
 
@@ -282,9 +284,9 @@ DeepSeek Flash 走网关的 Responses 接口(`/api/pricing` 列出 `openai-res
282
284
 
283
285
  ## 更新与卸载
284
286
 
285
- > **从 1.3.2 或更早版本升级:** 请在插件页填写 `dsh-packycode-api@1.4.11` 安装,不要点旧版设置页里的「更新插件」。旧按钮安装时会绕过 pnpm 的发布冷却期:装到的版本如果发布还不满 24 小时,这个 profile 在它满 24 小时之前就装不了其他插件。装好并重启后,按钮就换成了修好的版本,以后直接点即可。
287
+ > **从 1.3.2 或更早版本升级:** 请在插件页填写 `dsh-packycode-api@1.4.13` 安装,不要点旧版设置页里的「更新插件」。旧按钮安装时会绕过 pnpm 的发布冷却期:装到的版本如果发布还不满 24 小时,这个 profile 在它满 24 小时之前就装不了其他插件。装好并重启后,按钮就换成了修好的版本,以后直接点即可。
286
288
 
287
- **更新:** 打开 **设置 → PackyCode**,有新版本时点「更新插件」。它会在当前 profile 目录里用 DSH 自带的 pnpm 安装精确版本,并读回 `package.json` 确认版本落地。安装遵守 pnpm 的发布冷却策略,不会绕过它:默认情况下 pnpm 会直接装上这个版本,并把它记进 profile 的 `minimumReleaseAgeExclude`;如果你给 pnpm 配了更严格的策略,按钮会提示什么时候可以更新。新版本号是从 npm 读到的,pnpm 却从 profile 配置的安装源下载:刚发布的版本,安装源(尤其是国内镜像)可能还没同步到,这时按钮会提示过几分钟再更新;连不上安装源时,会提示检查网络或代理。本地 `link:` 开发安装不会出现这个按钮。完成后完全退出并重新打开桌面应用。只刷新页面不会重载 Host。也可以在**插件**页重新安装,同样要填写带版本号的包名(例如 `dsh-packycode-api@1.4.11`),否则装上的可能是发布满 24 小时的旧版。
289
+ **更新:** 打开 **设置 → PackyCode**,有新版本时点「更新插件」。它会在当前 profile 目录里用 DSH 自带的 pnpm 安装精确版本,并读回 `package.json` 确认版本落地。安装遵守 pnpm 的发布冷却策略,不会绕过它:默认情况下 pnpm 会直接装上这个版本,并把它记进 profile 的 `minimumReleaseAgeExclude`;如果你给 pnpm 配了更严格的策略,按钮会提示什么时候可以更新。新版本号是从 npm 读到的,pnpm 却从 profile 配置的安装源下载:刚发布的版本,安装源(尤其是国内镜像)可能还没同步到,这时按钮会提示过几分钟再更新;连不上安装源时,会提示检查网络或代理。本地 `link:` 开发安装不会出现这个按钮。完成后完全退出并重新打开桌面应用。只刷新页面不会重载 Host。也可以在**插件**页重新安装,同样要填写带版本号的包名(例如 `dsh-packycode-api@1.4.13`),否则装上的可能是发布满 24 小时的旧版。
288
290
 
289
291
  **从本地路径安装切回官方源时,必须先卸载。** 「更新」是 `pnpm add`,它只重写包目录里的文件,不会删除更早一次本地路径安装留在包目录内的 `node_modules`;那份旧依赖会继续挡住 DSH 自带的包,插件行加载失败且看不出原因。「卸载」执行的是 `pnpm remove`,会删掉整个包目录,重装才是干净的。用 `node scripts/install-check.mjs` 可以确认当前 profile 是否处于这个状态。
290
292
 
@@ -300,7 +302,7 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
300
302
 
301
303
  有输出就是残留:从 npm 安装的包不会自带 `node_modules`,这一份通常来自更早一次「本地路径」安装(`file:` 或直接写路径,而不是 `link:`)。它位于 profile 目录内部,而 DSH 解析插件导入时优先使用 profile 内的副本,所以插件拿到的仍是那份旧依赖 —— 例如 `@deepseek-ai/schemastery` 3.18.2 没有 `Schema.volatile()`,模块在导入阶段就抛错。导入失败时 Loader 不会为这一行创建 fiber,客户端 bundle 也不会被组合,于是模型路由、RPC 通道和设置页全都不会出现。
302
304
 
303
- 修复:到**插件**页**卸载**本插件,再用带版本号的包名重新**安装**(例如 `dsh-packycode-api@1.4.11`),然后完全退出并重新打开桌面应用。卸载执行的是 `pnpm remove`,会删掉整个包目录;直接重装或点「更新」只重写文件,不会清掉这份残留。也可以手动删掉上面那个 `node_modules` 再重启。
305
+ 修复:到**插件**页**卸载**本插件,再用带版本号的包名重新**安装**(例如 `dsh-packycode-api@1.4.13`),然后完全退出并重新打开桌面应用。卸载执行的是 `pnpm remove`,会删掉整个包目录;直接重装或点「更新」只重写文件,不会清掉这份残留。也可以手动删掉上面那个 `node_modules` 再重启。
304
306
 
305
307
  **首次安装后,设置页每张卡片都显示 `transport failure for /packycode-api/…: HTTP 405`?** 实际装上的是 1.1.6 或更早的版本,通常是因为安装时只填了包名:安装提示显示的是最新版,pnpm 实际装的却是发布满 24 小时的旧版(见「安装插件」)。这些旧版要等 DSH 重启、重建它的 `connection` 服务之后,才能注册设置通道。所以首次安装后 `/packycode-api` 通道还不存在,请求落到静态页面,返回 405;模型路由和设置页本身照常加载。1.1.7 起首次安装不需要重启。先确认装上的版本:
306
308
 
package/lib/client.js CHANGED
@@ -2062,7 +2062,11 @@ window.__ModuleLoader__.load({
2062
2062
  ]],
2063
2063
  ["Grok", ["grok-4.7"]],
2064
2064
  ["Hunyuan", ["hy4"]],
2065
- ["Gemini", ["gemini-4-argon", "gemini-3.8-flash"]],
2065
+ ["Gemini", [
2066
+ "gemini-4-carbon",
2067
+ "gemini-4-argon",
2068
+ "gemini-3.8-flash"
2069
+ ]],
2066
2070
  ["Claude", [
2067
2071
  "claude-fable-5-2",
2068
2072
  "claude-opus-5-5",
package/lib/index.js CHANGED
@@ -1085,8 +1085,9 @@ const DEFAULT_REASONING_LEVEL = "high";
1085
1085
  * and V4 Pro alike), Grok 4.7
1086
1086
  * (docs.x.ai/developers/grok-4-7), Hy4 (`high` or `no_think`, TokenHub's
1087
1087
  * deep-thinking page cloud.tencent.com/document/product/1823/131208), and
1088
- * Gemini 4 Argon and 3.8 Flash
1089
- * (ai.google.dev/gemini-api/docs/models/gemini-4-argon and gemini-3.8-flash).
1088
+ * Gemini 4 Carbon, 4 Argon and 3.8 Flash
1089
+ * (aistudio.google.com/docs/models/gemini-4-carbon and
1090
+ * ai.google.dev/gemini-api/docs/models/gemini-4-argon and gemini-3.8-flash).
1090
1091
  *
1091
1092
  * @module dsh-packycode-api/catalog
1092
1093
  */
@@ -1173,7 +1174,7 @@ const HY4_LEVELS = Object.freeze({
1173
1174
  xhigh: null,
1174
1175
  max: null
1175
1176
  });
1176
- /** Gemini 4 Argon and 3.8 Flash support low | medium | high, with no off. */
1177
+ /** Gemini 4 Carbon, 4 Argon and 3.8 Flash support low | medium | high, with no off. */
1177
1178
  const GEMINI_LEVELS = Object.freeze({
1178
1179
  ...ALWAYS_THINKING_LEVELS,
1179
1180
  xhigh: null,
@@ -1289,6 +1290,19 @@ const PACKYCODE_MODELS = Object.freeze([
1289
1290
  maxTokens: 64e3,
1290
1291
  thinkingLevelMap: HY4_LEVELS
1291
1292
  }),
1293
+ Object.freeze({
1294
+ id: "gemini-4-carbon",
1295
+ name: "Gemini 4 Carbon",
1296
+ api: "google-generative-ai",
1297
+ provider: PROVIDER,
1298
+ baseUrl: GEMINI_BASE,
1299
+ reasoning: true,
1300
+ input: Object.freeze(["text", "image"]),
1301
+ cost: NO_COST,
1302
+ contextWindow: 1048576,
1303
+ maxTokens: 65536,
1304
+ thinkingLevelMap: GEMINI_LEVELS
1305
+ }),
1292
1306
  Object.freeze({
1293
1307
  id: "gemini-4-argon",
1294
1308
  name: "Gemini 4 Argon",
@@ -3717,6 +3731,7 @@ function buildCliEnvironment({ baseUrl, apiKey, configDir, maxTokens, continues
3717
3731
  DISABLE_ERROR_REPORTING: "1",
3718
3732
  DISABLE_BUG_COMMAND: "1",
3719
3733
  CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1",
3734
+ CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: "1",
3720
3735
  CLAUDE_CODE_MAX_RETRIES: "0",
3721
3736
  CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK: "1",
3722
3737
  CLAUDE_CODE_DISABLE_REFUSAL_FALLBACK: "1",
@@ -8225,7 +8240,11 @@ function guardGeminiReplay(open, { model, context, signal, wait = waitForRetry }
8225
8240
  //#endregion
8226
8241
  //#region src/gemini-api.js
8227
8242
  /** Gemini's native API, including level-based thinking on older pi-ai hosts. */
8228
- const GEMINI_MODELS = ["gemini-4-argon", "gemini-3.8-flash"];
8243
+ const GEMINI_MODELS = [
8244
+ "gemini-4-carbon",
8245
+ "gemini-4-argon",
8246
+ "gemini-3.8-flash"
8247
+ ];
8229
8248
  /**
8230
8249
  * Google's documented thought signature for a function call whose real one
8231
8250
  * cannot be sent: the API skips signature validation for it.
@@ -8279,8 +8298,8 @@ const skipped = (payload) => ({
8279
8298
  contents: skipThoughtSignatures(payload.contents)
8280
8299
  });
8281
8300
  /**
8282
- * pi-ai 0.85 treats Argon as a budget-based model, and defaults Flash to
8283
- * MINIMAL when reasoning is omitted. Both models support LOW/MEDIUM/HIGH,
8301
+ * Older pi-ai hosts treat Gemini 4 as budget-based models, and default Flash
8302
+ * to MINIMAL when reasoning is omitted. These models support LOW/MEDIUM/HIGH,
8284
8303
  * default to MEDIUM and cannot disable thinking. Keep the native SDK stream,
8285
8304
  * credentials and tools; correct that config and send no real signature.
8286
8305
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-packycode-api",
3
- "version": "1.4.11",
3
+ "version": "1.4.13",
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",