refactor(core): replace Rust compatibility APIs with Python - #175
Conversation
WalkthroughChangesThe workspace removes switchyard-core as a workspace dependency, exposes compatibility contracts through switchyard-components, updates Rust and Python bindings, and replaces native session caching and key generation with Python implementations and tests. Components Migration
Python Session Primitives
Estimated code review effort: 4 (Complex) | ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
switchyard/lib/session_cache.py (1)
18-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDocument the
ValueErrorin__init__.Per coding guidelines, public entry points should document raised errors;
__init__raisesValueErrorfor negativemax_sessionsbut has no docstring.📝 Proposed docstring
def __init__(self, max_sessions: int) -> None: + """Create a cache bounded to ``max_sessions`` entries. + + Raises: + ValueError: If ``max_sessions`` is negative. + """ if max_sessions < 0: raise ValueError("max_sessions must be non-negative")🤖 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 `@switchyard/lib/session_cache.py` around lines 18 - 21, Add a docstring to the public __init__ method documenting that it raises ValueError when max_sessions is negative, while preserving the existing validation and initialization behavior.Source: Coding guidelines
switchyard/lib/session_key.py (1)
21-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDocstring omits the
ValueErrorandNone-return contract.
depth < 0raisesValueError, and the function returnsNonewhendepth > 0and the prefix is incomplete — neither is documented.📝 Proposed docstring
def session_key_from_body(body: Any, depth: int = 0) -> str | None: - """Hash stable conversation anchors and an optional early-response prefix.""" + """Hash stable conversation anchors and an optional early-response prefix. + + Raises: + ValueError: If ``depth`` is negative. + + Returns ``None`` when ``depth > 0`` and the conversation does not yet + contain ``depth`` complete messages after the anchoring user turn. + """🤖 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 `@switchyard/lib/session_key.py` around lines 21 - 24, Update the docstring for session_key_from_body to document that negative depth raises ValueError and that the function returns None when depth is greater than zero but the response prefix is incomplete, while preserving the existing description.Source: Coding guidelines
🤖 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 `@switchyard/lib/session_key.py`:
- Around line 81-97: Update the tool-call argument handling in the visible
tool-call serialization logic so non-string values use _json_text(raw_arguments)
instead of being replaced with an empty string. Apply this consistently in both
the nested tool_calls/function block and the top-level type == "function_call"
block, while preserving string arguments unchanged.
---
Nitpick comments:
In `@switchyard/lib/session_cache.py`:
- Around line 18-21: Add a docstring to the public __init__ method documenting
that it raises ValueError when max_sessions is negative, while preserving the
existing validation and initialization behavior.
In `@switchyard/lib/session_key.py`:
- Around line 21-24: Update the docstring for session_key_from_body to document
that negative depth raises ValueError and that the function returns None when
depth is greater than zero but the response prefix is incomplete, while
preserving the existing description.
🪄 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: 3916dd33-acd7-4c86-a4c1-04b82a24b986
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock,!Cargo.lock
📒 Files selected for processing (67)
Cargo.tomlcrates/switchyard-components/Cargo.tomlcrates/switchyard-components/src/backends/anthropic.rscrates/switchyard-components/src/backends/common.rscrates/switchyard-components/src/backends/multi.rscrates/switchyard-components/src/backends/openai.rscrates/switchyard-components/src/backends/selection.rscrates/switchyard-components/src/backends/stats.rscrates/switchyard-components/src/contracts/backend.rscrates/switchyard-components/src/contracts/context.rscrates/switchyard-components/src/contracts/error.rscrates/switchyard-components/src/contracts/ids.rscrates/switchyard-components/src/contracts/mod.rscrates/switchyard-components/src/contracts/roles.rscrates/switchyard-components/src/contracts/types.rscrates/switchyard-components/src/dimension_collector/response/checks.rscrates/switchyard-components/src/dimension_collector/response/mod.rscrates/switchyard-components/src/dimension_collector/tool_signals.rscrates/switchyard-components/src/intake/client.rscrates/switchyard-components/src/intake/context.rscrates/switchyard-components/src/intake/payload.rscrates/switchyard-components/src/lib.rscrates/switchyard-components/src/request_processors/dimension_collector.rscrates/switchyard-components/src/request_processors/intake.rscrates/switchyard-components/src/request_processors/random_routing.rscrates/switchyard-components/src/request_processors/stats.rscrates/switchyard-components/src/response_processors/intake.rscrates/switchyard-components/src/response_processors/response_signals.rscrates/switchyard-components/src/response_processors/stats.rscrates/switchyard-components/src/stats/accumulator.rscrates/switchyard-components/src/stats/context.rscrates/switchyard-components/src/stats/usage.rscrates/switchyard-components/tests/adversarial_multi_llm_backend.rscrates/switchyard-components/tests/adversarial_native_backends.rscrates/switchyard-components/tests/adversarial_random_routing.rscrates/switchyard-components/tests/contracts.rscrates/switchyard-components/tests/flat_target_live.rscrates/switchyard-components/tests/intake_http_sink.rscrates/switchyard-components/tests/intake_payload.rscrates/switchyard-components/tests/intake_request_processor.rscrates/switchyard-components/tests/intake_response_processor.rscrates/switchyard-components/tests/stats_accumulator.rscrates/switchyard-components/tests/stats_processors.rscrates/switchyard-components/tests/support/config.rscrates/switchyard-components/tests/support/intake.rscrates/switchyard-components/tests/support/mod.rscrates/switchyard-core/Cargo.tomlcrates/switchyard-core/src/lib.rscrates/switchyard-core/src/session.rscrates/switchyard-py/Cargo.tomlcrates/switchyard-py/src/component_bindings/backends.rscrates/switchyard-py/src/component_bindings/config.rscrates/switchyard-py/src/component_bindings/dimension_collector.rscrates/switchyard-py/src/core_bindings.rscrates/switchyard-py/src/core_bindings/context.rscrates/switchyard-py/src/core_bindings/request.rscrates/switchyard-py/src/core_bindings/response.rscrates/switchyard-py/src/core_bindings/roles.rscrates/switchyard-py/src/core_bindings/session.rscrates/switchyard-py/src/errors.rsswitchyard/lib/affinity_pin_store.pyswitchyard/lib/profiles/chain.pyswitchyard/lib/session_affinity.pyswitchyard/lib/session_cache.pyswitchyard/lib/session_key.pyswitchyard_rust/core.pytests/test_session_primitives.py
💤 Files with no reviewable changes (5)
- crates/switchyard-core/Cargo.toml
- crates/switchyard-core/src/session.rs
- crates/switchyard-py/src/core_bindings/session.rs
- crates/switchyard-core/src/lib.rs
- switchyard_rust/core.py
6514d24 to
bd31657
Compare
Signed-off-by: nachiketb <nachiketb@nvidia.com>
bd31657 to
2f1b2c8
Compare
Signed-off-by: nachiketb <nachiketb@nvidia.com>
What
switchyard-corecrate.Why
The compatibility chain no longer needs a separate Rust core crate or a Rust-owned Python surface. Python callers should own Python control-plane values, while native processors should receive explicit adapters instead of defining the public API.
How
switchyard-componentsmodules.LLMBackendrole inswitchyard_rust.core.LLMBackendimplementations.Scope
This removes
switchyard-core, the publiccore_bindingsmodule, and the redundant_NativeChatRequestand_NativeChatResponsecontainers. It does not remove public Python exports or compatibility-chain features. Private interop remains only where native typed state or resource ownership requires it.What to review
isinstanceand composition behavior.Validation
cargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warningscargo test --workspaceuv run maturin developuv run ruff check .uv run mypy switchyarduv run pytest tests/ -q(1723 passed, 35 skipped)