Skip to content

Merge plugin system prompts for provider compatibility#2339

Open
VamsiKrishna0101 wants to merge 1 commit into
different-ai:devfrom
VamsiKrishna0101:fix-openai-compatible-system-prompts-clean
Open

Merge plugin system prompts for provider compatibility#2339
VamsiKrishna0101 wants to merge 1 commit into
different-ai:devfrom
VamsiKrishna0101:fix-openai-compatible-system-prompts-clean

Conversation

@VamsiKrishna0101

@VamsiKrishna0101 VamsiKrishna0101 commented Jun 22, 2026

Copy link
Copy Markdown

Summary

  • Fixes strict OpenAI-compatible provider failures caused by multiple plugin-added system messages.
  • Merges OpenWork plugin system guidance into a single system prompt while preserving the existing agent instructions.
  • Adds tests covering system prompt merging for OpenWork capabilities and extension guidance plugins.

Why

  • Some OpenAI-compatible providers/proxies reject requests when more than one system message is sent.
  • Issue [Bug]: opencode customized model api calling router failure #2099 reports this with a custom OpenAI-compatible API through CC-Switch: OpenCode CLI worked, but OpenWork failed with System message must be at the beginning.
  • OpenWork plugins were appending additional system entries, which could produce provider payloads that strict APIs reject.
  • The fix keeps the OpenWork guidance but sends it as one provider-safe system prompt.

Issue

Scope

  • Updates apps/server/src/opencode-plugins/openwork-capabilities-knowledge.ts.
  • Updates apps/server/src/opencode-plugins/openwork-extensions-preview.ts.
  • Preserves OpenWork capabilities, docs, UI-control, extension, browser, voice, cloud, and session-memory guidance.
  • Flattens non-empty system prompt entries into one string separated by blank lines.
  • Mutates the system prompt array in place so hook callers that keep the original array reference see the merged prompt.
  • Adds focused unit coverage for both plugin transforms.

Out of scope

  • No provider configuration changes.
  • No model/provider SDK changes.
  • No changes to OpenCode CLI behavior.
  • No UI changes.
  • No new dependencies.
  • No changes to message persistence or SQLite handling.

Testing

Ran

  • pnpm --filter openwork-server exec bun test src/opencode-plugins/openwork-capabilities-knowledge.test.ts src/opencode-plugins/openwork-extensions-preview.test.ts
  • pnpm --filter openwork-server typecheck

Result

  • pass:
    • openwork-capabilities-knowledge.test.ts: 2 passed
    • openwork-extensions-preview.test.ts: 1 passed
    • tsc -p tsconfig.json --noEmit: passed
  • if fail, exact files/errors:
    • N/A

CI status

  • pass:
    • Not run locally beyond targeted tests and server typecheck.
  • code-related failures:
    • N/A
  • external/env/auth blockers:
    • N/A

Manual verification

  1. Configured a local OpenAI-compatible test provider against a fake /v1 server.
  2. Sent a message from the OpenWork desktop app using the custom provider.
  3. Verified the provider request contains a single leading system message instead of multiple plugin-added system messages.

Evidence

  • Local fake-provider request body confirmed the final messages payload contains only one system message at the beginning.
  • Screenshot/video: N/A

Risk

  • Low-to-medium.
  • The change is limited to plugin system prompt transforms.
  • The agent still receives the existing OpenWork guidance, but now as one merged system prompt.
  • Main behavioral risk is prompt-size/order sensitivity from concatenating existing system entries into one string.

Rollback

  • Revert this PR to restore the previous behavior where these plugins append separate system prompt entries.

Review in cubic

@vercel

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-landing Ready Ready Preview, Comment, Open in v0 Jun 23, 2026 1:01am

@vercel

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

@VamsiKrishna0101 is attempting to deploy a commit to the Different AI Team on Vercel.

A member of the Team first needs to authorize it.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Re-trigger cubic

@Pablosinyores Pablosinyores left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The in-place collapse is correct for a single transform, but the composition is worth a look. Both OpenWorkCapabilitiesKnowledge and OpenWorkExtensionsPreview register experimental.chat.system.transform and each flattens the entire output.system array. That only yields a single system message at send time if these two transforms run last. Any other plugin (or the base agent) that pushes a system entry after them reintroduces multiple system messages and the strict-proxy failure comes back. The guarantee is order-dependent and breaks silently if plugin order changes.

A single centralized flatten applied once, after all system.transform hooks have run, would be more robust than each plugin mutating the shared array, and it avoids duplicating the same six lines per plugin.

On the tests: both new cases exercise one plugin against a fresh array, so they do not cover the multi-system-message scenario the fix actually targets. A test that runs both transforms in sequence on the same output.system (or one transform over a pre-seeded multi-entry array) would prove the provider-compat behavior rather than the isolated case.

@VamsiKrishna0101

Copy link
Copy Markdown
Author

The in-place collapse is correct for a single transform, but the composition is worth a look. Both OpenWorkCapabilitiesKnowledge and OpenWorkExtensionsPreview register experimental.chat.system.transform and each flattens the entire output.system array. That only yields a single system message at send time if these two transforms run last. Any other plugin (or the base agent) that pushes a system entry after them reintroduces multiple system messages and the strict-proxy failure comes back. The guarantee is order-dependent and breaks silently if plugin order changes.

A single centralized flatten applied once, after all system.transform hooks have run, would be more robust than each plugin mutating the shared array, and it avoids duplicating the same six lines per plugin.

On the tests: both new cases exercise one plugin against a fresh array, so they do not cover the multi-system-message scenario the fix actually targets. A test that runs both transforms in sequence on the same output.system (or one transform over a pre-seeded multi-entry array) would prove the provider-compat behavior rather than the isolated case.

Good point, thanks. I updated the PR to avoid per-plugin flattening.

The OpenWork guidance plugins now only append their own system context, and I added a dedicated openwork-system-prompt-normalizer plugin that runs after the OpenWork/runtime plugin list. That final plugin merges non-empty system entries into one provider-safe system prompt in place.

I also updated the tests so the provider-compat behavior is covered at composition level: the new test runs both OpenWork system transforms on the same output.system, verifies multiple system entries exist before normalization, then runs the final normalizer and asserts the result is exactly one system message while preserving the capabilities and extension guidance.

I also added the new normalizer plugin to the server build entrypoints so it is bundled for packaged builds.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: opencode customized model api calling router failure

2 participants