Skip to content

feat(translation): prepare requests for routed targets - #455

Open
afourniernv wants to merge 1 commit into
NVIDIA-NeMo:mainfrom
afourniernv:afournier/switch-1253-target-prompt-translation
Open

feat(translation): prepare requests for routed targets#455
afourniernv wants to merge 1 commit into
NVIDIA-NeMo:mainfrom
afourniernv:afournier/switch-1253-target-prompt-translation

Conversation

@afourniernv

@afourniernv afourniernv commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds one translation-layer operation that stamps a routed target and optionally prepends that target's system prompt without losing provider-specific request fields.

This is 1 of 3 for SWITCH-1253. It establishes the wire-format operation only; it does not add target configuration or change router behavior by itself.

Before

Routing hosts changed only the normalized request:

request.llm_request.model = Some(target.to_string());

The normalized request may also retain an exact provider body so same-format forwarding can preserve fields Switchyard does not model. Updating only the normalized request could leave that body with the route alias and no target prompt. Dropping the body avoided stale replay, but also dropped provider-only fields.

After

Target selection and prompt insertion are one provider-aware operation:

prepare_request_for_target(&mut request.llm_request, target, prompt);

The helper updates the normalized request and any preserved OpenAI Chat, OpenAI Responses, or Anthropic Messages body together. Existing system content and provider-only fields remain intact, while same-format encoding cannot restore the route alias or omit the target prompt.

For a custom exact format, an unprompted exact body is left untouched; its codec remains responsible for stamping the wire-level model. If a configured prompt cannot be patched safely, Switchyard discards the stale exact replay and encodes from the normalized request.

Why this belongs in translation

Libsy decides which target and prompt apply. The translation crate knows how each provider represents model and system content. Keeping that mutation here gives libsy, the native server, and custom hosts one implementation instead of separate OpenAI and Anthropic patching rules.

There are no binding changes in this PR because it is the low-level operation used by the libsy layer in #463.

Scope

  • Adds the exported prepare_request_for_target(...) helper.
  • Preserves built-in provider fields and refreshes embedded preservation metadata without nesting stale snapshots.
  • Covers malformed and custom exact bodies explicitly.
  • Does not change a Python API, server API, router, or TOML schema.

Validation

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test -p switchyard-translation
  • Full non-PyO3 workspace tests passed on the complete stack.
  • PyO3 was rebuilt with maturin develop; 143 Python tests, ruff, mypy, and strict docs passed.
  • The complete stack passed 19 live NVIDIA scenarios across provider formats, streaming, retry/fallback, judge isolation, Stage compatibility, and direct Python libsy hosting.

Suggested review order

  1. crates/switchyard-translation/src/util.rs — the operation and the three built-in provider-body adapters
  2. crates/switchyard-translation/tests/request_translation.rs — preservation and failure boundaries
  3. crates/switchyard-translation/src/lib.rs — public export

Stack

PR Layer Responsibility
#455 (this PR) Translation Mutate normalized and exact provider requests safely
#463 libsy Prepare the request for each routed candidate
#464 Native server Expose targets.*.system_prompt, compatibility, docs, and integration tests

This PR is one signed commit: 7f749851 (3 files, +313/-5). The two dependent PRs remain drafts and currently show cumulative diffs against main; their unique commits and line counts are called out in their descriptions.

Summary by CodeRabbit

  • New Features

    • Added request preparation for targeting different models.
    • Supports optional system prompts while preserving provider-specific request settings.
    • Enables request translation across supported OpenAI and Anthropic formats.
  • Bug Fixes

    • Safely refreshes or removes preserved request data when it cannot be updated reliably.

@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8d3a3bb9-7653-48a1-b20d-074038e4ab19

📥 Commits

Reviewing files that changed from the base of the PR and between c7c07d5 and 7f74985.

📒 Files selected for processing (3)
  • crates/switchyard-translation/src/lib.rs
  • crates/switchyard-translation/src/util.rs
  • crates/switchyard-translation/tests/request_translation.rs

Included review availability: Your plan provides up to 12 included reviews per hour; 11 remain after this review.


Walkthrough

The translation crate exposes request preparation for target models and optional prompts. It patches preserved OpenAI Chat, OpenAI Responses, and Anthropic bodies, handles custom formats, restores preservation metadata, and adds cross-format and safety tests.

Changes

Request preparation

Layer / File(s) Summary
Preparation API and orchestration
crates/switchyard-translation/src/lib.rs, crates/switchyard-translation/src/util.rs
The crate exports prepare_request_for_target. The function updates the target model, optionally prepends a system instruction, and processes preserved bodies.
Preserved-body patching
crates/switchyard-translation/src/util.rs
Built-in OpenAI Chat, OpenAI Responses, and Anthropic bodies receive model and prompt updates. Unsupported custom bodies are retained without prompts or removed when patching is required. Preservation metadata is restored after serialization.
Preparation behavior validation
crates/switchyard-translation/tests/request_translation.rs
Tests cover target and prompt updates, provider-field preservation, cross-format relaying, no-prompt behavior, and removal of unpatchable bodies.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Merge Risk: ⚪ Minimal · up to 7f749

The translation change is localized and preserves provider request fields while applying routed target metadata and prompts. No actionable merge-blocking risk remains beyond normal checks and review.

Poem

I’m a rabbit with a request to prepare,
Models and prompts now travel with care.
OpenAI hops, Anthropic too,
Custom bodies know what they can do.
Tests guard each preserved hare.

🚥 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 clearly and concisely describes the new request-preparation operation for routed targets.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

Signed-off-by: Alex Fournier <afournier@nvidia.com>
@afourniernv
afourniernv force-pushed the afournier/switch-1253-target-prompt-translation branch from 7f74985 to 55d2a22 Compare August 19, 2026 16:29
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.

1 participant