fix(plugin): derive id from package name#92
Merged
NaNomicon merged 3 commits intotickernelz:mainfrom Apr 10, 2026
Merged
Conversation
added 2 commits
April 9, 2026 15:46
Apply typed request/response guards directly in openai-chat-completion and remove any usage in the provider implementation. Add provider-focused tests and clarify config comments for OpenAI-compatible endpoints.
Export a stable PluginModule id for file-path loading by deriving it from package.json name with a safe fallback. Extend plugin loader contract tests to assert id presence and alignment with package name.
There was a problem hiding this comment.
Pull request overview
This PR refactors the OpenAI Chat Completions provider to use tighter internal typings and adds a plugin id export (derived from package.json.name) to satisfy the OpenCode 1.3.x plugin-loader contract, along with expanded tests and config guidance.
Changes:
- Tightened typing in
OpenAIChatCompletionProvider(request/response message shapes, config typing, and response parsing). - Exported plugin
id(and included it in the defaultPluginModuleexport) and added a contract test assertingidmatches the package name. - Added provider-focused tests for the OpenAI chat path and clarified config template comments for OpenAI-compatible endpoints.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/plugin-loader-contract.test.ts | Adds an assertion that the built plugin default export includes a non-empty id matching package.json.name. |
| tests/openai-chat-completion-provider.test.ts | New test suite covering OpenAI chat provider behavior (headers, apiUrl, request body, tool-call loop behavior). |
| src/services/ai/providers/openai-chat-completion.ts | Refactors provider code to tighten types and introduce type guards + typed request/response objects. |
| src/plugin.ts | Exports id derived from package.json.name and includes it in the default PluginModule export. |
| src/config.ts | Updates config template comments to clarify OpenAI-compatible usage and examples. |
Comments suppressed due to low confidence (1)
src/services/ai/providers/openai-chat-completion.ts:26
ToolCallResponse.choices[].message.contentis typed asstring | undefined, but OpenAI Chat Completions can returncontent: nullwhen the assistant emitstool_calls. With the current type,isToolCallResponse()narrowsdatatoToolCallResponseeven whencontentis actuallynull, making the typing unsound and undermining the goal of “tightened typing”. Consider widening this tostring | null(and optionally reflecting that inAPIMessage.contenttoo).
interface ToolCallResponse {
choices: Array<{
message: {
content?: string;
tool_calls?: Array<{
id: string;
type: "function";
function: {
name: string;
arguments: string;
};
}>;
};
finish_reason?: string;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Author
|
@NaNomicon The Copilot-flagged items have been addressed and tested locally (18/18 passing):
As for the |
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
Export plugin
idinsrc/plugin.tsto satisfy the V1PluginModuleshape required by OpenCode's file/path plugin loading path.Note: The type-safety refactor commits that were originally part of this PR have been cherry-picked and merged separately via #93.
Problem
When loading
opencode-memfrom a local filesystem path (rather than npm install), the V1 plugin module shape requires an explicitid. Without it, loading fails with:Path plugin ... must export idChanges
idinsrc/plugin.ts, derived frompackage.json.namewith a safe fallbackPluginModuledefault export shape:{ id, server }idexists, is non-empty, and matchespackage.json.nameValidation
bun test tests/plugin-loader-contract.test.tsOriginal work by @regulusleow.