Merge pull request #2 from htekdev/copilot/add-github-copilot-cli-integration

Add GitHub Copilot CLI as a built-in CLI backend
This commit is contained in:
Hector Flores 2026-01-28 16:59:53 -06:00 committed by GitHub
commit b55b7315a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 273 additions and 6 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@ docker-compose.extra.yml
dist
*.bun-build
pnpm-lock.yaml
package-lock.json
bun.lock
bun.lockb
coverage

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-4.1
```
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,189 @@
---
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 account** (free tier works for `gpt-4.1`)
- **GitHub CLI** (`gh`) authenticated with your GitHub account
Note: `gpt-4.1` is available on the free GitHub tier. Other models like `gpt-4o`, `claude-sonnet-4-5`,
and `claude-opus-4-5` require a paid GitHub Copilot subscription.
## Installation
Install the Copilot CLI via npm:
```bash
npm install -g @github/copilot
```
Or via Homebrew:
```bash
brew install github/copilot/copilot
```
Verify installation:
```bash
copilot --help
```
## Quick start
Use Copilot CLI directly with Moltbot:
```bash
moltbot agent --message "hi" --model copilot-cli/gpt-4.1
```
## 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-4.1",
fallbacks: [
"copilot-cli/gpt-4.1"
]
},
models: {
"github-copilot/gpt-4.1": { alias: "Copilot" },
"copilot-cli/gpt-4.1": {}
}
}
}
}
```
## Supported models
Copilot CLI supports these models (availability depends on your GitHub plan):
**Free tier (GitHub Free):**
- `gpt-4.1` ← recommended default
- `gpt-4.1-mini`
**Paid tier (GitHub Copilot subscription):**
- `gpt-4o`
- `gpt-4-turbo`
- `claude-sonnet-4-5`
- `claude-opus-4-5`
Example model refs:
```
copilot-cli/gpt-4.1
copilot-cli/gpt-4.1-mini
copilot-cli/gpt-4o
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

@ -50,21 +50,21 @@ moltbot models auth login-github-copilot --yes
## Set a default model
```bash
moltbot models set github-copilot/gpt-4o
moltbot models set github-copilot/gpt-4.1
```
### Config snippet
```json5
{
agents: { defaults: { model: { primary: "github-copilot/gpt-4o" } } }
agents: { defaults: { model: { primary: "github-copilot/gpt-4.1" } } }
}
```
## Notes
- Requires an interactive TTY; run it directly in a terminal.
- Copilot model availability depends on your plan; if a model is rejected, try
another ID (for example `github-copilot/gpt-4.1`).
- `gpt-4.1` is available on the free GitHub tier. Other models like `gpt-4o` and
Claude models require a paid GitHub Copilot subscription.
- The login stores a GitHub token in the auth profile store and exchanges it for a
Copilot API token when Moltbot runs.

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-4.1"`
- `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,17 @@ 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-4.1" \
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).
`gpt-4.1` is available on the GitHub Free tier; other models require a paid subscription.
### Recommended live recipes
Narrow, explicit allowlists are fastest and least flaky:

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,20 @@ const DEFAULT_CODEX_BACKEND: CliBackendConfig = {
serialize: true,
};
const DEFAULT_COPILOT_CLI_BACKEND: CliBackendConfig = {
command: "copilot",
args: ["--allow-all-tools"],
resumeArgs: ["--allow-all-tools", "--resume", "{sessionId}"],
output: "text",
input: "arg",
promptArg: "-p",
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 +130,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 +159,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

@ -445,7 +445,11 @@ export function buildCliArgs(params: {
}
}
if (params.promptArg !== undefined) {
args.push(params.promptArg);
if (params.backend.promptArg) {
args.push(params.backend.promptArg, params.promptArg);
} else {
args.push(params.promptArg);
}
}
return args;
}

View File

@ -36,6 +36,7 @@ export function isCliProvider(provider: string, cfg?: MoltbotConfig): boolean {
const normalized = normalizeProviderId(provider);
if (normalized === "claude-cli") return true;
if (normalized === "codex-cli") return true;
if (normalized === "copilot-cli") return true;
const backends = cfg?.agents?.defaults?.cliBackends ?? {};
return Object.keys(backends).some((key) => normalizeProviderId(key) === normalized);
}

View File

@ -87,6 +87,8 @@ export type CliBackendConfig = {
imageArg?: string;
/** How to pass multiple images. */
imageMode?: "repeat" | "list";
/** Flag used to pass the prompt (e.g. -p, --prompt). */
promptArg?: string;
/** Serialize runs for this CLI. */
serialize?: boolean;
};

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) {