diff --git a/backend/app/services/ai_tree_builder.py b/backend/app/services/ai_tree_builder.py index c9f44c4b..6cfb50d2 100644 --- a/backend/app/services/ai_tree_builder.py +++ b/backend/app/services/ai_tree_builder.py @@ -45,7 +45,19 @@ No prose, no markdown fences. """ +def _strip_meta(walked_path: list[dict]) -> list[dict]: + """Drop the hidden ``meta`` entry (category carrier) the intake endpoint seeds. + + The first walked_path entry on an ai_build session may be a + ``{"node_type": "meta", "category": ...}`` marker used to persist the + classified category; it is not a real walk step and must be excluded from + both model context and tree normalization. + """ + return [s for s in walked_path if s.get("node_type") != "meta"] + + def _build_context(problem_text: str, category: str, walked_path: list[dict]) -> str: + walked_path = _strip_meta(walked_path) lines = [f"PROBLEM: {problem_text}", f"CATEGORY: {category}", "STEPS SO FAR:"] if not walked_path: lines.append("(none yet — produce the first diagnostic question)") @@ -116,6 +128,7 @@ def normalize_walked_path(walked_path: list[dict]) -> dict[str, Any]: Returns {id, nodes: {id: node}} — a dict with an id (passes the proposal approval guard). """ + walked_path = _strip_meta(walked_path) nodes: dict[str, Any] = {} if not walked_path: root_id = "root"