Skip to content

Commit 1433c52

Browse files
Mikeclaude
authored andcommitted
feat: add agy (Antigravity CLI) as a supported --cli provider
Adds agy alongside claude, gemini, codex, agent, openclaw, opencode, and copilot. Uses a plain-text path (--print + stdin) since agy does not support --output-format json. Default model is null — agy uses its own session default (Gemini 3.5 Flash) when no model is specified. Binary resolved via AGY_PATH env var or agy on PATH. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 6d43d34 commit 1433c52

23 files changed

Lines changed: 246 additions & 23 deletions

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ Use `summarize --help` or `summarize help` for the full help text.
331331
- `--length short|medium|long|xl|xxl|s|m|l|<chars>`
332332
- `--language, --lang <language>`: output language (`auto` = match source)
333333
- `--max-output-tokens <count>`: hard cap for LLM output tokens
334-
- `--cli [provider]`: use a CLI provider (`--model cli/<provider>`). Supports `claude`, `gemini`, `codex`, `agent`, `openclaw`, `opencode`. If omitted, uses auto selection with CLI enabled.
334+
- `--cli [provider]`: use a CLI provider (`--model cli/<provider>`). Supports `claude`, `gemini`, `codex`, `agent`, `openclaw`, `opencode`, `agy`. If omitted, uses auto selection with CLI enabled.
335335
- `--stream auto|on|off`: stream LLM output (`auto` = TTY only; disabled in `--json` mode)
336336
- `--plain`: keep raw output (no ANSI/OSC Markdown rendering)
337337
- `--no-color`: disable ANSI colors
@@ -353,7 +353,7 @@ Use `summarize --help` or `summarize help` for the full help text.
353353
- `--verbose`: debug/diagnostics on stderr
354354
- `--metrics off|on|detailed`: metrics output (default `on`)
355355

356-
### Coding CLIs (Codex, Claude, Gemini, Agent, OpenClaw, OpenCode)
356+
### Coding CLIs (Codex, Claude, Gemini, Agent, OpenClaw, OpenCode, Antigravity)
357357

358358
Summarize can use common coding CLIs as local model backends:
359359

@@ -363,15 +363,16 @@ Summarize can use common coding CLIs as local model backends:
363363
- `agent` (Cursor Agent CLI) -> `--cli agent` / `--model cli/agent/<model>`
364364
- `openclaw` -> `--cli openclaw` / `--model cli/openclaw/<model>` or `--model openclaw/<model>`
365365
- `opencode` -> `--cli opencode` / `--model cli/opencode/<model>` (`--model cli/opencode` uses the OpenCode runtime default)
366+
- `agy` (Antigravity CLI) -> `--cli agy` / `--model cli/agy/<model>` (uses agy's active session model when no model is specified)
366367

367368
Built-in preset:
368369

369370
- `--model codex-fast` runs Codex with GPT-5.5 Fast mode and requires `codex login`.
370371

371372
Requirements:
372373

373-
- Binary installed and on `PATH` (or set `CODEX_PATH`, `CLAUDE_PATH`, `GEMINI_PATH`, `AGENT_PATH`, `OPENCLAW_PATH`, `OPENCODE_PATH`)
374-
- Provider authenticated (`codex login`, `claude auth`, `gemini` login flow, `agent login` or `CURSOR_API_KEY`, `opencode auth login`)
374+
- Binary installed and on `PATH` (or set `CODEX_PATH`, `CLAUDE_PATH`, `GEMINI_PATH`, `AGENT_PATH`, `OPENCLAW_PATH`, `OPENCODE_PATH`, `AGY_PATH`)
375+
- Provider authenticated (`codex login`, `claude auth`, `gemini` login flow, `agent login` or `CURSOR_API_KEY`, `opencode auth login`, `agy` login flow or `ANTIGRAVITY_API_KEY`)
375376

376377
Quick smoke test:
377378

@@ -384,13 +385,14 @@ summarize --cli gemini --plain --timeout 2m /tmp/summarize-cli-smoke.txt
384385
summarize --cli agent --plain --timeout 2m /tmp/summarize-cli-smoke.txt
385386
summarize --cli openclaw --plain --timeout 2m /tmp/summarize-cli-smoke.txt
386387
summarize --cli opencode --plain --timeout 2m /tmp/summarize-cli-smoke.txt
388+
summarize --cli agy --plain --timeout 2m /tmp/summarize-cli-smoke.txt
387389
```
388390

389391
Set explicit CLI allowlist/order:
390392

391393
```json
392394
{
393-
"cli": { "enabled": ["codex", "claude", "gemini", "agent", "openclaw", "opencode"] }
395+
"cli": { "enabled": ["codex", "claude", "gemini", "agent", "openclaw", "opencode", "agy"] }
394396
}
395397
```
396398

@@ -402,7 +404,7 @@ Configure implicit auto CLI fallback:
402404
"autoFallback": {
403405
"enabled": true,
404406
"onlyWhenNoApiKeys": true,
405-
"order": ["claude", "gemini", "codex", "agent", "openclaw", "opencode"]
407+
"order": ["claude", "gemini", "codex", "agent", "openclaw", "opencode", "agy"]
406408
}
407409
}
408410
}

apps/chrome-extension/src/lib/settings.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ function normalizeAutoCliOrder(value: unknown): string {
151151
item !== "agent" &&
152152
item !== "openclaw" &&
153153
item !== "opencode" &&
154-
item !== "copilot"
154+
item !== "copilot" &&
155+
item !== "agy"
155156
) {
156157
continue;
157158
}
@@ -311,7 +312,7 @@ export const defaultSettings: Settings = {
311312
summaryTimestamps: true,
312313
extendedLogging: false,
313314
autoCliFallback: true,
314-
autoCliOrder: "claude,gemini,codex,agent,openclaw,opencode,copilot",
315+
autoCliOrder: "claude,gemini,codex,agent,openclaw,opencode,copilot,agy",
315316
hoverPrompt:
316317
"Plain text only (no Markdown). Summarize the linked page concisely in 1-2 sentences; aim for 100-200 characters.",
317318
transcriber: "",

src/config/parse-helpers.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ export function parseCliProvider(value: unknown, path: string): CliProvider {
1717
trimmed === "agent" ||
1818
trimmed === "openclaw" ||
1919
trimmed === "opencode" ||
20-
trimmed === "copilot"
20+
trimmed === "copilot" ||
21+
trimmed === "agy"
2122
) {
2223
return trimmed as CliProvider;
2324
}

src/config/sections.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ export function parseCliConfig(root: Record<string, unknown>, path: string): Cli
325325
const copilot = value.copilot
326326
? parseCliProviderConfig(value.copilot, path, "copilot")
327327
: undefined;
328+
const agy = value.agy ? parseCliProviderConfig(value.agy, path, "agy") : undefined;
328329
if (typeof value.autoFallback !== "undefined" && typeof value.magicAuto !== "undefined") {
329330
throw new Error(
330331
`Invalid config file ${path}: use only one of "cli.autoFallback" or legacy "cli.magicAuto".`,
@@ -359,6 +360,7 @@ export function parseCliConfig(root: Record<string, unknown>, path: string): Cli
359360
openclaw ||
360361
opencode ||
361362
copilot ||
363+
agy ||
362364
autoFallback ||
363365
promptOverride ||
364366
typeof allowTools === "boolean" ||
@@ -373,6 +375,7 @@ export function parseCliConfig(root: Record<string, unknown>, path: string): Cli
373375
...(openclaw ? { openclaw } : {}),
374376
...(opencode ? { opencode } : {}),
375377
...(copilot ? { copilot } : {}),
378+
...(agy ? { agy } : {}),
376379
...(autoFallback ? { autoFallback } : {}),
377380
...(promptOverride ? { promptOverride } : {}),
378381
...(typeof allowTools === "boolean" ? { allowTools } : {}),

src/config/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ export type CliProvider =
77
| "agent"
88
| "openclaw"
99
| "opencode"
10-
| "copilot";
10+
| "copilot"
11+
| "agy";
1112
export type OpenAiReasoningEffort = "none" | "low" | "medium" | "high" | "xhigh";
1213
export type OpenAiTextVerbosity = "low" | "medium" | "high";
1314
export type ModelRequestOptions = {
@@ -36,6 +37,7 @@ export type CliConfig = {
3637
openclaw?: CliProviderConfig;
3738
opencode?: CliProviderConfig;
3839
copilot?: CliProviderConfig;
40+
agy?: CliProviderConfig;
3941
autoFallback?: CliAutoFallbackConfig;
4042
magicAuto?: CliAutoFallbackConfig;
4143
promptOverride?: string;

src/daemon/env-snapshot.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const ENV_KEYS = [
4141
"OPENCLAW_PATH",
4242
"OPENCODE_PATH",
4343
"COPILOT_PATH",
44+
"AGY_PATH",
4445
"UVX_PATH",
4546
] as const;
4647

src/daemon/models.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ export async function buildModelPickerOptions({
142142
cliOpenclaw: boolean;
143143
cliOpencode: boolean;
144144
cliCopilot: boolean;
145+
cliAgy: boolean;
145146
};
146147
openaiBaseUrl: string | null;
147148
localModelsSource: { kind: "openai-compatible"; baseUrlHost: string } | null;
@@ -164,6 +165,7 @@ export async function buildModelPickerOptions({
164165
cliOpenclaw: false,
165166
cliOpencode: false,
166167
cliCopilot: false,
168+
cliAgy: false,
167169
};
168170
const cliAvailability = resolveCliAvailability({ env: envForRun, config: configForCli });
169171
providers.cliClaude = Boolean(cliAvailability.claude);
@@ -173,6 +175,7 @@ export async function buildModelPickerOptions({
173175
providers.cliOpenclaw = Boolean(cliAvailability.openclaw);
174176
providers.cliOpencode = Boolean(cliAvailability.opencode);
175177
providers.cliCopilot = Boolean(cliAvailability.copilot);
178+
providers.cliAgy = Boolean(cliAvailability.agy);
176179

177180
const options: ModelPickerOption[] = [
178181
{ id: "auto", label: "Auto" },
@@ -201,6 +204,9 @@ export async function buildModelPickerOptions({
201204
if (providers.cliCopilot) {
202205
options.push({ id: "cli/copilot", label: "CLI: GitHub Copilot" });
203206
}
207+
if (providers.cliAgy) {
208+
options.push({ id: "cli/agy", label: "CLI: Antigravity (agy)" });
209+
}
204210

205211
if (providers.openrouter) {
206212
options.push({ id: "free", label: "Free (OpenRouter)" });

src/llm/cli-provider-output.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { CliProvider } from "../config.js";
22
import type { LlmTokenUsage } from "./generate-text.js";
33

4-
export type JsonCliProvider = Exclude<CliProvider, "codex" | "openclaw" | "opencode" | "copilot">;
4+
export type JsonCliProvider = Exclude<CliProvider, "codex" | "openclaw" | "opencode" | "copilot" | "agy">;
55

66
const JSON_RESULT_FIELDS = ["result", "response", "output", "message", "text"] as const;
77

@@ -10,7 +10,8 @@ export function isJsonCliProvider(provider: CliProvider): provider is JsonCliPro
1010
provider !== "codex" &&
1111
provider !== "openclaw" &&
1212
provider !== "opencode" &&
13-
provider !== "copilot"
13+
provider !== "copilot" &&
14+
provider !== "agy"
1415
);
1516
}
1617

src/llm/cli.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const DEFAULT_BINARIES: Record<CliProvider, string> = {
2323
openclaw: "openclaw",
2424
opencode: "opencode",
2525
copilot: "copilot",
26+
agy: "agy",
2627
};
2728

2829
const OPENCLAW_MAX_MESSAGE_ARG_BYTES = 120 * 1024;
@@ -37,6 +38,7 @@ const PROVIDER_PATH_ENV: Record<CliProvider, string> = {
3738
openclaw: "OPENCLAW_PATH",
3839
opencode: "OPENCODE_PATH",
3940
copilot: "COPILOT_PATH",
41+
agy: "AGY_PATH",
4042
};
4143

4244
type RunCliModelOptions = {
@@ -72,6 +74,7 @@ function getCliProviderConfig(
7274
if (provider === "agent") return config.agent;
7375
if (provider === "openclaw") return config.openclaw;
7476
if (provider === "opencode") return config.opencode;
77+
if (provider === "agy") return config.agy;
7578
return config.copilot;
7679
}
7780

@@ -371,6 +374,28 @@ export async function runCliModel({
371374
return { text, usage: null, costUsd: null };
372375
}
373376

377+
if (provider === "agy") {
378+
const agyArgs: string[] = [...providerExtraArgs, "--print"];
379+
if (requestedModel) {
380+
agyArgs.push("--model", requestedModel);
381+
}
382+
if (allowTools) {
383+
agyArgs.push("--dangerously-skip-permissions");
384+
}
385+
const { stdout } = await execCliWithInput({
386+
execFileImpl: execFileFn,
387+
cmd: binary,
388+
args: agyArgs,
389+
input: prompt,
390+
timeoutMs,
391+
env: effectiveEnv,
392+
cwd,
393+
});
394+
const text = stdout.trim();
395+
if (!text) throw new Error("CLI returned empty output");
396+
return { text, usage: null, costUsd: null };
397+
}
398+
374399
if (!isJsonCliProvider(provider)) {
375400
throw new Error(`Unsupported CLI provider "${provider}".`);
376401
}

src/llm/provider-profile.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ export type RequiredModelEnv =
3535
| "CLI_AGENT"
3636
| "CLI_OPENCLAW"
3737
| "CLI_OPENCODE"
38-
| "CLI_COPILOT";
38+
| "CLI_COPILOT"
39+
| "CLI_AGY";
3940

4041
type GatewayProviderProfile = {
4142
requiredEnv: RequiredModelEnv;
@@ -105,6 +106,7 @@ export const DEFAULT_CLI_MODELS: Record<CliProvider, string | null> = {
105106
openclaw: "main",
106107
opencode: null,
107108
copilot: null,
109+
agy: null,
108110
};
109111

110112
export const DEFAULT_AUTO_CLI_ORDER: CliProvider[] = [
@@ -115,6 +117,10 @@ export const DEFAULT_AUTO_CLI_ORDER: CliProvider[] = [
115117
"openclaw",
116118
"opencode",
117119
"copilot",
120+
// agy (Antigravity CLI) included in auto-fallback: it uses the same
121+
// plain-text --print interface as copilot and falls back gracefully
122+
// when not installed (binary availability check via AGY_PATH / PATH).
123+
"agy",
118124
];
119125

120126
export function parseCliProviderName(raw: string): CliProvider | null {
@@ -126,6 +132,7 @@ export function parseCliProviderName(raw: string): CliProvider | null {
126132
if (normalized === "openclaw") return "openclaw";
127133
if (normalized === "opencode") return "opencode";
128134
if (normalized === "copilot") return "copilot";
135+
if (normalized === "agy") return "agy";
129136
return null;
130137
}
131138

@@ -142,7 +149,9 @@ export function requiredEnvForCliProvider(provider: CliProvider): RequiredModelE
142149
? "CLI_OPENCODE"
143150
: provider === "copilot"
144151
? "CLI_COPILOT"
145-
: "CLI_CLAUDE";
152+
: provider === "agy"
153+
? "CLI_AGY"
154+
: "CLI_CLAUDE";
146155
}
147156

148157
export function getGatewayProviderProfile(provider: GatewayProvider): GatewayProviderProfile {

0 commit comments

Comments
 (0)