Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules
.clawpatch/
.antigravitycli/
dist
dist-bun
*.bun-build
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Features

- Add Antigravity CLI (`agy`) as a supported CLI provider. (#231, thanks @yetmike)

### Fixes

- Chrome extension: abort stale side-panel summary streams on tab changes so delayed output from a closed or replaced tab cannot render under the new page title.
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ Use `summarize --help` or `summarize help` for the full help text.
- `--length short|medium|long|xl|xxl|s|m|l|<chars>`
- `--language, --lang <language>`: output language (`auto` = match source)
- `--max-output-tokens <count>`: hard cap for LLM output tokens
- `--cli [provider]`: use a CLI provider (`--model cli/<provider>`). Supports `claude`, `gemini`, `codex`, `agent`, `openclaw`, `opencode`. If omitted, uses auto selection with CLI enabled.
- `--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.
- `--stream auto|on|off`: stream LLM output (`auto` = TTY only; disabled in `--json` mode)
- `--plain`: keep raw output (no ANSI/OSC Markdown rendering)
- `--no-color`: disable ANSI colors
Expand All @@ -353,7 +353,7 @@ Use `summarize --help` or `summarize help` for the full help text.
- `--verbose`: debug/diagnostics on stderr
- `--metrics off|on|detailed`: metrics output (default `on`)

### Coding CLIs (Codex, Claude, Gemini, Agent, OpenClaw, OpenCode)
### Coding CLIs (Codex, Claude, Gemini, Agent, OpenClaw, OpenCode, Antigravity)

Summarize can use common coding CLIs as local model backends:

Expand All @@ -363,15 +363,16 @@ Summarize can use common coding CLIs as local model backends:
- `agent` (Cursor Agent CLI) -> `--cli agent` / `--model cli/agent/<model>`
- `openclaw` -> `--cli openclaw` / `--model cli/openclaw/<model>` or `--model openclaw/<model>`
- `opencode` -> `--cli opencode` / `--model cli/opencode/<model>` (`--model cli/opencode` uses the OpenCode runtime default)
- `agy` (Antigravity CLI) -> `--cli agy` / `--model cli/agy` (uses agy's active session model; per-call model selection is not supported by agy print mode)

Built-in preset:

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

Requirements:

- Binary installed and on `PATH` (or set `CODEX_PATH`, `CLAUDE_PATH`, `GEMINI_PATH`, `AGENT_PATH`, `OPENCLAW_PATH`, `OPENCODE_PATH`)
- Provider authenticated (`codex login`, `claude auth`, `gemini` login flow, `agent login` or `CURSOR_API_KEY`, `opencode auth login`)
- Binary installed and on `PATH` (or set `CODEX_PATH`, `CLAUDE_PATH`, `GEMINI_PATH`, `AGENT_PATH`, `OPENCLAW_PATH`, `OPENCODE_PATH`, `AGY_PATH`)
- 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`)

Quick smoke test:

Expand All @@ -384,13 +385,14 @@ summarize --cli gemini --plain --timeout 2m /tmp/summarize-cli-smoke.txt
summarize --cli agent --plain --timeout 2m /tmp/summarize-cli-smoke.txt
summarize --cli openclaw --plain --timeout 2m /tmp/summarize-cli-smoke.txt
summarize --cli opencode --plain --timeout 2m /tmp/summarize-cli-smoke.txt
summarize --cli agy --plain --timeout 2m /tmp/summarize-cli-smoke.txt
```

Set explicit CLI allowlist/order:

```json
{
"cli": { "enabled": ["codex", "claude", "gemini", "agent", "openclaw", "opencode"] }
"cli": { "enabled": ["codex", "claude", "gemini", "agent", "openclaw", "opencode", "agy"] }
}
```

Expand Down
3 changes: 2 additions & 1 deletion apps/chrome-extension/src/lib/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ function normalizeAutoCliOrder(value: unknown): string {
item !== "agent" &&
item !== "openclaw" &&
item !== "opencode" &&
item !== "copilot"
item !== "copilot" &&
item !== "agy"
) {
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ summary: "Docs index for summarize behaviors and modes."

- `docs/chrome-extension.md` — Chrome side panel extension + daemon setup/troubleshooting
- `docs/cache.md` — cache design + config (SQLite)
- `docs/cli.md` — CLI models (Claude/Codex/Gemini/Agent/OpenClaw/OpenCode/Copilot)
- `docs/cli.md` — CLI models (Claude/Codex/Gemini/Agent/OpenClaw/OpenCode/Copilot/Antigravity)
- `docs/config.md` — config file location, precedence, and schema
- `docs/extract-only.md` — extract mode (no summary LLM call)
- `docs/firecrawl.md` — Firecrawl mode + API key
Expand Down
14 changes: 11 additions & 3 deletions docs/cli.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---
title: "CLI providers"
kicker: "models"
summary: "CLI model providers and config for Claude, Codex, Gemini, Cursor Agent, OpenClaw, OpenCode, and GitHub Copilot."
summary: "CLI model providers and config for Claude, Codex, Gemini, Cursor Agent, OpenClaw, OpenCode, GitHub Copilot, and Antigravity."
read_when:
- "When changing CLI model integration."
---

# CLI models

Summarize can use installed CLIs (Claude, Codex, Gemini, Cursor Agent, OpenClaw, OpenCode, GitHub Copilot) as local model backends.
Summarize can use installed CLIs (Claude, Codex, Gemini, Cursor Agent, OpenClaw, OpenCode, GitHub Copilot, Antigravity) as local model backends.

## Model ids

Expand All @@ -22,8 +22,10 @@ Summarize can use installed CLIs (Claude, Codex, Gemini, Cursor Agent, OpenClaw,
- `cli/opencode` (use the OpenCode runtime default model)
- `cli/copilot/<model>` (e.g. `cli/copilot/gpt-5.2`)
- `cli/copilot` (use the Copilot CLI runtime default model)
- `cli/agy` (use the Antigravity CLI active session model)

Use `--cli [provider]` (case-insensitive) for the provider default, or `--model cli/<provider>/<model>` to pin a model.
Antigravity does not support per-call model selection in print mode, so use `cli/agy` without a model suffix.
If `--cli` is provided without a provider, auto selection is used with CLI enabled.

Codex GPT Fast:
Expand Down Expand Up @@ -100,13 +102,14 @@ path-based prompt and enables the required tool flags:
- Agent: uses built-in file tools in `agent --print` mode (no extra flags)
- OpenCode: `opencode run --format json ... --file <path>` when a file/image path is required
- Copilot: `copilot -p <prompt>`; passes `--model <model>` when one is configured
- Antigravity: `agy --print`; does not auto-approve tools for attachment prompts

## Config

```json
{
"cli": {
"enabled": ["claude", "gemini", "codex", "agent", "openclaw", "opencode", "copilot"],
"enabled": ["claude", "gemini", "codex", "agent", "openclaw", "opencode", "copilot", "agy"],
"autoFallback": {
"enabled": true,
"onlyWhenNoApiKeys": true,
Expand All @@ -132,6 +135,9 @@ path-based prompt and enables the required tool flags:
},
"copilot": {
"binary": "/usr/local/bin/copilot"
},
"agy": {
"binary": "/usr/local/bin/agy"
}
}
}
Expand All @@ -142,6 +148,8 @@ Notes:
- CLI output is treated as text only (no token accounting).
- If a CLI call fails, auto mode falls back to the next candidate.
- Cursor Agent CLI uses the `agent` binary and relies on Cursor CLI auth (login or `CURSOR_API_KEY`).
- Antigravity CLI uses the active agy session model; `cli.agy.model` is ignored by runtime selection.
- Antigravity normal text summaries run `agy --print` with no prompt argument in a temporary cwd with `--sandbox`, streaming the prompt over stdin so extracted content is not exposed in argv. Attachment prompts keep the caller cwd so agy can inspect the requested path but do not auto-approve tools.
- Codex CLI normal text summaries run isolated by default: `codex exec --ephemeral --ignore-user-config --ignore-rules -C <temp-dir> ...` with a sanitized temporary `CODEX_HOME` that carries auth only. Set `cli.codex.isolated` to `false` only when you intentionally need Codex to inherit local config/rules.
- Gemini CLI is invoked in headless mode with `--prompt` for compatibility with current Gemini CLI releases.
- OpenClaw uses `openclaw agent --agent <model> --message <prompt> --json` because current OpenClaw requires `-m/--message`; very large extracted inputs are rejected before launch to avoid argv limits.
Expand Down
6 changes: 4 additions & 2 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ Examples:
```json
{
"cli": {
"enabled": ["gemini", "agent", "openclaw", "opencode", "copilot"],
"enabled": ["gemini", "agent", "openclaw", "opencode", "copilot", "agy"],
"autoFallback": {
"enabled": true,
"onlyWhenNoApiKeys": true,
Expand All @@ -372,7 +372,8 @@ Examples:
"agent": { "binary": "/usr/local/bin/agent", "model": "gpt-5.2" },
"openclaw": { "binary": "/usr/local/bin/openclaw", "model": "main" },
"opencode": { "binary": "/usr/local/bin/opencode", "model": "openai/gpt-5.4" },
"copilot": { "binary": "/usr/local/bin/copilot", "model": "gpt-5.2" }
"copilot": { "binary": "/usr/local/bin/copilot", "model": "gpt-5.2" },
"agy": { "binary": "/usr/local/bin/agy" }
}
}
```
Expand All @@ -385,6 +386,7 @@ Notes:
- Auto fallback stores the last successful provider in `~/.summarize/cli-state.json` and prioritizes it on the next run.
- `cli.<provider>.binary` overrides CLI binary discovery.
- `cli.<provider>.extraArgs` appends extra CLI args.
- Antigravity CLI uses the active agy session model; `cli.agy.model` is ignored by runtime selection.
- `cli.codex.isolated` defaults to `true` for normal summaries, adding Codex ephemeral/no-user-config/no-rules flags, a temporary cwd, and a sanitized temporary `CODEX_HOME` that carries auth only. Set it to `false` only when local Codex config/rules are intentional.

## OpenAI config
Expand Down
5 changes: 3 additions & 2 deletions docs/llm.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ installed, auto mode can use local CLI models via `cli.enabled` or implicit auto
- `ANTHROPIC_API_KEY` (required for `anthropic/...` models)
- `ANTHROPIC_BASE_URL` (optional; override Anthropic API endpoint)
- `SUMMARIZE_MODEL` (optional; overrides default model selection)
- `CLAUDE_PATH` / `CODEX_PATH` / `GEMINI_PATH` / `AGENT_PATH` / `OPENCLAW_PATH` / `OPENCODE_PATH` / `COPILOT_PATH` (optional; override CLI binary paths)
- `CLAUDE_PATH` / `CODEX_PATH` / `GEMINI_PATH` / `AGENT_PATH` / `OPENCLAW_PATH` / `OPENCODE_PATH` / `COPILOT_PATH` / `AGY_PATH` (optional; override CLI binary paths)

## Flags

Expand All @@ -53,6 +53,7 @@ installed, auto mode can use local CLI models via `cli.enabled` or implicit auto
- `cli/openclaw/main`
- `cli/opencode/openai/gpt-5.4`
- `cli/copilot/gpt-5.2`
- `cli/agy`
- `openai/gpt-5.4`
- `openai/gpt-5.4-mini`
- `openai/gpt-5.4-nano`
Expand All @@ -69,7 +70,7 @@ installed, auto mode can use local CLI models via `cli.enabled` or implicit auto
- `anthropic/claude-sonnet-4-5`
- `openrouter/meta-llama/llama-3.3-70b-instruct:free` (force OpenRouter)
- `--cli [provider]`
- Examples: `--cli claude`, `--cli Gemini`, `--cli codex`, `--cli agent`, `--cli openclaw`, `--cli opencode`, `--cli copilot` (equivalent to `--model cli/<provider>`); `--cli` alone uses auto selection with CLI enabled.
- Examples: `--cli claude`, `--cli Gemini`, `--cli codex`, `--cli agent`, `--cli openclaw`, `--cli opencode`, `--cli copilot`, `--cli agy` (equivalent to `--model cli/<provider>`); `--cli` alone uses auto selection with CLI enabled.
- `--model auto`
- See `docs/model-auto.md`
- `--model <preset>`
Expand Down
3 changes: 2 additions & 1 deletion src/config/parse-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export function parseCliProvider(value: unknown, path: string): CliProvider {
trimmed === "agent" ||
trimmed === "openclaw" ||
trimmed === "opencode" ||
trimmed === "copilot"
trimmed === "copilot" ||
trimmed === "agy"
) {
return trimmed as CliProvider;
}
Expand Down
3 changes: 3 additions & 0 deletions src/config/sections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ export function parseCliConfig(root: Record<string, unknown>, path: string): Cli
const copilot = value.copilot
? parseCliProviderConfig(value.copilot, path, "copilot")
: undefined;
const agy = value.agy ? parseCliProviderConfig(value.agy, path, "agy") : undefined;
if (typeof value.autoFallback !== "undefined" && typeof value.magicAuto !== "undefined") {
throw new Error(
`Invalid config file ${path}: use only one of "cli.autoFallback" or legacy "cli.magicAuto".`,
Expand Down Expand Up @@ -359,6 +360,7 @@ export function parseCliConfig(root: Record<string, unknown>, path: string): Cli
openclaw ||
opencode ||
copilot ||
agy ||
autoFallback ||
promptOverride ||
typeof allowTools === "boolean" ||
Expand All @@ -373,6 +375,7 @@ export function parseCliConfig(root: Record<string, unknown>, path: string): Cli
...(openclaw ? { openclaw } : {}),
...(opencode ? { opencode } : {}),
...(copilot ? { copilot } : {}),
...(agy ? { agy } : {}),
...(autoFallback ? { autoFallback } : {}),
...(promptOverride ? { promptOverride } : {}),
...(typeof allowTools === "boolean" ? { allowTools } : {}),
Expand Down
4 changes: 3 additions & 1 deletion src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export type CliProvider =
| "agent"
| "openclaw"
| "opencode"
| "copilot";
| "copilot"
| "agy";
export type OpenAiReasoningEffort = "none" | "low" | "medium" | "high" | "xhigh";
export type OpenAiTextVerbosity = "low" | "medium" | "high";
export type ModelRequestOptions = {
Expand Down Expand Up @@ -36,6 +37,7 @@ export type CliConfig = {
openclaw?: CliProviderConfig;
opencode?: CliProviderConfig;
copilot?: CliProviderConfig;
agy?: CliProviderConfig;
autoFallback?: CliAutoFallbackConfig;
magicAuto?: CliAutoFallbackConfig;
promptOverride?: string;
Expand Down
4 changes: 3 additions & 1 deletion src/daemon/agent-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,10 @@ function buildNoAgentModelAvailableError({
if (attempt.requiredEnv === "CLI_GEMINI") return "gemini";
if (attempt.requiredEnv === "CLI_AGENT") return "agent";
if (attempt.requiredEnv === "CLI_OPENCLAW") return "openclaw";
if (attempt.requiredEnv === "CLI_OPENCODE") return "opencode";
if (attempt.requiredEnv === "CLI_COPILOT") return "copilot";
return "opencode";
if (attempt.requiredEnv === "CLI_AGY") return "agy";
return "unknown";
})
.filter((provider) => !cliAvailability[provider as keyof typeof cliAvailability]),
),
Expand Down
6 changes: 5 additions & 1 deletion src/daemon/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ function resolveConfiguredCliModel(
? cli?.agent?.model
: provider === "openclaw"
? cli?.openclaw?.model
: cli?.opencode?.model;
: provider === "opencode"
? cli?.opencode?.model
: provider === "agy"
? null
: cli?.copilot?.model;
return typeof raw === "string" && raw.trim().length > 0 ? raw.trim() : null;
}

Expand Down
2 changes: 2 additions & 0 deletions src/daemon/env-snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const ENV_KEYS = [
"OPENCLAW_PATH",
"OPENCODE_PATH",
"COPILOT_PATH",
"AGY_PATH",
"ANTIGRAVITY_API_KEY",
"UVX_PATH",
] as const;

Expand Down
6 changes: 6 additions & 0 deletions src/daemon/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ export async function buildModelPickerOptions({
cliOpenclaw: boolean;
cliOpencode: boolean;
cliCopilot: boolean;
cliAgy: boolean;
};
openaiBaseUrl: string | null;
localModelsSource: { kind: "openai-compatible"; baseUrlHost: string } | null;
Expand All @@ -164,6 +165,7 @@ export async function buildModelPickerOptions({
cliOpenclaw: false,
cliOpencode: false,
cliCopilot: false,
cliAgy: false,
};
const cliAvailability = resolveCliAvailability({ env: envForRun, config: configForCli });
providers.cliClaude = Boolean(cliAvailability.claude);
Expand All @@ -173,6 +175,7 @@ export async function buildModelPickerOptions({
providers.cliOpenclaw = Boolean(cliAvailability.openclaw);
providers.cliOpencode = Boolean(cliAvailability.opencode);
providers.cliCopilot = Boolean(cliAvailability.copilot);
providers.cliAgy = Boolean(cliAvailability.agy);

const options: ModelPickerOption[] = [
{ id: "auto", label: "Auto" },
Expand Down Expand Up @@ -201,6 +204,9 @@ export async function buildModelPickerOptions({
if (providers.cliCopilot) {
options.push({ id: "cli/copilot", label: "CLI: GitHub Copilot" });
}
if (providers.cliAgy) {
options.push({ id: "cli/agy", label: "CLI: Antigravity (agy)" });
}

if (providers.openrouter) {
options.push({ id: "free", label: "Free (OpenRouter)" });
Expand Down
8 changes: 6 additions & 2 deletions src/llm/cli-provider-output.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import type { CliProvider } from "../config.js";
import type { LlmTokenUsage } from "./generate-text.js";

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

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

Expand All @@ -10,7 +13,8 @@ export function isJsonCliProvider(provider: CliProvider): provider is JsonCliPro
provider !== "codex" &&
provider !== "openclaw" &&
provider !== "opencode" &&
provider !== "copilot"
provider !== "copilot" &&
provider !== "agy"
);
}

Expand Down
Loading