llm_cascade/models/
response.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
7#[serde(tag = "type", rename_all = "snake_case")]
8pub enum ContentBlock {
9 Text {
11 text: String,
13 },
14 ToolCall {
16 id: String,
18 name: String,
20 arguments: String,
22 },
23}
24
25impl ContentBlock {
26 pub fn text(text: impl Into<String>) -> Self {
28 ContentBlock::Text { text: text.into() }
29 }
30
31 pub fn tool_call(
33 id: impl Into<String>,
34 name: impl Into<String>,
35 arguments: impl Into<String>,
36 ) -> Self {
37 ContentBlock::ToolCall {
38 id: id.into(),
39 name: name.into(),
40 arguments: arguments.into(),
41 }
42 }
43
44 pub fn as_text(&self) -> Option<&str> {
46 match self {
47 ContentBlock::Text { text } => Some(text),
48 _ => None,
49 }
50 }
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct LlmResponse {
56 pub content: Vec<ContentBlock>,
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub input_tokens: Option<u32>,
61 #[serde(skip_serializing_if = "Option::is_none")]
63 pub output_tokens: Option<u32>,
64 pub model: String,
66}
67
68impl LlmResponse {
69 pub fn text_only(&self) -> String {
71 self.content
72 .iter()
73 .filter_map(|b| b.as_text())
74 .collect::<Vec<_>>()
75 .join("")
76 }
77}