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
5 changes: 5 additions & 0 deletions .changeset/minor-copilot-sdk-non-experimental.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/aw/syntax-agentic.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ description: Agentic workflow specific frontmatter fields for GitHub Agentic Wor
- **`antigravity` engine** (experimental): Google Antigravity CLI in headless mode. Requires `ANTIGRAVITY_API_KEY` secret; model via `model:` (maps to `ANTIGRAVITY_MODEL`). Supports `max-turns`, tools allow-list, AWF firewall, and LLM gateway. Does not support `web-search`, `max-continuations`, or native agent files (agent content is prepended to the prompt).
- **`opencode` engine** (experimental): Provider-agnostic, open-source AI coding agent (BYOK). Defaults to Copilot routing via `COPILOT_GITHUB_TOKEN` (or `${{ github.token }}` with `copilot-requests` feature). Supports 75+ models via `provider/model` format. Supports AWF firewall and LLM gateway.
- **`engine.driver:`** — canonical field to run a custom inner driver script instead of the engine's built-in CLI. For the `pi` engine it launches the driver directly with Node.js (e.g. built-in `pi_agent_core_driver.cjs`, or a workspace-relative path like `.github/drivers/pi_agent_core_driver_sample_node.cjs`); the driver must emit JSONL compatible with `parse_pi_log.cjs` so step summaries and token tracking keep working. Accepts a bare basename (resolved from the setup-action directory) or a workspace-relative path; no absolute paths, no `..`, only `.js`/`.cjs`/`.mjs` (pi).
- **`copilot-sdk` / `engine.driver`** (experimental, copilot only): set `copilot-sdk: true` to start a headless Copilot CLI SDK sidecar. Set `driver: <path-or-command>` on the copilot engine to supply a custom SDK driver (`.js`/`.cjs`/`.mjs`/`.py`/`.ts`/`.mts`/`.rb`, or a bare PATH command); this also enables `copilot-sdk: true` automatically. Tune the repeated-tool-denial safeguard with the top-level `max-tool-denials:` field (default `5`).
- **`copilot-sdk`** (copilot only): set `copilot-sdk: true` to start a headless Copilot CLI SDK sidecar. **`engine.driver`** (experimental, copilot only): set `driver: <path-or-command>` to supply a custom SDK driver (`.js`/`.cjs`/`.mjs`/`.py`/`.ts`/`.mts`/`.rb`, or a bare PATH command); this also enables `copilot-sdk: true` automatically. Tune the repeated-tool-denial safeguard with the top-level `max-tool-denials:` field (default `5`).

**Inline driver source** (copilot engine only): instead of pointing to a checked-in file, you can embed the driver source directly in the frontmatter using an object with exactly one runtime key (`node`, `python`, `go`, or `java`). The compiler materializes the source under `.gh-aw/copilot-sdk/` at runtime and generates a launcher wrapper. The required SDK package is installed automatically.

Expand Down
1 change: 1 addition & 0 deletions docs/src/content/docs/reference/engines.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Set `engine:` in your workflow frontmatter and configure the corresponding secre
| Engine | `engine:` value | Required Secret |
|--------|-----------------|-----------------|
| [GitHub Copilot CLI](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/use-copilot-cli) (default) | `copilot` | [`copilot-requests: write`](/gh-aw/reference/auth/#copilot-requests-write-permission) (recommended) or [`COPILOT_GITHUB_TOKEN`](/gh-aw/reference/auth/#copilot_github_token) |
| [GitHub Copilot (SDK mode)](/gh-aw/reference/engines/#copilot-sdk-support) | `copilot` + `copilot-sdk: true` | same as Copilot CLI |
| [Claude by Anthropic (Claude Code)](https://www.anthropic.com/index/claude) | `claude` | [`ANTHROPIC_API_KEY`](/gh-aw/reference/auth/#anthropic_api_key) (standard) or [`engine.auth` Anthropic WIF](/gh-aw/reference/auth/#anthropic-workload-identity-federation-wif) (keyless) |
| [OpenAI Codex](https://openai.com/blog/openai-codex) | `codex` | [OPENAI_API_KEY](/gh-aw/reference/auth/#openai_api_key) |
| [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) |
Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/reference/frontmatter-full.md
Original file line number Diff line number Diff line change
Expand Up @@ -2528,7 +2528,7 @@ engine:
# (optional)
tool-timeout: "example-value"

# Enables the experimental GitHub Copilot SDK integration (copilot engine only).
# Enables the GitHub Copilot SDK integration (copilot engine only).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 34aa776. Updated both remaining references:

  • .github/aw/syntax-agentic.md:303: removed experimental, from (experimental, copilot only)(copilot only)
  • pkg/workflow/README.md:150: removed **(Experimental)** from the CopilotSDK field description

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking this stable here contradicts two other docs that still call copilot-sdk experimental, leaving readers with conflicting lifecycle guidance.

💡 Details

.github/aw/syntax-agentic.md:303 still says **copilot-sdk/engine.driver** (experimental, copilot only) and pkg/workflow/README.md:150-151 still labels CopilotSDK/Driver as **(Experimental)**. If this PR's intent is to declare the feature stable, all doc surfaces referencing its maturity should be updated together; otherwise a reader following the frontmatter reference will get a different lifecycle status than the syntax guide or generated field docs.

Fix: update the three references consistently (either all say stable, or clarify why frontmatter differs).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 34aa776. Both references are now consistent:

  • .github/aw/syntax-agentic.md:303: (experimental, copilot only)(copilot only)
  • pkg/workflow/README.md:150: **(Experimental)** Enables GitHub Copilot SDK integrationEnables GitHub Copilot SDK integration

# When true, the harness starts a separate headless Copilot CLI sidecar on the
# configured localhost port and sets COPILOT_SDK_URI on child processes.
# (optional)
Expand Down
2 changes: 1 addition & 1 deletion pkg/workflow/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ The `checkout:` frontmatter key is parsed by `ParseCheckoutConfigs` into one or
| `UserAgent` | `string` | `engine.user-agent` | Custom user-agent string |
| `Command` | `string` | `engine.command` | Custom executable path; skips installation steps when set |
| `HarnessScript` | `string` | `engine.harness-script` | Custom Node.js harness script filename (replaces engine default) |
| `CopilotSDK` | `bool` | `engine.copilot-sdk` | **(Experimental)** Enables GitHub Copilot SDK integration. When `true`, the compiler starts a headless Copilot CLI sidecar and sets `COPILOT_SDK_URI` on child processes so the SDK can connect to it. Also enabled automatically for the copilot engine when `Driver` is non-empty. |
| `CopilotSDK` | `bool` | `engine.copilot-sdk` | Enables GitHub Copilot SDK integration. When `true`, the compiler starts a headless Copilot CLI sidecar and sets `COPILOT_SDK_URI` on child processes so the SDK can connect to it. Also enabled automatically for the copilot engine when `Driver` is non-empty. |
| `Driver` | `string` | `engine.driver` | **(Experimental)** Custom driver script filename or command. Supports `.js`/`.cjs`/`.mjs` (Node.js), `.py` (Python), `.ts`/`.mts` (TypeScript), `.rb` (Ruby), or a bare command name for an arbitrary executable on `PATH`. Setting this field implies `copilot-sdk: true` for the copilot engine. |
| `Env` | `map[string]string` | `engine.env` | Extra environment variables injected into the agent job |
| `Auth` | `*EngineAuthConfig` | `engine.auth` | Engine-level auth config for the API proxy sidecar |
Expand Down
1 change: 0 additions & 1 deletion pkg/workflow/compiler_validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,6 @@ func (c *Compiler) emitExperimentalFeatureWarnings(workflowData *WorkflowData) {
{enabled: workflowData.SafeOutputs != nil && workflowData.SafeOutputs.DispatchRepository != nil, message: "Using experimental feature: dispatch-repository"},
{enabled: workflowData.SafeOutputs != nil && workflowData.SafeOutputs.MergePullRequest != nil, message: "Using experimental feature: merge-pull-request"},
{enabled: workflowData.SafeOutputs != nil && workflowData.SafeOutputs.ReplaceLabel != nil, message: "Using experimental feature: replace-label"},
{enabled: workflowData.EngineConfig != nil && workflowData.EngineConfig.CopilotSDK, message: "Using experimental feature: engine.copilot-sdk"},
{enabled: isFeatureEnabled(constants.GHAWDetectionFeatureFlag, workflowData), message: "Using experimental feature: gh-aw-detection"},
{enabled: len(workflowData.LSP) > 0, message: "Using experimental feature: lsp"},
}
Expand Down
34 changes: 12 additions & 22 deletions pkg/workflow/copilot_sdk_experimental_warning_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ import (
"github.com/github/gh-aw/pkg/testutil"
)

func TestCopilotSDKExperimentalWarning(t *testing.T) {
// TestCopilotSDKNoExperimentalWarning tests that the copilot-sdk feature
// does not emit an experimental warning, as the feature is no longer
// considered experimental.
func TestCopilotSDKNoExperimentalWarning(t *testing.T) {
tests := []struct {
name string
content string
expectWarning bool
name string
content string
}{
{
name: "copilot-sdk enabled produces experimental warning",
name: "copilot-sdk enabled does not produce experimental warning",
content: `---
on: workflow_dispatch
engine:
Expand All @@ -32,7 +34,6 @@ permissions:

# Test Workflow
`,
expectWarning: true,
},
{
name: "copilot-sdk disabled does not produce experimental warning",
Expand All @@ -47,7 +48,6 @@ permissions:

# Test Workflow
`,
expectWarning: false,
},
{
name: "no copilot-sdk does not produce experimental warning",
Expand All @@ -60,7 +60,6 @@ permissions:

# Test Workflow
`,
expectWarning: false,
},
}

Expand All @@ -73,6 +72,7 @@ permissions:
t.Fatal(err)
}

// Capture stderr to check for warnings
oldStderr := os.Stderr
r, w, _ := os.Pipe()
os.Stderr = w
Expand All @@ -81,6 +81,7 @@ permissions:
compiler.SetStrictMode(false)
err := compiler.CompileWorkflow(testFile)

// Restore stderr
w.Close()
os.Stderr = oldStderr
var buf bytes.Buffer
Expand All @@ -92,20 +93,9 @@ permissions:
return
}

expectedMessage := "Using experimental feature: engine.copilot-sdk"

if tt.expectWarning {
if !strings.Contains(stderrOutput, expectedMessage) {
t.Errorf("Expected warning containing '%s', got stderr:\n%s", expectedMessage, stderrOutput)
}
if compiler.GetWarningCount() == 0 {
t.Error("Expected warning count > 0 but got 0")
}
return
}

if strings.Contains(stderrOutput, expectedMessage) {
t.Errorf("Did not expect warning '%s', but got stderr:\n%s", expectedMessage, stderrOutput)
unexpectedMessage := "Using experimental feature: engine.copilot-sdk"
if strings.Contains(stderrOutput, unexpectedMessage) {
t.Errorf("Did not expect experimental warning '%s', but got stderr:\n%s", unexpectedMessage, stderrOutput)
}
})
}
Expand Down
Loading