feat(visitor): Implement visitor chat functionality and enhance customer service interactions

- Added a new visitor chat API endpoint (`/api/chat/visitor`) to allow unauthenticated users to engage in conversations without requiring customer data.
- Introduced a visitor context dependency to manage visitor interactions seamlessly.
- Enhanced the chat API to support explicit session termination and improved response handling for customer service interactions.
- Updated the database configuration to include Redis client support for caching visitor data.
- Added a new customer note repository to persist user notes independently of the L1 profile slots.

This update significantly improves the customer service experience by enabling visitor interactions and ensuring efficient data handling for both registered and unregistered users.
This commit is contained in:
2026-09-09 18:32:00 +08:00
parent ad930c26b1
commit b841f68295
98 changed files with 10682 additions and 630 deletions
+35 -2
View File
@@ -6,8 +6,22 @@ from typing import Any, Literal
from pydantic import BaseModel, Field
AgentType = Literal["customer", "advisor", "analyst", "risk"]
TokenType = Literal["customer", "staff", "service"]
AgentType = Literal["customer", "advisor", "analyst", "risk", "visitor"]
TokenType = Literal["customer", "staff", "service", "visitor"]
IntentType = Literal[
"product_consult",
"policy_interpret",
"faq",
"chit_chat",
"save_note",
"reject",
"transfer_human",
"fallback",
"holding_query",
"transaction_query",
"risk_assessment_query",
"suitability_check",
]
class AuthContext(BaseModel):
@@ -58,6 +72,8 @@ class ChatResponseData(BaseModel):
reply: str
agent_type: AgentType
has_disclaimer: bool = False
intent: IntentType | None = Field(default=None, description="仅 customer 返回")
transfer_to_human: bool = Field(default=False, description="仅 customer 返回")
class ApiResponse(BaseModel):
@@ -65,3 +81,20 @@ class ApiResponse(BaseModel):
message: str = "ok"
data: Any = None
trace_id: str
class VisitorChatRequest(BaseModel):
"""游客对话请求(免认证)。"""
message: str = Field(..., min_length=1, max_length=8000)
session_id: str | None = None
class VisitorChatResponseData(BaseModel):
"""游客对话响应。"""
session_id: str
reply: str
intent: IntentType
has_disclaimer: bool = False
transfer_to_human: bool = False