Skip to content

fix(llm): collapse system messages when plugin appends a single entry - #34267

Closed
kagura-agent wants to merge 1 commit into
anomalyco:devfrom
kagura-agent:fix/system-collapse-threshold
Closed

fix(llm): collapse system messages when plugin appends a single entry#34267
kagura-agent wants to merge 1 commit into
anomalyco:devfrom
kagura-agent:fix/system-collapse-threshold

Conversation

@kagura-agent

Copy link
Copy Markdown
Contributor

Issue for this PR

Closes #34243

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

The post-hook collapse logic in packages/opencode/src/session/llm/request.ts checks system.length > 2 to decide whether to join plugin-appended entries into a single system message. However the initial system array always starts at length 1 (all base prompts are pre-joined). When a plugin pushes exactly one entry via experimental.chat.system.transform, the array becomes length 2 — which does not satisfy 2 > 2, so no collapse happens. This produces two separate {role: "system"} messages that OpenAI-compatible providers reject with:

A 'system' message can only appear at index 0 of the messages array.

The fix changes the threshold from > 2 to > 1 so collapse fires whenever any plugin appends to the system array.

How did you verify your code works?

  1. Traced the code path: system is initialized as [joinedPromptString] (length 1). After plugin trigger with one push, length becomes 2. With > 1, the collapse path activates correctly.
  2. Ran bun test --filter "trigger" — plugin trigger tests pass (2/2).
  3. Ran bun test --filter "system" — system prompt tests pass (88/88).
  4. Verified the fix matches the exact root cause identified in the issue.

Screenshots / recordings

N/A — logic fix, no UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

The post-hook collapse condition checked `system.length > 2` but the
initial system array always has length 1 (all prompts are joined before
the plugin trigger).  When a plugin pushes exactly one entry the array
becomes length 2, which does not satisfy `2 > 2`, so no collapse fires
and two separate {role: "system"} messages are sent — breaking
OpenAI-compatible providers.

Change the threshold to `> 1` so the collapse fires whenever a plugin
appends anything.

Closes anomalyco#34243
@kagura-agent

Copy link
Copy Markdown
Contributor Author

Hi 👋 Friendly check-in — this PR has been open for about a week. Would appreciate a review when you get a chance. Happy to rebase or make adjustments if needed. 🙏

@kagura-agent

Copy link
Copy Markdown
Contributor Author

Checking in again — this fix for system message collapsing has been open 9 days now. The change is minimal (single-entry system messages get merged into the initial system block instead of being appended as standalone entries). Happy to adjust anything if needed. 🙏

@kagura-agent

Copy link
Copy Markdown
Contributor Author

Closing per lifecycle policy — this PR has been open 12 days with no review despite two check-ins. Happy to reopen if there's interest in the fix. Thanks for the project!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Multiple system messages break OpenAI-compatible providers when plugins use experimental.chat.system.transform

1 participant