Repository navigation
fix(cli): stale squad roster + Antigravity auth failures get the re-auth bubble - #1023
Merged
Merged
Conversation
The squad roster is fetched once at session start (and after a switch or route), so an agent the user links AFTER the session started is missing from the cached copy. Live on the dev CodeAgent Box (2026-11-06): the user linked Antigravity mid-session, sent a start_task routed to `antigravity`, and the CLI logged "start_task routing to antigravity failed: Unknown agent 'antigravity' — not in your squad." — the turn was then answered by Claude. routeSquadTask now re-fetches the roster ONCE, on demand, when the target is absent from the cached roster, and only refuses if it is still absent. No timers or polling. SquadState owns the fetch (refreshRoster), so the runner's existing refresh points reuse the same path. Bead: codeagent-p1ch Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d reply agy (`agy acp`) does not report a provider/auth failure as a JSON-RPC error. It streams "⚠ Agent execution terminated due to error." plus the provider's message as a normal agent_message_chunk and then ends the turn with a clean end_turn. None of the throw/exit failure paths (failureBubble, reportCredentialInvalid) see that, so with an invalid API key (observed when agy was added: the turn fails with text including "API key not valid") the raw agy text was rendered as the agent's reply, the user got no re-auth bubble, and Profile › Agents kept showing the credential as CONNECTED. An antigravity classifyCompletedReply hook now classifies such a reply: - banner + a Google credential failure (API key not valid / API_KEY_INVALID / expired key, UNAUTHENTICATED / invalid authentication credentials, invalid_grant / token expired or revoked) -> the standard re-auth bubble + reportCredentialInvalid, the same path as Claude's "Not logged in" reply; - banner without an auth cause -> the honest generic TURN_FAILURE_MESSAGE, credential untouched. It requires agy's own banner and a reply of at most 1000 characters, so a substantive reply that merely discusses an API-key error is never misclassified. The Agent Pack path (completedReplyFailureBubble) honours the same classification. Bead: codeagent-6bg9 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first classifier (da221b5) looked for the credential cause in the reply text. A live capture on a CodeAgent Box (agy 1.5.2, `agy acp`, GEMINI_API_KEY = an invalid key, 2026-11-06) shows agy never streams it: the ONLY text is the agent_message_chunk "⚠ Agent execution terminated due to error.", session/prompt resolves {"stopReason":"end_turn"}, and stderr is empty. The cause is only in agy's log, ~/.gemini/antigravity-cli/log/acp-server-<ts>-<pid>.log: E1106 18:16:15.662983 233 errorreport.go:247] agent executor error: generating and executing: Error 400, Message: API key not valid. ... Status: INVALID_ARGUMENT, Details: [... reason:API_KEY_INVALID ...] So an invalid key still got the generic frame and the credential was never flagged. On a banner reply the classifier now (after the cheap reply-text check) reads the last 16 KB of the newest acp-server log under the agy process's HOME (the current agent env), keeps only E/F entries stamped since the turn started, and returns auth_failed when one names a credential failure (API_KEY_INVALID / API key not valid / expired key, UNAUTHENTICATED / 401, invalid_grant / token expired or revoked, PERMISSION_DENIED with a key/token reason). Otherwise, or with no log, the generic honest frame. The matched entry is logged with Google API keys and OAuth tokens redacted. An expired-and-unrefreshable OAuth token or a missing credential fails earlier, at session/new (-32000 "Authentication required"), on the existing startup path; this covers a credential that goes bad mid-session. Bead: codeagent-6bg9 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Two bugs found in the live Antigravity e2e (dev CodeAgent Box, 2026-11-06):
Unknown agent 'antigravity' — not in your squad.and the turn was answered by the current agent (Claude).routeSquadTasknow re-fetches the roster once on a miss (on demand, no timers) and only refuses if it is still absent.⚠ Agent execution terminated due to error.and ends withend_turn; nothing on stderr. The cause is only in agy's own log (~/.gemini/antigravity-cli/log/acp-server-*.log:Error 400 … API key not valid … reason:API_KEY_INVALID). The completed-reply classifier for antigravity now reads the tail of that log (entries since the turn started) → re-auth bubble +reportCredentialInvalidfor credential errors, the generic honest failure frame otherwise. Tokens are redacted in any logged line.Tests: new
start-task-routingcases +antigravity-reply-failure(behaviour) +antigravity/reply-failure(unit), each failing before the fix.🤖 Generated with Claude Code
Open in [code]smith · Need help on this PR? Tag
@codesmith-botwith what you need.