Amplifier GitHub Copilot Provider Module

June 22, 2026 · View on GitHub

GitHub Copilot SDK integration for Amplifier — provides access to Anthropic, OpenAI, and Google models via your GitHub Copilot plan.

Prerequisites

  • Python 3.11+
  • GitHub Copilot plan — Free, Pro, Pro+, Business, or Enterprise
  • UV (optional) — Fast Python package manager (pip works too)

Installing UV

# macOS/Linux/WSL
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

No Node.js required. The Copilot SDK binary is bundled with the Python package and discovered automatically.

Purpose

Provides access to Anthropic Claude, OpenAI GPT, and Google Gemini models as an LLM provider for Amplifier, using the GitHub Copilot SDK. Model availability reflects your GitHub Copilot plan — models are discovered dynamically at runtime.

Authentication

Set a GitHub token as an environment variable. The provider checks these in order (first non-empty wins):

PriorityVariableUse case
1COPILOT_AGENT_TOKENCopilot agent mode
2COPILOT_GITHUB_TOKENRecommended for direct use
3GH_TOKENGitHub CLI compatible
4GITHUB_TOKENGitHub Actions compatible

Linux/macOS:

export GITHUB_TOKEN=$(gh auth token)

Windows PowerShell:

$env:GITHUB_TOKEN = (gh auth token)

One command to bridge your existing gh CLI authentication into Amplifier.

Tip: Many developers already have gh CLI authenticated — if so, this is the fastest path to get started.

Option 2: Direct token

Linux/macOS:

export GITHUB_TOKEN="<YOUR_TOKEN_HERE>"

Windows PowerShell:

$env:GITHUB_TOKEN = "<YOUR_TOKEN_HERE>"

Use a GitHub Personal Access Token directly.

Installation

Linux/macOS:

# 1. Set token (if using gh CLI)
export GITHUB_TOKEN=$(gh auth token)

# 2. Install provider (includes SDK)
amplifier provider install github-copilot

# 3. Configure
amplifier init

Windows PowerShell:

# 1. Set token (if using gh CLI)
$env:GITHUB_TOKEN = (gh auth token)

# 2. Install provider (includes SDK)
amplifier provider install github-copilot

# 3. Configure
amplifier init

Tip: For permanent token setup:

  • Linux: Add export GITHUB_TOKEN=$(gh auth token) to ~/.bashrc
  • macOS: Add export GITHUB_TOKEN=$(gh auth token) to ~/.zshrc
  • Windows: Add $env:GITHUB_TOKEN = (gh auth token) to your PowerShell profile ($PROFILE)

Bundle reference

Reference the provider directly from a bundle YAML using a branch or commit SHA:

providers:
  - module: provider-github-copilot
    source: git+https://github.com/microsoft/amplifier-module-provider-github-copilot@main
    config:
      default_model: claude-opus-4.5

Usage

# Interactive session
amplifier run -p github-copilot

# One-shot prompt
amplifier run -p github-copilot -m claude-sonnet-4.6 "Explain this codebase"

# List available models
amplifier provider models github-copilot

Supported Models

Models are discovered dynamically from the SDK at runtime — the list reflects your GitHub Copilot plan. The tables below show the current public set as of SDK 1.0.2; run amplifier provider models github-copilot for the live list.

Routing:

Model IDContextMax OutputCapabilities
auto128k16kstreaming, tools

Anthropic:

Model IDContextMax OutputCapabilities
claude-opus-4.81M64kstreaming, tools, vision, thinking
claude-opus-4.71M64kstreaming, tools, vision, thinking
claude-opus-4.61M64kstreaming, tools, vision, thinking
claude-opus-4.5200k32kstreaming, tools, vision
claude-sonnet-4.61M64kstreaming, tools, vision, thinking
claude-sonnet-4.5200k32kstreaming, tools, vision
claude-haiku-4.5200k64kstreaming, tools, vision

OpenAI:

Model IDContextMax OutputCapabilities
gpt-5.51.05M128kstreaming, tools, vision, thinking
gpt-5.41.05M128kstreaming, tools, vision, thinking
gpt-5.3-codex400k128kstreaming, tools, vision, thinking
gpt-5.4-mini400k128kstreaming, tools, vision, thinking
gpt-5-mini264k136kstreaming, tools, vision, thinking

Google:

Model IDContextMax OutputCapabilities
gemini-3.1-pro-preview1M64kstreaming, tools, vision, thinking
gemini-3.5-flash1M64kstreaming, tools, vision, thinking

MAI:

Model IDContextMax OutputCapabilities
mai-code-1-flash-internal256k128kstreaming, tools, thinking

Tip: Want intelligent model selection? Use the Routing Matrix bundle to select models by semantic role (coding, reasoning, fast) rather than hardcoding a model ID.

Configuration

The provider runs with sensible defaults. Set values in the config block of your bundle YAML:

providers:
  - module: provider-github-copilot
    name: github-copilot
    config:
      default_model: claude-opus-4.5
KeyDefaultDescription
default_model"claude-opus-4.5"Model used when the caller does not specify one. Any ID from list_models() is valid.
rawfalseInclude raw SDK payloads as a "raw" field in llm:request / llm:response events. See Raw Payload Logging.

Raw Payload Logging

Set raw: true to capture the exact data exchanged with the Copilot SDK before any processing:

providers:
  - module: provider-github-copilot
    config:
      raw: true

When enabled, the standard llm:request and llm:response events include an additional "raw" field containing the complete, redacted payload:

Event"raw" field contains
llm:requestComplete request payload sent to the SDK (model, prompt, tools, system message)
llm:responseComplete response object returned by the SDK

Raw payloads pass through redact_dict() — tokens and credentials are scrubbed before the field is added to the event.

Warning: Raw events contain the full conversation content including tool definitions and system messages. Use only for deep provider integration debugging. Disable in production to avoid high log volume and potential data exposure.

Note: Accepts true/false (bool) or strings "true", "1", "yes" (truthy) / anything else (falsy). The string "false" is correctly treated as disabled — bool("false") == True is a Python footgun that _parse_raw_flag guards against.

Retry and Error Handling

The provider manages its own retry loop, giving full control over backoff timing, per-error-class behaviour, and Retry-After header honoring.

Error Translation

All errors are translated to typed kernel error types before the retry loop evaluates them. Every translated error preserves the original as __cause__.

TriggerKernel ErrorRetryable
Circuit breaker openProviderUnavailableErrorNo
Authentication or permission failureAuthenticationErrorNo
Rate limit (429)RateLimitErrorYes
Quota or billing limit exceededQuotaExceededErrorNo
Request timed outLLMTimeoutErrorYes
Content policy violationContentFilterErrorNo
Connection refused or unreachableProviderUnavailableErrorYes
SDK process exited unexpectedlyNetworkErrorYes
Model not foundNotFoundErrorNo
Context window exceededContextLengthErrorNo
Stream interruptedStreamErrorYes
Malformed or conflicting tool callInvalidToolCallErrorNo
Provider configuration errorConfigurationErrorNo
Request aborted or cancelledAbortErrorNo
Session lifecycle failureProviderUnavailableErrorYes
Invalid request body (e.g. unsupported image format)InvalidRequestErrorNo
Any other errorProviderUnavailableErrorNo

RateLimitError responses carry a Retry-After value; if present, it is used directly as the next retry delay (overriding the backoff formula).

Backoff Formula

Each retry delay is computed as follows. attempt is 0-indexed0 is the first retry:

$ \text{delay} = \text{min}(\text{base\_delay} \times 2^\text{attempt}, \text{max\_delay}) # \text{attempt} = 0, 1, 2, … \text{jitter} = \text{delay} \times \text{jitter\_factor} \times \text{random}(−1, 1) \text{sleep} = \text{max}(0, \text{delay} + \text{jitter}) $

Attempt (0-indexed)BaseCappedWith jitter (±10%)
0 (first retry)1 s1 s0.9 – 1.1 s
12 s2 s1.8 – 2.2 s
24 s4 s3.6 – 4.4 s

Example: Overloaded signal (10× multiplier, defaults)

When a RateLimitError carries delay_multiplier > 1.0 (set by the provider on overloaded responses), the base delay (after capping, with jitter) is multiplied. Default overloaded_delay_multiplier is `10.0$:

\text{Attempt}\text{base_delay}\text{capped}\times 10\text{Sleep} \text{range} (±10%)
0 (\text{first} \text{retry})1 \text{s}1 \text{s}10 \text{s}9 – 11 \text{s}
12 \text{s}2 \text{s}20 \text{s}18 – 22 \text{s}

\text{With} \text{default} $max_retries: 2, total wait is ≈ 30 s before the request is abandoned. Retry-After` from the server header always takes precedence over the multiplied delay.

Retry Configuration

Retry parameters can be overridden via bundle config. All keys are optional; omitted keys use the defaults shown.

Config KeyDefaultDescription
max_retries2Number of retries after the first attempt (0 = fail fast, single attempt)
min_retry_delay1.0Minimum base delay in seconds (doubles each attempt)
max_retry_delay30.0Maximum delay cap in seconds before jitter is applied
retry_jitter0.1Jitter fraction applied as ± of the capped delay (0.01.0)
overloaded_delay_multiplier10.0Multiplier applied to backoff when an overloaded signal is present (e.g. RateLimitError with delay_multiplier > 1.0); Retry-After still takes precedence. Must be >= 1.0 — values below 1.0 are rejected at construction and fall back to 1.0.

Retry Events

A provider:retry event is emitted before each retry sleep:

FieldDescription
providerProvider name ("github-copilot")
modelModel being called
attemptCurrent attempt number (1-based in event payload)
max_retriesTotal attempt count including the initial call (max_retries + 1); e.g. with max_retries: 2 configured, the event emits 3
delayComputed sleep duration in seconds
retry_afterServer Retry-After value in seconds, or null
error_typeKernel error class name (e.g. RateLimitError)
error_messageSanitized error description

error_message is passed through redact_sensitive_text() before emission — tokens and credentials are never leaked into events.

Observability

The provider emits three event types via the Amplifier hook system:

llm:request

Emitted immediately before the SDK call.

FieldTypeDescription
providerstring"github-copilot"
modelstringModel ID used for this request
message_countintNumber of messages in the conversation
tool_countintNumber of tools available
streamingboolWhether streaming is enabled (default: true)
timeoutfloatRequest timeout in seconds

llm:response

Emitted after the SDK call completes (success or error).

FieldTypeDescription
providerstring"github-copilot"
modelstringModel ID
statusstring"ok" or "error"
duration_msintWall-clock time in milliseconds
usageobject{"input": int, "output": int} token counts
finish_reasonstring"stop", "tool_calls", "length", "content_filter", "end_turn"
content_blocksintNumber of content blocks in the response
tool_callsintNumber of structured tool calls returned
sdk_session_idstring (optional)Copilot SDK session ID for log correlation
sdk_pidstring (optional)SDK process identifier for log correlation

On error: status, error_type, error_message (redacted), duration_ms.

provider:retry

See Retry Events above.

Features

  • Streaming support (always on; llm:request event reflects this)
  • Tool use (function calling)
  • Extended thinking (on supported models)
  • Vision capabilities (on supported models)
  • Token counting and management
  • Prompt injection prevention — role-marker sequences ([USER], [SYSTEM], etc.) in user content and tool call IDs are escaped before the request reaches the SDK
  • Tool sequence repair — orphaned tool calls are automatically repaired with synthetic results before LLM submission (see Tool Sequence Repair)
  • All log output and observability events pass through secret redaction (tokens, Bearer headers, GitHub token formats, API keys, JWTs, PEM blocks)
  • Raw payload logging — full SDK request/response capture for deep debugging (see Raw Payload Logging)

Contract

FieldValue
Module TypeProvider
Module IDprovider-github-copilot
Provider Namegithub-copilot
Mount Pointproviders
Entry Pointamplifier_module_provider_github_copilot:mount
Source URIgit+https://github.com/microsoft/amplifier-module-provider-github-copilot@main

Architecture

The provider uses a singleton SDK client shared across all instances, with ephemeral sessions created per complete() call and destroyed after each request. Tool execution remains the orchestrator's responsibility — the provider never executes tools directly.

For module structure, design decisions, and contract index see docs/ARCHITECTURE.md.

Graceful Error Recovery

The provider translates all SDK errors to typed kernel errors before they reach the caller. Each complete() call uses an independent session — no state accumulates between requests. The shared client and disk model cache persist across requests by design.

On list_models() failure, the provider falls back to a disk cache (24-hour TTL) before raising ProviderUnavailableError.

Tool Sequence Repair

The provider automatically detects and repairs incomplete tool call sequences before sending the request to the LLM.

The Problem: If a conversation history contains a tool call from the assistant that has no corresponding tool result (due to context compaction bugs, parsing errors, or state corruption), the LLM receives an incoherent message history and may produce confused or repetitive responses. The missing result is invisible to the caller.

The Solution: Before prompt extraction, the provider scans assistant messages for tool call blocks without matching tool results. For each unmatched call, a synthetic tool-result message is inserted immediately after the offending assistant message. The LLM receives a coherent history and can acknowledge the gap and continue.

What happens:

  1. Orphaned tool calls are detected (by tool_call_id set-difference)
  2. A synthetic user message containing a tool_result block is inserted after each offending assistant message
  3. One WARNING is logged per repair event with the count of repaired calls
  4. Prompt extraction proceeds on the repaired message list; the original request is not mutated

Synthetic result content:

Tool result unavailable — the result for this tool call was lost. Please acknowledge this and continue.

Example:

# Incoming messages (tool result missing)
messages = [
    {"role": "user",      "content": "Search for Python"},
    {"role": "assistant", "content": [{"type": "tool_call", "tool_call_id": "call-abc", "tool_name": "search"}]},
    # MISSING: tool_result for call-abc
    {"role": "user",      "content": "What did you find?"}
]

# After repair, the assistant message is followed by a synthetic result:
# {"role": "user", "content": [{"type": "tool_result", "tool_call_id": "call-abc",
#                                "output": "Tool result unavailable — ..."}]}

Observability: Repairs are logged as WARNING via the module logger. Monitor for "Malformed tool sequence repaired" log lines to detect upstream context management issues.

Security: tool_call_id values are sanitized through the same injection-prevention pipeline as user content before they are interpolated into the prompt. Role-marker sequences such as [SYSTEM] in a crafted ID are escaped automatically.

Fake Tool Call Detection

LLMs occasionally emit tool calls as plain text instead of using the structured calling mechanism. The provider detects and automatically corrects this before returning a response.

Detection only fires when the request included tools and the response contains no structured tool calls. Up to 2 correction attempts are made; if the model still does not use structured tool calls, the last response is returned as-is.

Environment Variables

VariableDescription
COPILOT_AGENT_TOKENGitHub token — Copilot agent mode (highest priority)
COPILOT_GITHUB_TOKENGitHub token — recommended for direct use
GH_TOKENGitHub token — GitHub CLI compatible
GITHUB_TOKENGitHub token — GitHub Actions compatible
COPILOT_SDK_LOG_LEVELSDK log verbosity: none, error, warning, info (default), debug, all

Warning: debug and all produce high-volume output including sensitive conversation data. Use only for targeted SDK debugging.

Development

Setup

cd amplifier-module-provider-github-copilot

# Install dependencies (using UV)
uv sync --extra dev

# Or using pip
pip install -e ".[dev]"

Testing

make test          # Run unit tests (excludes live API calls)
make live          # Run live integration tests (requires GITHUB_TOKEN)
make coverage      # Run with branch coverage report
make check         # Full check (lint + test)
make smoke         # Quick E2E smoke test (seconds)

Live Integration Tests

Live tests make real API calls and require valid GitHub Copilot authentication:

export GITHUB_TOKEN=$(gh auth token)
make live

Or run directly:

python -m pytest tests/ -m live -v --tb=short

On Windows PowerShell:

$env:GITHUB_TOKEN = (gh auth token)
python -m pytest tests/ -m live -v --tb=short

Project Status

Experimental. Breaking changes may occur without deprecation notice. For questions open a Discussion; for bugs open an Issue.

Troubleshooting

ErrorCauseSolution
Copilot SDK not installedProvider module not installedRun amplifier provider install github-copilot
Not authenticated to GitHub CopilotToken not setLinux/macOS: export GITHUB_TOKEN=$(gh auth token) Windows: $env:GITHUB_TOKEN = (gh auth token)
gh: command not foundGitHub CLI missingInstall gh CLI
Stale or wrong model listCached modelsDelete models_cache.json from your cache directory: %LOCALAPPDATA%\amplifier-provider-github-copilot\Cache\ (Windows), ~/Library/Caches/amplifier-provider-github-copilot/ (macOS), or ~/.cache/amplifier-provider-github-copilot/ (Linux).
Permission denied on SDK binaryuv stripped execute bitsProvider auto-repairs on startup; if it fails, run chmod +x <path-to-copilot-binary> (Linux/macOS only)

Common Mistake

Running amplifier init before authentication:

Linux/macOS:

 amplifier init                         # Fails with auth error
 export GITHUB_TOKEN=$(gh auth token)   # Set token first
 amplifier provider install github-copilot
 amplifier init                         # Now works

Windows PowerShell:

❌ amplifier init                              # Fails with auth error
✅ $env:GITHUB_TOKEN = (gh auth token)        # Set token first
✅ amplifier provider install github-copilot
✅ amplifier init                              # Now works

Dependencies

  • amplifier-core (provided by Amplifier runtime, not installed separately)
  • github-copilot-sdk==1.0.2
  • pyyaml>=6.0

Note: github-copilot-sdk is installed automatically when you install or initialize the provider via Amplifier (amplifier provider install github-copilot or amplifier init). It is not bundled with the main amplifier package.

Contributing

Note

This project is not currently accepting external contributions, but we're actively working toward opening this up. We value community input and look forward to collaborating in the future. For now, feel free to fork and experiment!

Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit Contributor License Agreements.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.