Skip to content

fix(llm): OpenCode Go session header and Go/Zen path detection - #6298

Open
kgrontis wants to merge 2 commits into
odysseus-dev:devfrom
kgrontis:fix/opencode-go-session-header
Open

kgrontis wants to merge 2 commits into
odysseus-dev:devfrom
kgrontis:fix/opencode-go-session-header

Conversation

@kgrontis

@kgrontis kgrontis commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Summary

OpenCode Go rejects chat requests without a stable x-opencode-session header (HTTP 400), and Odysseus never sent it — plus _detect_provider() could never return opencode-go/opencode-zen because _host_match() is hostname-only while zen/zen/go are path segments. This adds host+path Go/Zen detection, injects an Odysseus/1.0 User-Agent with the per-conversation session id (fallback odysseus-global for probes/model listing), routes Go responses-models (gpt-5.6-luna, grok-4.6, muse-spark) to .../v1/responses with an OpenAI Responses payload, and adds regression tests.

Target branch

  • This PR targets dev, not main. All PRs land in dev; main is curated by the maintainer at each release. If your PR is on main by accident, click "Edit" on this PR and change the base.

Linked Issue

Fixes #6281. Related to #4450.

Type of Change

  • Bug fix (non-breaking — fixes a confirmed issue)
  • New feature (non-breaking — adds new behaviour)
  • Breaking change (changes or removes existing behaviour)
  • Refactor / cleanup (behaviour unchanged)
  • Documentation only
  • CI / tooling / configuration

Checklist

  • I searched open issues and open PRs — this is not a duplicate.
  • This PR targets dev
  • My changes are limited to the scope described above — no unrelated refactors or whitespace changes mixed in.
  • I actually ran the app (docker compose up or uvicorn app:app) and verified the change works end-to-end. Type-checks and unit tests are not enough.
  • I did not run the app/runtime validation and stated that gap in How to Test. Leave this unchecked when the app-run box above is checked.

How to Test

  1. Add a Model Endpoint with base URL https://opencode.ai/zen/go/v1 and a valid Go API key.
  2. Send any chat message (e.g. hey) on a Go model such as longcat-2.0 — before this fix it fails with 400 ... missing x-opencode-session, after it the request carries User-Agent: Odysseus/1.0 and x-opencode-session: <chat session id>.
  3. Automated: run pytest tests/test_opencode_go_responses.py tests/test_opencode_go_headers.py tests/test_provider_detection_detect.py tests/test_provider_detection_host_match.py tests/test_provider_detection_builders.py tests/test_provider_classification.py tests/test_copilot.py tests/test_llm_core_ollama.py -q (from the repo venv) — 129 passed. Also python -m py_compile src/llm_core.py src/endpoint_resolver.py routes/model_routes.py.
  4. Gap: I did not run the full app (docker compose up / uvicorn) or a live Go key end-to-end — no Go subscription key available in this environment — so live verification against opencode.ai/zen/go is still needed by a reviewer with a key.
  5. Already tried live: gpt-5.6-luna and Muse Spark (muse-spark) previously returned Go 500 Internal server error because Odysseus sent all Go traffic to .../v1/chat/completions while Go serves those models on .../v1/responses (https://opencode.ai/docs/go/#endpoints). This PR now routes them to /responses with a Responses payload (reusing the validated Responses SSE path); live re-verification with a Go key is still needed. The /v1/messages Go models (qwen, minimax) remain out of scope.

Visual / UI changes — REQUIRED if you touched anything that renders

No UI/rendering changes (backend src/ + tests/ only).

  • Screenshot or short clip of the change in the running app, attached below. Mobile screenshot too if the change affects mobile.
  • Style match: the change uses Odysseus's existing visual language.
  • No new component patterns.
  • I am not an LLM agent submitting a bulk PR. If you are, please open an issue describing the problem first — bulk auto-generated PRs that don't match the project's visual style are closed on sight, even when the underlying fix is correct.

Screenshots / clips

N/A — no visual change.

…ction

OpenCode Go rejects requests without a stable x-opencode-session header (HTTP 400). Odysseus never sent it, and _detect_provider() could never return opencode-go/opencode-zen because _host_match() is hostname-only while 'zen' and 'zen/go' are path segments. Add host+path detection, inject Odysseus/1.0 User-Agent and per-conversation session header (fallback odysseus-global for probes), and cover with regression tests.
@github-actions

Copy link
Copy Markdown

⚠️ PR description is complete; validation evidence is still outstanding

Changed-file classification: backend/runtime.

Author-reported runtime / visual state

  • The author explicitly reports that app/runtime validation was not performed.

Checkboxes are author attestations. GitHub Actions results remain the execution evidence for CI; this check does not prove that a local command ran.


This comment updates automatically when the description or changed files change.

@github-actions github-actions Bot added the needs runtime validation Runtime validation not attested — tick the app-run box after running it, or state the gap label Sep 14, 2026
Go serves gpt-5.6-luna, grok-4.6 and muse-spark on the OpenAI Responses API, but Odysseus sent every Go model to /chat/completions (HTTP 500). Classify responses-models, build Responses payloads, reuse the validated Responses SSE streaming path, parse non-stream output text, and probe the right URL per model.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs runtime validation Runtime validation not attested — tick the app-run box after running it, or state the gap

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenCode Zen and Go are never detected: _host_match() cannot match path patterns

1 participant