Skip to content

feat(deps): upgrade rig-core to v0.33#480

Merged
vsumner merged 2 commits intomainfrom
upgrade/rig-0.33
Mar 24, 2026
Merged

feat(deps): upgrade rig-core to v0.33#480
vsumner merged 2 commits intomainfrom
upgrade/rig-0.33

Conversation

@vsumner
Copy link
Copy Markdown
Collaborator

@vsumner vsumner commented Mar 23, 2026

Summary

  • Upgrade rig-core from v0.31 to v0.33
  • Add Message::System handling in 8 locations (exhaustive match requirement from rig v0.33)
  • System messages converted to user role for Anthropic/OpenAI APIs (semantic mapping)
  • Token estimation and transcript rendering now account for system messages
  • Add 3 unit tests for Message::System conversion

Testing

  • cargo check --all-targets — passes
  • cargo fmt --all — applied
  • cargo test --no-run — compiles (execution blocked by local onnxruntime env)
  • 3 new unit tests for Message::System conversion:
    • convert_messages_to_anthropic_maps_system_to_user_role
    • convert_messages_to_openai_maps_system_to_user_role
    • convert_messages_to_openai_responses_maps_system_to_user_role

Notes

rig-core v0.33 adds a new Message::System { content: String } variant to the Message enum. This change is internal — .preamble() API remains unchanged, but internally creates Message::System variants that our code must handle in exhaustive match statements.

- Add Message::System handling in 8 locations (exhaustive match)
- System messages converted to user role for provider APIs
- Token estimation and transcript rendering handle system messages
- Add unit tests for Message::System conversion
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a852c9ac-64e0-4c08-ab77-ae8cc7f1309c

📥 Commits

Reviewing files that changed from the base of the PR and between cee1b17 and ef2b390.

📒 Files selected for processing (2)
  • src/conversation/worker_transcript.rs
  • src/tools/worker_inspect.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/tools/worker_inspect.rs
  • src/conversation/worker_transcript.rs

Walkthrough

System messages (Message::System { content }) are now propagated: counted in history token estimation, included in transcripts and per-message worker logs, represented in the transcript model, rendered in worker inspection output, and converted into LLM inputs (mapped to the "user" role); unit tests added for conversions.

Changes

Cohort / File(s) Summary
Agent compaction & worker logs
src/agent/compactor.rs, src/agent/worker.rs
Count Message::System { content } in token-estimate heuristic; render system lines into transcripts and per-message worker history; worker recap matching now explicitly ignores System messages.
Conversation transcript model
src/conversation/worker_transcript.rs
Add TranscriptStep::SystemText { text }; map Message::System { content }SystemText during history↔transcript conversions (skip empty text).
LLM message conversions & tests
src/llm/model.rs
Convert Message::System { content } into LLM inputs by emitting a message with role "user" for Anthropic and OpenAI conversions; add three unit tests verifying System→User mappings.
Worker inspect tool
src/tools/worker_inspect.rs
Render TranscriptStep::SystemText as a **System:** block in generated Markdown for worker inspection output.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat(deps): upgrade rig-core to v0.33' accurately describes the primary change (upgrading a dependency) but is generic regarding the main implementation work (adding exhaustive Message::System handling across 8 locations).
Description check ✅ Passed The PR description provides detailed context about the upgrade, System message handling requirements, API semantics, testing approach, and related notes, directly addressing the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch upgrade/rig-0.33

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@vsumner vsumner requested a review from jamiepine March 23, 2026 23:05
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/agent/worker.rs (1)

1137-1137: Add a targeted worker-path test for system-message compaction behavior.

Line 1137 changes behavior in the worker’s stateful compaction/recap flow; please add a focused test that exercises worker history compaction + transcript persistence/resume with Message::System present.

As per coding guidelines "For changes in async/stateful paths (worker lifecycle, cancellation, retrigger, recall cache behavior), include explicit race/terminal-state reasoning in the PR summary and run targeted tests in addition to just gate-pr."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/agent/worker.rs` at line 1137, Add a focused async worker-path test that
reproduces the stateful compaction/recap flow with Message::System present:
create a test (e.g., test_worker_history_compaction_with_system_message) that
spins up the worker instance, appends a sequence of messages including
rig::message::Message::System into the worker transcript, triggers the
compaction/recap routine (the same path exercised by the worker state machine),
persists the transcript, then shuts down and restarts the worker to verify
transcript resume and that system messages were handled/compacted as expected
(assert the persisted/transmitted transcript contains/omits system entries per
the new behavior); target the async worker lifecycle helpers used in the file
(the compaction/recap entry point and transcript persistence/resume functions)
so the test explicitly covers race/terminal-state scenarios for cancellation and
restart.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/conversation/worker_transcript.rs`:
- Around line 465-469: The code currently serializes
rig::message::Message::System as TranscriptStep::UserText, losing system
semantics on restore; update TranscriptStep to add a SystemText variant and
change the serialization branch that handles rig::message::Message::System (the
match arm currently producing TranscriptStep::UserText) to produce
TranscriptStep::SystemText, and update the restore logic that converts
TranscriptStep::UserText into rig::message::Message::User to instead convert
TranscriptStep::SystemText back into rig::message::Message::System (keeping
other TranscriptStep mappings unchanged) so system messages preserve their role
end-to-end.

---

Nitpick comments:
In `@src/agent/worker.rs`:
- Line 1137: Add a focused async worker-path test that reproduces the stateful
compaction/recap flow with Message::System present: create a test (e.g.,
test_worker_history_compaction_with_system_message) that spins up the worker
instance, appends a sequence of messages including rig::message::Message::System
into the worker transcript, triggers the compaction/recap routine (the same path
exercised by the worker state machine), persists the transcript, then shuts down
and restarts the worker to verify transcript resume and that system messages
were handled/compacted as expected (assert the persisted/transmitted transcript
contains/omits system entries per the new behavior); target the async worker
lifecycle helpers used in the file (the compaction/recap entry point and
transcript persistence/resume functions) so the test explicitly covers
race/terminal-state scenarios for cancellation and restart.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7d01a1ba-8704-4b0d-80b7-93ac5da0fa92

📥 Commits

Reviewing files that changed from the base of the PR and between 6f81f39 and 6f2a511.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock, !**/*.lock
  • Cargo.toml is excluded by !**/*.toml
📒 Files selected for processing (4)
  • src/agent/compactor.rs
  • src/agent/worker.rs
  • src/conversation/worker_transcript.rs
  • src/llm/model.rs

(!parts.is_empty())
.then(|| serde_json::json!({"role": "assistant", "content": parts}))
}
Message::System { content } => Some(serde_json::json!({
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.

Small guard: if Message::System ever comes through empty (or whitespace), skipping it avoids emitting an empty Anthropic message.

Suggested change
Message::System { content } => Some(serde_json::json!({
Message::System { content } => (!content.trim().is_empty()).then(|| serde_json::json!({
"role": "user",
"content": content,
})),

result.extend(tool_results);
}
Message::System { content } => {
result.push(serde_json::json!({
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.

Worth double-checking the source of Message::System here: stream_openai() already injects request.preamble as a role: system message. If rig v0.33 is emitting that same preamble as Message::System, this would send it twice (and demote it to user). If Message::System is meant as additional system content, mapping to role: system might preserve instruction priority.

}
}
}
rig::message::Message::System { content } => {
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.

Message::System is getting persisted as TranscriptStep::UserText, which transcript_to_history() later reconstructs as Message::User on resume. If that’s intentional (e.g., providers without a system role), a quick comment here would help avoid someone “fixing” this later and changing behavior.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/tools/worker_inspect.rs (1)

135-140: Inconsistent indentation on line 135.

The UserText match arm has extra leading whitespace compared to sibling arms (Action, SystemText, ToolResult). The SystemText handling logic itself is correct.

🔧 Suggested fix
-                            worker_transcript::TranscriptStep::UserText { text } => {
+                            worker_transcript::TranscriptStep::UserText { text } => {
                                 summary.push_str(&format!("**User:** {text}\n\n"));
                             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/tools/worker_inspect.rs` around lines 135 - 140, Normalize the
indentation of the match arms so the worker_transcript::TranscriptStep::UserText
arm aligns with its sibling arms (e.g., Action, SystemText, ToolResult);
specifically adjust the leading whitespace before the line containing
worker_transcript::TranscriptStep::UserText { text } => { and its
summary.push_str(&format!("**User:** {text}\n\n")); so it matches the
indentation level used by worker_transcript::TranscriptStep::SystemText { text }
=> { and others, leaving the logic unchanged.
src/conversation/worker_transcript.rs (1)

29-33: Add #[serde(other)] catch-all to handle unknown transcript variants safely.

The new SystemText variant is the correct semantic fix, but without a catch-all, old code cannot deserialize transcripts written by new code. This breaks the critical conversation-resume path in agent/channel_dispatch.rs (lines 1053-1055) if rollbacks occur. A similar pattern already exists in src/opencode/types.rs:358. Consider adding:

#[serde(other)]
Unknown,

to TranscriptStep and handle it in transcript_to_history(), or ensure deployments are atomic and rollbacks are impossible.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/conversation/worker_transcript.rs` around lines 29 - 33, TranscriptStep's
new SystemText variant can break deserialization of older code; add a serde
catch-all by adding an #[serde(other)] Unknown variant to the TranscriptStep
enum (alongside SystemText) and update transcript_to_history() to explicitly
handle Unknown (e.g., ignore or log and skip) so transcripts written by newer
code deserialize safely in older deployments; reference the TranscriptStep enum,
SystemText variant, and transcript_to_history() when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/conversation/worker_transcript.rs`:
- Around line 29-33: TranscriptStep's new SystemText variant can break
deserialization of older code; add a serde catch-all by adding an
#[serde(other)] Unknown variant to the TranscriptStep enum (alongside
SystemText) and update transcript_to_history() to explicitly handle Unknown
(e.g., ignore or log and skip) so transcripts written by newer code deserialize
safely in older deployments; reference the TranscriptStep enum, SystemText
variant, and transcript_to_history() when making the change.

In `@src/tools/worker_inspect.rs`:
- Around line 135-140: Normalize the indentation of the match arms so the
worker_transcript::TranscriptStep::UserText arm aligns with its sibling arms
(e.g., Action, SystemText, ToolResult); specifically adjust the leading
whitespace before the line containing
worker_transcript::TranscriptStep::UserText { text } => { and its
summary.push_str(&format!("**User:** {text}\n\n")); so it matches the
indentation level used by worker_transcript::TranscriptStep::SystemText { text }
=> { and others, leaving the logic unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1760488c-2c22-492a-8aa9-8469465a3e62

📥 Commits

Reviewing files that changed from the base of the PR and between 6f2a511 and cee1b17.

📒 Files selected for processing (2)
  • src/conversation/worker_transcript.rs
  • src/tools/worker_inspect.rs

- System messages now convert to SystemText in convert_history
- SystemText now converts back to Message::System in transcript_to_history
- Add unit tests for System message round-trip in all three converters
@vsumner vsumner enabled auto-merge March 24, 2026 01:39
@vsumner vsumner merged commit e6d7ad5 into main Mar 24, 2026
4 checks passed
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.

2 participants