feat: add shared model utilities and OpenCode 2 (V2) support - #15
Open
Majidalee1 wants to merge 4 commits into
Open
feat: add shared model utilities and OpenCode 2 (V2) support#15Majidalee1 wants to merge 4 commits into
Majidalee1 wants to merge 4 commits into
Conversation
Introduce src/models.ts so the V1 plugin and the upcoming V2 entrypoint
share one source of truth for loading models.json and converting entries
into their runtime-specific shapes.
- loadModels(): reads models.json once, typed as ModelEntry[]
- toConfigKey(): stable short key derivation (preserves prior behavior)
- toV1ModelConfig(): legacy { config } hook model shape
- toV2ModelDraft()/toV2ModelMap(): OpenCode V2 catalog model drafts
plugin.ts now delegates to the shared module; behavior is unchanged
and covered by tests.
OpenCode 2 loads plugins from a module's default export as
{ id, setup }, and requires provider/model registration through the
catalog transform API. The legacy plugin.ts factory (V1 only) fails to
load in V2 with a SchemaError.
Add a new ./v2 entrypoint that exports { id, setup } and registers the
commandcode provider plus all models from models.json via
ctx.catalog.transform. Users can now opt in with:
plugins: ["commandcode-go-opencode-provider/v2"]
No provider block or hand-written model list is needed.
- v2.ts: V2 plugin default export ({ id, setup })
- package.json: expose ./v2, include v2.ts in files, bump to 0.5.0
- tsconfig.json: include v2.ts
- tests/unit/v2.test.ts: coverage for provider/model registration
Add a V2 section to the README covering install via the ./v2 entrypoint, API-key setup, and model selection. Add a V2 local-development snippet and switch the repo's example opencode.json to the native V2 plugin config.
This was referenced Aug 7, 2026
Command Code can emit error events whose payload is a structured object
({ type, message, statusCode, isRetryable }). The parser passed the raw
object into the error part, which opencode rendered as '[object Object]'
instead of a readable message.
Extract the message field when the error is an object, and fall back to
JSON.stringify otherwise. Adds regression tests for both paths.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds support for OpenCode 2. It also moves model logic into one shared file. The shared file works for OpenCode 1 (V1) and OpenCode 2 (V2).
Problem
OpenCode 2 loads plugins in a new way. A plugin file must export
{ id, setup }. The currentplugin.tsfile exports a factory function instead. This function returns{ config, auth }. This is the V1 format. OpenCode 2 cannot load this format. It shows this error:The provider code already works with OpenCode 2. The files
index.tsandsrc/model.tsimplement theLanguageModelV3interface from the AI SDK. The provider only needs a new V2 plugin file to register it.Changes
1. Shared model utilities
src/models.ts. This file loads and converts model data frommodels.json.toConfigKey— creates a short, stable key for each model.toV1ModelConfig— creates a model config for the V1 plugin.toV2ModelDraftandtoV2ModelMap— create model entries for the V2 catalog.plugin.tsto use the shared functions. The V1 plugin behavior does not change.tests/unit/models.test.tsfor all functions.2. OpenCode 2 (V2) plugin entrypoint
v2.ts. This file exports the V2 plugin as{ id, setup }.commandcodeprovider throughctx.catalog.transform.aisdk:commandcode-go-opencode-provider. It has a defaultbaseURL.package.json:./v2.v2.tsto the published files.0.5.0.tsconfig.jsonto includev2.ts.tests/unit/v2.test.ts. These tests check provider registration, settings overrides, and that all 21 models frommodels.jsonregister with the correct shape.3. Documentation
README.md:plugins: ["commandcode-go-opencode-provider/v2"]./connectcommand or theCOMMANDCODE_API_KEYvariable.plugin/providerblock still works for the OpenCode 1 (V1) CLI.file://path to the./v2entrypoint.opencode.json. Change the example config to the V2 format (pluginsandproviders).How to use OpenCode 2 support
Add this to your config:
{ "plugins": ["commandcode-go-opencode-provider/v2"] }You do not need a
providerblock. You do not need a hand-written model list.Verification
bun run typecheckpasses.bun test tests/unit/passes. It runs 90+ tests with 0 failures.v2.tsplugin was tested in a liveopencode2instance. The provider and all 21 models registered correctly. This was checked through the/api/providerand/api/modelendpoints.Note on PR history
This PR replaces PR #15, PR #16, and PR #17. Those PRs formed a stack. GitHub does not allow a PR to use a fork branch as its base in the upstream repo. This blocks true stacking across a fork without push access to the upstream repo. This PR combines all three changes into one PR against
main. PR #16 and PR #17 are now closed. Both point to this PR.