Skip to content
Closed
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
28 changes: 15 additions & 13 deletions docs/src/content/docs/reference/engines.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: AI Engines (aka Coding Agents)
description: Complete guide to AI engines (coding agents) usable with GitHub Agentic Workflows, including Copilot, Claude, Codex, Gemini, OpenCode, and Pi with their specific configuration options.
description: Complete guide to AI engines (coding agents) usable with GitHub Agentic Workflows, including Copilot, Claude, Codex, Gemini, OpenCode, Pi, and Antigravity with their specific configuration options.
sidebar:
order: 600
---
Expand All @@ -19,6 +19,7 @@ Set `engine:` in your workflow frontmatter and configure the corresponding secre
| [Google Gemini CLI](https://github.com/google-gemini/gemini-cli) | `gemini` | [`GEMINI_API_KEY`](/gh-aw/reference/auth/#gemini_api_key) (standard) or [`engine.auth` Google WIF](/gh-aw/reference/auth/#google-workload-identity-federation-wif) (keyless) |
| [OpenCode](https://opencode.ai) (experimental) | `opencode` | [COPILOT_GITHUB_TOKEN](/gh-aw/reference/auth/#copilot_github_token) |
| [Pi](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) (experimental) | `pi` | [COPILOT_GITHUB_TOKEN](/gh-aw/reference/auth/#copilot_github_token) (default); switches to provider-specific secret when `model:` uses `provider/model` format |
| Google Antigravity CLI (experimental) | `antigravity` | [`ANTIGRAVITY_API_KEY`](/gh-aw/reference/auth/#antigravity_api_key) |

Copilot CLI is the default — `engine:` can be omitted when using Copilot. See the linked authentication docs for secret setup instructions.

Expand All @@ -30,18 +31,18 @@ Choose the engine that best matches your needs and existing AI account: Copilot

Not all features are available across all engines. The table below summarizes per-engine support for commonly used workflow options:

| Feature | Copilot | Claude | Codex | Gemini | OpenCode | Pi |
|---------|:-------:|:------:|:-----:|:------:|:--------:|:--:|
| `max-turns` (AWF invocation cap; `max-runs` deprecated) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `max-turns` | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
| `max-continuations` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| `tools.web-fetch` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `tools.web-search` | via MCP | via MCP | ✅ (opt-in) | via MCP | via MCP | via MCP |
| `engine.agent` (custom agent file) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| `engine.api-target` (custom endpoint) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `engine.bare` (disable context loading) | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| `engine.harness` (custom harness script) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Tools allowlist | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
| Feature | Copilot | Claude | Codex | Gemini | OpenCode | Pi | Antigravity |
|---------|:-------:|:------:|:-----:|:------:|:--------:|:--:|:-----------:|
| `max-turns` (AWF invocation cap; `max-runs` deprecated) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `max-turns` | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| `max-continuations` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| `tools.web-fetch` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `tools.web-search` | via MCP | via MCP | ✅ (opt-in) | via MCP | via MCP | via MCP | via MCP |
| `engine.agent` (custom agent file) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| `engine.api-target` (custom endpoint) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `engine.bare` (disable context loading) | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| `engine.harness` (custom harness script) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Tools allowlist | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |

`max-turns` (default `500`, legacy alias `max-runs`) and `max-ai-credits` (default `1000`) are top-level frontmatter fields supported by all engines. `engine.max-turns` is a deprecated nested alias that still limits Claude iterations when present; `max-continuations` enables Copilot autopilot mode. Codex `web-search` is opt-in via `tools: web-search:`; other engines use a third-party MCP server — see [Using Web Search](/gh-aw/reference/web-search/). `engine.agent`, `engine.bare`, and `engine.harness` are described below.

Expand Down Expand Up @@ -72,6 +73,7 @@ By default, workflows install the latest available version of each engine CLI. T
| Gemini CLI | `gemini` | `"0.31.0"` |
| OpenCode | `opencode` | `"0.1.0"` |
| Pi | `pi` | `"0.72.1"` |
| Antigravity CLI | `antigravity` | `"latest"` |

```yaml wrap
engine:
Expand Down
1 change: 1 addition & 0 deletions pkg/workflow/engine_definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func TestNewEngineCatalog_BuiltIns(t *testing.T) {
{"gemini", "Google Gemini CLI", "google"},
{"opencode", "OpenCode", "github"},
{"pi", "Pi", "github"},
{"antigravity", "Antigravity CLI", "google"},
}

for _, tt := range tests {
Expand Down
56 changes: 56 additions & 0 deletions pkg/workflow/engine_doc_sync_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//go:build !integration

package workflow

import (
"os"
"path/filepath"
"strings"
"testing"
)

// engineDocSyncPath is the path from the pkg/workflow package directory to
// the engines reference document.
const engineDocSyncPath = "../../docs/src/content/docs/reference/engines.md"

// TestEngineDocSync verifies that every built-in engine definition in
// data/engines/ has its engine ID referenced in the engines reference
// documentation.
//
// This test is the structural safeguard against "doc drift": when a new engine
// is added to data/engines/*.md but the docs are not updated, this test fails
// at PR time rather than being discovered and manually patched after the fact.
//
// To fix a failure: add the engine ID (e.g. `antigravity`) to the Available
// Coding Agents table in docs/src/content/docs/reference/engines.md.
func TestEngineDocSync(t *testing.T) {
// Read the engines reference doc.
docPath := filepath.Join("..", "..", "docs", "src", "content", "docs", "reference", "engines.md")
docContent, err := os.ReadFile(docPath)
if err != nil {
t.Fatalf("failed to read engines reference doc at %s: %v\n\n"+
"If the docs file was moved, update engineDocSyncPath in engine_doc_sync_test.go.",
engineDocSyncPath, err)
}
docStr := string(docContent)

// Load all built-in engine definitions using the same loader used at runtime.
definitions := loadBuiltinEngineDefinitions()

var missing []string
for _, def := range definitions {
// Check that the engine ID appears in the docs as a backtick-quoted value
// (e.g. `antigravity`) — the canonical form used in the Available Coding
// Agents table and throughout the engines reference page.
if !strings.Contains(docStr, "`"+def.ID+"`") {
missing = append(missing, def.ID)
}
}

if len(missing) > 0 {
t.Errorf("the following engine IDs are registered in data/engines/ but missing from the engines reference doc (%s):\n\n %s\n\n"+
"Add each missing engine to the Available Coding Agents table in that file.\n"+
"This check prevents engine-doc drift from recurring.",
engineDocSyncPath, strings.Join(missing, "\n "))
}
}