perf: auto-populate git context natively to avoid token waste
- Added get_git_context() to utils.rs using git2 to natively fetch branch, commit, and repo_name without CLI overhead. - Wired native auto-population into LogCodeChangeHandler, LogErrorFixHandler, TechDebtHandler, TasksHandler, MilestonesHandler, AutoSessionCheckpointHandler, and HandoffMemosHandler. - Eliminates the need for the LLM to waste repetitive background turns running git rev-parse HEAD and git branch --show-current via terminal shell commands just to feed the MCP logging tools.
This commit is contained in:
1 parent
11f375017a
commit
760ebfcd40
4 files changed
+48
-15
No files matched your search
@@ -34,8 +34,8 @@ impl McpTool for LogErrorFixHandler {
|
|||||||
signature: req.signature.clone(),
|
signature: req.signature.clone(),
|
||||||
solution: solution.clone(),
|
solution: solution.clone(),
|
||||||
timestamp: crate::handlers::utils::now_secs(),
|
timestamp: crate::handlers::utils::now_secs(),
|
||||||
git_commit: req.git_commit,
|
git_commit: req.git_commit.or_else(|| crate::handlers::utils::get_git_context().1),
|
||||||
git_branch: req.git_branch,
|
git_branch: req.git_branch.or_else(|| crate::handlers::utils::get_git_context().0),
|
||||||
embedding,
|
embedding,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
@@ -203,17 +203,20 @@ impl McpTool for LogCodeChangeHandler {
|
|||||||
_ => crate::models::ChangeKind::Modified,
|
_ => crate::models::ChangeKind::Modified,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let (auto_branch, auto_commit, auto_repo) = crate::handlers::utils::get_git_context();
|
||||||
|
let effective_repo = req.repo_name.clone().filter(|rn| !rn.trim().is_empty()).or(auto_repo.clone());
|
||||||
|
|
||||||
let namespace = req
|
let namespace = req
|
||||||
.namespace
|
.namespace
|
||||||
.filter(|ns| !ns.trim().is_empty())
|
.filter(|ns| !ns.trim().is_empty())
|
||||||
.or_else(|| req.repo_name.clone().filter(|rn| !rn.trim().is_empty()))
|
.or_else(|| effective_repo.clone())
|
||||||
.unwrap_or_else(crate::models::default_namespace);
|
.unwrap_or_else(crate::models::default_namespace);
|
||||||
|
|
||||||
let symbols = req.symbol_references.clone().unwrap_or_default();
|
let symbols = req.symbol_references.clone().unwrap_or_default();
|
||||||
let line_range = req.line_range.clone();
|
let line_range = req.line_range.clone();
|
||||||
|
|
||||||
let effective_rev = req.revision.clone().or_else(|| req.git_commit.clone());
|
let effective_rev = req.revision.clone().or_else(|| req.git_commit.clone()).or(auto_commit);
|
||||||
let effective_branch = req.branch.clone().or_else(|| req.git_branch.clone());
|
let effective_branch = req.branch.clone().or_else(|| req.git_branch.clone()).or(auto_branch);
|
||||||
let detected_vcs = if let Some(vcs) = req.vcs_type.clone() {
|
let detected_vcs = if let Some(vcs) = req.vcs_type.clone() {
|
||||||
Some(vcs)
|
Some(vcs)
|
||||||
} else if let Some(ref rev) = effective_rev {
|
} else if let Some(ref rev) = effective_rev {
|
||||||
@@ -248,7 +251,7 @@ impl McpTool for LogCodeChangeHandler {
|
|||||||
description: description.clone(),
|
description: description.clone(),
|
||||||
git_commit: effective_rev.clone(),
|
git_commit: effective_rev.clone(),
|
||||||
git_branch: effective_branch.clone(),
|
git_branch: effective_branch.clone(),
|
||||||
repo_name: req.repo_name,
|
repo_name: effective_repo,
|
||||||
repo_url: req.repo_url,
|
repo_url: req.repo_url,
|
||||||
namespace: namespace.clone(),
|
namespace: namespace.clone(),
|
||||||
change_kind,
|
change_kind,
|
||||||
@@ -629,10 +632,10 @@ impl McpTool for TechDebtHandler {
|
|||||||
ideal_solution: ideal,
|
ideal_solution: ideal,
|
||||||
is_resolved: false,
|
is_resolved: false,
|
||||||
created_at: crate::handlers::utils::now_secs(),
|
created_at: crate::handlers::utils::now_secs(),
|
||||||
git_commit: git_commit,
|
git_commit: git_commit.or_else(|| crate::handlers::utils::get_git_context().1),
|
||||||
git_branch: git_branch,
|
git_branch: git_branch.or_else(|| crate::handlers::utils::get_git_context().0),
|
||||||
embedding,
|
embedding,
|
||||||
repo_name: repo_name,
|
repo_name: repo_name.or_else(|| crate::handlers::utils::get_git_context().2),
|
||||||
severity: severity,
|
severity: severity,
|
||||||
file_path: file_path,
|
file_path: file_path,
|
||||||
line_range: line_range,
|
line_range: line_range,
|
||||||
@@ -1823,6 +1826,8 @@ impl McpTool for AutoSessionCheckpointHandler {
|
|||||||
timestamp, active_tasks, unverified_hyp, recent_changes
|
timestamp, active_tasks, unverified_hyp, recent_changes
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let (auto_branch, auto_commit, auto_repo) = crate::handlers::utils::get_git_context();
|
||||||
|
|
||||||
let memo = crate::models::HandoffMemo {
|
let memo = crate::models::HandoffMemo {
|
||||||
id: memo_id.clone(),
|
id: memo_id.clone(),
|
||||||
author,
|
author,
|
||||||
@@ -1830,6 +1835,9 @@ impl McpTool for AutoSessionCheckpointHandler {
|
|||||||
expires_at: None,
|
expires_at: None,
|
||||||
namespace: req.namespace,
|
namespace: req.namespace,
|
||||||
timestamp,
|
timestamp,
|
||||||
|
git_branch: auto_branch,
|
||||||
|
vcs_revision: auto_commit,
|
||||||
|
repo_name: auto_repo,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ impl McpTool for HandoffMemosHandler {
|
|||||||
let ns = req
|
let ns = req
|
||||||
.namespace
|
.namespace
|
||||||
.unwrap_or_else(crate::models::default_namespace);
|
.unwrap_or_else(crate::models::default_namespace);
|
||||||
|
let (auto_branch, auto_commit, auto_repo) = crate::handlers::utils::get_git_context();
|
||||||
state.telemetry.handoff_memos.modify(|memos| {
|
state.telemetry.handoff_memos.modify(|memos| {
|
||||||
memos.push(crate::models::HandoffMemo {
|
memos.push(crate::models::HandoffMemo {
|
||||||
id: uuid::Uuid::new_v4().to_string(),
|
id: uuid::Uuid::new_v4().to_string(),
|
||||||
@@ -40,6 +41,9 @@ impl McpTool for HandoffMemosHandler {
|
|||||||
namespace: ns,
|
namespace: ns,
|
||||||
timestamp: crate::handlers::utils::now_secs(),
|
timestamp: crate::handlers::utils::now_secs(),
|
||||||
expires_at: None,
|
expires_at: None,
|
||||||
|
git_branch: auto_branch,
|
||||||
|
vcs_revision: auto_commit,
|
||||||
|
repo_name: auto_repo,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
if memos.len() > 200 {
|
if memos.len() > 200 {
|
||||||
@@ -103,9 +107,9 @@ impl McpTool for AddSessionSummaryHandler {
|
|||||||
timestamp: crate::handlers::utils::now_secs(),
|
timestamp: crate::handlers::utils::now_secs(),
|
||||||
expires_at: None,
|
expires_at: None,
|
||||||
session_id: req.session_id,
|
session_id: req.session_id,
|
||||||
repo_name: req.repo_name,
|
repo_name: req.repo_name.or_else(|| crate::handlers::utils::get_git_context().2),
|
||||||
git_branch: req.git_branch,
|
git_branch: req.git_branch.or_else(|| crate::handlers::utils::get_git_context().0),
|
||||||
git_commit: req.git_commit,
|
git_commit: req.git_commit.or_else(|| crate::handlers::utils::get_git_context().1),
|
||||||
tasks_completed: req.tasks_completed.unwrap_or_default(),
|
tasks_completed: req.tasks_completed.unwrap_or_default(),
|
||||||
next_steps: req.next_steps.unwrap_or_default(),
|
next_steps: req.next_steps.unwrap_or_default(),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -37,13 +37,13 @@ impl McpTool for TasksHandler {
|
|||||||
description,
|
description,
|
||||||
created_at: now,
|
created_at: now,
|
||||||
updated_at: now,
|
updated_at: now,
|
||||||
git_branch,
|
git_branch: git_branch.or_else(|| crate::handlers::utils::get_git_context().0),
|
||||||
parent_id,
|
parent_id,
|
||||||
dependencies: deps,
|
dependencies: deps,
|
||||||
acceptance_criteria: vec![],
|
acceptance_criteria: vec![],
|
||||||
expires_at: None,
|
expires_at: None,
|
||||||
namespace: namespace.unwrap_or_else(|| "default".to_string()),
|
namespace: namespace.unwrap_or_else(|| "default".to_string()),
|
||||||
repo_name,
|
repo_name: repo_name.or_else(|| crate::handlers::utils::get_git_context().2),
|
||||||
priority,
|
priority,
|
||||||
assigned_agent,
|
assigned_agent,
|
||||||
verification_command,
|
verification_command,
|
||||||
@@ -430,7 +430,7 @@ impl McpTool for MilestonesHandler {
|
|||||||
description: description,
|
description: description,
|
||||||
task_ids: task_ids.unwrap_or_default(),
|
task_ids: task_ids.unwrap_or_default(),
|
||||||
deliverables: deliverables.unwrap_or_default(),
|
deliverables: deliverables.unwrap_or_default(),
|
||||||
repo_name,
|
repo_name: repo_name.or_else(|| crate::handlers::utils::get_git_context().2),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -57,6 +57,27 @@ pub fn sanitize_path(raw_path: &str) -> String {
|
|||||||
raw_path.to_string()
|
raw_path.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_git_context() -> (Option<String>, Option<String>, Option<String>) {
|
||||||
|
let mut branch = None;
|
||||||
|
let mut commit = None;
|
||||||
|
let mut repo_name = None;
|
||||||
|
|
||||||
|
if let Ok(cwd) = std::env::current_dir() {
|
||||||
|
if let Ok(repo) = git2::Repository::discover(&cwd) {
|
||||||
|
if let Ok(head) = repo.head() {
|
||||||
|
branch = head.shorthand().map(|s| s.to_string());
|
||||||
|
commit = head.target().map(|oid| oid.to_string());
|
||||||
|
}
|
||||||
|
if let Some(path) = repo.workdir() {
|
||||||
|
if let Some(name) = path.file_name() {
|
||||||
|
repo_name = name.to_str().map(|s| s.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(branch, commit, repo_name)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
Reference in new issue
Block a user