feat(agy): replace deprecated gemini CLI runtime with Google Antigravity (agy)#278
Open
ProfSynapse wants to merge 9 commits into
Open
feat(agy): replace deprecated gemini CLI runtime with Google Antigravity (agy)#278ProfSynapse wants to merge 9 commits into
ProfSynapse wants to merge 9 commits into
Conversation
UI-only brand relabel of the google-gemini-cli provider from Gemini to Antigravity across 3 display surfaces. Provider id 'google-gemini-cli' unchanged byte-for-byte (settings compat). Runtime-coupled strings (command tokens, signupUrl, auth-flow) deferred to slice d. - ProviderUtils.ts: 'Google (Gemini CLI)' -> 'Google (Antigravity)' - ProvidersTab.ts: name/keyFormat/providerLabel -> 'Antigravity CLI' - ModelDropdownRenderer.ts: label-map + per-model suffix '(Antigravity CLI)' Part of #271 AGY CLI re-route. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01NxKeRz1gihguL9wcidm78m
…fail-closed model normalize, tolerant auth probe (slices a/b/c + R7)
Replaces the deprecated gemini CLI runtime with Antigravity CLI (agy) in
the google-gemini-cli provider. Check-independent slices only; slice d
(invocation flags / temp-settings-MCP / env-strip / skip-permissions)
remains gated on a user verification.
- (a) binary swap: resolveDesktopBinaryPath('gemini') -> 'agy' (geminiCli.ts:49)
- (b) delete the gemini --output-format json parse pipeline (JSON type + 7
extract helpers) -> thin parseAgyOutput seam (stdout.trim); remove the now-
unsupported --output-format json arg; usage degrades to zero (agy reports
none); empty stdout -> PROVIDER_ERROR; supportsJSON:false correctness fix
- (c) new geminiCliModelNormalize.ts: fail-CLOSED allowlist mapping legacy
specs -> agy human labels; reject unknown slugs with CONFIGURATION_ERROR
before spawn (agy --model fails OPEN, so Nexus must validate)
- (R7) GeminiCliAuthService: strict whole-file JSON.parse -> tolerant
access_token-presence scan (whole-parse / NDJSON / structural regex).
Security invariant: boolean-only, token value never read/logged/returned
Adapter test rewritten to the agy plain-text contract (6/6). Build green.
Part of #271 AGY CLI re-route.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01NxKeRz1gihguL9wcidm78m
…strip, drop vestigial MCP/temp-settings (Scenario A) Invocation now: agy --print --model <normalized-label> --print-timeout 60s [--sandbox] with the prompt on stdin. --print-timeout is a named const (Go-duration string) and the bounded security kill-switch for a hung headless tool-permission block (no skip-perms, no idle watchdog on this branch). --sandbox is additive defense-in-depth, platform-guarded to darwin (macOS Seatbelt, Docker-free); non-darwin falls back to the no-MCP + no-skip-perms floor. Deletes the vestigial buildGeminiCliSystemSettings MCP/temp-settings block, the temp-settings file write, and the GEMINI_CLI_SYSTEM_SETTINGS_PATH env pointing (agy ignores it and the completion path is pure prompt->text). No config write, no --dangerously-skip-permissions. env-strip extended with ANTHROPIC_API_KEY + OPENAI_API_KEY. Prunes now-dead connectorPath/serverKey from GeminiCliRuntime. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01NxKeRz1gihguL9wcidm78m
…models anchor + env-strip (Anthropic/OpenAI) + Scenario A no-config Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01NxKeRz1gihguL9wcidm78m
Peer-review blocking findings (B1-B4): user-facing copy slice-e's 3-file relabel didn't reach. All misdirected users to the deprecated/nonexistent gemini binary. - ProvidersTab: statusHint no longer says 'run gemini auth' (agy has no auth subcommand); description -> Antigravity/agy framing; signupUrl dropped to '' with TODO (authoritative Antigravity docs URL TBD; not fabricated) - ProviderManager:327-328: provider name 'Gemini CLI' -> 'Antigravity CLI' - GeminiCliAuthService:35/46/58: auth-error guidance -> canonical agy flow (run agy once -> browser sign-in); R7 presence-only probe invariant untouched - GoogleGeminiCliAdapter:213/220 + OAuthBannerComponent + types.ts: stale 'Gemini CLI' error/JSDoc copy aligned to agy - tests: +1 multiline parseAgyOutput fixture (trim preserves internal newlines) provider-id google-gemini-cli byte-preserved. connectorContent.ts excluded.
…agy models Replace the stale 2-entry '*-preview' catalog with the 5 Gemini variants agy actually serves (Gemini 3.5 Flash Low/Medium/High, Gemini 3.1 Pro Low/High), labels copied verbatim from live `agy models`. Drop 'Preview' names; default model gemini-3-flash-preview -> gemini-3.5-flash-medium. Normalize allowlist kept in lockstep (closes review Future-finding F2): all 5 new slugs map to exact agy labels; both legacy *-preview slugs retained as aliases for settings-compat; unknown slugs still fail-closed. Provider-id google-gemini-cli byte-preserved; R7 auth probe + invocation/sandbox/env-strip untouched. Catalog + normalize test pins updated to the 5-slug list. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01NxKeRz1gihguL9wcidm78m
agy (Antigravity CLI) supports no tool/function calling and no streaming via
its headless --print surface (proven NOT-FEASIBLE across native-execute,
MCP-only, and emit-don't-execute spikes; memory 95feb811). The model catalog
was lying about this with supportsFunctions:true.
- Flip supportsFunctions:true->false on all 5 agy ModelSpecs as the honest
capability SSOT (supportsStreaming already false)
- Generalize the proven Perplexity text-only seam into isTextOnlyProvider()
over a TEXT_ONLY_PROVIDERS set {perplexity, google-gemini-cli}; add
google-gemini-cli to PROVIDERS_WITHOUT_EXPLICIT_TOOL_SCHEMAS so tool schemas
are no longer silently sent to a provider that can't use them
- Settings notice: generalize renderPerplexityWarning ->
renderTextOnlyProviderWarning with Antigravity copy covering BOTH limits
(no tools/agents, no streaming); chat + agent variants
- Runtime guard: non-silent Notice in ChatSendCoordinator when a text-only
provider is active AND the user invoked tools/prompts for that send
- SubagentExecutor: isPerplexityProvider -> isTextOnlyProvider for the
text-only subagent prompt branch
- Add TextOnlyProviderSeam.test.ts (8 cases: SSOT, seam classification,
schema suppression, webllm exclusion)
Warning/UX only -- does NOT re-enable agy tool-use (closed; memory 95feb811).
Part of PR #278 (issue #271). Pending manual Obsidian verification.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01NxKeRz1gihguL9wcidm78m
Deeper coverage for the Antigravity text-completion-only warning (3e91675), beyond the existing TextOnlyProviderSeam.test.ts (8 cases). - ChatSettingsRendererTextOnlyWarning.test.ts (NEW, 10 cases): Antigravity warning copy renders and names BOTH limits (no tools/agents, no streaming) for chat + agent variants; Perplexity copy pinned unchanged; tool-capable providers render nothing. Invokes the real copy methods (coupled to source SSOT, not a re-typed fixture). - ChatSendCoordinator.test.ts (+5 cases): runtime guard through the real handleSendMessage — Notice fires exactly once (6000ms) for text-only+tools and text-only+prompts; silent on plain-text send, empty arrays, and a normal tool-capable provider with tools. Paired fire-vs-silence cases falsify an inert always-fire/never-fire guard. Full suite 3747 passed / 0 failed. Part of PR #278 (issue #271). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01NxKeRz1gihguL9wcidm78m
Hygiene follow-up to the text-only warning (architect verify #71). - GoogleGeminiCliAdapter.getCapabilities() now returns supportsFunctions:false, matching the ModelSpecs SSOT (was still true). Provably non-functional — nothing tool-gates on provider-level getCapabilities; dispatch gating is 100% via the provider seam — pure honesty/consistency. - isPerplexityProvider: JSDoc note marking it a deliberate narrow predicate (do-not-broaden / do-not-delete) now that isTextOnlyProvider is the general seam. Fn + test untouched. Full suite 3747 passed. Part of PR #278 (issue #271). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01NxKeRz1gihguL9wcidm78m
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.
Summary
Replaces the deprecated
geminiCLI runtime with Google Antigravity (agy, v1.0.10) in thegoogle-gemini-cliprovider. Provider idgoogle-gemini-cliis preserved for settings compatibility; only the runtime binary, output parsing, model normalization, invocation, and user-facing labels change.Related to #271 (does not close it — see Verification below).
Approach — Scenario A (zero-footprint, security-first)
gemini→agy(slice a)agy --printemits plain text, not JSON. Deleted the--output-format jsonparse pipeline (~120 LoC) →parseAgyOutput=stdout.trim(); empty stdout →PROVIDER_ERROR;supportsJSON:false. No token-usage available (degrades gracefully).agy --modelfails open on an unknown slug (silently substitutes a default), so Nexus validates against a live-anchored allowlist and rejects unknown slugs withCONFIGURATION_ERRORbefore spawn.gemini-3-flash-preview→Gemini 3.5 Flash (Medium),gemini-3.1-flash-lite-preview→Gemini 3.5 Flash (Low).agy --print --model <label> --print-timeout 60s [--sandbox].--dangerously-skip-permissions— live-verified that without it, a built-in tool call hangs on an un-answerable headless permission prompt and is killed (fail-safe; tool never executes).--print-timeout 60s(Go-duration string) is the bounded security kill-switch for that hang (this branch has no idle watchdog yet).buildGeminiCliSystemSettingsMCP/temp-settings block (agy ignoresGEMINI_CLI_SYSTEM_SETTINGS_PATHand the prompt→text path never needed it). No~/.geminiwrites.--sandboxplatform-guarded to macOS (verified Seatbelt, Docker-free); off-darwin falls back to the no-MCP + no-skip-perms floor.ANTHROPIC_API_KEY+OPENAI_API_KEY(agy fronts Claude/GPT too).oauth_creds.json— boolean only, token value never read/logged/returned.Testing
TaskBoardEditCoordinator.test.ts, obsidian-mockModalexport gap) is pre-existing and unrelated — proven via stash-and-retest, zero agy references.agy modelsanchor test (pins the two label mappings so catalog drift fails at unit-test time), env-strip (Google + Anthropic + OpenAI), and a Scenario-A "no temp-settings file written" assertion.Verification — NOT yet manually tested
agysmoke only. Before merge, a manual round-trip in Obsidian is needed (provider selection, a real completion viaagy, auth flow). Issue #271 stays open until that manual verification passes.Manual-test residuals
--sandbox: verified darwin-only; Linux/Windows need a per-platform live-verify before--sandboxis ever enabled off-darwin (guarded off there today).agyhas noauthsubcommand — first run is bareagy→ browser Google sign-in (writes~/.gemini/oauth_creds.json).Notes
src/utils/connectorContent.tsis intentionally not committed (generated artifact; regenerated locally/CI).🤖 Generated with Claude Code