Skip to main content

switchyard_protocol/
envelope.rs

1// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! The request/response envelope: the normalized [`LlmRequest`]/[`LlmResponse`] paired
5//! with the original provider payload and correlation [`Metadata`].
6
7use crate::{LlmRequest, LlmResponse, Metadata};
8
9/// Agentic-stack events fed to an algorithm out of band (e.g. tool results, budget
10/// updates) — in libsy, via `Algorithm::process_signals`.
11///
12/// A placeholder today; a stateful algorithm can begin consuming signals as the enum
13/// grows without changing the orchestrator contract.
14#[derive(Clone)]
15pub struct Signals {}
16
17/// A request an algorithm routes: the normalized [`LlmRequest`] plus optional
18/// host-owned raw data and correlation [`Metadata`].
19#[derive(Clone, Default)]
20pub struct Request {
21    /// The normalized request an algorithm routes.
22    pub llm_request: LlmRequest,
23    /// An optional whole request body retained by the host. libsy and the translation
24    /// codecs do not read it. Exact same-format codec replay instead uses
25    /// [`LlmRequest::preservation`].
26    pub raw_request: Option<serde_json::Value>,
27    /// Correlation metadata carried through the request.
28    pub metadata: Option<Metadata>,
29}
30
31impl Request {
32    /// Returns the model name supplied by the inbound request, when present.
33    ///
34    /// This is not necessarily the target selected by a routing decision.
35    pub fn requested_model(&self) -> Option<&str> {
36        self.llm_request.model.as_deref()
37    }
38}
39
40/// A response an algorithm returns: the [`LlmResponse`] (streamed or aggregate) plus
41/// optional correlation [`Metadata`].
42///
43/// Not `Clone` — `llm_response` may own a live stream.
44pub struct Response {
45    /// The neutral model response — a chunk stream or the buffered aggregate.
46    pub llm_response: LlmResponse,
47    /// Correlation metadata carried through the response.
48    pub metadata: Option<Metadata>,
49}
50
51impl Response {
52    /// Returns the model recorded by a buffered response.
53    ///
54    /// Returns `None` for a live stream because inspecting its `MessageStart`
55    /// event would require consuming the stream.
56    pub fn selected_model(&self) -> Option<&str> {
57        self.llm_response.selected_model()
58    }
59}