python_analysis/
python_analysis.rs1use env_logger;
2use kowalski_code_agent::agent::CodeAgent;
3use kowalski_core::{
4 agent::Agent,
5 config::Config,
6 role::{Audience, Preset, Role},
7};
8use std::io::{self, Write};
9
10#[tokio::main]
11async fn main() -> Result<(), Box<dyn std::error::Error>> {
12 env_logger::init();
14
15 let config = Config::default();
17 let mut code_agent = CodeAgent::new(config).await?;
18
19 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 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 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 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 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 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 if !message.content.is_empty() {
133 print!("{}", message.content);
134 io::stdout().flush()?;
135 buffer.push_str(&message.content);
136 }
137
138 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 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 if !message.content.is_empty() {
182 print!("{}", message.content);
183 io::stdout().flush()?;
184 buffer.push_str(&message.content);
185 }
186
187 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}