"""Adaptive RAG mixin module.""" from __future__ import annotations from .shared import * class AdaptiveRAGAnswerEntryMixin: HIGH_ACCURACY_CHANNELS = { "feishu", "lark", "feishu_group", "feishu_dm", "pmflow", "pmflow_manual", "/ai-pmo/process-text", "ai-pmo-process-text", "ai_pmo", "ai_pmo_ui", } @classmethod def _is_high_accuracy_channel(cls, asked_via: str) -> bool: return str(asked_via or "").strip().lower() in cls.HIGH_ACCURACY_CHANNELS @staticmethod def _should_enforce_scene_prompt_only( *, asked_via: str, message_intent: Optional[str], ) -> bool: intent = str(message_intent or "").strip().lower() if intent == "mixed": return True channel = str(asked_via or "").strip().lower() return channel in { "feishu", "lark", "feishu_group", "feishu_dm", "pmflow_manual", "/ai-pmo/process-text", "ai-pmo-process-text", "ai_pmo", "ai_pmo_ui", } @staticmethod def _should_trigger_write_ack_gate( *, sync_requirement: bool, asked_via: str, effective_action_mode: str, message_intent: Optional[str] = None, ) -> bool: intent = str(message_intent or "").strip().lower() if intent in {"mixed", "question"}: return False return ( bool(sync_requirement) and str(asked_via or "").strip().lower() != "feishu" and str(effective_action_mode or "").strip().lower() in {ACTION_MODE_WRITE, ACTION_MODE_READ_WRITE} ) async def answer_question( self, *, question: str, asked_by: Optional[int], asked_via: str, project_id: Optional[int] = None, source_chat_id: Optional[str] = None, session_id: Optional[int] = None, conversation_key: Optional[str] = None, force_new_session: bool = False, thinking_mode: str = THINKING_MODE_NORMAL, action_mode: str = ACTION_MODE_AUTO, sync_requirement: bool = True, message_intent: Optional[str] = None, mixed_signal_part: Optional[str] = None, ) -> dict[str, Any]: started = time.perf_counter() clean_q = str(question or "").strip() active_thinking_mode = self._normalize_thinking_mode(thinking_mode) if self._is_high_accuracy_channel(asked_via): active_thinking_mode = THINKING_MODE_DEEP deep_thinking = active_thinking_mode == THINKING_MODE_DEEP enforce_scene_prompt_only = self._should_enforce_scene_prompt_only( asked_via=asked_via, message_intent=message_intent, ) deep_retrieval_steps = DEEP_RETRIEVAL_STEPS deep_vector_top_k = DEEP_VECTOR_TOP_K if not clean_q: return self._build_response_payload( answer="问题为空,无法检索。", sources=[], domains_used=[], response_time_ms=0, db_query_ms=0, vector_search_ms=0, db_timeout=False, vector_timeout=False, qa_id=None, session_id=None, turn_index=1, relevance_max=0.0, query_type=QUERY_TYPE_UNKNOWN, confidence=0.0, missing_fields=["question"], thinking_mode=active_thinking_mode, ) runtime = await self._prepare_answer_runtime( clean_q=clean_q, asked_by=asked_by, asked_via=asked_via, project_id=project_id, source_chat_id=source_chat_id, session_id=session_id, conversation_key=conversation_key, force_new_session=force_new_session, action_mode=action_mode, ) session_id = runtime["session_id"] turn_index = int(runtime["turn_index"] or 1) context_session_id = runtime["context_session_id"] conversation = runtime["conversation"] state_row = runtime["state_row"] effective_q = str(runtime["effective_q"] or "").strip() rewrite_meta = runtime["rewrite_meta"] if isinstance(runtime["rewrite_meta"], dict) else {} query_type = str(runtime["query_type"] or QUERY_TYPE_UNKNOWN) effective_action_mode = str(runtime["effective_action_mode"] or ACTION_MODE_AUTO).strip().lower() if self._should_trigger_write_ack_gate( sync_requirement=sync_requirement, asked_via=asked_via, effective_action_mode=effective_action_mode, message_intent=message_intent, ): ack_result = await self._handle_ack_first_requirement( question=clean_q, effective_question=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, query_type=query_type, action_mode=effective_action_mode, started_at=started, ) if ack_result is not None: return ack_result return await self._execute_base_answer_mainline( clean_q=clean_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, effective_q=effective_q, rewrite_meta=rewrite_meta, query_type=query_type, thinking_mode=active_thinking_mode, active_thinking_mode=active_thinking_mode, deep_thinking=deep_thinking, enforce_scene_prompt_only=enforce_scene_prompt_only, deep_retrieval_steps=deep_retrieval_steps, deep_vector_top_k=deep_vector_top_k, started=started, message_intent=message_intent, mixed_signal_part=mixed_signal_part, )