Skip to content

fix(providers): cache OpenRouter system prompts - #7634

Merged
Audacity88 merged 2 commits into
zeroclaw-labs:masterfrom
EyrieCommander:codex/coderabbit-openrouter-cache-control
Jun 15, 2026
Merged

fix(providers): cache OpenRouter system prompts#7634
Audacity88 merged 2 commits into
zeroclaw-labs:masterfrom
EyrieCommander:codex/coderabbit-openrouter-cache-control

Conversation

@Audacity88

@Audacity88 Audacity88 commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Base branch: master
  • What changed and why:
    • Routes OpenRouter chat_with_system request construction through the existing OpenRouter system-message content helper.
    • Preserves the cache_control: {"type": "ephemeral"} marker on system prompts for the simple chat-with-system path.
    • Adds regression coverage for system prompt serialization while keeping the user message as plain text.
  • Scope boundary: This PR does not add new OpenRouter endpoints, change provider configuration, change credentials handling, or add base-URL override support.
  • Blast radius: Limited to OpenRouter chat request serialization in zeroclaw-providers. Other providers, config loading, CLI behavior, and channel/runtime routing are unchanged.
  • Linked issue(s): None.
  • Labels: bug, risk: medium, size: S, provider, provider:openrouter

Validation Evidence (required)

  • Commands run and tail output:
cargo fmt --all -- --check
Result: passed

cargo test -p zeroclaw-providers chat_request_serializes_with_system_and_user --lib -- --nocapture
Result: passed, 1 test passed

cargo test -p zeroclaw-providers openrouter --lib -- --nocapture
Result: passed, 73 tests passed, 873 filtered out

cargo clippy -p zeroclaw-providers --lib -- -D warnings
Result: passed

cargo clippy --workspace --exclude zeroclaw-desktop --all-targets --features ci-all -- -D warnings
Result: passed, finished in 25m 53s

cargo nextest run --locked --workspace --exclude zeroclaw-desktop
Result: passed, 8546 tests passed, 10 skipped

git diff --check
Result: passed
  • Beyond CI — what did you manually verify? Manually checked that chat_with_system now uses the shared request builder and that the builder applies the existing OpenRouter system-message content helper. I did not perform a live OpenRouter API call.
  • If any command was intentionally skipped, why: No required local validation command was skipped. I did not perform a live OpenRouter API call because this change is limited to request serialization and is covered by local regression coverage plus the CI-shaped local test run.

Security & Privacy Impact (required)

Yes/No for each. Answer any Yes with a 1–2 sentence explanation.

  • New permissions, capabilities, or file system access scope? No
  • New external network calls? No
  • Secrets / tokens / credentials handling changed? No
  • PII, real identities, or personal data in diff, tests, fixtures, or docs? No
  • If any Yes, describe the risk and mitigation: None.

Compatibility (required)

  • Backward compatible? Yes
  • Config / env / CLI surface changed? No
  • If No or Yes to either: No upgrade steps are required.

Rollback (required for risk: medium and risk: high)

  • Fast rollback command/path: git revert 965761e1ebafac9f1baf9d4db552059d167f89d0
  • Feature flags or config toggles: None.
  • Observable failure symptoms: If reverted, OpenRouter requests with a system prompt would serialize without the cache_control content-part shape covered by the regression. No live API or log failure was verified.

Supersede Attribution (required only when Supersedes # is used)

  • Superseded PRs + authors (#<pr> by @<author>, one per line): None.
  • Scope materially carried forward: None.
  • Co-authored-by trailers added in commit messages for incorporated contributors? No
  • If No, why (inspiration-only, no direct code/design carry-over): No superseded PR or contributor code is carried forward.

@Audacity88 Audacity88 added bug Something isn't working size: S provider Auto scope: src/providers/** changed. provider:openrouter Auto module: provider/openrouter changed. labels Jun 14, 2026
@Audacity88
Audacity88 marked this pull request as ready for review June 14, 2026 17:02

@WareWolf-MoonWall WareWolf-MoonWall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed at 965761e. The bug is that chat_with_system was constructing system-message content as MessageContent::Text directly, bypassing to_message_content("system", …) — the only path that wraps the content in the content-part array with cache_control: {"type": "ephemeral"}. Every other call site in this file routes through that helper; this one didn't. The fix extracts a build_chat_with_system_request private builder that calls to_message_content for both roles, and routes chat_with_system through it, closing the gap.

🟢 What looks good — SSOT is now enforced structurally

Before this PR, whether a system prompt got cache_control depended on which code path constructed the message — chat went through to_message_content, chat_with_system didn't, and nothing at the type level prevented that drift from recurring. After this PR, both paths go through build_chat_with_system_request, which calls to_message_content for the system role. There is now one place that knows how to construct a system message for OpenRouter; the previous gap is structurally closed.

🟢 What looks good — test upgrade matches the fix

The old chat_request_serializes_with_system_and_user test was constructing MessageContent::Text directly (the same bug the fix patches) and only checking for string substrings in the serialized output, so it would have passed even without cache_control. The updated test calls build_chat_with_system_request and asserts system_parts[0]["cache_control"]["type"] == "ephemeral" explicitly. This test now covers the exact property that was regressing, and it would have caught the original bug.

🟢 What looks good — validation evidence is thorough for the scope

cargo nextest run --locked --workspace --exclude zeroclaw-desktop (8546 passed), full workspace clippy with ci-all, and the targeted 73 openrouter-scoped tests. The rollback SHA in the PR body exactly matches the current head commit, which I verified. No required local step was skipped.

Approving. The fix is correct, the SSOT story is sound, and the test upgrade provides the right regression coverage.

@Audacity88
Audacity88 merged commit 030808b into zeroclaw-labs:master Jun 15, 2026
17 checks passed
itzmail pushed a commit to itzmail/brai that referenced this pull request Jun 18, 2026
- 965761e fix(providers): cache OpenRouter system prompts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working provider:openrouter Auto module: provider/openrouter changed. provider Auto scope: src/providers/** changed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants