ДОМЕНЫ - ВОПРОСЫ - СКЛАД - Починить selected-object follow-up по складу и включить разговорные/UI-варианты в обязательный domain-loop

This commit is contained in:
2026-04-14 14:18:38 +03:00
parent 9048632d3e
commit d41819eabd
67 changed files with 3800 additions and 195 deletions
+51 -1
View File
@@ -167,6 +167,48 @@ def merge_analysis_context(base_context: Any, override_context: Any) -> dict[str
return merged
def carry_forward_analysis_context(
scenario_state: dict[str, Any],
analysis_context: dict[str, Any],
) -> dict[str, Any]:
carried = dict(analysis_context)
semantic_memory = scenario_state.get("semantic_memory")
if isinstance(semantic_memory, dict):
date_scope = semantic_memory.get("date_scope")
if isinstance(date_scope, dict):
carried_as_of_date = normalize_iso_date(date_scope.get("as_of_date"))
if carried_as_of_date and not carried.get("as_of_date"):
carried["as_of_date"] = carried_as_of_date
if not carried.get("source"):
carried["source"] = "scenario_state_carryover"
return carried
def merge_scenario_date_scope(
previous_date_scope: Any,
current_date_scope: Any,
*,
depends_on: list[str],
) -> Any:
previous = previous_date_scope if isinstance(previous_date_scope, dict) else None
current = current_date_scope if isinstance(current_date_scope, dict) else None
if not current:
return previous or current_date_scope
if not depends_on or not previous:
return current
previous_as_of_date = normalize_iso_date(previous.get("as_of_date"))
current_as_of_date = normalize_iso_date(current.get("as_of_date"))
if previous_as_of_date and current_as_of_date and current_as_of_date != previous_as_of_date:
merged = dict(current)
merged["as_of_date"] = previous_as_of_date
if not merged.get("source"):
merged["source"] = "scenario_state_carryover"
return merged
return current
def repair_text_mojibake(value: str) -> str:
if not value:
return value
@@ -1219,6 +1261,7 @@ def execute_scenario_manifest(
for step_index, step in enumerate(manifest["steps"], start=1):
step_dir = steps_dir / step["step_id"]
step_analysis_context = merge_analysis_context(manifest.get("analysis_context"), step.get("analysis_context"))
step_analysis_context = carry_forward_analysis_context(scenario_state, step_analysis_context)
try:
resolved_question = resolve_question_template(step["question_template"], scenario_state)
result = run_assistant_step(
@@ -1273,12 +1316,19 @@ def execute_scenario_manifest(
scenario_state["session_id"] = result["session_id"]
scenario_state["step_outputs"][step["step_id"]] = result["step_state"]
previous_semantic_memory = scenario_state.get("semantic_memory") or {}
previous_date_scope = previous_semantic_memory.get("date_scope") if isinstance(previous_semantic_memory, dict) else None
current_date_scope = result["step_state"].get("date_scope")
scenario_state["semantic_memory"] = {
"latest_step_id": step["step_id"],
"latest_step_status": result["step_state"].get("status"),
"active_result_set_id": result["step_state"].get("active_result_set_id"),
"last_confirmed_route": result["step_state"].get("last_confirmed_route"),
"date_scope": result["step_state"].get("date_scope"),
"date_scope": merge_scenario_date_scope(
previous_date_scope,
current_date_scope,
depends_on=step.get("depends_on") or [],
),
"organization_scope": result["step_state"].get("organization_scope"),
"entries": result["step_state"].get("entries"),
}