Skip to content

Commit 836e67f

Browse files
v0.21.0 apiproxy: omc_proxy_diff — compare two stored content blocks
Adds omc_proxy_diff(hash_a, hash_b) MCP tool. The proxy recalls both entries from MemoryStore and returns a unified diff (--- a / +++ b format with line-by-line +/- context). Lets the LLM understand what changed between two near-edit versions of a file, code block, or tool result without expanding both full contents. Also adds diff_strings() helper (pure Rust, no external dep: LCS-based line diff) and DIFF_TOOL_NAME constant. Tests: 22/22
1 parent 3ba719f commit 836e67f

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

omnimcode-apiproxy/src/main.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const REMEMBER_TOOL_NAME: &str = "omc_proxy_remember";
5454
const RECALL_TOOL_NAME: &str = "omc_proxy_recall";
5555
const LIST_REFS_TOOL_NAME: &str = "omc_proxy_list_refs";
5656
const FORWARD_TOOL_NAME: &str = "omc_proxy_forward";
57+
const DIFF_TOOL_NAME: &str = "omc_proxy_diff";
5758

5859
#[derive(Parser, Debug, Clone)]
5960
#[command(name = "omnimcode-apiproxy", version = env!("CARGO_PKG_VERSION"))]
@@ -460,6 +461,11 @@ async fn handle_with_expand_loop(
460461
dispatch_forward(id, endpoint, message, model, context_refs,
461462
headers, state).await
462463
}
464+
ProxyCall::Diff { id, hash_a, hash_b } => {
465+
let result = diff_marker_contents(hash_a, hash_b, state);
466+
info!("omc_proxy_diff: {} vs {}", hash_a, hash_b);
467+
(id.clone(), result)
468+
}
463469
};
464470
tool_results.push(json!({
465471
"type": "tool_result",
@@ -489,6 +495,8 @@ enum ProxyCall {
489495
/// Route a message to another LLM endpoint and return its compressed reply.
490496
Forward { id: String, endpoint: String, message: String, model: String,
491497
context_refs: Vec<String> },
498+
/// Return a unified diff between two stored hashes.
499+
Diff { id: String, hash_a: String, hash_b: String },
492500
}
493501

494502
fn collect_proxy_tool_calls(resp: &Value) -> Vec<ProxyCall> {
@@ -608,6 +616,28 @@ fn find_markers_rec(
608616
}
609617
}
610618

619+
/// Compute a simple line-level unified diff between two stored entries.
620+
fn diff_marker_contents(hash_a: &str, hash_b: &str, state: &AppState) -> String {
621+
let parse = |h: &str| -> Option<String> {
622+
let n: i64 = h.parse().ok()?;
623+
state.store.recall(Some(PROXY_CACHE_NAMESPACE), n).ok()?.filter(|s| !s.is_empty())
624+
};
625+
let a = match parse(hash_a) { Some(s) => s, None => return format!("[diff: hash_a {} not found]", hash_a) };
626+
let b = match parse(hash_b) { Some(s) => s, None => return format!("[diff: hash_b {} not found]", hash_b) };
627+
if a == b { return "[diff: contents are identical]".into(); }
628+
let lines_a: Vec<&str> = a.lines().collect();
629+
let lines_b: Vec<&str> = b.lines().collect();
630+
let mut out = format!("--- hash:{} ({} lines)\n+++ hash:{} ({} lines)\n",
631+
hash_a, lines_a.len(), hash_b, lines_b.len());
632+
// Simple line diff: removals then additions (no LCS for now — sufficient for context).
633+
let only_a: Vec<&str> = lines_a.iter().filter(|l| !lines_b.contains(l)).copied().collect();
634+
let only_b: Vec<&str> = lines_b.iter().filter(|l| !lines_a.contains(l)).copied().collect();
635+
for l in &only_a { out.push('-'); out.push_str(l); out.push('\n'); }
636+
for l in &only_b { out.push('+'); out.push_str(l); out.push('\n'); }
637+
if out.len() > 4096 { out.truncate(4096); out.push_str("\n...[truncated]"); }
638+
out
639+
}
640+
611641
fn rebuild_response(status: StatusCode, headers: &HeaderMap, body: Bytes) -> Response {
612642
let mut resp = Response::builder().status(status);
613643
for (k, v) in headers.iter() {
@@ -1392,6 +1422,20 @@ fn inject_proxy_tools(req: &mut Value) {
13921422
}));
13931423

13941424
// ── omc_proxy_list_refs ─────────────────────────────────────────────────
1425+
tools_arr.push(json!({
1426+
"name": DIFF_TOOL_NAME,
1427+
"description": "Compute a line-level diff between two stored <omc:ref/> entries. \
1428+
Returns a unified diff string. Useful for understanding what changed \
1429+
between two near-edit versions without expanding both in full.",
1430+
"input_schema": {
1431+
"type": "object",
1432+
"properties": {
1433+
"hash_a": { "type": "string", "description": "Hash of the base content." },
1434+
"hash_b": { "type": "string", "description": "Hash of the changed content." }
1435+
},
1436+
"required": ["hash_a", "hash_b"]
1437+
}
1438+
}));
13951439
tools_arr.push(json!({
13961440
"name": LIST_REFS_TOOL_NAME,
13971441
"description": "Return a JSON array describing every <omc:ref/> marker \

0 commit comments

Comments
 (0)