https://github.com/hsaghir/copilot-lm-proxy
Access GitHub Copilot's LLMs (GPT, Claude, Gemini) from Python scripts. Zero dependencies. OpenAI-compatible API.
https://github.com/hsaghir/copilot-lm-proxy
claude copilot gemini github-copilot gpt llm openai proxy python vscode-extension
Last synced: 2 months ago
JSON representation
Access GitHub Copilot's LLMs (GPT, Claude, Gemini) from Python scripts. Zero dependencies. OpenAI-compatible API.
- Host: GitHub
- URL: https://github.com/hsaghir/copilot-lm-proxy
- Owner: hsaghir
- License: mit
- Created: 2026-03-26T05:59:15.000Z (3 months ago)
- Default Branch: master
- Last Pushed: 2026-03-26T08:09:53.000Z (3 months ago)
- Last Synced: 2026-03-27T02:07:38.943Z (3 months ago)
- Topics: claude, copilot, gemini, github-copilot, gpt, llm, openai, proxy, python, vscode-extension
- Language: Python
- Homepage: https://github.com/hsaghir/copilot-proxy#readme
- Size: 77.1 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
Awesome Lists containing this project
README
# Copilot LM Proxy
[](https://github.com/hsaghir/copilot-lm-proxy/actions/workflows/ci.yml)
[](https://pypi.org/project/copilot-lm-proxy/)
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/MIT)
Access GitHub Copilot's LLM models (GPT-4.1, GPT-5.x, Claude, Gemini, and more) from any Python script via a local HTTP server. Works with the standard OpenAI Python client. Zero dependencies.
## Prerequisites
- **VS Code** with the **GitHub Copilot** extension (requires a Copilot subscription)
- **Node.js** (v18+) — for building the VS Code extension
- **Python 3.10+**
## Quick Start
### One-command install
```bash
git clone https://github.com/hsaghir/copilot-lm-proxy.git
cd copilot-lm-proxy
make install
```
This builds the VS Code extension, installs it, and installs the Python client. Then reload VS Code (`Ctrl+Shift+P` → "Reload Window").
Manual install (without Make)
**1. Install the VS Code extension:**
```bash
cd vscode-extension
npm install
npm run compile
npx @vscode/vsce package --allow-missing-repository
code --install-extension copilot-lm-proxy.vsix
```
Reload VS Code. The proxy starts automatically on `http://127.0.0.1:19823`.
**2. Install the Python client:**
```bash
pip install -e .
# or with uv:
uv pip install -e .
```
### Verify it works
```python
from copilot_proxy import ask
print(ask("Hello!"))
```
## Usage
### Python Client (zero dependencies)
```python
from copilot_proxy import ask, chat, list_models
# Simple question (uses default model)
response = ask("Explain neural networks")
# Use a specific model
response = ask("Explain quantum computing", model="gpt-4.1")
# Multi-turn conversation
response = chat([
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is 2+2?"}
], model="claude-sonnet-4")
# List all available models
for m in list_models():
print(f" {m['id']} ({m['vendor']})")
```
### Async Python Client
`AsyncCopilotClient` is a drop-in async replacement for `CopilotClient`, ideal for
async frameworks such as **FastAPI**, **aiohttp**, or any `asyncio`-based application.
All I/O runs in a thread-pool executor via `asyncio.to_thread` — zero extra dependencies.
```python
import asyncio
from copilot_proxy import AsyncCopilotClient
async def main():
client = AsyncCopilotClient()
# 1. Single question — awaitable, never blocks the event loop
answer = await client.ask("Explain neural networks in one sentence")
print(answer)
# 2. Multi-turn conversation (non-streaming)
response = await client.chat([
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "What is the capital of France?"},
], model="gpt-4.1")
print(response)
# 3. Streaming output — async for over chunks as they arrive
async for chunk in await client.chat(
[{"role": "user", "content": "Count to five."}],
stream=True,
):
print(chunk, end="", flush=True)
print()
# 4. Parallel concurrent requests — the primary value of the async client
prompts = [
"Summarise the Python GIL in one sentence.",
"What is asyncio.gather?",
"Name one benefit of async/await.",
]
results = await asyncio.gather(*[client.ask(p) for p in prompts])
for prompt, result in zip(prompts, results):
print(f"Q: {prompt}\nA: {result}\n")
asyncio.run(main())
```
**FastAPI example** — serve Copilot responses without blocking request handlers:
```python
from fastapi import FastAPI
from copilot_proxy import AsyncCopilotClient
app = FastAPI()
client = AsyncCopilotClient()
@app.get("/ask")
async def ask_endpoint(prompt: str) -> dict:
answer = await client.ask(prompt)
return {"answer": answer}
```
### OpenAI Python Client (drop-in compatible)
```python
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:19823/v1", api_key="dummy")
response = client.chat.completions.create(
model="gpt-4.1",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
# Streaming
for chunk in client.chat.completions.create(
model="gpt-4.1",
messages=[{"role": "user", "content": "Tell me a joke"}],
stream=True
):
print(chunk.choices[0].delta.content or "", end="")
```
### HTTP API (curl)
```bash
# List models
curl http://127.0.0.1:19823/v1/models
# Chat completion
curl http://127.0.0.1:19823/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "gpt-4.1", "messages": [{"role": "user", "content": "Hello!"}]}'
```
## Available Models
With a GitHub Copilot subscription you get access to many models. Run `list_models()` or `curl http://127.0.0.1:19823/v1/models` to see all. Common ones:
| Model | ID |
|-------|-----|
| GPT-4.1 | `gpt-4.1` |
| GPT-5.1 | `gpt-5.1` |
| GPT-5.4 | `gpt-5.4` |
| GPT-4o | `gpt-4o` |
| Claude Sonnet 4.6 | `claude-sonnet-4.6` |
| Claude Opus 4.6 | `claude-opus-4.6` |
| Claude Haiku 4.5 | `claude-haiku-4.5` |
| Gemini 2.5 Pro | `gemini-2.5-pro` |
| Gemini 3 Pro | `gemini-3-pro-preview` |
## Structured Output with Pydantic
```bash
pip install copilot-lm-proxy[pydantic]
```
```python
from pydantic import BaseModel
from copilot_proxy import ask
import json
class MovieReview(BaseModel):
title: str
rating: float
summary: str
schema = MovieReview.model_json_schema()
prompt = f"Review Inception. Return JSON matching this schema: {json.dumps(schema)}"
response = ask(prompt, model="gpt-4.1")
review = MovieReview.model_validate_json(response)
```
## Configuration
The proxy uses sensible defaults but everything is configurable:
| Setting | Default | How to change |
|---------|---------|---------------|
| Proxy port | `19823` | VS Code: `Settings → Copilot Proxy → Port` |
| Python base URL | `http://127.0.0.1:19823` | Env var `COPILOT_PROXY_URL` or `CopilotClient(base_url=...)` |
## Error Handling
```python
from copilot_proxy import ask, ProxyConnectionError, ModelNotFoundError
try:
result = ask("Hello", model="gpt-4.1")
except ProxyConnectionError:
print("Proxy not running — reload VS Code")
except ModelNotFoundError:
print("Model not available")
```
## Troubleshooting
| Problem | Fix |
|---------|-----|
| `Connection refused` on port 19823 | Reload VS Code. Check Output → "Copilot Proxy" panel. |
| `EADDRINUSE: address already in use` | `lsof -ti:19823 \| xargs kill -9` then reload VS Code. |
| Empty responses | Make sure you're signed into GitHub Copilot in VS Code. |
| `No models available` | Open Copilot Chat in VS Code first to initialize the session. |
| Model returns empty but `gpt-4o` works | Try specifying a different model — not all models are available in all regions. |
## Development
```bash
pip install -e ".[dev]" # install with test deps
pytest tests/test_client.py -v # unit tests (no proxy needed)
pytest -v # all tests (proxy must be running)
```
See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
## License
MIT