Skip to content

fix(agy): report the failure reason instead of echoing the answer - #1642

Open
junmo-kim wants to merge 1 commit into
tiann:mainfrom
junmo-kim:fix/agy-failure-echo
Open

fix(agy): report the failure reason instead of echoing the answer#1642
junmo-kim wants to merge 1 commit into
tiann:mainfrom
junmo-kim:fix/agy-failure-echo

Conversation

@junmo-kim

Copy link
Copy Markdown
Contributor

Problem

On an agy session, a turn that ends with a non-SUCCESS result envelope
delivers its answer twice: once as the streamed agy_message, then again as an
error event right below it — the whole answer rendered as plain text with a ⚠
prefix.

The driver takes the failure text from response:

if (event.status !== 'SUCCESS') {
    resultFailure = event.response?.trim()
        || `agy turn failed: ${event.status}`;
}

But response is the answer field. agy fills it from the completed buffer
regardless of status, so on a failed turn it holds the same answer that already
went out through the delta stream. The reason for the failure is reported
separately, in error, which the parser did not read at all.

Measured on agy 1.1.13 (--print-timeout 15s against a long prompt):

{"event":"result","result":{"conversation_id":"","status":"ERROR","response":"","error":"timeout waiting for response","duration_seconds":2.4,}}

response is empty and the reason lives in error. On a turn that produced
text before failing, response carries that text instead — which is what ends
up duplicated in the chat.

Change

  • agyNdjsonParser.ts: carry error through the result envelope (added to
    ResultEnvelope and to the result stream event; null when absent).
  • agyHeadlessDriver.ts: read the failure text from error rather than
    response. The existing agy turn failed: <status> fallback still applies
    when the envelope carries no reason, so a failed turn stays visible.

The SUCCESS branch is untouched.

Tests

  • parser: an envelope with error surfaces it; the existing SUCCESS/FAILURE
    cases now assert error: null.
  • driver: a failed envelope whose response holds the answer reports the
    error text and never emits the answer as an error; a failed envelope with no
    error falls back to the status; a timeout envelope surfaces
    timeout waiting for response.

bun run test:cli and bun run typecheck:cli pass.

Note

#1629 fixes the same duplication on the SUCCESS path (where the guard comparing
the streamed text with the envelope misfires on mangled deltas). This one is the
failure path, which that guard never reaches. The two touch adjacent hunks of the
same file but do not depend on each other in either order.

AI disclosure per CONTRIBUTING: written with Claude Code (Opus 5).

A failed `result` envelope still carries the turn's answer in `response` —
agy decodes that field from the complete buffer regardless of status. The
driver used it as the failure text, so a failed turn delivered the whole
answer a second time as an error event, right under the streamed copy.

Read the reason from `error` instead, which is what agy actually reports
there (e.g. "timeout waiting for response"), and keep the existing
`agy turn failed: <status>` fallback when the envelope carries none.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings

  • No reportable issues found.

Summary

  • Review mode: initial. Reviewed the full four-file diff; no correctness, security, regression, data-loss, performance, or maintainability issue met the 80% confidence threshold. A formal agy result-envelope schema was not found in repo/docs, so compatibility remains dependent on the observed CLI envelope shape.

Testing

  • Not run (automation; PR code was not executed). Static inspection only; GitHub test and integration checks were still in progress at review time.

HAPI Bot

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