mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-05-24 08:55:59 +00:00
feat(persistence): add user feedback + follow-up run association
Phase 2-C: feedback and follow-up tracking. - FeedbackRow ORM model (rating +1/-1, optional message_id, comment) - FeedbackRepository with CRUD, list_by_run/thread, aggregate stats - Feedback API endpoints: create, list, stats, delete - follow_up_to_run_id in RunCreateRequest (explicit or auto-detected from latest successful run on the thread) - Worker writes follow_up_to_run_id into human_message event metadata - Gateway deps: feedback_repo factory + getter - 17 new tests (14 FeedbackRepository + 3 follow-up association) - 109 total tests pass, zero regressions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,9 @@ async def langgraph_runtime(app: FastAPI) -> AsyncGenerator[None, None]:
|
||||
# Initialize run event store based on config
|
||||
app.state.run_event_store = _make_run_event_store(config)
|
||||
|
||||
# Initialize feedback repository (None when no DB engine)
|
||||
app.state.feedback_repo = _make_feedback_repo()
|
||||
|
||||
# RunManager with store backing for persistence
|
||||
app.state.run_manager = RunManager(store=app.state.run_store)
|
||||
|
||||
@@ -74,6 +77,18 @@ def _make_run_store() -> RunStore:
|
||||
return MemoryRunStore()
|
||||
|
||||
|
||||
def _make_feedback_repo():
|
||||
"""Create a FeedbackRepository if DB engine is available, else None."""
|
||||
from deerflow.persistence.engine import get_session_factory
|
||||
|
||||
sf = get_session_factory()
|
||||
if sf is not None:
|
||||
from deerflow.persistence.repositories.feedback_repo import FeedbackRepository
|
||||
|
||||
return FeedbackRepository(sf)
|
||||
return None
|
||||
|
||||
|
||||
def _make_run_event_store(config) -> RunEventStore:
|
||||
from deerflow.runtime.events.store import make_run_event_store
|
||||
|
||||
@@ -123,6 +138,14 @@ def get_run_event_store(request: Request) -> RunEventStore:
|
||||
return store
|
||||
|
||||
|
||||
def get_feedback_repo(request: Request):
|
||||
"""Return the FeedbackRepository, or 503 if not available."""
|
||||
repo = getattr(request.app.state, "feedback_repo", None)
|
||||
if repo is None:
|
||||
raise HTTPException(status_code=503, detail="Feedback not available")
|
||||
return repo
|
||||
|
||||
|
||||
def get_run_store(request: Request) -> RunStore:
|
||||
"""Return the RunStore, or 503 if not available."""
|
||||
store = getattr(request.app.state, "run_store", None)
|
||||
|
||||
Reference in New Issue
Block a user