91 lines
3.3 KiB
Python
91 lines
3.3 KiB
Python
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
|