mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-04 11:22:10 +00:00
fix: prevent thread prefetches from marking threads viewed (#1456)
* fix: prevent thread prefetches from marking threads viewed Sidebar prefetches now request thread details with mark_viewed=false so loading /agents no longer clears the unread/finished indicator for threads the user has not opened. Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com> * fix: always refetch active thread on mount to mark viewed Prefetches cache details fetched with mark_viewed=false under the same query key as the active thread. Forcing refetchOnMount="always" ensures opening a thread issues a mark_viewed=true request, so last_viewed_* is recorded even when prefetched data is still fresh. Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com> --------- Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This commit is contained in:
parent
85049290a3
commit
8fc06dac8a
5 changed files with 36 additions and 6 deletions
|
|
@ -783,9 +783,15 @@ async def api_create_thread(
|
||||||
@router.get("/threads/{thread_id}")
|
@router.get("/threads/{thread_id}")
|
||||||
async def api_get_thread(
|
async def api_get_thread(
|
||||||
thread_id: str,
|
thread_id: str,
|
||||||
|
mark_viewed: bool = True,
|
||||||
session: dict[str, Any] = _SESSION_DEP,
|
session: dict[str, Any] = _SESSION_DEP,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
return await get_dashboard_thread(thread_id, session["sub"], email=session.get("email"))
|
return await get_dashboard_thread(
|
||||||
|
thread_id,
|
||||||
|
session["sub"],
|
||||||
|
email=session.get("email"),
|
||||||
|
mark_viewed=mark_viewed,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/threads/{thread_id}/messages")
|
@router.post("/threads/{thread_id}/messages")
|
||||||
|
|
|
||||||
|
|
@ -420,7 +420,7 @@ async def _mark_thread_viewed(
|
||||||
|
|
||||||
|
|
||||||
async def get_dashboard_thread(
|
async def get_dashboard_thread(
|
||||||
thread_id: str, login: str, *, email: str | None = None
|
thread_id: str, login: str, *, email: str | None = None, mark_viewed: bool = True
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
client = langgraph_client()
|
client = langgraph_client()
|
||||||
try:
|
try:
|
||||||
|
|
@ -456,7 +456,7 @@ async def get_dashboard_thread(
|
||||||
else None
|
else None
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
if status != "running":
|
if mark_viewed and status != "running":
|
||||||
metadata = await _mark_thread_viewed(
|
metadata = await _mark_thread_viewed(
|
||||||
client,
|
client,
|
||||||
thread_id,
|
thread_id,
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,25 @@ async def test_get_dashboard_thread_marks_finished_thread_viewed(monkeypatch) ->
|
||||||
assert client.threads.thread["metadata"]["last_viewed_run_id"] == "run-1"
|
assert client.threads.thread["metadata"]["last_viewed_run_id"] == "run-1"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_get_dashboard_thread_skips_mark_viewed_when_disabled(monkeypatch) -> None:
|
||||||
|
client = FakeClient(
|
||||||
|
{
|
||||||
|
"source": "dashboard",
|
||||||
|
"github_login": "octocat",
|
||||||
|
"latest_run_id": "run-1",
|
||||||
|
"latest_run_status": "success",
|
||||||
|
},
|
||||||
|
"success",
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(thread_api, "langgraph_client", lambda: client)
|
||||||
|
|
||||||
|
result = await thread_api.get_dashboard_thread("tid", "octocat", mark_viewed=False)
|
||||||
|
|
||||||
|
assert result["status"] == "finished"
|
||||||
|
assert result["viewed"] is False
|
||||||
|
assert "last_viewed_run_id" not in client.threads.thread["metadata"]
|
||||||
|
|
||||||
|
|
||||||
async def test_get_dashboard_thread_does_not_mark_running_thread_viewed(monkeypatch) -> None:
|
async def test_get_dashboard_thread_does_not_mark_running_thread_viewed(monkeypatch) -> None:
|
||||||
client = FakeClient(
|
client = FakeClient(
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -93,8 +93,12 @@ export const agentsApi = {
|
||||||
agentsRequest<void>(`/schedules/${encodeURIComponent(scheduleId)}`, {
|
agentsRequest<void>(`/schedules/${encodeURIComponent(scheduleId)}`, {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
}),
|
}),
|
||||||
getThread: (threadId: string) =>
|
getThread: (threadId: string, options?: { markViewed?: boolean }) =>
|
||||||
agentsRequest<AgentThread>(`/threads/${encodeURIComponent(threadId)}`),
|
agentsRequest<AgentThread>(
|
||||||
|
`/threads/${encodeURIComponent(threadId)}${
|
||||||
|
options?.markViewed === false ? "?mark_viewed=false" : ""
|
||||||
|
}`
|
||||||
|
),
|
||||||
createThread: (body: ThreadCreateRequest) =>
|
createThread: (body: ThreadCreateRequest) =>
|
||||||
agentsRequest<AgentThread>("/threads", {
|
agentsRequest<AgentThread>("/threads", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ export function usePrefetchAgentThreadDetails(
|
||||||
threadIds.forEach((threadId) => {
|
threadIds.forEach((threadId) => {
|
||||||
void queryClient.prefetchQuery({
|
void queryClient.prefetchQuery({
|
||||||
queryKey: agentThreadKeys.detail(threadId),
|
queryKey: agentThreadKeys.detail(threadId),
|
||||||
queryFn: () => agentsApi.getThread(threadId),
|
queryFn: () => agentsApi.getThread(threadId, { markViewed: false }),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}, [activeThreadId, queryClient, threads])
|
}, [activeThreadId, queryClient, threads])
|
||||||
|
|
@ -54,6 +54,7 @@ export function useAgentThread(threadId: string) {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: agentThreadKeys.detail(threadId),
|
queryKey: agentThreadKeys.detail(threadId),
|
||||||
queryFn: () => agentsApi.getThread(threadId),
|
queryFn: () => agentsApi.getThread(threadId),
|
||||||
|
refetchOnMount: "always",
|
||||||
refetchInterval: (query) => {
|
refetchInterval: (query) => {
|
||||||
const status = query.state.data?.status
|
const status = query.state.data?.status
|
||||||
return status === "running" ? 2000 : false
|
return status === "running" ? 2000 : false
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue