← Back to PRs

#17577: feat: add GET /v1/models endpoint for OpenAI-compatible model listing

by lazmo88 open 2026-02-15 23:01 View on GitHub →
gateway size: S
## Summary Adds `GET /v1/models` and `GET /v1/models/<id>` endpoints to the OpenAI-compatible HTTP API. This enables compatibility with clients that probe `/v1/models` before using `/v1/chat/completions` — including n8n, Open WebUI, LibreChat, OneDev, and any standard OpenAI SDK client. - Each configured agent is exposed as a model with id `openclaw/<agentId>` - The default agent is also exposed as the plain `openclaw` model - Auth is optional on `/v1/models` (many clients don't send bearer tokens for model listing) - Gated by the existing `chatCompletions.enabled` config flag - Returns proper error responses: 404 for unknown models, 405 for wrong method ## Changes Only modifies `src/gateway/openai-http.ts`: - Adds `handleModelsRequest()` function (~55 lines) - Adds two imports: `loadConfig` from `config/io.js` and `listAgentsForGateway` from `session-utils.js` - Adds dispatch call at the top of `handleOpenAiHttpRequest()` ## Example Response ```json GET /v1/models → 200 { "object": "list", "data": [ { "id": "openclaw", "object": "model", "created": 1771031029, "owned_by": "openclaw" }, { "id": "openclaw/main", "object": "model", "created": 1771031029, "owned_by": "openclaw", "name": "Main Agent" } ] } GET /v1/models/openclaw → 200 { "id": "openclaw", "object": "model", "created": 1771031029, "owned_by": "openclaw" } GET /v1/models/nonexistent → 404 { "error": { "message": "Model 'nonexistent' not found.", "type": "invalid_request_error" } } POST /v1/models → 405 ``` ## Test Plan - [x] `GET /v1/models` → 200 with model list - [x] `GET /v1/models/openclaw` → 200 with single model object - [x] `GET /v1/models` without auth → 200 (auth optional) - [x] `GET /v1/models/nonexistent` → 404 with error - [x] `POST /v1/models` → 405 - [x] `/v1/chat/completions` unaffected - [x] Tested with OneDev (real client) via Nginx Proxy Manager - [x] `pnpm build` passes with zero errors - [x] Rebased onto current main ## Design Decisions 1. **Auth optional on /v1/models**: Many OpenAI-compatible clients (OneDev, some n8n nodes) don't send bearer tokens when listing models. Making auth optional here improves compatibility. 2. **Single file change**: The entire feature fits in `openai-http.ts` with no new dependencies. Uses existing `loadConfig()` and `listAgentsForGateway()`. 3. **Gated by chatCompletions.enabled**: Reuses the existing config flag rather than adding a new one, keeping the config surface small. 4. **Model ID format**: `openclaw/<agentId>` for agents, plain `openclaw` for the default. This follows the `provider/model` convention used by other APIs. ## AI Disclosure 🤖 - **AI-assisted**: Yes — written with Claude (Opus), with human review and testing - **Testing level**: Build-verified (`pnpm build` zero errors); endpoint tested with curl and OneDev client - **Understanding**: The author understands the code — it adds a URL-matched handler that enumerates agents via existing `listAgentsForGateway()` and returns them as OpenAI model objects

Most Similar PRs