@@ -54,6 +54,7 @@ const REMEMBER_TOOL_NAME: &str = "omc_proxy_remember";
5454const RECALL_TOOL_NAME : & str = "omc_proxy_recall" ;
5555const LIST_REFS_TOOL_NAME : & str = "omc_proxy_list_refs" ;
5656const 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
494502fn 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+
611641fn 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