64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
"""Kernel 事件日志:一炁(EventStore)之上的 Kernel 写入接口。
|
||
|
||
- 落库走 ``DbEventStore``(run 内单调 sequence,DB 为事实源,SSE 断线重放依据);
|
||
- 双发进程内 ``bus``(RunEventBus)供既有 ``/runs/{id}/stream`` SSE 实时转发。
|
||
该双发是 M0 骨架的过渡接法,M2 重建 runs 路由时收敛为 EventStore 单通道。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import Any
|
||
|
||
from app.modules.runtime.events import Event, EventStore
|
||
from app.schemas.runtime import EventResponse
|
||
from app.services.event_bus import bus
|
||
|
||
|
||
class KernelEventLog:
|
||
"""Kernel 视角的事件写入与检索。"""
|
||
|
||
def __init__(self, store: EventStore) -> None:
|
||
self._store = store
|
||
|
||
async def emit(
|
||
self,
|
||
*,
|
||
type: str, # noqa: A002 — 对齐事件字段名
|
||
run_id: str,
|
||
character_id: str,
|
||
source: str = "kernel",
|
||
payload: dict[str, Any] | None = None,
|
||
visibility: str = "public",
|
||
trace_id: str | None = None,
|
||
) -> Event:
|
||
event = await self._store.append(
|
||
Event(
|
||
type=type,
|
||
source=source,
|
||
payload=payload or {},
|
||
visibility=visibility, # type: ignore[arg-type]
|
||
run_id=run_id,
|
||
character_id=character_id,
|
||
trace_id=trace_id,
|
||
)
|
||
)
|
||
bus.publish(run_id, _to_response(event))
|
||
return event
|
||
|
||
async def list_by_run(self, run_id: str) -> list[Event]:
|
||
return await self._store.list_by_run(run_id)
|
||
|
||
|
||
def _to_response(event: Event) -> EventResponse:
|
||
return EventResponse(
|
||
event_id=event.id,
|
||
run_id=event.run_id or "",
|
||
character_id=event.character_id or "",
|
||
type=event.type,
|
||
sequence=event.sequence if event.sequence is not None else 0,
|
||
visibility=event.visibility,
|
||
payload=event.payload,
|
||
created_at=event.created_at,
|
||
trace_id=event.trace_id,
|
||
)
|