Problem Statement
@asclearuc's review on #1584 flagged several near-duplicate helpers across the DB/graph nodes that have already drifted:
Proposed Solution
Extract the genuinely engine-agnostic helpers — _sanitize_value, _formatResultAsMarkdown, and the build-loop control flow — into ai.common.utils, and consume them from db_instance_base, db_arango, db_neo4j, and graph_instance_base. Keep the engine-specific driver-level serialisers local (they legitimately differ per engine). Do this as a dedicated refactor pass, not smuggled into a feature PR.
Alternatives Considered
Leave the copies as-is — rejected: they have already diverged silently and will keep doing so as each node evolves.
Affected Modules
DRY follow-up to #1584. Lower priority than the correctness port (companion bug issue).
Problem Statement
@asclearuc's review on #1584 flagged several near-duplicate helpers across the DB/graph nodes that have already drifted:
_sanitize_value/_sanitize_rowexist indb_instance_baseandgraph_instance_basewith divergent behaviour (Decimal→1.5vs'1.50'before feat(nodes, ai): add graph base class; make FalkorDB a real graph node #1584 aligned the graph copy)._formatResultAsMarkdownhas ~5 near-verbatim copies (db_instance_base,db_arango,db_neo4j,graph_instance_base) with silent per-copy differences (e.g. a missing(headers, rows)tuple branch)._buildQuery/_buildSQLQueryretry loop is duplicated — and the graph fix is not in the SQL one (see the companion bug issue).parse_is_validwas removed in feat(nodes, ai): add graph base class; make FalkorDB a real graph node #1584, but the SQL base still carries a third.lower() == 'true'variant of the same idea.Proposed Solution
Extract the genuinely engine-agnostic helpers —
_sanitize_value,_formatResultAsMarkdown, and the build-loop control flow — intoai.common.utils, and consume them fromdb_instance_base,db_arango,db_neo4j, andgraph_instance_base. Keep the engine-specific driver-level serialisers local (they legitimately differ per engine). Do this as a dedicated refactor pass, not smuggled into a feature PR.Alternatives Considered
Leave the copies as-is — rejected: they have already diverged silently and will keep doing so as each node evolves.
Affected Modules
DRY follow-up to #1584. Lower priority than the correctness port (companion bug issue).