refactor(persistence): introduce ThreadMetaStore ABC for backend-agnostic thread metadata

Add ThreadMetaStore abstract base class with create/get/search/update/delete
interface. ThreadMetaRepository (SQL) now inherits from it. New
MemoryThreadMetaStore wraps LangGraph BaseStore for memory-mode deployments.

deps.py now always provides a non-None thread_meta_repo, eliminating all
`if thread_meta_repo is not None` guards in services.py, worker.py, and
routers/threads.py. search_threads no longer needs a Store fallback branch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
rayhpeng
2026-04-06 17:45:41 +08:00
parent 51c68db376
commit 29547c0ee4
7 changed files with 203 additions and 78 deletions
+3 -4
View File
@@ -54,11 +54,12 @@ async def langgraph_runtime(app: FastAPI) -> AsyncGenerator[None, None]:
app.state.feedback_repo = FeedbackRepository(sf)
app.state.thread_meta_repo = ThreadMetaRepository(sf)
else:
from deerflow.persistence.repositories.thread_meta_memory import MemoryThreadMetaStore
from deerflow.runtime.runs.store.memory import MemoryRunStore
app.state.run_store = MemoryRunStore()
app.state.feedback_repo = None
app.state.thread_meta_repo = None
app.state.thread_meta_repo = MemoryThreadMetaStore(app.state.store)
# Run event store (has its own factory with config-driven backend selection)
run_events_config = getattr(config, "run_events", None)
@@ -104,9 +105,7 @@ def get_store(request: Request):
return getattr(request.app.state, "store", None)
def get_thread_meta_repo(request: Request):
"""Return the ThreadMetaRepository, or None if not available."""
return getattr(request.app.state, "thread_meta_repo", None)
get_thread_meta_repo = _require("thread_meta_repo", "Thread metadata store")
def get_run_context(request: Request) -> RunContext: