|
| 1 | +# Qoder OpenAI Proxy |
| 2 | + |
| 3 | +An OpenAI-compatible API wrapper for `qodercli` with built-in dashboard, metrics, and Docker support. |
| 4 | +Use Qoder through any tool or library designed for OpenAI's API. |
| 5 | + |
| 6 | +## Features |
| 7 | + |
| 8 | +- **🔌 OpenAI-Compatible**: Drop-in API replacement for apps like Cursor, Cline, LangChain, and Open WebUI |
| 9 | +- **💬 Full Chat Support**: Support for `/v1/chat/completions` (system messages, multi-turn history) |
| 10 | +- **⚡ Streaming**: Real-time SSE streaming responses without lag |
| 11 | +- **🔄 Intelligent Tier Mapping**: Seamless translation between OpenAI aliases (gpt-4, claude-3.5) and Qoder tiers (auto, ultimate, lite) |
| 12 | +- **📊 Admin Dashboard**: Built-in dark-themed web dashboard for testing, viewing live logs, and monitoring proxy health |
| 13 | +- **🐳 Docker Native**: Zero-persistence RAM-only architecture designed for easy deployment to cloud services via our public GHCR image |
| 14 | + |
| 15 | +--- |
| 16 | + |
| 17 | +## 🚀 Quick Start (Docker / Cloud Deployment) |
| 18 | + |
| 19 | +The proxy is containerized and available on the GitHub Container Registry. It runs completely statelessly—no volumes or persistent storage needed. All configuration is done via environment variables. |
| 20 | + |
| 21 | +### Deploying via Docker Run |
| 22 | + |
| 23 | +We expose port `3000` via TCP. Configure your personal tokens securely using environment variables: |
| 24 | + |
| 25 | +```bash |
| 26 | +docker run -d \ |
| 27 | + --name qoder-proxy \ |
| 28 | + -p 3000:3000 \ |
| 29 | + -e QODER_PERSONAL_ACCESS_TOKEN="your-qoder-pat" \ |
| 30 | + -e PROXY_API_KEY="your-secret-custom-key" \ |
| 31 | + -e DASHBOARD_PASSWORD="secure-dashboard-password" \ |
| 32 | + ghcr.io/foxy1402/qoder-proxy:latest |
| 33 | +``` |
| 34 | + |
| 35 | +### Environment Variables |
| 36 | + |
| 37 | +| Variable | Description | Required | Profile/Type | |
| 38 | +|---|---|---|---| |
| 39 | +| `QODER_PERSONAL_ACCESS_TOKEN` | Your Personal Access Token from [Qoder Integrations](https://qoder.com/account/integrations) | **Yes** | Secret | |
| 40 | +| `PROXY_API_KEY` | The secret key *you* choose to protect the `/v1` API from outside internet requests | **Yes*** | Secret (Bearer Token) | |
| 41 | +| `DASHBOARD_PASSWORD` | Password to access the web UI at `/dashboard/` | **Yes*** | Secret | |
| 42 | +| `PORT` | Container internal TCP port | No | Defaults to `3000` | |
| 43 | +| `DASHBOARD_ENABLED`| Set to `false` to disable the web UI | No | Defaults to `true` | |
| 44 | +| `CORS_ORIGIN` | Allowed domains for web clients calling the API | No | Defaults to `*` | |
| 45 | +| `QODER_TIMEOUT_MS`| Maximum request timeout | No | Defaults to `120000` (2 min) | |
| 46 | + |
| 47 | +*\* Highly recommended when running on the public internet.* |
| 48 | + |
| 49 | +--- |
| 50 | + |
| 51 | +## 🌐 The Admin Dashboard |
| 52 | + |
| 53 | +The built-in web dashboard provides full observability into what your proxy is doing. Access it at `http://your-server-ip:3000/dashboard/`. |
| 54 | + |
| 55 | +1. **Endpoints**: Get quick copy-paste snippets for integrating tools. |
| 56 | +2. **Playground**: Test the API live in your browser and swap between available models. |
| 57 | +3. **Request Logs**: Inspect live incoming requests, view request payloads, duration, HTTP status, and assembled response text. |
| 58 | +4. **System Logs**: View background system errors from `qodercli`. |
| 59 | + |
| 60 | +*Note: All logs are stored securely in RAM and are completely erased whenever the Docker container restarts.* |
| 61 | + |
| 62 | +--- |
| 63 | + |
| 64 | +## 🤖 Model Intelligence & Mapping |
| 65 | + |
| 66 | +The proxy dynamically understands standard OpenAI names and routes them intelligently to your permitted Qoder tiers. |
| 67 | + |
| 68 | +| OpenAI / Anthropic Alias | Routes To Qoder Tier | |
| 69 | +|---|---| |
| 70 | +| `gpt-4`, `gpt-4o`, `claude-3.5-sonnet` | `auto` | |
| 71 | +| `o1`, `claude-3-opus` | `ultimate` | |
| 72 | +| `o1-mini`, `o3-mini`, `claude-3-sonnet`| `performance` | |
| 73 | +| `claude-3.5-haiku`, `gemini-flash` | `efficient` | |
| 74 | +| `gpt-3.5-turbo`, `gpt-4o-mini`, `claude-3-haiku` | `lite` | |
| 75 | +| *(New frontier models)* `qwen`, `kimi`, `glm`| Respective custom identifier (`qmodel`, `kmodel`, etc.) | |
| 76 | + |
| 77 | +--- |
| 78 | + |
| 79 | +## 🛠 Usage Examples |
| 80 | + |
| 81 | +Once deployed, copy your host URL (e.g. `http://localhost:3000/v1` or `https://my-proxy.com/v1`) into any app that takes OpenAI-style endpoints, and set the API Key to whatever you defined as `PROXY_API_KEY`. |
| 82 | + |
| 83 | +### Python (OpenAI SDK) |
| 84 | + |
| 85 | +```python |
| 86 | +from openai import OpenAI |
| 87 | + |
| 88 | +client = OpenAI( |
| 89 | + base_url="http://localhost:3000/v1", |
| 90 | + api_key="your-secret-custom-key" |
| 91 | +) |
| 92 | + |
| 93 | +stream = client.chat.completions.create( |
| 94 | + model="gpt-4o", # The proxy will map this to the 'auto' tier |
| 95 | + messages=[{"role": "user", "content": "Hello!"}], |
| 96 | + stream=True |
| 97 | +) |
| 98 | + |
| 99 | +for chunk in stream: |
| 100 | + if chunk.choices[0].delta.content: |
| 101 | + print(chunk.choices[0].delta.content, end="", flush=True) |
| 102 | +``` |
| 103 | + |
| 104 | +### Direct HTTP (cURL) |
| 105 | + |
| 106 | +```bash |
| 107 | +curl http://localhost:3000/v1/chat/completions \ |
| 108 | + -H "Content-Type: application/json" \ |
| 109 | + -H "Authorization: Bearer your-secret-custom-key" \ |
| 110 | + -d '{ |
| 111 | + "model": "claude-3.5-sonnet", |
| 112 | + "messages": [ |
| 113 | + {"role": "system", "content": "You are a helpful assistant."}, |
| 114 | + {"role": "user", "content": "Hello!"} |
| 115 | + ], |
| 116 | + "stream": false |
| 117 | + }' |
| 118 | +``` |
| 119 | + |
| 120 | +## ⚠️ Limitations |
| 121 | +- **Embeddings**: Qoder does not support embeddings. Calling `/v1/embeddings` securely returns a `501 Not Implemented`. |
| 122 | +- **Token usage limits**: Request token tracking / `usage` payload properties return `null`. |
| 123 | +- **Function calling**: Not implemented by the Qoder CLI wrapper yet. |
| 124 | + |
| 125 | +## License |
| 126 | +MIT |
0 commit comments