feat: add GitHub Copilot CLI as a built-in CLI backend

Co-authored-by: htekdev <100806365+htekdev@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-01-28 22:10:53 +00:00
parent 647cf2e177
commit 44ea06f36a
10 changed files with 13564 additions and 1 deletions

View File

@ -6,6 +6,7 @@ Docs: https://docs.molt.bot
Status: beta.
### Changes
- Agents: add GitHub Copilot CLI (`copilot-cli`) as a built-in CLI backend for text-only fallback.
- Rebrand: rename the npm package/CLI to `moltbot`, add a `moltbot` compatibility shim, and move extensions to the `@moltbot/*` scope.
- Commands: group /help and /commands output with Telegram paging. (#2504) Thanks @hougangdev.
- macOS: limit project-local `node_modules/.bin` PATH preference to debug builds (reduce PATH hijacking risk).

View File

@ -1008,6 +1008,8 @@
"providers/models",
"providers/openai",
"providers/anthropic",
"providers/github-copilot",
"providers/github-copilot-cli",
"bedrock",
"providers/moonshot",
"providers/minimax",

View File

@ -32,6 +32,12 @@ Codex CLI also works out of the box:
moltbot agent --message "hi" --model codex-cli/gpt-5.2-codex
```
GitHub Copilot CLI works the same way (requires GitHub CLI auth):
```bash
moltbot agent --message "hi" --model copilot-cli/gpt-4o
```
If your gateway runs under launchd/systemd and PATH is minimal, add just the
command path:
@ -200,6 +206,18 @@ Moltbot also ships a default for `codex-cli`:
- `imageArg: "--image"`
- `sessionMode: "existing"`
Moltbot also ships a default for `copilot-cli`:
- `command: "copilot"`
- `args: ["-p"]`
- `resumeArgs: ["-p", "--resume", "{sessionId}"]`
- `output: "text"`
- `modelArg: "--model"`
- `sessionMode: "existing"`
Note: Copilot CLI uses GitHub CLI (`gh`) for authentication and currently outputs
text only (JSON output is not yet supported).
Override only if needed (common: absolute `command` path).
## Limitations

View File

@ -1668,6 +1668,9 @@ Example:
"claude-cli": {
command: "/opt/homebrew/bin/claude"
},
"copilot-cli": {
command: "/opt/homebrew/bin/copilot"
},
"my-cli": {
command: "my-cli",
args: ["--json"],

View File

@ -0,0 +1,191 @@
---
summary: "Use GitHub Copilot CLI as a text-only fallback backend"
read_when:
- You want to use GitHub Copilot CLI as a model provider
- You need a fallback when API providers fail
- You already have GitHub Copilot CLI installed
---
# GitHub Copilot CLI
GitHub Copilot CLI (`copilot`) is GitHub's terminal-based AI assistant. Moltbot can use it as a
**CLI backend** for text-only fallback when API providers are unavailable.
## Prerequisites
- **GitHub Copilot subscription** (Individual, Business, or Enterprise)
- **Node.js 22+**
- **GitHub CLI** (`gh`) authenticated with your GitHub account
## Installation
Install the Copilot CLI via npm:
```bash
npm install -g @github/copilot
```
Or via Homebrew:
```bash
brew install github/copilot/copilot
```
Or use the `gh copilot` extension:
```bash
gh extension install github/gh-copilot
```
Verify installation:
```bash
copilot --help
# or
gh copilot --help
```
## Quick start
Use Copilot CLI directly with Moltbot:
```bash
moltbot agent --message "hi" --model copilot-cli/gpt-4o
```
## Configuration
### Minimal config (custom command path)
If your gateway runs under launchd/systemd with a minimal PATH, specify the full path:
```json5
{
agents: {
defaults: {
cliBackends: {
"copilot-cli": {
command: "/opt/homebrew/bin/copilot"
}
}
}
}
}
```
### Using as a fallback
Add `copilot-cli` to your fallback list so it only runs when primary models fail:
```json5
{
agents: {
defaults: {
model: {
primary: "github-copilot/gpt-4o",
fallbacks: [
"copilot-cli/gpt-4o"
]
},
models: {
"github-copilot/gpt-4o": { alias: "Copilot" },
"copilot-cli/gpt-4o": {}
}
}
}
}
```
## Supported models
Copilot CLI supports these models (availability depends on your plan):
- `gpt-4o`
- `gpt-4.1`
- `gpt-4.1-mini`
- `gpt-4-turbo`
- `claude-sonnet-4-5`
- `claude-opus-4-5`
Example model refs:
```
copilot-cli/gpt-4o
copilot-cli/gpt-4.1
copilot-cli/claude-sonnet-4-5
```
## Authentication
Copilot CLI uses GitHub CLI authentication. Ensure you're logged in:
```bash
gh auth status
```
If not logged in:
```bash
gh auth login
```
## Limitations
- **Text output only**: Copilot CLI does not support JSON output, so responses are plain text.
- **Tools disabled**: CLI backends never receive tool calls. The CLI may still run its own agent tooling internally.
- **No streaming**: CLI output is collected then returned.
- **Session resume**: Uses `--resume` flag with session ID when available.
## Differences from the API provider
| Aspect | `github-copilot` (API) | `copilot-cli` (CLI backend) |
|--------|------------------------|----------------------------|
| Output format | JSON (structured) | Text only |
| Tools | Moltbot tools work | Tools disabled |
| Streaming | Supported | Not supported |
| Auth | Device flow / token exchange | GitHub CLI (`gh auth`) |
Choose the API provider (`github-copilot`) for full functionality. Use `copilot-cli` as a
fallback when you want "always works" text responses.
## Troubleshooting
### CLI not found
Set the full command path in your config:
```json5
{
agents: {
defaults: {
cliBackends: {
"copilot-cli": {
command: "/usr/local/bin/copilot"
}
}
}
}
}
```
### Authentication errors
Re-authenticate with GitHub CLI:
```bash
gh auth login
gh auth status
```
### Model not available
Model availability depends on your GitHub Copilot plan. Try a different model:
```bash
moltbot agent --message "hi" --model copilot-cli/gpt-4.1
```
## See also
- [GitHub Copilot (API provider)](/providers/github-copilot)
- [CLI backends](/gateway/cli-backends)
- [Configuration](/gateway/configuration)

View File

@ -35,6 +35,7 @@ See [Venice AI](/providers/venice).
- [OpenAI (API + Codex)](/providers/openai)
- [Anthropic (API + Claude Code CLI)](/providers/anthropic)
- [GitHub Copilot (API + CLI)](/providers/github-copilot)
- [Qwen (OAuth)](/providers/qwen)
- [OpenRouter](/providers/openrouter)
- [Vercel AI Gateway](/providers/vercel-ai-gateway)

View File

@ -188,6 +188,7 @@ CLAWDBOT_LIVE_SETUP_TOKEN=1 CLAWDBOT_LIVE_SETUP_TOKEN_PROFILE=anthropic:setup-to
- Overrides (optional):
- `CLAWDBOT_LIVE_CLI_BACKEND_MODEL="claude-cli/claude-opus-4-5"`
- `CLAWDBOT_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.2-codex"`
- `CLAWDBOT_LIVE_CLI_BACKEND_MODEL="copilot-cli/gpt-4o"`
- `CLAWDBOT_LIVE_CLI_BACKEND_COMMAND="/full/path/to/claude"`
- `CLAWDBOT_LIVE_CLI_BACKEND_ARGS='["-p","--output-format","json","--permission-mode","bypassPermissions"]'`
- `CLAWDBOT_LIVE_CLI_BACKEND_CLEAR_ENV='["ANTHROPIC_API_KEY","ANTHROPIC_API_KEY_OLD"]'`
@ -205,6 +206,16 @@ CLAWDBOT_LIVE_CLI_BACKEND=1 \
pnpm test:live src/gateway/gateway-cli-backend.live.test.ts
```
### Copilot CLI
```bash
CLAWDBOT_LIVE_CLI_BACKEND=1 \
CLAWDBOT_LIVE_CLI_BACKEND_MODEL="copilot-cli/gpt-4o" \
pnpm test:live src/gateway/gateway-cli-backend.live.test.ts
```
Note: Copilot CLI requires GitHub CLI auth (`gh auth status`). Output is text-only (no JSON).
### Recommended live recipes
Narrow, explicit allowlists are fastest and least flaky:

13304
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -25,6 +25,15 @@ const CLAUDE_MODEL_ALIASES: Record<string, string> = {
"claude-haiku-3-5": "haiku",
};
const COPILOT_CLI_MODEL_ALIASES: Record<string, string> = {
"gpt-4o": "gpt-4o",
"gpt-4.1": "gpt-4.1",
"gpt-4.1-mini": "gpt-4.1-mini",
"gpt-4-turbo": "gpt-4-turbo",
"claude-sonnet-4-5": "claude-sonnet-4-5",
"claude-opus-4-5": "claude-opus-4-5",
};
const DEFAULT_CLAUDE_BACKEND: CliBackendConfig = {
command: "claude",
args: ["-p", "--output-format", "json", "--dangerously-skip-permissions"],
@ -74,6 +83,19 @@ const DEFAULT_CODEX_BACKEND: CliBackendConfig = {
serialize: true,
};
const DEFAULT_COPILOT_CLI_BACKEND: CliBackendConfig = {
command: "copilot",
args: ["-p"],
resumeArgs: ["-p", "--resume", "{sessionId}"],
output: "text",
input: "arg",
modelArg: "--model",
modelAliases: COPILOT_CLI_MODEL_ALIASES,
sessionIdFields: ["session_id", "sessionId"],
sessionMode: "existing",
serialize: true,
};
function normalizeBackendKey(key: string): string {
return normalizeProviderId(key);
}
@ -107,6 +129,7 @@ export function resolveCliBackendIds(cfg?: MoltbotConfig): Set<string> {
const ids = new Set<string>([
normalizeBackendKey("claude-cli"),
normalizeBackendKey("codex-cli"),
normalizeBackendKey("copilot-cli"),
]);
const configured = cfg?.agents?.defaults?.cliBackends ?? {};
for (const key of Object.keys(configured)) {
@ -135,6 +158,12 @@ export function resolveCliBackendConfig(
if (!command) return null;
return { id: normalized, config: { ...merged, command } };
}
if (normalized === "copilot-cli") {
const merged = mergeBackendConfig(DEFAULT_COPILOT_CLI_BACKEND, override);
const command = merged.command?.trim();
if (!command) return null;
return { id: normalized, config: { ...merged, command } };
}
if (!override) return null;
const command = override.command?.trim();

View File

@ -29,6 +29,7 @@ const DEFAULT_CODEX_ARGS = [
"read-only",
"--skip-git-repo-check",
];
const DEFAULT_COPILOT_CLI_ARGS = ["-p"];
const DEFAULT_CLEAR_ENV = ["ANTHROPIC_API_KEY", "ANTHROPIC_API_KEY_OLD"];
function randomImageProbeCode(len = 6): string {
@ -216,7 +217,9 @@ describeLive("gateway live (cli backend)", () => {
? { command: "claude", args: DEFAULT_CLAUDE_ARGS }
: providerId === "codex-cli"
? { command: "codex", args: DEFAULT_CODEX_ARGS }
: null;
: providerId === "copilot-cli"
? { command: "copilot", args: DEFAULT_COPILOT_CLI_ARGS }
: null;
const cliCommand = process.env.CLAWDBOT_LIVE_CLI_BACKEND_COMMAND ?? providerDefaults?.command;
if (!cliCommand) {