From be37d543c3f5c00dc9a495f2d6138ef397f3f840 Mon Sep 17 00:00:00 2001 From: user Date: Mon, 15 Jun 2026 15:46:25 -0400 Subject: [PATCH 1/2] fix(frontend): restore chat history when returning to a session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace async params.then() + useState pattern with synchronous React.use(params) so projectName and sessionName are available from the first render. The previous pattern left both values as empty strings on mount, causing the AG-UI EventSource connection to be deferred until a second render cycle. On fast re-navigation this race could result in historical SSE events being missed and chat history not rendering. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../[name]/sessions/[sessionName]/page.tsx | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx b/components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx index 31357837c..60ab551bb 100755 --- a/components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx +++ b/components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, useEffect, useMemo, useRef, useCallback } from "react"; +import { use, useState, useEffect, useMemo, useRef, useCallback } from "react"; import { Loader2, PanelRight, @@ -117,9 +117,15 @@ export default function ProjectSessionDetailPage({ }) { const router = useRouter(); const queryClient = useQueryClient(); - const [projectName, setProjectName] = useState(""); - const [sessionName, setSessionName] = useState(""); - const [backHref, setBackHref] = useState(null); + const { name: projectName, sessionName } = use(params); + const backHref = useMemo(() => { + if (typeof window !== "undefined") { + try { + return new URL(window.location.href).searchParams.get("backHref"); + } catch {} + } + return null; + }, []); const [contextModalOpen, setContextModalOpen] = useState(false); const [uploadModalOpen, setUploadModalOpen] = useState(false); const [repoChanging, setRepoChanging] = useState(false); @@ -148,18 +154,6 @@ export default function ProjectSessionDetailPage({ const [customWorkflowDialogOpen, setCustomWorkflowDialogOpen] = useState(false); - // Extract params - useEffect(() => { - params.then(({ name, sessionName: sName }) => { - setProjectName(name); - setSessionName(sName); - try { - const url = new URL(window.location.href); - setBackHref(url.searchParams.get("backHref")); - } catch {} - }); - }, [params]); - // Session queue hook (localStorage-backed) const sessionQueue = useSessionQueue(projectName, sessionName); @@ -208,8 +202,8 @@ export default function ProjectSessionDetailPage({ // Note: autoConnect is intentionally false to avoid SSR hydration mismatch // Connection is triggered manually in useEffect after client hydration const aguiStream = useAGUIStream({ - projectName: projectName || "", - sessionName: sessionName || "", + projectName, + sessionName, autoConnect: false, // Manual connection after hydration onError: (err) => { console.error("AG-UI stream error:", err) From 9bfcaec7b5fb69cbb9904988bd7b68277b9bbdf6 Mon Sep 17 00:00:00 2001 From: user Date: Mon, 15 Jun 2026 16:39:10 -0400 Subject: [PATCH 2/2] fix(backend): include thread_id in between-run listener events URL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The between-run listener was calling GET /events without a thread_id path parameter, causing the runner to return 404 on every attempt. The runner endpoint requires GET /events/{thread_id}. Use the session name as the thread_id (matching the convention in HandleAGUIRunProxy). 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- components/backend/websocket/agui_proxy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/backend/websocket/agui_proxy.go b/components/backend/websocket/agui_proxy.go index 441ab7f53..b8c54b58b 100755 --- a/components/backend/websocket/agui_proxy.go +++ b/components/backend/websocket/agui_proxy.go @@ -1171,7 +1171,7 @@ func listenBetweenRunEvents(projectName, sessionName string) { for attempt := 0; attempt < betweenRunMaxRetries; attempt++ { runnerURL := getRunnerEndpoint(projectName, sessionName) - eventsURL := strings.TrimSuffix(runnerURL, "/") + "/events" + eventsURL := strings.TrimSuffix(runnerURL, "/") + "/events/" + sessionName req, err := http.NewRequest("GET", eventsURL, nil) if err != nil {