dsh-agy-link 0.4.20 → 0.4.22

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,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.22 (2026-08-27)
4
+
5
+ - **Fixed: `registration.adapter.prepareCall is not a function` on new DSH hosts (本轮运行失败 UNKNOWN).**
6
+ - **Field report**: after upgrading the DSH host (manjh's source checkout), every turn failed immediately with `registration.adapter.prepareCall is not a function` — category UNKNOWN in the GUI, no reply at all.
7
+ - **Root cause (interface drift)**: dsh-llm >= 0.1.1-rc.2 added `LlmAdapter.prepareCall(provider, model, signal)` and `LlmRuntime.prepareCall()` now calls `registration.adapter.prepareCall(...)` **unconditionally** (both the prepared-call path and the direct `adapterStream` path). The plugin's devDependency pinned `@deepseek-ai/dsh-llm ^0.1.0-rc.6` (base class without `prepareCall`); when the plugin's adapter class resolved an older dsh-llm copy than the host runtime, `registration.adapter.prepareCall` was `undefined` and every turn threw a bare TypeError.
8
+ - **Fix**: `AgyAdapter` now implements `prepareCall` explicitly, returning `{ model: await this.resolveModel(...), stream: options => this.stream(options) }` — the exact one-generation capability-bound handle the new runtime expects (same shape as the base default, but present regardless of which dsh-llm copy the plugin resolves). Backward compatible: runtimes < 0.1.1-rc.2 never call it. The method is declared structurally (no `override` / new-type import) so the plugin keeps typechecking against dsh-llm `^0.1.0-rc.6` and the repo's `npm ci` peer resolution stays intact; the runtime contract matches the 0.1.1-rc.2 `PreparedAdapterCall` shape.
9
+ - Regression test pins the contract end-to-end: `prepareCall` returns resolved model metadata (id/provider/defaultMaxTokens) plus a stream that runs a full fake turn.
10
+
11
+ ## 0.4.21 (2026-08-27)
12
+
13
+ - **Fixed: Silent `agy exited with code 1` Hid the Real Cause (发送消息无回复、只见 exit 1).**
14
+ - **Field report**: a user session log showed every turn failing with the bare message `agy exited with code 1` (code PROCESS_EXIT, empty stderr, zero tokens) — each attempt ran ~7–10s, failed once, retried once, failed again, and the UI never surfaced WHY (no reply text at all).
15
+ - **Root cause of the blindness (verified live against agy 1.1.22)**: agy reports its failure as a `result` envelope on **stdout** (`{"event":"result",...,"status":"ERROR","error":"<human-readable reason>"}`) and exits 1 with EMPTY stderr — e.g. an invalid model/effort pairing fails instantly with `--model gemini-3.7-flash requires --effort (available: low, medium, high)`. The adapter's non-zero-exit branch dropped that envelope entirely: rate-limit-shaped errors were still classified (the classifier already read `lastResultError`), but any OTHER failure degraded to the bare exit-code line with no cause.
16
+ - **Fix**: the PROCESS_EXIT failure message now prefers the stdout envelope's error text (falling back to the stderr tail). Same error code and retry policy; users finally see agy's own reason, e.g. `agy exited with code 1: upstream request failed while generating` or `…: --model gemini-3.7-flash requires --effort (available: low, medium, high)`.
17
+ - **Diagnostics unaffected**: `/agy doctor` (`~/.dsh/agy-link/diagnostics/doctor-*.md`) still carries the full redacted raw stdout tail for deeper incidents.
18
+ - Regression test pins the exact silent-failure shape (stdout envelope + exit 1 + empty stderr) via a new `exit-error` fake-agy mode.
19
+
3
20
  ## 0.4.20 (2026-08-27)
4
21
 
5
22
  - **Fixed: Primary Account Quota Fetched With a STALE Token (主账号刷新/同步拿的值不对).**
package/dist/index.js CHANGED
@@ -2127,6 +2127,25 @@ var AgyAdapter = class extends LlmAdapter {
2127
2127
  }
2128
2128
  return resolved;
2129
2129
  }
2130
+ /**
2131
+ * Bind exact model metadata and dispatch to ONE adapter generation.
2132
+ * Required by dsh-llm >= 0.1.1-rc.2: LlmRuntime.prepareCall calls
2133
+ * registration.adapter.prepareCall(provider, model, signal) unconditionally,
2134
+ * so an adapter compiled against the old base class (no prepareCall) crashed
2135
+ * with "registration.adapter.prepareCall is not a function" on new hosts.
2136
+ * Implemented explicitly here so both old and new runtimes work: the old
2137
+ * runtime never calls it, the new runtime gets the capability-bound handle.
2138
+ * Declared without `override`/imported types on purpose: the plugin still
2139
+ * typechecks against dsh-llm ^0.1.0-rc.6 (no prepareCall in the base), while
2140
+ * the runtime contract matches the 0.1.1-rc.2 PreparedAdapterCall shape
2141
+ * { model: LlmResolvedModelInfo; stream(options): AsyncIterable<StreamChunk> }.
2142
+ */
2143
+ async prepareCall(provider, model, signal) {
2144
+ return {
2145
+ model: await this.resolveModel(provider, model, signal),
2146
+ stream: (options) => this.stream(options)
2147
+ };
2148
+ }
2130
2149
  /** Build the agy argv for one call. Exported for tests. */
2131
2150
  buildArgs(opts) {
2132
2151
  const args = [
@@ -2430,12 +2449,14 @@ var AgyAdapter = class extends LlmAdapter {
2430
2449
  message: "Google Antigravity quota / rate limit reached: " + bestMsg
2431
2450
  };
2432
2451
  } else if (!consumable) {
2433
- if (outcome.code !== 0) failure = {
2434
- kind: "error",
2435
- code: Err.PROCESS_EXIT,
2436
- message: "agy exited with code " + outcome.code + (outcome.stderrTail !== "" ? ": " + brief(outcome.stderrTail) : "")
2437
- };
2438
- else if (parser.stats.lastResultError) failure = {
2452
+ if (outcome.code !== 0) {
2453
+ const detail = parser.stats.lastResultError ?? (outcome.stderrTail !== "" ? brief(outcome.stderrTail) : "");
2454
+ failure = {
2455
+ kind: "error",
2456
+ code: Err.PROCESS_EXIT,
2457
+ message: "agy exited with code " + outcome.code + (detail !== "" ? ": " + detail : "")
2458
+ };
2459
+ } else if (parser.stats.lastResultError) failure = {
2439
2460
  kind: "error",
2440
2461
  code: Err.AGY_ERROR,
2441
2462
  message: "agy reported an error: " + parser.stats.lastResultError
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-agy-link",
3
- "version": "0.4.20",
3
+ "version": "0.4.22",
4
4
  "description": "Google Antigravity (agy CLI) models for DeepSeek Harness — stream Gemini/Claude/GPT-OSS subscriptions into DSH with thinking, tool activity, token usage and in-GUI Google OAuth login.",
5
5
  "type": "module",
6
6
  "license": "MIT",