Execution working
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
use g3_providers::{ProviderRegistry, CompletionRequest, Message, MessageRole};
|
use anyhow::Result;
|
||||||
use g3_config::Config;
|
use g3_config::Config;
|
||||||
use g3_execution::CodeExecutor;
|
use g3_execution::CodeExecutor;
|
||||||
use anyhow::Result;
|
use g3_providers::{CompletionRequest, Message, MessageRole, ProviderRegistry};
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
use tracing::field::debug;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
pub struct Agent {
|
pub struct Agent {
|
||||||
@@ -172,15 +173,44 @@ impl Agent {
|
|||||||
Ok(response.content)
|
Ok(response.content)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn execute_task(&self, description: &str, language: Option<&str>, _auto_execute: bool) -> Result<String> {
|
pub async fn execute_task(
|
||||||
self.execute_task_with_options(description, language, false, false, false).await
|
&self,
|
||||||
|
description: &str,
|
||||||
|
language: Option<&str>,
|
||||||
|
_auto_execute: bool,
|
||||||
|
) -> Result<String> {
|
||||||
|
self.execute_task_with_options(description, language, false, false, false)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn execute_task_with_options(&self, description: &str, language: Option<&str>, _auto_execute: bool, show_prompt: bool, show_code: bool) -> Result<String> {
|
pub async fn execute_task_with_options(
|
||||||
self.execute_task_with_timing(description, language, _auto_execute, show_prompt, show_code, false).await
|
&self,
|
||||||
|
description: &str,
|
||||||
|
language: Option<&str>,
|
||||||
|
_auto_execute: bool,
|
||||||
|
show_prompt: bool,
|
||||||
|
show_code: bool,
|
||||||
|
) -> Result<String> {
|
||||||
|
self.execute_task_with_timing(
|
||||||
|
description,
|
||||||
|
language,
|
||||||
|
_auto_execute,
|
||||||
|
show_prompt,
|
||||||
|
show_code,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn execute_task_with_timing(&self, description: &str, language: Option<&str>, _auto_execute: bool, show_prompt: bool, show_code: bool, show_timing: bool) -> Result<String> {
|
pub async fn execute_task_with_timing(
|
||||||
|
&self,
|
||||||
|
description: &str,
|
||||||
|
language: Option<&str>,
|
||||||
|
_auto_execute: bool,
|
||||||
|
show_prompt: bool,
|
||||||
|
show_code: bool,
|
||||||
|
show_timing: bool,
|
||||||
|
) -> Result<String> {
|
||||||
info!("Executing task: {}", description);
|
info!("Executing task: {}", description);
|
||||||
|
|
||||||
let total_start = Instant::now();
|
let total_start = Instant::now();
|
||||||
@@ -248,10 +278,19 @@ Then execute it and show the output.",
|
|||||||
let response = provider.complete(request).await?;
|
let response = provider.complete(request).await?;
|
||||||
let llm_duration = llm_start.elapsed();
|
let llm_duration = llm_start.elapsed();
|
||||||
|
|
||||||
|
// Log the LLM response before passing to CodeExecutor
|
||||||
|
// debug!(
|
||||||
|
// "LLM Response received ({} chars): {}\n=== END ===",
|
||||||
|
// response.content.len(),
|
||||||
|
// response.content
|
||||||
|
// );
|
||||||
|
|
||||||
// Time the code execution
|
// Time the code execution
|
||||||
let exec_start = Instant::now();
|
let exec_start = Instant::now();
|
||||||
let executor = CodeExecutor::new();
|
let executor = CodeExecutor::new();
|
||||||
let result = executor.execute_from_response_with_options(&response.content, show_code).await?;
|
let result = executor
|
||||||
|
.execute_from_response_with_options(&response.content, show_code)
|
||||||
|
.await?;
|
||||||
let exec_duration = exec_start.elapsed();
|
let exec_duration = exec_start.elapsed();
|
||||||
|
|
||||||
let total_duration = total_start.elapsed();
|
let total_duration = total_start.elapsed();
|
||||||
@@ -377,7 +416,11 @@ Then execute it and show the output.",
|
|||||||
Ok(response.content)
|
Ok(response.content)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn execute_file_operation(&self, operation: &str, path: Option<&str>) -> Result<String> {
|
pub async fn execute_file_operation(
|
||||||
|
&self,
|
||||||
|
operation: &str,
|
||||||
|
path: Option<&str>,
|
||||||
|
) -> Result<String> {
|
||||||
info!("Executing file operation: {}", operation);
|
info!("Executing file operation: {}", operation);
|
||||||
|
|
||||||
let provider = self.providers.get(None)?;
|
let provider = self.providers.get(None)?;
|
||||||
@@ -433,14 +476,18 @@ Then execute it and show the output.",
|
|||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
if let Some(ext) = path.extension() {
|
if let Some(ext) = path.extension() {
|
||||||
// Only read common code files
|
// Only read common code files
|
||||||
if matches!(ext.to_str(), Some("rs" | "py" | "js" | "ts" | "go" | "java" | "cpp" | "c" | "h")) {
|
if matches!(
|
||||||
|
ext.to_str(),
|
||||||
|
Some("rs" | "py" | "js" | "ts" | "go" | "java" | "cpp" | "c" | "h")
|
||||||
|
) {
|
||||||
content.push_str(&format!("\n--- {} ---\n", path.display()));
|
content.push_str(&format!("\n--- {} ---\n", path.display()));
|
||||||
if let Ok(file_content) = std::fs::read_to_string(&path) {
|
if let Ok(file_content) = std::fs::read_to_string(&path) {
|
||||||
content.push_str(&file_content);
|
content.push_str(&file_content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if path.is_dir() && !path.file_name().unwrap().to_str().unwrap().starts_with('.') {
|
} else if path.is_dir() && !path.file_name().unwrap().to_str().unwrap().starts_with('.')
|
||||||
|
{
|
||||||
self.read_directory_recursive(&path, content)?;
|
self.read_directory_recursive(&path, content)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -458,13 +505,21 @@ impl std::fmt::Display for AnalysisResult {
|
|||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
writeln!(f, "Metrics:")?;
|
writeln!(f, "Metrics:")?;
|
||||||
writeln!(f, "- Lines of Code: {}", self.metrics.lines_of_code)?;
|
writeln!(f, "- Lines of Code: {}", self.metrics.lines_of_code)?;
|
||||||
writeln!(f, "- Complexity Score: {:.2}", self.metrics.complexity_score)?;
|
writeln!(
|
||||||
writeln!(f, "- Maintainability Index: {:.2}", self.metrics.maintainability_index)?;
|
f,
|
||||||
|
"- Complexity Score: {:.2}",
|
||||||
|
self.metrics.complexity_score
|
||||||
|
)?;
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"- Maintainability Index: {:.2}",
|
||||||
|
self.metrics.maintainability_index
|
||||||
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod providers {
|
pub mod providers {
|
||||||
pub mod openai;
|
|
||||||
pub mod anthropic;
|
pub mod anthropic;
|
||||||
|
pub mod openai;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ impl CodeExecutor {
|
|||||||
|
|
||||||
/// Extract code blocks from LLM response and execute them with UI options
|
/// Extract code blocks from LLM response and execute them with UI options
|
||||||
pub async fn execute_from_response_with_options(&self, response: &str, show_code: bool) -> Result<String> {
|
pub async fn execute_from_response_with_options(&self, response: &str, show_code: bool) -> Result<String> {
|
||||||
|
debug!("CodeExecutor received response ({} chars): {}", response.len(), response);
|
||||||
let code_blocks = self.extract_code_blocks(response)?;
|
let code_blocks = self.extract_code_blocks(response)?;
|
||||||
|
|
||||||
if code_blocks.is_empty() {
|
if code_blocks.is_empty() {
|
||||||
@@ -89,20 +90,25 @@ impl CodeExecutor {
|
|||||||
|
|
||||||
/// Extract code blocks from markdown-formatted text
|
/// Extract code blocks from markdown-formatted text
|
||||||
fn extract_code_blocks(&self, text: &str) -> Result<Vec<(String, String)>> {
|
fn extract_code_blocks(&self, text: &str) -> Result<Vec<(String, String)>> {
|
||||||
let re = Regex::new(r"```(\w+)?\n(.*?)```")?;
|
let re = Regex::new(r"(?s)```(\w+)?\n(.*?)```")?;
|
||||||
let mut blocks = Vec::new();
|
let mut blocks = Vec::new();
|
||||||
|
|
||||||
|
debug!("Extracting code blocks from text: {}", text);
|
||||||
|
|
||||||
for cap in re.captures_iter(text) {
|
for cap in re.captures_iter(text) {
|
||||||
let language = cap.get(1)
|
let language = cap.get(1)
|
||||||
.map(|m| m.as_str().to_lowercase())
|
.map(|m| m.as_str().to_lowercase())
|
||||||
.unwrap_or_else(|| "bash".to_string()); // Default to bash
|
.unwrap_or_else(|| "bash".to_string()); // Default to bash
|
||||||
let code = cap.get(2).map(|m| m.as_str()).unwrap_or("").trim();
|
let code = cap.get(2).map(|m| m.as_str()).unwrap_or("").trim();
|
||||||
|
|
||||||
|
debug!("Found code block - language: '{}', code: '{}'", language, code);
|
||||||
|
|
||||||
if !code.is_empty() {
|
if !code.is_empty() {
|
||||||
blocks.push((language, code.to_string()));
|
blocks.push((language, code.to_string()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!("Total code blocks found: {}", blocks.len());
|
||||||
Ok(blocks)
|
Ok(blocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user