feat: add customer profile candidate flow
This commit is contained in:
@@ -25,7 +25,7 @@ class AgentPersistenceService:
|
||||
|
||||
async def complete_run(
|
||||
self, run_id: str, result: AgentResult, memory_extraction_requested: bool = True,
|
||||
*, worker_id: str | None = None,
|
||||
*, worker_id: str | None = None, profile_candidate_requested: bool = False,
|
||||
) -> int:
|
||||
now = datetime.now(UTC).replace(tzinfo=None)
|
||||
async with self.session.begin():
|
||||
@@ -167,6 +167,19 @@ class AgentPersistenceService:
|
||||
payload={"run_id": run_id, "message_id": message.id,
|
||||
"customer_id": run.user_id}, occurred_at=now,
|
||||
))
|
||||
if profile_candidate_requested:
|
||||
# 候选事件只允许由已登录客服会话触发,消费者仍会再次校验身份标记。
|
||||
events.append(DomainEvent(
|
||||
event_id=str(uuid4()),
|
||||
event_type="customer_profile.candidate_requested",
|
||||
aggregate_type="agent_run", aggregate_id=run_id, trace_id=run.trace_id,
|
||||
payload={
|
||||
"run_id": run_id, "message_id": message.id,
|
||||
"customer_id": run.user_id,
|
||||
"actor_type": "authenticated_customer",
|
||||
},
|
||||
occurred_at=now,
|
||||
))
|
||||
if handover_ticket is not None:
|
||||
# Outbox 事件由后续管理员通知/工单消费方可靠投递,服务层不直接通知外部系统。
|
||||
assert handover_context is not None
|
||||
|
||||
@@ -118,6 +118,7 @@ class MemoryService:
|
||||
confidence: float = 0.5,
|
||||
source_type: str = "conversation",
|
||||
structured_value: dict[str, Any] | None = None,
|
||||
status: str = "active",
|
||||
) -> MemoryUnit:
|
||||
"""按 (customer_id, active_memory_key) 语义更新唯一有效记忆。
|
||||
|
||||
@@ -125,8 +126,11 @@ class MemoryService:
|
||||
内容变化时记录一条冲突:左侧为被覆盖的旧值所在记忆行,右侧为该记忆的新版本
|
||||
标识(见 `_conflict_right_id`)。两侧绝不指向同一条记录,避免自引用冲突。
|
||||
"""
|
||||
if status not in {"active", "candidate"}:
|
||||
raise ValueError("status must be active or candidate")
|
||||
now = datetime.now(UTC).replace(tzinfo=None)
|
||||
memory = await self._active(customer_id, memory_key)
|
||||
# 候选记录不能覆盖现有有效记忆,必须等待确认或审核后再晋升。
|
||||
memory = await self._active(customer_id, memory_key) if status == "active" else None
|
||||
if memory is not None:
|
||||
updated = await self._update(memory, content, confidence, now, structured_value)
|
||||
await self.invalidate_recall_cache(customer_id)
|
||||
@@ -137,7 +141,7 @@ class MemoryService:
|
||||
source_type=source_type, source_confidence=confidence,
|
||||
confidence=confidence, structured_value=structured_value,
|
||||
evidence_count=0, conflict_count=0, recall_count=0,
|
||||
status="active", valid_from=now, version=1, created_at=now, updated_at=now,
|
||||
status=status, valid_from=now, version=1, created_at=now, updated_at=now,
|
||||
)
|
||||
self.session.add(memory)
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user