[Provider compatibility]: Kimi Coding presets cannot use the native Responses wire — registry pins chat, and the shipped "Kimi (Responses)" preset is not reachable

Open
#8,087 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
22/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
cli, typescript
Domain
api, backend

Research direction

Start with the registry preset definitions (kimi, kimi-code, kimi-responses) and routedProviderConfig(), which pins the upstream wire to openai-chat regardless of the configured adapter. The provider-presets endpoint and the CLI provider add --live path are the other entry points. Mirroring the modelWireDefaults change from #5673 is the reference; done would mean the Responses inbound uses openai-responses for Kimi and kimi-responses is listed and addable.

Written by the indexing model from the issue text.

Description

account-pool provider provider-compatibility
Client or integration

Codex App

Provider or upstream service

Kimi Coding Plan (https://api.kimi.com/coding/v1). Registry presets: kimi (OAuth), kimi-code (API key), kimi-responses (Kimi (Responses), OAuth), plus the modelAdapters config field.

OpenCodex version

2.96.0 — Desktop build, ocx 2.96.0 at C:\Program Files\OpenCodex\ocx.exe; /healthz reports {"status":"ok","service":"opencodex","version":"2.96.0"}. Windows 11 x64.

Endpoint or capability

POST https://api.kimi.com/coding/v1/responses — Kimi's native OpenAI Responses wire (streaming/non-streaming, reasoning, function calling). Route existence verified without credentials: the endpoint returns 401 {"error":{"message":"Invalid Authentication","type":"invalid_authentication_error"}}, not 404.

Current behaviour

Kimi ships three parallel presets, and none of them gives a user the native Responses wire in practice:

preset auth upstream wire reachable from the dashboard
kimi OAuth openai-chat (registry-pinned) yes
kimi-code API key openai-chat (registry-pinned) yes
kimi-responses OAuth openai-responses no

1. Registry authority overrides the configured adapter. Setting adapter: "openai-responses" on either kimi or kimi-code succeeds — ocx provider edit ... --adapter openai-responses reports success and the value is persisted in ~/.opencodex/config.json — but routing does not change. The provider settings page still shows 上游协议 openai-chat / 决定来源 提供商目录, and:

$ ocx api protocols --provider kimi
Provider kimi: adapter openai-chat (registry), upstream chat, auth oauth

$ ocx api protocols --provider kimi-code
Provider kimi-code: adapter openai-chat (registry), upstream chat, auth key

The request log keeps labelling calls Responses → Chat · 已转换, and the logged attempt carries "adapter": "openai-chat". This is the routedProviderConfig() behaviour already described in #5097.

2. The shipped Responses preset is not offered by the dashboard. GET /api/provider-presets returns 100 presets and does not contain kimi-responses. The Add-provider picker is rendered from that list, so searching "kimi" shows only Kimi, Kimi (coding), Fire Pass (Fireworks Kimi) and Moonshot (Kimi API) — no Responses option. The same endpoint also omits devin, github-copilot, google-antigravity, kiro and meta-muse, so this looks like a class of OAuth presets excluded from the dashboard picker rather than a Kimi-only omission.

3. The CLI path for that preset also fails. ocx provider add kimi-responses --live (with and without --auth-mode oauth) exits with Provider operation did not return a usable outcome. Inspect the selected target before retrying; no rollback is implied. The row is not created (ocx provider show kimi-responses reports not configured).

4. The dashboard's per-model override table is display-only. The provider settings page renders 使用其他协议的模型 / 所有模型都使用提供商的协议 but offers no control that writes modelAdapters; in 2.96.0 that config field is the only user-side wire override that survives routedProviderConfig().

Net effect: the only working Responses path is a manually created custom provider id that does not collide with a registry entry (Custom provider in the picker, or ocx provider add <custom-id> --adapter openai-responses ...). It works, but it is not discoverable, drops the preset's model metadata and aliases, and is not documented as the Kimi path.

Expected behaviour

Kimi should not hard-pin the wire, and the existing Responses preset should be usable:

  1. Wire defaults per model, gated by inbound surface, following the pattern already merged for Alibaba Token Plan in #5097 → #5673: registry modelWireDefaults so Responses inbound uses openai-responses, while Chat and Anthropic inbound keep openai-chat as today.
  2. Expose the wire in the dashboard — either make the 使用其他协议的模型 table editable, or surface the per-model override next to the adapter field, so an API-key user can opt in without hand-editing config.json.
  3. Make kimi-responses reachable — list the preset in /api/provider-presets / the Add-provider picker, or add an API-key sibling preset next to the OAuth one (the existing kimi / kimi-code split already establishes that pattern). At minimum, the CLI provider add failure above should return an actionable error instead of "no usable outcome".

Kimi's own documentation is the motivation: its official Codex integration guide states the server natively supports the OpenAI Responses API, requires wire_api = "responses", and warns that proxy protocol conversion may cause output instability.

Minimal redacted request or reproduction
Provider rows (credentials redacted; `kimi` and `kimi-code` behave identically):


{
  "kimi": {
    "adapter": "openai-responses",
    "baseUrl": "https://api.kimi.com/coding/v1",
    "authMode": "oauth",
    "defaultModel": "kimi-for-coding"
  },
  "kimi-code": {
    "adapter": "openai-responses",
    "baseUrl": "https://api.kimi.com/coding/v1",
    "authMode": "key",
    "apiKey": "sk-kimi-***",
    "defaultModel": "kimi-for-coding"
  }
}


Request through the proxy:


curl -s -X POST http://127.0.0.1:10100/v1/responses \
  -H 'content-type: application/json' \
  -d '{"model":"kimi-code/kimi-for-coding","input":"say OK","max_output_tokens":32}'


Routing resolution and preset availability:


$ ocx api explain --model kimi-for-coding --inbound responses
responses kimi-for-coding: translated (direct route, preview)
  kimi-code/kimi-for-coding: translated responses > ir > chat

$ curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:10100/api/provider-presets
{"providers": [... 100 entries ...]}   # no "kimi-responses"

$ ocx provider add kimi-responses --live
Error: Provider operation did not return a usable outcome.


Control experiment isolating the cause to registry authority — same credential, same base URL, non-registry provider id:


$ ocx provider add kimi-resp --adapter openai-responses \
    --base-url https://api.kimi.com/coding/v1 --auth-mode key --live
$ ocx api protocols --provider kimi-resp
Provider kimi-resp: adapter openai-responses (operator), upstream responses, auth key


The same request then succeeds, and the request log records `attempts: [{"adapter": "openai-responses", "status": 200}]`.
Actual response or error
No HTTP error — this is a silent protocol downgrade plus an unreachable preset, not a failed request. Observable symptoms: the dashboard source label `提供商目录`, the `Responses → Chat · 已转换` badge in the request log, `"adapter": "openai-chat"` on the logged attempt, and the absence of `kimi-responses` from `/api/provider-presets`.
Upstream documentation
  • Kimi Code — Use with Codex (official integration guide): https://www.kimi.com/code/docs/third-party-tools/codex.html
    • "Kimi Code 服务端原生支持 OpenAI Responses API(流式/非流式、reasoning、function calling 均可用)"
    • wire_api = "responses" is required for the native path
    • "推荐使用 Kimi Coding Plan 原生接口协议,以获得最佳效果稳定性,代理协议转换可能引起效果波动"
  • Kimi API platform — overview / Responses API: https://platform.kimi.ai/docs/overview
Suggested mapping or implementation notes
  • Reuse the #5673 mechanism: registry modelWireDefaults keyed by model id and gated on the inbound surface, so only Responses inbound switches to openai-responses.
  • Keep it a per-model opt-in rather than flipping the whole preset on route existence alone, per the review guidance on #5097.
  • Once Responses is reachable without hand-editing, the Chat-path-only normalizations must stay correct: tool-result adjacency (#4726) and the encrypted-include rejection reported in #8075.
  • If a dashboard control is preferred over registry defaults, the existing 使用其他协议的模型 table already renders the resolved wire and its source, so it is a natural place to make editable.
  • The /api/provider-presets omission deserves an explicit decision either way: if these OAuth presets are intentionally CLI-only, that should be stated, and provider add should fail with a clear reason instead of a generic "no usable outcome".
Additional context and attachments
  • Precedent: #5097 (same class of report for Alibaba Token Plan) → fixed by #5673 via modelWireDefaults.
  • Related Kimi Responses reports: #4726 (tool-result adjacency on the Kimi Responses wire), #8075 (Kimi rejects output.encrypted_content from Codex App), #7708 (account-specific context budgets).
  • The registry already defines a kimi-responses preset (adapter: "openai-responses", authKind: "oauth", oauthId: "kimi"), so this is not a request for new upstream support — only for making the existing capability reachable and not overridden.
  • No credentials, request ids, account identifiers or session data are included; key material is redacted and the provider blocks show configuration shape only.
Checks
  • I searched existing provider and compatibility issues.
  • The request and response were redacted.
  • The expected behaviour is based on an upstream specification or a concrete client requirement.
Dominant language
TypeScript
Stars
16.9k
Forks
1.3k
Avg merge
18h 28m
Merged PRs (30d)
697

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from lidge-jun/opencodex

All issues in lidge-jun/opencodex

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.