Skip to content

Commit 8a35e14

Browse files
MH4GFclaude
andcommitted
Improve workflow reconnection handling
Separate workflow completion from abortion to preserve reconnection ability. When a workflow is aborted or errors, keep the in-progress flag so users can reconnect on page reload. Only clear the flag when workflow completes successfully. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 2a6c788 commit 8a35e14

File tree

2 files changed

+17
-11
lines changed

2 files changed

+17
-11
lines changed

frontend/apps/app/components/SessionDetailPage/hooks/useStream/useStream.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,20 @@ export const useStream = ({ designSessionId, initialMessages }: Props) => {
8181
const abortRef = useRef<AbortController | null>(null)
8282
const retryCountRef = useRef(0)
8383

84-
const finalizeStream = useCallback((sessionId: string) => {
84+
const completeWorkflow = useCallback((sessionId: string) => {
8585
setIsStreaming(false)
8686
abortRef.current = null
8787
retryCountRef.current = 0
88-
89-
// Clear workflow in progress flag
9088
clearWorkflowInProgress(sessionId)
9189
}, [])
9290

91+
const abortWorkflow = useCallback(() => {
92+
setIsStreaming(false)
93+
abortRef.current = null
94+
retryCountRef.current = 0
95+
// Do NOT clear workflow flag - allow reconnection
96+
}, [])
97+
9398
const stop = useCallback(() => {
9499
abortRef.current?.abort()
95100
abortRef.current = null
@@ -180,7 +185,7 @@ export const useStream = ({ designSessionId, initialMessages }: Props) => {
180185
})
181186

182187
if (!res.body) {
183-
finalizeStream(params.designSessionId)
188+
abortWorkflow()
184189
return err({
185190
type: 'network',
186191
message: ERROR_MESSAGES.FETCH_FAILED,
@@ -192,7 +197,7 @@ export const useStream = ({ designSessionId, initialMessages }: Props) => {
192197

193198
if (!endEventReceived) {
194199
if (controller.signal.aborted) {
195-
finalizeStream(params.designSessionId)
200+
abortWorkflow()
196201
return err({
197202
type: 'abort',
198203
message: 'Request was aborted',
@@ -204,10 +209,10 @@ export const useStream = ({ designSessionId, initialMessages }: Props) => {
204209
return ok('shouldRetry')
205210
}
206211

207-
finalizeStream(params.designSessionId)
212+
completeWorkflow(params.designSessionId)
208213
return ok('complete')
209214
} catch (unknownError) {
210-
finalizeStream(params.designSessionId)
215+
abortWorkflow()
211216

212217
if (
213218
unknownError instanceof Error &&
@@ -225,7 +230,7 @@ export const useStream = ({ designSessionId, initialMessages }: Props) => {
225230
})
226231
}
227232
},
228-
[finalizeStream, processStreamEvents],
233+
[completeWorkflow, abortWorkflow, processStreamEvents],
229234
)
230235

231236
const replay = useCallback(
@@ -245,14 +250,14 @@ export const useStream = ({ designSessionId, initialMessages }: Props) => {
245250
}
246251

247252
const timeoutMessage = ERROR_MESSAGES.CONNECTION_TIMEOUT
248-
finalizeStream(params.designSessionId)
253+
abortWorkflow()
249254
setError(timeoutMessage)
250255
return err({
251256
type: 'timeout',
252257
message: timeoutMessage,
253258
})
254259
},
255-
[finalizeStream, runStreamAttempt],
260+
[abortWorkflow, runStreamAttempt],
256261
)
257262

258263
const start = useCallback(

frontend/apps/app/components/SessionDetailPage/utils/workflowStorage.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ const WORKFLOW_KEY_PREFIX = 'liam:workflow:'
66
export const getWorkflowInProgress = (designSessionId: string): boolean => {
77
if (typeof window === 'undefined') return false
88
const key = `${WORKFLOW_KEY_PREFIX}${designSessionId}`
9-
return sessionStorage.getItem(key) === 'in_progress'
9+
const value = sessionStorage.getItem(key)
10+
return value === 'in_progress'
1011
}
1112

1213
/**

0 commit comments

Comments
 (0)