aaif-goose / aaif-goose/goose

ACP: a failed/unreachable-provider turn is reported as a successful session/prompt (stopReason: end_turn, no JSON-RPC error)

Ouverte
#11,047 1 commentaire 0 réactions 1 personne assignée Réclamée par @jbg Voir sur GitHub
Langage dominant
Rust
Étoiles
54.2k
Forks
6.2k
Merge moyen
3 j 2 h
PR mergées (30 j)
262

Description

**Describe the bug**

Over ACP, when the configured provider is completely unreachable, `session/prompt` does not return a JSON-RPC error and `stopReason` does not indicate failure. The network failure is instead surfaced only as ordinary assistant text, and the request completes as `end_turn`. An automated ACP client cannot detect this failure from the JSON-RPC contract at all — it would have to pattern-match human-readable, locale-specific text in the streamed content.

---

**To Reproduce**

1. Configure `GOOSE_PROVIDER=ollama` with no Ollama daemon running (or otherwise make the configured provider fully unreachable).
2. Connect over ACP (`goose acp` over stdio), `initialize`, create a session, send `session/prompt` with a simple prompt.
3. Observe the exchange:

```
→ {"id":4,"method":"session/prompt","params":{"sessionId":"…","prompt":[{"type":"text","text":"Say hi"}]}}
← notif session/update {"sessionUpdate":"session_info_update","_meta":{"goose":{"activeRunId":"run_…"}}}
(logs: 10× "Request failed, retrying (n/10): NetworkError(\"Could not connect to localhost:11434…\")"
"Backing off for 2.2s / 5.1s / 11.2s / 17.7s … before retry")
← notif session/update {"sessionUpdate":"agent_message_chunk","content":{"type":"text",
"text":"Network error: Could not connect to localhost:11434 — check your network connection and try again.\n\nPlease resend your m…"}}
← notif session/update {"sessionUpdate":"session_info_update","_meta":{"goose":{"activeRunId":null}}}
← notif session/update {"sessionUpdate":"usage_update","used":0,"size":128000}
← {"id":4,"result":{"stopReason":"end_turn"}}
```

No JSON-RPC `error` object anywhere in the exchange; `result.stopReason` is `"end_turn"`, identical to a successful turn.

---

**Expected behavior**

Not prescribing a specific fix, but as options: a distinct `stopReason` (e.g. an error/refusal variant) or a structured error field on the response would let a programmatic ACP client distinguish "the model answered" from "the provider was unreachable and goose gave up" without string-matching assistant text.

---

**Please provide the following information**

- **OS & Arch:** Linux x86_64
- **Interface:** ACP (stdio), `goose acp`
- **Version:** `1.45.0-canary+eea5609` (`goose-x86_64-unknown-linux-musl`, `canary` release tag)
- **Extensions enabled:** none
- **Provider & Model:** Ollama, unreachable (`GOOSE_PROVIDER=ollama`, no daemon running)

---

**Additional context**

- The whole failure took **~105 seconds across ~10 retries**. This latency is already tracked for the Desktop UI in #10917 ("Connection-refused to a down local provider is retried for ~2 minutes before surfacing an error") and mid-stream transient errors in #10897 — both about the same retry/backoff mechanism (`crates/goose-provider-types/src/retry.rs`), so linking those for context rather than duplicating the latency complaint. This issue is specifically about the **JSON-RPC success/failure contract** over ACP, not the latency.
- We set `GOOSE_PROVIDER_SKIP_BACKOFF=1` to shorten the repro and it had no visible effect. Looking at `retry.rs`, `skip_backoff` is parsed with `std::env::var(...).parse::().unwrap_or(false)` — Rust's `bool::from_str` only accepts the literals `"true"`/`"false"` (case-sensitive), so `"1"` fails to parse and silently falls back to `false`. That's consistent with what we observed, though we haven't confirmed whether `"true"` behaves differently — flagging it as a likely explanation, not a verified fix.
- Tested **without real provider credentials** — Ollama was simply not running, purely to get past the "no provider configured" wall using a free/local provider. This means we only exercised the network-failure path; we did not verify what a genuinely successful ACP turn's `stopReason`/`result` looks like, only that this particular failure path is indistinguishable from one.

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.