Commit f9e2fc5
feat: add Codex-compatible GET
## Summary
`handler.rs` had grown to 630 lines mixing WebSocket logic, HTTP
handlers, proxy utilities, and model transformation code in a single
file. This PR splits it into a focused module tree and adds a Codex
CLI-compatible `/v1/models` endpoint.
**`GET /v1/models`: Codex CLI compatibility**
- Added `proxy_get(path, headers, state)` to `agentic-core/proxy.rs`: a
GET variant of `proxy_request` that applies the same header filtering
and auth injection.
- Codex CLI is detected via `?client_version=<ver>` query param (typed
`ModelsParams` extractor).
- Non-Codex clients: upstream vLLM response streamed back unchanged via
`proxy_get`.
- Codex clients: vLLM `{ "object": "list", "data": [...] }` transformed
to `{ "models": [...] }` with the full `ModelInfo` shape Codex expects
(`slug`, `context_window`, `auto_review_model_override`,
`apply_patch_tool_type`, capabilities, etc.).
- Static `ModelInfo` fields built once via `OnceLock` and cloned per
model; only the five per-model fields are patched at response time.
**WebSocket session bug fixes**
Identified and fixed two bugs in `websocket/responses.rs` that prevented
Codex CLI from persisting history to the database:
- **Pipelined requests caused connection resets**: Codex sends the next
`response.create` on the same WebSocket connection while the current
stream is still active. The old handler returned a `ConcurrentMessage`
error and closed the connection, forcing Codex to reconnect on every
turn. Fixed by introducing a `VecDeque` queue: incoming requests that
arrive mid-stream are enqueued and processed in order after the current
stream completes. The `ConcurrentMessage` error variant was removed as
it is no longer reachable.
- **`store: false` bypassed the database**: Codex CLI explicitly sends
`"store": false` in every request body, which caused the gateway to skip
persistence entirely and proxy straight to vLLM. Fixed by forcing
`payload.store = true` on the WebSocket path; the gateway is the
stateful layer and should always persist regardless of what the client
sends.
Together these fixes ensure every completed Codex turn is written to the
DB with its full SSE history, and that multi-turn conversations chain
correctly via `previous_response_id`.
**Handler reorganization**
- `handler.rs` deleted. Replaced by `handler/` module tree:
- `common.rs`: shared utilities used across handlers:
`convert_response`, `executor_error_response`, `read_bytes`,
`resolve_exec_ctx`, `sse_response`
- `http/conversations.rs`: `POST /v1/conversations`
- `http/models.rs`: `GET /health`, `GET /ready`, `GET /v1/models` +
Codex model transform logic
- `http/responses.rs`: `POST /v1/responses` (proxy and stateful paths)
- `websocket/responses.rs`: WebSocket `/v1/responses` handler and
streaming loop
- `websocket/error.rs`: `WsError` enum with status/code/frame helpers
- `handler/mod.rs` re-exports all public handlers; no import paths in
`app.rs` changed.
## Codex CLI setup
Create `$CODEX_HOME/config.toml` (e.g. `~/.codex/config.toml`) pointing
at agentic-api:
```toml
model_provider = "agentic-api"
[model_providers.agentic-api]
name = "agentic-api"
base_url = "http://localhost:9000/v1"
wire_api = "responses"
requires_openai_auth = false
supports_websockets = true
```
Run with:
```bash
codex --disable image_generation -c model_provider=agentic-api -m "model_name"
```
## Test Plan
- `cargo clippy --all-targets -- -D warnings` clean
- `cargo test`: all tests pass, 0 failed
---------
Signed-off-by: maral <maralbahari.98@gmail.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>v1/models and WebSocket session bug fixes (vllm-project#79)1 parent 647e49d commit f9e2fc5
12 files changed
Lines changed: 761 additions & 500 deletions
File tree
- crates
- agentic-core/src
- agentic-server/src
- handler
- http
- websocket
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
153 | 153 | | |
154 | 154 | | |
155 | 155 | | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
156 | 198 | | |
157 | 199 | | |
158 | 200 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
| 74 | + | |
74 | 75 | | |
75 | 76 | | |
76 | 77 | | |
| |||
0 commit comments