fix(plugin): make tool values structural#37202
Merged
Merged
Conversation
This was referenced Jul 16, 2026
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.
What
Make V2 Effect tool values transparent structural declarations so tools created by an external plugin remain valid when the plugin and OpenCode resolve separate physical copies of
@opencode-ai/plugin.Typed tools now accept either Effect codecs or schemas implementing both Standard Schema V1 and Standard JSON Schema V1. The existing raw
jsonSchemaoverload remains available for MCP, manifests, and process bridges.Before / After
Before:
Tool.makereturned a frozen empty object and stored its schemas and executor in a module-localWeakMap. When an external Effect plugin registered a tool from its package copy, OpenCode looked up that object in the host package copy's differentWeakMapand threwInvalid Tool value.After: the tool value directly carries its declaration. The host derives definitions and settles calls from those fields, so package-copy identity is irrelevant.
How
WeakMapcarrier with structural typed and raw-JSON declaration variants.Scope
Tool.makeoverload for raw JSON Schema tools; no separateTool.dynamicAPI is added.addDynamicmethod worked around the package-identity issue without fixing the tool representation.Testing
bun run testinpackages/core: 1,301 passed, 6 skippedbun run testinpackages/plugin: 6 passedbun run buildinpackages/pluginbun run typecheck: 32 tasks passed