Skip to content

feat(acp): add stable error_class to turn_error observer events - #2289

Open
Bartok9 wants to merge 1 commit into
block:mainfrom
Bartok9:bartok9/agent-turn-error-class
Open

feat(acp): add stable error_class to turn_error observer events#2289
Bartok9 wants to merge 1 commit into
block:mainfrom
Bartok9:bartok9/agent-turn-error-class

Conversation

@Bartok9

@Bartok9 Bartok9 commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Refs #1659

Problem

Agent turn failures are emitted to the observer feed as undifferentiated turn_error events carrying only outcome + an error string. As #1659 notes, the harness boundary (handle_prompt_result in crates/buzz-acp/src/lib.rs) doesn't include a class field, so every failure type arrives at the UI as the same thing — and the UI collapses it to a transient "Turn error" that disappears before a human can act on it. Operators can't tell an idle timeout from a dead process from a provider/application error.

Why it matters

Agents are first-class citizens in Buzz; when an agent turn fails, humans and other agents need to know how it failed to react correctly (retry vs. wait vs. fix credentials vs. report a crash). A stable, machine-readable class is the minimum needed for the UI (and other observers) to persist a differentiated, actionable badge.

What this changes (harness boundary — seam #1 of #1659)

Threads a machine-readable error_class onto every turn_error observer payload:

Outcome error_class
AgentExited exited
Timeout(Idle) idle_timeout
Timeout(Hard) hard_timeout
CancelDrainTimeout cancel_drain_timeout
transport/protocol Error (Io/WriteTimeout/Timeout/Protocol) transport_error
application Error (pipe intact) application_error
task panic (agent_panic event) panic

The fatal-death classes reuse the existing outcome_label taxonomy; the two Error sub-branches already distinguish transport vs application for respawn decisions, so this just surfaces that same distinction to observers.

Additive / no breaking changes

Existing outcome, error, and code fields are unchanged and still emitted. error_class is a new key alongside them. This means the UI-store fix (seam #2, activeAgentTurnsStore.ts) can consume error_class in a decoupled follow-up PR without depending on this one's timing.

How to test

cargo test -p buzz-acp error_outcome_emission   # 16 passed (incl. new test)
cargo fmt -p buzz-acp --check
cargo clippy -p buzz-acp

New regression test turn_error_carries_stable_error_class asserts the emitted class per outcome (exited, idle_timeout). The existing "exactly one feed event" tests still pass, confirming no double-emit or dropped-emit regressions.

Observability / security notes

  • Purely additive to an existing observer event; no new surface, no new unsafe (crate is #![deny(unsafe_code)]).
  • error_class is a fixed enum of static strings — no user/agent-controlled data flows into the class value, so it's safe to branch on in the UI.
  • Error message content is unchanged (same redaction/handling as before).

Signed-off-by DCO.


Context: this mirrors a classified-failure/observability pattern we've used elsewhere — never collapse distinct failure modes into one transient signal. Happy to take the UI-store persistence half in a follow-up PR if you'd like to keep PRs one-seam-each.

@Bartok9
Bartok9 marked this pull request as ready for review July 21, 2026 21:44
@Bartok9
Bartok9 requested a review from a team as a code owner July 21, 2026 21:44
@Bartok9
Bartok9 force-pushed the bartok9/agent-turn-error-class branch from 6ee365f to 2dee886 Compare July 22, 2026 14:33
@Bartok9
Bartok9 force-pushed the bartok9/agent-turn-error-class branch from 2dee886 to 71f6f67 Compare July 24, 2026 16:42
@Bartok9
Bartok9 force-pushed the bartok9/agent-turn-error-class branch 8 times, most recently from 6c9457a to d52e620 Compare August 1, 2026 17:59
@Bartok9
Bartok9 force-pushed the bartok9/agent-turn-error-class branch 3 times, most recently from 8974fdb to 315299b Compare August 7, 2026 13:34
@Bartok9
Bartok9 force-pushed the bartok9/agent-turn-error-class branch 2 times, most recently from b3135cd to a216dec Compare August 14, 2026 13:27
@Bartok9
Bartok9 force-pushed the bartok9/agent-turn-error-class branch 4 times, most recently from d7b2c6b to e421885 Compare August 21, 2026 13:17
Agent turn failures were emitted to the observer feed as undifferentiated
turn_error events (only outcome + error string), so the UI could not persist
a differentiated, actionable badge and collapsed everything to a transient
"Turn error". This threads a machine-readable error_class onto every
turn_error payload:

- fatal process death (exited / idle_timeout / hard_timeout /
  cancel_drain_timeout) surfaces as its outcome label
- transport/protocol errors -> "transport_error"
- application errors (pipe intact) -> "application_error"
- agent_panic events carry "panic"

Additive only; existing outcome/error/code fields unchanged. Adds a focused
regression test asserting error_class per outcome.

Refs block#1659

Signed-off-by: Bartok9 <danielrpike9@gmail.com>
(cherry picked from commit 6c93355)
Signed-off-by: Bartok9 <259807879+Bartok9@users.noreply.github.com>
(cherry picked from commit d7b2c6b)
Signed-off-by: Bartok9 <259807879+Bartok9@users.noreply.github.com>
(cherry picked from commit e421885)
Signed-off-by: Bartok9 <259807879+Bartok9@users.noreply.github.com>
@Bartok9
Bartok9 force-pushed the bartok9/agent-turn-error-class branch from e421885 to a513134 Compare August 21, 2026 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant