dsh-packycode-api 1.2.11 → 1.3.0
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 +11 -0
- package/README.en.md +35 -54
- package/README.md +34 -53
- package/SECURITY.md +6 -8
- package/lib/client.js +4 -212
- package/lib/index.js +1674 -5061
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.3.0
|
|
4
|
+
|
|
5
|
+
- **Claude runs directly inside the plugin.** Opus, Sonnet and Haiku now use the native Anthropic Messages HTTP route with DSH tools, attachments, permissions, plan mode and durable history. Claude session titles use Haiku over HTTP. No Claude Code installation, login or subprocess is required.
|
|
6
|
+
- **Remove the old CLI subsystem.** Removed the runner, installer, delegation tool, local MCP bridges, CLI settings/RPC/UI and obsolete exports. Existing standalone Claude Code installations are untouched, and images saved by older plugin versions remain viewable.
|
|
7
|
+
- **Preserve native tool execution.** Offered bash/read/write/edit/glob/grep tools declare the CLI-compatible spellings, with other tools using bounded MCP names. Responses map back only to tools offered for that request; arguments, call IDs, validation and permissions remain under DSH. This fixes repeated `unknown tool "Bash"` calls without granting unoffered tools.
|
|
8
|
+
- **Unambiguous working directories.** The legacy cwd sentence is rewritten only when it matches the initiating session's metadata. The exact path is a standalone JSON string and is also explained in shell workdir defaults. Current-project commands are guided to relative paths. Legitimate final dots, Unicode, spaces and Windows drive/UNC/extended paths remain intact; commands and history are never rewritten.
|
|
9
|
+
- **Complete streaming and signed replay.** Responses finish at the protocol terminal frame without waiting for HTTP EOF, split CRLF delimiters survive network chunking, and empty signed thinking blocks survive persisted tool history. Model effort and output limits stay unchanged; thinking display follows the verified client defaults.
|
|
10
|
+
- **Client-policy failures stay separate from invalid keys.** The already-authorized/test-message refusal has its own category and does not disable credentials. Specific captured Haiku/Sonnet tool-context anomalies may repeat the exact request once before streaming begins; ordinary refusals, rate limits and accepted streams do not trigger this guard. This is bounded compatibility handling, not a repair of the gateway's internal policy.
|
|
11
|
+
- Retains 1.2.10's OpenAI upstream-server-error classification and 1.2.11's Gemini signature handling and release-artifact handoff.
|
|
12
|
+
- Validation, 2026-10-17: 395 offline tests, both rebuilt bundles and the versioned package passed. All three Claude models passed text, native tool roundtrip, image input and Chinese title checks (12 checks / 15 model requests, all HTTP 200 with successful stream completion and business validation). The all-model route, in-memory key-rotation and RPC checks passed; Grok completed its stream with a refusal of the exact-marker prompt. Working-directory and PowerShell request regressions retain simulated tool results and are not a Windows desktop execution test. Earlier failed probes remain in local evidence, and the stopped scheduled observation is not a completed six-hour reliability run.
|
|
13
|
+
|
|
3
14
|
## 1.2.11
|
|
4
15
|
|
|
5
16
|
- **Gemini tool continuations send no real thought signature.** Gemini 4 Argon long tasks ended in HTTP 400 `Invalid thought signature.` (`packy_upstream_error`) after DSH's retries. PackyCode support attributes this to its native Gemini route not handling the signature field in tool calls. It advises against resending through that route and recommends that clients ignore the field. Requests for both Gemini models now replace every thought signature with Google's documented `skip_thought_signature_validator`, which also fills the first function call of each step whose response came back unsigned. Only the signature field changes: the protocol (`google-generative-ai`), base URL, model IDs, thinking levels and DSH's stored replay state are unchanged, and no request is routed elsewhere. Google notes that skipped signatures can weaken reasoning continuity across tool steps. Flash keeps its one resend after an HTTP 400 signature refusal; such a refusal still never disables or rotates a key.
|
package/README.en.md
CHANGED
|
@@ -29,7 +29,7 @@ The `PackyCode` model group ships with the plugin. No YAML edits and no separate
|
|
|
29
29
|
| **Keys used in order** | An exhausted or rejected key is disabled and the next usable key takes over; the failed step is retried on that key |
|
|
30
30
|
| **Keys chosen by group** | Each key lists its PackyCode groups and the models they reach; when the active key's groups cannot reach the selected model (no `cc` group for Claude, say), that turn runs on a stored key whose groups can |
|
|
31
31
|
| **Visible balance** | Settings lists each key's remaining, used, limit, reset period, and a usage bar, plus a total of those keys. The composer shows the active key's remaining balance |
|
|
32
|
-
| **Claude
|
|
32
|
+
| **Claude inside the plugin** | All three Claude models use HTTP Messages with DSH tools, permissions and conversation history; no local CLI is needed |
|
|
33
33
|
| **Web search through PackyCode** | Optional: DSH's `web_search` searches through PackyCode, with a DeepSeek or GPT backend, for every request or for PackyCode models only |
|
|
34
34
|
| **Image generation and editing** | Separate image keys, GPT Image 2 / 2.5 Flare / 2.5 Sunburst, model and quality settings, reference edits and original PNG storage; generation and editing verified against the gateway |
|
|
35
35
|
| **Credentials stay on the machine** | Keys live in the DSH credential file. The browser receives labels, state, and balances only |
|
|
@@ -38,7 +38,6 @@ The `PackyCode` model group ships with the plugin. No YAML edits and no separate
|
|
|
38
38
|
<img width="575" height="522" alt="截屏2026-10-15 10 34 49" src="https://github.com/user-attachments/assets/3cf4d090-a4f9-49fe-9ab3-3aab21d6e909" />
|
|
39
39
|
<img width="257" height="309" alt="截屏2026-10-15 10 37 21" src="https://github.com/user-attachments/assets/621cd800-17a2-42f6-8dfe-c1b4be09af61" />
|
|
40
40
|
|
|
41
|
-
|
|
42
41
|
## Install
|
|
43
42
|
|
|
44
43
|
You need **DeepSeek Harness** and a **PackyCode (PackyAPI) API key**. For DSH setup, see the [official instructions](https://github.com/deepseek-ai/deepseek-harness#run). No API key yet? You can register with PackyCode and apply for one through [this invite link](https://www.packyapi.ai/register?aff=Im3l).
|
|
@@ -48,10 +47,10 @@ You need **DeepSeek Harness** and a **PackyCode (PackyAPI) API key**. For DSH se
|
|
|
48
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**:
|
|
49
48
|
|
|
50
49
|
```text
|
|
51
|
-
dsh-packycode-api@1.
|
|
50
|
+
dsh-packycode-api@1.3.0
|
|
52
51
|
```
|
|
53
52
|
|
|
54
|
-
Choose the **official** install source, then click **Install**. `1.
|
|
53
|
+
Choose the **official** install source, then click **Install**. `1.3.0` was the latest release when this was written; the [npm page](https://www.npmjs.com/package/dsh-packycode-api) shows the current one.
|
|
55
54
|
|
|
56
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**.
|
|
57
56
|
|
|
@@ -65,14 +64,14 @@ Open **Settings → PackyCode**. Paste the API key under **Add a key**. A label
|
|
|
65
64
|
|
|
66
65
|
### 3. Select a model
|
|
67
66
|
|
|
68
|
-
Choose a model from the `PackyCode` group.
|
|
67
|
+
Choose a model from the `PackyCode` group. All nine models use the plugin’s HTTP route. Your key’s groups must cover the selected model.
|
|
69
68
|
|
|
70
69
|
<details>
|
|
71
70
|
<summary>Verify the install / other profiles / a local checkout</summary>
|
|
72
71
|
|
|
73
72
|
The **Plugins** page shows the installed state and version, and is also where you enable, disable, or uninstall.
|
|
74
73
|
|
|
75
|
-
**For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.
|
|
74
|
+
**For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.3.0`. Do not use it for `desktop` — the CLI refuses it (`profile "desktop" is managed exclusively by the Electron application`).
|
|
76
75
|
|
|
77
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.
|
|
78
77
|
|
|
@@ -86,11 +85,11 @@ A profile without a browser can still use the model route. It just has no settin
|
|
|
86
85
|
|
|
87
86
|
**Switch keys.** Keys are used in the order they were added. **Use this key** picks the preferred key, effective from the next turn; **Rename** changes its label (at most 60 characters, empty names are refused); **Re-enable** puts a disabled key back after a top-up or replacement.
|
|
88
87
|
|
|
89
|
-
**See groups.** Under **Accounts and keys**, each key lists its PackyCode groups (hover for the group's description) and which models they reach: ✓ yes, ◐ partly, ✕ no. The groups come from the gateway itself (its refusal of a model id it cannot route names the token's groups; nothing is billed), matched against PackyCode's public model-group table. Claude
|
|
88
|
+
**See groups.** Under **Accounts and keys**, each key lists its PackyCode groups (hover for the group's description) and which models they reach: ✓ yes, ◐ partly, ✕ no. The groups come from the gateway itself (its refusal of a model id it cannot route names the token's groups; nothing is billed), matched against PackyCode's public model-group table. Check Claude group coverage per model; do not assume `cc-sale` serves all three models; GPT needs `codex` / `codex-sale`; DeepSeek needs `deepseek-officially` / `deepseek-sale`.
|
|
90
89
|
|
|
91
90
|
**Read the balance.** The total at the top of **Accounts and keys** is the remaining, used, and limit of **the keys listed here**, not the bill for every token on the PackyCode account. A key that could not be read is left out of the total and counted in a note; a key whose read failed this time but succeeded before keeps showing its last balance with the time it was read (the composer shows it as `≈US$…`) until DSH restarts. The composer shows the active key's remaining balance only while a PackyCode model is selected. **Refresh** bypasses the roughly 60-second cache. The default model host is `https://cf.api.fan` and the balance host is `https://www.packyapi.ai`; both can be changed under **Advanced: endpoints**. The old default, `https://www.packyapi.com`, is DNS-poisoned on mainland networks and answers `fetch failed` without a proxy; even when settings still name it, `.ai` is tried first.
|
|
92
91
|
|
|
93
|
-
**Use Claude.**
|
|
92
|
+
**Use Claude.** Select any Claude model directly; no CLI installation is needed. Reasoning effort is sent to the model. DSH owns the history, attachments, tool loop, plan mode and permissions.
|
|
94
93
|
|
|
95
94
|
**Web search.** DSH's `web_search` calls DeepSeek's official API by default (billed to `DEEPSEEK_API_KEY`). **Settings → PackyCode → Web search** can route it through PackyCode instead:
|
|
96
95
|
|
|
@@ -107,17 +106,7 @@ A profile without a browser can still use the model route. It just has no settin
|
|
|
107
106
|
|
|
108
107
|
PackyCode has no dedicated search endpoint: one search is one model call with a server-side search tool, billed to the keys stored here. An exhausted or rejected key rotates exactly as on the model route.
|
|
109
108
|
|
|
110
|
-
**Claude
|
|
111
|
-
|
|
112
|
-
```text
|
|
113
|
-
Claude Code CLI → temporary local MCP web_search → selected PackyCode DeepSeek/GPT backend
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
- **Backend selection applies to CLI; routing selection only applies to DSH.** Even with Off/Do not take over selected, CLI searches use the selected backend, not DSH's default. A backend change applies to the next search.
|
|
117
|
-
- Ordinary Claude requests still need a Claude-group key. Search needs a plugin-stored key covering DeepSeek or GPT; it can be another key. Failures are returned to the CLI, with no invented success or automatic switch to another backend.
|
|
118
|
-
- Read-only/edit modes auto-approve only this specific read-only MCP search tool, without adding shell or file-write privileges. User/managed denials still apply. CLI `--allowedTools` is an additive auto-approval list, not an exclusive tool whitelist; existing other permissions are preserved.
|
|
119
|
-
- At most 8 searches per invocation, 2 concurrently, 2000 characters per query and 8 sources per result, with a 60-second end-to-end search deadline. Title generation allocates no MCP server or search grant.
|
|
120
|
-
- Reasoning reports `▸ 网页搜索:PackyCode DeepSeek(MCP,原生 WebSearch 已禁用)` (or GPT). The temporary server binds only `127.0.0.1`; its private config contains an independent one-run capability, never a search API key. CLI completion/cancellation/timeout/plugin unload revokes it and removes the private config, leaving existing user MCP configurations untouched.
|
|
109
|
+
**Claude search.** Claude uses DSH’s `web_search` with the routing choices above and the same stored-key rules as other native models.
|
|
121
110
|
|
|
122
111
|
<details>
|
|
123
112
|
<summary>How web search is wired into DSH</summary>
|
|
@@ -136,8 +125,8 @@ Claude Code CLI → temporary local MCP web_search → selected PackyCode DeepSe
|
|
|
136
125
|
<summary>When a key is rotated</summary>
|
|
137
126
|
|
|
138
127
|
- **Rotates and disables the current key:** the gateway reports exhausted quota, or it rejects the key (HTTP 401 / invalid token). The harness retries the failed step, which is what actually sends it on the next key.
|
|
139
|
-
- **Passes over a key by its groups, without disabling it:** when the group reading shows the active key cannot reach this turn's model and another stored key can, the turn runs on that key (
|
|
140
|
-
- **Does not rotate:** rate limits (429); a 400 that this gateway uses for a dead upstream channel; and a 403 that means the group accepts only the vendor's official client.
|
|
128
|
+
- **Passes over a key by its groups, without disabling it:** when the group reading shows the active key cannot reach this turn's model and another stored key can, the turn runs on that key (an explicit Claude Code delegation says so in its reasoning: “当前 Key「A」的分组不能用 …,本轮改用 Key「B」”). The active key stays active for every other model. Only evidence counts: a key whose groups are not read yet is used as before.
|
|
129
|
+
- **Does not rotate:** rate limits (429); a 400 that this gateway uses for a dead upstream channel; and a 403 that means the group accepts only the vendor's official client. The separate 403 saying the client is already authorized and should not send connectivity test messages is classified as `GATEWAY_TEST_MESSAGE`. It explains the refusal without disabling the key. Only Haiku tool context may replay it once under the bounds below.
|
|
141
130
|
- When every stored key is disabled, the request fails and says so. There is no fallback credential.
|
|
142
131
|
|
|
143
132
|
</details>
|
|
@@ -150,7 +139,7 @@ The image card shows each image key's remaining/used quota, limits when supplied
|
|
|
150
139
|
|
|
151
140
|
Choose the image model and quality, then click **Create image** in a PackyCode conversation or explicitly request `packycode_image_generate`. Attach references and describe changes to use `/v1/images/edits`; new images use `/v1/images/generations`. The image model is independent of the conversation model and other image plugins can coexist.
|
|
152
141
|
|
|
153
|
-
|
|
142
|
+
Claude generates and edits images through DSH’s `packycode_image_generate`, with the same separate image key, preferences and balance cache as other models. Saved images from older CLI-backed sessions remain viewable without regeneration.
|
|
154
143
|
|
|
155
144
|
**Image visible in tool details but unavailable in the final answer:** a standalone main-chat gallery remains visible when reasoning/tool details are collapsed, including PTC child calls. Reopening an existing conversation restores the gallery from its saved attachments without regenerating or spending image quota. An old invalid Markdown image link to a host path does not affect this gallery.
|
|
156
145
|
|
|
@@ -174,9 +163,9 @@ Live checks on 2026-10-15 passed generation and editing at `low` on all three en
|
|
|
174
163
|
| `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 |
|
|
175
164
|
| `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` |
|
|
176
165
|
| `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` |
|
|
177
|
-
| `claude-opus-5-5` |
|
|
166
|
+
| `claude-opus-5-5` | HTTP, Anthropic Messages, images and native tools | Cannot be off; `low` / `medium` / `high` / `xhigh` / `max` | Claude-group coverage reported in Settings |
|
|
178
167
|
| `claude-sonnet-5-5` | Same | Same | Same |
|
|
179
|
-
| `claude-haiku-5-5` | Same;
|
|
168
|
+
| `claude-haiku-5-5` | Same; also generates Claude session titles | Same | Same |
|
|
180
169
|
|
|
181
170
|
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.
|
|
182
171
|
|
|
@@ -191,29 +180,27 @@ Grok 4.7's context and reasoning levels follow the [official guide](https://docs
|
|
|
191
180
|
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.
|
|
192
181
|
|
|
193
182
|
<details>
|
|
194
|
-
<summary>Protocol, group
|
|
195
|
-
|
|
196
|
-
-
|
|
197
|
-
-
|
|
198
|
-
- The
|
|
199
|
-
-
|
|
200
|
-
-
|
|
201
|
-
-
|
|
202
|
-
-
|
|
203
|
-
-
|
|
204
|
-
-
|
|
205
|
-
- The
|
|
206
|
-
-
|
|
207
|
-
-
|
|
208
|
-
-
|
|
209
|
-
- The `claude_code` tool can delegate one task to the local CLI while the session model is `gpt-6.1-sol`, `gpt-6-astra`, or `deepseek-flash`. The requested `mode` cannot exceed what the session preset allows. While the session is in plan mode the delegation plans too, and returns the plan text to the parent model.
|
|
210
|
-
- An effort level the model does not support is rejected before the request is sent. Do not edit a model's effort map casually.
|
|
183
|
+
<summary>Protocol, group and client compatibility</summary>
|
|
184
|
+
|
|
185
|
+
- All nine models use HTTP inside the plugin. Claude keeps `anthropic-messages`, with a base URL without `/v1`; the SDK appends `/v1/messages`. Model ids, protocols, context limits and effort mappings are unchanged.
|
|
186
|
+
- Claude requests use the live-verified CLI-compatible headers, bearer authentication, session metadata and identity system prefix while preserving DSH instructions, tool schemas, images and signed replay. The compatibility version is pinned to `2.1.295`; no local CLI is detected or started for a model turn.
|
|
187
|
+
- The bearer comes only from the plugin’s stored key chosen for the model. No CLI login, external configuration, ambient key or alternate provider is used.
|
|
188
|
+
- This compatibility envelope does not remove the gateway’s group restrictions. The key still needs Claude coverage. Client-policy refusals are explained without disabling a key or falling back to a CLI. Server changes may invalidate the envelope; see [PackyCode group policy](https://docs.packyapi.ai/docs/token/).
|
|
189
|
+
- Identical Haiku and Sonnet tool requests have been both refused with the captured client-anomaly 403 and accepted. The plugin waits one second and repeats the unchanged request once for that response. Haiku also covers the captured already-authorized/test-message 403, sharing the same one-replay limit. A second refusal remains visible. Opus, plain text, ordinary official-CLI-only refusals, 429s and accepted streams do not trigger this replay. Records retain the original failures; this does not establish a repair of the gateway's internal classifier.
|
|
190
|
+
- Claude streams finish at `message_stop` without waiting for the gateway to close the HTTP body, and CRLF delimiters remain intact across network chunks. Stream errors and cancellation still surface; waiting for response headers is not counted as success.
|
|
191
|
+
- Offered DSH bash/read/write/edit/glob/grep tools use canonical CLI names such as `Bash` and `Read` over HTTP; other tools use MCP names. Only aliases declared for the current request regain their original names before DSH dispatch; unknown names never grant execution. Arguments, call IDs, results and signed history remain intact. Thinking display follows the CLI defaults: `omitted` for Haiku and `updates` with its required beta for Sonnet and Opus. Reasoning effort and output limits remain unchanged, signatures on empty thinking blocks survive replay, and explicit display options take precedence.
|
|
192
|
+
- When the legacy working-directory sentence agrees with the initiating session metadata, Claude receives the exact path as a separate JSON string. Sentence punctuation stays outside the path; real trailing dots, Windows drive/UNC paths, spaces and backslashes remain intact. Commands are never trimmed or rewritten. Shell guidance prefers the current directory or `workdir`, preserving PowerShell syntax for Windows tools.
|
|
193
|
+
- Native Claude turns retain the full DSH tool loop, permissions and plan mode, using host search and image tools. Claude titles use Haiku over HTTP; Astra titles still use Sol.
|
|
194
|
+
- The old `claude_code` delegation tool, CLI runner, detection/installation UI, configuration fields and local MCP bridges have been removed. Old `claudeCliPath`, `claudeCliMode` and `claudeCliCwd` settings no longer affect requests. Separately installed Claude Code remains untouched.
|
|
195
|
+
- Codex Responses requests still need `prompt_cache_key`; the plugin supplies a missing session identity. Other Responses families omit it.
|
|
196
|
+
- After building, `node scripts/claude-check.mjs` checks all three Claude models on order totals, support triage, replenishment, read-only inventory tool roundtrips, product color labels and Chinese titles, validating the business answers. `node scripts/claude-stability.mjs --start --hours 6 --key-label <label>` starts a deadline- and request-budget-limited window. Invoke the same script on a schedule to sample again; `--status` reads the record. Each round records its build and scenario version. A test-message policy refusal fails that check while the other scheduled checks continue; real credential or quota failures still stop the window. Checks never change stored credentials or start DSH.
|
|
197
|
+
- For continuous dialogs, use `node scripts/claude-conversation-check.mjs --model claude-haiku-5-5 --rounds 3 --key-label <label> --output .artifacts/claude-conversation.json`. One plugin adapter handles independent sessions; each group retains six user turns and full tool history, validates arithmetic, final JSON and unexpected characters, and stops on a failure without discarding evidence. Requests default to 65 seconds and 2048 output tokens. Diagnostic overrides use `--timeout-ms` (5000–300000) and `--max-tokens` (1024–128000). `--capture-wire` records the synthetic business requests, non-authentication headers and partial stream events for exact replay, without keys. Reports include scenario and adapter lifecycle, configured limits, response-header latency and total response time. These options do not alter the plugin's runtime settings.
|
|
211
198
|
|
|
212
199
|
</details>
|
|
213
200
|
|
|
214
201
|
## Update and uninstall
|
|
215
202
|
|
|
216
|
-
**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. 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.
|
|
203
|
+
**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. 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.0`); without it you may get a version that is merely the newest one published at least 24 hours ago.
|
|
217
204
|
|
|
218
205
|
**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.
|
|
219
206
|
|
|
@@ -229,7 +216,7 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
|
|
|
229
216
|
|
|
230
217
|
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.
|
|
231
218
|
|
|
232
|
-
Recovery: **uninstall** the plugin on the **Plugins** page, **install** it again with the version in the package name (for example `dsh-packycode-api@1.
|
|
219
|
+
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.0`), 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.
|
|
233
220
|
|
|
234
221
|
**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:
|
|
235
222
|
|
|
@@ -243,25 +230,25 @@ Recovery: quit and reopen the desktop application, and the old version works. Th
|
|
|
243
230
|
|
|
244
231
|
**One model fails, but the key is valid?** Look at that key's groups and ✓ / ✕ under **Accounts and keys**. When its groups do not cover the model, use a key whose groups do, or add the group to the key in the PackyCode console. With such a key stored, the plugin runs that model on it automatically. A group refusal never disables a key.
|
|
245
232
|
|
|
246
|
-
**Claude
|
|
233
|
+
**Claude reports an official-client-only or client-anomaly refusal?** This is a gateway client-policy refusal, not proof of an invalid key. Check the selected model’s group coverage under **Accounts and keys** and in PackyCode’s model catalog, then collect diagnostics if a covered model is still refused. The plugin does not disable the key, switch providers or start a CLI for this refusal.
|
|
247
234
|
|
|
248
235
|
**The balance does not match the account bill?** Settings totals only the keys stored here, not other tokens on the same PackyCode account. A key that failed to read is noted separately and is not treated as zero.
|
|
249
236
|
|
|
250
237
|
**The balance reads `fetch failed` from `https://www.packyapi.com`?** That host, the default through 1.0.4, is DNS-poisoned on mainland networks and only answers through a proxy, so it works on and off. The default is now `https://www.packyapi.ai`. The model list is built into the plugin and never queried from PackyCode, so it is unaffected.
|
|
251
238
|
|
|
252
|
-
**A Claude model
|
|
239
|
+
**A Claude model stays on “thinking”?** Check DSH errors or diagnostics. HTTP 429/503 means gateway queueing or throttling and follows the host retry policy; client-policy refusals are explained directly. Native model turns never start a local CLI.
|
|
253
240
|
|
|
254
241
|
**A rate limit disabled the key?** It should not. HTTP 429 does not rotate. Exhausted quota or HTTP 401 does; after a top-up, click **Re-enable**.
|
|
255
242
|
|
|
256
243
|
**Installing from the Plugins page fails with `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION`?** By default pnpm accepts only versions published at least 24 hours ago and checks the whole profile lockfile. (Entering only this plugin's bare name does not raise this error; it silently installs an older version that has passed 24 hours instead, see **Install the plugin**.) The package it names is often another plugin that was just updated, not this one. Retry once it is 24 hours old, or add the reported `name@version` under `minimumReleaseAgeExclude` in the profile's `pnpm-workspace.yaml`. Once this plugin is installed, **Update plugin** in Settings is not subject to that check.
|
|
257
244
|
|
|
258
|
-
**
|
|
245
|
+
**Do I still need the previously installed Claude Code?** This plugin no longer runs, installs or delegates to a CLI. Claude models use HTTP directly. Keep Claude Code if you use it separately; this plugin does not modify its installation or configuration.
|
|
259
246
|
|
|
260
247
|
**Replies stop at the output token limit (已达到输出 token 上限), or requests keep failing — how do I report it?** Open **Settings → PackyCode → Diagnostics**, pick the session (the 20 most recent, newest first, labelled with their folder name), click **Generate diagnostics** and then **Copy**, and paste the text into an [Issue](https://github.com/BaronCyrus/dsh-packycode-api/issues) or send it to the plugin author. It holds settings and numbers only: the plugin version, the session id and start time, each key's position and groups (no labels, no keys), each request's model, reasoning effort and output limit, the latest steps' token usage and finish reasons, and retry and failure codes (messages redacted and shortened). It contains no conversation text, file paths or keys. Where copying is unavailable, the text is selected instead; press ⌘C or Ctrl+C.
|
|
261
248
|
|
|
262
249
|
## Security and scope
|
|
263
250
|
|
|
264
|
-
This is a community plugin, not affiliated with or endorsed by DeepSeek or PackyCode. Model requests go to the PackyCode host you configured. Keeping credentials out of browser responses does not mean inference is local. Claude
|
|
251
|
+
This is a community plugin, not affiliated with or endorsed by DeepSeek or PackyCode. Model requests go to the PackyCode host you configured. Keeping credentials out of browser responses does not mean inference is local. Claude also uses the plugin’s native HTTP route.
|
|
265
252
|
|
|
266
253
|
Keys stay in the local DSH credential file (`~/.dsh/.credentials.yaml`, owner-only as enforced by DSH). They are not written into settings, logs, or the transcript. Balance requests run only on the host, with a timeout and redirects refused.
|
|
267
254
|
|
|
@@ -278,13 +265,7 @@ pnpm run check
|
|
|
278
265
|
|
|
279
266
|
`pnpm run check` runs every test, rebuilds, and writes a tarball under `.artifacts/`. `lib/` is a committed build; regenerate it with `pnpm run build` after editing `src/`, and do not hand-edit it.
|
|
280
267
|
|
|
281
|
-
`node scripts/live-check.mjs` checks the live gateway through the same route the plugin registers: balance and groups, one answer per HTTP model, a rotation rehearsal, and the failure classification, printing only the key's last four characters. `--with-
|
|
282
|
-
|
|
283
|
-
`node scripts/cli-search-check.mjs` runs the real CLI against a local test gateway and MCP bridge; Claude responses and search data are mocked by default, with no quota consumed. It checks all three permission modes, native-search exclusion and temporary-resource cleanup. `--live --backend deepseek` or `--live --backend gpt` sends the read-only mode's one search to the real backend (edit/full remain mocked). This does not verify actual Claude upstream turns or a running DSH integration.
|
|
284
|
-
|
|
285
|
-
`node scripts/cli-image-check.mjs` checks the real official CLI generating an image, editing its result, and persisting both through DSH's message assembler. Default model/image responses are local fixtures, covering read-only/edit/full/plan/title modes and temporary-config cleanup. `--live` makes one real Sunburst low-quality generation and one edit using the stored image key, while Claude replies remain local fixtures. `--with-claude` additionally uses a real Claude upstream turn (Haiku by default), consuming conversation quota too. Outputs go under `.artifacts/`; neither option starts DSH or claims a running desktop conversation was tested.
|
|
286
|
-
|
|
287
|
-
`node scripts/cli-plan-check.mjs` checks plan mode with the real CLI and a local fake gateway: stdio handoff, concurrent plan ownership, invocation-only file fallback, stale-plan exclusion, actual denial limits and cleanup. It reads no real credentials, spends no quota and starts no DSH instance.
|
|
268
|
+
`node scripts/live-check.mjs` checks the live gateway through the same route the plugin registers: balance and groups, one answer per HTTP model, a rotation rehearsal, and the failure classification, printing only the key's last four characters. `--with-search` runs one search per backend; the default run spends a small amount of quota.
|
|
288
269
|
|
|
289
270
|
`node scripts/install-check.mjs` diagnoses an installed plugin that never appears: it reads one profile, lists any host package shadowed by a leftover `node_modules` inside an installed package (with versions) plus the recovery steps, and exits 1 when it finds one. `--profile <name>`, `--home <dir>`, and `--json` are available.
|
|
290
271
|
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
| **多 Key 按顺序使用** | 额度用尽或 Key 被拒绝时自动切到下一个可用 Key;失败的那一步由重试接手 |
|
|
30
30
|
| **按分组选 Key** | 每个 Key 后面列出它所在的 PackyCode 分组和能用的模型;当前 Key 的分组用不了所选模型(例如没有 cc 分组却选了 Claude)时,这一轮自动改用分组合适的 Key |
|
|
31
31
|
| **余额一眼可见** | 设置页列出每个 Key 的剩余、已用、额度、重置周期和用量条,并给出这些 Key 的合计;输入框右侧显示当前 Key 的剩余额度 |
|
|
32
|
-
| **Claude
|
|
32
|
+
| **Claude 插件内直连** | 三个 Claude 模型通过 HTTP Messages 调用,使用 DSH 的工具、权限和完整对话历史,无需本机 CLI |
|
|
33
33
|
| **网页搜索可走 PackyCode** | 可选:DSH 的 `web_search` 改用 PackyCode 搜索,后端在 DeepSeek 与 GPT 之间切换;可只对 PackyCode 模型生效 |
|
|
34
34
|
| **图片生成与编辑** | 独立图片 Key,支持 GPT Image 2 / 2.5 Flare / 2.5 Sunburst、型号与质量设置、参考图编辑和 PNG 原图保存;已通过网关生图与编辑实测 |
|
|
35
35
|
| **凭据不离开本机** | Key 只存在 DSH 凭据文件里。浏览器只能看到备注、状态和余额,拿不到 Key |
|
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
<img width="575" height="522" alt="截屏2026-10-15 10 34 49" src="https://github.com/user-attachments/assets/89cf89ca-fce3-427d-95cb-94fa2b05d6aa" />
|
|
39
39
|
<img width="272" height="425" alt="截屏2026-10-13 10 07 46" src="https://github.com/user-attachments/assets/040fc57a-2dd2-4195-9bbc-5fa3357d1eb1" />
|
|
40
40
|
|
|
41
|
-
|
|
42
41
|
## 安装
|
|
43
42
|
|
|
44
43
|
先准备好 **DeepSeek Harness** 和 **PackyCode(PackyAPI)的 API Key**。尚未安装 DSH,可查看 [DSH 官方说明](https://github.com/deepseek-ai/deepseek-harness#run)。还没有 API Key 的,可以通过[这个邀请链接](https://www.packyapi.ai/register?aff=Im3l)注册 PackyCode 申请。
|
|
@@ -48,10 +47,10 @@
|
|
|
48
47
|
打开桌面应用的**插件**页,点击**添加插件**,在**包名或地址**中填入**带版本号**的包名:
|
|
49
48
|
|
|
50
49
|
```text
|
|
51
|
-
dsh-packycode-api@1.
|
|
50
|
+
dsh-packycode-api@1.3.0
|
|
52
51
|
```
|
|
53
52
|
|
|
54
|
-
在**安装源**中选择**官方源**,然后点击**安装**。`1.
|
|
53
|
+
在**安装源**中选择**官方源**,然后点击**安装**。`1.3.0` 是写这份说明时的最新版,当前最新版本号以 [npm 页面](https://www.npmjs.com/package/dsh-packycode-api) 为准。
|
|
55
54
|
|
|
56
55
|
> **一定要带版本号。** 只填 `dsh-packycode-api` 时,安装前的提示显示的是 npm 上的最新版,但 DSH 自带的 pnpm 默认只安装发布满 24 小时的版本,实际装上的可能是好几个版本之前的旧版,而安装提示里看不出这一点。填写精确版本时,pnpm 会直接安装这个版本,并自动把它加入 profile 的 `minimumReleaseAgeExclude`。装好后可以在 **设置 → PackyCode → 插件版本** 核对「当前版本」。
|
|
57
56
|
|
|
@@ -65,14 +64,14 @@ dsh-packycode-api@1.2.11
|
|
|
65
64
|
|
|
66
65
|
### 3. 选择模型
|
|
67
66
|
|
|
68
|
-
回到对话,在模型选择器里选 `PackyCode`
|
|
67
|
+
回到对话,在模型选择器里选 `PackyCode` 分组下的模型。九个模型都通过插件内 HTTP 调用;Key 的分组必须覆盖所选模型。
|
|
69
68
|
|
|
70
69
|
<details>
|
|
71
70
|
<summary>检查安装 / 其它 profile / 本地目录</summary>
|
|
72
71
|
|
|
73
72
|
桌面应用的**插件**页可以看到已安装状态与版本,也可以在那里启用、停用或卸载。
|
|
74
73
|
|
|
75
|
-
**仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.
|
|
74
|
+
**仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.3.0`。不要对 `desktop` 使用它 —— CLI 会直接拒绝(`profile "desktop" is managed exclusively by the Electron application`)。
|
|
76
75
|
|
|
77
76
|
本地开发要加 `link:` 前缀:`dsh plugin --profile <name> add link:/path/to/dsh-packycode-api`。**不要直接写路径(或 `file:`)** —— 那样的安装会把整个仓库目录(连同 `node_modules`)复制进 profile,之后它会在 profile 内部挡住 DSH 自带的包,插件看起来像没装,见「常见问题」。已经那样装过的话,先卸载再按上面的方式重装。
|
|
78
77
|
|
|
@@ -86,11 +85,11 @@ dsh-packycode-api@1.2.11
|
|
|
86
85
|
|
|
87
86
|
**换 Key。** Key 按添加顺序使用。点「切到此 Key」指定优先使用的 Key,下一轮就生效;「重命名」改备注(最多 60 字,不能为空);充值或更换后点「重新启用」。
|
|
88
87
|
|
|
89
|
-
**看分组。** 「账户与 Key」里每个 Key 下面列出它所在的 PackyCode 分组(鼠标悬停可看分组说明),以及能用哪些模型:✓ 可用、◐ 部分可用、✕ 不可用。分组由网关自己报出(对一个不存在的模型 id 的拒绝里会写明「已选分组」,不产生费用),再对照 PackyCode 公开的模型分组表。Claude
|
|
88
|
+
**看分组。** 「账户与 Key」里每个 Key 下面列出它所在的 PackyCode 分组(鼠标悬停可看分组说明),以及能用哪些模型:✓ 可用、◐ 部分可用、✕ 不可用。分组由网关自己报出(对一个不存在的模型 id 的拒绝里会写明「已选分组」,不产生费用),再对照 PackyCode 公开的模型分组表。Claude 的分组覆盖要按具体模型确认,不能假定 `cc-sale` 支持全部三个型号;GPT 需要 `codex` / `codex-sale`;DeepSeek 需要 `deepseek-officially` / `deepseek-sale`。
|
|
90
89
|
|
|
91
90
|
**看余额。** 「账户与 Key」顶部的合计是**已列出的这些 Key** 的剩余、已用与额度,不是 PackyCode 账号下全部令牌的账单。读失败的 Key 不计入合计,并会注明个数;某个 Key 这次读失败但之前读到过,会继续显示上次的余额并注明读取时间(输入框里显示为 `≈US$…`),重启 DSH 后才清空。输入框右侧只在选中 PackyCode 模型时显示当前 Key 的剩余额度。「刷新」会跳过约 60 秒的缓存。默认模型接口是 `https://cf.api.fan`,余额接口是 `https://www.packyapi.ai`,可在「高级:接口地址」里改。旧默认值 `https://www.packyapi.com` 在国内网络下 DNS 被污染、直连会 `fetch failed`,即使设置里保存的是它,插件也会先试 `.ai`。
|
|
92
91
|
|
|
93
|
-
**用 Claude。**
|
|
92
|
+
**用 Claude。** 直接选择三个 Claude 模型之一即可,无需安装 CLI。思考档位会发送给模型;对话历史、附件、工具调用、计划模式和权限均由 DSH 管理。
|
|
94
93
|
|
|
95
94
|
**网页搜索。** DSH 的 `web_search` 默认调用 DeepSeek 官方接口(用 `DEEPSEEK_API_KEY` 计费)。在 **设置 → PackyCode → 网页搜索** 里可以改走 PackyCode:
|
|
96
95
|
|
|
@@ -107,17 +106,7 @@ dsh-packycode-api@1.2.11
|
|
|
107
106
|
|
|
108
107
|
PackyCode 没有专用搜索接口:一次搜索就是一次带服务端搜索工具的模型调用,用这里的 Key 计费,额度用尽或 Key 被拒绝时同样切到下一个 Key。
|
|
109
108
|
|
|
110
|
-
**Claude
|
|
111
|
-
|
|
112
|
-
```text
|
|
113
|
-
Claude Code CLI → 本机临时 MCP web_search → 插件选定的 DeepSeek/GPT 后端
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
- **后端选择对 CLI 生效;路由选择只影响 DSH。** 即使选了「不接管」,CLI 搜索仍用这里选的后端,不转到 DSH 默认搜索。更改后端后下一次搜索即使用新选择。
|
|
117
|
-
- Claude 普通对话仍需要 Claude 分组;搜索需要存入插件的 Key 覆盖 DeepSeek 或 GPT 分组,可以是另一个 Key。搜索错误会返回给 CLI,不伪造成功、不自动切另一个后端。
|
|
118
|
-
- 只读、编辑模式单独自动允许这个只读 MCP 搜索工具,不增加 Shell 或文件写权限;用户/管理员的拒绝规则仍有效。CLI 的 `--allowedTools` 是自动批准列表,不是可用工具的排他列表,已有其他工具权限保持原样。
|
|
119
|
-
- 每轮最多 8 次搜索,最多同时 2 次;查询不超过 2000 字符,每次最多 8 个来源,整体搜索预算 60 秒。标题生成不启动 MCP 或进行搜索。
|
|
120
|
-
- 思考区会显示 `▸ 网页搜索:PackyCode DeepSeek(MCP,原生 WebSearch 已禁用)`(或 GPT)。临时服务只监听 `127.0.0.1`,配置中仅含本机一次性凭证,不含搜索 API Key;CLI 结束、取消、超时或插件卸载时关闭并清理,不修改用户现有 MCP 配置。
|
|
109
|
+
**Claude 的搜索。** Claude 对话使用 DSH 的 `web_search`,遵守上表的路由选择,搜索所用 Key 与其它原生模型遵循同一规则。
|
|
121
110
|
|
|
122
111
|
<details>
|
|
123
112
|
<summary>网页搜索是怎么接进 DSH 的</summary>
|
|
@@ -137,7 +126,7 @@ Claude Code CLI → 本机临时 MCP web_search → 插件选定的 DeepSeek/GPT
|
|
|
137
126
|
|
|
138
127
|
- **会切换并停用当前 Key:** 额度用尽(网关报额度、余额、insufficient quota 之类),或 Key 被拒绝(HTTP 401 / `无效的令牌`)。失败的那一步由 harness 重试,从而用上新 Key。
|
|
139
128
|
- **按分组改用,不停用:** 分组读数显示当前 Key 用不了这一轮的模型、而另一个 Key 能用时,这一轮直接用那个 Key(Claude 轮次会在思考区写明「当前 Key「A」的分组不能用 …,本轮改用 Key「B」」)。「使用中」的 Key 不变,其它模型照常用它。只在有证据时才改用:分组还没读到的 Key 照旧使用。
|
|
140
|
-
- **不会切换:** 限速(429);网关把上游渠道故障误报成 400(`当前令牌未覆盖供应商 …`);以及「只允许官方客户端」的 403
|
|
129
|
+
- **不会切换:** 限速(429);网关把上游渠道故障误报成 400(`当前令牌未覆盖供应商 …`);以及「只允许官方客户端」的 403。网关表示「客户端已授权,无需发送连通性测试消息」的 403 单独记为 `GATEWAY_TEST_MESSAGE`,直接说明请求被当作测试消息拒绝,不禁用 Key。仅 Haiku 工具上下文可按下方规则原样重发一次。
|
|
141
130
|
- 全部 Key 都停用时,请求失败并说明没有可用 Key,不会回退到别的凭据。
|
|
142
131
|
|
|
143
132
|
</details>
|
|
@@ -150,7 +139,7 @@ Claude Code CLI → 本机临时 MCP web_search → 插件选定的 DeepSeek/GPT
|
|
|
150
139
|
|
|
151
140
|
选择请求型号与质量后,可在 PackyCode 对话里点 **创建图片** 补充描述,或明确要求使用 `packycode_image_generate`。上传参考图后描述修改要求会调用 `/v1/images/edits`;新图调用 `/v1/images/generations`。图片型号独立于对话型号,其他插件的图片工具仍可并存。
|
|
152
141
|
|
|
153
|
-
|
|
142
|
+
Claude 与其它模型一样,通过 DSH 的 `packycode_image_generate` 工具生图、编辑图片并回传会话,使用独立的图片 Key、设置和余额缓存。旧版 CLI 会话已经保存的图片仍可查看,无需重新生成。
|
|
154
143
|
|
|
155
144
|
**详情里有图、主聊天却显示「图片无法预览」:** 图片结果会在主聊天单独展示,收起思维链或工具详情时仍可见,包括 PTC 嵌套调用。修复版重新打开历史对话也会用已保存的附件补出图片卡片,无需再次生图;模型回复里遗留的无效本机路径图片链接不影响这张卡片。
|
|
156
145
|
|
|
@@ -174,9 +163,9 @@ Claude Code CLI → 本机临时 MCP web_search → 插件选定的 DeepSeek/GPT
|
|
|
174
163
|
| `grok-4.7`(Grok 4.7) | HTTP,Responses,可带图;500k 上下文 | 不能关;`low` / `medium` / `high` / `xhigh` | 以设置页从网关读取的 Grok 分组覆盖为准 |
|
|
175
164
|
| `gemini-4-argon`(Gemini 4 Argon) | HTTP,Gemini 原生流式,可带图;1,048,576 上下文,65,536 输出 | 不能关;`low` / `medium` / `high` | `gemini-slb` |
|
|
176
165
|
| `gemini-3.8-flash`(Gemini 3.8 Flash) | HTTP,Gemini 原生流式,可带图;1,048,576 输入,65,536 输出 | 不能关;`low` / `medium` / `high` | `gemini-slb` |
|
|
177
|
-
| `claude-opus-5-5` |
|
|
166
|
+
| `claude-opus-5-5` | HTTP,Anthropic Messages,可带图和原生工具 | 不能关;`low` / `medium` / `high` / `xhigh` / `max` | 以设置页读取的 Claude 分组覆盖为准 |
|
|
178
167
|
| `claude-sonnet-5-5` | 同上 | 同上 | 同上 |
|
|
179
|
-
| `claude-haiku-5-5` |
|
|
168
|
+
| `claude-haiku-5-5` | 同上;Claude 会话标题固定走它 | 同上 | 同上 |
|
|
180
169
|
|
|
181
170
|
列表里看得到模型,不代表当前令牌分组一定放行。换分组时不要把对应分组一起去掉。
|
|
182
171
|
|
|
@@ -191,29 +180,27 @@ Grok 4.7 的上下文与推理档位来自 [官方文档](https://docs.x.ai/deve
|
|
|
191
180
|
Responses 请求只有 GPT 模型保留 `prompt_cache_key`,其他 Responses 模型默认省略。当前网关的 Grok 路由会将这个字段误报成 `Incorrect API key provided`。
|
|
192
181
|
|
|
193
182
|
<details>
|
|
194
|
-
<summary
|
|
195
|
-
|
|
196
|
-
-
|
|
197
|
-
-
|
|
198
|
-
-
|
|
199
|
-
-
|
|
200
|
-
-
|
|
201
|
-
-
|
|
202
|
-
-
|
|
203
|
-
-
|
|
204
|
-
-
|
|
205
|
-
-
|
|
206
|
-
-
|
|
207
|
-
-
|
|
208
|
-
-
|
|
209
|
-
- 另有 `claude_code` 工具:当前模型是 `gpt-6.1-sol`、`gpt-6-astra` 或 `deepseek-flash` 时,可以把一个任务委派给本机 Claude Code。请求的 `mode` 不会超过会话权限允许的上限;会话处于计划模式时,这个委派也只规划,并把计划正文交回父模型。
|
|
210
|
-
- 声明了模型不支持的推理档位会被 harness 在发请求前拒绝,不要随手改档位映射。
|
|
183
|
+
<summary>协议、分组与客户端兼容性</summary>
|
|
184
|
+
|
|
185
|
+
- 九个模型均在插件内通过 HTTP 调用。Claude 使用 `anthropic-messages`,base URL 不带 `/v1`;SDK 会拼出 `/v1/messages`。模型、协议、上下文和档位映射保持不变。
|
|
186
|
+
- Claude 请求带上实测通过的 CLI 兼容请求头、Bearer 认证、会话元数据和身份系统提示前缀,并保留原始 DSH 系统说明、工具 schema、附件及签名回放。兼容版本固定为 `2.1.295`,无需检测或启动本机 CLI。
|
|
187
|
+
- Bearer 只来自插件保存并按模型选中的 Key;不读取 CLI 登录状态、外部配置或环境 Key,不切换其它提供商。
|
|
188
|
+
- 这组兼容处理不代表服务端取消了分组的客户端限制。当前 Key 仍需覆盖 Claude;客户端政策拒绝会直接说明原因,不禁用 Key,也不自动改用 CLI。服务端规则变化可能使兼容处理失效,详见 [PackyCode 分组政策](https://docs.packyapi.ai/docs/token/)。
|
|
189
|
+
- Haiku 与 Sonnet 的工具请求都已出现「客户端异常」403 后相同请求成功的情况。插件只对这一特定响应等待 1 秒、原样重发一次;Haiku 另覆盖已捕获的「客户端已授权,无需发送测试消息」403,两种错误共用一次上限。再次拒绝仍会报错。Opus、纯文本请求、普通「只允许官方 CLI」拒绝、429 和已经开始的响应流不触发这次重发。原始失败保留在实测记录中;这不是网关内部判定已得到修复的证明。
|
|
190
|
+
- Claude 流收到 `message_stop` 后即可完成,不再等网关关闭 HTTP 连接;跨分片的 CRLF 换行保持完整。流内错误与取消仍会返回,未收到响应头的等待也不会被当作成功。
|
|
191
|
+
- DSH 的 bash/read/write/edit/glob/grep 在 HTTP 请求中使用已声明的 CLI 标准名称(如 `Bash`、`Read`),其它工具使用 MCP 命名;回到 DSH 时仅还原本次实际提供的工具名称,未知名称不会获得执行权限。工具参数、调用 id、结果和历史签名不变。思考展示采用 CLI 默认:Haiku 为 `omitted`,Sonnet / Opus 为 `updates`(附带相应 beta)。所选推理强度和输出上限不变,空思考块的签名仍完整回传;明确指定的显示模式优先。
|
|
192
|
+
- Claude 请求中的旧工作目录句式会在与当前会话元数据一致时转换为单独的 JSON 路径,避免把提示语的句号复制进路径。真实目录名中的点、Windows 盘符、UNC、空格和反斜杠保持不变;命令参数不会被自动修剪。命令工具优先使用当前目录或 `workdir`,Windows 的 PowerShell 工具保持其原有语法。
|
|
193
|
+
- 普通 Claude 对话保留完整 DSH 工具循环、权限及计划模式;网页搜索和生图使用宿主工具。会话标题改由 `claude-haiku-5-5` 通过 HTTP 生成;Astra 标题仍交给 Sol。
|
|
194
|
+
- 已移除旧 `claude_code` 委派工具、CLI 运行器、检测与安装界面、配置字段及本机 MCP 桥。旧配置中的 `claudeCliPath`、`claudeCliMode` 和 `claudeCliCwd` 不再生效;用户独立安装的 Claude Code 不受影响。
|
|
195
|
+
- Codex 的 Responses 请求仍需要 `prompt_cache_key`;插件补上缺失的会话标识,其它 Responses 模型省略该字段。
|
|
196
|
+
- 构建后可用 `node scripts/claude-check.mjs` 验证三个 Claude 模型的订单核算、工单归类、库存补货、只读库存查询工具回传、商品色卡标注和中文标题,并核对业务答案。`node scripts/claude-stability.mjs --start --hours 6 --key-label <备注名>` 开始有截止时间和请求上限的采样;定时执行同一脚本继续采样,用 `--status` 查看记录。业务场景版本和每轮构建分别记录;测试消息拒绝将对应检查记为失败,其余预定检查继续,真实凭据或额度错误仍会停止整个窗口。测试不改变已保存的凭据,也不启动 DSH。
|
|
197
|
+
- 连续对话可用 `node scripts/claude-conversation-check.mjs --model claude-haiku-5-5 --rounds 3 --key-label <备注名> --output .artifacts/claude-conversation.json`:同一插件适配器处理独立会话,每组保留六轮对话和完整工具历史,检查追问中的数值一致性、最终 JSON 和异常字符;遇到失败停止该批次并保留记录。单请求默认 65 秒、输出上限 2048 token;诊断可通过 `--timeout-ms`(5000–300000)和 `--max-tokens`(1024–128000)显式调整。`--capture-wire` 记录这组模拟业务的完整请求、非认证头和中断前的流事件,用于精确重放;不记录 Key。报告包含场景版本、适配器生命周期、所用上限、首响应和完整响应耗时。这些选项不修改插件的运行参数。
|
|
211
198
|
|
|
212
199
|
</details>
|
|
213
200
|
|
|
214
201
|
## 更新与卸载
|
|
215
202
|
|
|
216
|
-
**更新:** 打开 **设置 → PackyCode**,有新版本时点「更新插件」。它会在当前 profile 目录里用 DSH 自带的 pnpm 安装精确版本,并读回 `package.json` 确认版本落地。本地 `link:` 开发安装不会出现这个按钮。完成后完全退出并重新打开桌面应用。只刷新页面不会重载 Host。也可以在**插件**页重新安装,同样要填写带版本号的包名(例如 `dsh-packycode-api@1.
|
|
203
|
+
**更新:** 打开 **设置 → PackyCode**,有新版本时点「更新插件」。它会在当前 profile 目录里用 DSH 自带的 pnpm 安装精确版本,并读回 `package.json` 确认版本落地。本地 `link:` 开发安装不会出现这个按钮。完成后完全退出并重新打开桌面应用。只刷新页面不会重载 Host。也可以在**插件**页重新安装,同样要填写带版本号的包名(例如 `dsh-packycode-api@1.3.0`),否则装上的可能是发布满 24 小时的旧版。
|
|
217
204
|
|
|
218
205
|
**从本地路径安装切回官方源时,必须先卸载。** 「更新」是 `pnpm add`,它只重写包目录里的文件,不会删除更早一次本地路径安装留在包目录内的 `node_modules`;那份旧依赖会继续挡住 DSH 自带的包,插件行加载失败且看不出原因。「卸载」执行的是 `pnpm remove`,会删掉整个包目录,重装才是干净的。用 `node scripts/install-check.mjs` 可以确认当前 profile 是否处于这个状态。
|
|
219
206
|
|
|
@@ -229,7 +216,7 @@ ls ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/node_modules
|
|
|
229
216
|
|
|
230
217
|
有输出就是残留:从 npm 安装的包不会自带 `node_modules`,这一份通常来自更早一次「本地路径」安装(`file:` 或直接写路径,而不是 `link:`)。它位于 profile 目录内部,而 DSH 解析插件导入时优先使用 profile 内的副本,所以插件拿到的仍是那份旧依赖 —— 例如 `@deepseek-ai/schemastery` 3.18.2 没有 `Schema.volatile()`,模块在导入阶段就抛错。导入失败时 Loader 不会为这一行创建 fiber,客户端 bundle 也不会被组合,于是模型路由、RPC 通道和设置页全都不会出现。
|
|
231
218
|
|
|
232
|
-
修复:到**插件**页**卸载**本插件,再用带版本号的包名重新**安装**(例如 `dsh-packycode-api@1.
|
|
219
|
+
修复:到**插件**页**卸载**本插件,再用带版本号的包名重新**安装**(例如 `dsh-packycode-api@1.3.0`),然后完全退出并重新打开桌面应用。卸载执行的是 `pnpm remove`,会删掉整个包目录;直接重装或点「更新」只重写文件,不会清掉这份残留。也可以手动删掉上面那个 `node_modules` 再重启。
|
|
233
220
|
|
|
234
221
|
**首次安装后,设置页每张卡片都显示 `transport failure for /packycode-api/…: HTTP 405`?** 实际装上的是 1.1.6 或更早的版本,通常是因为安装时只填了包名:安装提示显示的是最新版,pnpm 实际装的却是发布满 24 小时的旧版(见「安装插件」)。这些旧版要等 DSH 重启、重建它的 `connection` 服务之后,才能注册设置通道。所以首次安装后 `/packycode-api` 通道还不存在,请求落到静态页面,返回 405;模型路由和设置页本身照常加载。1.1.7 起首次安装不需要重启。先确认装上的版本:
|
|
235
222
|
|
|
@@ -241,13 +228,13 @@ grep '"version"' ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/package.
|
|
|
241
228
|
|
|
242
229
|
**某个模型不可用,但 Key 是有效的?** 看「账户与 Key」里这个 Key 的分组和 ✓ / ✕:分组不覆盖这个模型时,换一个分组合适的 Key,或在 PackyCode 控制台给 Key 加上对应分组。存了分组合适的 Key 时,插件会自动用它跑这个模型。分组拒绝不会停用 Key。
|
|
243
230
|
|
|
244
|
-
**Claude
|
|
231
|
+
**Claude 报「只接受官方 Claude Code CLI」或「客户端存在异常」?** 这是网关的客户端政策拒绝,不等于 Key 失效。先在「账户与 Key」和 PackyCode 模型广场确认所选模型的分组覆盖;确认覆盖后仍被拒绝,可用诊断信息定位。插件不会因此禁用 Key、切换提供商或启动 CLI。
|
|
245
232
|
|
|
246
233
|
**余额对不上账号账单?** 设置页合计的是这里列出的 Key,不含同账号下没添加到本插件的其它令牌。个别 Key 读失败时会单独注明,不会被算成 0。
|
|
247
234
|
|
|
248
235
|
**余额显示 `读取失败: https://www.packyapi.com: fetch failed`?** 这是 1.0.4 及更早版本的默认余额接口在国内网络下被 DNS 污染,开了代理才能连上,所以有时正常、有时失败。新版本默认改用 `https://www.packyapi.ai`。模型列表是插件内置的,不需要向 PackyCode 查询,不受影响。
|
|
249
236
|
|
|
250
|
-
**选了 Claude 模型一直显示「深度求索中」?**
|
|
237
|
+
**选了 Claude 模型一直显示「深度求索中」?** 查看 DSH 的错误或诊断信息。429/503 表示网关排队或限流,按宿主重试策略处理;客户端政策拒绝会直接说明原因。普通模型对话不会启动本机 CLI。
|
|
251
238
|
|
|
252
239
|
**限速之后 Key 被停用了?** 不该发生。429 不会切换 Key。额度用尽或 401 才会停用;充值后点「重新启用」。
|
|
253
240
|
|
|
@@ -255,13 +242,13 @@ grep '"version"' ~/.dsh/profiles/desktop/node_modules/dsh-packycode-api/package.
|
|
|
255
242
|
|
|
256
243
|
**网页搜索报「no stored API key's group covers …」?** 所选搜索后端的模型不在你的令牌分组里(或网关暂时把它路由到了别的供应商)。在 **设置 → PackyCode → 网页搜索** 换一个后端,或添加分组覆盖它的 Key。
|
|
257
244
|
|
|
258
|
-
|
|
245
|
+
**以前安装的 Claude Code 还需要吗?** 本插件已经移除 CLI 运行、安装和委派功能,Claude 模型直接通过 HTTP 调用。独立使用 Claude Code 的用户可继续保留它;本插件不会改动其安装或配置。
|
|
259
246
|
|
|
260
247
|
**回答被截断(「已达到输出 token 上限」)、请求反复失败,怎么反馈?** 打开 **设置 → PackyCode → 诊断信息**,选出问题的会话(最近 20 个,按时间倒序,标着所在文件夹名),点「生成诊断信息」再点「复制」,把内容贴到 [Issue](https://github.com/BaronCyrus/dsh-packycode-api/issues) 或发给插件作者。内容只有设置和数字:插件版本、会话 id 与创建时间、每个 Key 的序号与分组(不含备注名和 Key 本身)、每次请求用的模型、推理档位和输出上限、最近若干步的 token 用量与结束原因,以及重试和失败的错误码(错误信息已脱敏并截短)。不含对话内容、文件路径和 Key。复制不可用时,文本会被全选,按 ⌘C 或 Ctrl+C 即可。
|
|
261
248
|
|
|
262
249
|
## 安全边界
|
|
263
250
|
|
|
264
|
-
本项目是社区插件,与 DeepSeek、PackyCode 无隶属或背书关系。模型请求会发到你配置的 PackyCode 接口;凭据不返回浏览器,不代表推理在本地完成。Claude
|
|
251
|
+
本项目是社区插件,与 DeepSeek、PackyCode 无隶属或背书关系。模型请求会发到你配置的 PackyCode 接口;凭据不返回浏览器,不代表推理在本地完成。Claude 也通过插件内的 HTTP 路由调用。
|
|
265
252
|
|
|
266
253
|
Key 存在本机 DSH 凭据文件(`~/.dsh/.credentials.yaml`,权限由 DSH 设为仅所有者可读),不进设置文档、日志或对话记录。余额请求只在宿主侧发出,带超时并禁止重定向。
|
|
267
254
|
|
|
@@ -278,13 +265,7 @@ pnpm run check
|
|
|
278
265
|
|
|
279
266
|
`pnpm run check` 会跑全部测试、重新构建,并在 `.artifacts/` 打出 tarball。`lib/` 是已提交的构建产物,改 `src/` 后用 `pnpm run build` 生成,不要手改。
|
|
280
267
|
|
|
281
|
-
真机网关用 `node scripts/live-check.mjs` 验证:它通过插件注册的同一条路由,读余额和分组、让每个 HTTP 模型回答一次、演练 Key 轮换和失败分类,只打印 Key 的末 4 位。加 `--with-
|
|
282
|
-
|
|
283
|
-
Claude CLI 的 MCP 接口验证用 `node scripts/cli-search-check.mjs`:运行真实 CLI,普通 Claude 响应和搜索数据默认由本地测试服务模拟,不消费额度;会检查三种权限模式、原生搜索禁用和临时资源清理。加 `--live --backend deepseek` 或 `--live --backend gpt` 会让只读模式的那一次搜索走真实后端(其它两种模式仍模拟)。这不等于验证了真实 Claude 上游对话或运行中的 DSH 集成。
|
|
284
|
-
|
|
285
|
-
图片 MCP 验证用 `node scripts/cli-image-check.mjs`:真实官方 CLI 依次生图、用生成结果编辑,并经 DSH 消息组装器验证持久化图片;默认 Claude 和图片网关响应均在本地模拟,同时检查只读/编辑/完全权限、计划模式、标题和临时配置清理。加 `--live` 会用已保存的独立图片 Key 向真实图片网关发出一次 Sunburst `low` 生图与一次编辑,结果写入 `.artifacts/`;Claude 回复仍由本地模拟网关提供。加 `--with-claude` 则连 Claude 也走真实网关,默认 Haiku,另消费对话额度;两者都不启动或重启 DSH,也不等于验证了运行中桌面会话。
|
|
286
|
-
|
|
287
|
-
计划模式另用 `node scripts/cli-plan-check.mjs` 验证:真实 CLI 对接本地模拟网关,检查 stdio 计划提交、并发计划归属、本轮文件回退、旧计划隔离、实际拒绝次数上限和清理;不读取真实凭据、不消费额度、不启动 DSH。
|
|
268
|
+
真机网关用 `node scripts/live-check.mjs` 验证:它通过插件注册的同一条路由,读余额和分组、让每个 HTTP 模型回答一次、演练 Key 轮换和失败分类,只打印 Key 的末 4 位。加 `--with-search` 会每个搜索后端各搜一次;默认运行只消耗少量额度。
|
|
288
269
|
|
|
289
270
|
排查「装了却看不到插件」用 `node scripts/install-check.mjs`:它只读当前 profile,列出被包内残留 `node_modules` 挡住的宿主包(含版本)和对应的修复步骤,发现问题时以退出码 1 结束;`--profile <name>`、`--home <dir>` 可指定其它 profile,`--json` 输出结构化结果。
|
|
290
271
|
|