From c04dc589f4249a271ab5a8d6f6dea02cfdd5112d Mon Sep 17 00:00:00 2001 From: Alex-Gilbert Date: Wed, 18 Feb 2026 12:01:53 -0600 Subject: [PATCH] feat: wire dictionary full-name solver into solve endpoint Co-Authored-By: Claude Opus 4.6 --- unredact/app.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/unredact/app.py b/unredact/app.py index 12ac774..0fcf7da 100644 --- a/unredact/app.py +++ b/unredact/app.py @@ -21,7 +21,7 @@ from unredact.pipeline.font_detect import CANDIDATE_FONTS, _find_font_path from unredact.pipeline.analyze_page import analyze_page from unredact.pipeline.detect_redactions import spot_redaction from unredact.pipeline.solver import build_constraint, SolveResult -from unredact.pipeline.dictionary import DictionaryStore, solve_dictionary +from unredact.pipeline.dictionary import DictionaryStore, solve_dictionary, solve_full_name_dictionary from unredact.pipeline.word_filter import _get_emails from unredact.pipeline.width_table import build_width_table, CHARSETS @@ -363,6 +363,27 @@ async def solve(req: SolveRequest): "source": "emails", }) + # Full-name dictionary solve (associate names) + if use_full_name and not _active_solves.get(solve_id): + fn_results = solve_full_name_dictionary( + font, req.gap_width_px, req.tolerance_px, + req.left_context, req.right_context, + uppercase_only=(charset_name == "full_name_caps"), + ) + for r in fn_results: + if _active_solves.get(solve_id): + break + if r.text in found_texts: + continue + found_texts.add(r.text) + yield json.dumps({ + "status": "match", + "text": r.text, + "width_px": round(r.width, 2), + "error_px": round(r.error, 2), + "source": "names", + }) + if req.mode in ("enumerate", "both") and not _active_solves.get(solve_id): # Build payload and call Rust solver (streaming SSE) if use_full_name: