hemant2747/multi-agent-framework
0
1"""Line-level diff for rendering accept/reject cards in the UI."""2from __future__ import annotations3 4import difflib5from typing import Dict, List6 7 8def line_diff(original: str, modified: str) -> List[Dict]:9 """Return rows: {type: 'ctx'|'add'|'del', text, old, new}.10 11 'old'/'new' are 1-based line numbers (or None when not applicable).12 """13 a = original.splitlines()14 b = modified.splitlines()15 sm = difflib.SequenceMatcher(a=a, b=b)16 rows: List[Dict] = []17 oi = ni = 118 for tag, i1, i2, j1, j2 in sm.get_opcodes():19 if tag == "equal":20 for k in range(i1, i2):21 rows.append({"type": "ctx", "text": a[k], "old": oi, "new": ni})22 oi += 123 ni += 124 elif tag == "delete":25 for k in range(i1, i2):26 rows.append({"type": "del", "text": a[k], "old": oi, "new": None})27 oi += 128 elif tag == "insert":29 for k in range(j1, j2):30 rows.append({"type": "add", "text": b[k], "old": None, "new": ni})31 ni += 132 elif tag == "replace":33 for k in range(i1, i2):34 rows.append({"type": "del", "text": a[k], "old": oi, "new": None})35 oi += 136 for k in range(j1, j2):37 rows.append({"type": "add", "text": b[k], "old": None, "new": ni})38 ni += 139 return rows40 41 42def diff_stats(rows: List[Dict]) -> Dict[str, int]:43 return {44 "additions": sum(1 for r in rows if r["type"] == "add"),45 "deletions": sum(1 for r in rows if r["type"] == "del"),46 }47 