"""对话接口:四 Agent 统一 chat 入口。""" from __future__ import annotations from typing import Annotated from fastapi import APIRouter, Depends, Request from app.gateway.auth_deps import get_auth_context from app.gateway.ownership import assert_customer_access, resolve_effective_customer_id from app.model.schemas import AuthContext, ChatRequest, ChatResponseData from app.repository.agent_repository import AgentSessionRepository from app.repository.audit_repository import AuditRepository from app.service.agent_service import run_chat from app.utils.input_guard import validate_user_message from app.utils.response import ok router = APIRouter(prefix="/api", tags=["chat"]) @router.post("/chat") def chat( body: ChatRequest, request: Request, ctx: Annotated[AuthContext, Depends(get_auth_context)], ): message = validate_user_message(body.message) customer_id = resolve_effective_customer_id(ctx, body.customer_id) if customer_id and ctx.agent_type in ("advisor", "analyst", "risk", "customer"): assert_customer_access(ctx, customer_id) session_repo = AgentSessionRepository() session_id = session_repo.ensure_session(ctx, body.session_id, customer_id) seq = session_repo.next_seq(session_id) session_repo.insert_message( session_id=session_id, trace_id=ctx.trace_id, seq_no=seq, role="user", content=message, ) reply, has_disclaimer = run_chat(ctx, message, customer_id) session_repo.insert_message( session_id=session_id, trace_id=ctx.trace_id, seq_no=seq + 1, role="assistant", content=reply, has_disclaimer=has_disclaimer, ) AuditRepository().insert( trace_id=ctx.trace_id, event_type="chat_completed", agent_type=ctx.agent_type, actor_id=ctx.sub, customer_id=customer_id, input_summary={"session_id": session_id, "message_len": len(message)}, decision="success", ) data = ChatResponseData( session_id=session_id, reply=reply, agent_type=ctx.agent_type, has_disclaimer=has_disclaimer, ) return ok(data.model_dump(), ctx.trace_id)