feat(providers): run Google Antigravity (agy) as a coding agent provider - #8113
feat(providers): run Google Antigravity (agy) as a coding agent provider#8113Marve10s wants to merge 1 commit into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| detail: "Antigravity turns require text or an attachment.", | ||
| }); | ||
| } | ||
| if ((yield* isHostWindows) && turnInput.message.text.length > 24_000) { |
There was a problem hiding this comment.
🟠 High Adapters/AntigravityAdapterV2.ts:666
The Windows guard lets turns with long attachment paths, --add-dir paths, or configured launchArgs reach spawn even when the complete argv exceeds the command-line limit, so a short message can still fail at process startup. The check only measures turnInput.message.text; validate the fully assembled arguments, including the -p value and all additional arguments, before spawning.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/orchestration-v2/Adapters/AntigravityAdapterV2.ts around line 666:
The Windows guard lets turns with long attachment paths, `--add-dir` paths, or configured `launchArgs` reach `spawn` even when the complete argv exceeds the command-line limit, so a short message can still fail at process startup. The check only measures `turnInput.message.text`; validate the fully assembled arguments, including the `-p` value and all additional arguments, before spawning.
| context.tools.set(step.step_index, { | ||
| name: step.tool_name ?? step.tool_info?.name ?? existing?.name ?? "tool", | ||
| input: step.tool_info?.parameters ?? existing?.input ?? {}, | ||
| ...(step.tool_info?.output ? { output: step.tool_info.output } : {}), |
There was a problem hiding this comment.
🟡 Medium Adapters/AntigravityAdapterV2.ts:479
A DONE tool update without a truthy step.tool_info.output drops output captured by an earlier update, so the completed turn_item is emitted without its result. Preserve existing.output when the current update omits or sends an empty output.
- ...(step.tool_info?.output ? { output: step.tool_info.output } : {}),
+ ...(step.tool_info?.output
+ ? { output: step.tool_info.output }
+ : existing?.output !== undefined
+ ? { output: existing.output }
+ : {}),🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/orchestration-v2/Adapters/AntigravityAdapterV2.ts around line 479:
A `DONE` tool update without a truthy `step.tool_info.output` drops output captured by an earlier update, so the completed `turn_item` is emitted without its result. Preserve `existing.output` when the current update omits or sends an empty output.
| } | ||
|
|
||
| function itemOrdinal(context: ActiveTurn, stepIndex: number) { | ||
| return context.input.providerTurnOrdinal * 100 + stepIndex + 1; |
There was a problem hiding this comment.
🟡 Medium Adapters/AntigravityAdapterV2.ts:248
itemOrdinal emits duplicate OrchestrationV2TurnItem.ordinal values: step_index === 98 produces providerTurnOrdinal * 100 + 99, which is also the failed-turn item ordinal, and indices at least 100 overlap ordinals from the next provider turn. Long or tool-heavy agy turns therefore corrupt turn-item ordering and can collide in the work log. Allocate item ordinals independently of the external step_index, or validate/remap indices before deriving the ordinal.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/orchestration-v2/Adapters/AntigravityAdapterV2.ts around line 248:
`itemOrdinal` emits duplicate `OrchestrationV2TurnItem.ordinal` values: `step_index === 98` produces `providerTurnOrdinal * 100 + 99`, which is also the failed-turn item ordinal, and indices at least `100` overlap ordinals from the next provider turn. Long or tool-heavy `agy` turns therefore corrupt turn-item ordering and can collide in the work log. Allocate item ordinals independently of the external `step_index`, or validate/remap indices before deriving the ordinal.
There was a problem hiding this comment.
Effect service conventions review of the new Antigravity provider modules. The service/layer structure, namespace imports, and environment-based dependency acquisition all look consistent with the existing driver/adapter modules. Three error-modelling and change-discipline findings below.
Posted via Macroscope — Effect Service Conventions
| const parsed = metadata(contents); | ||
| if (!parsed.valid) continue; |
There was a problem hiding this comment.
The comment explaining why malformed frontmatter is skipped was dropped when this logic moved out of ClaudeSkills.ts. Worth restoring it so the invariant survives the extraction.
| const parsed = metadata(contents); | |
| if (!parsed.valid) continue; | |
| const parsed = metadata(contents); | |
| // Malformed frontmatter means the skill won't load in the provider CLI | |
| // either — skip it rather than surfacing a broken entry under its | |
| // directory name. | |
| if (!parsed.valid) continue; |
Posted via Macroscope — Effect Service Conventions
| new ProviderDriverError({ | ||
| driver: DRIVER_KIND, | ||
| instanceId, | ||
| detail: `Failed to build Antigravity snapshot: ${cause.message ?? String(cause)}`, |
There was a problem hiding this comment.
detail here only restates cause.message (and is then used to build ProviderDriverError.message), while the real failure is already preserved as cause. Deriving the wrapper text from its own structural attributes keeps the message stable and avoids duplicating/stringifying the underlying error.
| detail: `Failed to build Antigravity snapshot: ${cause.message ?? String(cause)}`, | |
| detail: "Failed to build the Antigravity provider snapshot.", |
Posted via Macroscope — Effect Service Conventions
| if (Number(exitCode) !== 0) { | ||
| return yield* new TextGenerationError({ | ||
| operation: input.operation, | ||
| detail: stderr.trim() || stdout.trim() || `Antigravity exited with code ${exitCode}.`, |
There was a problem hiding this comment.
Raw CLI output is copied into detail, and TextGenerationError.message renders detail back to callers, so unbounded agy stdout/stderr (including anything sensitive it prints) becomes part of the caller-visible error. The sibling implementations (GrokTextGeneration, CursorTextGeneration) keep detail a stable structural string and let the underlying value travel only as cause. Consider a bounded detail with normalized diagnostics instead.
| detail: stderr.trim() || stdout.trim() || `Antigravity exited with code ${exitCode}.`, | |
| detail: `Antigravity CLI exited with code ${exitCode} (stdout ${stdout.length} chars, stderr ${stderr.length} chars).`, |
Posted via Macroscope — Effect Service Conventions
|
Closing this. With #8050 and #8008 already open there are three Antigravity PRs on the table, and there is no sign the maintainers want an |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 961c5c3. Configure here.
| input: step.tool_info?.parameters ?? existing?.input ?? {}, | ||
| ...(step.tool_info?.output ? { output: step.tool_info.output } : {}), | ||
| startedAt: existing?.startedAt ?? (yield* DateTime.now), | ||
| }); |
There was a problem hiding this comment.
Tool output dropped on updates
Medium Severity
Tool step merges keep prior name and input, but output is only set when the new event includes a truthy tool_info.output. A later status-only or empty-output update for the same step_index rebuilds the tool entry without the earlier output, so the completed work-log item can finish with no output even though the CLI already sent it.
Reviewed by Cursor Bugbot for commit 961c5c3. Configure here.
| context.conversationId = | ||
| normalizeAntigravityConversationId(event.result.conversation_id) ?? | ||
| context.conversationId; | ||
| return; |
There was a problem hiding this comment.
Final response text ignored
Medium Severity
The result event records status and conversation id but never applies result.response as assistant text. Assistant messages are only built from agent_response events that include a truthy text_delta, so a turn whose final answer arrives only on result (or whose deltas were incomplete) can complete with no assistant message even when the CLI returned one.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 961c5c3. Configure here.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR introduces a complete Antigravity coding-agent provider with a large orchestration adapter, CLI process execution, persistent conversations, streaming event mapping, and new user-facing settings and workflows. Its scope is substantial, and unresolved findings affect command launching and streamed turn projection, so the runtime behavior should receive human review. Not approved because:
Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 961c5c386b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "-p", | ||
| input.prompt, |
There was a problem hiding this comment.
Avoid passing generated prompts as one argv value
When Antigravity is selected for commit-message or PR generation, input.prompt includes the staged or PR diff and is passed as one command-line argument. On Linux, a single argument commonly hits E2BIG around 128 KiB, so moderately large changes fail during process spawning before agy runs; the regular turn path has the same unbounded argv construction. Pass the prompt through stdin if supported, or enforce a platform-appropriate bound before spawning.
Useful? React with 👍 / 👎.
| const at = yield* DateTime.now; | ||
| for (const stepIndex of context.assistant.keys()) | ||
| yield* emitAssistant(context, stepIndex, true); | ||
| for (const stepIndex of context.tools.keys()) yield* emitTool(context, stepIndex, true); |
There was a problem hiding this comment.
Preserve unsuccessful tool states when finalizing
If a tool has emitted an ACTIVE update and the process is then interrupted, cancelled, or fails before its DONE event, this loop unconditionally re-emits that tool as completed. The web work log maps that status directly to a successful completion, so a killed or partially executed command is presented as having succeeded. Track whether each tool actually reached DONE and finalize remaining tools as interrupted, cancelled, or failed according to the terminal status.
AGENTS.md reference: AGENTS.md:L141-L141
Useful? React with 👍 / 👎.
| const home = path.join(NodeOS.homedir(), ".gemini"); | ||
| const roots: ReadonlyArray<SkillRoot> = [ | ||
| { directory: path.join(home, "config", "skills"), scope: "user" }, | ||
| { directory: path.join(home, "antigravity-cli", "skills"), scope: "user" }, |
There was a problem hiding this comment.
Discover skills from the provider instance's home
When an Antigravity instance overrides HOME through its provider environment—for example to isolate separate accounts—the spawned agy process receives that override, but skill discovery still scans the server process user's ~/.gemini. Because this driver explicitly supports multiple instances, the affected instance exposes another instance's skills and misses its own; derive the skill roots from the same merged environment used to spawn the CLI.
Useful? React with 👍 / 👎.


T3 Code cannot drive Google's Antigravity CLI (
agy). Anyone with an Antigravity subscription has to leave T3 Code to use it.This adds Antigravity as a built-in provider on the v2 orchestration runtime. The adapter runs
agyin print mode withstream-jsonoutput and maps its events onto v2 turn items: assistant text streams as it arrives, tool starts, outputs, and completions show up in the work log, and token usage lands on the turn. Follow-up messages reuse theagyconversation id, so a thread stays inside one Antigravity project. The provider also acts as a text-generation backend for thread titles, discovers Antigravity skills from the project and user skill directories, and shows up in provider settings, status probing, and the web and mobile icon sets.Print mode cannot pause for interactive approvals, so the adapter accepts only the full-access runtime mode and fails every other mode with an explicit error rather than silently ignoring the choice. Plan mode maps to
agy --mode plan.Based on #2829 (the v2 orchestrator). The diff is against that branch.
Two other Antigravity PRs are open, #8050 and #8008. Both target
mainand plug into the v1 provider stack (provider/Layers/*Adapter.tsandprovider/Services/*Adapter.ts), which #2829 removes when the v2 orchestrator lands, so either of them would need a rewrite right after merging. This PR builds the provider as a v2 adapter (orchestration-v2/Adapters/AntigravityAdapterV2.ts) from the start. The parts that look similar across the three PRs are the shared shapes: provider status probing, settings schema, icons, and title generation. The part that differs is the adapter itself and howagyturns map onto v2 runs, turn items, and runtime requests.We tested it end to end and it works for us: threads start, stream, continue, and title themselves through the CLI. Expect follow-up commits while the automated reviewers run; the branch may be broken for short stretches between them.
Preview recording: https://github.com/Marve10s/t3code/releases/download/pr-assets-antigravity/antigravity-preview.mov
Confidence: 85%. The happy path is verified against a real
agyinstall and a copy of production data. The remaining risk is in corners of the CLI's stream-json protocol that the fixture-based tests do not cover.Built by Claude Fable 5 in the Claude Code harness.