pub struct ChatSession {
pub messages: Vec<ChatMessage>,
pub system_prompt: Option<String>,
pub metadata: HashMap<String, String>,
}Expand description
Represents a chat session, including the conversation history and metadata.
Fields§
§messages: Vec<ChatMessage>The messages in the chat session.
system_prompt: Option<String>The system prompt for the chat session.
metadata: HashMap<String, String>Metadata associated with the chat session.
Implementations§
Source§impl ChatSession
impl ChatSession
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new, empty chat session.
Examples found in repository?
examples/direct_llm_usage.rs (line 103)
88async fn conversation_with_context() -> helios_engine::Result<()> {
89 // Create a configuration for the LLM.
90 let llm_config = LLMConfig {
91 model_name: "gpt-3.5-turbo".to_string(),
92 base_url: "https://api.openai.com/v1".to_string(),
93 api_key: std::env::var("OPENAI_API_KEY")
94 .unwrap_or_else(|_| "your-api-key-here".to_string()),
95 temperature: 0.7,
96 max_tokens: 2048,
97 };
98
99 // Create a new LLM client.
100 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
101
102 // Use a `ChatSession` to manage the conversation history.
103 let mut session = ChatSession::new()
104 .with_system_prompt("You are a helpful math tutor. Give brief, clear explanations.");
105
106 // --- First turn ---
107 println!("Turn 1:");
108 session.add_user_message("What is 15 * 23?");
109 print!(" User: What is 15 * 23?\n ");
110
111 match client.chat(session.get_messages(), None).await {
112 Ok(response) => {
113 session.add_assistant_message(&response.content);
114 println!("Assistant: {}", response.content);
115 }
116 Err(e) => {
117 println!("Error: {}", e);
118 return Ok(());
119 }
120 }
121
122 // --- Second turn (with context from the first turn) ---
123 println!("\nTurn 2:");
124 session.add_user_message("Now divide that by 5.");
125 print!(" User: Now divide that by 5.\n ");
126
127 match client.chat(session.get_messages(), None).await {
128 Ok(response) => {
129 session.add_assistant_message(&response.content);
130 println!("Assistant: {}", response.content);
131 }
132 Err(e) => {
133 println!("Error: {}", e);
134 }
135 }
136
137 println!("\n💡 Notice how the assistant remembered the result from the first calculation!");
138
139 Ok(())
140}
141
142/// Provides information about using different LLM providers.
143fn different_providers_info() {
144 println!("You can use Helios with various LLM providers:\n");
145
146 println!("🔵 OpenAI:");
147 println!(" LLMConfig {{");
148 println!(" model_name: \"gpt-4\".to_string(),");
149 println!(" base_url: \"https://api.openai.com/v1\".to_string(),");
150 println!(" api_key: env::var(\"OPENAI_API_KEY\").unwrap(),");
151 println!(" temperature: 0.7,");
152 println!(" max_tokens: 2048,");
153 println!(" }}\n");
154
155 println!("🟢 Local LM Studio:");
156 println!(" LLMConfig {{");
157 println!(" model_name: \"local-model\".to_string(),");
158 println!(" base_url: \"http://localhost:1234/v1\".to_string(),");
159 println!(" api_key: \"not-needed\".to_string(),");
160 println!(" temperature: 0.7,");
161 println!(" max_tokens: 2048,");
162 println!(" }}\n");
163
164 println!("🦙 Ollama:");
165 println!(" LLMConfig {{");
166 println!(" model_name: \"llama2\".to_string(),");
167 println!(" base_url: \"http://localhost:11434/v1\".to_string(),");
168 println!(" api_key: \"not-needed\".to_string(),");
169 println!(" temperature: 0.7,");
170 println!(" max_tokens: 2048,");
171 println!(" }}\n");
172
173 println!("🔷 Azure OpenAI:");
174 println!(" LLMConfig {{");
175 println!(" model_name: \"gpt-35-turbo\".to_string(),");
176 println!(" base_url: \"https://your-resource.openai.azure.com/...\".to_string(),");
177 println!(" api_key: env::var(\"AZURE_OPENAI_KEY\").unwrap(),");
178 println!(" temperature: 0.7,");
179 println!(" max_tokens: 2048,");
180 println!(" }}\n");
181}
182
183/// Starts an interactive chat session with the LLM.
184async fn interactive_chat() -> helios_engine::Result<()> {
185 // Create a configuration for the LLM.
186 let llm_config = LLMConfig {
187 model_name: "gpt-3.5-turbo".to_string(),
188 base_url: "https://api.openai.com/v1".to_string(),
189 api_key: std::env::var("OPENAI_API_KEY")
190 .unwrap_or_else(|_| "your-api-key-here".to_string()),
191 temperature: 0.7,
192 max_tokens: 2048,
193 };
194
195 // Create a new LLM client.
196 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
197 let mut session =
198 ChatSession::new().with_system_prompt("You are a friendly and helpful AI assistant.");
199
200 println!("Chat started! Type 'exit' or 'quit' to end the conversation.\n");
201
202 loop {
203 print!("You: ");
204 io::stdout().flush()?;
205
206 let mut input = String::new();
207 io::stdin().read_line(&mut input)?;
208 let input = input.trim();
209
210 if input.is_empty() {
211 continue;
212 }
213
214 if input == "exit" || input == "quit" {
215 println!("\n👋 Goodbye!");
216 break;
217 }
218
219 // Handle special commands.
220 if input == "clear" {
221 session.clear();
222 println!("🧹 Conversation cleared!\n");
223 continue;
224 }
225
226 if input == "history" {
227 println!("\n📜 Conversation history:");
228 for (i, msg) in session.messages.iter().enumerate() {
229 println!(" {}. {:?}: {}", i + 1, msg.role, msg.content);
230 }
231 println!();
232 continue;
233 }
234
235 session.add_user_message(input);
236
237 print!("Assistant: ");
238 io::stdout().flush()?;
239
240 match client.chat(session.get_messages(), None).await {
241 Ok(response) => {
242 session.add_assistant_message(&response.content);
243 println!("{}\n", response.content);
244 }
245 Err(e) => {
246 println!("\n❌ Error: {}", e);
247 println!(" (Make sure OPENAI_API_KEY is set correctly)\n");
248 // Remove the last user message since it failed.
249 session.messages.pop();
250 }
251 }
252 }
253
254 Ok(())
255}More examples
examples/local_streaming.rs (line 65)
12async fn main() -> helios_engine::Result<()> {
13 println!("🚀 Helios Engine - Local Model Streaming Example");
14 println!("=================================================\n");
15
16 // Configure the local model to use.
17 let local_config = LocalConfig {
18 huggingface_repo: "unsloth/Qwen2.5-0.5B-Instruct-GGUF".to_string(),
19 model_file: "Qwen2.5-0.5B-Instruct-Q4_K_M.gguf".to_string(),
20 context_size: 2048,
21 temperature: 0.7,
22 max_tokens: 512,
23 };
24
25 println!("📥 Loading local model...");
26 println!(" Repository: {}", local_config.huggingface_repo);
27 println!(" Model: {}\n", local_config.model_file);
28
29 // Create a new LLM client with the local model configuration.
30 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Local(local_config)).await?;
31
32 println!("✓ Model loaded successfully!\n");
33
34 // --- Example 1: Simple streaming response ---
35 println!("Example 1: Simple Streaming Response");
36 println!("======================================\n");
37
38 let messages = vec![
39 ChatMessage::system("You are a helpful coding assistant."),
40 ChatMessage::user("Write a short explanation of what Rust is."),
41 ];
42
43 print!("Assistant: ");
44 io::stdout().flush()?;
45
46 // Stream the response from the model, printing each chunk as it arrives.
47 let _response = client
48 .chat_stream(messages, None, |chunk| {
49 print!("{}", chunk);
50 io::stdout().flush().unwrap();
51 })
52 .await?;
53
54 println!("\n");
55
56 // --- Example 2: Interactive streaming ---
57 println!("Example 2: Interactive Streaming");
58 println!("==================================\n");
59
60 let questions = vec![
61 "What are the main benefits of Rust?",
62 "Give me a simple code example.",
63 ];
64
65 let mut session = helios_engine::ChatSession::new()
66 .with_system_prompt("You are a helpful programming assistant.");
67
68 for question in questions {
69 println!("User: {}", question);
70 session.add_user_message(question);
71
72 print!("Assistant: ");
73 io::stdout().flush()?;
74
75 // Stream the response, maintaining the conversation context.
76 let response = client
77 .chat_stream(session.get_messages(), None, |chunk| {
78 print!("{}", chunk);
79 io::stdout().flush().unwrap();
80 })
81 .await?;
82
83 session.add_assistant_message(&response.content);
84 println!("\n");
85 }
86
87 println!("✅ Local model streaming completed successfully!");
88 println!("\n💡 Features:");
89 println!(" • Token-by-token streaming for local models");
90 println!(" • Real-time response display (no more instant full responses)");
91 println!(" • Same streaming API for both local and remote models");
92 println!(" • Improved user experience with progressive output");
93
94 Ok(())
95}examples/streaming_chat.rs (line 57)
14async fn main() -> helios_engine::Result<()> {
15 println!("🚀 Helios Engine - Streaming Example");
16 println!("=====================================\n");
17
18 // Set up the LLM configuration.
19 let llm_config = LLMConfig {
20 model_name: "gpt-3.5-turbo".to_string(),
21 base_url: "https://api.openai.com/v1".to_string(),
22 api_key: std::env::var("OPENAI_API_KEY")
23 .unwrap_or_else(|_| "your-api-key-here".to_string()),
24 temperature: 0.7,
25 max_tokens: 2048,
26 };
27
28 // Create a new LLM client.
29 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
30
31 // --- Example 1: Simple streaming response ---
32 println!("Example 1: Simple Streaming Response");
33 println!("======================================\n");
34
35 let messages = vec![
36 ChatMessage::system("You are a helpful assistant."),
37 ChatMessage::user("Write a short poem about coding."),
38 ];
39
40 print!("Assistant: ");
41 io::stdout().flush()?;
42
43 // Stream the response from the model, printing each chunk as it arrives.
44 let response = client
45 .chat_stream(messages, None, |chunk| {
46 print!("{}", chunk);
47 io::stdout().flush().unwrap();
48 })
49 .await?;
50
51 println!("\n\n");
52
53 // --- Example 2: Interactive streaming chat ---
54 println!("Example 2: Interactive Streaming Chat");
55 println!("======================================\n");
56
57 let mut session = ChatSession::new().with_system_prompt("You are a helpful coding assistant.");
58
59 let questions = vec![
60 "What is Rust?",
61 "What are its main benefits?",
62 "Show me a simple example.",
63 ];
64
65 for question in questions {
66 println!("User: {}", question);
67 session.add_user_message(question);
68
69 print!("Assistant: ");
70 io::stdout().flush()?;
71
72 // Stream the response, maintaining the conversation context.
73 let response = client
74 .chat_stream(session.get_messages(), None, |chunk| {
75 print!("{}", chunk);
76 io::stdout().flush().unwrap();
77 })
78 .await?;
79
80 session.add_assistant_message(&response.content);
81 println!("\n");
82 }
83
84 // --- Example 3: Streaming with thinking tags ---
85 println!("\nExample 3: Streaming with Thinking Tags");
86 println!("=========================================\n");
87 println!("When using models that support thinking tags (like o1),");
88 println!("you can detect and display them during streaming.\n");
89
90 /// A helper struct to track and display thinking tags in streamed responses.
91 struct ThinkingTracker {
92 in_thinking: bool,
93 thinking_buffer: String,
94 }
95
96 impl ThinkingTracker {
97 /// Creates a new `ThinkingTracker`.
98 fn new() -> Self {
99 Self {
100 in_thinking: false,
101 thinking_buffer: String::new(),
102 }
103 }
104
105 /// Processes a chunk of a streamed response and returns the processed output.
106 fn process_chunk(&mut self, chunk: &str) -> String {
107 let mut output = String::new();
108 let mut chars = chunk.chars().peekable();
109
110 while let Some(c) = chars.next() {
111 if c == '<' {
112 let remaining: String = chars.clone().collect();
113 if remaining.starts_with("thinking>") {
114 self.in_thinking = true;
115 self.thinking_buffer.clear();
116 output.push_str("\n💭 [Thinking");
117 for _ in 0..9 {
118 chars.next();
119 }
120 continue;
121 } else if remaining.starts_with("/thinking>") {
122 self.in_thinking = false;
123 output.push_str("]\n");
124 for _ in 0..10 {
125 chars.next();
126 }
127 continue;
128 }
129 }
130
131 if self.in_thinking {
132 self.thinking_buffer.push(c);
133 if self.thinking_buffer.len() % 3 == 0 {
134 output.push('.');
135 }
136 } else {
137 output.push(c);
138 }
139 }
140
141 output
142 }
143 }
144
145 let messages = vec![ChatMessage::user(
146 "Solve this problem: What is 15 * 234 + 89?",
147 )];
148
149 let mut tracker = ThinkingTracker::new();
150 print!("Assistant: ");
151 io::stdout().flush()?;
152
153 // Stream the response, processing thinking tags as they arrive.
154 let _response = client
155 .chat_stream(messages, None, |chunk| {
156 let output = tracker.process_chunk(chunk);
157 print!("{}", output);
158 io::stdout().flush().unwrap();
159 })
160 .await?;
161
162 println!("\n\n✅ Streaming examples completed!");
163 println!("\nKey benefits of streaming:");
164 println!(" • Real-time response display");
165 println!(" • Better user experience for long responses");
166 println!(" • Ability to show thinking/reasoning process");
167 println!(" • Early cancellation possible (future feature)");
168
169 Ok(())
170}Sourcepub fn with_system_prompt(self, prompt: impl Into<String>) -> Self
pub fn with_system_prompt(self, prompt: impl Into<String>) -> Self
Sets the system prompt for the chat session.
Examples found in repository?
examples/direct_llm_usage.rs (line 104)
88async fn conversation_with_context() -> helios_engine::Result<()> {
89 // Create a configuration for the LLM.
90 let llm_config = LLMConfig {
91 model_name: "gpt-3.5-turbo".to_string(),
92 base_url: "https://api.openai.com/v1".to_string(),
93 api_key: std::env::var("OPENAI_API_KEY")
94 .unwrap_or_else(|_| "your-api-key-here".to_string()),
95 temperature: 0.7,
96 max_tokens: 2048,
97 };
98
99 // Create a new LLM client.
100 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
101
102 // Use a `ChatSession` to manage the conversation history.
103 let mut session = ChatSession::new()
104 .with_system_prompt("You are a helpful math tutor. Give brief, clear explanations.");
105
106 // --- First turn ---
107 println!("Turn 1:");
108 session.add_user_message("What is 15 * 23?");
109 print!(" User: What is 15 * 23?\n ");
110
111 match client.chat(session.get_messages(), None).await {
112 Ok(response) => {
113 session.add_assistant_message(&response.content);
114 println!("Assistant: {}", response.content);
115 }
116 Err(e) => {
117 println!("Error: {}", e);
118 return Ok(());
119 }
120 }
121
122 // --- Second turn (with context from the first turn) ---
123 println!("\nTurn 2:");
124 session.add_user_message("Now divide that by 5.");
125 print!(" User: Now divide that by 5.\n ");
126
127 match client.chat(session.get_messages(), None).await {
128 Ok(response) => {
129 session.add_assistant_message(&response.content);
130 println!("Assistant: {}", response.content);
131 }
132 Err(e) => {
133 println!("Error: {}", e);
134 }
135 }
136
137 println!("\n💡 Notice how the assistant remembered the result from the first calculation!");
138
139 Ok(())
140}
141
142/// Provides information about using different LLM providers.
143fn different_providers_info() {
144 println!("You can use Helios with various LLM providers:\n");
145
146 println!("🔵 OpenAI:");
147 println!(" LLMConfig {{");
148 println!(" model_name: \"gpt-4\".to_string(),");
149 println!(" base_url: \"https://api.openai.com/v1\".to_string(),");
150 println!(" api_key: env::var(\"OPENAI_API_KEY\").unwrap(),");
151 println!(" temperature: 0.7,");
152 println!(" max_tokens: 2048,");
153 println!(" }}\n");
154
155 println!("🟢 Local LM Studio:");
156 println!(" LLMConfig {{");
157 println!(" model_name: \"local-model\".to_string(),");
158 println!(" base_url: \"http://localhost:1234/v1\".to_string(),");
159 println!(" api_key: \"not-needed\".to_string(),");
160 println!(" temperature: 0.7,");
161 println!(" max_tokens: 2048,");
162 println!(" }}\n");
163
164 println!("🦙 Ollama:");
165 println!(" LLMConfig {{");
166 println!(" model_name: \"llama2\".to_string(),");
167 println!(" base_url: \"http://localhost:11434/v1\".to_string(),");
168 println!(" api_key: \"not-needed\".to_string(),");
169 println!(" temperature: 0.7,");
170 println!(" max_tokens: 2048,");
171 println!(" }}\n");
172
173 println!("🔷 Azure OpenAI:");
174 println!(" LLMConfig {{");
175 println!(" model_name: \"gpt-35-turbo\".to_string(),");
176 println!(" base_url: \"https://your-resource.openai.azure.com/...\".to_string(),");
177 println!(" api_key: env::var(\"AZURE_OPENAI_KEY\").unwrap(),");
178 println!(" temperature: 0.7,");
179 println!(" max_tokens: 2048,");
180 println!(" }}\n");
181}
182
183/// Starts an interactive chat session with the LLM.
184async fn interactive_chat() -> helios_engine::Result<()> {
185 // Create a configuration for the LLM.
186 let llm_config = LLMConfig {
187 model_name: "gpt-3.5-turbo".to_string(),
188 base_url: "https://api.openai.com/v1".to_string(),
189 api_key: std::env::var("OPENAI_API_KEY")
190 .unwrap_or_else(|_| "your-api-key-here".to_string()),
191 temperature: 0.7,
192 max_tokens: 2048,
193 };
194
195 // Create a new LLM client.
196 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
197 let mut session =
198 ChatSession::new().with_system_prompt("You are a friendly and helpful AI assistant.");
199
200 println!("Chat started! Type 'exit' or 'quit' to end the conversation.\n");
201
202 loop {
203 print!("You: ");
204 io::stdout().flush()?;
205
206 let mut input = String::new();
207 io::stdin().read_line(&mut input)?;
208 let input = input.trim();
209
210 if input.is_empty() {
211 continue;
212 }
213
214 if input == "exit" || input == "quit" {
215 println!("\n👋 Goodbye!");
216 break;
217 }
218
219 // Handle special commands.
220 if input == "clear" {
221 session.clear();
222 println!("🧹 Conversation cleared!\n");
223 continue;
224 }
225
226 if input == "history" {
227 println!("\n📜 Conversation history:");
228 for (i, msg) in session.messages.iter().enumerate() {
229 println!(" {}. {:?}: {}", i + 1, msg.role, msg.content);
230 }
231 println!();
232 continue;
233 }
234
235 session.add_user_message(input);
236
237 print!("Assistant: ");
238 io::stdout().flush()?;
239
240 match client.chat(session.get_messages(), None).await {
241 Ok(response) => {
242 session.add_assistant_message(&response.content);
243 println!("{}\n", response.content);
244 }
245 Err(e) => {
246 println!("\n❌ Error: {}", e);
247 println!(" (Make sure OPENAI_API_KEY is set correctly)\n");
248 // Remove the last user message since it failed.
249 session.messages.pop();
250 }
251 }
252 }
253
254 Ok(())
255}More examples
examples/local_streaming.rs (line 66)
12async fn main() -> helios_engine::Result<()> {
13 println!("🚀 Helios Engine - Local Model Streaming Example");
14 println!("=================================================\n");
15
16 // Configure the local model to use.
17 let local_config = LocalConfig {
18 huggingface_repo: "unsloth/Qwen2.5-0.5B-Instruct-GGUF".to_string(),
19 model_file: "Qwen2.5-0.5B-Instruct-Q4_K_M.gguf".to_string(),
20 context_size: 2048,
21 temperature: 0.7,
22 max_tokens: 512,
23 };
24
25 println!("📥 Loading local model...");
26 println!(" Repository: {}", local_config.huggingface_repo);
27 println!(" Model: {}\n", local_config.model_file);
28
29 // Create a new LLM client with the local model configuration.
30 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Local(local_config)).await?;
31
32 println!("✓ Model loaded successfully!\n");
33
34 // --- Example 1: Simple streaming response ---
35 println!("Example 1: Simple Streaming Response");
36 println!("======================================\n");
37
38 let messages = vec![
39 ChatMessage::system("You are a helpful coding assistant."),
40 ChatMessage::user("Write a short explanation of what Rust is."),
41 ];
42
43 print!("Assistant: ");
44 io::stdout().flush()?;
45
46 // Stream the response from the model, printing each chunk as it arrives.
47 let _response = client
48 .chat_stream(messages, None, |chunk| {
49 print!("{}", chunk);
50 io::stdout().flush().unwrap();
51 })
52 .await?;
53
54 println!("\n");
55
56 // --- Example 2: Interactive streaming ---
57 println!("Example 2: Interactive Streaming");
58 println!("==================================\n");
59
60 let questions = vec![
61 "What are the main benefits of Rust?",
62 "Give me a simple code example.",
63 ];
64
65 let mut session = helios_engine::ChatSession::new()
66 .with_system_prompt("You are a helpful programming assistant.");
67
68 for question in questions {
69 println!("User: {}", question);
70 session.add_user_message(question);
71
72 print!("Assistant: ");
73 io::stdout().flush()?;
74
75 // Stream the response, maintaining the conversation context.
76 let response = client
77 .chat_stream(session.get_messages(), None, |chunk| {
78 print!("{}", chunk);
79 io::stdout().flush().unwrap();
80 })
81 .await?;
82
83 session.add_assistant_message(&response.content);
84 println!("\n");
85 }
86
87 println!("✅ Local model streaming completed successfully!");
88 println!("\n💡 Features:");
89 println!(" • Token-by-token streaming for local models");
90 println!(" • Real-time response display (no more instant full responses)");
91 println!(" • Same streaming API for both local and remote models");
92 println!(" • Improved user experience with progressive output");
93
94 Ok(())
95}examples/streaming_chat.rs (line 57)
14async fn main() -> helios_engine::Result<()> {
15 println!("🚀 Helios Engine - Streaming Example");
16 println!("=====================================\n");
17
18 // Set up the LLM configuration.
19 let llm_config = LLMConfig {
20 model_name: "gpt-3.5-turbo".to_string(),
21 base_url: "https://api.openai.com/v1".to_string(),
22 api_key: std::env::var("OPENAI_API_KEY")
23 .unwrap_or_else(|_| "your-api-key-here".to_string()),
24 temperature: 0.7,
25 max_tokens: 2048,
26 };
27
28 // Create a new LLM client.
29 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
30
31 // --- Example 1: Simple streaming response ---
32 println!("Example 1: Simple Streaming Response");
33 println!("======================================\n");
34
35 let messages = vec![
36 ChatMessage::system("You are a helpful assistant."),
37 ChatMessage::user("Write a short poem about coding."),
38 ];
39
40 print!("Assistant: ");
41 io::stdout().flush()?;
42
43 // Stream the response from the model, printing each chunk as it arrives.
44 let response = client
45 .chat_stream(messages, None, |chunk| {
46 print!("{}", chunk);
47 io::stdout().flush().unwrap();
48 })
49 .await?;
50
51 println!("\n\n");
52
53 // --- Example 2: Interactive streaming chat ---
54 println!("Example 2: Interactive Streaming Chat");
55 println!("======================================\n");
56
57 let mut session = ChatSession::new().with_system_prompt("You are a helpful coding assistant.");
58
59 let questions = vec![
60 "What is Rust?",
61 "What are its main benefits?",
62 "Show me a simple example.",
63 ];
64
65 for question in questions {
66 println!("User: {}", question);
67 session.add_user_message(question);
68
69 print!("Assistant: ");
70 io::stdout().flush()?;
71
72 // Stream the response, maintaining the conversation context.
73 let response = client
74 .chat_stream(session.get_messages(), None, |chunk| {
75 print!("{}", chunk);
76 io::stdout().flush().unwrap();
77 })
78 .await?;
79
80 session.add_assistant_message(&response.content);
81 println!("\n");
82 }
83
84 // --- Example 3: Streaming with thinking tags ---
85 println!("\nExample 3: Streaming with Thinking Tags");
86 println!("=========================================\n");
87 println!("When using models that support thinking tags (like o1),");
88 println!("you can detect and display them during streaming.\n");
89
90 /// A helper struct to track and display thinking tags in streamed responses.
91 struct ThinkingTracker {
92 in_thinking: bool,
93 thinking_buffer: String,
94 }
95
96 impl ThinkingTracker {
97 /// Creates a new `ThinkingTracker`.
98 fn new() -> Self {
99 Self {
100 in_thinking: false,
101 thinking_buffer: String::new(),
102 }
103 }
104
105 /// Processes a chunk of a streamed response and returns the processed output.
106 fn process_chunk(&mut self, chunk: &str) -> String {
107 let mut output = String::new();
108 let mut chars = chunk.chars().peekable();
109
110 while let Some(c) = chars.next() {
111 if c == '<' {
112 let remaining: String = chars.clone().collect();
113 if remaining.starts_with("thinking>") {
114 self.in_thinking = true;
115 self.thinking_buffer.clear();
116 output.push_str("\n💭 [Thinking");
117 for _ in 0..9 {
118 chars.next();
119 }
120 continue;
121 } else if remaining.starts_with("/thinking>") {
122 self.in_thinking = false;
123 output.push_str("]\n");
124 for _ in 0..10 {
125 chars.next();
126 }
127 continue;
128 }
129 }
130
131 if self.in_thinking {
132 self.thinking_buffer.push(c);
133 if self.thinking_buffer.len() % 3 == 0 {
134 output.push('.');
135 }
136 } else {
137 output.push(c);
138 }
139 }
140
141 output
142 }
143 }
144
145 let messages = vec![ChatMessage::user(
146 "Solve this problem: What is 15 * 234 + 89?",
147 )];
148
149 let mut tracker = ThinkingTracker::new();
150 print!("Assistant: ");
151 io::stdout().flush()?;
152
153 // Stream the response, processing thinking tags as they arrive.
154 let _response = client
155 .chat_stream(messages, None, |chunk| {
156 let output = tracker.process_chunk(chunk);
157 print!("{}", output);
158 io::stdout().flush().unwrap();
159 })
160 .await?;
161
162 println!("\n\n✅ Streaming examples completed!");
163 println!("\nKey benefits of streaming:");
164 println!(" • Real-time response display");
165 println!(" • Better user experience for long responses");
166 println!(" • Ability to show thinking/reasoning process");
167 println!(" • Early cancellation possible (future feature)");
168
169 Ok(())
170}Sourcepub fn add_message(&mut self, message: ChatMessage)
pub fn add_message(&mut self, message: ChatMessage)
Adds a message to the chat session.
Sourcepub fn add_user_message(&mut self, content: impl Into<String>)
pub fn add_user_message(&mut self, content: impl Into<String>)
Adds a user message to the chat session.
Examples found in repository?
examples/direct_llm_usage.rs (line 108)
88async fn conversation_with_context() -> helios_engine::Result<()> {
89 // Create a configuration for the LLM.
90 let llm_config = LLMConfig {
91 model_name: "gpt-3.5-turbo".to_string(),
92 base_url: "https://api.openai.com/v1".to_string(),
93 api_key: std::env::var("OPENAI_API_KEY")
94 .unwrap_or_else(|_| "your-api-key-here".to_string()),
95 temperature: 0.7,
96 max_tokens: 2048,
97 };
98
99 // Create a new LLM client.
100 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
101
102 // Use a `ChatSession` to manage the conversation history.
103 let mut session = ChatSession::new()
104 .with_system_prompt("You are a helpful math tutor. Give brief, clear explanations.");
105
106 // --- First turn ---
107 println!("Turn 1:");
108 session.add_user_message("What is 15 * 23?");
109 print!(" User: What is 15 * 23?\n ");
110
111 match client.chat(session.get_messages(), None).await {
112 Ok(response) => {
113 session.add_assistant_message(&response.content);
114 println!("Assistant: {}", response.content);
115 }
116 Err(e) => {
117 println!("Error: {}", e);
118 return Ok(());
119 }
120 }
121
122 // --- Second turn (with context from the first turn) ---
123 println!("\nTurn 2:");
124 session.add_user_message("Now divide that by 5.");
125 print!(" User: Now divide that by 5.\n ");
126
127 match client.chat(session.get_messages(), None).await {
128 Ok(response) => {
129 session.add_assistant_message(&response.content);
130 println!("Assistant: {}", response.content);
131 }
132 Err(e) => {
133 println!("Error: {}", e);
134 }
135 }
136
137 println!("\n💡 Notice how the assistant remembered the result from the first calculation!");
138
139 Ok(())
140}
141
142/// Provides information about using different LLM providers.
143fn different_providers_info() {
144 println!("You can use Helios with various LLM providers:\n");
145
146 println!("🔵 OpenAI:");
147 println!(" LLMConfig {{");
148 println!(" model_name: \"gpt-4\".to_string(),");
149 println!(" base_url: \"https://api.openai.com/v1\".to_string(),");
150 println!(" api_key: env::var(\"OPENAI_API_KEY\").unwrap(),");
151 println!(" temperature: 0.7,");
152 println!(" max_tokens: 2048,");
153 println!(" }}\n");
154
155 println!("🟢 Local LM Studio:");
156 println!(" LLMConfig {{");
157 println!(" model_name: \"local-model\".to_string(),");
158 println!(" base_url: \"http://localhost:1234/v1\".to_string(),");
159 println!(" api_key: \"not-needed\".to_string(),");
160 println!(" temperature: 0.7,");
161 println!(" max_tokens: 2048,");
162 println!(" }}\n");
163
164 println!("🦙 Ollama:");
165 println!(" LLMConfig {{");
166 println!(" model_name: \"llama2\".to_string(),");
167 println!(" base_url: \"http://localhost:11434/v1\".to_string(),");
168 println!(" api_key: \"not-needed\".to_string(),");
169 println!(" temperature: 0.7,");
170 println!(" max_tokens: 2048,");
171 println!(" }}\n");
172
173 println!("🔷 Azure OpenAI:");
174 println!(" LLMConfig {{");
175 println!(" model_name: \"gpt-35-turbo\".to_string(),");
176 println!(" base_url: \"https://your-resource.openai.azure.com/...\".to_string(),");
177 println!(" api_key: env::var(\"AZURE_OPENAI_KEY\").unwrap(),");
178 println!(" temperature: 0.7,");
179 println!(" max_tokens: 2048,");
180 println!(" }}\n");
181}
182
183/// Starts an interactive chat session with the LLM.
184async fn interactive_chat() -> helios_engine::Result<()> {
185 // Create a configuration for the LLM.
186 let llm_config = LLMConfig {
187 model_name: "gpt-3.5-turbo".to_string(),
188 base_url: "https://api.openai.com/v1".to_string(),
189 api_key: std::env::var("OPENAI_API_KEY")
190 .unwrap_or_else(|_| "your-api-key-here".to_string()),
191 temperature: 0.7,
192 max_tokens: 2048,
193 };
194
195 // Create a new LLM client.
196 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
197 let mut session =
198 ChatSession::new().with_system_prompt("You are a friendly and helpful AI assistant.");
199
200 println!("Chat started! Type 'exit' or 'quit' to end the conversation.\n");
201
202 loop {
203 print!("You: ");
204 io::stdout().flush()?;
205
206 let mut input = String::new();
207 io::stdin().read_line(&mut input)?;
208 let input = input.trim();
209
210 if input.is_empty() {
211 continue;
212 }
213
214 if input == "exit" || input == "quit" {
215 println!("\n👋 Goodbye!");
216 break;
217 }
218
219 // Handle special commands.
220 if input == "clear" {
221 session.clear();
222 println!("🧹 Conversation cleared!\n");
223 continue;
224 }
225
226 if input == "history" {
227 println!("\n📜 Conversation history:");
228 for (i, msg) in session.messages.iter().enumerate() {
229 println!(" {}. {:?}: {}", i + 1, msg.role, msg.content);
230 }
231 println!();
232 continue;
233 }
234
235 session.add_user_message(input);
236
237 print!("Assistant: ");
238 io::stdout().flush()?;
239
240 match client.chat(session.get_messages(), None).await {
241 Ok(response) => {
242 session.add_assistant_message(&response.content);
243 println!("{}\n", response.content);
244 }
245 Err(e) => {
246 println!("\n❌ Error: {}", e);
247 println!(" (Make sure OPENAI_API_KEY is set correctly)\n");
248 // Remove the last user message since it failed.
249 session.messages.pop();
250 }
251 }
252 }
253
254 Ok(())
255}More examples
examples/local_streaming.rs (line 70)
12async fn main() -> helios_engine::Result<()> {
13 println!("🚀 Helios Engine - Local Model Streaming Example");
14 println!("=================================================\n");
15
16 // Configure the local model to use.
17 let local_config = LocalConfig {
18 huggingface_repo: "unsloth/Qwen2.5-0.5B-Instruct-GGUF".to_string(),
19 model_file: "Qwen2.5-0.5B-Instruct-Q4_K_M.gguf".to_string(),
20 context_size: 2048,
21 temperature: 0.7,
22 max_tokens: 512,
23 };
24
25 println!("📥 Loading local model...");
26 println!(" Repository: {}", local_config.huggingface_repo);
27 println!(" Model: {}\n", local_config.model_file);
28
29 // Create a new LLM client with the local model configuration.
30 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Local(local_config)).await?;
31
32 println!("✓ Model loaded successfully!\n");
33
34 // --- Example 1: Simple streaming response ---
35 println!("Example 1: Simple Streaming Response");
36 println!("======================================\n");
37
38 let messages = vec![
39 ChatMessage::system("You are a helpful coding assistant."),
40 ChatMessage::user("Write a short explanation of what Rust is."),
41 ];
42
43 print!("Assistant: ");
44 io::stdout().flush()?;
45
46 // Stream the response from the model, printing each chunk as it arrives.
47 let _response = client
48 .chat_stream(messages, None, |chunk| {
49 print!("{}", chunk);
50 io::stdout().flush().unwrap();
51 })
52 .await?;
53
54 println!("\n");
55
56 // --- Example 2: Interactive streaming ---
57 println!("Example 2: Interactive Streaming");
58 println!("==================================\n");
59
60 let questions = vec![
61 "What are the main benefits of Rust?",
62 "Give me a simple code example.",
63 ];
64
65 let mut session = helios_engine::ChatSession::new()
66 .with_system_prompt("You are a helpful programming assistant.");
67
68 for question in questions {
69 println!("User: {}", question);
70 session.add_user_message(question);
71
72 print!("Assistant: ");
73 io::stdout().flush()?;
74
75 // Stream the response, maintaining the conversation context.
76 let response = client
77 .chat_stream(session.get_messages(), None, |chunk| {
78 print!("{}", chunk);
79 io::stdout().flush().unwrap();
80 })
81 .await?;
82
83 session.add_assistant_message(&response.content);
84 println!("\n");
85 }
86
87 println!("✅ Local model streaming completed successfully!");
88 println!("\n💡 Features:");
89 println!(" • Token-by-token streaming for local models");
90 println!(" • Real-time response display (no more instant full responses)");
91 println!(" • Same streaming API for both local and remote models");
92 println!(" • Improved user experience with progressive output");
93
94 Ok(())
95}examples/streaming_chat.rs (line 67)
14async fn main() -> helios_engine::Result<()> {
15 println!("🚀 Helios Engine - Streaming Example");
16 println!("=====================================\n");
17
18 // Set up the LLM configuration.
19 let llm_config = LLMConfig {
20 model_name: "gpt-3.5-turbo".to_string(),
21 base_url: "https://api.openai.com/v1".to_string(),
22 api_key: std::env::var("OPENAI_API_KEY")
23 .unwrap_or_else(|_| "your-api-key-here".to_string()),
24 temperature: 0.7,
25 max_tokens: 2048,
26 };
27
28 // Create a new LLM client.
29 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
30
31 // --- Example 1: Simple streaming response ---
32 println!("Example 1: Simple Streaming Response");
33 println!("======================================\n");
34
35 let messages = vec![
36 ChatMessage::system("You are a helpful assistant."),
37 ChatMessage::user("Write a short poem about coding."),
38 ];
39
40 print!("Assistant: ");
41 io::stdout().flush()?;
42
43 // Stream the response from the model, printing each chunk as it arrives.
44 let response = client
45 .chat_stream(messages, None, |chunk| {
46 print!("{}", chunk);
47 io::stdout().flush().unwrap();
48 })
49 .await?;
50
51 println!("\n\n");
52
53 // --- Example 2: Interactive streaming chat ---
54 println!("Example 2: Interactive Streaming Chat");
55 println!("======================================\n");
56
57 let mut session = ChatSession::new().with_system_prompt("You are a helpful coding assistant.");
58
59 let questions = vec![
60 "What is Rust?",
61 "What are its main benefits?",
62 "Show me a simple example.",
63 ];
64
65 for question in questions {
66 println!("User: {}", question);
67 session.add_user_message(question);
68
69 print!("Assistant: ");
70 io::stdout().flush()?;
71
72 // Stream the response, maintaining the conversation context.
73 let response = client
74 .chat_stream(session.get_messages(), None, |chunk| {
75 print!("{}", chunk);
76 io::stdout().flush().unwrap();
77 })
78 .await?;
79
80 session.add_assistant_message(&response.content);
81 println!("\n");
82 }
83
84 // --- Example 3: Streaming with thinking tags ---
85 println!("\nExample 3: Streaming with Thinking Tags");
86 println!("=========================================\n");
87 println!("When using models that support thinking tags (like o1),");
88 println!("you can detect and display them during streaming.\n");
89
90 /// A helper struct to track and display thinking tags in streamed responses.
91 struct ThinkingTracker {
92 in_thinking: bool,
93 thinking_buffer: String,
94 }
95
96 impl ThinkingTracker {
97 /// Creates a new `ThinkingTracker`.
98 fn new() -> Self {
99 Self {
100 in_thinking: false,
101 thinking_buffer: String::new(),
102 }
103 }
104
105 /// Processes a chunk of a streamed response and returns the processed output.
106 fn process_chunk(&mut self, chunk: &str) -> String {
107 let mut output = String::new();
108 let mut chars = chunk.chars().peekable();
109
110 while let Some(c) = chars.next() {
111 if c == '<' {
112 let remaining: String = chars.clone().collect();
113 if remaining.starts_with("thinking>") {
114 self.in_thinking = true;
115 self.thinking_buffer.clear();
116 output.push_str("\n💭 [Thinking");
117 for _ in 0..9 {
118 chars.next();
119 }
120 continue;
121 } else if remaining.starts_with("/thinking>") {
122 self.in_thinking = false;
123 output.push_str("]\n");
124 for _ in 0..10 {
125 chars.next();
126 }
127 continue;
128 }
129 }
130
131 if self.in_thinking {
132 self.thinking_buffer.push(c);
133 if self.thinking_buffer.len() % 3 == 0 {
134 output.push('.');
135 }
136 } else {
137 output.push(c);
138 }
139 }
140
141 output
142 }
143 }
144
145 let messages = vec![ChatMessage::user(
146 "Solve this problem: What is 15 * 234 + 89?",
147 )];
148
149 let mut tracker = ThinkingTracker::new();
150 print!("Assistant: ");
151 io::stdout().flush()?;
152
153 // Stream the response, processing thinking tags as they arrive.
154 let _response = client
155 .chat_stream(messages, None, |chunk| {
156 let output = tracker.process_chunk(chunk);
157 print!("{}", output);
158 io::stdout().flush().unwrap();
159 })
160 .await?;
161
162 println!("\n\n✅ Streaming examples completed!");
163 println!("\nKey benefits of streaming:");
164 println!(" • Real-time response display");
165 println!(" • Better user experience for long responses");
166 println!(" • Ability to show thinking/reasoning process");
167 println!(" • Early cancellation possible (future feature)");
168
169 Ok(())
170}Sourcepub fn add_assistant_message(&mut self, content: impl Into<String>)
pub fn add_assistant_message(&mut self, content: impl Into<String>)
Adds an assistant message to the chat session.
Examples found in repository?
examples/direct_llm_usage.rs (line 113)
88async fn conversation_with_context() -> helios_engine::Result<()> {
89 // Create a configuration for the LLM.
90 let llm_config = LLMConfig {
91 model_name: "gpt-3.5-turbo".to_string(),
92 base_url: "https://api.openai.com/v1".to_string(),
93 api_key: std::env::var("OPENAI_API_KEY")
94 .unwrap_or_else(|_| "your-api-key-here".to_string()),
95 temperature: 0.7,
96 max_tokens: 2048,
97 };
98
99 // Create a new LLM client.
100 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
101
102 // Use a `ChatSession` to manage the conversation history.
103 let mut session = ChatSession::new()
104 .with_system_prompt("You are a helpful math tutor. Give brief, clear explanations.");
105
106 // --- First turn ---
107 println!("Turn 1:");
108 session.add_user_message("What is 15 * 23?");
109 print!(" User: What is 15 * 23?\n ");
110
111 match client.chat(session.get_messages(), None).await {
112 Ok(response) => {
113 session.add_assistant_message(&response.content);
114 println!("Assistant: {}", response.content);
115 }
116 Err(e) => {
117 println!("Error: {}", e);
118 return Ok(());
119 }
120 }
121
122 // --- Second turn (with context from the first turn) ---
123 println!("\nTurn 2:");
124 session.add_user_message("Now divide that by 5.");
125 print!(" User: Now divide that by 5.\n ");
126
127 match client.chat(session.get_messages(), None).await {
128 Ok(response) => {
129 session.add_assistant_message(&response.content);
130 println!("Assistant: {}", response.content);
131 }
132 Err(e) => {
133 println!("Error: {}", e);
134 }
135 }
136
137 println!("\n💡 Notice how the assistant remembered the result from the first calculation!");
138
139 Ok(())
140}
141
142/// Provides information about using different LLM providers.
143fn different_providers_info() {
144 println!("You can use Helios with various LLM providers:\n");
145
146 println!("🔵 OpenAI:");
147 println!(" LLMConfig {{");
148 println!(" model_name: \"gpt-4\".to_string(),");
149 println!(" base_url: \"https://api.openai.com/v1\".to_string(),");
150 println!(" api_key: env::var(\"OPENAI_API_KEY\").unwrap(),");
151 println!(" temperature: 0.7,");
152 println!(" max_tokens: 2048,");
153 println!(" }}\n");
154
155 println!("🟢 Local LM Studio:");
156 println!(" LLMConfig {{");
157 println!(" model_name: \"local-model\".to_string(),");
158 println!(" base_url: \"http://localhost:1234/v1\".to_string(),");
159 println!(" api_key: \"not-needed\".to_string(),");
160 println!(" temperature: 0.7,");
161 println!(" max_tokens: 2048,");
162 println!(" }}\n");
163
164 println!("🦙 Ollama:");
165 println!(" LLMConfig {{");
166 println!(" model_name: \"llama2\".to_string(),");
167 println!(" base_url: \"http://localhost:11434/v1\".to_string(),");
168 println!(" api_key: \"not-needed\".to_string(),");
169 println!(" temperature: 0.7,");
170 println!(" max_tokens: 2048,");
171 println!(" }}\n");
172
173 println!("🔷 Azure OpenAI:");
174 println!(" LLMConfig {{");
175 println!(" model_name: \"gpt-35-turbo\".to_string(),");
176 println!(" base_url: \"https://your-resource.openai.azure.com/...\".to_string(),");
177 println!(" api_key: env::var(\"AZURE_OPENAI_KEY\").unwrap(),");
178 println!(" temperature: 0.7,");
179 println!(" max_tokens: 2048,");
180 println!(" }}\n");
181}
182
183/// Starts an interactive chat session with the LLM.
184async fn interactive_chat() -> helios_engine::Result<()> {
185 // Create a configuration for the LLM.
186 let llm_config = LLMConfig {
187 model_name: "gpt-3.5-turbo".to_string(),
188 base_url: "https://api.openai.com/v1".to_string(),
189 api_key: std::env::var("OPENAI_API_KEY")
190 .unwrap_or_else(|_| "your-api-key-here".to_string()),
191 temperature: 0.7,
192 max_tokens: 2048,
193 };
194
195 // Create a new LLM client.
196 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
197 let mut session =
198 ChatSession::new().with_system_prompt("You are a friendly and helpful AI assistant.");
199
200 println!("Chat started! Type 'exit' or 'quit' to end the conversation.\n");
201
202 loop {
203 print!("You: ");
204 io::stdout().flush()?;
205
206 let mut input = String::new();
207 io::stdin().read_line(&mut input)?;
208 let input = input.trim();
209
210 if input.is_empty() {
211 continue;
212 }
213
214 if input == "exit" || input == "quit" {
215 println!("\n👋 Goodbye!");
216 break;
217 }
218
219 // Handle special commands.
220 if input == "clear" {
221 session.clear();
222 println!("🧹 Conversation cleared!\n");
223 continue;
224 }
225
226 if input == "history" {
227 println!("\n📜 Conversation history:");
228 for (i, msg) in session.messages.iter().enumerate() {
229 println!(" {}. {:?}: {}", i + 1, msg.role, msg.content);
230 }
231 println!();
232 continue;
233 }
234
235 session.add_user_message(input);
236
237 print!("Assistant: ");
238 io::stdout().flush()?;
239
240 match client.chat(session.get_messages(), None).await {
241 Ok(response) => {
242 session.add_assistant_message(&response.content);
243 println!("{}\n", response.content);
244 }
245 Err(e) => {
246 println!("\n❌ Error: {}", e);
247 println!(" (Make sure OPENAI_API_KEY is set correctly)\n");
248 // Remove the last user message since it failed.
249 session.messages.pop();
250 }
251 }
252 }
253
254 Ok(())
255}More examples
examples/local_streaming.rs (line 83)
12async fn main() -> helios_engine::Result<()> {
13 println!("🚀 Helios Engine - Local Model Streaming Example");
14 println!("=================================================\n");
15
16 // Configure the local model to use.
17 let local_config = LocalConfig {
18 huggingface_repo: "unsloth/Qwen2.5-0.5B-Instruct-GGUF".to_string(),
19 model_file: "Qwen2.5-0.5B-Instruct-Q4_K_M.gguf".to_string(),
20 context_size: 2048,
21 temperature: 0.7,
22 max_tokens: 512,
23 };
24
25 println!("📥 Loading local model...");
26 println!(" Repository: {}", local_config.huggingface_repo);
27 println!(" Model: {}\n", local_config.model_file);
28
29 // Create a new LLM client with the local model configuration.
30 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Local(local_config)).await?;
31
32 println!("✓ Model loaded successfully!\n");
33
34 // --- Example 1: Simple streaming response ---
35 println!("Example 1: Simple Streaming Response");
36 println!("======================================\n");
37
38 let messages = vec![
39 ChatMessage::system("You are a helpful coding assistant."),
40 ChatMessage::user("Write a short explanation of what Rust is."),
41 ];
42
43 print!("Assistant: ");
44 io::stdout().flush()?;
45
46 // Stream the response from the model, printing each chunk as it arrives.
47 let _response = client
48 .chat_stream(messages, None, |chunk| {
49 print!("{}", chunk);
50 io::stdout().flush().unwrap();
51 })
52 .await?;
53
54 println!("\n");
55
56 // --- Example 2: Interactive streaming ---
57 println!("Example 2: Interactive Streaming");
58 println!("==================================\n");
59
60 let questions = vec![
61 "What are the main benefits of Rust?",
62 "Give me a simple code example.",
63 ];
64
65 let mut session = helios_engine::ChatSession::new()
66 .with_system_prompt("You are a helpful programming assistant.");
67
68 for question in questions {
69 println!("User: {}", question);
70 session.add_user_message(question);
71
72 print!("Assistant: ");
73 io::stdout().flush()?;
74
75 // Stream the response, maintaining the conversation context.
76 let response = client
77 .chat_stream(session.get_messages(), None, |chunk| {
78 print!("{}", chunk);
79 io::stdout().flush().unwrap();
80 })
81 .await?;
82
83 session.add_assistant_message(&response.content);
84 println!("\n");
85 }
86
87 println!("✅ Local model streaming completed successfully!");
88 println!("\n💡 Features:");
89 println!(" • Token-by-token streaming for local models");
90 println!(" • Real-time response display (no more instant full responses)");
91 println!(" • Same streaming API for both local and remote models");
92 println!(" • Improved user experience with progressive output");
93
94 Ok(())
95}examples/streaming_chat.rs (line 80)
14async fn main() -> helios_engine::Result<()> {
15 println!("🚀 Helios Engine - Streaming Example");
16 println!("=====================================\n");
17
18 // Set up the LLM configuration.
19 let llm_config = LLMConfig {
20 model_name: "gpt-3.5-turbo".to_string(),
21 base_url: "https://api.openai.com/v1".to_string(),
22 api_key: std::env::var("OPENAI_API_KEY")
23 .unwrap_or_else(|_| "your-api-key-here".to_string()),
24 temperature: 0.7,
25 max_tokens: 2048,
26 };
27
28 // Create a new LLM client.
29 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
30
31 // --- Example 1: Simple streaming response ---
32 println!("Example 1: Simple Streaming Response");
33 println!("======================================\n");
34
35 let messages = vec![
36 ChatMessage::system("You are a helpful assistant."),
37 ChatMessage::user("Write a short poem about coding."),
38 ];
39
40 print!("Assistant: ");
41 io::stdout().flush()?;
42
43 // Stream the response from the model, printing each chunk as it arrives.
44 let response = client
45 .chat_stream(messages, None, |chunk| {
46 print!("{}", chunk);
47 io::stdout().flush().unwrap();
48 })
49 .await?;
50
51 println!("\n\n");
52
53 // --- Example 2: Interactive streaming chat ---
54 println!("Example 2: Interactive Streaming Chat");
55 println!("======================================\n");
56
57 let mut session = ChatSession::new().with_system_prompt("You are a helpful coding assistant.");
58
59 let questions = vec![
60 "What is Rust?",
61 "What are its main benefits?",
62 "Show me a simple example.",
63 ];
64
65 for question in questions {
66 println!("User: {}", question);
67 session.add_user_message(question);
68
69 print!("Assistant: ");
70 io::stdout().flush()?;
71
72 // Stream the response, maintaining the conversation context.
73 let response = client
74 .chat_stream(session.get_messages(), None, |chunk| {
75 print!("{}", chunk);
76 io::stdout().flush().unwrap();
77 })
78 .await?;
79
80 session.add_assistant_message(&response.content);
81 println!("\n");
82 }
83
84 // --- Example 3: Streaming with thinking tags ---
85 println!("\nExample 3: Streaming with Thinking Tags");
86 println!("=========================================\n");
87 println!("When using models that support thinking tags (like o1),");
88 println!("you can detect and display them during streaming.\n");
89
90 /// A helper struct to track and display thinking tags in streamed responses.
91 struct ThinkingTracker {
92 in_thinking: bool,
93 thinking_buffer: String,
94 }
95
96 impl ThinkingTracker {
97 /// Creates a new `ThinkingTracker`.
98 fn new() -> Self {
99 Self {
100 in_thinking: false,
101 thinking_buffer: String::new(),
102 }
103 }
104
105 /// Processes a chunk of a streamed response and returns the processed output.
106 fn process_chunk(&mut self, chunk: &str) -> String {
107 let mut output = String::new();
108 let mut chars = chunk.chars().peekable();
109
110 while let Some(c) = chars.next() {
111 if c == '<' {
112 let remaining: String = chars.clone().collect();
113 if remaining.starts_with("thinking>") {
114 self.in_thinking = true;
115 self.thinking_buffer.clear();
116 output.push_str("\n💭 [Thinking");
117 for _ in 0..9 {
118 chars.next();
119 }
120 continue;
121 } else if remaining.starts_with("/thinking>") {
122 self.in_thinking = false;
123 output.push_str("]\n");
124 for _ in 0..10 {
125 chars.next();
126 }
127 continue;
128 }
129 }
130
131 if self.in_thinking {
132 self.thinking_buffer.push(c);
133 if self.thinking_buffer.len() % 3 == 0 {
134 output.push('.');
135 }
136 } else {
137 output.push(c);
138 }
139 }
140
141 output
142 }
143 }
144
145 let messages = vec![ChatMessage::user(
146 "Solve this problem: What is 15 * 234 + 89?",
147 )];
148
149 let mut tracker = ThinkingTracker::new();
150 print!("Assistant: ");
151 io::stdout().flush()?;
152
153 // Stream the response, processing thinking tags as they arrive.
154 let _response = client
155 .chat_stream(messages, None, |chunk| {
156 let output = tracker.process_chunk(chunk);
157 print!("{}", output);
158 io::stdout().flush().unwrap();
159 })
160 .await?;
161
162 println!("\n\n✅ Streaming examples completed!");
163 println!("\nKey benefits of streaming:");
164 println!(" • Real-time response display");
165 println!(" • Better user experience for long responses");
166 println!(" • Ability to show thinking/reasoning process");
167 println!(" • Early cancellation possible (future feature)");
168
169 Ok(())
170}Sourcepub fn get_messages(&self) -> Vec<ChatMessage>
pub fn get_messages(&self) -> Vec<ChatMessage>
Returns all messages in the chat session, including the system prompt.
Examples found in repository?
examples/direct_llm_usage.rs (line 111)
88async fn conversation_with_context() -> helios_engine::Result<()> {
89 // Create a configuration for the LLM.
90 let llm_config = LLMConfig {
91 model_name: "gpt-3.5-turbo".to_string(),
92 base_url: "https://api.openai.com/v1".to_string(),
93 api_key: std::env::var("OPENAI_API_KEY")
94 .unwrap_or_else(|_| "your-api-key-here".to_string()),
95 temperature: 0.7,
96 max_tokens: 2048,
97 };
98
99 // Create a new LLM client.
100 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
101
102 // Use a `ChatSession` to manage the conversation history.
103 let mut session = ChatSession::new()
104 .with_system_prompt("You are a helpful math tutor. Give brief, clear explanations.");
105
106 // --- First turn ---
107 println!("Turn 1:");
108 session.add_user_message("What is 15 * 23?");
109 print!(" User: What is 15 * 23?\n ");
110
111 match client.chat(session.get_messages(), None).await {
112 Ok(response) => {
113 session.add_assistant_message(&response.content);
114 println!("Assistant: {}", response.content);
115 }
116 Err(e) => {
117 println!("Error: {}", e);
118 return Ok(());
119 }
120 }
121
122 // --- Second turn (with context from the first turn) ---
123 println!("\nTurn 2:");
124 session.add_user_message("Now divide that by 5.");
125 print!(" User: Now divide that by 5.\n ");
126
127 match client.chat(session.get_messages(), None).await {
128 Ok(response) => {
129 session.add_assistant_message(&response.content);
130 println!("Assistant: {}", response.content);
131 }
132 Err(e) => {
133 println!("Error: {}", e);
134 }
135 }
136
137 println!("\n💡 Notice how the assistant remembered the result from the first calculation!");
138
139 Ok(())
140}
141
142/// Provides information about using different LLM providers.
143fn different_providers_info() {
144 println!("You can use Helios with various LLM providers:\n");
145
146 println!("🔵 OpenAI:");
147 println!(" LLMConfig {{");
148 println!(" model_name: \"gpt-4\".to_string(),");
149 println!(" base_url: \"https://api.openai.com/v1\".to_string(),");
150 println!(" api_key: env::var(\"OPENAI_API_KEY\").unwrap(),");
151 println!(" temperature: 0.7,");
152 println!(" max_tokens: 2048,");
153 println!(" }}\n");
154
155 println!("🟢 Local LM Studio:");
156 println!(" LLMConfig {{");
157 println!(" model_name: \"local-model\".to_string(),");
158 println!(" base_url: \"http://localhost:1234/v1\".to_string(),");
159 println!(" api_key: \"not-needed\".to_string(),");
160 println!(" temperature: 0.7,");
161 println!(" max_tokens: 2048,");
162 println!(" }}\n");
163
164 println!("🦙 Ollama:");
165 println!(" LLMConfig {{");
166 println!(" model_name: \"llama2\".to_string(),");
167 println!(" base_url: \"http://localhost:11434/v1\".to_string(),");
168 println!(" api_key: \"not-needed\".to_string(),");
169 println!(" temperature: 0.7,");
170 println!(" max_tokens: 2048,");
171 println!(" }}\n");
172
173 println!("🔷 Azure OpenAI:");
174 println!(" LLMConfig {{");
175 println!(" model_name: \"gpt-35-turbo\".to_string(),");
176 println!(" base_url: \"https://your-resource.openai.azure.com/...\".to_string(),");
177 println!(" api_key: env::var(\"AZURE_OPENAI_KEY\").unwrap(),");
178 println!(" temperature: 0.7,");
179 println!(" max_tokens: 2048,");
180 println!(" }}\n");
181}
182
183/// Starts an interactive chat session with the LLM.
184async fn interactive_chat() -> helios_engine::Result<()> {
185 // Create a configuration for the LLM.
186 let llm_config = LLMConfig {
187 model_name: "gpt-3.5-turbo".to_string(),
188 base_url: "https://api.openai.com/v1".to_string(),
189 api_key: std::env::var("OPENAI_API_KEY")
190 .unwrap_or_else(|_| "your-api-key-here".to_string()),
191 temperature: 0.7,
192 max_tokens: 2048,
193 };
194
195 // Create a new LLM client.
196 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
197 let mut session =
198 ChatSession::new().with_system_prompt("You are a friendly and helpful AI assistant.");
199
200 println!("Chat started! Type 'exit' or 'quit' to end the conversation.\n");
201
202 loop {
203 print!("You: ");
204 io::stdout().flush()?;
205
206 let mut input = String::new();
207 io::stdin().read_line(&mut input)?;
208 let input = input.trim();
209
210 if input.is_empty() {
211 continue;
212 }
213
214 if input == "exit" || input == "quit" {
215 println!("\n👋 Goodbye!");
216 break;
217 }
218
219 // Handle special commands.
220 if input == "clear" {
221 session.clear();
222 println!("🧹 Conversation cleared!\n");
223 continue;
224 }
225
226 if input == "history" {
227 println!("\n📜 Conversation history:");
228 for (i, msg) in session.messages.iter().enumerate() {
229 println!(" {}. {:?}: {}", i + 1, msg.role, msg.content);
230 }
231 println!();
232 continue;
233 }
234
235 session.add_user_message(input);
236
237 print!("Assistant: ");
238 io::stdout().flush()?;
239
240 match client.chat(session.get_messages(), None).await {
241 Ok(response) => {
242 session.add_assistant_message(&response.content);
243 println!("{}\n", response.content);
244 }
245 Err(e) => {
246 println!("\n❌ Error: {}", e);
247 println!(" (Make sure OPENAI_API_KEY is set correctly)\n");
248 // Remove the last user message since it failed.
249 session.messages.pop();
250 }
251 }
252 }
253
254 Ok(())
255}More examples
examples/local_streaming.rs (line 77)
12async fn main() -> helios_engine::Result<()> {
13 println!("🚀 Helios Engine - Local Model Streaming Example");
14 println!("=================================================\n");
15
16 // Configure the local model to use.
17 let local_config = LocalConfig {
18 huggingface_repo: "unsloth/Qwen2.5-0.5B-Instruct-GGUF".to_string(),
19 model_file: "Qwen2.5-0.5B-Instruct-Q4_K_M.gguf".to_string(),
20 context_size: 2048,
21 temperature: 0.7,
22 max_tokens: 512,
23 };
24
25 println!("📥 Loading local model...");
26 println!(" Repository: {}", local_config.huggingface_repo);
27 println!(" Model: {}\n", local_config.model_file);
28
29 // Create a new LLM client with the local model configuration.
30 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Local(local_config)).await?;
31
32 println!("✓ Model loaded successfully!\n");
33
34 // --- Example 1: Simple streaming response ---
35 println!("Example 1: Simple Streaming Response");
36 println!("======================================\n");
37
38 let messages = vec![
39 ChatMessage::system("You are a helpful coding assistant."),
40 ChatMessage::user("Write a short explanation of what Rust is."),
41 ];
42
43 print!("Assistant: ");
44 io::stdout().flush()?;
45
46 // Stream the response from the model, printing each chunk as it arrives.
47 let _response = client
48 .chat_stream(messages, None, |chunk| {
49 print!("{}", chunk);
50 io::stdout().flush().unwrap();
51 })
52 .await?;
53
54 println!("\n");
55
56 // --- Example 2: Interactive streaming ---
57 println!("Example 2: Interactive Streaming");
58 println!("==================================\n");
59
60 let questions = vec![
61 "What are the main benefits of Rust?",
62 "Give me a simple code example.",
63 ];
64
65 let mut session = helios_engine::ChatSession::new()
66 .with_system_prompt("You are a helpful programming assistant.");
67
68 for question in questions {
69 println!("User: {}", question);
70 session.add_user_message(question);
71
72 print!("Assistant: ");
73 io::stdout().flush()?;
74
75 // Stream the response, maintaining the conversation context.
76 let response = client
77 .chat_stream(session.get_messages(), None, |chunk| {
78 print!("{}", chunk);
79 io::stdout().flush().unwrap();
80 })
81 .await?;
82
83 session.add_assistant_message(&response.content);
84 println!("\n");
85 }
86
87 println!("✅ Local model streaming completed successfully!");
88 println!("\n💡 Features:");
89 println!(" • Token-by-token streaming for local models");
90 println!(" • Real-time response display (no more instant full responses)");
91 println!(" • Same streaming API for both local and remote models");
92 println!(" • Improved user experience with progressive output");
93
94 Ok(())
95}examples/streaming_chat.rs (line 74)
14async fn main() -> helios_engine::Result<()> {
15 println!("🚀 Helios Engine - Streaming Example");
16 println!("=====================================\n");
17
18 // Set up the LLM configuration.
19 let llm_config = LLMConfig {
20 model_name: "gpt-3.5-turbo".to_string(),
21 base_url: "https://api.openai.com/v1".to_string(),
22 api_key: std::env::var("OPENAI_API_KEY")
23 .unwrap_or_else(|_| "your-api-key-here".to_string()),
24 temperature: 0.7,
25 max_tokens: 2048,
26 };
27
28 // Create a new LLM client.
29 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
30
31 // --- Example 1: Simple streaming response ---
32 println!("Example 1: Simple Streaming Response");
33 println!("======================================\n");
34
35 let messages = vec![
36 ChatMessage::system("You are a helpful assistant."),
37 ChatMessage::user("Write a short poem about coding."),
38 ];
39
40 print!("Assistant: ");
41 io::stdout().flush()?;
42
43 // Stream the response from the model, printing each chunk as it arrives.
44 let response = client
45 .chat_stream(messages, None, |chunk| {
46 print!("{}", chunk);
47 io::stdout().flush().unwrap();
48 })
49 .await?;
50
51 println!("\n\n");
52
53 // --- Example 2: Interactive streaming chat ---
54 println!("Example 2: Interactive Streaming Chat");
55 println!("======================================\n");
56
57 let mut session = ChatSession::new().with_system_prompt("You are a helpful coding assistant.");
58
59 let questions = vec![
60 "What is Rust?",
61 "What are its main benefits?",
62 "Show me a simple example.",
63 ];
64
65 for question in questions {
66 println!("User: {}", question);
67 session.add_user_message(question);
68
69 print!("Assistant: ");
70 io::stdout().flush()?;
71
72 // Stream the response, maintaining the conversation context.
73 let response = client
74 .chat_stream(session.get_messages(), None, |chunk| {
75 print!("{}", chunk);
76 io::stdout().flush().unwrap();
77 })
78 .await?;
79
80 session.add_assistant_message(&response.content);
81 println!("\n");
82 }
83
84 // --- Example 3: Streaming with thinking tags ---
85 println!("\nExample 3: Streaming with Thinking Tags");
86 println!("=========================================\n");
87 println!("When using models that support thinking tags (like o1),");
88 println!("you can detect and display them during streaming.\n");
89
90 /// A helper struct to track and display thinking tags in streamed responses.
91 struct ThinkingTracker {
92 in_thinking: bool,
93 thinking_buffer: String,
94 }
95
96 impl ThinkingTracker {
97 /// Creates a new `ThinkingTracker`.
98 fn new() -> Self {
99 Self {
100 in_thinking: false,
101 thinking_buffer: String::new(),
102 }
103 }
104
105 /// Processes a chunk of a streamed response and returns the processed output.
106 fn process_chunk(&mut self, chunk: &str) -> String {
107 let mut output = String::new();
108 let mut chars = chunk.chars().peekable();
109
110 while let Some(c) = chars.next() {
111 if c == '<' {
112 let remaining: String = chars.clone().collect();
113 if remaining.starts_with("thinking>") {
114 self.in_thinking = true;
115 self.thinking_buffer.clear();
116 output.push_str("\n💭 [Thinking");
117 for _ in 0..9 {
118 chars.next();
119 }
120 continue;
121 } else if remaining.starts_with("/thinking>") {
122 self.in_thinking = false;
123 output.push_str("]\n");
124 for _ in 0..10 {
125 chars.next();
126 }
127 continue;
128 }
129 }
130
131 if self.in_thinking {
132 self.thinking_buffer.push(c);
133 if self.thinking_buffer.len() % 3 == 0 {
134 output.push('.');
135 }
136 } else {
137 output.push(c);
138 }
139 }
140
141 output
142 }
143 }
144
145 let messages = vec![ChatMessage::user(
146 "Solve this problem: What is 15 * 234 + 89?",
147 )];
148
149 let mut tracker = ThinkingTracker::new();
150 print!("Assistant: ");
151 io::stdout().flush()?;
152
153 // Stream the response, processing thinking tags as they arrive.
154 let _response = client
155 .chat_stream(messages, None, |chunk| {
156 let output = tracker.process_chunk(chunk);
157 print!("{}", output);
158 io::stdout().flush().unwrap();
159 })
160 .await?;
161
162 println!("\n\n✅ Streaming examples completed!");
163 println!("\nKey benefits of streaming:");
164 println!(" • Real-time response display");
165 println!(" • Better user experience for long responses");
166 println!(" • Ability to show thinking/reasoning process");
167 println!(" • Early cancellation possible (future feature)");
168
169 Ok(())
170}Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clears all messages from the chat session.
Examples found in repository?
examples/direct_llm_usage.rs (line 221)
184async fn interactive_chat() -> helios_engine::Result<()> {
185 // Create a configuration for the LLM.
186 let llm_config = LLMConfig {
187 model_name: "gpt-3.5-turbo".to_string(),
188 base_url: "https://api.openai.com/v1".to_string(),
189 api_key: std::env::var("OPENAI_API_KEY")
190 .unwrap_or_else(|_| "your-api-key-here".to_string()),
191 temperature: 0.7,
192 max_tokens: 2048,
193 };
194
195 // Create a new LLM client.
196 let client = LLMClient::new(helios_engine::llm::LLMProviderType::Remote(llm_config)).await?;
197 let mut session =
198 ChatSession::new().with_system_prompt("You are a friendly and helpful AI assistant.");
199
200 println!("Chat started! Type 'exit' or 'quit' to end the conversation.\n");
201
202 loop {
203 print!("You: ");
204 io::stdout().flush()?;
205
206 let mut input = String::new();
207 io::stdin().read_line(&mut input)?;
208 let input = input.trim();
209
210 if input.is_empty() {
211 continue;
212 }
213
214 if input == "exit" || input == "quit" {
215 println!("\n👋 Goodbye!");
216 break;
217 }
218
219 // Handle special commands.
220 if input == "clear" {
221 session.clear();
222 println!("🧹 Conversation cleared!\n");
223 continue;
224 }
225
226 if input == "history" {
227 println!("\n📜 Conversation history:");
228 for (i, msg) in session.messages.iter().enumerate() {
229 println!(" {}. {:?}: {}", i + 1, msg.role, msg.content);
230 }
231 println!();
232 continue;
233 }
234
235 session.add_user_message(input);
236
237 print!("Assistant: ");
238 io::stdout().flush()?;
239
240 match client.chat(session.get_messages(), None).await {
241 Ok(response) => {
242 session.add_assistant_message(&response.content);
243 println!("{}\n", response.content);
244 }
245 Err(e) => {
246 println!("\n❌ Error: {}", e);
247 println!(" (Make sure OPENAI_API_KEY is set correctly)\n");
248 // Remove the last user message since it failed.
249 session.messages.pop();
250 }
251 }
252 }
253
254 Ok(())
255}Sourcepub fn set_metadata(&mut self, key: impl Into<String>, value: impl Into<String>)
pub fn set_metadata(&mut self, key: impl Into<String>, value: impl Into<String>)
Sets a metadata key-value pair for the session.
Sourcepub fn get_metadata(&self, key: &str) -> Option<&String>
pub fn get_metadata(&self, key: &str) -> Option<&String>
Gets a metadata value by key.
Sourcepub fn remove_metadata(&mut self, key: &str) -> Option<String>
pub fn remove_metadata(&mut self, key: &str) -> Option<String>
Removes a metadata key-value pair.
Sourcepub fn get_summary(&self) -> String
pub fn get_summary(&self) -> String
Returns a summary of the chat session.
Trait Implementations§
Source§impl Clone for ChatSession
impl Clone for ChatSession
Source§fn clone(&self) -> ChatSession
fn clone(&self) -> ChatSession
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for ChatSession
impl Debug for ChatSession
Auto Trait Implementations§
impl Freeze for ChatSession
impl RefUnwindSafe for ChatSession
impl Send for ChatSession
impl Sync for ChatSession
impl Unpin for ChatSession
impl UnwindSafe for ChatSession
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more