This commit is contained in:
2026-04-25 17:22:41 +03:30
parent 569d520a5c
commit aa24fc22b0
124 changed files with 8491 additions and 2582 deletions
+88 -3
View File
@@ -54,6 +54,62 @@ def _find_section(sections: list[dict], section_type: str) -> dict | None:
return None
def _field_sources(llm_section: dict, fallback_section: dict, merged_section: dict) -> dict[str, str]:
sources: dict[str, str] = {}
for key, value in merged_section.items():
if key == "provenance":
continue
llm_value = llm_section.get(key)
fallback_value = fallback_section.get(key)
if key in llm_section and value == llm_value and value != fallback_value:
sources[key] = "llm"
elif key in fallback_section and value == fallback_value and value != llm_value:
sources[key] = "fallback"
elif key in llm_section and key in fallback_section and llm_value == fallback_value == value:
sources[key] = "shared"
elif key in llm_section and key in fallback_section:
sources[key] = "merged"
else:
sources[key] = "fallback" if key in fallback_section else "llm"
return sources
def _attach_provenance(section_type: str, llm_section: dict, fallback_section: dict, merged_section: dict) -> dict:
merged = dict(merged_section)
field_sources = _field_sources(llm_section, fallback_section, merged)
merged["provenance"] = {
"sectionType": section_type,
"llmProvided": bool(llm_section),
"fallbackUsed": any(source != "llm" for source in field_sources.values()),
"fieldSources": field_sources,
}
return merged
def _fallback_with_provenance(fallback: dict, reason: str) -> dict:
sections = []
for section in fallback.get("sections", []):
section_with_provenance = dict(section)
section_with_provenance["provenance"] = {
"sectionType": section.get("type"),
"llmProvided": False,
"fallbackUsed": True,
"fieldSources": {
key: "fallback"
for key in section.keys()
if key != "provenance"
},
}
sections.append(section_with_provenance)
return {
"sections": sections,
"mergeMetadata": {
"source": "fallback_only",
"reason": reason,
},
}
def _build_fertilization_fallback(*, optimized_result: dict | None) -> dict:
if optimized_result:
recommended = optimized_result["recommended_strategy"]
@@ -134,11 +190,11 @@ def _merge_fertilization_response(
) -> dict:
fallback = _build_fertilization_fallback(optimized_result=optimized_result)
if not isinstance(parsed_result, dict):
return fallback
return _fallback_with_provenance(fallback, "invalid_llm_payload")
sections = parsed_result.get("sections")
if not isinstance(sections, list):
return fallback
return _fallback_with_provenance(fallback, "missing_sections")
recommendation = _find_section(sections, "recommendation") or {}
list_section = _find_section(sections, "list") or {}
@@ -169,7 +225,36 @@ def _merge_fertilization_response(
"content": warning_section.get("content") or fallback_warning["content"],
}
return {"sections": [merged_recommendation, merged_list, merged_warning]}
merged_recommendation = _attach_provenance(
"recommendation",
recommendation,
fallback_recommendation,
merged_recommendation,
)
merged_list = _attach_provenance(
"list",
list_section,
fallback_list,
merged_list,
)
merged_warning = _attach_provenance(
"warning",
warning_section,
fallback_warning,
merged_warning,
)
return {
"sections": [merged_recommendation, merged_list, merged_warning],
"mergeMetadata": {
"source": "llm_with_fallback_merge",
"llmSectionsDetected": [section.get("type") for section in sections if isinstance(section, dict)],
"fallbackSectionsApplied": [
item["type"]
for item in (fallback_recommendation, fallback_list, fallback_warning)
],
},
}
def get_fertilization_recommendation(