Skip to content

refactor(server): serve libsy algorithms without profiles#98

Merged
nachiketb-nvidia merged 4 commits into
mainfrom
nachiketb/libsy-server
Jul 21, 2026
Merged

refactor(server): serve libsy algorithms without profiles#98
nachiketb-nvidia merged 4 commits into
mainfrom
nachiketb/libsy-server

Conversation

@nachiketb-nvidia

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

Copy link
Copy Markdown
Contributor

What

Replace the components-v2 profile server with a thin HTTP host for libsy algorithms.

  • ServerState maps route model IDs directly to Arc<dyn Algorithm> values.
  • Repeated --route MODEL=TARGET[,TARGET...] arguments create independent libsy Random
    algorithms over one shared TranslatingLlmClient.
  • OpenAI Chat Completions, OpenAI Responses, and Anthropic Messages requests are decoded, run
    through the selected algorithm, and encoded back to the caller's format.
  • Harness headers are normalized by switchyard-protocol::Metadata::from_headers and retained for
    upstream forwarding.
  • The components-v2 config loader, profile registry, Rust stats endpoints, PyO3 server binding, and
    Python wrapper for the Rust server are removed.
  • switchyard serve --config remains on the existing Python FastAPI path instead of dispatching
    profile-only configs to Rust.
  • A concise crate README documents the current CLI.

Provider-specific Responses tool-turn translation is intentionally split into #111.

Why

The Rust server should own HTTP transport and algorithm dispatch while libsy owns routing behavior.
Keeping YAML parsing, profile construction, and profile-specific state in the server duplicated the
old architecture and prevented the server from being a small host for arbitrary libsy algorithms.

How

Each inbound request selects an algorithm by its model, translates the wire payload into a libsy
request, calls Algorithm::run, and converts the buffered or streaming result directly into an Axum
response. The CLI currently builds uniform-random algorithms only; all configured targets share one
upstream base URL, API key, and wire format.

switchyard-server \
  --route switchyard/general=model/a,model/b \
  --route switchyard/coding=model/c,model/d \
  --base-url https://example.com/v1

The server retains canonical HTTP errors, routing headers, /v1/models, /health, TLS, streaming,
and --dry-run. The removed Rust stats endpoints depended on the deleted profile runtime and are
not part of the libsy server surface.

What to review

  1. Direct model-to-algorithm lookup and rejection of empty or duplicate route IDs.
  2. Independent random target sets sharing one translating LLM client.
  3. Protocol-owned metadata normalization and preservation of forwarded HTTP headers.
  4. Inbound decode -> Algorithm::run -> direct buffered/SSE response conversion.
  5. Streaming termination, upstream error mapping, and routing response headers.
  6. Removal of profile/config ownership and the Rust server's Python bridge.
  7. Consolidated tests: endpoint behavior remains covered while libsy owns Random correctness.

Validation

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test -p switchyard-server (7 passed)
  • git diff --check origin/main

#79 is merged and this branch is based directly on main.

@nachiketb-nvidia
nachiketb-nvidia requested a review from a team as a code owner July 20, 2026 21:30
@nachiketb-nvidia
nachiketb-nvidia force-pushed the nachiketb/libsy-server branch from 018f51d to fbde70e Compare July 20, 2026 21:32
@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1

🚀 View preview at
https://NVIDIA-NeMo.github.io/Switchyard/pr-preview/pr-98/

Built to branch gh-pages at 2026-07-21 21:37 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@nachiketb-nvidia nachiketb-nvidia changed the title refactor(server): serve libsy random routing directly refactor(server): serve libsy algorithms directly Jul 20, 2026
@nachiketb-nvidia
nachiketb-nvidia force-pushed the nachiketb/libsy-server branch from e7855c6 to afe1dbe Compare July 20, 2026 21:55
@nachiketb-nvidia nachiketb-nvidia changed the title refactor(server): serve libsy algorithms directly refactor(server): initial work to serve libsy algorithms directly Jul 20, 2026
@grahamking
grahamking force-pushed the grclark/llm-client-crate branch from ae15075 to 4ec1acf Compare July 21, 2026 16:45
Base automatically changed from grclark/llm-client-crate to main July 21, 2026 16:55
@nachiketb-nvidia
nachiketb-nvidia force-pushed the nachiketb/libsy-server branch from f61aace to 48ee966 Compare July 21, 2026 21:04
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The pull request replaces the Rust profile-config server with a libsy algorithm-based HTTP server, routes profile-config serving through Python, removes obsolete bindings, and updates Responses translation for signed reasoning and tool-call arguments.

Changes

Libsy HTTP server

Layer / File(s) Summary
CLI and runtime construction
crates/switchyard-server/Cargo.toml, crates/switchyard-server/src/cli.rs, crates/switchyard-server/README.md
The CLI accepts repeatable routes, upstream settings, and wire-format options, then builds routed algorithms and runtime configuration.
State, routing, and HTTP handlers
crates/switchyard-server/src/lib.rs
Server state, unified LLM endpoints, model listing, TLS handling, errors, lifecycle, and startup output now use libsy algorithms.
Response encoding and SSE termination
crates/switchyard-server/src/response.rs, crates/switchyard-server/src/sse.rs
Responses use libsy encoders, and failed SSE streams stop without emitting later events or [DONE].
HTTP integration coverage
crates/switchyard-server/tests/server.rs
Tests cover routing, formats, random targets, streaming, health/models, missing endpoints, and errors.

Responses translation contracts

Layer / File(s) Summary
Buffered Responses input encoding
crates/switchyard-translation/src/codecs/responses/buffered.rs, crates/switchyard-translation/tests/request_translation.rs
Signed reasoning is omitted from Responses input, while tool-call arguments are serialized as JSON strings and covered by translation tests.

Python profile-serving path

Layer / File(s) Summary
Remove Rust profile-server bindings
crates/switchyard-py/Cargo.toml, crates/switchyard-py/src/lib.rs, switchyard_rust/core.py
The native profile-server dependency, registration, and protocol declaration are removed.
Use the Python HTTP application
switchyard/cli/switchyard_cli.py, switchyard/lib/profiles/loader.py, switchyard/lib/processors/random_routing_request_processor.py
The profile-config command uses the Python application directly and removes obsolete profile inspection and deprecation paths.
Serving documentation and test updates
docs/cli_reference.md, docs/internal/metrics_reference.md, tests/test_profile_migration.py, tests/test_route_bundle.py, tests/test_serve_profile_config.py
Documentation and tests are updated for Python-based profile serving and no longer verify Rust delegation.

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

Poem

A rabbit hops through routes anew,
With libsy paths and headers blue.
Signed thoughts fade from the stream,
Tool-call strings now neatly gleam.
Python serves the profiles bright—
SSE stops at errors’ night.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: the server now serves libsy algorithms instead of profile-based configs.

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

@nachiketb-nvidia
nachiketb-nvidia force-pushed the nachiketb/libsy-server branch from 48ee966 to 6b79ac8 Compare July 21, 2026 21:29
@nachiketb-nvidia nachiketb-nvidia changed the title refactor(server): initial work to serve libsy algorithms directly refactor(server): serve libsy algorithms without profiles Jul 21, 2026
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-server branch from 6b79ac8 to 2425ab7 Compare July 21, 2026 21:37
@nachiketb-nvidia
nachiketb-nvidia enabled auto-merge (squash) July 21, 2026 21:38
@nachiketb-nvidia
nachiketb-nvidia merged commit e09b5b0 into main Jul 21, 2026
20 checks passed
@nachiketb-nvidia
nachiketb-nvidia deleted the nachiketb/libsy-server branch July 21, 2026 21:40
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