devcopilot 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. api/__init__.py +17 -0
  2. api/admin_config.py +1303 -0
  3. api/admin_routes.py +287 -0
  4. api/admin_static/admin.css +459 -0
  5. api/admin_static/admin.js +497 -0
  6. api/admin_static/index.html +77 -0
  7. api/admin_urls.py +34 -0
  8. api/app.py +194 -0
  9. api/command_utils.py +164 -0
  10. api/dependencies.py +144 -0
  11. api/detection.py +152 -0
  12. api/gateway_model_ids.py +54 -0
  13. api/model_catalog.py +133 -0
  14. api/model_router.py +125 -0
  15. api/models/__init__.py +45 -0
  16. api/models/anthropic.py +234 -0
  17. api/models/openai_responses.py +28 -0
  18. api/models/responses.py +60 -0
  19. api/optimization_handlers.py +154 -0
  20. api/request_pipeline.py +424 -0
  21. api/routes.py +156 -0
  22. api/runtime.py +334 -0
  23. api/validation_log.py +48 -0
  24. api/web_server_tools.py +22 -0
  25. api/web_tools/__init__.py +17 -0
  26. api/web_tools/constants.py +15 -0
  27. api/web_tools/egress.py +99 -0
  28. api/web_tools/outbound.py +278 -0
  29. api/web_tools/parsers.py +104 -0
  30. api/web_tools/request.py +87 -0
  31. api/web_tools/streaming.py +206 -0
  32. cli/__init__.py +5 -0
  33. cli/claude_env.py +12 -0
  34. cli/entrypoints.py +166 -0
  35. cli/env.example +209 -0
  36. cli/launchers/__init__.py +1 -0
  37. cli/launchers/claude.py +84 -0
  38. cli/launchers/codex.py +204 -0
  39. cli/launchers/codex_model_catalog.py +186 -0
  40. cli/launchers/common.py +93 -0
  41. cli/managed/__init__.py +6 -0
  42. cli/managed/claude.py +215 -0
  43. cli/managed/manager.py +157 -0
  44. cli/managed/session.py +260 -0
  45. cli/process_registry.py +78 -0
  46. config/__init__.py +5 -0
  47. config/constants.py +13 -0
  48. config/logging_config.py +159 -0
  49. config/nim.py +118 -0
  50. config/paths.py +91 -0
  51. config/provider_catalog.py +259 -0
  52. config/provider_ids.py +7 -0
  53. config/settings.py +538 -0
  54. core/__init__.py +1 -0
  55. core/anthropic/__init__.py +46 -0
  56. core/anthropic/content.py +31 -0
  57. core/anthropic/conversion.py +587 -0
  58. core/anthropic/emitted_sse_tracker.py +346 -0
  59. core/anthropic/errors.py +70 -0
  60. core/anthropic/native_messages_request.py +280 -0
  61. core/anthropic/native_sse_block_policy.py +313 -0
  62. core/anthropic/provider_stream_error.py +34 -0
  63. core/anthropic/server_tool_sse.py +14 -0
  64. core/anthropic/sse.py +440 -0
  65. core/anthropic/stream_contracts.py +205 -0
  66. core/anthropic/stream_recovery.py +346 -0
  67. core/anthropic/stream_recovery_session.py +133 -0
  68. core/anthropic/thinking.py +140 -0
  69. core/anthropic/tokens.py +117 -0
  70. core/anthropic/tools.py +212 -0
  71. core/anthropic/utils.py +9 -0
  72. core/openai_responses/__init__.py +5 -0
  73. core/openai_responses/adapter.py +31 -0
  74. core/openai_responses/anthropic_sse.py +59 -0
  75. core/openai_responses/errors.py +22 -0
  76. core/openai_responses/events.py +19 -0
  77. core/openai_responses/ids.py +21 -0
  78. core/openai_responses/input.py +258 -0
  79. core/openai_responses/items.py +37 -0
  80. core/openai_responses/reasoning.py +52 -0
  81. core/openai_responses/stream.py +25 -0
  82. core/openai_responses/stream_state.py +654 -0
  83. core/openai_responses/tools.py +374 -0
  84. core/openai_responses/usage.py +37 -0
  85. core/rate_limit.py +60 -0
  86. core/trace.py +216 -0
  87. devcopilot-0.2.0.dist-info/METADATA +687 -0
  88. devcopilot-0.2.0.dist-info/RECORD +189 -0
  89. devcopilot-0.2.0.dist-info/WHEEL +4 -0
  90. devcopilot-0.2.0.dist-info/entry_points.txt +6 -0
  91. devcopilot-0.2.0.dist-info/licenses/LICENSE +21 -0
  92. messaging/__init__.py +26 -0
  93. messaging/cli_event_constants.py +67 -0
  94. messaging/command_context.py +66 -0
  95. messaging/command_dispatcher.py +37 -0
  96. messaging/commands.py +275 -0
  97. messaging/event_parser.py +181 -0
  98. messaging/limiter.py +300 -0
  99. messaging/models.py +36 -0
  100. messaging/node_event_pipeline.py +127 -0
  101. messaging/node_runner.py +342 -0
  102. messaging/platforms/__init__.py +15 -0
  103. messaging/platforms/base.py +228 -0
  104. messaging/platforms/discord.py +567 -0
  105. messaging/platforms/factory.py +103 -0
  106. messaging/platforms/outbox.py +144 -0
  107. messaging/platforms/telegram.py +688 -0
  108. messaging/platforms/voice_flow.py +295 -0
  109. messaging/rendering/__init__.py +3 -0
  110. messaging/rendering/discord_markdown.py +318 -0
  111. messaging/rendering/markdown_tables.py +49 -0
  112. messaging/rendering/profiles.py +55 -0
  113. messaging/rendering/telegram_markdown.py +327 -0
  114. messaging/safe_diagnostics.py +17 -0
  115. messaging/session.py +334 -0
  116. messaging/transcript.py +581 -0
  117. messaging/transcription.py +164 -0
  118. messaging/trees/__init__.py +15 -0
  119. messaging/trees/data.py +482 -0
  120. messaging/trees/manager.py +433 -0
  121. messaging/trees/processor.py +179 -0
  122. messaging/trees/repository.py +177 -0
  123. messaging/turn_intake.py +235 -0
  124. messaging/ui_updates.py +101 -0
  125. messaging/voice.py +76 -0
  126. messaging/workflow.py +200 -0
  127. providers/__init__.py +31 -0
  128. providers/base.py +152 -0
  129. providers/cerebras/__init__.py +7 -0
  130. providers/cerebras/client.py +31 -0
  131. providers/cerebras/request.py +55 -0
  132. providers/codestral/__init__.py +7 -0
  133. providers/codestral/client.py +34 -0
  134. providers/deepseek/__init__.py +11 -0
  135. providers/deepseek/client.py +51 -0
  136. providers/deepseek/request.py +475 -0
  137. providers/defaults.py +41 -0
  138. providers/error_mapping.py +309 -0
  139. providers/exceptions.py +113 -0
  140. providers/fireworks/__init__.py +5 -0
  141. providers/fireworks/client.py +45 -0
  142. providers/fireworks/request.py +48 -0
  143. providers/gemini/__init__.py +7 -0
  144. providers/gemini/client.py +49 -0
  145. providers/gemini/request.py +199 -0
  146. providers/groq/__init__.py +7 -0
  147. providers/groq/client.py +31 -0
  148. providers/groq/request.py +83 -0
  149. providers/kimi/__init__.py +10 -0
  150. providers/kimi/client.py +53 -0
  151. providers/kimi/request.py +42 -0
  152. providers/llamacpp/__init__.py +3 -0
  153. providers/llamacpp/client.py +16 -0
  154. providers/lmstudio/__init__.py +5 -0
  155. providers/lmstudio/client.py +16 -0
  156. providers/mistral/__init__.py +7 -0
  157. providers/mistral/client.py +31 -0
  158. providers/mistral/request.py +37 -0
  159. providers/model_listing.py +133 -0
  160. providers/nvidia_nim/__init__.py +7 -0
  161. providers/nvidia_nim/client.py +91 -0
  162. providers/nvidia_nim/request.py +430 -0
  163. providers/nvidia_nim/voice.py +95 -0
  164. providers/ollama/__init__.py +7 -0
  165. providers/ollama/client.py +39 -0
  166. providers/open_router/__init__.py +7 -0
  167. providers/open_router/client.py +124 -0
  168. providers/open_router/request.py +42 -0
  169. providers/opencode/__init__.py +11 -0
  170. providers/opencode/client.py +31 -0
  171. providers/opencode/request.py +35 -0
  172. providers/rate_limit.py +300 -0
  173. providers/registry.py +527 -0
  174. providers/transports/__init__.py +1 -0
  175. providers/transports/anthropic_messages/__init__.py +5 -0
  176. providers/transports/anthropic_messages/http.py +118 -0
  177. providers/transports/anthropic_messages/recovery.py +206 -0
  178. providers/transports/anthropic_messages/stream.py +295 -0
  179. providers/transports/anthropic_messages/transport.py +236 -0
  180. providers/transports/openai_chat/__init__.py +5 -0
  181. providers/transports/openai_chat/recovery.py +217 -0
  182. providers/transports/openai_chat/stream.py +384 -0
  183. providers/transports/openai_chat/tool_calls.py +293 -0
  184. providers/transports/openai_chat/transport.py +156 -0
  185. providers/wafer/__init__.py +10 -0
  186. providers/wafer/client.py +50 -0
  187. providers/zai/__init__.py +10 -0
  188. providers/zai/client.py +46 -0
  189. providers/zai/request.py +42 -0
@@ -0,0 +1,687 @@
1
+ Metadata-Version: 2.4
2
+ Name: devcopilot
3
+ Version: 0.2.0
4
+ Summary: DevCopilot: Middleware for Claude Code CLI (Anthropic API) and NVIDIA NIM
5
+ License-File: LICENSE
6
+ Requires-Python: >=3.11
7
+ Requires-Dist: aiohttp>=3.14.1
8
+ Requires-Dist: discord-py>=2.7.1
9
+ Requires-Dist: fastapi[standard]>=0.138.0
10
+ Requires-Dist: httpx[socks]>=0.28.1
11
+ Requires-Dist: jsonschema>=4.25.0
12
+ Requires-Dist: loguru>=0.7.0
13
+ Requires-Dist: markdown-it-py>=4.2.0
14
+ Requires-Dist: openai>=2.43.0
15
+ Requires-Dist: pydantic-settings>=2.14.2
16
+ Requires-Dist: pydantic>=2.13.4
17
+ Requires-Dist: python-dotenv>=1.2.2
18
+ Requires-Dist: python-telegram-bot>=22.8
19
+ Requires-Dist: tiktoken>=0.13.0
20
+ Requires-Dist: uvicorn>=0.49.0
21
+ Provides-Extra: voice
22
+ Requires-Dist: grpcio-tools>=1.81.1; extra == 'voice'
23
+ Requires-Dist: grpcio>=1.81.1; extra == 'voice'
24
+ Requires-Dist: nvidia-riva-client>=2.26.0; extra == 'voice'
25
+ Provides-Extra: voice-local
26
+ Requires-Dist: accelerate>=1.14.0; extra == 'voice-local'
27
+ Requires-Dist: librosa>=0.10.0; extra == 'voice-local'
28
+ Requires-Dist: torch>=2.12.1; extra == 'voice-local'
29
+ Requires-Dist: transformers>=5.12.1; extra == 'voice-local'
30
+ Description-Content-Type: text/markdown
31
+
32
+ <div align="center">
33
+
34
+ # 🤖 DevCopilot
35
+
36
+ Use Claude Code CLI, Codex CLI, their VS Code extensions, JetBrains ACP, or chat bots through your own provider-backed proxy.
37
+
38
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=for-the-badge)](https://opensource.org/licenses/MIT)
39
+ [![Python 3.14](https://img.shields.io/badge/python-3.14-3776ab.svg?style=for-the-badge&logo=python&logoColor=white)](https://www.python.org/downloads/)
40
+ [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json&style=for-the-badge)](https://github.com/astral-sh/uv)
41
+ [![Tested with Pytest](https://img.shields.io/badge/testing-Pytest-00c0ff.svg?style=for-the-badge)](https://github.com/Alishahryar1/devcopilot/actions/workflows/tests.yml)
42
+ [![Type checking: Ty](https://img.shields.io/badge/type%20checking-ty-ffcc00.svg?style=for-the-badge)](https://pypi.org/project/ty/)
43
+ [![Code style: Ruff](https://img.shields.io/badge/code%20formatting-ruff-f5a623.svg?style=for-the-badge)](https://github.com/astral-sh/ruff)
44
+ [![Logging: Loguru](https://img.shields.io/badge/logging-loguru-4ecdc4.svg?style=for-the-badge)](https://github.com/Delgan/loguru)
45
+
46
+ DevCopilot routes Anthropic Messages API traffic from Claude Code (CLI and VS Code extension) and OpenAI Responses API traffic from Codex (CLI and VS Code extension) to any provider. It keeps each client's protocol stable while letting you choose free, paid, or local models through the same proxy and Admin UI.
47
+
48
+ [Quick Start](#quick-start) · [Providers](#choose-a-provider) · [Clients](#connect-your-client) · [Integrations](#optional-integrations) · [Development](#development)
49
+
50
+ </div>
51
+
52
+ <div align="center">
53
+ <img src="assets/pic.png" alt="DevCopilot in action" width="700">
54
+ <p><em>Claude Code running through the DevCopilot proxy.</em></p>
55
+ </div>
56
+
57
+ <div align="center">
58
+ <img src="assets/codex.png" alt="Codex CLI in action through DevCopilot" width="700">
59
+ <p><em>Codex CLI using the local DevCopilot Responses provider.</em></p>
60
+ </div>
61
+
62
+ <a id="model-picker"></a>
63
+
64
+ <div align="center">
65
+ <img src="assets/cc-model-picker.png" alt="Claude Code model picker showing gateway models" width="700">
66
+ <p><em>Claude Code native <code>/model</code> picker with DevCopilot gateway models.</em></p>
67
+ </div>
68
+
69
+ <div align="center">
70
+ <img src="assets/codex-model-picker.png" alt="Codex model picker showing generated DevCopilot model catalog" width="700">
71
+ <p><em>Codex native <code>/model</code> picker with the generated DevCopilot catalog.</em></p>
72
+ </div>
73
+
74
+ ## Star History
75
+
76
+ <div align="center">
77
+ <a href="https://star-history.com/#Alishahryar1/devcopilot&Date">
78
+ <picture>
79
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Alishahryar1/devcopilot&type=Date&theme=dark">
80
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Alishahryar1/devcopilot&type=Date">
81
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Alishahryar1/devcopilot&type=Date" width="700">
82
+ </picture>
83
+ </a>
84
+ </div>
85
+
86
+ ## What You Get
87
+
88
+ - Drop-in proxy for Claude Code's Anthropic API calls (`/v1/messages`, `/v1/models`).
89
+ - Drop-in proxy for Codex via the OpenAI Responses API (`/v1/responses`).
90
+ - `devcopilot-claude` and `devcopilot-codex` launchers that read the current Admin UI port and auth token each time they start.
91
+ - 17 provider backends: NVIDIA NIM, OpenRouter, Google AI Studio (Gemini), DeepSeek, Mistral La Plateforme, Mistral Codestral, OpenCode Zen, OpenCode Go, Wafer, Kimi, Cerebras Inference, Groq, Fireworks AI, Z.ai, LM Studio, llama.cpp, and Ollama.
92
+ - Per-model routing for Claude Code: send Opus, Sonnet, Haiku, and fallback traffic to different providers.
93
+ - Native Claude Code `/model` picker support through the proxy's `/v1/models` endpoint (see [Model Picker](#model-picker)).
94
+ - Native Codex `/model` picker support when launched through `devcopilot-codex`, using a generated local model catalog.
95
+ - Streaming, tool use, reasoning/thinking block handling, and local request optimizations.
96
+ - Optional Discord or Telegram bot wrapper for remote Claude Code sessions.
97
+ - Optional Usage through the Claude Code VS Code extension.
98
+ - Codex CLI and VS Code extension support through the shared `~/.codex/config.toml` provider config.
99
+ - Optional voice-note transcription through local Whisper or NVIDIA NIM.
100
+ - Local **Admin UI** at `/admin` to edit supported proxy settings, validate changes, and check providers (loopback access only).
101
+
102
+ ## Quick Start
103
+
104
+ ### 1. Install/Update The Proxy
105
+
106
+ macOS/Linux:
107
+
108
+ ```bash
109
+ curl -fsSL "https://github.com/Alishahryar1/devcopilot/blob/main/scripts/install.sh?raw=1" | sh
110
+ ```
111
+
112
+ Windows PowerShell:
113
+
114
+ ```powershell
115
+ irm "https://github.com/Alishahryar1/devcopilot/blob/main/scripts/install.ps1?raw=1" | iex
116
+ ```
117
+
118
+ Review the installers at [scripts/install.sh](https://github.com/Alishahryar1/devcopilot/blob/main/scripts/install.sh) and [scripts/install.ps1](https://github.com/Alishahryar1/devcopilot/blob/main/scripts/install.ps1). They install Claude Code and Codex when missing, then install or update DevCopilot. Re-run these commands to update to the latest version.
119
+
120
+ To remove only DevCopilot (not uv, Claude Code, Codex, or the uv-managed Python runtime):
121
+
122
+ macOS/Linux:
123
+
124
+ ```bash
125
+ curl -fsSL "https://raw.githubusercontent.com/Alishahryar1/devcopilot/main/scripts/uninstall.sh" | sh
126
+ ```
127
+
128
+ Windows PowerShell:
129
+
130
+ ```powershell
131
+ irm "https://raw.githubusercontent.com/Alishahryar1/devcopilot/main/scripts/uninstall.ps1" | iex
132
+ ```
133
+
134
+ Review [scripts/uninstall.sh](https://github.com/Alishahryar1/devcopilot/blob/main/scripts/uninstall.sh) and [scripts/uninstall.ps1](https://github.com/Alishahryar1/devcopilot/blob/main/scripts/uninstall.ps1). They remove the DevCopilot uv tool and always delete `~/.fcc/`. Stop any running `devcopilot-server`, `devcopilot-claude`, `devcopilot-codex`, `devcopilot-init`, or `devcopilot` process before uninstalling.
135
+
136
+ ### 2. Start The Proxy
137
+
138
+ ```bash
139
+ devcopilot-server
140
+ ```
141
+
142
+ After startup, Uvicorn prints the proxy bind address and the app logs the admin URL:
143
+
144
+ ```text
145
+ INFO: Admin UI: http://127.0.0.1:8082/admin (local-only)
146
+ ```
147
+
148
+ Many terminals make these clickable. Use your configured `PORT` if it is not `8082`.
149
+
150
+ ### 3. Open The Admin UI And Configure NVIDIA NIM
151
+
152
+ Open the **Admin UI** URL from the terminal output.
153
+
154
+ Need an NVIDIA NIM API key? Use the **[NVIDIA NIM provider](#nvidia-nim-provider)** section below, then scroll back up here.
155
+
156
+ <div align="center">
157
+ <img src="assets/admin-page.png" alt="Local admin UI for proxy settings" width="700">
158
+ </div>
159
+
160
+ Paste your NVIDIA NIM API key into `NVIDIA_NIM_API_KEY`, then click **Validate** and **Apply**.
161
+
162
+ The default model is already set to `nvidia_nim/nvidia/nemotron-3-super-120b-a12b`. You can change it later from the same Admin UI.
163
+
164
+ ### 4. Run Your Coding Agent
165
+
166
+ Keep `devcopilot-server` running while you work.
167
+
168
+ **Claude Code**
169
+
170
+ ```bash
171
+ devcopilot-claude
172
+ ```
173
+
174
+ `devcopilot-claude` reads the current configured port and auth token each time it starts, sets the Claude Code environment variables (including a 190k-token `CLAUDE_CODE_AUTO_COMPACT_WINDOW` for auto-compaction), and then launches the real `claude` command. When proxy auth is disabled, it still passes `ANTHROPIC_AUTH_TOKEN=fcc-no-auth` so newer Claude Code versions do not stop at their local login gate before contacting the proxy.
175
+
176
+ **Codex**
177
+
178
+ ```bash
179
+ devcopilot-codex
180
+ ```
181
+
182
+ `devcopilot-codex` reads the same port and auth token, registers an ephemeral `fcc` model provider that points at the local proxy's `/v1/responses` endpoint, generates a Codex model catalog from the proxy's `/v1/models` response, sets `FCC_CODEX_API_KEY` from the Admin UI auth token, strips official `OPENAI_*` credentials from the child environment, and then launches the real `codex` command. Type `/model` inside Codex to open its native picker. Pass through Codex args as usual, for example `devcopilot-codex exec "hello"`.
183
+
184
+ ## Choose A Provider
185
+
186
+ Pick one provider, enter its key or local URL in the Admin UI, and set `MODEL` to a provider-prefixed model slug. `MODEL` is the fallback. `MODEL_OPUS`, `MODEL_SONNET`, and `MODEL_HAIKU` can override routing for Claude Code's model tiers.
187
+
188
+ <a id="nvidia-nim-provider"></a>
189
+
190
+ ### 1. [NVIDIA NIM](https://build.nvidia.com/)
191
+
192
+ Get a key at [build.nvidia.com/settings/api-keys](https://build.nvidia.com/settings/api-keys).
193
+
194
+ In the Admin UI, paste it into `NVIDIA_NIM_API_KEY`. The default `MODEL` is `nvidia_nim/nvidia/nemotron-3-super-120b-a12b`.
195
+
196
+ Popular examples:
197
+
198
+ - `nvidia_nim/nvidia/nemotron-3-super-120b-a12b`
199
+ - `nvidia_nim/z-ai/glm5.1`
200
+ - `nvidia_nim/moonshotai/kimi-k2.5`
201
+ - `nvidia_nim/minimaxai/minimax-m2.5`
202
+
203
+ Browse models at [build.nvidia.com](https://build.nvidia.com/explore/discover).
204
+
205
+ ### 2. [OpenRouter](https://openrouter.ai/)
206
+
207
+ Get a key at [openrouter.ai/keys](https://openrouter.ai/keys).
208
+
209
+ In the Admin UI, paste it into `OPENROUTER_API_KEY`, then set `MODEL` to an OpenRouter slug such as `open_router/openrouter/free`.
210
+
211
+ Browse [all models](https://openrouter.ai/models) or [free models](https://openrouter.ai/collections/free-models).
212
+
213
+ ### 3. [Google AI Studio (Gemini)](https://aistudio.google.com/)
214
+
215
+ Get a Gemini API key at [Google AI Studio](https://aistudio.google.com/apikey) (see Google's [Gemini OpenAI compatibility](https://ai.google.dev/gemini-api/docs/openai) docs).
216
+
217
+ In the Admin UI, paste it into `GEMINI_API_KEY`, then set `MODEL` to a Gemini model slug such as `gemini/models/gemini-3.1-flash-lite`.
218
+
219
+ The Gemini API exposes an OpenAI-compatible endpoint at `https://generativelanguage.googleapis.com/v1beta/openai/`. Free tier quotas are per-model; prompts may be used to improve Google's products outside the UK/CH/EEA/EU unless your account region says otherwise—see Google's terms.
220
+
221
+ Popular examples:
222
+
223
+ - `gemini/models/gemini-3.1-flash-lite`
224
+
225
+ ### 4. [DeepSeek](https://platform.deepseek.com/)
226
+
227
+ Get a key at [platform.deepseek.com/api_keys](https://platform.deepseek.com/api_keys).
228
+
229
+ In the Admin UI, paste it into `DEEPSEEK_API_KEY`, then set `MODEL` to a DeepSeek slug such as `deepseek/deepseek-chat`.
230
+
231
+ This provider uses DeepSeek's Anthropic-compatible endpoint, not the OpenAI chat-completions endpoint.
232
+
233
+ ### 5. [Mistral La Plateforme](https://console.mistral.ai/)
234
+
235
+ [Mistral](https://mistral.ai) hosts an OpenAI-compatible Chat Completions API at `https://api.mistral.ai/v1`. Activate the **Experiment** plan on [console.mistral.ai](https://console.mistral.ai/) for free-tier API access with rate limits (upgrade for higher quotas).
236
+
237
+ In the Admin UI, paste your API key into `MISTRAL_API_KEY`, then set `MODEL` to a Mistral model slug such as `mistral/devstral-small-latest` or `mistral/mistral-small-latest`.
238
+
239
+ Popular examples:
240
+
241
+ - `mistral/devstral-small-latest`
242
+ - `mistral/mistral-small-latest`
243
+
244
+ Browse models at [Mistral documentation](https://docs.mistral.ai/).
245
+
246
+ ### 6. [Mistral Codestral](https://console.mistral.ai/)
247
+
248
+ Mistral's **Codestral** gateway uses a **separate API key** from La Plateforme: provision `CODESTRAL_API_KEY`, then route with the `mistral_codestral/` prefix. The default upstream is **`https://codestral.mistral.ai/v1`** (OpenAI-compatible Chat Completions; same request shaping as the `mistral` provider). See Mistral's [coding / FIM domains](https://docs.mistral.ai/mistral-vibe/using-fim-api); the curated [free LLM API list](https://github.com/cheahjs/free-llm-api-resources#mistral-codestral) summarizes typical Codestral access terms.
249
+
250
+ Popular examples:
251
+
252
+ - `mistral_codestral/codestral-latest`
253
+
254
+ ### 7. [OpenCode Zen](https://opencode.ai/)
255
+
256
+ Get an API key at [opencode.ai/auth](https://opencode.ai/auth).
257
+
258
+ In the Admin UI, paste it into `OPENCODE_API_KEY`, then set `MODEL` to an OpenCode Zen model slug such as `opencode/gpt-5.3-codex`. The same `OPENCODE_API_KEY` powers **OpenCode Go** (below); use `opencode_go/` slugs there.
259
+
260
+ OpenCode Zen is a curated model gateway that provides access to models from Anthropic, OpenAI, Google, DeepSeek, and more through a single API key and OpenAI-compatible endpoint at `https://opencode.ai/zen/v1`.
261
+
262
+ Popular examples:
263
+
264
+ - `opencode/gpt-5.3-codex`
265
+ - `opencode/claude-sonnet-4`
266
+ - `opencode/deepseek-v4-flash-free` (free)
267
+ - `opencode/gemini-3-flash`
268
+ - `opencode/big-pickle` (free)
269
+ - `opencode/glm-5.1`
270
+
271
+ Browse available models at [opencode.ai](https://opencode.ai).
272
+
273
+ ### 8. [OpenCode Go](https://opencode.ai/)
274
+
275
+ Get an API key at [opencode.ai/auth](https://opencode.ai/auth) (same as OpenCode Zen).
276
+
277
+ In the Admin UI, use `OPENCODE_API_KEY`, then set `MODEL` to an OpenCode Go model slug such as `opencode_go/minimax-m2.7`.
278
+
279
+ OpenCode Go is a subscription gateway with its own curated catalog and OpenAI-compatible endpoint at `https://opencode.ai/zen/go/v1`. It shares the **same OpenCode API key** as Zen; only the slug prefix (`opencode_go/` vs `opencode/`) and upstream path differ.
280
+
281
+ Popular examples:
282
+
283
+ - `opencode_go/minimax-m2.7`
284
+
285
+ Browse available models at [opencode.ai](https://opencode.ai).
286
+
287
+ ### 9. [Wafer](https://wafer.ai/)
288
+
289
+ Get a key from [wafer.ai](https://wafer.ai). In the Admin UI, paste it into `WAFER_API_KEY`, then set `MODEL` to a Wafer Pass model such as `wafer/DeepSeek-V4-Pro`.
290
+
291
+ Popular examples:
292
+
293
+ - `wafer/DeepSeek-V4-Pro`
294
+ - `wafer/MiniMax-M2.7`
295
+ - `wafer/Qwen3.5-397B-A17B`
296
+ - `wafer/GLM-5.1`
297
+
298
+ This provider uses Wafer's Anthropic-compatible endpoint at `https://pass.wafer.ai/v1/messages`.
299
+
300
+ ### 10. [Kimi](https://platform.moonshot.ai/)
301
+
302
+ Get a key at [platform.moonshot.ai/console/api-keys](https://platform.moonshot.ai/console/api-keys).
303
+
304
+ In the Admin UI, paste it into `KIMI_API_KEY`, then set `MODEL` to a Kimi slug such as `kimi/kimi-k2.5`.
305
+
306
+ This provider calls Kimi's **Anthropic-compatible** Messages API (`https://api.moonshot.ai/anthropic/v1/messages`; model discovery uses OpenAI-compat `GET https://api.moonshot.ai/v1/models`). It is **not** the OpenAI Chat Completions path.
307
+
308
+ Browse models at [platform.moonshot.ai](https://platform.moonshot.ai).
309
+
310
+ ### 11. [Cerebras Inference](https://inference-docs.cerebras.ai/quickstart)
311
+
312
+ Sign up and create an API key in the [Cerebras Cloud Console](https://cloud.cerebras.ai) (see [Quickstart](https://inference-docs.cerebras.ai/quickstart)).
313
+
314
+ In the Admin UI, set `CEREBRAS_API_KEY`, then route with `MODEL` such as `cerebras/llama3.1-8b` or `cerebras/gpt-oss-120b` (ids from [List models](https://inference-docs.cerebras.ai/api-reference/models/list-models)).
315
+
316
+ Cerebras exposes an OpenAI-compatible API at `https://api.cerebras.ai/v1` ([OpenAI compatibility](https://inference-docs.cerebras.ai/resources/openai)). Non-standard request fields should go in `extra_body` when using the OpenAI client; see the same page. For reasoning models and parameters, see [Reasoning](https://inference-docs.cerebras.ai/capabilities/reasoning). This proxy follows other OpenAI-compat adapters for thinking via `reasoning_content` when Claude-style thinking is enabled.
317
+
318
+ ### 12. [Groq](https://console.groq.com/)
319
+
320
+ Get an API key at [console.groq.com/keys](https://console.groq.com/keys).
321
+
322
+ In the Admin UI, paste it into `GROQ_API_KEY`, then set `MODEL` to a Groq OpenAI-compat model slug such as `groq/llama-3.3-70b-versatile`.
323
+
324
+ Groq routes through `https://api.groq.com/openai/v1` ([OpenAI-compatible Chat Completions](https://console.groq.com/docs/openai)). Some request fields yield HTTP 400; this adapter strips known-unsupported shapes (documented in Groq's compatibility notes).
325
+
326
+ Reasoning-heavy models expose extra knobs documented under [Groq reasoning](https://console.groq.com/docs/reasoning). This release mirrors other OpenAI-compat adapters for thinking via `reasoning_content` deltas when Claude-style thinking is enabled; you can tune advanced parameters through request `extra_body` when needed.
327
+
328
+ Browse models at [console.groq.com/docs/models](https://console.groq.com/docs/models).
329
+
330
+ ### 13. [Fireworks AI](https://fireworks.ai/)
331
+
332
+ Get an API key at [fireworks.ai/account/api-keys](https://fireworks.ai/account/api-keys).
333
+
334
+ In the Admin UI, paste it into `FIREWORKS_API_KEY`, then set `MODEL` to a Fireworks model slug such as `fireworks/accounts/fireworks/models/llama-v3p3-70b-instruct`.
335
+
336
+ Fireworks exposes an **Anthropic-compatible** Messages API at `https://api.fireworks.ai/inference/v1/messages` (same inference host as before; Chat Completions is not used here). Vendor-specific JSON keys can still be merged from request `extra_body` when allowed.
337
+
338
+ Browse models at [fireworks.ai/models](https://fireworks.ai/models).
339
+
340
+ ### 14. [Z.ai](https://z.ai/)
341
+
342
+ Get an API key at [Z.ai/manage-apikey/apikey-list](https://z.ai/manage-apikey/apikey-list).
343
+
344
+ In the Admin UI, paste it into `ZAI_API_KEY`, then set `MODEL` to a Z.ai model slug such as `zai/glm-5.1`.
345
+
346
+ This provider calls Z.ai's **Anthropic-compatible** Messages API (`https://api.z.ai/api/anthropic/v1/messages`). The former OpenAI Coding Plan base (`https://api.z.ai/api/coding/paas/v4`) is **not** used by this gateway.
347
+
348
+ Popular examples:
349
+
350
+ - `zai/glm-5.1`
351
+ - `zai/glm-5-turbo`
352
+
353
+ Browse models at [Z.ai](https://z.ai).
354
+
355
+ ### 15. [LM Studio](https://lmstudio.ai/)
356
+
357
+ Start LM Studio's local server and load a model. In the Admin UI, keep or update `LM_STUDIO_BASE_URL`, then set `MODEL` to the model identifier shown by LM Studio, prefixed with `lmstudio/`.
358
+
359
+ Prefer models with tool-use support for Claude Code workflows.
360
+
361
+ ### 16. [llama.cpp](https://github.com/ggml-org/llama.cpp)
362
+
363
+ Start `llama-server` with an Anthropic-compatible `/v1/messages` endpoint and enough context for Claude Code requests.
364
+
365
+ In the Admin UI, keep or update `LLAMACPP_BASE_URL`, then set `MODEL` to the local model slug, prefixed with `llamacpp/`.
366
+
367
+ For local coding models, context size matters. If llama.cpp returns HTTP 400 for normal Claude Code requests, increase `--ctx-size` and verify the model/server build supports the requested features.
368
+
369
+ ### 17. [Ollama](https://ollama.com/)
370
+
371
+ Run Ollama and pull a model:
372
+
373
+ ```bash
374
+ ollama pull llama3.1
375
+ ollama serve
376
+ ```
377
+
378
+ In the Admin UI, keep or update `OLLAMA_BASE_URL`, then set `MODEL` to the same tag shown by `ollama list`, prefixed with `ollama/`.
379
+
380
+ `OLLAMA_BASE_URL` is the Ollama server root; do not append `/v1`. Example model slugs include `ollama/llama3.1` and `ollama/llama3.1:8b`.
381
+
382
+ ### 18. Mix Providers By Model Tier
383
+
384
+ Each model tier can use a different provider by setting `MODEL_OPUS`, `MODEL_SONNET`, and `MODEL_HAIKU` in the Admin UI. Leave a tier blank to inherit `MODEL`. These tier overrides apply to Claude model names that contain `opus`, `sonnet`, or `haiku`. Codex uses the Admin `MODEL` default through `devcopilot-codex` unless a session requests a provider-prefixed slug directly.
385
+
386
+ For example, you can route Opus to `nvidia_nim/moonshotai/kimi-k2.6`, Sonnet to `open_router/openrouter/free`, Haiku to `lmstudio/qwen3.5-coder`, and keep the fallback `MODEL` on `zai/glm-5.1`.
387
+
388
+ <a id="connect-your-client"></a>
389
+
390
+ ## Connect Your Client
391
+
392
+ ### 1. Claude Code CLI
393
+
394
+ For terminal use, prefer the installed launcher:
395
+
396
+ ```bash
397
+ devcopilot-claude
398
+ ```
399
+
400
+ The Admin UI manages proxy config, restarts the server when runtime settings change, and `devcopilot-claude` reads the current Admin UI-managed port and auth token every time it starts. It also sets `CLAUDE_CODE_AUTO_COMPACT_WINDOW` to `190000` for auto-compaction. When proxy auth is blank, `devcopilot-claude` injects `ANTHROPIC_AUTH_TOKEN=fcc-no-auth` only to satisfy Claude Code's local login check; the proxy still treats blank auth as disabled.
401
+
402
+ ### 2. Codex CLI
403
+
404
+ For terminal use, prefer the installed launcher:
405
+
406
+ ```bash
407
+ devcopilot-codex
408
+ ```
409
+
410
+ The installer provisions Codex when it is missing (`npm install -g @openai/codex`). `devcopilot-codex` injects ephemeral Codex config on every launch:
411
+
412
+ - `model_provider=fcc`
413
+ - `model_providers.fcc.base_url=http://127.0.0.1:<PORT>/v1`
414
+ - `model_providers.fcc.env_key=FCC_CODEX_API_KEY`
415
+ - `model_providers.fcc.wire_api=responses`
416
+ - `model_catalog_json=~/.fcc/codex-model-catalog.json`
417
+
418
+ The Admin UI auth token is reused as `FCC_CODEX_API_KEY`. Official OpenAI credentials are stripped from the child environment so traffic stays on the local proxy. The generated model catalog lets Codex's native `/model` picker list provider-selectable DevCopilot model slugs. If the catalog cannot be fetched or written, `devcopilot-codex` warns and still launches without picker injection.
419
+
420
+ **Advanced manual setup**
421
+
422
+ If you launch `codex` directly, point it at the proxy with equivalent config:
423
+
424
+ ```bash
425
+ codex \
426
+ -c 'model_provider="fcc"' \
427
+ -c 'model_providers.fcc.name="DevCopilot"' \
428
+ -c 'model_providers.fcc.base_url="http://127.0.0.1:8082/v1"' \
429
+ -c 'model_providers.fcc.env_key="FCC_CODEX_API_KEY"' \
430
+ -c 'model_providers.fcc.wire_api="responses"' \
431
+ exec "hello"
432
+ ```
433
+
434
+ Set `FCC_CODEX_API_KEY` to the same value as `ANTHROPIC_AUTH_TOKEN` in the Admin UI.
435
+
436
+ ### 3. Claude Code in VS Code
437
+
438
+ Install the [Claude Code extension](https://marketplace.visualstudio.com/items?itemName=anthropic.claude-code). Open Settings, search for `claude-code.environmentVariables`, choose **Edit in settings.json**, and add:
439
+
440
+ ```json
441
+ "claudeCode.environmentVariables": [
442
+ { "name": "ANTHROPIC_BASE_URL", "value": "http://localhost:8082" },
443
+ { "name": "ANTHROPIC_AUTH_TOKEN", "value": "freecc" },
444
+ { "name": "CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY", "value": "1" },
445
+ { "name": "CLAUDE_CODE_AUTO_COMPACT_WINDOW", "value": "190000" }
446
+ ]
447
+ ```
448
+
449
+ Reload the extension. If the extension shows a login screen, choose the Anthropic Console path once; the local proxy still handles model traffic after the environment variables are active.
450
+
451
+ ### 4. Codex in VS Code
452
+
453
+ Install the [Codex extension](https://marketplace.visualstudio.com/items?itemName=openai.chatgpt). The extension shares the same user-level Codex config as the CLI (`~/.codex/config.toml` on macOS/Linux, `%USERPROFILE%\.codex\config.toml` on Windows).
454
+
455
+ Create or edit that file with the `fcc` provider pointing at your local proxy:
456
+
457
+ ```toml
458
+ model_provider = "fcc"
459
+ model = "nvidia_nim/nvidia/nemotron-3-super-120b-a12b"
460
+
461
+ [model_providers.fcc]
462
+ name = "DevCopilot"
463
+ base_url = "http://127.0.0.1:8082/v1"
464
+ env_key = "FCC_CODEX_API_KEY"
465
+ wire_api = "responses"
466
+ ```
467
+
468
+ Set `model` to your Admin UI `MODEL` value. Replace `8082` if your proxy uses a different `PORT`.
469
+
470
+ Store the proxy auth token in `~/.codex/auth.json` (or the Windows equivalent):
471
+
472
+ ```json
473
+ {
474
+ "FCC_CODEX_API_KEY": "freecc"
475
+ }
476
+ ```
477
+
478
+ Use the same value as `ANTHROPIC_AUTH_TOKEN` in the Admin UI. Restart VS Code after changing these files. On Windows with WSL-backed Codex, edit the WSL `~/.codex/` files instead and enable `chatgpt.runCodexInWindowsSubsystemForLinux` in VS Code settings when needed.
479
+
480
+ ### 5. Claude Code in JetBrains ACP
481
+
482
+ Edit the installed Claude ACP config:
483
+
484
+ - Windows: `C:\Users\%USERNAME%\AppData\Roaming\JetBrains\acp-agents\installed.json`
485
+ - Linux/macOS: `~/.jetbrains/acp.json`
486
+
487
+ Set the environment for `acp.registry.claude-acp`:
488
+
489
+ ```json
490
+ "env": {
491
+ "ANTHROPIC_BASE_URL": "http://localhost:8082",
492
+ "ANTHROPIC_AUTH_TOKEN": "freecc",
493
+ "CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY": "1",
494
+ "CLAUDE_CODE_AUTO_COMPACT_WINDOW": "190000"
495
+ }
496
+ ```
497
+
498
+ Restart the IDE after changing the file.
499
+
500
+ ## Optional Integrations
501
+
502
+ For every integration below, change **managed proxy settings** only in the **Admin UI** at `/admin`: edit fields, click **Validate**, then **Apply**. The footer shows where the managed config is stored; this README does not walk through editing that file by hand.
503
+
504
+ ### 1. Discord And Telegram Bots
505
+
506
+ The bot wrapper runs Claude Code sessions remotely, streams progress, supports reply-based conversation branches, and can stop or clear tasks. Discord and Telegram bots use Claude Code today; use `devcopilot-codex` or the Codex VS Code extension for Codex sessions.
507
+
508
+ **Discord**
509
+
510
+ 1. Create the bot in the [Discord Developer Portal](https://discord.com/developers/applications).
511
+ 2. Enable **Message Content Intent**.
512
+ 3. Invite the bot with read, send, and message history permissions.
513
+ 4. Copy the bot token and the numeric channel ID (or IDs) where the bot should respond.
514
+
515
+ **Telegram**
516
+
517
+ 1. Create a bot with [@BotFather](https://t.me/BotFather) and copy the bot token.
518
+ 2. Get your numeric user ID from [@userinfobot](https://t.me/userinfobot) so only you can use the bot.
519
+
520
+ **Configure in the Admin UI**
521
+
522
+ 1. With `devcopilot-server` running, open the **Admin UI** URL from the terminal output.
523
+ 2. In the sidebar, choose **Messaging**.
524
+ 3. Set **Messaging Platform** to **discord** or **telegram**.
525
+ 4. For Discord, paste **Discord Bot Token** and **Allowed Discord Channels**. For Telegram, paste **Telegram Bot Token** and **Allowed Telegram User ID**.
526
+ 5. Set **Allowed Directory** to an absolute path on the machine running the proxy—the workspace root the bot may use.
527
+ 6. Click **Validate**, then **Apply**. Restart the server if the UI says one is required.
528
+
529
+ <div align="center">
530
+ <img src="assets/admin-messaging.png" alt="Admin UI Messaging view with bot and voice settings" width="700">
531
+ </div>
532
+
533
+ <p align="center"><em>Admin UI → Messaging (platform, bots, and Voice)</em></p>
534
+
535
+ **Useful commands**
536
+
537
+ - `/stop` cancels a task; reply to a task message to stop only that branch.
538
+ - `/clear` resets sessions; reply to clear one branch.
539
+ - `/stats` shows session state.
540
+
541
+ ### 2. Voice Notes
542
+
543
+ Voice notes work on Discord and Telegram after you extend your [DevCopilot install](#1-fast-install) with the matching optional extras.
544
+
545
+ macOS/Linux:
546
+
547
+ ```bash
548
+ # NVIDIA NIM transcription (Riva gRPC)
549
+ curl -fsSL "https://github.com/Alishahryar1/devcopilot/blob/main/scripts/install.sh?raw=1" | sh -s -- --voice-nim
550
+
551
+ # Local Whisper (CPU or CUDA)
552
+ curl -fsSL "https://github.com/Alishahryar1/devcopilot/blob/main/scripts/install.sh?raw=1" | sh -s -- --voice-local
553
+
554
+ # Both backends
555
+ curl -fsSL "https://github.com/Alishahryar1/devcopilot/blob/main/scripts/install.sh?raw=1" | sh -s -- --voice-all
556
+
557
+ # Local Whisper with CUDA
558
+ curl -fsSL "https://github.com/Alishahryar1/devcopilot/blob/main/scripts/install.sh?raw=1" | sh -s -- --voice-local --torch-backend cu130
559
+ ```
560
+
561
+ Windows PowerShell:
562
+
563
+ ```powershell
564
+ # NVIDIA NIM transcription (Riva gRPC)
565
+ & ([scriptblock]::Create((irm "https://github.com/Alishahryar1/devcopilot/blob/main/scripts/install.ps1?raw=1"))) -VoiceNim
566
+
567
+ # Local Whisper (CPU or CUDA)
568
+ & ([scriptblock]::Create((irm "https://github.com/Alishahryar1/devcopilot/blob/main/scripts/install.ps1?raw=1"))) -VoiceLocal
569
+
570
+ # Both backends
571
+ & ([scriptblock]::Create((irm "https://github.com/Alishahryar1/devcopilot/blob/main/scripts/install.ps1?raw=1"))) -VoiceAll
572
+
573
+ # Local Whisper with CUDA
574
+ & ([scriptblock]::Create((irm "https://github.com/Alishahryar1/devcopilot/blob/main/scripts/install.ps1?raw=1"))) -VoiceLocal -TorchBackend cu130
575
+ ```
576
+
577
+ Restart `devcopilot-server` after reinstalling.
578
+
579
+ In the **Admin UI**, open **Messaging** and scroll to **Voice**. Turn on **Voice Notes**, choose **Whisper Device** (`cpu`, `cuda`, or `nvidia_nim`), set **Whisper Model**, and enter **Hugging Face Token** when your setup needs it. For **nvidia_nim** transcription, install the `voice` extra and set **NVIDIA NIM API Key** on the **Providers** view. The screenshot above shows the **Voice** block in the same view.
580
+
581
+ ## How It Works
582
+
583
+ <div align="center">
584
+ <img src="assets/how-it-works.svg" alt="DevCopilot request flow architecture" width="900">
585
+ </div>
586
+
587
+ Diagram source: [`assets/how-it-works.mmd`](assets/how-it-works.mmd).
588
+
589
+ Important pieces:
590
+
591
+ - FastAPI exposes Anthropic-compatible routes such as `/v1/messages`, `/v1/messages/count_tokens`, and `/v1/models`, plus OpenAI Responses at `/v1/responses`.
592
+ - Claude Code sends Anthropic Messages; Codex sends OpenAI Responses SSE to the same proxy.
593
+ - Responses requests convert to Anthropic Messages internally, then share the same model router, normalizer, and provider adapters.
594
+ - `devcopilot-codex` registers a custom `fcc` provider that points Codex at the local proxy's `/v1/responses` endpoint.
595
+ - Model routing resolves Claude model names to `MODEL_OPUS`, `MODEL_SONNET`, `MODEL_HAIKU`, or `MODEL`.
596
+ - NIM, OpenCode Zen, and OpenCode Go use OpenAI chat streaming translated into Anthropic SSE.
597
+ - Wafer, OpenRouter, DeepSeek, Kimi, Fireworks AI, Z.ai, LM Studio, llama.cpp, and Ollama use Anthropic Messages style transports where applicable (with provider-specific quirks and model-list URLs).
598
+ - The proxy normalizes thinking blocks, tool calls, token usage metadata, and provider errors into the shape each client expects.
599
+ - Request optimizations answer trivial Claude Code probes locally to save latency and quota.
600
+
601
+ ## Development
602
+
603
+ ### 1. Project Structure
604
+
605
+ ```text
606
+ devcopilot/
607
+ ├── server.py # ASGI entry point
608
+ ├── api/ # FastAPI routes, service layer, routing, optimizations
609
+ ├── core/ # Shared Anthropic protocol helpers, SSE, OpenAI Responses
610
+ │ └── openai_responses/ # Responses ↔ Anthropic conversion and SSE mapping
611
+ ├── providers/ # Provider transports, registry, rate limiting
612
+ ├── messaging/ # Discord/Telegram adapters, sessions, voice
613
+ ├── cli/ # Package entry points and client CLI process management
614
+ ├── config/ # Settings, provider catalog, logging
615
+ └── tests/ # Unit and contract tests
616
+ ```
617
+
618
+ ### 2. Run From Source
619
+
620
+ Use this path if you are developing or want to run directly from a checkout:
621
+
622
+ ```bash
623
+ git clone https://github.com/Alishahryar1/devcopilot.git
624
+ cd devcopilot
625
+ uv run uvicorn server:app --host 0.0.0.0 --port 8082
626
+ ```
627
+
628
+ ### 3. Commands
629
+
630
+ Run the local CI sequence (requires `uv` on PATH). The local scripts format
631
+ Python files and apply autofixable Ruff lint fixes before type checking and
632
+ tests:
633
+
634
+ ```bash
635
+ ./scripts/ci.sh
636
+ ```
637
+
638
+ ```powershell
639
+ .\scripts\ci.ps1
640
+ ```
641
+
642
+ Useful flags: `--only pytest`, `--skip pytest`, `--dry-run` (PowerShell: `-Only pytest`, `-Skip pytest`, `-DryRun`).
643
+
644
+ Or run individual repair/check commands manually:
645
+
646
+ ```bash
647
+ uv run ruff format
648
+ uv run ruff check --fix
649
+ uv run ty check
650
+ uv run pytest -v --tb=short
651
+ ```
652
+
653
+ GitHub CI remains check-only for Ruff with `uv run ruff format --check` and
654
+ `uv run ruff check`, so required status checks verify committed code.
655
+
656
+ CI also enforces a ban on `# type: ignore` / `# ty: ignore` suppressions; `scripts/ci.sh` and `scripts/ci.ps1` run that grep too.
657
+
658
+ ### 4. Package Scripts
659
+
660
+ `pyproject.toml` installs:
661
+
662
+ - `devcopilot-server`: starts the proxy with configured host and port.
663
+ - `devcopilot-init`: optional advanced scaffold for `~/.fcc/.env`; prefer the **Admin UI** for normal configuration.
664
+ - `devcopilot-claude`: launches Claude Code with the configured local proxy URL, an auth-token env var or `fcc-no-auth` sentinel, model discovery flag, and a 190k `CLAUDE_CODE_AUTO_COMPACT_WINDOW` for auto-compaction.
665
+ - `devcopilot-codex`: launches Codex with ephemeral `fcc` provider config pointing at the local proxy's `/v1/responses` endpoint, a generated native `/model` picker catalog, and `FCC_CODEX_API_KEY` from the Admin UI auth token.
666
+
667
+ ### 5. Extending
668
+
669
+ - Add OpenAI-compatible providers by extending `OpenAIChatTransport`.
670
+ - Add Anthropic Messages providers by extending `AnthropicMessagesTransport`.
671
+ - Extend OpenAI Responses conversion in `core/openai_responses/` when Codex adds new request or stream shapes.
672
+ - Register provider metadata in `config.provider_catalog` and factory wiring in `providers.registry`.
673
+ - Add messaging platforms by implementing the `MessagingPlatform` interface in `messaging/`.
674
+
675
+ ## Contributing
676
+
677
+ - [`.env.example`](.env.example) lists env key names as a read-only reference for contributors; use the **Admin UI** to change managed proxy settings.
678
+ - Report bugs and feature requests in [Issues](https://github.com/Alishahryar1/devcopilot/issues). For bug always include all model mapping, current model when issue occured and the issue string
679
+ - Keep changes small and covered by focused tests.
680
+ - Do not open Docker integration PRs.
681
+ - Do not open README change PRs just open an issue for it.
682
+ - Run the full check sequence before opening a pull request.
683
+ - The syntax `except X, Y` is brought back in python 3.14 final version (not in 3.14 alpha). Keep in mind before opening PRs.
684
+
685
+ ## License
686
+
687
+ MIT License. See [LICENSE](LICENSE) for details.