aaif-goose / aaif-goose/goose

ACP: agent updates that arrive outside a prompt are dropped — background-task turns never reach the user

Đang mở
#11,320 0 bình luận 0 reaction 1 người được giao Được @alexhancock nhận Xem trên GitHub
Ngôn ngữ chính
Rust
Star
54.2k
Fork
6.2k
Merge trung bình
3 ngày 4 giờ
Pull request đã merge (30 ngày)
240

Mô tả

**Describe the bug**

An ACP backend can send `session/update` notifications when no `session/prompt` is in flight. goose receives them and throws them away, so any work the backend does after the turn it was asked for is lost — silently, apart from a `WARN` line.

This is routine with `claude-acp`. Claude Code answers, ends the turn, and later resumes itself when a backgrounded task completes (a build, a test run) — producing a full turn of text and tool calls that the user asked for and never sees. The session simply stops at "waiting on the build" and nothing more arrives, so it reads as the model hanging.

The drop is in the notification dispatch handler (`crates/goose/src/acp/provider.rs`). `AcpProvider::stream` breaks out of its consumer loop at `AcpUpdate::Complete` and drops the receiver, so a chunk arriving afterwards fails to send and is discarded:

```rust
if let Err(e) = tx.send(AcpUpdate::Text(text)).await {
tracing::warn!(error = %e, "undelivered ACP agent message chunk");
}
```

There is no path in goose for an assistant message that is not a response to a prompt goose sent.

---

**To Reproduce**

1. Configure the `claude-acp` provider and start a session.
2. Ask for something that makes Claude Code start a long task in the background and end its turn — e.g. "kick off a release build in the background and tell me when it finishes".
3. The turn ends with a message like "I'll report when it finishes".
4. When the build finishes, Claude Code produces its report. Nothing appears in goose.
5. `~/.local/state/goose/logs/cli//*.log` shows one `undelivered ACP agent message chunk` warning per lost chunk.

The backend's own transcript (`~/.claude/projects//*.jsonl`) contains the complete lost turn, which is how I confirmed the content exists and only goose discards it.

---

**Expected behavior**

Updates that arrive for the active session outside a prompt are surfaced as a new assistant message: persisted to the session and pushed to the UI, so the session shows the late turn as it arrives.

`set_session_title_callback` is the existing precedent for a provider pushing something into the session outside the reply stream — the same shape would work here:

- a `Provider` hook alongside `set_session_title_callback` in `crates/goose-provider-types/src/base.rs`
- the ACP provider routing `Text`/`Thought`/tool-call updates to it when no turn is live, instead of warning and dropping
- `Agent::update_provider` persisting the message and emitting it on the session update channel
- a notifier in `crates/goose/src/acp/server.rs` alongside `spawn_session_name_update_notifier` to send `agent_message_chunk` to Desktop

Whatever the mechanism, the requirement is that goose stop discarding content it has already received.

---

**Please provide the following information**
- **OS & Arch:** macOS 26.6.1 arm64
- **Interface:** UI (Desktop)
- **Version:** v2.0-rc-04-27-0 (desktop 1.45.0)
- **Extensions enabled:** developer, context7, playwright, goose docs
- **Provider & Model:** claude-acp — claude-agent-acp 0.63.0 — claude-opus-5

---

**Additional context**

Evidence from a diagnostics bundle for one affected session: the goose transcript's last message is `"Waiting on just make-ui ... I'll report as soon as it lands."`, and the log carries twelve `undelivered ACP agent message chunk` warnings over the following six seconds — the whole report turn, dropped chunk by chunk.

The warning itself only exists because of the fix for #11178, which keeps `prompt_response_tx` registered past the prompt response; before that the drop was completely silent. That fix is about chunks racing the *end* of a turn, and its bounded grace window is deliberately short. This is the separate case of chunks belonging to no turn at all, which no grace window can cover.

Related but distinct: #10433 (a dropped MCP `notifications/tools/list_changed`) is the same class of defect — a notification goose receives and discards — on a different channel.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bug nằm trong `crates/goose/src/acp/provider.rs`, nơi vòng lặp `AcpProvider::stream` loại bỏ các bản cập nhật sau khi một lượt hoàn tất. Hãy kiểm tra notification dispatch handler và cảnh báo của `tx.send`. Xem `crates/goose-provider-types/src/base.rs` để tìm pattern hook của `Provider`, tương tự như `set_session_title_callback`. Xem `crates/goose/src/acp/server.rs`, trong đó `spawn_session_name_update_notifier` là mô hình cho một notifier mới. Bản sửa bao gồm việc định tuyến các bản cập nhật `Text`/`Thought`/tool-call đến một hook mới khi không có lượt nào đang hoạt động, lưu bền vững thông báo thông qua `Agent::update_provider` và phát thông báo đó trên kênh cập nhật session. Kiểm thử bằng cách tái hiện vấn đề với `claude-acp` và kiểm tra logs để tìm cảnh báo.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
rust
Lĩnh vực
ai-infra-agents, backend
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
45/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.