pub struct CodeAgent { /* private fields */ }Expand description
CodeAgent: A specialized agent for code analysis and development tasks This agent is built on top of the TemplateAgent and provides code-specific functionality
Implementations§
Source§impl CodeAgent
impl CodeAgent
Sourcepub async fn new(_config: Config) -> Result<Self, KowalskiError>
pub async fn new(_config: Config) -> Result<Self, KowalskiError>
Creates a new CodeAgent with the specified configuration
Examples found in repository?
examples/java_analysis.rs (line 17)
11async fn main() -> Result<(), Box<dyn std::error::Error>> {
12 // Initialize logging
13 env_logger::init();
14
15 // Load configuration
16 let config = Config::default();
17 let mut code_agent = CodeAgent::new(config).await?;
18
19 // Start a conversation
20 println!("☕ Starting Java Code Analysis...");
21 let conversation_id = code_agent.start_conversation("llama3.2");
22 println!("Code Agent Conversation ID: {}", conversation_id);
23
24 // Set up the role for code analysis
25 let role = Role::new(
26 "Java Code Analysis Assistant",
27 "You are an expert at analyzing Java code, providing insights on code quality, best practices, and potential improvements.",
28 )
29 .with_audience(Audience::new(
30 "Java Developer",
31 "You are speaking to a Java developer who needs detailed code analysis.",
32 ))
33 .with_preset(Preset::new(
34 "Analysis",
35 "Provide comprehensive analysis with specific recommendations for improvement.",
36 ));
37
38 // Sample Java code for analysis
39 let java_code = r#"
40import java.util.*;
41
42public class Calculator {
43 private int result;
44
45 public Calculator() {
46 this.result = 0;
47 }
48
49 public int add(int a, int b) {
50 result = a + b;
51 return result;
52 }
53
54 public int subtract(int a, int b) {
55 result = a - b;
56 return result;
57 }
58
59 public int multiply(int a, int b) {
60 result = a * b;
61 return result;
62 }
63
64 public double divide(int a, int b) {
65 if (b == 0) {
66 System.out.println("Error: Division by zero");
67 return 0;
68 }
69 result = a / b;
70 return (double) result;
71 }
72
73 public static void main(String[] args) {
74 Calculator calc = new Calculator();
75 System.out.println("Addition: " + calc.add(10, 5));
76 System.out.println("Subtraction: " + calc.subtract(10, 5));
77 System.out.println("Multiplication: " + calc.multiply(10, 5));
78 System.out.println("Division: " + calc.divide(10, 5));
79 }
80}
81"#;
82
83 println!("\n📝 Java Code to Analyze:");
84 println!("{}", java_code);
85
86 // Analyze the Java code
87 let analysis_result = code_agent.analyze_java(java_code).await?;
88
89 println!("\n📊 Java Analysis Results:");
90 println!("Language: {}", analysis_result.language);
91 println!(
92 "Metrics: {}",
93 serde_json::to_string_pretty(&analysis_result.metrics)?
94 );
95 println!("Suggestions: {:?}", analysis_result.suggestions);
96 println!("Issues: {:?}", analysis_result.issues);
97
98 // Ask the agent to analyze the code
99 let analysis_prompt = format!(
100 "Please analyze this Java code and provide insights:\n\n{}\n\nAnalysis results:\nMetrics: {}\nSuggestions: {:?}\nIssues: {:?}",
101 java_code,
102 serde_json::to_string_pretty(&analysis_result.metrics)?,
103 analysis_result.suggestions,
104 analysis_result.issues
105 );
106
107 let mut response = code_agent
108 .chat_with_history(&conversation_id, &analysis_prompt, Some(role))
109 .await?;
110
111 println!("\n🤖 AI Analysis:");
112
113 // Process the streaming response
114 let mut buffer = String::new();
115 while let Some(chunk) = response.chunk().await? {
116 match code_agent
117 .process_stream_response(&conversation_id, &chunk)
118 .await
119 {
120 Ok(Some(message)) => {
121 // Print the content if it exists
122 if !message.content.is_empty() {
123 print!("{}", message.content);
124 io::stdout().flush()?;
125 buffer.push_str(&message.content);
126 }
127
128 // Handle tool calls if they exist
129 if let Some(tool_calls) = &message.tool_calls {
130 for tool_call in tool_calls {
131 print!("\n[Tool Call] {}(", tool_call.function.name);
132 if let Some(obj) = tool_call.function.arguments.as_object() {
133 for (key, value) in obj {
134 print!("{}: {}, ", key, value);
135 }
136 }
137 println!(")");
138 io::stdout().flush()?;
139 }
140 }
141 }
142 Ok(None) => {
143 code_agent
144 .add_message(&conversation_id, "assistant", &buffer)
145 .await;
146 println!("\n✅ Analysis complete!\n");
147 break;
148 }
149 Err(e) => {
150 eprintln!("\n❌ Error processing stream: {}", e);
151 break;
152 }
153 }
154 }
155
156 // Ask a follow-up question about specific improvements
157 let follow_up = "What specific improvements would you recommend for this Java code?";
158 let mut follow_up_response = code_agent
159 .chat_with_history(&conversation_id, follow_up, None)
160 .await?;
161
162 println!("\n🔍 Follow-up Analysis:");
163 let mut buffer = String::new();
164 while let Some(chunk) = follow_up_response.chunk().await? {
165 match code_agent
166 .process_stream_response(&conversation_id, &chunk)
167 .await
168 {
169 Ok(Some(message)) => {
170 // Print the content if it exists
171 if !message.content.is_empty() {
172 print!("{}", message.content);
173 io::stdout().flush()?;
174 buffer.push_str(&message.content);
175 }
176
177 // Handle tool calls if they exist
178 if let Some(tool_calls) = &message.tool_calls {
179 for tool_call in tool_calls {
180 print!("\n[Tool Call] {}(", tool_call.function.name);
181 if let Some(obj) = tool_call.function.arguments.as_object() {
182 for (key, value) in obj {
183 print!("{}: {}, ", key, value);
184 }
185 }
186 println!(")");
187 io::stdout().flush()?;
188 }
189 }
190 }
191 Ok(None) => {
192 code_agent
193 .add_message(&conversation_id, "assistant", &buffer)
194 .await;
195 println!("\n");
196 break;
197 }
198 Err(e) => {
199 eprintln!("\n❌ Error processing stream: {}", e);
200 break;
201 }
202 }
203 }
204
205 Ok(())
206}More examples
examples/python_analysis.rs (line 17)
11async fn main() -> Result<(), Box<dyn std::error::Error>> {
12 // Initialize logging
13 env_logger::init();
14
15 // Load configuration
16 let config = Config::default();
17 let mut code_agent = CodeAgent::new(config).await?;
18
19 // Start a conversation
20 println!("🐍 Starting Python Code Analysis...");
21 let conversation_id = code_agent.start_conversation("llama3.2");
22 println!("Code Agent Conversation ID: {}", conversation_id);
23
24 // Set up the role for code analysis
25 let role = Role::new(
26 "Python Code Analysis Assistant",
27 "You are an expert at analyzing Python code, providing insights on code quality, PEP 8 compliance, and potential improvements.",
28 )
29 .with_audience(Audience::new(
30 "Python Developer",
31 "You are speaking to a Python developer who needs detailed code analysis.",
32 ))
33 .with_preset(Preset::new(
34 "Analysis",
35 "Provide comprehensive analysis with specific recommendations for improvement.",
36 ));
37
38 // Sample Python code for analysis
39 let python_code = r#"
40import os
41import sys
42from typing import List, Optional
43
44class DataProcessor:
45 def __init__(self, data: List[int]):
46 self.data = data
47 self.result = 0
48
49 def calculate_sum(self) -> int:
50 """Calculate the sum of all data points."""
51 total = 0
52 for item in self.data:
53 total += item
54 return total
55
56 def calculate_average(self) -> float:
57 """Calculate the average of all data points."""
58 if len(self.data) == 0:
59 print("Error: No data to calculate average")
60 return 0.0
61 return self.calculate_sum() / len(self.data)
62
63 def find_max(self) -> Optional[int]:
64 """Find the maximum value in the data."""
65 if not self.data:
66 return None
67 max_val = self.data[0]
68 for item in self.data:
69 if item > max_val:
70 max_val = item
71 return max_val
72
73def main():
74 # Sample data
75 numbers = [10, 20, 30, 40, 50]
76
77 # Create processor
78 processor = DataProcessor(numbers)
79
80 # Calculate statistics
81 print(f"Sum: {processor.calculate_sum()}")
82 print(f"Average: {processor.calculate_average()}")
83 print(f"Maximum: {processor.find_max()}")
84
85 # Process empty data
86 empty_processor = DataProcessor([])
87 print(f"Empty average: {empty_processor.calculate_average()}")
88
89if __name__ == "__main__":
90 main()
91"#;
92
93 println!("\n📝 Python Code to Analyze:");
94 println!("{}", python_code);
95
96 // Analyze the Python code
97 let analysis_result = code_agent.analyze_python(python_code).await?;
98
99 println!("\n📊 Python Analysis Results:");
100 println!("Language: {}", analysis_result.language);
101 println!(
102 "Metrics: {}",
103 serde_json::to_string_pretty(&analysis_result.metrics)?
104 );
105 println!("Suggestions: {:?}", analysis_result.suggestions);
106 println!("PEP 8 Issues: {:?}", analysis_result.issues);
107
108 // Ask the agent to analyze the code
109 let analysis_prompt = format!(
110 "Please analyze this Python code and provide insights:\n\n{}\n\nAnalysis results:\nMetrics: {}\nSuggestions: {:?}\nPEP 8 Issues: {:?}",
111 python_code,
112 serde_json::to_string_pretty(&analysis_result.metrics)?,
113 analysis_result.suggestions,
114 analysis_result.issues
115 );
116
117 let mut response = code_agent
118 .chat_with_history(&conversation_id, &analysis_prompt, Some(role))
119 .await?;
120
121 println!("\n🤖 AI Analysis:");
122
123 // Process the streaming response
124 let mut buffer = String::new();
125 while let Some(chunk) = response.chunk().await? {
126 match code_agent
127 .process_stream_response(&conversation_id, &chunk)
128 .await
129 {
130 Ok(Some(message)) => {
131 // Print the content if it exists
132 if !message.content.is_empty() {
133 print!("{}", message.content);
134 io::stdout().flush()?;
135 buffer.push_str(&message.content);
136 }
137
138 // Handle tool calls if they exist
139 if let Some(tool_calls) = &message.tool_calls {
140 for tool_call in tool_calls {
141 print!("\n[Tool Call] {}(", tool_call.function.name);
142 if let Some(obj) = tool_call.function.arguments.as_object() {
143 for (key, value) in obj {
144 print!("{}: {}, ", key, value);
145 }
146 }
147 println!(")");
148 io::stdout().flush()?;
149 }
150 }
151 }
152 Ok(None) => {
153 code_agent
154 .add_message(&conversation_id, "assistant", &buffer)
155 .await;
156 println!("\n✅ Analysis complete!\n");
157 break;
158 }
159 Err(e) => {
160 eprintln!("\n❌ Error processing stream: {}", e);
161 break;
162 }
163 }
164 }
165
166 // Ask a follow-up question about PEP 8 compliance
167 let follow_up = "How can this Python code be improved to better follow PEP 8 guidelines?";
168 let mut follow_up_response = code_agent
169 .chat_with_history(&conversation_id, follow_up, None)
170 .await?;
171
172 println!("\n🔍 Follow-up Analysis:");
173 let mut buffer = String::new();
174 while let Some(chunk) = follow_up_response.chunk().await? {
175 match code_agent
176 .process_stream_response(&conversation_id, &chunk)
177 .await
178 {
179 Ok(Some(message)) => {
180 // Print the content if it exists
181 if !message.content.is_empty() {
182 print!("{}", message.content);
183 io::stdout().flush()?;
184 buffer.push_str(&message.content);
185 }
186
187 // Handle tool calls if they exist
188 if let Some(tool_calls) = &message.tool_calls {
189 for tool_call in tool_calls {
190 print!("\n[Tool Call] {}(", tool_call.function.name);
191 if let Some(obj) = tool_call.function.arguments.as_object() {
192 for (key, value) in obj {
193 print!("{}: {}, ", key, value);
194 }
195 }
196 println!(")");
197 io::stdout().flush()?;
198 }
199 }
200 }
201 Ok(None) => {
202 code_agent
203 .add_message(&conversation_id, "assistant", &buffer)
204 .await;
205 println!("\n");
206 break;
207 }
208 Err(e) => {
209 eprintln!("\n❌ Error processing stream: {}", e);
210 break;
211 }
212 }
213 }
214
215 Ok(())
216}examples/rust_analysis.rs (line 17)
11async fn main() -> Result<(), Box<dyn std::error::Error>> {
12 // Initialize logging
13 env_logger::init();
14
15 // Load configuration
16 let config = Config::default();
17 let mut code_agent = CodeAgent::new(config).await?;
18
19 // Start a conversation
20 println!("🦀 Starting Rust Code Analysis...");
21 let conversation_id = code_agent.start_conversation("llama3.2");
22 println!("Code Agent Conversation ID: {}", conversation_id);
23
24 // Set up the role for code analysis
25 let role = Role::new(
26 "Rust Code Analysis Assistant",
27 "You are an expert at analyzing Rust code, providing insights on code quality, safety, and potential improvements.",
28 )
29 .with_audience(Audience::new(
30 "Rust Developer",
31 "You are speaking to a Rust developer who needs detailed code analysis.",
32 ))
33 .with_preset(Preset::new(
34 "Analysis",
35 "Provide comprehensive analysis with specific recommendations for improvement.",
36 ));
37
38 // Sample Rust code for analysis
39 let rust_code = r#"
40use std::collections::HashMap;
41use std::error::Error;
42
43#[derive(Debug)]
44struct DataProcessor {
45 data: Vec<i32>,
46 cache: HashMap<String, i32>,
47}
48
49impl DataProcessor {
50 fn new(data: Vec<i32>) -> Self {
51 Self {
52 data,
53 cache: HashMap::new(),
54 }
55 }
56
57 fn calculate_sum(&self) -> i32 {
58 self.data.iter().sum()
59 }
60
61 fn calculate_average(&self) -> Option<f64> {
62 if self.data.is_empty() {
63 None
64 } else {
65 Some(self.calculate_sum() as f64 / self.data.len() as f64)
66 }
67 }
68
69 fn find_max(&self) -> Option<&i32> {
70 self.data.iter().max()
71 }
72
73 fn process_with_cache(&mut self, key: String) -> Result<i32, Box<dyn Error>> {
74 if let Some(&cached_value) = self.cache.get(&key) {
75 return Ok(cached_value);
76 }
77
78 let result = self.calculate_sum();
79 self.cache.insert(key, result);
80 Ok(result)
81 }
82}
83
84fn main() {
85 let numbers = vec![10, 20, 30, 40, 50];
86 let mut processor = DataProcessor::new(numbers);
87
88 println!("Sum: {}", processor.calculate_sum());
89
90 match processor.calculate_average() {
91 Some(avg) => println!("Average: {}", avg),
92 None => println!("No data to calculate average"),
93 }
94
95 match processor.find_max() {
96 Some(max) => println!("Maximum: {}", max),
97 None => println!("No data to find maximum"),
98 }
99
100 match processor.process_with_cache("sum".to_string()) {
101 Ok(result) => println!("Cached result: {}", result),
102 Err(e) => println!("Error: {}", e),
103 }
104}
105"#;
106
107 println!("\n📝 Rust Code to Analyze:");
108 println!("{}", rust_code);
109
110 // Analyze the Rust code
111 let analysis_result = code_agent.analyze_rust(rust_code).await?;
112
113 println!("\n📊 Rust Analysis Results:");
114 println!("Language: {}", analysis_result.language);
115 println!(
116 "Metrics: {}",
117 serde_json::to_string_pretty(&analysis_result.metrics)?
118 );
119 println!("Suggestions: {:?}", analysis_result.suggestions);
120 println!("Rust Issues: {:?}", analysis_result.issues);
121
122 // Ask the agent to analyze the code
123 let analysis_prompt = format!(
124 "Please analyze this Rust code and provide insights:\n\n{}\n\nAnalysis results:\nMetrics: {}\nSuggestions: {:?}\nRust Issues: {:?}",
125 rust_code,
126 serde_json::to_string_pretty(&analysis_result.metrics)?,
127 analysis_result.suggestions,
128 analysis_result.issues
129 );
130
131 let mut response = code_agent
132 .chat_with_history(&conversation_id, &analysis_prompt, Some(role))
133 .await?;
134
135 println!("\n🤖 AI Analysis:");
136
137 // Process the streaming response
138 let mut buffer = String::new();
139 while let Some(chunk) = response.chunk().await? {
140 match code_agent
141 .process_stream_response(&conversation_id, &chunk)
142 .await
143 {
144 Ok(Some(message)) => {
145 // Print the content if it exists
146 if !message.content.is_empty() {
147 print!("{}", message.content);
148 io::stdout().flush()?;
149 buffer.push_str(&message.content);
150 }
151
152 // Handle tool calls if they exist
153 if let Some(tool_calls) = &message.tool_calls {
154 for tool_call in tool_calls {
155 print!("\n[Tool Call] {}(", tool_call.function.name);
156 if let Some(obj) = tool_call.function.arguments.as_object() {
157 for (key, value) in obj {
158 print!("{}: {}, ", key, value);
159 }
160 }
161 println!(")");
162 io::stdout().flush()?;
163 }
164 }
165 }
166 Ok(None) => {
167 code_agent
168 .add_message(&conversation_id, "assistant", &buffer)
169 .await;
170 println!("\n✅ Analysis complete!\n");
171 break;
172 }
173 Err(e) => {
174 eprintln!("\n❌ Error processing stream: {}", e);
175 break;
176 }
177 }
178 }
179
180 // Ask a follow-up question about Rust-specific improvements
181 let follow_up = "What Rust-specific improvements would you recommend for this code?";
182 let mut follow_up_response = code_agent
183 .chat_with_history(&conversation_id, follow_up, None)
184 .await?;
185
186 println!("\n🔍 Follow-up Analysis:");
187 let mut buffer = String::new();
188 while let Some(chunk) = follow_up_response.chunk().await? {
189 match code_agent
190 .process_stream_response(&conversation_id, &chunk)
191 .await
192 {
193 Ok(Some(message)) => {
194 // Print the content if it exists
195 if !message.content.is_empty() {
196 print!("{}", message.content);
197 io::stdout().flush()?;
198 buffer.push_str(&message.content);
199 }
200
201 // Handle tool calls if they exist
202 if let Some(tool_calls) = &message.tool_calls {
203 for tool_call in tool_calls {
204 print!("\n[Tool Call] {}(", tool_call.function.name);
205 if let Some(obj) = tool_call.function.arguments.as_object() {
206 for (key, value) in obj {
207 print!("{}: {}, ", key, value);
208 }
209 }
210 println!(")");
211 io::stdout().flush()?;
212 }
213 }
214 }
215 Ok(None) => {
216 code_agent
217 .add_message(&conversation_id, "assistant", &buffer)
218 .await;
219 println!("\n");
220 break;
221 }
222 Err(e) => {
223 eprintln!("\n❌ Error processing stream: {}", e);
224 break;
225 }
226 }
227 }
228
229 Ok(())
230}Sourcepub async fn analyze_java(
&self,
code: &str,
) -> Result<CodeAnalysisResult, KowalskiError>
pub async fn analyze_java( &self, code: &str, ) -> Result<CodeAnalysisResult, KowalskiError>
Analyzes Java code
Examples found in repository?
examples/java_analysis.rs (line 87)
11async fn main() -> Result<(), Box<dyn std::error::Error>> {
12 // Initialize logging
13 env_logger::init();
14
15 // Load configuration
16 let config = Config::default();
17 let mut code_agent = CodeAgent::new(config).await?;
18
19 // Start a conversation
20 println!("☕ Starting Java Code Analysis...");
21 let conversation_id = code_agent.start_conversation("llama3.2");
22 println!("Code Agent Conversation ID: {}", conversation_id);
23
24 // Set up the role for code analysis
25 let role = Role::new(
26 "Java Code Analysis Assistant",
27 "You are an expert at analyzing Java code, providing insights on code quality, best practices, and potential improvements.",
28 )
29 .with_audience(Audience::new(
30 "Java Developer",
31 "You are speaking to a Java developer who needs detailed code analysis.",
32 ))
33 .with_preset(Preset::new(
34 "Analysis",
35 "Provide comprehensive analysis with specific recommendations for improvement.",
36 ));
37
38 // Sample Java code for analysis
39 let java_code = r#"
40import java.util.*;
41
42public class Calculator {
43 private int result;
44
45 public Calculator() {
46 this.result = 0;
47 }
48
49 public int add(int a, int b) {
50 result = a + b;
51 return result;
52 }
53
54 public int subtract(int a, int b) {
55 result = a - b;
56 return result;
57 }
58
59 public int multiply(int a, int b) {
60 result = a * b;
61 return result;
62 }
63
64 public double divide(int a, int b) {
65 if (b == 0) {
66 System.out.println("Error: Division by zero");
67 return 0;
68 }
69 result = a / b;
70 return (double) result;
71 }
72
73 public static void main(String[] args) {
74 Calculator calc = new Calculator();
75 System.out.println("Addition: " + calc.add(10, 5));
76 System.out.println("Subtraction: " + calc.subtract(10, 5));
77 System.out.println("Multiplication: " + calc.multiply(10, 5));
78 System.out.println("Division: " + calc.divide(10, 5));
79 }
80}
81"#;
82
83 println!("\n📝 Java Code to Analyze:");
84 println!("{}", java_code);
85
86 // Analyze the Java code
87 let analysis_result = code_agent.analyze_java(java_code).await?;
88
89 println!("\n📊 Java Analysis Results:");
90 println!("Language: {}", analysis_result.language);
91 println!(
92 "Metrics: {}",
93 serde_json::to_string_pretty(&analysis_result.metrics)?
94 );
95 println!("Suggestions: {:?}", analysis_result.suggestions);
96 println!("Issues: {:?}", analysis_result.issues);
97
98 // Ask the agent to analyze the code
99 let analysis_prompt = format!(
100 "Please analyze this Java code and provide insights:\n\n{}\n\nAnalysis results:\nMetrics: {}\nSuggestions: {:?}\nIssues: {:?}",
101 java_code,
102 serde_json::to_string_pretty(&analysis_result.metrics)?,
103 analysis_result.suggestions,
104 analysis_result.issues
105 );
106
107 let mut response = code_agent
108 .chat_with_history(&conversation_id, &analysis_prompt, Some(role))
109 .await?;
110
111 println!("\n🤖 AI Analysis:");
112
113 // Process the streaming response
114 let mut buffer = String::new();
115 while let Some(chunk) = response.chunk().await? {
116 match code_agent
117 .process_stream_response(&conversation_id, &chunk)
118 .await
119 {
120 Ok(Some(message)) => {
121 // Print the content if it exists
122 if !message.content.is_empty() {
123 print!("{}", message.content);
124 io::stdout().flush()?;
125 buffer.push_str(&message.content);
126 }
127
128 // Handle tool calls if they exist
129 if let Some(tool_calls) = &message.tool_calls {
130 for tool_call in tool_calls {
131 print!("\n[Tool Call] {}(", tool_call.function.name);
132 if let Some(obj) = tool_call.function.arguments.as_object() {
133 for (key, value) in obj {
134 print!("{}: {}, ", key, value);
135 }
136 }
137 println!(")");
138 io::stdout().flush()?;
139 }
140 }
141 }
142 Ok(None) => {
143 code_agent
144 .add_message(&conversation_id, "assistant", &buffer)
145 .await;
146 println!("\n✅ Analysis complete!\n");
147 break;
148 }
149 Err(e) => {
150 eprintln!("\n❌ Error processing stream: {}", e);
151 break;
152 }
153 }
154 }
155
156 // Ask a follow-up question about specific improvements
157 let follow_up = "What specific improvements would you recommend for this Java code?";
158 let mut follow_up_response = code_agent
159 .chat_with_history(&conversation_id, follow_up, None)
160 .await?;
161
162 println!("\n🔍 Follow-up Analysis:");
163 let mut buffer = String::new();
164 while let Some(chunk) = follow_up_response.chunk().await? {
165 match code_agent
166 .process_stream_response(&conversation_id, &chunk)
167 .await
168 {
169 Ok(Some(message)) => {
170 // Print the content if it exists
171 if !message.content.is_empty() {
172 print!("{}", message.content);
173 io::stdout().flush()?;
174 buffer.push_str(&message.content);
175 }
176
177 // Handle tool calls if they exist
178 if let Some(tool_calls) = &message.tool_calls {
179 for tool_call in tool_calls {
180 print!("\n[Tool Call] {}(", tool_call.function.name);
181 if let Some(obj) = tool_call.function.arguments.as_object() {
182 for (key, value) in obj {
183 print!("{}: {}, ", key, value);
184 }
185 }
186 println!(")");
187 io::stdout().flush()?;
188 }
189 }
190 }
191 Ok(None) => {
192 code_agent
193 .add_message(&conversation_id, "assistant", &buffer)
194 .await;
195 println!("\n");
196 break;
197 }
198 Err(e) => {
199 eprintln!("\n❌ Error processing stream: {}", e);
200 break;
201 }
202 }
203 }
204
205 Ok(())
206}Sourcepub async fn analyze_python(
&self,
code: &str,
) -> Result<CodeAnalysisResult, KowalskiError>
pub async fn analyze_python( &self, code: &str, ) -> Result<CodeAnalysisResult, KowalskiError>
Analyzes Python code
Examples found in repository?
examples/python_analysis.rs (line 97)
11async fn main() -> Result<(), Box<dyn std::error::Error>> {
12 // Initialize logging
13 env_logger::init();
14
15 // Load configuration
16 let config = Config::default();
17 let mut code_agent = CodeAgent::new(config).await?;
18
19 // Start a conversation
20 println!("🐍 Starting Python Code Analysis...");
21 let conversation_id = code_agent.start_conversation("llama3.2");
22 println!("Code Agent Conversation ID: {}", conversation_id);
23
24 // Set up the role for code analysis
25 let role = Role::new(
26 "Python Code Analysis Assistant",
27 "You are an expert at analyzing Python code, providing insights on code quality, PEP 8 compliance, and potential improvements.",
28 )
29 .with_audience(Audience::new(
30 "Python Developer",
31 "You are speaking to a Python developer who needs detailed code analysis.",
32 ))
33 .with_preset(Preset::new(
34 "Analysis",
35 "Provide comprehensive analysis with specific recommendations for improvement.",
36 ));
37
38 // Sample Python code for analysis
39 let python_code = r#"
40import os
41import sys
42from typing import List, Optional
43
44class DataProcessor:
45 def __init__(self, data: List[int]):
46 self.data = data
47 self.result = 0
48
49 def calculate_sum(self) -> int:
50 """Calculate the sum of all data points."""
51 total = 0
52 for item in self.data:
53 total += item
54 return total
55
56 def calculate_average(self) -> float:
57 """Calculate the average of all data points."""
58 if len(self.data) == 0:
59 print("Error: No data to calculate average")
60 return 0.0
61 return self.calculate_sum() / len(self.data)
62
63 def find_max(self) -> Optional[int]:
64 """Find the maximum value in the data."""
65 if not self.data:
66 return None
67 max_val = self.data[0]
68 for item in self.data:
69 if item > max_val:
70 max_val = item
71 return max_val
72
73def main():
74 # Sample data
75 numbers = [10, 20, 30, 40, 50]
76
77 # Create processor
78 processor = DataProcessor(numbers)
79
80 # Calculate statistics
81 print(f"Sum: {processor.calculate_sum()}")
82 print(f"Average: {processor.calculate_average()}")
83 print(f"Maximum: {processor.find_max()}")
84
85 # Process empty data
86 empty_processor = DataProcessor([])
87 print(f"Empty average: {empty_processor.calculate_average()}")
88
89if __name__ == "__main__":
90 main()
91"#;
92
93 println!("\n📝 Python Code to Analyze:");
94 println!("{}", python_code);
95
96 // Analyze the Python code
97 let analysis_result = code_agent.analyze_python(python_code).await?;
98
99 println!("\n📊 Python Analysis Results:");
100 println!("Language: {}", analysis_result.language);
101 println!(
102 "Metrics: {}",
103 serde_json::to_string_pretty(&analysis_result.metrics)?
104 );
105 println!("Suggestions: {:?}", analysis_result.suggestions);
106 println!("PEP 8 Issues: {:?}", analysis_result.issues);
107
108 // Ask the agent to analyze the code
109 let analysis_prompt = format!(
110 "Please analyze this Python code and provide insights:\n\n{}\n\nAnalysis results:\nMetrics: {}\nSuggestions: {:?}\nPEP 8 Issues: {:?}",
111 python_code,
112 serde_json::to_string_pretty(&analysis_result.metrics)?,
113 analysis_result.suggestions,
114 analysis_result.issues
115 );
116
117 let mut response = code_agent
118 .chat_with_history(&conversation_id, &analysis_prompt, Some(role))
119 .await?;
120
121 println!("\n🤖 AI Analysis:");
122
123 // Process the streaming response
124 let mut buffer = String::new();
125 while let Some(chunk) = response.chunk().await? {
126 match code_agent
127 .process_stream_response(&conversation_id, &chunk)
128 .await
129 {
130 Ok(Some(message)) => {
131 // Print the content if it exists
132 if !message.content.is_empty() {
133 print!("{}", message.content);
134 io::stdout().flush()?;
135 buffer.push_str(&message.content);
136 }
137
138 // Handle tool calls if they exist
139 if let Some(tool_calls) = &message.tool_calls {
140 for tool_call in tool_calls {
141 print!("\n[Tool Call] {}(", tool_call.function.name);
142 if let Some(obj) = tool_call.function.arguments.as_object() {
143 for (key, value) in obj {
144 print!("{}: {}, ", key, value);
145 }
146 }
147 println!(")");
148 io::stdout().flush()?;
149 }
150 }
151 }
152 Ok(None) => {
153 code_agent
154 .add_message(&conversation_id, "assistant", &buffer)
155 .await;
156 println!("\n✅ Analysis complete!\n");
157 break;
158 }
159 Err(e) => {
160 eprintln!("\n❌ Error processing stream: {}", e);
161 break;
162 }
163 }
164 }
165
166 // Ask a follow-up question about PEP 8 compliance
167 let follow_up = "How can this Python code be improved to better follow PEP 8 guidelines?";
168 let mut follow_up_response = code_agent
169 .chat_with_history(&conversation_id, follow_up, None)
170 .await?;
171
172 println!("\n🔍 Follow-up Analysis:");
173 let mut buffer = String::new();
174 while let Some(chunk) = follow_up_response.chunk().await? {
175 match code_agent
176 .process_stream_response(&conversation_id, &chunk)
177 .await
178 {
179 Ok(Some(message)) => {
180 // Print the content if it exists
181 if !message.content.is_empty() {
182 print!("{}", message.content);
183 io::stdout().flush()?;
184 buffer.push_str(&message.content);
185 }
186
187 // Handle tool calls if they exist
188 if let Some(tool_calls) = &message.tool_calls {
189 for tool_call in tool_calls {
190 print!("\n[Tool Call] {}(", tool_call.function.name);
191 if let Some(obj) = tool_call.function.arguments.as_object() {
192 for (key, value) in obj {
193 print!("{}: {}, ", key, value);
194 }
195 }
196 println!(")");
197 io::stdout().flush()?;
198 }
199 }
200 }
201 Ok(None) => {
202 code_agent
203 .add_message(&conversation_id, "assistant", &buffer)
204 .await;
205 println!("\n");
206 break;
207 }
208 Err(e) => {
209 eprintln!("\n❌ Error processing stream: {}", e);
210 break;
211 }
212 }
213 }
214
215 Ok(())
216}Sourcepub async fn analyze_rust(
&self,
code: &str,
) -> Result<CodeAnalysisResult, KowalskiError>
pub async fn analyze_rust( &self, code: &str, ) -> Result<CodeAnalysisResult, KowalskiError>
Analyzes Rust code
Examples found in repository?
examples/rust_analysis.rs (line 111)
11async fn main() -> Result<(), Box<dyn std::error::Error>> {
12 // Initialize logging
13 env_logger::init();
14
15 // Load configuration
16 let config = Config::default();
17 let mut code_agent = CodeAgent::new(config).await?;
18
19 // Start a conversation
20 println!("🦀 Starting Rust Code Analysis...");
21 let conversation_id = code_agent.start_conversation("llama3.2");
22 println!("Code Agent Conversation ID: {}", conversation_id);
23
24 // Set up the role for code analysis
25 let role = Role::new(
26 "Rust Code Analysis Assistant",
27 "You are an expert at analyzing Rust code, providing insights on code quality, safety, and potential improvements.",
28 )
29 .with_audience(Audience::new(
30 "Rust Developer",
31 "You are speaking to a Rust developer who needs detailed code analysis.",
32 ))
33 .with_preset(Preset::new(
34 "Analysis",
35 "Provide comprehensive analysis with specific recommendations for improvement.",
36 ));
37
38 // Sample Rust code for analysis
39 let rust_code = r#"
40use std::collections::HashMap;
41use std::error::Error;
42
43#[derive(Debug)]
44struct DataProcessor {
45 data: Vec<i32>,
46 cache: HashMap<String, i32>,
47}
48
49impl DataProcessor {
50 fn new(data: Vec<i32>) -> Self {
51 Self {
52 data,
53 cache: HashMap::new(),
54 }
55 }
56
57 fn calculate_sum(&self) -> i32 {
58 self.data.iter().sum()
59 }
60
61 fn calculate_average(&self) -> Option<f64> {
62 if self.data.is_empty() {
63 None
64 } else {
65 Some(self.calculate_sum() as f64 / self.data.len() as f64)
66 }
67 }
68
69 fn find_max(&self) -> Option<&i32> {
70 self.data.iter().max()
71 }
72
73 fn process_with_cache(&mut self, key: String) -> Result<i32, Box<dyn Error>> {
74 if let Some(&cached_value) = self.cache.get(&key) {
75 return Ok(cached_value);
76 }
77
78 let result = self.calculate_sum();
79 self.cache.insert(key, result);
80 Ok(result)
81 }
82}
83
84fn main() {
85 let numbers = vec![10, 20, 30, 40, 50];
86 let mut processor = DataProcessor::new(numbers);
87
88 println!("Sum: {}", processor.calculate_sum());
89
90 match processor.calculate_average() {
91 Some(avg) => println!("Average: {}", avg),
92 None => println!("No data to calculate average"),
93 }
94
95 match processor.find_max() {
96 Some(max) => println!("Maximum: {}", max),
97 None => println!("No data to find maximum"),
98 }
99
100 match processor.process_with_cache("sum".to_string()) {
101 Ok(result) => println!("Cached result: {}", result),
102 Err(e) => println!("Error: {}", e),
103 }
104}
105"#;
106
107 println!("\n📝 Rust Code to Analyze:");
108 println!("{}", rust_code);
109
110 // Analyze the Rust code
111 let analysis_result = code_agent.analyze_rust(rust_code).await?;
112
113 println!("\n📊 Rust Analysis Results:");
114 println!("Language: {}", analysis_result.language);
115 println!(
116 "Metrics: {}",
117 serde_json::to_string_pretty(&analysis_result.metrics)?
118 );
119 println!("Suggestions: {:?}", analysis_result.suggestions);
120 println!("Rust Issues: {:?}", analysis_result.issues);
121
122 // Ask the agent to analyze the code
123 let analysis_prompt = format!(
124 "Please analyze this Rust code and provide insights:\n\n{}\n\nAnalysis results:\nMetrics: {}\nSuggestions: {:?}\nRust Issues: {:?}",
125 rust_code,
126 serde_json::to_string_pretty(&analysis_result.metrics)?,
127 analysis_result.suggestions,
128 analysis_result.issues
129 );
130
131 let mut response = code_agent
132 .chat_with_history(&conversation_id, &analysis_prompt, Some(role))
133 .await?;
134
135 println!("\n🤖 AI Analysis:");
136
137 // Process the streaming response
138 let mut buffer = String::new();
139 while let Some(chunk) = response.chunk().await? {
140 match code_agent
141 .process_stream_response(&conversation_id, &chunk)
142 .await
143 {
144 Ok(Some(message)) => {
145 // Print the content if it exists
146 if !message.content.is_empty() {
147 print!("{}", message.content);
148 io::stdout().flush()?;
149 buffer.push_str(&message.content);
150 }
151
152 // Handle tool calls if they exist
153 if let Some(tool_calls) = &message.tool_calls {
154 for tool_call in tool_calls {
155 print!("\n[Tool Call] {}(", tool_call.function.name);
156 if let Some(obj) = tool_call.function.arguments.as_object() {
157 for (key, value) in obj {
158 print!("{}: {}, ", key, value);
159 }
160 }
161 println!(")");
162 io::stdout().flush()?;
163 }
164 }
165 }
166 Ok(None) => {
167 code_agent
168 .add_message(&conversation_id, "assistant", &buffer)
169 .await;
170 println!("\n✅ Analysis complete!\n");
171 break;
172 }
173 Err(e) => {
174 eprintln!("\n❌ Error processing stream: {}", e);
175 break;
176 }
177 }
178 }
179
180 // Ask a follow-up question about Rust-specific improvements
181 let follow_up = "What Rust-specific improvements would you recommend for this code?";
182 let mut follow_up_response = code_agent
183 .chat_with_history(&conversation_id, follow_up, None)
184 .await?;
185
186 println!("\n🔍 Follow-up Analysis:");
187 let mut buffer = String::new();
188 while let Some(chunk) = follow_up_response.chunk().await? {
189 match code_agent
190 .process_stream_response(&conversation_id, &chunk)
191 .await
192 {
193 Ok(Some(message)) => {
194 // Print the content if it exists
195 if !message.content.is_empty() {
196 print!("{}", message.content);
197 io::stdout().flush()?;
198 buffer.push_str(&message.content);
199 }
200
201 // Handle tool calls if they exist
202 if let Some(tool_calls) = &message.tool_calls {
203 for tool_call in tool_calls {
204 print!("\n[Tool Call] {}(", tool_call.function.name);
205 if let Some(obj) = tool_call.function.arguments.as_object() {
206 for (key, value) in obj {
207 print!("{}: {}, ", key, value);
208 }
209 }
210 println!(")");
211 io::stdout().flush()?;
212 }
213 }
214 }
215 Ok(None) => {
216 code_agent
217 .add_message(&conversation_id, "assistant", &buffer)
218 .await;
219 println!("\n");
220 break;
221 }
222 Err(e) => {
223 eprintln!("\n❌ Error processing stream: {}", e);
224 break;
225 }
226 }
227 }
228
229 Ok(())
230}Trait Implementations§
Source§impl Agent for CodeAgent
impl Agent for CodeAgent
Source§fn new<'async_trait>(
config: Config,
) -> Pin<Box<dyn Future<Output = Result<Self, KowalskiError>> + Send + 'async_trait>>where
Self: 'async_trait,
fn new<'async_trait>(
config: Config,
) -> Pin<Box<dyn Future<Output = Result<Self, KowalskiError>> + Send + 'async_trait>>where
Self: 'async_trait,
Creates a new agent with the specified configuration.
Source§fn start_conversation(&mut self, model: &str) -> String
fn start_conversation(&mut self, model: &str) -> String
Starts a new conversation
Source§fn get_conversation(&self, id: &str) -> Option<&Conversation>
fn get_conversation(&self, id: &str) -> Option<&Conversation>
Gets a conversation by ID
Source§fn list_conversations(&self) -> Vec<&Conversation>
fn list_conversations(&self) -> Vec<&Conversation>
Lists all conversations
Source§fn delete_conversation(&mut self, id: &str) -> bool
fn delete_conversation(&mut self, id: &str) -> bool
Deletes a conversation
Source§fn chat_with_history<'life0, 'life1, 'life2, 'async_trait>(
&'life0 mut self,
conversation_id: &'life1 str,
content: &'life2 str,
role: Option<Role>,
) -> Pin<Box<dyn Future<Output = Result<Response, KowalskiError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn chat_with_history<'life0, 'life1, 'life2, 'async_trait>(
&'life0 mut self,
conversation_id: &'life1 str,
content: &'life2 str,
role: Option<Role>,
) -> Pin<Box<dyn Future<Output = Result<Response, KowalskiError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Chats with history
Source§fn process_stream_response<'life0, 'life1, 'life2, 'async_trait>(
&'life0 mut self,
conversation_id: &'life1 str,
chunk: &'life2 [u8],
) -> Pin<Box<dyn Future<Output = Result<Option<Message>, KowalskiError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn process_stream_response<'life0, 'life1, 'life2, 'async_trait>(
&'life0 mut self,
conversation_id: &'life1 str,
chunk: &'life2 [u8],
) -> Pin<Box<dyn Future<Output = Result<Option<Message>, KowalskiError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Processes a stream response
Source§fn add_message<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 mut self,
conversation_id: &'life1 str,
role: &'life2 str,
content: &'life3 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn add_message<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 mut self,
conversation_id: &'life1 str,
role: &'life2 str,
content: &'life3 str,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Adds a message to a conversation
Source§fn description(&self) -> &str
fn description(&self) -> &str
Gets the agent’s description
Auto Trait Implementations§
impl Freeze for CodeAgent
impl !RefUnwindSafe for CodeAgent
impl Send for CodeAgent
impl Sync for CodeAgent
impl Unpin for CodeAgent
impl !UnwindSafe for CodeAgent
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
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more