from __future__ import annotations from typing import Any from ..models import User from ..schemas.rag import RAGAskRequest def resolve_effective_tenant_id(current_user: User, fallback_tenant_id: int) -> int: try: return int(getattr(current_user, "tenant_id") or fallback_tenant_id or 1) except Exception: return int(fallback_tenant_id or 1) def build_answer_question_kwargs(request: RAGAskRequest, current_user: User) -> dict[str, Any]: asked_by = int(getattr(current_user, "id")) return { "question": request.question, "asked_by": asked_by, "asked_via": request.asked_via, "project_id": request.project_id, "source_chat_id": request.source_chat_id, "session_id": request.session_id, "force_new_session": bool(request.new_session), "thinking_mode": request.thinking_mode, "action_mode": request.action_mode, "sync_requirement": bool(request.sync_requirement), "message_intent": request.message_intent, "mixed_signal_part": request.mixed_signal_part, } def _safe_int(value: Any) -> int | None: try: if value is None: return None return int(value) except Exception: return None def _resolve_sender_name(current_user: User) -> str: sender = str( getattr(current_user, "name", None) or getattr(current_user, "username", None) or "PMFlow用户" ).strip() return sender or "PMFlow用户" def build_kernel_ingress_kwargs(request: RAGAskRequest, current_user: User) -> dict[str, Any]: rag_request_context = build_answer_question_kwargs(request=request, current_user=current_user) return { "source_system": str(request.asked_via or "pmflow").strip() or "pmflow", "source_message_id": None, "message_text": request.question, "sender": _resolve_sender_name(current_user), "channel_ref": request.source_chat_id, "source_sender_open_id": None, "captured_at": None, "chat_type": "manual", "project_hint_id": request.project_id, "ingress_options": { "rag_request_context": rag_request_context, }, } def build_rag_response_payload(*, ingress_result: dict[str, Any]) -> dict[str, Any]: result = ingress_result if isinstance(ingress_result, dict) else {} rag_result = result.get("rag_result") if isinstance(result.get("rag_result"), dict) else {} payload = dict(rag_result) answer = str(payload.get("answer") or result.get("direct_reply_text") or "").strip() payload["answer"] = answer or "当前暂无可用回答。" if "reply_required" not in payload: payload["reply_required"] = bool(result.get("direct_reply_required")) if "reply_text" not in payload: payload["reply_text"] = str(result.get("direct_reply_text") or "").strip() or None if "trace_id" not in payload: payload["trace_id"] = str(result.get("ai_trace_id") or "").strip() or None if "processing_stage" not in payload: payload["processing_stage"] = "qa" payload["work_item_id"] = _safe_int(result.get("work_item_id")) payload["ingress_status"] = str(result.get("status") or "").strip() or None payload["intent"] = str(result.get("intent") or "").strip() or None return payload