walrus_core/model/
stream.rs1use crate::model::{
4 FinishReason,
5 response::{Choice, CompletionMeta, Delta},
6 tool::ToolCall,
7};
8use serde::Deserialize;
9
10#[derive(Debug, Clone, Deserialize, Default)]
12pub struct StreamChunk {
13 #[serde(flatten)]
15 pub meta: CompletionMeta,
16
17 pub choices: Vec<Choice>,
19
20 pub usage: Option<crate::model::Usage>,
22}
23
24impl StreamChunk {
25 pub fn tool(calls: &[ToolCall]) -> Self {
27 Self {
28 choices: vec![Choice {
29 delta: Delta {
30 tool_calls: Some(calls.to_vec()),
31 ..Default::default()
32 },
33 ..Default::default()
34 }],
35 ..Default::default()
36 }
37 }
38
39 pub fn separator() -> Self {
41 Self {
42 choices: vec![Choice {
43 delta: Delta {
44 content: Some("\n".into()),
45 ..Default::default()
46 },
47 ..Default::default()
48 }],
49 ..Default::default()
50 }
51 }
52
53 pub fn content(&self) -> Option<&str> {
55 self.choices
56 .first()
57 .and_then(|c| c.delta.content.as_deref())
58 .filter(|s| !s.is_empty())
59 }
60
61 pub fn reasoning_content(&self) -> Option<&str> {
63 self.choices
64 .first()
65 .and_then(|c| c.delta.reasoning_content.as_deref())
66 .filter(|s| !s.is_empty())
67 }
68
69 pub fn tool_calls(&self) -> Option<&[ToolCall]> {
71 self.choices
72 .first()
73 .and_then(|choice| choice.delta.tool_calls.as_deref())
74 }
75
76 pub fn reason(&self) -> Option<&FinishReason> {
78 self.choices
79 .first()
80 .and_then(|choice| choice.finish_reason.as_ref())
81 }
82}