Repository navigation
feat: support OpenCode V2 plugin API (dual V1/V2 entrypoint) - #4
Merged
Merged
Conversation
- Dual default export: V2 Plugin.define({ id: "orvix", setup }) spread with
the V1 server() function (config + auth hooks), per the official
migrate-v1 pattern. Requires OpenCode >= 1.18.29 for the V1 object
entrypoint.
- New src/v2.ts: catalog transform registering the orvix provider
(aisdk:@ai-sdk/openai-compatible, base URL, integrationID) and upserting
models in the V2 shape (variant array, tiered costs, capabilities);
integration transforms registering env + key credential methods.
- Live /models discovery, fallback catalog, and user-model preservation
match V1 semantics.
- Add @opencode/plugin as a runtime dependency.
- Validate against local OpenCode 2.0.2: provider + 19 models registered,
env credential resolved, orvix/* selectable via 'opencode models'.
5 tasks done
algonacci
added a commit
that referenced
this pull request
Oct 3, 2026
## Summary The OpenCode 2.x entrypoint no longer loads on current OpenCode. `@opencode/plugin` 2.0.4 (2026-09-16) removed `ctx.catalog`, so setup throws: ``` failed to load plugin plugin.id=orvix cause="TypeError: undefined is not an object (evaluating 'ctx.catalog.transform')" ``` After that error every `orvix/*` model reports `Model unavailable`. The V2 support from #4 targeted 2.0.2, which still had `catalog`. This PR makes two changes: - **Register through `ctx.provider.transform`.** If the provider does not exist yet, the plugin calls `add({ info, models })`. If the user already configured it, the plugin fills in missing provider fields with `update` and appends its models with `models.set`. User-configured provider fields and models are still never overwritten. Each model record now carries `id` (the OpenCode key), `modelID` (the exact upstream id, so managed `orvix/*` and BYOK ids still go upstream verbatim), and `providerID`. - **Put reasoning variants in `body`.** Variants stored `reasoning_effort` under `settings`, which configures the provider package and is never sent in the request. Selecting `orvix/muse-spark-1.3#high` therefore sent no `reasoning_effort`. Variants now use `body`. The test fakes now mirror the provider editor. AGENTS.md and the README no longer mention the catalog API. A patch changeset is included. ## Verification - `npm run check`: typecheck clean, 58/58 tests pass. - `npm run package`: passes. - End-to-end on OpenCode 2.0.21 (`opencode run --standalone`, isolated XDG dirs) against a local mock OpenAI-compatible server, with `providers.orvix.settings.baseURL` pointing at the mock: - Before: the plugin fails to load and `orvix/glm-5.3-flash` is unavailable. - After: the plugin loads, and requests reach `/v1/chat/completions` with `model: "orvix/muse-spark-1.3"` / `"orvix/glm-5.3-flash"` and a bearer key. The user's `baseURL` override is respected. - `-m orvix/muse-spark-1.3#high` now sends `reasoning_effort: "high"`. Models without variants send none. - Not tested against the live Orvix API. ## Checklist - [x] The change is focused and contains no unrelated churn. - [x] Tests pass with `npm run check`. - [x] Packaging passes with `npm run package`. - [x] User-visible changes include a Changeset; otherwise, this is not applicable. - [x] Relevant documentation is updated; otherwise, this is not applicable. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
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
Adds OpenCode V2 plugin API support in a minor release (0.3.0), following the official V1 plugin migration guide. The 0.2.x line remains the V1-only line; users on OpenCode < 1.18.29 stay on 0.2.
Changes
plugin.ts): default export spreads a V2Plugin.define({ id: "orvix", setup })with the V1server()function returning the classicconfig+authhooks. V1 (≥ 1.18.29) callsserver(); V2 readsid/setup.src/v2.ts(new) — V2 registration:ctx.catalog.transform: creates theorvixprovider (aisdk:@ai-sdk/openai-compatible, baseURLhttps://api.orvix.id/v1,integrationID) and upserts the model catalog in the V2 shape (variants as array, tiered$/Mtok costs, capabilities).ctx.integration.transform: registersenv(ORVIX_API_KEY) +keycredential methods on theorvixintegration (V2 replacement for the V1authhook)./modelsdiscovery, fallback catalog, and user-model preservation match V1 semantics exactly.@opencode/pluginadded as a runtime dependency;@ai-sdk/openai-compatiblestays an optional peer.provider.list()shape caveat.Validation
npm run check(typecheck + 58 tests, incl. 10 new V2 tests with a stubbed plugin context) andnpm run packagepass locally.plugin.tsagainst local OpenCode 2.0.2: provider + 19 fallback models registered, env credential resolved through the registered env method, and allorvix/*models selectable viaopencode models.catalog.provider.updatecreates missing providers (applied on registry replay).orvixexists as a built-in V2 integration; methods can be attached by the plugin.catalog.provider.list()returns flat records, unlike the published.d.ts— V2 context is typed structurally insrc/v2.tsto avoid coupling..envkey is empty); routing path/provider/package are otherwise verified.