feat(server): 新增运行时聊天服务和用户代理服务,支持智能对话和用户行为分析
This commit is contained in:
@@ -27,7 +27,7 @@ class RuntimeChatService:
|
|||||||
|
|
||||||
def complete(
|
def complete(
|
||||||
self,
|
self,
|
||||||
messages: list[dict[str, str]],
|
messages: list[dict[str, Any]],
|
||||||
*,
|
*,
|
||||||
slot_priority: tuple[str, ...] = ("main", "backup"),
|
slot_priority: tuple[str, ...] = ("main", "backup"),
|
||||||
max_tokens: int = 500,
|
max_tokens: int = 500,
|
||||||
@@ -91,7 +91,7 @@ class RuntimeChatService:
|
|||||||
def _request_chat_completion(
|
def _request_chat_completion(
|
||||||
self,
|
self,
|
||||||
config: dict[str, str],
|
config: dict[str, str],
|
||||||
messages: list[dict[str, str]],
|
messages: list[dict[str, Any]],
|
||||||
*,
|
*,
|
||||||
max_tokens: int,
|
max_tokens: int,
|
||||||
temperature: float,
|
temperature: float,
|
||||||
@@ -136,7 +136,7 @@ class RuntimeChatService:
|
|||||||
endpoint: str,
|
endpoint: str,
|
||||||
model: str,
|
model: str,
|
||||||
api_key: str,
|
api_key: str,
|
||||||
messages: list[dict[str, str]],
|
messages: list[dict[str, Any]],
|
||||||
max_tokens: int,
|
max_tokens: int,
|
||||||
temperature: float,
|
temperature: float,
|
||||||
) -> str:
|
) -> str:
|
||||||
@@ -165,7 +165,7 @@ class RuntimeChatService:
|
|||||||
endpoint: str,
|
endpoint: str,
|
||||||
model: str,
|
model: str,
|
||||||
api_key: str,
|
api_key: str,
|
||||||
messages: list[dict[str, str]],
|
messages: list[dict[str, Any]],
|
||||||
max_tokens: int,
|
max_tokens: int,
|
||||||
temperature: float,
|
temperature: float,
|
||||||
) -> str:
|
) -> str:
|
||||||
@@ -197,7 +197,7 @@ class RuntimeChatService:
|
|||||||
endpoint: str,
|
endpoint: str,
|
||||||
model: str,
|
model: str,
|
||||||
api_key: str,
|
api_key: str,
|
||||||
messages: list[dict[str, str]],
|
messages: list[dict[str, Any]],
|
||||||
max_tokens: int,
|
max_tokens: int,
|
||||||
temperature: float,
|
temperature: float,
|
||||||
) -> str:
|
) -> str:
|
||||||
|
|||||||
@@ -2124,6 +2124,61 @@ class UserAgentService:
|
|||||||
item: dict[str, object],
|
item: dict[str, object],
|
||||||
payload: UserAgentRequest,
|
payload: UserAgentRequest,
|
||||||
) -> dict[str, str]:
|
) -> dict[str, str]:
|
||||||
|
provided_type = str(item.get("document_type") or "").strip().lower()
|
||||||
|
expense_type_code = self._collect_entity_values(payload).get("expense_type_code", "")
|
||||||
|
has_customer = bool(self._collect_entity_values(payload).get("customer"))
|
||||||
|
if provided_type:
|
||||||
|
if provided_type in {"flight_itinerary", "train_ticket"}:
|
||||||
|
return {
|
||||||
|
"document_type": provided_type,
|
||||||
|
"expense_type": "travel",
|
||||||
|
"group_code": "travel",
|
||||||
|
"scene_label": "差旅票据",
|
||||||
|
}
|
||||||
|
if provided_type == "hotel_invoice":
|
||||||
|
return {
|
||||||
|
"document_type": provided_type,
|
||||||
|
"expense_type": "hotel",
|
||||||
|
"group_code": "travel",
|
||||||
|
"scene_label": "住宿票据",
|
||||||
|
}
|
||||||
|
if provided_type in {"taxi_receipt", "parking_toll_receipt"}:
|
||||||
|
return {
|
||||||
|
"document_type": provided_type,
|
||||||
|
"expense_type": "transport",
|
||||||
|
"group_code": "travel",
|
||||||
|
"scene_label": "交通票据",
|
||||||
|
}
|
||||||
|
if provided_type == "meal_receipt":
|
||||||
|
group_code = "entertainment" if expense_type_code == "entertainment" or has_customer else "meal"
|
||||||
|
return {
|
||||||
|
"document_type": provided_type,
|
||||||
|
"expense_type": group_code,
|
||||||
|
"group_code": group_code,
|
||||||
|
"scene_label": "餐饮票据",
|
||||||
|
}
|
||||||
|
if provided_type == "office_invoice":
|
||||||
|
return {
|
||||||
|
"document_type": provided_type,
|
||||||
|
"expense_type": "office",
|
||||||
|
"group_code": "office",
|
||||||
|
"scene_label": "办公用品票据",
|
||||||
|
}
|
||||||
|
if provided_type == "meeting_invoice":
|
||||||
|
return {
|
||||||
|
"document_type": provided_type,
|
||||||
|
"expense_type": "meeting",
|
||||||
|
"group_code": "meeting",
|
||||||
|
"scene_label": "会务票据",
|
||||||
|
}
|
||||||
|
if provided_type == "training_invoice":
|
||||||
|
return {
|
||||||
|
"document_type": provided_type,
|
||||||
|
"expense_type": "training",
|
||||||
|
"group_code": "training",
|
||||||
|
"scene_label": "培训票据",
|
||||||
|
}
|
||||||
|
|
||||||
text = " ".join(
|
text = " ".join(
|
||||||
[
|
[
|
||||||
str(item.get("filename") or ""),
|
str(item.get("filename") or ""),
|
||||||
@@ -2132,8 +2187,6 @@ class UserAgentService:
|
|||||||
]
|
]
|
||||||
).lower()
|
).lower()
|
||||||
compact = text.replace(" ", "")
|
compact = text.replace(" ", "")
|
||||||
expense_type_code = self._collect_entity_values(payload).get("expense_type_code", "")
|
|
||||||
has_customer = bool(self._collect_entity_values(payload).get("customer"))
|
|
||||||
|
|
||||||
if any(keyword in compact for keyword in ("机票", "航班", "火车", "高铁", "行程单")):
|
if any(keyword in compact for keyword in ("机票", "航班", "火车", "高铁", "行程单")):
|
||||||
return {
|
return {
|
||||||
@@ -2187,6 +2240,19 @@ class UserAgentService:
|
|||||||
return "other"
|
return "other"
|
||||||
|
|
||||||
def _extract_document_fields(self, item: dict[str, object]) -> dict[str, str]:
|
def _extract_document_fields(self, item: dict[str, object]) -> dict[str, str]:
|
||||||
|
raw_fields = item.get("document_fields")
|
||||||
|
if isinstance(raw_fields, list):
|
||||||
|
normalized_fields: dict[str, str] = {}
|
||||||
|
for field in raw_fields:
|
||||||
|
if not isinstance(field, dict):
|
||||||
|
continue
|
||||||
|
label = str(field.get("label") or "").strip()
|
||||||
|
value = str(field.get("value") or "").strip()
|
||||||
|
if label and value:
|
||||||
|
normalized_fields[label] = value
|
||||||
|
if normalized_fields:
|
||||||
|
return normalized_fields
|
||||||
|
|
||||||
text = " ".join([str(item.get("summary") or ""), str(item.get("text") or "")]).strip()
|
text = " ".join([str(item.get("summary") or ""), str(item.get("text") or "")]).strip()
|
||||||
fields: dict[str, str] = {}
|
fields: dict[str, str] = {}
|
||||||
amount_match = AMOUNT_TEXT_PATTERN.search(text)
|
amount_match = AMOUNT_TEXT_PATTERN.search(text)
|
||||||
|
|||||||
Reference in New Issue
Block a user