fix(acp): tolerate CodeBuddy dialect and stop misreporting empty turns as needs-auth - #692
Merged
Merged
Conversation
…s as needs-auth Empty team-collaboration turns from the CodeBuddy ACP backend were surfaced as "the agent may need you to sign in (Login with iOA)" even when the channel was online and authenticated. CodeBuddy unconditionally advertises authMethods, so every empty end_turn fell through to the auth-hint fallback regardless of the real cause (Sentry 136586749 / ELECTRON-3R1). - Add a local tolerant pre-parse layer (protocol/acp_dialect.rs) that classifies each raw incoming JSON-RPC line and absorbs CodeBuddy's non-standard session_end and compact-maxtoken / emergency-auto notifications before the vendored agent-client-protocol schema hard-rejects them as -32602. Every other line, including genuinely malformed input and other unknown variants, is forwarded unchanged so the SDK still surfaces real errors. Wire criteria are grounded in this issue's captured logs.txt payloads. - Switch the SDK transport from ByteStreams to the first-party Lines interception point (equivalent newline framing) and raise an internal-only AcpDialectSignal when a dialect line is absorbed. The signal never counts as visible output and is never forwarded to the WebSocket; the relay and message_service discard it like SegmentBreak. Enable the tokio-util "codec" feature for the line codec. - Converge the empty-turn judgment: a dialect signal observed within the turn / near-window now yields the new ACP_EMPTY_TURN_TOKEN_LIMIT tip (possibility wording) ahead of the auth hint, demoting authMethods-only empty turns to the last-resort ACP_EMPTY_TURN_NEEDS_AUTH fallback. The existing stderr terminal-error path is unchanged, and the kilo-style authMethods fallback is kept (not deleted). The new tip does not set needs_auth, so it never reflects the agent as unavailable. Adds unit tests for line classification, the judgment priority (token signal beats auth hint; the reported clean empty turn still falls back to needs-auth), the turn-observation drain, and relay forwarding / needs-auth guardrails.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fix for Sentry
136586749/ ELECTRON-3R1.Empty team-collaboration turns from the CodeBuddy ACP backend were surfaced as "the agent may need you to sign in (Login with iOA)" even when the channel was online and authenticated. CodeBuddy unconditionally advertises
authMethods, so every emptyend_turnfell through to the auth-hint fallback regardless of the real cause. Separately, CodeBuddy's non-standardsession_end/compact-maxtokennotifications were hard-rejected as-32602and silently dropped, discarding a signal that could have attributed the empty turn correctly.Changes
protocol/acp_dialect.rs, pure function): classifies each raw incoming JSON-RPC line and absorbs CodeBuddy's non-standardsession_endandcompact-maxtoken/emergency-autonotifications before the vendoredagent-client-protocolschema hard-rejects them as-32602. Every other line — including genuinely malformed input and other unknown variants — is forwarded unchanged so the SDK still surfaces real errors. Wire criteria are grounded in this issue's capturedlogs.txtpayloads. No vendored-crate edits.Linesinterception: the SDK transport moves fromByteStreamsto a first-partyLinesinterception point (equivalent newline framing) and raises an internal-onlyAcpDialectSignalwhen a dialect line is absorbed. The signal never counts as visible output and is never forwarded to the WebSocket; the relay andmessage_servicediscard it likeSegmentBreak. Enables thetokio-utilcodecfeature.ACP_EMPTY_TURN_TOKEN_LIMITtip (possibility wording) ahead of the auth hint, demotingauthMethods-only empty turns to the last-resortACP_EMPTY_TURN_NEEDS_AUTHfallback. The existing stderr terminal-error path is unchanged and the kilo-styleauthMethodsfallback is kept (not deleted). The new tip does not setneeds_auth, so it never reflects the agent as unavailable.Tests
Adds unit / contract tests for line classification, the judgment priority (token signal beats auth hint; the reported clean empty turn still falls back to needs-auth), the turn-observation drain, and relay forwarding /
needs_authguardrails.cargo fmt --all -- --check— exit 0cargo clippy -p aionui-ai-agent -p aionui-conversation -- -D warnings— exit 0cargo test -p aionui-ai-agent -p aionui-conversation— exit 0 (779aionui-ai-agentlib tests +aionui-conversationrelay guardrails, 0 failed)Reviewer notes
ByteStreams → Linestransport switch touches the incoming framing path shared by all ACP backends, not just CodeBuddy. Please confirm equivalent framing and no regression for other ACP CLIs (claude / codex / gemini).session_end/compact-maxtokenlines are absorbed; everything else (including truly malformed messages) is forwarded and still surfaces-32602as before.-32602warn; a localinfo-level structured log records the absorption (kind / session_id / marker only, no sensitive payload).end_turnis cross-boundary and intentionally not asserted.Related
136586749/ ELECTRON-3R1 (reported on AionUi 2.1.41, production, moduleagent-team)ACP_EMPTY_TURN_NEEDS_AUTHand the newACP_EMPTY_TURN_TOKEN_LIMITtips.Pending manual verification
EndTurnno longer shows the hard "Login with iOA" assertion.session_end/compact-maxtokenno longer-32602), andACP_EMPTY_TURN_TOKEN_LIMITproduced when a real token-pressure signal is present.