diff --git a/backend/app/gateway/routers/thread_runs.py b/backend/app/gateway/routers/thread_runs.py index a8e6cb94c..8f81fc7fb 100644 --- a/backend/app/gateway/routers/thread_runs.py +++ b/backend/app/gateway/routers/thread_runs.py @@ -646,6 +646,10 @@ async def list_thread_messages( event_store = get_run_event_store(request) messages = await event_store.list_messages(thread_id, limit=limit, before_seq=before_seq, after_seq=after_seq) + # Resolve the caller once; it is needed both to scope the feedback query + # below and to list the thread's runs for turn-duration injection. + user_id = await get_current_user(request) + # Find the last AI message per run_id. AI messages are persisted by # RunJournal with event_type "llm.ai.response" (see runtime/journal.py); # the event store returns that value verbatim, so match on it here. @@ -660,7 +664,6 @@ async def list_thread_messages( feedback_map: dict[str, dict] = {} if last_ai_per_run: feedback_repo = get_feedback_repo(request) - user_id = await get_current_user(request) feedback_map = await feedback_repo.list_by_thread_grouped(thread_id, user_id=user_id) last_ai_indices = set(last_ai_per_run.values()) diff --git a/backend/tests/test_thread_messages_feedback.py b/backend/tests/test_thread_messages_feedback.py index b539a5912..027fac0f3 100644 --- a/backend/tests/test_thread_messages_feedback.py +++ b/backend/tests/test_thread_messages_feedback.py @@ -29,6 +29,12 @@ def _make_app(messages, feedback_grouped): feedback_repo.list_by_thread_grouped = AsyncMock(return_value=feedback_grouped) app.state.feedback_repo = feedback_repo + # list_thread_messages also calls run_manager.list_by_thread to inject + # turn durations; stub it to return no runs so that path stays inert. + run_manager = MagicMock() + run_manager.list_by_thread = AsyncMock(return_value=[]) + app.state.run_manager = run_manager + return app, feedback_repo