初始化提交
This commit is contained in:
commit
887c1f449e
963 files changed
+166869
No files matched your search
@@ -0,0 +1,99 @@
|
||||
"""叩心枢会话/消息创建与一炁事件推送。
|
||||
|
||||
设计 docs/domain/core-domains.md§7。
|
||||
|
||||
主动会话优先复用已有活跃会话,避免每次触发都新建会话。
|
||||
只有在角色无活跃会话时才会创建新会话。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import UTC, datetime
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.logging import logger
|
||||
from app.models.chat import ChatMessage, ChatSession
|
||||
from app.modules.runtime.events import Event
|
||||
from app.services.event_store import DbEventStore
|
||||
|
||||
|
||||
async def create_proactive_message(
|
||||
session: AsyncSession,
|
||||
event_store: DbEventStore,
|
||||
character_id: str,
|
||||
opener_text: str,
|
||||
condition_name: str,
|
||||
*,
|
||||
session_id: str | None = None,
|
||||
now: datetime | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""创建叩心枢主动发起的消息,可追加到现有会话或新建会话。
|
||||
|
||||
策略:
|
||||
- 若 ``session_id`` 不为空,追加消息到该会话(不创建新会话)
|
||||
- 若 ``session_id`` 为空,新建会话 + 消息
|
||||
|
||||
Returns:
|
||||
{"session_id": str, "message_id": str}: 实际写入的会话 ID 和消息 ID。
|
||||
"""
|
||||
now = now or datetime.now(UTC)
|
||||
is_new = session_id is None
|
||||
|
||||
if is_new:
|
||||
# 创建新会话(status 默认 'active')
|
||||
chat_session = ChatSession(
|
||||
character_id=character_id,
|
||||
title=opener_text[:60],
|
||||
)
|
||||
session.add(chat_session)
|
||||
await session.flush()
|
||||
session_id = chat_session.id
|
||||
event_type = "proactive.session"
|
||||
else:
|
||||
event_type = "proactive.message"
|
||||
|
||||
# 创建开场消息(无 run_id——非流式、无推理过程)
|
||||
message = ChatMessage(
|
||||
character_id=character_id,
|
||||
session_id=session_id,
|
||||
role="assistant",
|
||||
modality="text",
|
||||
content=opener_text,
|
||||
)
|
||||
session.add(message)
|
||||
await session.flush()
|
||||
|
||||
# 推一炁事件
|
||||
payload: dict[str, Any] = {
|
||||
"session_id": session_id,
|
||||
"message_id": message.id,
|
||||
"character_id": character_id,
|
||||
"preview": opener_text[:100],
|
||||
"trigger": condition_name,
|
||||
"is_new": is_new,
|
||||
}
|
||||
if is_new:
|
||||
payload["title_preview"] = opener_text[:60]
|
||||
|
||||
event = Event(
|
||||
type=event_type,
|
||||
source="knocking_pivot",
|
||||
character_id=character_id,
|
||||
payload=payload,
|
||||
visibility="public",
|
||||
created_at=now.isoformat(),
|
||||
)
|
||||
# 复用调用方的 session——同一事务写 events 表,避免 session A 写 chat 表、
|
||||
# session B 写 events 表时两条连接争写导致锁冲突
|
||||
await event_store.append(event, session=session)
|
||||
|
||||
logger.info(
|
||||
f"knocking_pivot_{'session_created' if is_new else 'message_appended'}",
|
||||
character_id=character_id,
|
||||
session_id=session_id,
|
||||
message_id=message.id,
|
||||
trigger=condition_name,
|
||||
)
|
||||
return {"session_id": session_id, "message_id": message.id}
|
||||
Reference in new issue
Block a user