feat(persistence): add RunEventStore ABC + MemoryRunEventStore

Phase 2-A prerequisite for event storage: adds the unified run event
stream interface (RunEventStore) with an in-memory implementation,
RunEventsConfig, gateway integration, and comprehensive tests (27 cases).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
rayhpeng
2026-04-02 14:23:13 +08:00
parent 1ff6b5f7ab
commit 23eacf9533
9 changed files with 563 additions and 0 deletions
+15
View File
@@ -14,6 +14,7 @@ from contextlib import AsyncExitStack, asynccontextmanager
from fastapi import FastAPI, HTTPException, Request
from deerflow.runtime import RunManager, StreamBridge
from deerflow.runtime.events.store.base import RunEventStore
from deerflow.runtime.runs.store.base import RunStore
@@ -46,6 +47,12 @@ async def langgraph_runtime(app: FastAPI) -> AsyncGenerator[None, None]:
# RunRepository when models are implemented)
app.state.run_store = MemoryRunStore()
# Initialize run event store (MemoryRunEventStore for now)
# TODO(Phase 2-B): switch to db/jsonl backend based on config.run_events.backend
from deerflow.runtime.events.store.memory import MemoryRunEventStore
app.state.run_event_store = MemoryRunEventStore()
try:
yield
finally:
@@ -86,6 +93,14 @@ def get_store(request: Request):
return getattr(request.app.state, "store", None)
def get_run_event_store(request: Request) -> RunEventStore:
"""Return the RunEventStore, or 503 if not available."""
store = getattr(request.app.state, "run_event_store", None)
if store is None:
raise HTTPException(status_code=503, detail="Run event store not available")
return store
def get_run_store(request: Request) -> RunStore:
"""Return the RunStore, or 503 if not available."""
store = getattr(request.app.state, "run_store", None)