Skip to content

fix(opencode): restore Zen model catalog#92495

Merged
sallyom merged 16 commits into
openclaw:mainfrom
mushuiyu886:fix/issue-92479-opencode-zen-catalog
Jun 28, 2026
Merged

fix(opencode): restore Zen model catalog#92495
sallyom merged 16 commits into
openclaw:mainfrom
mushuiyu886:fix/issue-92479-opencode-zen-catalog

Conversation

@mushuiyu886

@mushuiyu886 mushuiyu886 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: the bundled opencode Zen provider exposed auth/setup but did not own a Zen model catalog/resolver, so users had to hand-register opencode/<model> rows; review also found route/cost/docs drift around MiniMax, static Zen metadata, and the documented Gemini example.
  • Solution: restore the Zen provider-owned catalog, dynamic resolver, runtime discovery filter, route normalization, provider-discovery static catalog, manifest anchor metadata, cost metadata, and regression tests at the opencode plugin boundary.
  • Latest follow-up: this update moves the full 49-row offline Zen catalog behind providerCatalogEntry/provider discovery, trims openclaw.plugin.json to 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.
  • What changed: the PR now filters live discovery to provider-owned rows only, keeps the curated 49-row seed visible through provider discovery when live discovery is unavailable, routes MiniMax through the Zen OpenAI-compatible /v1/chat/completions path, preserves required cost metadata 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 adds glm-5.2 after authenticated Zen /models returned it.
  • Why it matters / User impact: users can select advertised opencode/<model> Zen models without hand-writing every model row, and docs no longer point them at an unresolved Gemini reference.
  • Out of scope: this does not change non-OpenCode providers, opencode-go runtime behavior, generic LLM adapter APIs, the shared OpenCode credential fallback policy, or the public model/config cost contract.
  • Fixes bug(opencode): Zen provider ships no model catalog — every Zen model must be hand-registered (opencode-go discovers, opencode does not) #92479

Origin / follow-up

  • Follows / completes: This updates the existing fix(opencode): restore Zen model catalog #92495 repair branch after ClawSweeper flagged live-only Zen row synthesis, missing successful MiniMax live proof, cost-contract failures, and a stale documented Gemini example.
  • Gap this fills: The branch now proves the documented examples resolve, refreshes authenticated Zen /models proof with a redacted key, and keeps MiniMax on the verified OpenAI-compatible Zen route.
  • Consistency: The live-discovery behavior matches the shared buildLiveModelProviderConfig shape used by opencode-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 mirrors opencode-go by exposing the complete catalog through provider discovery instead of forcing every row into the manifest.

Competition / linked PR analysis

  • Linked PR(s): fix(opencode): restore Zen model catalog #92495 is the existing linked PR for bug(opencode): Zen provider ships no model catalog — every Zen model must be hand-registered (opencode-go discovers, opencode does not) #92479; check-upstream-fixed found origin/main does not already cover this repair.
  • Related open PR / same-contract scan: The linked issue and ClawSweeper review identify this PR as the active candidate fix. I did not find a same-contract canonical PR on origin/main superseding the Zen catalog owner-boundary repair.
  • Gap in linked PR(s): The current linked PR itself had author-actionable gaps: live-only discovery rows were exposed with inferred metadata, MiniMax was grouped with the Zen Anthropic Messages route, cost metadata briefly violated the required model contract, and docs referenced gemini-3-pro, which the provider could not resolve.
  • Why this patch is better/canonical: It fixes the gaps at the provider-owned catalog/routing/docs boundary instead of adding downstream special cases, publishing guessed live-only rows, or widening the shared model schema from one provider PR.

Real behavior proof

  • Behavior or issue addressed: The bundled opencode Zen provider now exposes usable opencode/<model> rows without hand-written user config. Documented Zen examples resolve through the provider runtime, authenticated Zen /models discovery returns the expected curated rows including glm-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.
  • Real environment tested: Linux, Node/Vitest/pnpm in the local OpenClaw PR worktree. The OpenCode Zen API key was used only as a transient environment variable for live proof; logs redact secret-like strings and the key is not stored in the repo or PR body.
  • Exact steps or command run after this patch:
cd "$TASK_WORKTREE"

git diff --check
node scripts/run-vitest.mjs extensions/opencode/index.test.ts

# Fresh validation after sync-main and the credential-scoped cache regression:
node scripts/run-vitest.mjs extensions/opencode/index.test.ts
git diff --check

pnpm docs:list
pnpm run check:test-types
pnpm run tsgo:prod
pnpm run test:extensions:package-boundary:compile
pnpm run test:extensions:package-boundary:canary

OPENCODE_API_KEY=[REDACTED] node --import tsx <redacted live proof runner>
curl -H "Authorization: Bearer [REDACTED]" -H "Accept: application/json" https://opencode.ai/zen/v1/models
  • Evidence after fix: Focused provider regression tests now include the docs/catalog contract, provider-discovery offline catalog contract, manifest-anchor cost contract, live-only discovery filtering, static fallback, and credential-scoped live discovery cache behavior. The earlier branch validation passed all 13 tests, and the fresh sync-main follow-up passes all 14 tests:
Test Files  1 passed (1)
     Tests  13 passed (13)
[test] passed 1 Vitest shard in 56.04s
node scripts/run-vitest.mjs extensions/opencode/index.test.ts
Test Files  1 passed (1)
Tests  14 passed (14)
[test] passed 1 Vitest shard in 29.99s
git diff --check
# passed with no output

The docs list command completed before the type/package-boundary gates, and the type gates completed successfully:

## pnpm docs:list
$ node scripts/docs-list.js
Listing all markdown files in docs folder:
...
## pnpm run check:test-types
$ pnpm tsgo:test
...
## pnpm run tsgo:prod
$ pnpm tsgo:core && pnpm tsgo:extensions

The extension package-boundary checks passed in both compile and canary modes:

extension package boundary check passed
mode: compile
compiled plugins: 115
canary plugins: 0
extension package boundary check passed
mode: canary
compiled plugins: 0
canary plugins: 2

The fresh authenticated Zen live proof passed with the redacted key:

step=documented_examples_resolve
opencode/claude-opus-4-6 -> api=anthropic-messages baseUrl=https://opencode.ai/zen
opencode/gpt-5.5 -> api=openai-responses baseUrl=https://opencode.ai/zen/v1
opencode/gemini-3.1-pro -> api=google-generative-ai baseUrl=https://opencode.ai/zen/v1
opencode/glm-5.2 -> api=openai-completions baseUrl=https://opencode.ai/zen/v1
step=live_catalog_builder
modelCount=49
requiredIdsPresent.claude-opus-4-6=true
requiredIdsPresent.gpt-5.5=true
requiredIdsPresent.gemini-3.1-pro=true
requiredIdsPresent.glm-5.2=true
requiredIdsPresent.minimax-m2.7=true
minimaxRoute.api=openai-completions
minimaxRoute.baseUrl=https://opencode.ai/zen/v1
step=authenticated_models_endpoint
status=200
finalUrl=https://opencode.ai/zen/v1/models
liveModelCount=49
requiredIdsPresentInLiveModels.claude-opus-4-6=true
requiredIdsPresentInLiveModels.gpt-5.5=true
requiredIdsPresentInLiveModels.gemini-3.1-pro=true
requiredIdsPresentInLiveModels.glm-5.2=true
requiredIdsPresentInLiveModels.minimax-m2.7=true
minimaxIds=minimax-m2.5,minimax-m2.7,minimax-m3-free
requiredIdsPresentInLiveModels.minimax-m3=false
step=minimax_openai_compatible_completion
status=200
modelId=minimax-m2.7
api=openai-completions
endpoint=https://opencode.ai/zen/v1/chat/completions
assistantTextLength=324
step=live_proof_result
result=PASS
checks=documented OpenCode Zen examples resolve through provider runtime, including opencode/glm-5.2; runtime live catalog builder consumes authenticated Zen /models rows through its fetch guard and returns required curated rows; GET https://opencode.ai/zen/v1/models succeeds and includes required curated rows including glm-5.2; minimax-m2.7 uses openai-completions at https://opencode.ai/zen/v1 and returns non-empty assistant content; current authenticated Zen catalog does not expose minimax-m3, only minimax-m3-free

The cost-contract summary remains satisfied: the 49-row provider-discovery seed and the four manifest anchors have no missing cost fields, glm-5.2 uses provider-owned OpenCode GLM metadata, tiered public-doc rows keep tieredPricing, and free rows are explicit zero-cost rows.

  • Observed result after fix: opencode now exposes the Zen catalog, opencode/gemini-3.1-pro and opencode/glm-5.2 are documented resolvable examples, authenticated Zen /models returns the required curated rows including glm-5.2, minimax-m2.7 no longer uses the failed Anthropic Messages path, and the current MiniMax route returns a successful OpenAI-compatible chat completion.
  • What was not tested: This latest live proof does not re-run paid completions for every Zen family; it focuses on authenticated catalog discovery, documented example resolution including GLM-5.2, provider-discovery static catalog coverage, and the MiniMax route ClawSweeper specifically challenged. Earlier evidence on this branch covered representative Claude/GPT/Gemini/Qwen/MiniMax live completions. The authenticated Zen catalog did not expose 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 shared opencode/opencode-go credential fallback policy.

Review findings addressed

  • RF-001 — 49-row static seed drift risk: Reduced the manifest ownership surface by moving the complete 49-row offline catalog behind providerCatalogEntry: "./provider-discovery.ts", while keeping openclaw.plugin.json to four representative route/cost anchors. The focused test now proves provider discovery exposes all 49 rows including glm-5.2, and the manifest anchors still match runtime cost metadata.
  • RF-002 — shared OpenCode credential fallback policy: Left the existing shared opencode/opencode-go credential 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.
  • RF-003 — current-head CI/check completion: The previously visible current-head CI, CodeQL Critical Quality, OpenGrep, labeler, dependency guard, security guard, workflow sanity, and Real behavior proof runs were passing for the pre-sync head; after sync-main, fresh local extensions/opencode/index.test.ts validation passes all 14 tests and git diff --check passes. Earlier queued/cancelled entries remain stale workflow noise, not current patch failures.
  • RF-004 — maintainer decision boundary: The remaining provider-owner decision is now narrower: accept the provider-owned 49-row TS source-of-truth and four manifest anchors, instead of accepting a full 49-row user-visible manifest blob. No automated repair is needed for the split-key policy decision.
  • RF-005 — real behavior proof refresh: Addressed with fresh redacted OpenCode Zen live proof in opencode-zen-live-proof-20260622.log: authenticated /models returned 49 rows including the documented examples and minimax-m2.7, and MiniMax returned a 200 OpenAI-compatible chat completion on https://opencode.ai/zen/v1/chat/completions.
  • RF-006 — re-review / proof refresh request: Addressed by syncing the branch to current origin/main, rerunning focused extensions/opencode/index.test.ts validation 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.
  • Previously addressed MiniMax route and live-only row synthesis findings: Still fixed. MiniMax M2.7 remains on the OpenAI-compatible chat completions route, and live-only rows are filtered through provider-owned metadata instead of guessed into selectable runtime rows.

Regression Test Plan

  • Target test file: extensions/opencode/index.test.ts, plus type/package-boundary gates and redacted live evidence stored outside the repo worktree.
  • Scenario locked in: Regression tests assert provider discovery exposes the complete 49-row offline Zen catalog including glm-5.2, the manifest keeps only four representative route/cost anchors, dynamic model resolution works for Zen IDs, documented docs/providers/opencode.md Zen examples are resolvable, shared opencode-go credentials can populate the opencode catalog 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.
  • Why this is the smallest reliable guardrail: A focused provider test locks the source-of-truth catalog/routing/docs/cost contract without broad adapter mocks, while live proof covers the external Zen catalog and the exact MiniMax route that review requested.

Merge risk

  • Risk labels considered: merge-risk: 🚨 compatibility, merge-risk: 🚨 auth-provider, provider catalog/routing, provider-discovery metadata, manifest anchors, docs accuracy, and catalog seed review cost.
  • Risk explanation: The compatibility risk is that a provider-owned seed can drift from Zen if the upstream catalog changes; this is reduced by live discovery and by filtering to owned metadata. The auth-provider risk is bounded to resolving the same OpenCode credential across opencode and opencode-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.
  • Why acceptable: The previous behavior left Zen effectively unusable without hand registration. This patch restores the provider contract at the owner boundary, keeps live discovery as the preferred source when credentials are present, prevents live-only metadata synthesis, preserves a no-discovery local seed through provider discovery, fixes the concrete MiniMax routing defect, and keeps docs examples aligned with resolvable model rows.

Root Cause

  • Root cause: The opencode Zen provider was migrated as an auth/setup surface without owning the Zen model catalog contract that opencode-go already 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.
  • Why this is root-cause fix: The patch restores the missing provider-owned catalog/resolver boundary, keeps rich metadata owned by the provider seed, fixes MiniMax route selection before downstream adapter execution, keeps the existing required cost contract, and makes docs examples test against the same resolver users rely on.
  • Fix classification: Root-cause provider catalog, routing, docs, and model-cost contract repair for the bundled opencode Zen provider.
  • Maintainer-ready confidence: High for author-actionable source repair: catalog restoration, live-only synthesis filtering, MiniMax route proof, cost-contract coverage, docs/example regression, type gates, package-boundary checks, and fresh authenticated Zen live proof are all covered.
  • Patch quality notes: The fallback/default warnings are intentional provider-catalog boundary behavior, not symptom masking: live Zen discovery is advisory, provider-owned static rows remain visible through provider discovery when discovery is unavailable, and unknown live-only IDs are filtered rather than guessed into selectable rich model rows. This follow-up reduces manifest review cost by moving the full offline catalog out of openclaw.plugin.json and into the provider-owned TS discovery source.
  • Architecture / source-of-truth check: The opencode provider 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.
  • Out of scope: final provider-owner approval of the full 49-row seed membership, split-key policy changes for opencode versus opencode-go, non-OpenCode provider behavior, and schema-wide model cost contract changes.

@openclaw-barnacle openclaw-barnacle Bot added extensions: opencode size: L triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 12, 2026
@clawsweeper

clawsweeper Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 28, 2026, 12:02 PM ET / 16:02 UTC.

Summary
The PR adds an OpenCode Zen provider-owned model catalog, runtime/live discovery hooks, route normalization, manifest anchors, docs example updates, focused regression tests, and a live catalog drift canary.

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 Unknown model for advertised opencode/... refs on v2026.6.10.

Review metrics: 2 noteworthy metrics.

  • Provider Catalog Surface: 1 providerCatalogEntry added; 4 manifest anchors; 49 static discovery rows. This is the compatibility-sensitive offline model catalog surface maintainers must own after merge.
  • Credential/Config Surface: 0 env vars or config options added; shared OpenCode fallback retained. The PR fixes catalog resolution without widening configuration, but keeps existing shared credential behavior in the merge decision.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #92479
Summary: This PR is the active candidate fix for the canonical missing OpenCode Zen catalog regression; adjacent split-key credential policy remains separately tracked.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦀 challenger crab
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Risk before merge

  • [P1] Merging makes OpenClaw own a 49-row provider catalog for OpenCode Zen; the live drift canary helps, but upstream model ids, costs, context windows, or routing can still require maintenance updates over time.
  • [P2] The PR intentionally retains the shared opencode/opencode-go credential fallback, leaving separate Zen and Go key policy to [Feature]: Support separate Zen and Go API key env vars #87790 rather than solving it here.

Maintainer options:

  1. Accept the provider-owned seed with canary coverage (recommended)
    Merge with explicit owner acceptance that opencode maintains the 49-row seed and uses the live drift canary to catch future Zen catalog drift.
  2. Narrow the seed before merge
    If maintainers do not want to own the full static seed, reduce it to an approved subset and keep live discovery/filtering around that smaller metadata set.
  3. Pause for split-key policy
    If separate Zen and Go credentials must be solved in the same release, pause this PR and resolve [Feature]: Support separate Zen and Go API key env vars #87790 first.

Next step before merge

  • No automated repair is needed; the remaining action is maintainer acceptance of the catalog/auth-provider tradeoff and normal merge gating.

Security
Cleared: The diff adds provider catalog code, tests, and docs without changing dependencies, lockfiles, workflows, secret handling storage, or broadening execution permissions; live fetches use the existing bounded SSRF-guarded catalog helper.

Review details

Best 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 Unknown model for advertised opencode/... refs on v2026.6.10.

Is this the best way to solve the issue?

Yes. Restoring catalog, route, cost, docs, and live discovery at the extensions/opencode provider boundary matches the sibling opencode-go pattern and avoids downstream special cases.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 27c1685f106d.

Label changes

Label justifications:

  • P1: The PR fixes a user-confirmed OpenCode Zen regression where advertised opencode model refs fail without hand-registering every model row.
  • merge-risk: 🚨 compatibility: The new provider-owned Zen catalog can drift from upstream model availability, routing, cost, context, and capability metadata over time.
  • merge-risk: 🚨 auth-provider: The runtime catalog path still shares opencode and opencode-go credential fallback behavior, which affects provider model discovery and key selection.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦀 challenger crab and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes copied after-fix live output for authenticated Zen model discovery, documented example resolution, MiniMax completion routing, and focused local validation with redacted credentials.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes copied after-fix live output for authenticated Zen model discovery, documented example resolution, MiniMax completion routing, and focused local validation with redacted credentials.
Evidence reviewed

PR surface:

Source +744, Tests +539, Docs 0. Total +1283 across 7 files.

View PR surface stats
Area Files Added Removed Net
Source 4 749 5 +744
Tests 2 540 1 +539
Docs 1 5 5 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 7 1294 11 +1283

What I checked:

  • Current main lacks Zen catalog hooks: Current main registers the OpenCode Zen provider auth/replay/media hooks but has no catalog, augmentModelCatalog, or resolveDynamicModel hook for non-default Zen rows. (extensions/opencode/index.ts:36, 27c1685f106d)
  • Current main has no opencode catalog metadata: Searching the current opencode plugin found no provider-catalog, providerCatalogEntry, modelCatalog, resolveDynamicModel, or catalog hook entries. (extensions/opencode, 27c1685f106d)
  • PR wires runtime catalog hooks: The PR head adds normalizeConfig, normalizeResolvedModel, normalizeTransport, resolveDynamicModel, catalog.run, and augmentModelCatalog to the opencode provider registration. (extensions/opencode/index.ts:96, c80f81029ded)
  • PR adds provider-owned static/live catalog: The PR head defines a 49-row OpenCode Zen seed, transport routing, cost metadata, live discovery filtering, static fallback, and dynamic model resolution in the plugin boundary. (extensions/opencode/provider-catalog.ts:267, c80f81029ded)
  • Manifest and provider discovery are aligned: The PR head adds providerCatalogEntry plus four manifest model anchors, and provider-discovery exposes the full static catalog through the provider discovery surface. (extensions/opencode/openclaw.plugin.json:7, c80f81029ded)
  • Regression coverage targets the catalog contract: PR-head tests assert all 49 Zen ids resolve, docs examples resolve, manifest anchors retain matching cost metadata, live-only rows are filtered, static fallback remains, and live discovery cache is credential-scoped. (extensions/opencode/index.test.ts:81, c80f81029ded)

Likely related people:

  • magimetal: The original OpenCode Zen provider work included the old core Zen model catalog that this PR restores at the plugin boundary. (role: historical catalog author; confidence: high; commits: a399fa36c81a; files: src/agents/opencode-zen-models.ts, src/commands/opencode-zen-model-default.ts)
  • steipete: History shows the bundled provider plugin migration touched both opencode plugin files, and a later dead-code refactor removed the orphaned core Zen catalog files. (role: provider-boundary refactor author; confidence: high; commits: 8e2a1d0941c7, 8477f1841ad7; files: extensions/opencode/index.ts, extensions/opencode/openclaw.plugin.json, src/agents/opencode-zen-models.ts)
  • vincentkoc: Recent shared OpenCode catalog/auth helper work touched both opencode and opencode-go provider surfaces involved in the shared credential behavior. (role: recent area contributor; confidence: medium; commits: 66701d5a1e16; files: extensions/opencode/index.ts, extensions/opencode-go/index.ts, src/plugin-sdk/opencode.ts)
  • fuller-stack-dev: The merged live provider model catalog helper PR added the shared live discovery/cache machinery and opencode-go catalog pattern this PR mirrors. (role: adjacent catalog infrastructure owner; confidence: medium; commits: e9cfd912adc6; files: src/plugin-sdk/provider-catalog-live-runtime.ts, src/plugin-sdk/provider-catalog-shared.ts, extensions/opencode-go/provider-catalog.ts)
  • sallyom: The assignee added the latest live drift canary commit and posted the review note accepting the 49-row seed as the intended repair shape. (role: recent reviewer and likely follow-up owner; confidence: medium; commits: c80f81029ded; files: extensions/opencode/opencode.live.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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 keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels Jun 12, 2026
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 12, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jun 12, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 12, 2026
@mushuiyu886

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@mushuiyu886

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 13, 2026
@openclaw-barnacle openclaw-barnacle Bot added the docs Improvements or additions to documentation label Jun 21, 2026
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 21, 2026
@mushuiyu886

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@xuwei-xy

Copy link
Copy Markdown

A potential solution is to modify api. What do you think?

@daohunliwei

Copy link
Copy Markdown

+1 to the urgency. Hit the same regression on 2026.6.10 — running openclaw onboard --auth-choice opencode-zen and then setting agents.defaults.model.primary: "opencode/claude-opus-4-6" immediately errors with Unknown model: opencode/claude-opus-4-6 on the very first turn.

As a workaround I had to hand-register all 49 Zen models in models.providers.opencode.models[] (with baseUrl, api, cost, context windows scraped from the public https://opencode.ai/docs/zen/ table). It works, but doctor keeps warning models.providers.opencode is set; this overrides the built-in OpenCode Zen catalog even though there's no built-in catalog to override.

Two questions for maintainers:

  1. Is there a target release for this fix? It'd be much cleaner to drop our hand-rolled catalog once the plugin ships a real one, and to silence the doctor false positive.
  2. The claude-sonnet-4-5 / claude-sonnet-4 family has tiered pricing (≤200K vs >200K context) on the Zen docs page — does the new catalog model that, or is cost tracked per-token at runtime?

Happy to test the next RC and report back.

@mushuiyu886

mushuiyu886 commented Jun 27, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @daohunliwei for the concrete repro and for calling out the tiered-pricing detail.

I verified the current PR state against that question:

  • The OpenCode Zen catalog side now does model the claude-sonnet-4 and claude-sonnet-4-5 tiers in the static provider catalog: 0..200K uses input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75; >=200K uses input: 6, output: 22.5, cacheRead: 0.6, cacheWrite: 7.5.
  • The openclaw onboard --auth-choice opencode-zen path now exposes the OpenCode Zen catalog rows, including opencode/claude-opus-4-6, without hand-registering all Zen models.
  • One caveat: I would not yet claim end-to-end usage-cost accounting is fully wired for manifest-only tiered pricing. I tested a Gateway usage-cost --json --expect-final path with synthetic opencode/claude-sonnet-4-5 transcript usage above and below 200K, and it did not recompute from the manifest tiered pricing; it preserved the transcript-recorded cost. So the catalog metadata is present, but usage-cost still needs the tiered pricing to reach the configured/gateway pricing-cache lookup path before we can call that part complete.

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.

@sallyom

sallyom commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Local maintainer review note on the 49-row static seed:

The 49-row static seed is the right repair here. OpenCode Zen's live /models endpoint exposes model ids, but OpenClaw needs provider-owned routing, base URL, context, capability, and cost metadata to make those ids usable offline, during startup, and when live discovery cannot run. Keeping that metadata in extensions/opencode is the correct owner boundary and matches the existing opencode-go catalog shape.

This is not a new catalog pattern for OpenClaw: bundled providers already carry provider-owned static model metadata with live-discovery fallback, including opencode-go, Chutes, Venice, and DeepInfra. The new Zen drift canary makes this static seed better guarded than several existing fallback catalogs.

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 extensions/opencode/opencode.live.test.ts that compares the provider-owned static seed against the current Zen /v1/models id set and reports both missing static metadata and stale static rows. I verified it with:

OPENCLAW_LIVE_TEST=1 pnpm exec vitest run --config test/vitest/vitest.live.config.ts extensions/opencode/opencode.live.test.ts --reporter=verbose

Result: 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 c80f81029deddd0b5a5dba78e66a174e9977d331.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation extensions: opencode merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: XL status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(opencode): Zen provider ships no model catalog — every Zen model must be hand-registered (opencode-go discovers, opencode does not)

4 participants