LLM Translation¶
For a small integration example, read Use the translation crate. For field mappings, use LLM Requests and Responses and Streams.
TranslationEngine converts between provider JSON and Switchyard protocol
types. It makes no network calls. WireFormat identifies the built-in Chat
Completions, Responses, and Anthropic Messages formats. FormatId can also
identify custom formats registered through the codec interfaces.
Engine operations¶
All operations below are methods of TranslationEngine. The request and
buffered-response methods take a TranslationPolicy.
| Method | Input and result | Use it for |
|---|---|---|
decode_request |
Provider JSON to LlmRequest, plus diagnostics. |
Accepting a request from a provider-facing gateway or harness. |
encode_request |
LlmRequest to provider JSON, plus diagnostics. |
Sending a call through an existing client. |
translate_request |
Source provider JSON to target provider JSON. | Direct request conversion without handling the protocol value yourself. |
decode_response |
Provider JSON to AggLlmResponse, plus diagnostics. |
Returning a buffered response to libsy. |
encode_response |
AggLlmResponse to provider JSON, plus diagnostics. |
Returning a buffered answer in the caller's format. |
translate_response |
Source provider JSON to target provider JSON. | Direct buffered-response conversion. |
decode_stream_event |
One parsed provider event to LlmResponseStreamEvent. |
Retaining the source event alongside neutral chunks. |
encode_stream_event |
One LlmResponseStreamEvent to zero or more provider events. |
Replaying or converting incremental output. |
finish_stream |
Stream state to any remaining target events. | Closing the target format after the source stream ends. |
Buffered encoders return TranslationOutput with the encoded body and
TranslationDiagnostic values. Inspect diagnostics from decoding and encoding;
the direct translation helpers combine them and annotate source/target formats.
Policies¶
These defaults come from TranslationPolicy::default().
| Field and type | Default | Meaning |
|---|---|---|
TranslationPolicy.unknown_field_policy: UnknownFieldPolicy |
UnknownFieldPolicy::Preserve |
Keep unknown provider fields where the codec can retain them. Alternatives warn and drop, or reject. |
TranslationPolicy.lossy_conversion_policy: LossyConversionPolicy |
LossyConversionPolicy::AllowWithDiagnostics |
Allow known losses and record warnings. Use LossyConversionPolicy::Reject to fail on known lossy conversions. |
TranslationPolicy.deterministic_ids: DeterministicIdPolicy |
DeterministicIdPolicy::GenerateStable, prefix sw |
Generate stable IDs when needed. The alternative preserves IDs without generation. |
TranslationPolicy.preservation: PreservationPolicy |
PreservationPolicy::InMemory |
Retain original parsed bodies in protocol values for replay. |
TranslationPolicy.target_capabilities: TargetCapabilities |
All capability fields unspecified | Optionally constrain supported tools, media, reasoning, schema output, and other target features. |
Unspecified capabilities are not proof that a model supports a feature. A provider can still reject the encoded request. Known-loss rejection covers the codec's implemented checks, rather than proving semantic equivalence for every possible provider extension.
Preservation and edits¶
An original body takes precedence over reconstructed fields for its own format.
The codec looks up a request in PreservationMetadata.requests, or a buffered
response in PreservationMetadata.responses.
| Policy | Behavior | Boundary |
|---|---|---|
PreservationPolicy::InMemory |
Keep original JSON in protocol values. | Same-format replay works while that preservation data remains available. |
PreservationPolicy::Embed |
Also embed preservation metadata in translated JSON. | Supports multi-hop round trips when intermediaries retain it; provider metadata limits can prevent use. |
PreservationPolicy::Disabled |
Do not use preservation for replay. | Encoders reconstruct the body from current protocol fields. |
If you edit a decoded request, remove that format's entry from
PreservationMetadata.requests or encode with PreservationPolicy::Disabled.
This applies to model changes, messages, generation settings, and schema
enforcement. Apply the same rule to buffered response edits.
Replay preserves parsed JSON values, not original HTTP bytes, whitespace, or
headers. Input cleanup can happen before capture, including removal of Codex
internal compaction markers. Request.raw_request is host-owned and is not the
codec's replay source. Preserved data can contain the full conversation and
other sensitive provider fields.
Stream translation¶
Use a separate StreamTranslationState for each response stream. Feed parsed
provider events to decode_stream_event, pass the resulting event to
encode_stream_event, and call finish_stream when the source closes.
The encoder may emit several target events for one input event.
When the source and target formats match, a preserved event replays its retained
JSON. Cross-format encoding uses normalized chunks. After changing a stream
event, use replace_normalized() to clear raw data that no longer describes it.
The response reference
explains what aggregation retains and drops.
Conversion limits¶
Retention and destination support are separate. Anthropic has no distinct developer authority, the OpenAI formats have no standard tool-result error flag, and provider built-in tools or encrypted reasoning may lack equivalents.
Use ProviderExtensions and preservation to retain source data, then inspect
diagnostics and the destination model's capabilities. For a custom format,
FormatCodec and StreamCodec define the codec contracts;
TranslationEngine::with_registries accepts explicit registries.