streaming_chat/
streaming_chat.rs1use helios_engine::{LLMClient, ChatMessage, ChatSession};
7use helios_engine::config::LLMConfig;
8use std::io::{self, Write};
9
10#[tokio::main]
11async fn main() -> helios_engine::Result<()> {
12 println!("š Helios Engine - Streaming Example");
13 println!("=====================================\n");
14
15 let llm_config = LLMConfig {
17 model_name: "gpt-3.5-turbo".to_string(),
18 base_url: "https://api.openai.com/v1".to_string(),
19 api_key: std::env::var("OPENAI_API_KEY")
20 .unwrap_or_else(|_| "your-api-key-here".to_string()),
21 temperature: 0.7,
22 max_tokens: 2048,
23 };
24
25 let client = LLMClient::new(llm_config);
26
27 println!("Example 1: Simple Streaming Response");
28 println!("======================================\n");
29
30 let messages = vec![
31 ChatMessage::system("You are a helpful assistant."),
32 ChatMessage::user("Write a short poem about coding."),
33 ];
34
35 print!("Assistant: ");
36 io::stdout().flush()?;
37
38 let response = client.chat_stream(messages, None, |chunk| {
39 print!("{}", chunk);
40 io::stdout().flush().unwrap();
41 }).await?;
42
43 println!("\n\n");
44
45 println!("Example 2: Interactive Streaming Chat");
46 println!("======================================\n");
47
48 let mut session = ChatSession::new()
49 .with_system_prompt("You are a helpful coding assistant.");
50
51 let questions = vec![
52 "What is Rust?",
53 "What are its main benefits?",
54 "Show me a simple example.",
55 ];
56
57 for question in questions {
58 println!("User: {}", question);
59 session.add_user_message(question);
60
61 print!("Assistant: ");
62 io::stdout().flush()?;
63
64 let response = client.chat_stream(session.get_messages(), None, |chunk| {
65 print!("{}", chunk);
66 io::stdout().flush().unwrap();
67 }).await?;
68
69 session.add_assistant_message(&response.content);
70 println!("\n");
71 }
72
73 println!("\nExample 3: Streaming with Thinking Tags");
74 println!("=========================================\n");
75 println!("When using models that support thinking tags (like o1),");
76 println!("you can detect and display them during streaming.\n");
77
78 struct ThinkingTracker {
79 in_thinking: bool,
80 thinking_buffer: String,
81 }
82
83 impl ThinkingTracker {
84 fn new() -> Self {
85 Self {
86 in_thinking: false,
87 thinking_buffer: String::new(),
88 }
89 }
90
91 fn process_chunk(&mut self, chunk: &str) -> String {
92 let mut output = String::new();
93 let mut chars = chunk.chars().peekable();
94
95 while let Some(c) = chars.next() {
96 if c == '<' {
97 let remaining: String = chars.clone().collect();
98 if remaining.starts_with("thinking>") {
99 self.in_thinking = true;
100 self.thinking_buffer.clear();
101 output.push_str("\nš [Thinking");
102 for _ in 0..9 {
103 chars.next();
104 }
105 continue;
106 } else if remaining.starts_with("/thinking>") {
107 self.in_thinking = false;
108 output.push_str("]\n");
109 for _ in 0..10 {
110 chars.next();
111 }
112 continue;
113 }
114 }
115
116 if self.in_thinking {
117 self.thinking_buffer.push(c);
118 if self.thinking_buffer.len() % 3 == 0 {
119 output.push('.');
120 }
121 } else {
122 output.push(c);
123 }
124 }
125
126 output
127 }
128 }
129
130 let messages = vec![
131 ChatMessage::user("Solve this problem: What is 15 * 234 + 89?"),
132 ];
133
134 let mut tracker = ThinkingTracker::new();
135 print!("Assistant: ");
136 io::stdout().flush()?;
137
138 let _response = client.chat_stream(messages, None, |chunk| {
139 let output = tracker.process_chunk(chunk);
140 print!("{}", output);
141 io::stdout().flush().unwrap();
142 }).await?;
143
144 println!("\n\nā
Streaming examples completed!");
145 println!("\nKey benefits of streaming:");
146 println!(" ⢠Real-time response display");
147 println!(" ⢠Better user experience for long responses");
148 println!(" ⢠Ability to show thinking/reasoning process");
149 println!(" ⢠Early cancellation possible (future feature)");
150
151 Ok(())
152}