196 lines
5.3 KiB
Markdown
196 lines
5.3 KiB
Markdown
# copilet2api
|
||
|
||
Cloudflare Worker that proxies **GitHub Copilot** to **OpenAI** and **Anthropic** compatible HTTP APIs.
|
||
|
||
> **Warning:** This uses unofficial Copilot endpoints. GitHub may change or block them at any time. Excessive automated use may trigger abuse detection and limit your Copilot access. Use responsibly.
|
||
|
||
## Features
|
||
|
||
- OpenAI-compatible: `GET /v1/models`, `POST /v1/chat/completions`, `POST /v1/responses` (streaming supported)
|
||
- Models like `gpt-5.4-mini`, `gpt-5.3-codex` auto-route to Copilot **Responses API** when using `/v1/chat/completions`
|
||
- Anthropic-compatible: `POST /v1/messages` (streaming supported)
|
||
- Client auth via API key (default `sk-shumengya666`, configurable via `API_KEY`)
|
||
- GitHub token stored as Worker Secret (`GITHUB_TOKEN`)
|
||
|
||
## Quick start
|
||
|
||
### 1. Install
|
||
|
||
```bash
|
||
npm install
|
||
```
|
||
|
||
### 2. Configure GitHub token (local)
|
||
|
||
```bash
|
||
cp .dev.vars.example .dev.vars
|
||
# Edit .dev.vars and set GITHUB_TOKEN (ghu_, gho_, or github_pat_ with Copilot access)
|
||
```
|
||
|
||
### 3. Run locally
|
||
|
||
```bash
|
||
npm run dev
|
||
```
|
||
|
||
### 4. Deploy
|
||
|
||
```bash
|
||
npx wrangler secret put GITHUB_TOKEN
|
||
npm run deploy
|
||
```
|
||
|
||
Optionally override the client API key in production:
|
||
|
||
```bash
|
||
npx wrangler secret put API_KEY
|
||
```
|
||
|
||
## Authentication
|
||
|
||
Clients must send one of:
|
||
|
||
- `Authorization: Bearer <API_KEY>` (default: `sk-shumengya666`, not shown on `GET /`)
|
||
- `x-api-key: <API_KEY>`
|
||
|
||
Override with `wrangler secret put API_KEY` or `.dev.vars` for production.
|
||
|
||
The Worker uses `GITHUB_TOKEN` (Wrangler secret) to authenticate with Copilot:
|
||
|
||
| Token type | Prefix | How it works |
|
||
|------------|--------|--------------|
|
||
| OAuth (recommended) | `ghu_`, `gho_` | Exchanged via `GET /copilot_internal/v2/token` |
|
||
| Fine-grained PAT | `github_pat_` | Used directly; requires **Copilot Requests** permission; uses `Copilot-Integration-Id: copilot-developer-cli` |
|
||
|
||
Classic PAT (`ghp_`) is **not supported** by the Copilot API.
|
||
|
||
## Endpoints
|
||
|
||
| Method | Path | Description |
|
||
|--------|------|-------------|
|
||
| GET | `/` | Service info |
|
||
| GET | `/health` | Health check |
|
||
| GET | `/v1/models` | List Copilot models |
|
||
| POST | `/v1/chat/completions` | OpenAI chat completions |
|
||
| POST | `/v1/messages` | Anthropic messages |
|
||
|
||
## Usage examples
|
||
|
||
### gpt-5.4-mini / Codex 模型
|
||
|
||
这类模型**不能**走 `/chat/completions` 直连 Copilot,必须用 **Responses API**。本 Worker 已支持两种方式:
|
||
|
||
**方式 1(推荐)**:仍用 Chat Completions,Worker 会自动转发到 `/responses`:
|
||
|
||
```bash
|
||
curl http://localhost:8787/v1/chat/completions \
|
||
-H "Authorization: Bearer $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "gpt-5.4-mini",
|
||
"max_tokens": 256,
|
||
"messages": [{"role": "user", "content": "Hello"}]
|
||
}'
|
||
```
|
||
|
||
**方式 2**:直接调用 OpenAI Responses 格式:
|
||
|
||
```bash
|
||
curl http://localhost:8787/v1/responses \
|
||
-H "Authorization: Bearer $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "gpt-5.4-mini",
|
||
"input": "Hello",
|
||
"max_output_tokens": 256
|
||
}'
|
||
```
|
||
|
||
注意:`max_output_tokens` 最小为 **16**。
|
||
|
||
### 流式 / 工具 / 视觉(gpt-5.4-mini 等)
|
||
|
||
`/v1/chat/completions` 与 `/v1/messages` 均已支持:
|
||
|
||
| 能力 | OpenAI Chat | Anthropic Messages |
|
||
|------|-------------|-------------------|
|
||
| 流式 | `stream: true` | `stream: true` |
|
||
| 工具 | `tools` + `tool_choice` | `tools` + `tool_choice` |
|
||
| 图片 | `image_url` 多模态 content | `image` + `source.base64` / `url` |
|
||
|
||
工具调用时 Chat 返回 `finish_reason: tool_calls`;Claude 返回 `stop_reason: tool_use` 与 `tool_use` 内容块。
|
||
|
||
### curl (OpenAI)
|
||
|
||
```bash
|
||
curl http://localhost:8787/v1/chat/completions \
|
||
-H "Authorization: Bearer $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "gpt-4o",
|
||
"messages": [{"role": "user", "content": "Hello"}]
|
||
}'
|
||
```
|
||
|
||
### curl (Anthropic)
|
||
|
||
```bash
|
||
curl http://localhost:8787/v1/messages \
|
||
-H "Authorization: Bearer $API_KEY" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "claude-sonnet-4",
|
||
"max_tokens": 1024,
|
||
"messages": [{"role": "user", "content": "Hello"}]
|
||
}'
|
||
```
|
||
|
||
### OpenAI Python SDK
|
||
|
||
```python
|
||
from openai import OpenAI
|
||
|
||
client = OpenAI(
|
||
api_key=os.environ["API_KEY"],
|
||
base_url="https://<your-worker>.workers.dev/v1",
|
||
)
|
||
print(client.chat.completions.create(
|
||
model="gpt-4o",
|
||
messages=[{"role": "user", "content": "hi"}],
|
||
))
|
||
```
|
||
|
||
### Anthropic Python SDK
|
||
|
||
```python
|
||
import anthropic
|
||
|
||
client = anthropic.Anthropic(
|
||
api_key=os.environ["API_KEY"],
|
||
base_url="https://<your-worker>.workers.dev",
|
||
)
|
||
print(client.messages.create(
|
||
model="claude-sonnet-4",
|
||
max_tokens=1024,
|
||
messages=[{"role": "user", "content": "hi"}],
|
||
))
|
||
```
|
||
|
||
## Environment variables
|
||
|
||
| Variable | Source | Description |
|
||
|----------|--------|-------------|
|
||
| `API_KEY` | `wrangler.jsonc` vars or secret | Client API key (default `sk-shumengya666`, not exposed on `GET /`) |
|
||
| `GITHUB_TOKEN` | Secret / `.dev.vars` | GitHub OAuth or PAT with Copilot |
|
||
| `COPILOT_API_BASE` | vars (optional) | Default `https://api.githubcopilot.com`; set for Enterprise |
|
||
|
||
## Security notes
|
||
|
||
- Do **not** commit `.dev.vars` or real tokens to git.
|
||
- The default API key is public in `wrangler.jsonc`. For public deployments, set a strong `API_KEY` secret and consider Cloudflare Access or IP restrictions.
|
||
- Anyone with the API key can consume your Copilot quota.
|
||
|
||
## License
|
||
|
||
MIT
|