Skip to content

refactor(libsy): use conversation IR request and response types#58

Merged
nachiketb-nvidia merged 8 commits into
mainfrom
nachiketb/libsy-conversation-ir
Jul 14, 2026
Merged

refactor(libsy): use conversation IR request and response types#58
nachiketb-nvidia merged 8 commits into
mainfrom
nachiketb/libsy-conversation-ir

Conversation

@nachiketb-nvidia

@nachiketb-nvidia nachiketb-nvidia commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Linear: SWITCH-620 - Run a 24 hr stress test on Switchyard server

Why

PR #17 introduced libsy with bespoke LlmRequest / LlmResponse structs that only carried a text prompt and completion. That makes libsy look like it owns a new LLM wire abstraction, when Switchyard already has a shared provider-neutral conversation IR in switchyard-translation.

This change makes libsy align with that direction now: LlmRequest and LlmResponse are semantic aliases over ConversationRequest and ConversationResponse, while provider-specific details stay in clients/hosts rather than in router algorithms.

What

  • Replaces libsy-owned LlmRequest and LlmResponse structs with aliases to ConversationRequest and ConversationResponse.
  • Adds small text helpers for text-only router logic and examples: text_request, text_response, request_text, and response_text.
  • Updates llm_class, ensemble, and rand to inspect conversation IR via the helpers instead of old prompt / completion fields.
  • Boxes Step::ReturnToAgent so the larger conversation response does not inflate the stream enum.
  • Updates libsy examples and README to teach the conversation IR contract.
  • Updates the libsy proxy demo to the current Algorithm / Request / Response API and compiles it against the shared router builder.

How

The algorithms still operate on plain text where their current logic requires text, but that text is now extracted from the shared IR. Generated subcalls are built as text-only ConversationRequests with the inbound model preserved in model; routed target selection remains on Decision::selected_model().

The proxy demo still lets libsy make routing decisions and Switchyard own HTTP/profile serving. The demo now creates a text-only libsy request from inbound prompt text, runs the classifier algorithm directly, and returns a chat-completion response for Switchyard to translate back to the inbound format.

What to Review

  • Whether aliasing LlmRequest / LlmResponse to the translation IR is the right libsy contract for this PR.
  • Whether the helper functions are the right minimum bridge for text-based router algorithms without reintroducing a second IR.
  • Whether boxing Step::ReturnToAgent is acceptable for the stream API after the response type becomes larger.
  • Whether the demo proxy update is appropriately scoped to compiling against the current libsy/server APIs.

Validation

  • cargo test -p libsy
  • cargo check -p libsy --examples
  • cargo check -p libsy-proxy
  • cargo test -p libsy-proxy
  • pre-commit hook: cargo fmt, cargo clippy

Summary by CodeRabbit

  • New Features

    • Added a shared, provider-neutral protocol for structured LLM conversations, including messages, roles, content blocks, and responses.
    • Updated the library API to support model selection and multi-part response content.
    • Improved routing and orchestration examples to use structured requests and responses.
  • Documentation

    • Refreshed usage examples and API documentation to demonstrate the new conversation format.
  • Refactor

    • Unified protocol types across the library and translation components.

@nachiketb-nvidia nachiketb-nvidia requested a review from a team as a code owner July 13, 2026 21:15
@messiaen messiaen force-pushed the grclark/feat/libsy-routers-poc branch from fcdc0ad to eab29f6 Compare July 14, 2026 14:20
Base automatically changed from grclark/feat/libsy-routers-poc to main July 14, 2026 14:28
@messiaen messiaen self-requested a review July 14, 2026 14:31
@messiaen

Copy link
Copy Markdown
Contributor

#17 is merged can you rebase? @nachiketb-nvidia

Comment thread crates/libsy/src/types.rs Outdated
@messiaen messiaen requested a review from grahamking July 14, 2026 14:36
@nachiketb-nvidia nachiketb-nvidia force-pushed the nachiketb/libsy-conversation-ir branch 2 times, most recently from e4e241c to 55aa536 Compare July 14, 2026 18:54
Signed-off-by: nachiketb <nachiketb@nvidia.com>
Signed-off-by: nachiketb <nachiketb@nvidia.com>
Signed-off-by: nachiketb <nachiketb@nvidia.com>
Signed-off-by: nachiketb <nachiketb@nvidia.com>
@nachiketb-nvidia nachiketb-nvidia force-pushed the nachiketb/libsy-conversation-ir branch from 55aa536 to 836e153 Compare July 14, 2026 18:55
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The workspace adds switchyard-protocol as the shared conversation IR crate. libsy, switchyard-translation, routing algorithms, research examples, documentation, and tests migrate from legacy prompt/completion fields to structured messages, outputs, and content blocks.

Changes

Shared protocol foundation

Layer / File(s) Summary
Protocol crate foundation
Cargo.toml, crates/switchyard-protocol/*
Adds the protocol crate, exposes shared format and IR modules, and removes the role-name helper from the protocol crate.
Translation protocol wiring
crates/switchyard-translation/Cargo.toml, crates/switchyard-translation/src/*
Uses protocol-provided format and IR modules and relocates role-name recognition to codec helpers.

libsy API migration

Layer / File(s) Summary
Conversation IR contract and documentation
crates/libsy/src/*, crates/libsy/README.md, crates/libsy/Cargo.toml
Re-exports protocol types and updates API documentation and examples for structured requests and responses.
Runtime and test adaptation
crates/libsy/src/lib.rs
Boxes terminal responses and updates runtime handling, test clients, request builders, assertions, and model extraction.

Routing and examples

Layer / File(s) Summary
Ensemble structured flow
crates/libsy-examples/src/ensemble.rs
Builds message-based judge requests, extracts output content blocks, and updates ensemble mocks and assertions.
Classifier and random routing
crates/libsy-examples/src/llm_class.rs, crates/libsy-examples/src/rand.rs
Migrates classifier and random routing requests, responses, forwarding, and tests to the new fields.
Research agent examples
crates/libsy-examples/examples/research_agent.rs, crates/libsy-examples/examples/research_agent_core.rs
Updates research-agent requests, stub responses, and note aggregation for structured outputs.

Estimated code review effort: 4 (Complex) | ~45 minutes

Poem

I’m a rabbit with messages in a row,
Structured blocks make the carrots glow.
Prompts hop out, responses land,
Protocol paths now neatly stand.
Hop hop—tests follow the flow!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main libsy refactor to use shared conversation IR request and response types.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

@coderabbitai coderabbitai 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.

Actionable comments posted: 6

🧹 Nitpick comments (1)
crates/libsy-examples/examples/research_agent.rs (1)

81-105: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the duplicated response-text extraction into a shared helper. Both examples reimplement the identical filter_map over output.content (Text/Refusal/Reasoning → text, Unknown → raw, else dropped) to build notes; libsy already offers LlmMessage::text_content(sep) for the request side but nothing symmetric for response outputs, so this logic is hand-rolled at every call site (also seen in llm_class.rs/ensemble.rs).

  • crates/libsy-examples/examples/research_agent.rs#L81-L105: replace the inline filter_map/collect/join with a call to a shared response_text(&response) helper.
  • crates/libsy-examples/examples/research_agent_core.rs#L92-L109: replace the identical inline block with the same shared helper call.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/libsy-examples/examples/research_agent.rs` around lines 81 - 105,
Extract the duplicated LlmContentBlock text/unknown extraction into a shared
response_text(&response) helper, preserving the existing newline-joined output
and omission of unsupported blocks. Replace the inline filter_map/collect/join
logic in crates/libsy-examples/examples/research_agent.rs lines 81-105 and
crates/libsy-examples/examples/research_agent_core.rs lines 92-109 with calls to
that helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/libsy-examples/src/ensemble.rs`:
- Around line 297-311: Reuse the existing text-extraction helper used by the
earlier response-processing code and build_judge_prompt instead of duplicating
the closure in the judge_text construction. Update the judge_text path to call
that shared helper, preserving the current handling of Text, Refusal, Reasoning,
and Unknown content blocks.
- Around line 205-225: Consolidate the repeated LlmContentBlock text extraction
into a shared helper, covering Text, Refusal, Reasoning, and Unknown raw
content, then update this user_prompt construction and the corresponding sites
in ensemble.rs and llm_class.rs to reuse it instead of duplicating the match
closure.

In `@crates/libsy-examples/src/llm_class.rs`:
- Around line 155-169: Replace the duplicated content-extraction logic in the
classifier score parsing flow with the existing shared text-extraction closure
or helper used elsewhere in the diff. Use it to build score_text from
classify_response, preserving the current handling of text, refusal, reasoning,
and unknown blocks before parsing the trimmed result as f64.
- Around line 109-129: Consolidate the duplicated LlmContentBlock text
extraction used by the user_prompt construction and ensemble.rs into one shared
helper, covering Text, Refusal, Reasoning, and Unknown::raw while excluding
other variants. Replace the local filter_map logic with that helper and preserve
the existing newline-joined output.

In `@crates/libsy/README.md`:
- Around line 81-87: Update the client example before constructing the Response
and nested LlmResponse to define completion by extracting the provider response
value, so the existing LlmContentBlock::Text usage compiles when copied.
- Around line 180-187: Update the classifier example around classify_response
and score to match the extraction logic in llm_class.rs: scan all response
outputs and content blocks and support the same text-like block variants before
parsing the classifier score. Do not retain the first-output/first-content-only
behavior unless the example explicitly documents that assumption.

---

Nitpick comments:
In `@crates/libsy-examples/examples/research_agent.rs`:
- Around line 81-105: Extract the duplicated LlmContentBlock text/unknown
extraction into a shared response_text(&response) helper, preserving the
existing newline-joined output and omission of unsupported blocks. Replace the
inline filter_map/collect/join logic in
crates/libsy-examples/examples/research_agent.rs lines 81-105 and
crates/libsy-examples/examples/research_agent_core.rs lines 92-109 with calls to
that helper.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 434057d8-6307-487b-bdb1-7e1cc7eb85ef

📥 Commits

Reviewing files that changed from the base of the PR and between 07d6446 and e4e241c.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock, !Cargo.lock
📒 Files selected for processing (20)
  • Cargo.toml
  • crates/libsy-examples/examples/research_agent.rs
  • crates/libsy-examples/examples/research_agent_core.rs
  • crates/libsy-examples/src/ensemble.rs
  • crates/libsy-examples/src/llm_class.rs
  • crates/libsy-examples/src/rand.rs
  • crates/libsy/Cargo.toml
  • crates/libsy/README.md
  • crates/libsy/src/lib.rs
  • crates/libsy/src/types.rs
  • crates/switchyard-protocol/Cargo.toml
  • crates/switchyard-protocol/src/format.rs
  • crates/switchyard-protocol/src/ir.rs
  • crates/switchyard-protocol/src/lib.rs
  • crates/switchyard-translation/Cargo.toml
  • crates/switchyard-translation/src/codecs/anthropic/buffered.rs
  • crates/switchyard-translation/src/codecs/common.rs
  • crates/switchyard-translation/src/codecs/openai_chat/buffered.rs
  • crates/switchyard-translation/src/codecs/responses/buffered.rs
  • crates/switchyard-translation/src/lib.rs

Comment thread crates/libsy-examples/src/ensemble.rs
Comment thread crates/libsy-examples/src/ensemble.rs
Comment thread crates/libsy-examples/src/llm_class.rs
Comment thread crates/libsy-examples/src/llm_class.rs
Comment thread crates/libsy/README.md Outdated
Comment thread crates/libsy/README.md
Signed-off-by: nachiketb <nachiketb@nvidia.com>
Signed-off-by: nachiketb <nachiketb@nvidia.com>

@messiaen messiaen 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.

Couple of minor naming comments otherwise LGTM

Comment thread crates/libsy/src/lib.rs Outdated
Comment thread crates/switchyard-protocol/Cargo.toml Outdated
Signed-off-by: nachiketb <nachiketb@nvidia.com>

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.

Should this type also be move to libsy-protocol?
Can be separate PR.

@messiaen messiaen self-requested a review July 14, 2026 20:27
Signed-off-by: nachiketb <nachiketb@nvidia.com>
@nachiketb-nvidia nachiketb-nvidia merged commit 64d02db into main Jul 14, 2026
14 checks passed
@nachiketb-nvidia nachiketb-nvidia deleted the nachiketb/libsy-conversation-ir branch July 14, 2026 21:12
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