{"id":47681641,"url":"https://github.com/hsaghir/copilot-lm-proxy","last_synced_at":"2026-04-02T14:01:22.755Z","repository":{"id":346967446,"uuid":"1192348546","full_name":"hsaghir/copilot-lm-proxy","owner":"hsaghir","description":"Access GitHub Copilot's LLMs (GPT, Claude, Gemini) from Python scripts. Zero dependencies. OpenAI-compatible API.","archived":false,"fork":false,"pushed_at":"2026-03-26T08:09:53.000Z","size":79,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-03-27T02:07:38.943Z","etag":null,"topics":["claude","copilot","gemini","github-copilot","gpt","llm","openai","proxy","python","vscode-extension"],"latest_commit_sha":null,"homepage":"https://github.com/hsaghir/copilot-proxy#readme","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hsaghir.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-26T05:59:15.000Z","updated_at":"2026-03-26T08:09:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hsaghir/copilot-lm-proxy","commit_stats":null,"previous_names":["hsaghir/copilot-proxy"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/hsaghir/copilot-lm-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsaghir%2Fcopilot-lm-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsaghir%2Fcopilot-lm-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsaghir%2Fcopilot-lm-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsaghir%2Fcopilot-lm-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hsaghir","download_url":"https://codeload.github.com/hsaghir/copilot-lm-proxy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsaghir%2Fcopilot-lm-proxy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31074726,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-28T00:48:58.392Z","status":"ssl_error","status_checked_at":"2026-03-28T00:48:40.933Z","response_time":164,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude","copilot","gemini","github-copilot","gpt","llm","openai","proxy","python","vscode-extension"],"created_at":"2026-04-02T14:00:44.738Z","updated_at":"2026-04-02T14:01:22.737Z","avatar_url":"https://github.com/hsaghir.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Copilot LM Proxy\n\n[![CI](https://github.com/hsaghir/copilot-lm-proxy/actions/workflows/ci.yml/badge.svg)](https://github.com/hsaghir/copilot-lm-proxy/actions/workflows/ci.yml)\n[![PyPI](https://img.shields.io/pypi/v/copilot-lm-proxy)](https://pypi.org/project/copilot-lm-proxy/)\n[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nAccess 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.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/demo.svg\" alt=\"Copilot Proxy Demo\" width=\"700\"\u003e\n\u003c/p\u003e\n\n## Prerequisites\n\n- **VS Code** with the **GitHub Copilot** extension (requires a Copilot subscription)\n- **Node.js** (v18+) — for building the VS Code extension\n- **Python 3.10+**\n\n## Quick Start\n\n### One-command install\n\n```bash\ngit clone https://github.com/hsaghir/copilot-lm-proxy.git\ncd copilot-lm-proxy\nmake install\n```\n\nThis builds the VS Code extension, installs it, and installs the Python client. Then reload VS Code (`Ctrl+Shift+P` → \"Reload Window\").\n\n\u003cdetails\u003e\n\u003csummary\u003eManual install (without Make)\u003c/summary\u003e\n\n**1. Install the VS Code extension:**\n\n```bash\ncd vscode-extension\nnpm install\nnpm run compile\nnpx @vscode/vsce package --allow-missing-repository\ncode --install-extension copilot-lm-proxy.vsix\n```\n\nReload VS Code. The proxy starts automatically on `http://127.0.0.1:19823`.\n\n**2. Install the Python client:**\n\n```bash\npip install -e .\n# or with uv:\nuv pip install -e .\n```\n\n\u003c/details\u003e\n\n### Verify it works\n\n```python\nfrom copilot_proxy import ask\nprint(ask(\"Hello!\"))\n```\n\n## Usage\n\n### Python Client (zero dependencies)\n\n```python\nfrom copilot_proxy import ask, chat, list_models\n\n# Simple question (uses default model)\nresponse = ask(\"Explain neural networks\")\n\n# Use a specific model\nresponse = ask(\"Explain quantum computing\", model=\"gpt-4.1\")\n\n# Multi-turn conversation\nresponse = chat([\n    {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n    {\"role\": \"user\", \"content\": \"What is 2+2?\"}\n], model=\"claude-sonnet-4\")\n\n# List all available models\nfor m in list_models():\n    print(f\"  {m['id']} ({m['vendor']})\")\n```\n\n### Async Python Client\n\n`AsyncCopilotClient` is a drop-in async replacement for `CopilotClient`, ideal for\nasync frameworks such as **FastAPI**, **aiohttp**, or any `asyncio`-based application.\nAll I/O runs in a thread-pool executor via `asyncio.to_thread` — zero extra dependencies.\n\n```python\nimport asyncio\nfrom copilot_proxy import AsyncCopilotClient\n\nasync def main():\n    client = AsyncCopilotClient()\n\n    # 1. Single question — awaitable, never blocks the event loop\n    answer = await client.ask(\"Explain neural networks in one sentence\")\n    print(answer)\n\n    # 2. Multi-turn conversation (non-streaming)\n    response = await client.chat([\n        {\"role\": \"system\", \"content\": \"You are a concise assistant.\"},\n        {\"role\": \"user\", \"content\": \"What is the capital of France?\"},\n    ], model=\"gpt-4.1\")\n    print(response)\n\n    # 3. Streaming output — async for over chunks as they arrive\n    async for chunk in await client.chat(\n        [{\"role\": \"user\", \"content\": \"Count to five.\"}],\n        stream=True,\n    ):\n        print(chunk, end=\"\", flush=True)\n    print()\n\n    # 4. Parallel concurrent requests — the primary value of the async client\n    prompts = [\n        \"Summarise the Python GIL in one sentence.\",\n        \"What is asyncio.gather?\",\n        \"Name one benefit of async/await.\",\n    ]\n    results = await asyncio.gather(*[client.ask(p) for p in prompts])\n    for prompt, result in zip(prompts, results):\n        print(f\"Q: {prompt}\\nA: {result}\\n\")\n\nasyncio.run(main())\n```\n\n**FastAPI example** — serve Copilot responses without blocking request handlers:\n\n```python\nfrom fastapi import FastAPI\nfrom copilot_proxy import AsyncCopilotClient\n\napp = FastAPI()\nclient = AsyncCopilotClient()\n\n@app.get(\"/ask\")\nasync def ask_endpoint(prompt: str) -\u003e dict:\n    answer = await client.ask(prompt)\n    return {\"answer\": answer}\n```\n\n### OpenAI Python Client (drop-in compatible)\n\n```python\nfrom openai import OpenAI\n\nclient = OpenAI(base_url=\"http://127.0.0.1:19823/v1\", api_key=\"dummy\")\n\nresponse = client.chat.completions.create(\n    model=\"gpt-4.1\",\n    messages=[{\"role\": \"user\", \"content\": \"Hello!\"}]\n)\nprint(response.choices[0].message.content)\n\n# Streaming\nfor chunk in client.chat.completions.create(\n    model=\"gpt-4.1\",\n    messages=[{\"role\": \"user\", \"content\": \"Tell me a joke\"}],\n    stream=True\n):\n    print(chunk.choices[0].delta.content or \"\", end=\"\")\n```\n\n### HTTP API (curl)\n\n```bash\n# List models\ncurl http://127.0.0.1:19823/v1/models\n\n# Chat completion\ncurl http://127.0.0.1:19823/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\": \"gpt-4.1\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}]}'\n```\n\n## Available Models\n\nWith 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:\n\n| Model | ID |\n|-------|-----|\n| GPT-4.1 | `gpt-4.1` |\n| GPT-5.1 | `gpt-5.1` |\n| GPT-5.4 | `gpt-5.4` |\n| GPT-4o | `gpt-4o` |\n| Claude Sonnet 4.6 | `claude-sonnet-4.6` |\n| Claude Opus 4.6 | `claude-opus-4.6` |\n| Claude Haiku 4.5 | `claude-haiku-4.5` |\n| Gemini 2.5 Pro | `gemini-2.5-pro` |\n| Gemini 3 Pro | `gemini-3-pro-preview` |\n\n## Structured Output with Pydantic\n\n```bash\npip install copilot-lm-proxy[pydantic]\n```\n\n```python\nfrom pydantic import BaseModel\nfrom copilot_proxy import ask\nimport json\n\nclass MovieReview(BaseModel):\n    title: str\n    rating: float\n    summary: str\n\nschema = MovieReview.model_json_schema()\nprompt = f\"Review Inception. Return JSON matching this schema: {json.dumps(schema)}\"\n\nresponse = ask(prompt, model=\"gpt-4.1\")\nreview = MovieReview.model_validate_json(response)\n```\n\n## Configuration\n\nThe proxy uses sensible defaults but everything is configurable:\n\n| Setting | Default | How to change |\n|---------|---------|---------------|\n| Proxy port | `19823` | VS Code: `Settings → Copilot Proxy → Port` |\n| Python base URL | `http://127.0.0.1:19823` | Env var `COPILOT_PROXY_URL` or `CopilotClient(base_url=...)` |\n\n## Error Handling\n\n```python\nfrom copilot_proxy import ask, ProxyConnectionError, ModelNotFoundError\n\ntry:\n    result = ask(\"Hello\", model=\"gpt-4.1\")\nexcept ProxyConnectionError:\n    print(\"Proxy not running — reload VS Code\")\nexcept ModelNotFoundError:\n    print(\"Model not available\")\n```\n\n## Troubleshooting\n\n| Problem | Fix |\n|---------|-----|\n| `Connection refused` on port 19823 | Reload VS Code. Check Output → \"Copilot Proxy\" panel. |\n| `EADDRINUSE: address already in use` | `lsof -ti:19823 \\| xargs kill -9` then reload VS Code. |\n| Empty responses | Make sure you're signed into GitHub Copilot in VS Code. |\n| `No models available` | Open Copilot Chat in VS Code first to initialize the session. |\n| Model returns empty but `gpt-4o` works | Try specifying a different model — not all models are available in all regions. |\n\n## Development\n\n```bash\npip install -e \".[dev]\"      # install with test deps\npytest tests/test_client.py -v  # unit tests (no proxy needed)\npytest -v                       # all tests (proxy must be running)\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhsaghir%2Fcopilot-lm-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhsaghir%2Fcopilot-lm-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhsaghir%2Fcopilot-lm-proxy/lists"}