"""Adaptive RAG answer mainline orchestration helpers.""" from __future__ import annotations from .shared import * from .internal_query_context import InternalContextPacket, internal_context_block_reason class AdaptiveRAGAnswerMainlineMixin: @staticmethod def _mirror_internal_context_to_query_semantics( *, query_semantics: Optional[dict[str, Any]], operation_contract: Optional[dict[str, Any]] = None, target_resolution: Optional[dict[str, Any]] = None, query_plan: Optional[dict[str, Any]] = None, ) -> dict[str, Any]: mirrored = dict(query_semantics or {}) if isinstance(query_semantics, dict) else {} if isinstance(operation_contract, dict): mirrored["operation_contract"] = dict(operation_contract) if isinstance(target_resolution, dict): mirrored["target_resolution"] = dict(target_resolution) if isinstance(query_plan, dict): mirrored["query_plan"] = dict(query_plan) return mirrored @staticmethod def _normalize_runtime_consultant_mode_preference(value: Optional[str]) -> Optional[str]: text = str(value or "").strip().lower() if text in {"clarify", "advise", "challenge", "brainstorm", "execute"}: return text return None @staticmethod def _internal_answer_contract_for_query_type(query_type: str) -> str: normalized = str(query_type or QUERY_TYPE_UNKNOWN).strip().lower() if normalized == QUERY_TYPE_EXISTENCE: return "yes_no_with_evidence" if normalized == QUERY_TYPE_COUNT: return "count_scalar" if normalized == QUERY_TYPE_LIST: return "entity_list" if normalized == QUERY_TYPE_STATUS: return "entity_snapshot" if normalized == QUERY_TYPE_EXPLAIN: return "explanation_with_citations" if normalized == QUERY_TYPE_DIAGNOSE: return "diagnosis_with_evidence" if normalized == QUERY_TYPE_COMPARE: return "comparison_with_basis" return "clarify_or_fail" @staticmethod def _has_resolved_followup_rewrite(rewrite_meta: Optional[dict[str, Any]]) -> bool: if not isinstance(rewrite_meta, dict): return False mode = str(rewrite_meta.get("mode") or "").strip().lower() return mode in { "state_subject", "state_entities", "followup_anchor_recent_reply", "followup_anchor_meta", } @staticmethod def _mirror_followup_state_to_query_semantics( *, query_semantics: Optional[dict[str, Any]], session_state: Optional[QASessionState], rewrite_meta: Optional[dict[str, Any]], ) -> dict[str, Any]: semantics = dict(query_semantics or {}) if isinstance(query_semantics, dict) else {} if not isinstance(rewrite_meta, dict): return semantics rewrite_mode = str(rewrite_meta.get("mode") or "").strip().lower() if rewrite_mode not in {"state_subject", "state_entities"}: return semantics entity_ids: list[int] = [] if isinstance(getattr(session_state, "last_entity_ids", None), list): for value in list(getattr(session_state, "last_entity_ids", None) or []): try: entity_ids.append(int(value)) except Exception: continue payload = { "rewrite_mode": rewrite_mode, "last_subject": str(getattr(session_state, "last_subject", "") or "").strip() or None, "last_entity_ids": entity_ids[:6], } semantics["session_followup_context"] = payload return semantics @staticmethod def _internal_entity_type_for_subject_focus(subject_focus: str) -> str: normalized = str(subject_focus or "").strip().lower() if normalized == "people": return "user" if normalized in {"project", "task", "signal", "feature"}: return normalized return "unknown" def _build_internal_query_plan( self, *, question: str, project_id: Optional[int], query_semantics: Optional[dict[str, Any]], operation_contract: Optional[dict[str, Any]] = None, target_resolution: Optional[dict[str, Any]] = None, ) -> Optional[dict[str, Any]]: semantics = query_semantics if isinstance(query_semantics, dict) else {} operation = operation_contract if isinstance(operation_contract, dict) else ( semantics.get("operation_contract") if isinstance(semantics.get("operation_contract"), dict) else {} ) target = target_resolution if isinstance(target_resolution, dict) else ( semantics.get("target_resolution") if isinstance(semantics.get("target_resolution"), dict) else {} ) source_policy = str( semantics.get("effective_source_policy") or semantics.get("source_policy") or "" ).strip().lower() if source_policy != "internal": return None query_type = str( operation.get("query_type") or semantics.get("query_type") or QUERY_TYPE_UNKNOWN ).strip().lower() or QUERY_TYPE_UNKNOWN subject_focus = self._query_subject_focus(semantics) if hasattr(self, "_query_subject_focus") else "unknown" entity_type = str( target.get("target_entity_type") or self._internal_entity_type_for_subject_focus(subject_focus) ).strip().lower() or "unknown" scope_hint = self._query_scope_hint(semantics) if hasattr(self, "_query_scope_hint") else "none" target_ref = str(target.get("target_ref") or "").strip() or None filters: list[dict[str, Any]] = [] if entity_type == "project" and target_ref and target_ref.startswith("project:"): try: resolved_project_id = int(target_ref.split(":", 1)[1]) except Exception: resolved_project_id = None if resolved_project_id is not None: filters.append( { "field": "project_id", "operator": "equals", "value": resolved_project_id, "value_source": "target_resolution", } ) elif entity_type == "project": mention_collector = getattr(self, "_collect_lookup_terms", None) if callable(mention_collector): operation_mentions = mention_collector( question=question, query_semantics=semantics, operation_contract=operation, target_resolution=target, limit=3, ) else: operation_mentions = [ str(item or "").strip() for item in list(operation.get("object_mentions") or []) if str(item or "").strip() ] if operation_mentions: for raw in operation_mentions[:3]: filters.append( { "field": "semantic_label", "operator": "equals_or_alias", "value": raw, "value_source": "operation_contract", } ) elif entity_type == "feature" and target_ref: filters.append( { "field": "feature_ref", "operator": "equals", "value": target_ref, "value_source": "target_resolution", } ) elif entity_type == "config" and target_ref: filters.append( { "field": "config_ref", "operator": "equals", "value": target_ref, "value_source": "target_resolution", } ) return { "plan_version": "v2" if operation or target else "v1", "query_type": query_type, "entity_type": entity_type, "answer_contract": self._internal_answer_contract_for_query_type(query_type), "target_ref": target_ref, "filters": filters, "scope": { "tenant_bound": True, "project_id": int(project_id) if project_id is not None else None, "scope_hint": scope_hint, }, "retrieval_policy": { "facts_first": True, "allow_fallback_text": True, }, "verifier_checks": [ "contract_matches_query_type", "evidence_backed", ], } def _build_internal_query_context_packet( self, *, question: str, project_id: Optional[int], session_id: Optional[int], conversation_scope_key: Optional[str], reply_to_message_id: Optional[str], root_message_id: Optional[str], route_decision: Optional[dict[str, Any]], operation_contract: Optional[dict[str, Any]], target_resolution: Optional[dict[str, Any]], query_plan: Optional[dict[str, Any]], ) -> InternalContextPacket | None: normalize_route_decision = getattr(self, "_normalize_query_route_decision", None) normalized_route = ( normalize_route_decision(route_decision) if callable(normalize_route_decision) else (dict(route_decision or {}) if isinstance(route_decision, dict) else {}) ) if str(normalized_route.get("effective_source_policy") or "").strip().lower() != "internal": return None return InternalContextPacket.model_validate( { "packet_version": "v1", "question": str(question or "").strip(), "scope": { "tenant_id": int(getattr(self, "tenant_id", 0) or 0), "project_id": int(project_id) if project_id is not None else None, "session_id": int(session_id) if session_id is not None else None, "conversation_scope_key": str(conversation_scope_key or "").strip() or None, "reply_to_message_id": str(reply_to_message_id or "").strip() or None, "root_message_id": str(root_message_id or "").strip() or None, }, "route_decision": dict(normalized_route), "operation_contract": dict(operation_contract or {}) if isinstance(operation_contract, dict) else {}, "target_resolution": dict(target_resolution or {}) if isinstance(target_resolution, dict) else {}, "query_plan": dict(query_plan or {}) if isinstance(query_plan, dict) else {}, "executor_summary": {}, "verifier_summary": {}, "uncertainties": [], } ) async def _maybe_return_internal_context_precheck_response( self, *, question: str, effective_question: str, asked_by: Optional[int], asked_via: str, project_id: Optional[int], session_id: Optional[int], context_session_id: Optional[int], turn_index: int, state_row: Optional[QASessionState], rewrite_meta: Optional[dict[str, Any]], thinking_mode: str, query_type: str, route_decision: Optional[dict[str, Any]], query_semantics: Optional[dict[str, Any]], internal_context_packet: Any, ) -> Optional[dict[str, Any]]: packet_block = internal_context_block_reason( internal_context_packet, route_decision=route_decision, ) if packet_block is None: return None reason_code, missing_fields = packet_block guard_builder = getattr(self, "_build_internal_answer_contract_guard_payload", None) if not callable(guard_builder): return None guard_payload = guard_builder( query_type=query_type, reason_code=reason_code, missing_fields=list(missing_fields or []), ) persist_fast_answer = getattr(self, "_persist_fast_answer", None) if callable(persist_fast_answer): return await persist_fast_answer( question=question, asked_by=asked_by, asked_via=asked_via, project_id=project_id, fast_result={ "answer": str(guard_payload.get("answer") or "").strip(), "sources": list(guard_payload.get("sources") or []), "missing_fields": list(guard_payload.get("missing_fields") or []), "reason_code": str(guard_payload.get("reason_code") or "").strip() or reason_code, "query_type": str(query_type or QUERY_TYPE_UNKNOWN).strip() or QUERY_TYPE_UNKNOWN, "confidence": 0.0, "db_query_ms": 0, "response_time_ms": 0, "prompt_variant_id": "internal_context_guard", }, session_id=session_id, external_session_id=context_session_id, turn_index=turn_index, query_type=query_type, missing_fields=list(guard_payload.get("missing_fields") or []), state_row=state_row, effective_question=effective_question, rewrite_meta=rewrite_meta or {}, thinking_mode=thinking_mode, answer_mode=str(guard_payload.get("answer_mode") or ANSWER_MODE_CLARIFY), route_decision=route_decision, query_semantics=query_semantics, internal_context_packet=internal_context_packet, ) return dict(guard_payload or {}) @classmethod def _extract_prompt_variant_from_policy_version(cls, policy_version: Optional[str]) -> Optional[str]: raw = str(policy_version or "").strip() if not raw: return None for part in raw.split("|"): normalized = str(part or "").strip() if not normalized.startswith("prompt:"): continue value = normalized.split(":", 1)[1].strip().lower() return value or None return None async def _resolve_anchor_prompt_variant( self, *, anchor_resolution: Optional[FollowupAnchorResolution], conversation_scope_key: Optional[str], ) -> Optional[str]: resolver = getattr(self, "_resolve_anchor_qa_record", None) if not callable(resolver): return None try: anchor_row = await resolver( anchor_resolution=anchor_resolution, conversation_scope_key=conversation_scope_key, ) except Exception: return None if anchor_row is None: return None return self._extract_prompt_variant_from_policy_version(getattr(anchor_row, "policy_version", None)) def _apply_chat_external_fact_scene_policy( self, *, question: str, project_id: Optional[int], scene_semantics: Optional[dict[str, Any]], anchor_prompt_variant: Optional[str] = None, ) -> dict[str, Any]: _ = question normalized = dict(scene_semantics or {}) scene_key = str(normalized.get("scene_key") or "default").strip().lower() or "default" anchor_variant = str(anchor_prompt_variant or "").strip().lower() if scene_key in {"ai_pmo", "ai_pmo_correction"} and anchor_variant in {"external_trend", "industry_trend"}: scene_key = anchor_variant normalized["snapshot_focus"] = "none" normalized["deep_intent"] = "none" if scene_key == "external_trend" and project_id is None: scene_key = "industry_trend" if scene_key in {"external_trend", "industry_trend"}: normalized["external_fact_chat"] = True normalized["scene_key"] = scene_key return normalized def _plan_query_runtime( self, *, question: str, effective_question: str, query_type: str, scene_semantics: Optional[dict[str, Any]] = None, requested_thinking_mode: str, enforce_scene_prompt_only: bool, consultant_mode_preference: Optional[str] = None, ) -> QueryPlannerDecision: normalize_thinking_mode = getattr( self, "_normalize_thinking_mode", lambda value: THINKING_MODE_DEEP if str(value or "").strip().lower() == THINKING_MODE_DEEP else THINKING_MODE_NORMAL, ) normalized_thinking_mode = normalize_thinking_mode(requested_thinking_mode) normalized_query_type = str(query_type or QUERY_TYPE_UNKNOWN).strip().lower() normalized_consultant_mode = self._normalize_runtime_consultant_mode_preference( consultant_mode_preference ) fast_path_candidate = normalized_query_type in { QUERY_TYPE_EXISTENCE, QUERY_TYPE_COUNT, QUERY_TYPE_LIST, QUERY_TYPE_STATUS, } normalized_question = str(question or "").strip() normalized_effective = str(effective_question or "").strip() normalized_scene_semantics = scene_semantics if isinstance(scene_semantics, dict) else {} deep_intent = str(normalized_scene_semantics.get("deep_intent") or "none").strip().lower() force_deep_by_semantics = deep_intent in { "correction_turn", "correction_escalation", "engine_process_query", "runtime_state_query", } if enforce_scene_prompt_only: retrieval_mode = ANSWER_MODE_RETRIEVAL_DEEP if normalized_thinking_mode == THINKING_MODE_DEEP else ANSWER_MODE_RETRIEVAL_NORMAL return QueryPlannerDecision( answer_mode=retrieval_mode, thinking_mode=THINKING_MODE_DEEP if retrieval_mode == ANSWER_MODE_RETRIEVAL_DEEP else THINKING_MODE_NORMAL, allow_fast_path=False, retrieval_answer_mode=retrieval_mode, budget=RetrievalBudget( max_steps=DEEP_RETRIEVAL_STEPS if retrieval_mode == ANSWER_MODE_RETRIEVAL_DEEP else AGENT_MAX_RETRIEVAL_STEPS, vector_top_k=DEEP_VECTOR_TOP_K if retrieval_mode == ANSWER_MODE_RETRIEVAL_DEEP else DEFAULT_TOP_K, ), reason="scene_prompt_only", ) if fast_path_candidate and not force_deep_by_semantics: if normalized_consultant_mode: return QueryPlannerDecision( answer_mode=ANSWER_MODE_RETRIEVAL_NORMAL, thinking_mode=THINKING_MODE_NORMAL, allow_fast_path=False, retrieval_answer_mode=ANSWER_MODE_RETRIEVAL_NORMAL, budget=RetrievalBudget(max_steps=AGENT_MAX_RETRIEVAL_STEPS, vector_top_k=DEFAULT_TOP_K), reason=f"consultant_mode:{normalized_consultant_mode}", ) return QueryPlannerDecision( answer_mode=ANSWER_MODE_FAST_PATH, thinking_mode=THINKING_MODE_NORMAL, allow_fast_path=True, retrieval_answer_mode=ANSWER_MODE_RETRIEVAL_NORMAL, budget=RetrievalBudget(max_steps=AGENT_MAX_RETRIEVAL_STEPS, vector_top_k=DEFAULT_TOP_K), reason="deterministic_query_type", ) retrieval_mode = ANSWER_MODE_RETRIEVAL_DEEP if (normalized_thinking_mode == THINKING_MODE_DEEP or force_deep_by_semantics) else ANSWER_MODE_RETRIEVAL_NORMAL return QueryPlannerDecision( answer_mode=retrieval_mode, thinking_mode=THINKING_MODE_DEEP if retrieval_mode == ANSWER_MODE_RETRIEVAL_DEEP else THINKING_MODE_NORMAL, allow_fast_path=False, retrieval_answer_mode=retrieval_mode, budget=RetrievalBudget( max_steps=DEEP_RETRIEVAL_STEPS if retrieval_mode == ANSWER_MODE_RETRIEVAL_DEEP else AGENT_MAX_RETRIEVAL_STEPS, vector_top_k=DEEP_VECTOR_TOP_K if retrieval_mode == ANSWER_MODE_RETRIEVAL_DEEP else DEFAULT_TOP_K, ), reason="requested_thinking_mode" if retrieval_mode == ANSWER_MODE_RETRIEVAL_DEEP else "default_retrieval", ) async def _prepare_answer_runtime( self, *, clean_q: str, asked_by: Optional[int], asked_via: str, project_id: Optional[int], source_chat_id: Optional[str], session_id: Optional[int], conversation_key: Optional[str], force_new_session: bool, action_mode: str, source_message_id: Optional[str] = None, source_sender_open_id: Optional[str] = None, thread_context: Optional[dict[str, Any]] = None, source_policy: Optional[str] = None, precomputed_query_semantics: Optional[dict[str, Any]] = None, route_decision: Optional[dict[str, Any]] = None, ) -> dict[str, Any]: external_conversation_key = self._build_external_conversation_key( asked_via=asked_via, source_chat_id=source_chat_id, conversation_key=conversation_key, source_sender_open_id=source_sender_open_id, sender=None, thread_context=thread_context, ) self._set_active_external_qa_context( source_chat_id=source_chat_id, source_message_id=source_message_id, source_sender_open_id=source_sender_open_id, conversation_scope_key=external_conversation_key, thread_context=thread_context, ) session_id, turn_index = await self._touch_session_for_new_record( asked_by=asked_by, asked_via=asked_via, project_id=project_id, question=clean_q, preferred_session_id=session_id, force_new_session=bool(force_new_session), external_conversation_key=external_conversation_key, ) context_session_id: Optional[int] if session_id is not None: context_session_id = int(session_id) elif asked_by is None: context_session_id = self._external_session_id_from_key(external_conversation_key) else: context_session_id = None conversation = await self._load_recent_conversation( asked_by=asked_by, asked_via=asked_via, project_id=project_id, session_id=session_id, external_session_id=context_session_id, limit=10, ) state_session_id = int(session_id) if session_id is not None else ( int(context_session_id) if context_session_id is not None else None ) state_row = await self._ensure_session_state(session_id=state_session_id) pending_selection = self._consume_pending_clarification_selection( question=clean_q, session_state=state_row, ) resolved_question = str(pending_selection.get("effective_question") or clean_q).strip() if isinstance( pending_selection, dict ) else clean_q consumed_source_policy_hint = ( str(pending_selection.get("source_policy_hint") or "").strip().lower() or None if isinstance(pending_selection, dict) else None ) anchor_resolution = await self._resolve_followup_anchor( question=resolved_question, session_id=state_session_id, context_session_id=context_session_id, session_state=state_row, conversation_scope_key=external_conversation_key, source_chat_id=source_chat_id, source_sender_open_id=source_sender_open_id, source_message_id=source_message_id, thread_context=thread_context, ) effective_q, rewrite_meta = self._rewrite_question_with_state( question=resolved_question, conversation=conversation, session_state=state_row, anchor_resolution=anchor_resolution, ) query_semantics = dict(precomputed_query_semantics or {}) if isinstance(precomputed_query_semantics, dict) else {} should_refresh_route_preview = bool( isinstance(pending_selection, dict) and ( resolved_question != clean_q or consumed_source_policy_hint ) ) if should_refresh_route_preview: query_semantics = {} route_decision = None route_preview = await self.preview_query_route_decision( question=effective_q, asked_via=asked_via, project_id=project_id, source_chat_id=source_chat_id, source_message_id=source_message_id, conversation_scope_key=external_conversation_key, reply_to_message_id=str((thread_context or {}).get("reply_to_message_id") or "").strip() or None, root_message_id=str((thread_context or {}).get("root_message_id") or "").strip() or None, source_policy_hint=consumed_source_policy_hint or source_policy, query_semantics=query_semantics, ) if should_refresh_route_preview or not isinstance(route_decision, dict) or not query_semantics else { "query_semantics": self._apply_route_decision_to_query_semantics( query_semantics=query_semantics, route_decision=route_decision, ), "route_decision": self._normalize_query_route_decision(route_decision), } query_semantics = ( dict(route_preview.get("query_semantics") or {}) if isinstance(route_preview.get("query_semantics"), dict) else {} ) operation_contract = None operation_contract_builder = getattr(self, "_build_operation_contract", None) if callable(operation_contract_builder): operation_contract = operation_contract_builder( question=effective_q, query_semantics=query_semantics, ) query_semantics = self._mirror_internal_context_to_query_semantics( query_semantics=query_semantics, operation_contract=operation_contract, ) internal_query_plan = self._build_internal_query_plan( question=effective_q, project_id=project_id, query_semantics=query_semantics, operation_contract=operation_contract, ) query_semantics = self._mirror_internal_context_to_query_semantics( query_semantics=query_semantics, query_plan=internal_query_plan, ) route_decision = ( dict(route_preview.get("route_decision") or {}) if isinstance(route_preview.get("route_decision"), dict) else {} ) query_type = str( (operation_contract or {}).get("query_type") or query_semantics.get("query_type") or QUERY_TYPE_UNKNOWN ).strip().lower() or QUERY_TYPE_UNKNOWN conversation_text = "\n".join( [ f"Q: {str(row.get('question') or '').strip()}\nA: {str(row.get('answer') or '').strip()}" for row in conversation[-4:] if isinstance(row, dict) ] ) or "无" scene_semantics = await self._resolve_answer_scene_semantics( question=clean_q, effective_question=effective_q, asked_via=asked_via, message_intent=str(query_semantics.get("message_intent") or query_semantics.get("intent") or "").strip().lower() or None, query_type=query_type, conversation_text=conversation_text, source_policy=str( route_decision.get("effective_source_policy") or query_semantics.get("effective_source_policy") or query_semantics.get("source_policy") or source_policy or "" ).strip().lower() or None, project_id=project_id, query_semantics=query_semantics, ) anchor_prompt_variant = await self._resolve_anchor_prompt_variant( anchor_resolution=anchor_resolution, conversation_scope_key=external_conversation_key, ) scene_semantics = self._apply_chat_external_fact_scene_policy( question=resolved_question, project_id=project_id, scene_semantics=scene_semantics, anchor_prompt_variant=anchor_prompt_variant, ) if bool(scene_semantics.get("requires_freshness")): query_semantics["external_freshness_only"] = True query_semantics["retrieval_domains"] = ["url"] query_semantics["source_policy"] = "external" query_semantics["effective_source_policy"] = "external" route_decision = self._normalize_query_route_decision( { **route_decision, "route_mode": str(route_decision.get("route_mode") or "external"), "effective_source_policy": "external", "decision_origin": str(route_decision.get("decision_origin") or "freshness_guard"), "reply_contract": { "mode": "explicit_source", "head": "外部实时查询:", "tail_hint": None, }, "query_profile": query_semantics.get("query_profile"), "probe_snapshot_summary": route_decision.get("probe_snapshot_summary"), "probe_snapshot": route_decision.get("probe_snapshot"), } ) requested_action_mode = self._normalize_action_mode(action_mode) effective_action_mode = await self._resolve_action_mode_async( requested_mode=requested_action_mode, question=resolved_question, effective_question=effective_q, asked_via=asked_via, ) return { "session_id": session_id, "turn_index": turn_index, "context_session_id": context_session_id, "conversation": conversation, "state_row": state_row, "resolved_question": resolved_question, "effective_q": effective_q, "rewrite_meta": rewrite_meta, "query_type": query_type, "query_semantics": query_semantics, "retrieval_domains": list(query_semantics.get("retrieval_domains") or []), "message_intent": str(query_semantics.get("message_intent") or query_semantics.get("intent") or "").strip().lower() or None, "scene_semantics": scene_semantics if isinstance(scene_semantics, dict) else {}, "effective_action_mode": effective_action_mode, "anchor_resolution": anchor_resolution, "route_decision": route_decision, } async def _execute_base_answer_mainline( self, *, clean_q: str, asked_by: Optional[int], asked_via: str, project_id: Optional[int], source_chat_id: Optional[str], session_id: Optional[int], turn_index: int, context_session_id: Optional[int], conversation: list[dict[str, str]], state_row: Optional[QASessionState], effective_q: str, rewrite_meta: dict[str, Any], query_type: str, query_semantics: dict[str, Any], retrieval_domains: list[str], scene_semantics: dict[str, Any], thinking_mode: str, active_thinking_mode: str, deep_thinking: bool, enforce_scene_prompt_only: bool, deep_retrieval_steps: int, deep_vector_top_k: int, started: float, message_intent: Optional[str], mixed_signal_part: Optional[str], anchor_resolution: Optional[FollowupAnchorResolution] = None, consultant_mode_preference: Optional[str] = None, route_decision: Optional[dict[str, Any]] = None, ) -> dict[str, Any]: operation_contract = ( dict(query_semantics.get("operation_contract") or {}) if isinstance(query_semantics.get("operation_contract"), dict) else {} ) operation_contract_builder = getattr(self, "_build_operation_contract", None) if not operation_contract and callable(operation_contract_builder): operation_contract = operation_contract_builder( question=effective_q, query_semantics=query_semantics, ) if isinstance(operation_contract, dict): query_semantics["operation_contract"] = operation_contract query_type = str( operation_contract.get("query_type") or query_type or QUERY_TYPE_UNKNOWN ).strip().lower() or QUERY_TYPE_UNKNOWN planner = self._plan_query_runtime( question=clean_q, effective_question=effective_q, query_type=query_type, scene_semantics=scene_semantics, requested_thinking_mode=active_thinking_mode, enforce_scene_prompt_only=enforce_scene_prompt_only, consultant_mode_preference=consultant_mode_preference, ) active_thinking_mode = planner.thinking_mode deep_thinking = planner.retrieval_answer_mode == ANSWER_MODE_RETRIEVAL_DEEP deep_retrieval_steps = int(planner.budget.max_steps or deep_retrieval_steps) deep_vector_top_k = int(planner.budget.vector_top_k or deep_vector_top_k) forced_deep_reason = "" if not deep_thinking and not planner.allow_fast_path: deep_intent = str((scene_semantics or {}).get("deep_intent") or "none").strip().lower() if deep_intent != "none": forced_deep_reason = deep_intent deep_thinking = True active_thinking_mode = THINKING_MODE_DEEP clarification_payload = None if not self._has_resolved_followup_rewrite(rewrite_meta): clarification_payload = self._build_followup_clarification_payload( question=clean_q, anchor_resolution=anchor_resolution, session_state=state_row, ) route_clarification_payload = self._build_route_clarification_payload(route_decision=route_decision) meta_followup_payload = await self._build_meta_followup_payload( question=clean_q, anchor_resolution=anchor_resolution, conversation_scope_key=self._get_active_external_qa_context().get("conversation_scope_key"), ) clarification_result = await self._maybe_return_clarification_response( clarification_payload=clarification_payload or route_clarification_payload, started=started, clean_q=clean_q, effective_q=effective_q, query_type=query_type, asked_by=asked_by, asked_via=asked_via, project_id=project_id, session_id=session_id, turn_index=turn_index, state_row=state_row, rewrite_meta=rewrite_meta, context_session_id=context_session_id, active_thinking_mode=active_thinking_mode, route_decision=route_decision, ) if clarification_result is not None: return clarification_result meta_followup_result = await self._maybe_return_meta_followup_response( meta_followup_payload=meta_followup_payload, started=started, clean_q=clean_q, effective_q=effective_q, query_type=query_type, asked_by=asked_by, asked_via=asked_via, project_id=project_id, session_id=session_id, turn_index=turn_index, state_row=state_row, rewrite_meta=rewrite_meta, context_session_id=context_session_id, active_thinking_mode=active_thinking_mode, route_decision=route_decision, ) if meta_followup_result is not None: return meta_followup_result system_snapshot = await self.context_cache.get_system_snapshot( db=self.db, tenant_id=self.tenant_id, ) user_snapshot = await self.context_cache.get_user_snapshot( db=self.db, tenant_id=self.tenant_id, user_id=asked_by, ) prefers_external_retrieval = ( str(query_semantics.get("effective_source_policy") or query_semantics.get("source_policy") or "").strip().lower() == "external" ) query_semantics = self._mirror_followup_state_to_query_semantics( query_semantics=query_semantics, session_state=state_row, rewrite_meta=rewrite_meta, ) target_resolution = ( dict(query_semantics.get("target_resolution") or {}) if isinstance(query_semantics.get("target_resolution"), dict) else {} ) target_resolver = getattr(self, "_resolve_internal_target", None) if not prefers_external_retrieval and callable(target_resolver): target_resolution = await target_resolver( question=effective_q, project_id=project_id, query_semantics=query_semantics, system_snapshot=system_snapshot, operation_contract=operation_contract, ) query_semantics = self._mirror_internal_context_to_query_semantics( query_semantics=query_semantics, target_resolution=target_resolution, ) patch_scene_semantics = getattr(self, "_patch_scene_semantics_with_target_resolution", None) if callable(patch_scene_semantics): scene_semantics = patch_scene_semantics( scene_semantics=scene_semantics, operation_contract=operation_contract, target_resolution=target_resolution, ) internal_query_plan = self._build_internal_query_plan( question=effective_q, project_id=project_id, query_semantics=query_semantics, operation_contract=operation_contract, target_resolution=target_resolution, ) query_semantics = self._mirror_internal_context_to_query_semantics( query_semantics=query_semantics, query_plan=internal_query_plan, ) active_context = ( self._get_active_external_qa_context() if hasattr(self, "_get_active_external_qa_context") else {} ) # Keep query_semantics as a compatibility mirror only; internal execution truth moves to the packet. internal_context_packet = self._build_internal_query_context_packet( question=effective_q, project_id=project_id, session_id=session_id, conversation_scope_key=str(active_context.get("conversation_scope_key") or "").strip() or None, reply_to_message_id=str(active_context.get("reply_to_message_id") or "").strip() or None, root_message_id=str(active_context.get("root_message_id") or "").strip() or None, route_decision=route_decision, operation_contract=operation_contract, target_resolution=target_resolution, query_plan=internal_query_plan, ) precheck_response = await self._maybe_return_internal_context_precheck_response( question=clean_q, effective_question=effective_q, asked_by=asked_by, asked_via=asked_via, project_id=project_id, session_id=session_id, context_session_id=context_session_id, turn_index=turn_index, state_row=state_row, rewrite_meta=rewrite_meta, thinking_mode=active_thinking_mode, query_type=query_type, route_decision=route_decision, query_semantics=query_semantics, internal_context_packet=internal_context_packet, ) if precheck_response is not None: return precheck_response if planner.allow_fast_path and not prefers_external_retrieval: deterministic_result = await self._run_deterministic_query( question=effective_q, project_id=project_id, query_type=query_type, query_semantics=query_semantics, internal_context_packet=internal_context_packet, ) if deterministic_result is not None: return await self._persist_fast_answer( question=clean_q, asked_by=asked_by, asked_via=asked_via, project_id=project_id, fast_result=deterministic_result, session_id=session_id, external_session_id=context_session_id, turn_index=turn_index, query_type=str(deterministic_result.get("query_type") or query_type), missing_fields=list(deterministic_result.get("missing_fields") or []), state_row=state_row, effective_question=effective_q, rewrite_meta=rewrite_meta, thinking_mode=active_thinking_mode, answer_mode=ANSWER_MODE_FAST_PATH, route_decision=route_decision, query_semantics=query_semantics, internal_context_packet=internal_context_packet, ) internal_model_config_fast_answer = None internal_model_config_builder = getattr(self, "_build_internal_model_config_fast_answer", None) if not prefers_external_retrieval and callable(internal_model_config_builder): internal_model_config_fast_answer = await internal_model_config_builder( question=effective_q, query_semantics=query_semantics, internal_context_packet=internal_context_packet, ) if internal_model_config_fast_answer is not None: return await self._persist_fast_answer( question=clean_q, asked_by=asked_by, asked_via=asked_via, project_id=project_id, fast_result=internal_model_config_fast_answer, session_id=session_id, external_session_id=context_session_id, turn_index=turn_index, query_type=QUERY_TYPE_STATUS, missing_fields=[], state_row=state_row, effective_question=effective_q, rewrite_meta=rewrite_meta, thinking_mode=active_thinking_mode, answer_mode=ANSWER_MODE_FAST_PATH, route_decision=route_decision, query_semantics=query_semantics, internal_context_packet=internal_context_packet, ) direct_answer = None allow_snapshot_direct_answer = planner.allow_fast_path and not prefers_external_retrieval snapshot_direct_guard = getattr(self, "_should_allow_snapshot_direct_answer", None) if callable(snapshot_direct_guard): allow_snapshot_direct_answer = allow_snapshot_direct_answer and snapshot_direct_guard( scene_semantics=scene_semantics, operation_contract=operation_contract, target_resolution=target_resolution, ) if allow_snapshot_direct_answer: direct_answer = self._build_snapshot_direct_answer( effective_q, system_snapshot=system_snapshot, user_snapshot=user_snapshot, snapshot_focus=str((scene_semantics or {}).get("snapshot_focus") or "none"), ) direct_result = None if allow_snapshot_direct_answer: direct_result = await self._maybe_return_snapshot_direct_response( direct_answer=direct_answer, started=started, clean_q=clean_q, effective_q=effective_q, asked_by=asked_by, asked_via=asked_via, project_id=project_id, session_id=session_id, turn_index=turn_index, state_row=state_row, rewrite_meta=rewrite_meta, context_session_id=context_session_id, active_thinking_mode=active_thinking_mode, user_snapshot=user_snapshot, route_decision=route_decision, ) if direct_result is not None: return direct_result is_snapshot_direct_question = str((scene_semantics or {}).get("snapshot_focus") or "none").strip().lower() != "none" if planner.allow_fast_path and not prefers_external_retrieval and not is_snapshot_direct_question: glm_semantic_result = await self._try_glm_project_semantic_answer( clean_q=effective_q, project_id=project_id, query_semantics=query_semantics, internal_context_packet=internal_context_packet, ) if glm_semantic_result is not None: return await self._persist_fast_answer( question=clean_q, asked_by=asked_by, asked_via=asked_via, project_id=project_id, fast_result=glm_semantic_result, session_id=session_id, external_session_id=context_session_id, turn_index=turn_index, query_type=query_type if query_type != QUERY_TYPE_UNKNOWN else QUERY_TYPE_EXPLAIN, missing_fields=[], state_row=state_row, effective_question=effective_q, rewrite_meta=rewrite_meta, thinking_mode=active_thinking_mode, answer_mode=ANSWER_MODE_FAST_PATH, route_decision=route_decision, query_semantics=query_semantics, internal_context_packet=internal_context_packet, ) return await self._build_retrieval_response( clean_q=clean_q, effective_q=effective_q, asked_by=asked_by, asked_via=asked_via, project_id=project_id, source_chat_id=source_chat_id, session_id=session_id, turn_index=turn_index, context_session_id=context_session_id, conversation=conversation, state_row=state_row, rewrite_meta=rewrite_meta, query_type=query_type, query_semantics=query_semantics, retrieval_domains=retrieval_domains, scene_semantics=scene_semantics, thinking_mode=thinking_mode, active_thinking_mode=active_thinking_mode, deep_thinking=deep_thinking, forced_deep_reason=forced_deep_reason or str(planner.reason or ""), deep_retrieval_steps=deep_retrieval_steps, deep_vector_top_k=deep_vector_top_k, system_snapshot=system_snapshot, user_snapshot=user_snapshot, started=started, message_intent=message_intent, mixed_signal_part=mixed_signal_part, answer_mode=planner.retrieval_answer_mode, consultant_mode_preference=consultant_mode_preference, route_decision=route_decision, internal_context_packet=internal_context_packet, )