Skip to content

fix(opencode): route GPT models and discover OSS fallbacks - #239

Open
dgokeeffe wants to merge 4 commits into
databricks:mainfrom
dgokeeffe:fix/opencode-model-routing-followup
Open

fix(opencode): route GPT models and discover OSS fallbacks#239
dgokeeffe wants to merge 4 commits into
databricks:mainfrom
dgokeeffe:fix/opencode-model-routing-followup

Conversation

@dgokeeffe

@dgokeeffe dgokeeffe commented Jul 24, 2026

Copy link
Copy Markdown

Issue and stack

Closes #85.

Depends on #217, #333, and #223. Review only the OpenCode/discovery incremental range:

dgokeeffe/ucode@94fe107...816588f

Do not merge before #223. Once prerequisites merge, the visible PR diff collapses to the eight-file OpenCode unit.


Unit 04 — OpenCode GPT routing and OSS fallback discovery

Objective and user-visible behavior

Route GPT/Codex models through OpenCode's Databricks Responses provider and discover validated OSS serving endpoints when UC model services do not expose them.

Candidate: review/opencode-routing (816588f), mandatory PR target review/pi-gpt-reasoning (94fe107), existing PR #239.

Exact scope

Production: src/ucode/agents/opencode.py, src/ucode/cli.py, src/ucode/databricks.py.
Tests/fixtures: tests/conftest.py, tests/test_agent_opencode.py, tests/test_cli.py, tests/test_databricks.py, tests/test_e2e.py.
Non-goals: Pi behavior, context policy, dynamic OSS capability metadata, MLflow repair proxy, cache behavior.

Before / after reproduction

git diff --stat 94fe107..816588f
# 8 files changed, 480 insertions(+), 20 deletions(-)

git show review/opencode-routing:src/ucode/agents/opencode.py | rg 'databricks-openai|openai-responses'
# databricks-openai provider and model qualification are present

Focused validation:

uv run --frozen pytest tests/test_agent_opencode.py tests/test_cli.py tests/test_databricks.py tests/test_e2e.py -q
# 469 passed, 29 skipped
uv run --frozen ruff check .
# All checks passed

Full suite:

uv run --frozen pytest -q
# 2 failed, 1649 passed, 36 skipped

Failures are installed Claude/Pi User-Agent capture tests. The branch predates the independent config-dir unit; integrated dev passes the Pi capture test and independently reproduces the Claude capture failure.

Live/discovery evidence

No token-bearing output is retained. Fixture coverage reproduces UC-first discovery, serving-endpoint fallback, dialect filtering, validated GLM/Kimi allowlisting, GPT provider qualification, default routing, and per-model E2E configuration with workspace-gated skips.

Impact map

  • Agent: OpenCode.
  • Providers: databricks-openai Responses and existing databricks-oss MLflow provider.
  • Discovery/config: shared state gains OpenCode GPT list and fallback OSS IDs; OpenCode config qualifies defaults by provider.
  • Compatibility: native Claude/Gemini endpoints and unsupported chat models remain excluded from OSS fallback.
  • Pi/MLflow proxy/MCP/skills: unchanged.

Rollback and residual risk

Revert 816588f; OpenCode loses GPT routing and serving-endpoint OSS fallback but existing native-family behavior remains. Residual risk is future endpoint metadata drift; unit 05 adds structured capability validation separately.

Hygiene

git diff --check review/pi-gpt-reasoning..review/opencode-routing passes. PR #239 must target unit 02; its target-relative diff is the review contract. No generated files, credentials, uv.lock, .pi-subagents/, or goal.md; no merge markers or unresolved index entries.

@dgokeeffe

Copy link
Copy Markdown
Author

This stack has been rebuilt on current main with one clean commit per layer. The incremental OpenCode diff is linked in the description; the rejected proxy and broad OSS cohort are gone. Local focused validation is 480 passing with Ruff clean. A maintainer CI approval/review is now the remaining gate.

@dgokeeffe
dgokeeffe force-pushed the fix/opencode-model-routing-followup branch from b53813f to 3f1c227 Compare July 26, 2026 04:38
@dgokeeffe

Copy link
Copy Markdown
Author

Post-review update: OpenCode GPT entries now carry shared context/output limits and prefer the newest eligible GPT; foundation endpoint parsing is defensive against malformed records; CLI fallback tests are deterministic; and the live e2e fixture now populates OpenAI/OSS models and isolates Pi settings paths. Round-3 reviewers found no production blocker; final validation is 588 passed/29 skipped focused and 1062 passed/36 skipped excluding environment-sensitive installed-agent capture tests.

@dgokeeffe

dgokeeffe commented Aug 7, 2026

Copy link
Copy Markdown
Author

Rebased this PR stack onto current main (67429ec) and force-pushed the existing branch. New head: 816588f.

Hard stack dependency

This is 3 of 3 and must land after #223:

  1. feat(pi): add validated GLM/Kimi MLflow provider #217 — Pi MLflow OSS provider
  2. fix(pi): omit unsupported GPT off-reasoning effort #223 — shared Claude/GPT metadata + Pi GPT thinking-off fix
  3. fix(opencode): route GPT models and discover OSS fallbacks #239 — OpenCode GPT routing + OSS discovery fallback (this PR)

This is a code dependency, not just a review preference: #239's preferred_gpt_model uses _normalized_foundation_model_id, and its per-model overlay uses gpt_model_token_limits; both are introduced by #223. #239 cannot safely apply directly to main before #223.

The helper and its tests now live in this PR with their only consumer (src/ucode/agents/opencode.py), rather than leaking into #223.

If #217/#223 are squash-merged, please rebase this branch onto the updated main before merging.

Validation

  • CI-parity suite: 1,648 passed, 6 skipped
  • Only local failures: the two pre-existing CLI capture-server tests (TestClaudeUserAgent, TestPiUserAgent), which skip in CI's unit-test job
  • ruff check and ruff format --check: clean
  • No committed uv.lock churn or conflict markers

This PR adds lower-level OpenCode GPT routing, but managed-config OpenCode GPT mapping and admin allowlist intersection are deliberately deferred to #290.

Expose the GLM and Kimi coding-model cohort through Pi and OpenCode with shared token limits and reasoning metadata. Keep unsupported chat models out of discovery, including Inkling until gateway issue databricks#215 is fixed, and retain the GPT-OSS Responses API routing guard.
Centralize Claude family/version parsing so Pi metadata, adaptive-thinking compatibility, and Claude Code's [1m] selector cannot drift. Cover Sonnet 4.5, Opus 4.6, future major versions, Fable fallback, and prefixed model IDs.
`_pi_gpt_model_entry` declared `reasoning: True` without an off-state, so for
the thinking-off case Pi's Responses builder fell back to
`reasoning: {effort: "none"}` (pi-ai openai-responses.js, the
`thinkingLevelMap?.off !== null` branch). `"none"` is only valid on gpt-5.1+,
so every request to gpt-5, gpt-5-mini, gpt-5-nano and gpt-5-5-pro was rejected:

  BAD_REQUEST: Unsupported value: 'none' is not supported with the 'gpt-5'
  model. Supported values are: 'minimal', 'low', 'medium', and 'high'.

Setting `thinkingLevelMap: {"off": None}` makes Pi omit `reasoning` entirely,
which the gateway accepts for all 14 codex ids. Verified against
/ai-gateway/codex/v1/responses: effort="none" 400s on gpt-5/-mini/-nano/-5-5-pro
and 200s on gpt-5-1..-5-6; omitting `reasoning` is 200 everywhere.
`{"off": "minimal"}` was rejected as an alternative because gpt-5-5-pro 400s on
it too. Same pattern already used for the Gemini 3.x entries.

The rest of Pi's Responses payload was bisected against the gateway and is
fine: store:false, prompt_cache_key, prompt_cache_retention:"24h",
prompt_cache_options, include:["reasoning.encrypted_content"], developer role,
flat tool schemas, and the session_id / x-client-request-id affinity headers.

Regression was hard to spot because the gateway returns
{"error_code","message"} rather than OpenAI's {"error":...}, so Pi's
error-body.js recovery no-ops and every 400 renders as
"OpenAI API error (400): 400 status code (no body)". Reported upstream as
earendil-works/pi#7748.

Refs databricks#286
Configure the Databricks OpenAI Responses provider alongside the validated GLM/Kimi provider, and fall back to foundation-model serving endpoints when UC model services are unavailable.
@dgokeeffe
dgokeeffe force-pushed the fix/opencode-model-routing-followup branch from 48a91ba to 816588f Compare August 7, 2026 10:58
@dgokeeffe dgokeeffe changed the title fix(opencode): add GPT routing alongside OSS discovery fix(opencode): route GPT models and discover OSS fallbacks Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Opencode Model Configuration

1 participant