"""CLI pour générer une visualisation de sous-graphe JDM en HTML. Usage:: python -m jdm_agent.apps.viz_cli "plat asiatique" python -m jdm_agent.apps.viz_cli polyphonie --depth 2 --top-k 8 python -m jdm_agent.apps.viz_cli chat --relations r_isa,r_has_part,r_carac \ --output-path chat.html Aucun LLM impliqué — seulement le client JDM + la couche viz. """ from __future__ import annotations import argparse import sys import webbrowser from pathlib import Path from jdm_agent.client import JDMClient from jdm_agent.viz import ( DEFAULT_DEPTH2_RELATIONS, DEFAULT_DEPTH3_RELATIONS, DEFAULT_DEPTH4_RELATIONS, DEFAULT_RELATIONS, build_subgraph, ) def _csv(value: str | None) -> list[str] | None: if not value: return None return [s.strip() for s in value.split(",") if s.strip()] def main(argv: list[str] | None = None) -> int: p = argparse.ArgumentParser( description="Construit un sous-graphe JDM autour d'un terme (HTML interactif).", ) p.add_argument("term", help="terme racine (ex. \"plat asiatique\", \"polyphonie\")") p.add_argument("--depth", type=int, default=1, help="profondeur (1 à 4 ; défaut = 1)") p.add_argument("--top-k", type=int, default=3, help="top-K niveau 1 (défaut = 3) — applique aussi aux niveaux 2..4 si non précisés") p.add_argument("--top-k-depth2", type=int, default=None, help="top-K niveau 2 (défaut = même que --top-k)") p.add_argument("--top-k-depth3", type=int, default=None, help="top-K niveau 3 (défaut = même que --top-k)") p.add_argument("--top-k-depth4", type=int, default=None, help="top-K niveau 4 (défaut = même que --top-k)") p.add_argument("--min-weight", type=float, default=None, help="poids minimum (défaut : aucun, JDM décide)") p.add_argument("--relations", type=str, default=None, help="liste CSV de relations (défaut = jeu standard : " + ",".join(DEFAULT_RELATIONS) + ")") p.add_argument("--depth2-relations", type=str, default=None, help="liste CSV pour la profondeur 2 (défaut : " + ",".join(DEFAULT_DEPTH2_RELATIONS) + ")") p.add_argument("--depth3-relations", type=str, default=None, help="liste CSV pour la profondeur 3 (défaut : " + ",".join(DEFAULT_DEPTH3_RELATIONS) + ")") p.add_argument("--depth4-relations", type=str, default=None, help="liste CSV pour la profondeur 4 (défaut : " + ",".join(DEFAULT_DEPTH4_RELATIONS) + ")") p.add_argument("--output-path", type=str, default=None, help="fichier HTML de sortie (défaut = _subgraph.html)") p.add_argument("--no-open", action="store_true", help="ne pas ouvrir le fichier dans le navigateur à la fin") args = p.parse_args(argv) client = JDMClient() res = build_subgraph( args.term, client=client, depth=args.depth, top_k_per_relation=args.top_k, min_weight=args.min_weight, relations=_csv(args.relations), depth2_relations=_csv(args.depth2_relations), depth3_relations=_csv(args.depth3_relations), depth4_relations=_csv(args.depth4_relations), top_k_depth2=args.top_k_depth2, top_k_depth3=args.top_k_depth3, top_k_depth4=args.top_k_depth4, output="html", output_path=args.output_path, ) stats = res["stats"] path = res["html_path"] # ASCII only pour compat console Windows cp1252. print(f"[OK] {stats['n_nodes']} nodes, {stats['n_edges']} edges, " f"{stats['n_negative']} negations (depth={stats['depth']})") print(f" -> {path}") if not args.no_open: webbrowser.open(Path(path).as_uri()) return 0 if __name__ == "__main__": raise SystemExit(main(sys.argv[1:]))