fix(opencode): restore Zen model catalog#92495
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 28, 2026, 12:02 PM ET / 16:02 UTC. Summary PR surface: Source +744, Tests +539, Docs 0. Total +1283 across 7 files. Reproducibility: yes. Source inspection shows current main has no opencode Zen catalog or dynamic resolver, and linked users reproduced Review metrics: 2 noteworthy metrics.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the provider-boundary catalog repair after maintainers accept the catalog drift ownership and shared credential policy tradeoff, while keeping split-key behavior tracked separately. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main has no opencode Zen catalog or dynamic resolver, and linked users reproduced Is this the best way to solve the issue? Yes. Restoring catalog, route, cost, docs, and live discovery at the AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 27c1685f106d. Label changesLabel justifications:
Evidence reviewedPR surface: Source +744, Tests +539, Docs 0. Total +1283 across 7 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
A potential solution is to modify api. What do you think? |
|
+1 to the urgency. Hit the same regression on As a workaround I had to hand-register all 49 Zen models in Two questions for maintainers:
Happy to test the next RC and report back. |
|
Thanks @daohunliwei for the concrete repro and for calling out the tiered-pricing detail. I verified the current PR state against that question:
So the answer is: the catalog now models the tiers, but runtime/session cost reporting still has a follow-up gap. I can split that into a follow-up fix if maintainers want this PR to stay focused on restoring Zen catalog resolution. |
|
Local maintainer review note on the 49-row static seed: The 49-row static seed is the right repair here. OpenCode Zen's live This is not a new catalog pattern for OpenClaw: bundled providers already carry provider-owned static model metadata with live-discovery fallback, including This does not add new SDK, config, CLI, env-var, or public API surface. I do not see breaking changes for upgrades: existing broken/unknown Zen model refs become resolvable, existing configured provider rows still go through the normal config merge path, and live discovery narrows to currently advertised known rows when credentials are available. The only compatibility-sensitive point is catalog drift over time. To reduce that maintainer burden, we added a live-only drift canary in OPENCLAW_LIVE_TEST=1 pnpm exec vitest run --config test/vitest/vitest.live.config.ts extensions/opencode/opencode.live.test.ts --reporter=verboseResult: 1 passed, 1 skipped. Current live Zen returns the same 49 ids as this seed, including the manifest/docs anchors. Autoreview was clean, ClawSweeper has no actionable code findings, CI was green before the test-only follow-up, and the local review found this to be the best narrow fix for the real #92479 issue. Latest head is |
Signed-off-by: sallyom <[email protected]>
Summary
opencodeZen provider exposed auth/setup but did not own a Zen model catalog/resolver, so users had to hand-registeropencode/<model>rows; review also found route/cost/docs drift around MiniMax, static Zen metadata, and the documented Gemini example.opencodeplugin boundary.providerCatalogEntry/provider discovery, trimsopenclaw.plugin.jsonto four representative route/cost anchors, keeps the documented Gemini and GLM-5.2 examples resolvable, and adds a sync-main follow-up regression for credential-scoped live discovery caching./v1/chat/completionspath, preserves requiredcostmetadata for every runtime row and manifest anchor, verifies the docs examples are resolvable, proves different OpenCode discovery credentials do not share cached live catalog rows, and addsglm-5.2after authenticated Zen/modelsreturned it.opencode/<model>Zen models without hand-writing every model row, and docs no longer point them at an unresolved Gemini reference.opencode-goruntime behavior, generic LLM adapter APIs, the shared OpenCode credential fallback policy, or the public model/config cost contract.Origin / follow-up
/modelsproof with a redacted key, and keeps MiniMax on the verified OpenAI-compatible Zen route.buildLiveModelProviderConfigshape used byopencode-go: use live discovery when authenticated rows are available, filter to provider-owned metadata rows, and retain the static seed when discovery is unavailable or not provider-owned. The offline static surface also now mirrorsopencode-goby exposing the complete catalog through provider discovery instead of forcing every row into the manifest.Competition / linked PR analysis
check-upstream-fixedfoundorigin/maindoes not already cover this repair.origin/mainsuperseding the Zen catalog owner-boundary repair.gemini-3-pro, which the provider could not resolve.Real behavior proof
opencodeZen provider now exposes usableopencode/<model>rows without hand-written user config. Documented Zen examples resolve through the provider runtime, authenticated Zen/modelsdiscovery returns the expected curated rows includingglm-5.2, unknown live-only IDs are not promoted without owned metadata, MiniMax uses the OpenAI-compatible Zen v1 route, and every static Zen row remains compatible with the required model cost contract.The docs list command completed before the type/package-boundary gates, and the type gates completed successfully:
The extension package-boundary checks passed in both compile and canary modes:
The fresh authenticated Zen live proof passed with the redacted key:
The cost-contract summary remains satisfied: the 49-row provider-discovery seed and the four manifest anchors have no missing
costfields,glm-5.2uses provider-owned OpenCode GLM metadata, tiered public-doc rows keeptieredPricing, and free rows are explicit zero-cost rows.opencodenow exposes the Zen catalog,opencode/gemini-3.1-proandopencode/glm-5.2are documented resolvable examples, authenticated Zen/modelsreturns the required curated rows includingglm-5.2,minimax-m2.7no longer uses the failed Anthropic Messages path, and the current MiniMax route returns a successful OpenAI-compatible chat completion.minimax-m3, so this update does not add or claim a paid MiniMax M3 row. I also did not change or prove final product decisions for the full 49-row seed membership or the sharedopencode/opencode-gocredential fallback policy.Review findings addressed
providerCatalogEntry: "./provider-discovery.ts", while keepingopenclaw.plugin.jsonto four representative route/cost anchors. The focused test now proves provider discovery exposes all 49 rows includingglm-5.2, and the manifest anchors still match runtime cost metadata.opencode/opencode-gocredential fallback unchanged because it matches current docs and sibling behavior; the split-key policy remains out of scope for [Feature]: Support separate Zen and Go API key env vars #87790. Added a provider-level regression proving different discovery credentials do not reuse the same live catalog cache rows.sync-main, fresh localextensions/opencode/index.test.tsvalidation passes all 14 tests andgit diff --checkpasses. Earlier queued/cancelled entries remain stale workflow noise, not current patch failures.opencode-zen-live-proof-20260622.log: authenticated/modelsreturned 49 rows including the documented examples andminimax-m2.7, and MiniMax returned a 200 OpenAI-compatible chat completion onhttps://opencode.ai/zen/v1/chat/completions.origin/main, rerunning focusedextensions/opencode/index.test.tsvalidation after the sync, adding the credential-scoped live discovery cache regression, and keeping the existing redacted OpenCode Zen live proof plus explicit not-tested boundaries in this PR body.Regression Test Plan
extensions/opencode/index.test.ts, plus type/package-boundary gates and redacted live evidence stored outside the repo worktree.glm-5.2, the manifest keeps only four representative route/cost anchors, dynamic model resolution works for Zen IDs, documenteddocs/providers/opencode.mdZen examples are resolvable, sharedopencode-gocredentials can populate theopencodecatalog path, Claude/GPT/Gemini/GLM/Qwen/MiniMax families route to the expected adapter/base URL pairs, live-only discovery rows are filtered until metadata is owned, live discovery cache entries stay scoped to discovery credentials, every provider-discovery/runtime row and manifest anchor has required cost metadata, and static fallback remains visible when live discovery is unavailable or returns no owned IDs.Merge risk
merge-risk: 🚨 compatibility,merge-risk: 🚨 auth-provider, provider catalog/routing, provider-discovery metadata, manifest anchors, docs accuracy, and catalog seed review cost.opencodeandopencode-go; no key is stored in the repo or PR body. The manifest review risk is reduced because the user-visible manifest now carries only four representative anchors while the complete offline catalog lives in the provider-owned TS discovery source.Root Cause
opencodeZen provider was migrated as an auth/setup surface without owning the Zen model catalog contract thatopencode-goalready supported. Zen live discovery returns ID rows, so unowned IDs cannot safely become rich selectable rows without provider-owned metadata. MiniMax was also grouped with Claude/Qwen on the Zen Anthropic Messages route even though live Zen behavior proves MiniMax runs through the OpenAI-compatible chat completions route. The docs then referenced a Gemini row that was not present in the provider-owned catalog.opencodeZen provider.openclaw.plugin.jsonand into the provider-owned TS discovery source.opencodeprovider plugin is the source-of-truth owner for bundled Zen catalog metadata, route selection, docs examples, provider discovery, and manifest anchor synchronization. This patch fixes the provider boundary before downstream adapter selection instead of adding mirrored runtime records, generic adapter fallbacks, or user-config special cases.opencodeversusopencode-go, non-OpenCode provider behavior, and schema-wide model cost contract changes.