Skip to main content

sim_lib_bridge/
model.rs

1use sim_codec_bridge::{BridgePacket, BridgePart};
2use sim_kernel::{Error, Expr, Result, Symbol};
3use sim_lib_agent_runner_core::{ModelResponse, OutputContract};
4use sim_lib_stream_fabric::ContentKey;
5use sim_value::access::field;
6
7use crate::rx::{shape_from_contract_expr, terminal_bridge_text as rx_terminal_bridge_text};
8use crate::tx::eval_request_for_checked_packet;
9
10/// Returns the terminal BRIDGE text from a model response.
11pub fn terminal_bridge_text(response: &ModelResponse) -> Result<&str> {
12    rx_terminal_bridge_text(response)
13}
14
15/// Decodes the terminal content item of a model response as a BRIDGE packet.
16pub fn terminal_response_packet(
17    response: &ModelResponse,
18    book: &sim_codec_bridge::BridgeBook,
19) -> Result<BridgePacket> {
20    sim_codec_bridge::decode_bridge_text(terminal_bridge_text(response)?, book)
21}
22
23/// Derives the content key for a checked BRIDGE model request.
24pub fn bridge_request_content_key(
25    cx: &mut sim_kernel::Cx,
26    book: &sim_codec_bridge::BridgeBook,
27    packet: &BridgePacket,
28) -> Result<ContentKey> {
29    let request = eval_request_for_checked_packet(cx, book, packet)?;
30    Ok(ContentKey::from_request(&request))
31}
32
33/// Builds the model output contract declared by a packet's output part.
34pub fn output_contract_for_packet(packet: &BridgePacket) -> Result<OutputContract> {
35    let output = output_part(packet).ok_or_else(|| {
36        Error::Eval(format!(
37            "BRIDGE packet output part {} is missing",
38            packet.header.output
39        ))
40    })?;
41    let codec = match field(&output.payload, "codec") {
42        Some(Expr::Symbol(symbol)) => symbol.clone(),
43        None => Symbol::qualified("codec", "bridge"),
44        Some(other) => {
45            return Err(Error::Eval(format!(
46                "BRIDGE Return codec must be a symbol, found {other:?}"
47            )));
48        }
49    };
50    let shape_expr = field(&output.payload, "shape")
51        .cloned()
52        .unwrap_or_else(|| Expr::Symbol(Symbol::qualified("core", "Any")));
53    let required = !matches!(field(&output.payload, "strict"), Some(Expr::Bool(false)));
54    let Some(shape) = shape_from_contract_expr(&shape_expr) else {
55        return Ok(OutputContract::new(codec, shape_expr, None, required));
56    };
57    Ok(OutputContract::for_shape(
58        codec,
59        shape_expr,
60        shape.as_ref(),
61        required,
62    ))
63}
64
65fn output_part(packet: &BridgePacket) -> Option<&BridgePart> {
66    packet
67        .body
68        .iter()
69        .find(|part| part.id == packet.header.output)
70}