feat(tui): integrate rich context builder into agent turn process
This commit is contained in:
@@ -191,3 +191,73 @@ pub fn build_workspace_tree(root: &Path, max_files: usize) -> String {
|
|||||||
|
|
||||||
tree.trim_end().to_string()
|
tree.trim_end().to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Rich Context Builder
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Gathers essential project context (OS, Time, Git, Tech Stack, Rules) into a string.
|
||||||
|
pub fn build_rich_context(root: &Path) -> String {
|
||||||
|
use std::process::Command;
|
||||||
|
let mut ctx = String::new();
|
||||||
|
|
||||||
|
// 1. Time and OS
|
||||||
|
let os = std::env::consts::OS;
|
||||||
|
let arch = std::env::consts::ARCH;
|
||||||
|
let time = chrono::Local::now().to_rfc3339();
|
||||||
|
ctx.push_str(&format!("Environment: {} ({}), Current Time: {}\n\n", os, arch, time));
|
||||||
|
|
||||||
|
// 2. Custom Rules
|
||||||
|
let rule_files = [".cursorrules", ".zesdexrules", "claude.md", "agent.md"];
|
||||||
|
for file in rule_files {
|
||||||
|
let p = root.join(file);
|
||||||
|
if let Ok(content) = std::fs::read_to_string(&p) {
|
||||||
|
ctx.push_str(&format!("### Project Rules ({})\n```\n{}\n```\n\n", file, content.trim()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Git Status
|
||||||
|
if root.join(".git").exists() {
|
||||||
|
let branch = Command::new("git")
|
||||||
|
.arg("branch")
|
||||||
|
.arg("--show-current")
|
||||||
|
.current_dir(root)
|
||||||
|
.output()
|
||||||
|
.map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let status = Command::new("git")
|
||||||
|
.arg("status")
|
||||||
|
.arg("-s")
|
||||||
|
.current_dir(root)
|
||||||
|
.output()
|
||||||
|
.map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
if !branch.is_empty() {
|
||||||
|
ctx.push_str(&format!("### Git State (branch: {})\n", branch));
|
||||||
|
if !status.is_empty() {
|
||||||
|
ctx.push_str(&format!("Uncommitted changes:\n```\n{}\n```\n", status));
|
||||||
|
} else {
|
||||||
|
ctx.push_str("No uncommitted changes.\n");
|
||||||
|
}
|
||||||
|
ctx.push('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Tech Stack (manifests)
|
||||||
|
let manifests = ["Cargo.toml", "package.json", "go.mod"];
|
||||||
|
for file in manifests {
|
||||||
|
let p = root.join(file);
|
||||||
|
if let Ok(content) = std::fs::read_to_string(&p) {
|
||||||
|
let snippet = if content.len() > 1500 {
|
||||||
|
format!("{}\n... (truncated)", &content[..1500])
|
||||||
|
} else {
|
||||||
|
content
|
||||||
|
};
|
||||||
|
ctx.push_str(&format!("### Tech Stack Manifest ({})\n```\n{}\n```\n\n", file, snippet.trim()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.trim_end().to_string()
|
||||||
|
}
|
||||||
|
|||||||
@@ -129,9 +129,13 @@ fn run_turn(params: TurnParams) {
|
|||||||
|
|
||||||
if let Some(root) = params.workspace_roots.first() {
|
if let Some(root) = params.workspace_roots.first() {
|
||||||
let tree = zesdex_infrastructure::utils::build_workspace_tree(root, 800);
|
let tree = zesdex_infrastructure::utils::build_workspace_tree(root, 800);
|
||||||
|
let rich_ctx = zesdex_infrastructure::utils::build_rich_context(root);
|
||||||
|
|
||||||
sys_prompt.push_str("\n\nWorkspace structure:\n```\n");
|
sys_prompt.push_str("\n\nWorkspace structure:\n```\n");
|
||||||
sys_prompt.push_str(&tree);
|
sys_prompt.push_str(&tree);
|
||||||
sys_prompt.push_str("\n```\n");
|
sys_prompt.push_str("\n```\n\n");
|
||||||
|
|
||||||
|
sys_prompt.push_str(&rich_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
let sys_msg = ChatMessage::system(sys_prompt);
|
let sys_msg = ChatMessage::system(sys_prompt);
|
||||||
|
|||||||
Reference in New Issue
Block a user