Finally solved: two hours of testing to get the headless Antigravity CLI right
I wanted to wire Google’s Antigravity CLI (agy) into an auto-execution pipeline, running headless. The plan was simple: one specific model per run via --model, everything non-interactive via -p/--print, collect the output, process it downstream. The first call looked harmless:
agy -p --model "gemini-3.1-pro" "Reply with ONLY your exact model name."
The reply: Gemini 3.5 Flash. The default — not the model I had requested. No matter what string I put in --model, agy fell back to the standard model every time. No error, no warning, nothing. Two hours later I knew why, and the reason is in no documentation. Here it is, step by step.
Step 1: The model names are not slugs
My first suspicion: wrong model name. agy models cleared that up — and surprised me. The CLI lists models as display names with the reasoning level in parentheses, not as technical slugs:
agy models
# Gemini 3.5 Flash (Medium)
# Gemini 3.5 Flash (High)
# Gemini 3.5 Flash (Low)
# Gemini 3.1 Pro (Low)
# Gemini 3.1 Pro (High)
# Claude Sonnet 4.6 (Thinking)
# Claude Opus 4.6 (Thinking)
# GPT-OSS 120B (Medium)
Important: there is no separate --effort or --reasoning flag. The reasoning level is part of the model string. My slug variants — gemini-3.1-pro, :high, -high — all triggered the fallback. Only the exact display name with parentheses was accepted in interactive mode, visible in the status bar at the bottom right. Even that is documented nowhere cleanly.
Step 2: Don’t ask the model who it is
Armed with the correct name, the next headless test:
agy -p --model "Gemini 3.1 Pro (High)" "Reply with ONLY your exact model name."
Reply: I’m running on the GPT-OSS 120B (Medium) model. That was instructive on two levels. First: --model was ignored again — a different default this time, but in any case not my requested model. Second, and this is the real trap: a model’s self-report is worthless as proof of identity. Models often don’t know their exact name reliably and guess from the system prompt or training data. If you work headless, you can’t rely on it.
Self-report is no proof of identity
The only reliable signals are the status bar in interactive mode or a log check on the actual API call: set --log-file and grep for streamGenerate or the model name. Whatever the model says about itself is noise.
Step 3: It’s the order of the flags
The breakthrough came from blunt trial and error: I swapped the flags on the same model. And suddenly the result was correct. That’s the moment the order clicks — and turns everything before it into a footnote.
# WRONG — silently falls back to the default:
agy -p --model "Gemini 3.1 Pro (High)" "Reply with ONLY your exact model name."
# RIGHT — uses the requested model:
agy --model "Gemini 3.1 Pro (High)" -p "Reply with ONLY your exact model name."
--model must come before -p. If -p comes first, the print mode swallows the following model argument and silently falls back to the default — exit code 0, no message. I cross-checked this across all eight models on the list: as soon as --model precedes -p, the correct result comes back every time.
The working pattern
The constellation I now run in the pipeline is exactly one line:
agy --model "<display name (level)>" -p "<prompt>"
Concretely, for three of the models:
agy --model "Gemini 3.1 Pro (High)" -p "..."
agy --model "Claude Opus 4.6 (Thinking)" -p "..."
agy --model "GPT-OSS 120B (Medium)" -p "..."
Three pitfalls that would have caught me otherwise
With the flag order sorted, the main problem is solved, but for unattended runs there are three more points I planned for right away.
- Non-TTY stdout drop. In pipes, subprocesses or CI,
agy -pcan silently swallow the reply — exit code 0, but empty stdout (documented as GitHub Issue #76). If you captureagyas a subprocess, you need a pseudo-TTY:script -qfc 'agy --model "..." -p "..."' /dev/null. - Name stability. The display strings can change between
agyversions. Instead of hardcoding names, I parseagy modelsonce before each run and pull the matching string dynamically. - API key paths.
GEMINI_API_KEYis ignored on some code paths. For CI I setANTIGRAVITY_TOKENorANTIGRAVITY_API_KEY.
Conclusion
The central, undocumented rule: --model before -p. Plus three guardrails — display name with parentheses instead of a slug, logs instead of self-report, a pseudo-TTY against the stdout drop. With that, agy runs reliably headless for me. The point of all the fiddling: agy is just one engine in a multi-model pipeline that runs several AI coding tools headless and pits their output against each other. I deliberately left the OpenAI models out; I’ll test those separately and add the results later.
Entdecke mehr
Saving Tokens with Claude: 6 Principles That Make Experts Twice as Fast
How I turned my CLAUDE.md from a style guide into a token budget — 6 principles for lower cost, less waiting, and more honest reporting.
GlossarAider
Aider is an open-source AI pair programmer for the command line that edits code directly in the Git repository and commits every change automatically.
LexikonAI Coding Tools Compared
Cursor, Windsurf, Claude Code, GitHub Copilot, Continue.dev, Aider compared. With table and decision guide for four typical developer workflows.