Repository navigation
[Provider compatibility] Pi native Chat requests still omit OpenCode Go session affinity in 2.46.0 #3857
Description
Client or integration
OpenAI-compatible SDK
Provider or upstream service
OpenCode Go (opencode-go), through Pi's generated opencodex provider.
OpenCodex version
2.46.0; also reproduced against dev at 6cf38b5 with a mocked upstream regression test.
Endpoint or capability
POST /v1/chat/completions; per-conversation session affinity.
Current behaviour
Pi 0.84.4 requests to opencode-go/omen-alpha fail with HTTP 400 even after updating and restarting OpenCodex. There are two gaps:
- Native Chat takes the shortcut into
handleNativeChatCompletionsbefore the Responses pipeline'sresolveOpenCodeGoTransportcall, so no Go session header is generated even when a client sendssession_id. - The generated Pi provider is named
opencodexand points at the local proxy. Pi therefore does not apply its native OpenCode attribution, and session-affinity headers are disabled by default for this custom provider. The generated config does not opt in.
Expected behaviour
Generated Pi integrations should send a stable per-session identifier. Both native Chat and bridged requests to canonical Go destinations should derive a stable opaque x-opencode-session, preserving configured overrides and keeping distinct conversations separate.
Minimal redacted request or reproduction
# With an authenticated OpenCode Go provider configured in OpenCodex:
curl http://127.0.0.1:10100/v1/chat/completions \
-H 'Content-Type: application/json' \
-H 'session_id: example-conversation-a' \
-d '{"model":"opencode-go/omen-alpha","messages":[{"role":"user","content":"Coding connectivity check: reply OK."}],"stream":false}'
# This exercises native Chat and still omits the upstream Go header before the fix.
# A generated Pi provider additionally needs compat.sendSessionAffinityHeaders=true
# so that Pi sends session_id to the proxy in the first place.Actual response or error
Provider error 400: Error from provider (Console Go): Request is missing x-opencode-session and cannot be routed efficiently. Please see https://opencode.ai/docs/go/#where-can-i-use-it
Upstream documentation
https://opencode.ai/docs/go/#where-can-i-use-it
Suggested mapping or implementation notes
Reuse resolveOpenCodeGoTransport before native Chat wire selection; enable Pi's supported compat.sendSessionAffinityHeaders in generated configs. Preserve inbound OpenCode session metadata through the internal Chat-to-Responses bridge, validate/hash it, and scope upstream injection to canonical Go destinations. Do not add a global static session ID.
Additional context and attachments
Related: #3344, #3378, #3405. Those addressed Responses-ingress normalization; this reports the remaining native Chat ingress and generated Pi configuration gaps. The regression test failed with a null session header before the fix. After patching and enabling Pi affinity, an actual Pi SDK request through the local proxy to Omen returned PI_GO_OK.
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
johnsonmarynpgcq5689-stack commentedon Sep 7, 2026
我在codex中也出现了这个问题
lidge-jun commentedon Sep 7, 2026
리뷰 · 우선순위 70 / 80
이슈 #3857은 Pi가 만든
opencodex제공자로 OpenCode Go(예:opencode-go/omen-alpha)에 Chat Completions를 보낼 때, 업스트림이 요구하는 세션 헤더x-opencode-session이 빠지는 문제입니다. 증상은 명확합니다. HTTP 400과 함께 Console Go가 “Request is missing x-opencode-session and cannot be routed efficiently”를 돌려줍니다. 제보 버전은 설치본 2.46.0이고, 같은 구멍을dev6cf38b5기준으로도 재현했다고 적혀 있습니다. 지금devHEAD(ece556a6e, 패키지 2.47.0, #3854 code-mode host contract까지 반영)에서도 이 구멍은 그대로입니다. #3854는 라우티드 code-mode의 호스트 계약만 다루고 Go 세션 친화도는 건드리지 않았습니다.왜 이렇게 되는지 HEAD 코드로 보면 두 갈래입니다. 첫째, Responses 경로에는 이미
src/server/responses/core.ts약 2307줄에서resolveOpenCodeGoTransport(route.provider, sessionLaneIdFromRequest(req.headers))를 호출합니다.src/providers/opencode-go-transport.ts는 목적지가 카노니컬opencode-go일 때만, 세션 레인 문자열을 SHA-256으로 접어ocx_…형태의 opaquex-opencode-session을 provider.headers에 넣습니다. 설정된 헤더가 이미 있으면 덮지 않습니다. 둘째, Chat Completions 진입점src/server/chat-completions.ts는routeModel직후resolveWireProtocolOverride만 하고(약 138–141줄), native Chat로 갈 자격이 있으면 약 174줄에서 바로handleNativeChatCompletions로 빠져 나갑니다. 이 숏컷에는resolveOpenCodeGoTransport가 없습니다. 그래서 클라이언트가session_id를 보내도 native Chat 와이어로는 Go 헤더가 생기지 않습니다.Pi 쪽도 한 겹 더 있습니다. 생성기
src/clients/config-export.ts의buildPiClientConfig(약 850–870줄)는opencodex블록에baseUrl/api/apiKey/models만 넣고, Pi가 지원하는compat.sendSessionAffinityHeaders를 켜지 않습니다. Pi는 커스텀 제공자에 대해 기본으로 세션 친화도 헤더를 안 보냅니다. 설령 프록시가 헤더를 만들 준비가 되어 있어도, Pi가session_id를 안 주면sessionLaneIdFromRequest(src/server/request-log-conversation.ts약 76줄: parent thread → thread-id → session_id/session-id)가 비어 Go 헤더를 못 만듭니다.FORWARD_HEADERS(src/adapters/openai-responses.ts)에는session_id/session-id는 있지만x-opencode-session은 없습니다. Chat→Responses 내부 브리지가 그 헤더를 따로 넘기지 않으면 브리지 경로에서도 끊깁니다.이 이슈는 이미 닫힌 #3344 / #3378 / #3405의 남은 구멍입니다. 그때는 Responses 입구 정규화가 중심이었고, native Chat 숏컷과 생성 Pi 설정 opt-in은 남겨 둔 상태입니다. #3716 conversation affinity는 계정 풀 쪽이고, Go 업스트림 라우팅 헤더와는 다릅니다. types.ts/config.ts 분할과도 무관합니다. 구현 PR은 #3858(draft)이 같은 작성자로 열려 있습니다.
src/server/chat-completions.ts:138-174 - route 직후 native Chat 숏컷에 resolveOpenCodeGoTransport가 없음. session_id가 있어도 Go 헤더 미생성
src/server/responses/core.ts:2307 - Responses만 resolveOpenCodeGoTransport 호출. Chat native와 비대칭
src/clients/config-export.ts:850-870 buildPiClientConfig - PiProviderBlock에 compat.sendSessionAffinityHeaders 없음. 생성 설정이 session_id를 안 보냄
src/providers/opencode-go-transport.ts:26-42 - 카노니컬 Go + sessionLane 있을 때만 헤더 주입. lane이 비면 no-op(의도)
src/adapters/openai-responses.ts FORWARD_HEADERS - session_id는 전달, x-opencode-session은 미포함. 브리지 메타데이터 별도 전달 필요
메인테이너의 판단이 필요한 지점
너의 추천
이슈는 열어 둔다. 라벨(
provider-compatibility,provider) 유지. 수정은 #3858 한 줄기로: (1) Chat 라우팅 직후 Go transport resolve, (2) 생성 Pi에 sendSessionAffinityHeaders, (3) 브리지에 x-opencode-session 전달, (4) native Chat 회귀 테스트. 전역 고정 세션 ID는 넣지 않는다. #3858이 머지되면 이 이슈는 closes로 같이 닫는다.이 댓글은 grok-bot이 작성했습니다