fix(opencode): concatenate routing block to last system entry instead of splice(1,0) - #989
Open
aalvarez-dev wants to merge 3 commits into
Open
fix(opencode): concatenate routing block to last system entry instead of splice(1,0)#989aalvarez-dev wants to merge 3 commits into
aalvarez-dev wants to merge 3 commits into
Conversation
… of splice(1,0) Strict OpenAI-compatible providers (NaN, and others) reject requests when multiple role:system messages are present because they require the system message at messages[0] only (HTTP 400). The splice(1,0) pattern was intentionally inserting the routing block and resume snapshot at index 1 to preserve OpenCode's cache-fold (llm.ts:117-128). However, OpenCode serializes system[] entries as separate role:system messages for OpenAI-compatible providers, creating a second system message at index 1 that strict providers reject. Changed to concatenate to the last system entry — same pattern used by engram.ts. This sacrifices the cache-fold optimization but ensures compatibility with strict providers. Anthropic/Moonshot are unaffected (they merge system blocks internally). Also updated debug log references from system[1] to the injected content directly.
Update all 57 system.transform test assertions to reflect the new concatenation approach: routing block and resume snapshot are appended to the last system entry instead of splice(1,0). System length no longer increases for each injection. Affected assertions: - length expectations (decreased by 1 per concatenated entry) - index references (system[1]→system[0], system[2]→system[1]) - strict equality (.toBe) → partial match (.toContain) for entries that now have appended content - cache-fold test uses join() instead of slice(1,-1)
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 / Why / How
fix(opencode): concatenate routing block to last system entry instead of splice(1,0)
Strict OpenAI-compatible providers (NaN builders, and potentially others) reject requests with HTTP 400 when multiple role:system messages are present. The OpenCode adapter's experimental.chat.system.transform hook used output.system.splice(1, 0, routingBlock) to inject the routing block and resume snapshot at index 1 — preserving system[0] for OpenCode's cache-fold.
However, OpenCode serializes system[] entries as separate role:system messages for OpenAI-compatible providers, creating a second system message at index 1 that strict providers reject.
Changed both splice(1,0) calls to concatenate to the last system entry — the same pattern used by engram.ts for memory instructions. This sacrifices the cache-fold optimization for cross-provider compatibility. Anthropic and Moonshot are unaffected (they merge system blocks internally).
Affected platforms
Test plan
Updated 32 test assertions in tests/opencode-plugin.test.ts to reflect concatenation behavior:
All 57 plugin tests pass (npm test). TypeScript typecheck passes (npm run typecheck).
Checklist
npm testpassesnpm run typecheckpassesnextbranch (unless hotfix)Cross-platform notes
Our CI runs on Ubuntu, macOS, and Windows.
path.join()/path.resolve(), never hardcode/separatorsreadFileSync(0)breaks on Windowsos.tmpdir(), never hardcode/tmp