Skip to main content

starweaver_runtime/
stream.rs

1//! Runtime stream-result type and compatibility exports for raw stream protocol records.
2
3use serde::{Deserialize, Serialize};
4
5use crate::AgentResult;
6
7#[cfg(test)]
8mod tests;
9
10pub use starweaver_stream::{
11    AgentSidebandEvent, AgentSidebandEventCategory, AgentStreamEvent, AgentStreamRecord,
12    AgentStreamSink, AgentStreamSource, AgentStreamSourceKind,
13};
14
15/// Result returned by collection-based stream runs.
16#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
17pub struct AgentStreamResult {
18    /// Final agent result.
19    pub result: AgentResult,
20    /// Events captured while the run progressed.
21    pub events: Vec<AgentStreamRecord>,
22}
23
24/// Project raw live records into the evidence-safe representation used by durable stores.
25///
26/// The returned records are a clone. Process-local Computer Use screenshot bytes are removed from
27/// geometry-marked tool returns while the caller's live stream remains byte-for-byte unchanged.
28#[must_use]
29pub fn project_stream_records_for_durable_evidence(
30    records: &[AgentStreamRecord],
31) -> Vec<AgentStreamRecord> {
32    let mut projected = records.to_vec();
33    for record in &mut projected {
34        if let AgentStreamEvent::ToolReturn { tool_return, .. } = &mut record.event {
35            starweaver_context::project_tool_return_for_durable_evidence(tool_return);
36        }
37    }
38    projected
39}
40
41impl AgentStreamResult {
42    /// Return captured stream records.
43    #[must_use]
44    pub fn events(&self) -> &[AgentStreamRecord] {
45        &self.events
46    }
47
48    /// Return the final result.
49    #[must_use]
50    pub const fn result(&self) -> &AgentResult {
51        &self.result
52    }
53
54    /// Project captured raw runtime stream records into JSON values.
55    ///
56    /// # Errors
57    ///
58    /// Returns a serialization error if a nested event payload cannot be encoded.
59    pub fn raw_json_records(&self) -> serde_json::Result<Vec<serde_json::Value>> {
60        self.events
61            .iter()
62            .map(AgentStreamRecord::to_raw_json)
63            .collect()
64    }
65}
66
67pub(crate) fn push_stream_event(
68    events: &mut Option<&mut Vec<AgentStreamRecord>>,
69    event: AgentStreamEvent,
70) {
71    if let Some(events) = events.as_deref_mut() {
72        events.push(AgentStreamRecord::new(events.len(), event));
73    }
74}
75
76pub(crate) fn push_stream_record(
77    events: &mut Option<&mut Vec<AgentStreamRecord>>,
78    record: AgentStreamRecord,
79) {
80    if let Some(events) = events.as_deref_mut() {
81        events.push(record.with_sequence(events.len()));
82    }
83}