1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use super::{TokenUsage, ToolCallRequest};
5
6#[doc = include_str!("docs/stop_reason.md")]
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
8#[serde(rename_all = "snake_case")]
9pub enum StopReason {
10 EndTurn,
11 Length,
12 ToolCalls,
13 ContentFilter,
14 FunctionCall,
15 Unknown(String),
16}
17
18#[doc = include_str!("docs/llm_response.md")]
19#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
20#[serde(tag = "type", rename_all = "camelCase")]
21pub enum LlmResponse {
22 Start,
23 Text {
24 chunk: String,
25 },
26 Reasoning {
27 chunk: String,
28 },
29 EncryptedReasoning {
30 id: String,
31 content: String,
32 },
33 ToolRequestStart {
34 id: String,
35 name: String,
36 },
37 ToolRequestArg {
38 id: String,
39 chunk: String,
40 },
41 ToolRequestComplete {
42 tool_call: ToolCallRequest,
43 },
44 Done {
45 stop_reason: Option<StopReason>,
46 },
47 Error {
48 message: String,
49 },
50 Usage {
51 #[serde(flatten)]
52 tokens: TokenUsage,
53 },
54}
55
56impl LlmResponse {
57 pub fn text(chunk: &str) -> Self {
58 Self::Text { chunk: chunk.to_string() }
59 }
60
61 pub fn reasoning(chunk: &str) -> Self {
62 Self::Reasoning { chunk: chunk.to_string() }
63 }
64
65 pub fn encrypted_reasoning(id: &str, encrypted: &str) -> Self {
66 Self::EncryptedReasoning { id: id.to_string(), content: encrypted.to_string() }
67 }
68
69 pub fn tool_request_start(id: &str, name: &str) -> Self {
70 Self::ToolRequestStart { id: id.to_string(), name: name.to_string() }
71 }
72
73 pub fn tool_request_arg(id: &str, chunk: &str) -> Self {
74 Self::ToolRequestArg { id: id.to_string(), chunk: chunk.to_string() }
75 }
76
77 pub fn tool_request_complete(id: &str, name: &str, arguments: &str) -> Self {
78 Self::ToolRequestComplete {
79 tool_call: ToolCallRequest { id: id.to_string(), name: name.to_string(), arguments: arguments.to_string() },
80 }
81 }
82
83 pub fn usage(input_tokens: u64, output_tokens: u64) -> Self {
84 Self::Usage { tokens: TokenUsage::new(input_tokens, output_tokens) }
85 }
86
87 pub fn done() -> Self {
88 Self::Done { stop_reason: None }
89 }
90
91 pub fn done_with_stop_reason(stop_reason: StopReason) -> Self {
92 Self::Done { stop_reason: Some(stop_reason) }
93 }
94}