Repository navigation
Pi export: openai-chat providers should emit supportsDeveloperRole: false (or demote developer→system in chat dialect) #5664
Description
Client or integration
Other — pi coding agent (0.85.1), running against the opencodex loopback using the provider block that ocx exports to ~/.pi/agent/models.json (chat dialect, api: "openai-completions").
Provider or upstream service
Alibaba Cloud Bailian DashScope compatible-mode (openai-chat provider)
OpenCodex version
2.63.0
Endpoint or capability
/v1/chat/completions, message role translation (developer role)
Current behaviour
pi sends the system prompt as role: "developer" for models marked reasoning: true (per the newer OpenAI Chat Completions convention). The opencodex openai-chat adapter forwards the developer message verbatim to the upstream. DashScope compatible-mode rejects the role outright:
developer is not one of ['system','assistant','user','tool','function']
So pi → opencodex → any openai-chat provider that does not accept developer fails with 400 on every request.
Additionally, the exported opencodex provider block in ~/.pi/agent/models.json (src/clients/config-export.ts) carries only:
{ "compat": { "sendSessionAffinityHeaders": true } }There is no supportsDeveloperRole: false, and every ocx export rewrites the whole pi provider block, so a user-side manual compat.supportsDeveloperRole: false is clobbered on the next export. There is no persistent workaround.
Expected behaviour
Either one of the following would fix it:
- a) The exporter emits
compat.supportsDeveloperRole: falsefor providers exported with the openai-chat dialect (api: "openai-completions"), so pi sendssysteminstead ofdeveloper. - b) The
openai-chatadapter demotesdeveloper→systemwhen building the outbound chat-dialect request (the/v1/responseschannel already normalizes this — same request with adevelopermessage returns 200 there).
Minimal redacted request or reproduction
opencodex 2.63.0, local loopback :10100, a configured Bailian token-plan provider.
developer role → 400:
curl -s http://127.0.0.1:10100/v1/chat/completions \
-H 'Authorization: Bearer <loopback-key>' \
-H 'Content-Type: application/json' \
-d '{"model":"alibaba-token-plan/qwen3.8-max","messages":[{"role":"developer","content":"sys"},{"role":"user","content":"hi"}],"max_tokens":50}'
# → 400 Provider error 400Same request with role: "system" → 200.
/v1/responses with a developer message → 200 (this channel already normalizes the role), so only chat-dialect clients (pi's default) hit the bug.
Actual response or error
400 Provider error 400
developer is not one of ['system','assistant','user','tool','function']
Upstream documentation
Alibaba Cloud Model Studio (DashScope) OpenAI-compatible mode: https://help.aliyun.com/zh/model-studio/ — there is no public spec page enumerating the accepted role set; the allowed roles are declared by the upstream 400 error body itself: ['system','assistant','user','tool','function'].
Suggested mapping or implementation notes
- Exporter fix is the more robust one: it also covers other pi-side chat-dialect clients and survives the whole-block rewrite on every export.
- Adapter-side demotion (b) fixes all clients at once but changes behavior for upstreams that do accept
developerand expect its distinct precedence (seedevelopermessages are folded into the system prompt on every Chat host except api.openai.com #5213, where folding intosystemwas the complaint). - Related:
developermessages are folded into the system prompt on every Chat host except api.openai.com #5213 (closed) — that issue reported the opposite direction (non-api.openai.comhosts hoistingdeveloperinto the system preamble); on 2.63.0 the observed behavior is verbatim forwarding to an upstream that rejects the role.
Additional context and attachments
- Environment: opencodex 2.63.0 (npm
@bitkyc08/opencodex), macOS, client pi 0.85.1. - No secrets are included; the loopback key is redacted as
<loopback-key>.
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.
Activity
github-actions commentedon Sep 23, 2026
Issue reopened
The report now contains the information required by the automated check. Thanks for updating it.
fix(openai-chat): Pi developer role and duplicated serialized tool ca…
lidge-jun commentedon Sep 23, 2026
Fixed on
devby #5674 (squash-merged as a1dba2c): the Pi and omo client exports now writecompat.supportsDeveloperRole: falsefor openai-chat providers, so Pi sendssysteminstead ofdeveloper. The Pi guide is updated in all eight locales.