From 4c8bd7b47ac0da6caab9099bf0acab119826f98b Mon Sep 17 00:00:00 2001 From: marko-kraemer Date: Thu, 8 May 2025 02:00:50 +0200 Subject: [PATCH] error msg toast on stream --- backend/agent/prompt.txt | 1 + backend/agent/run.py | 2 + .../utils/scripts/archive_old_sandboxes.py | 4 +- .../(dashboard)/agents/[threadId]/page.tsx | 7 +- frontend/src/app/share/[threadId]/page.tsx | 7 +- frontend/src/hooks/useAgentStream.ts | 65 +++++-------------- frontend/src/lib/api.ts | 16 +++++ 7 files changed, 43 insertions(+), 59 deletions(-) diff --git a/backend/agent/prompt.txt b/backend/agent/prompt.txt index 977bddc2..255daf2c 100644 --- a/backend/agent/prompt.txt +++ b/backend/agent/prompt.txt @@ -802,6 +802,7 @@ Ask user a question and wait for response. Use for: 1) Requesting clarification + \n Example: diff --git a/backend/agent/run.py b/backend/agent/run.py index 81795398..d3fc5717 100644 --- a/backend/agent/run.py +++ b/backend/agent/run.py @@ -187,6 +187,8 @@ async def run_agent( elif "gpt-4" in model_name.lower(): max_tokens = 4096 + model_name = "open123router/nvidia/llama-3.1-nemotron-ultra-253b-v1:free" + response = await thread_manager.run_thread( thread_id=thread_id, system_prompt=system_message, diff --git a/backend/utils/scripts/archive_old_sandboxes.py b/backend/utils/scripts/archive_old_sandboxes.py index 00573943..c0ebce9d 100644 --- a/backend/utils/scripts/archive_old_sandboxes.py +++ b/backend/utils/scripts/archive_old_sandboxes.py @@ -16,6 +16,8 @@ Make sure your environment variables are properly set: - DAYTONA_SERVER_URL """ +# TODO: SAVE THE LATEST SANDBOX STATE SOMEWHERE OR LIKE MASS CHECK THE STATE BEFORE STARTING TO ARCHIVE - AS ITS GOING TO GO OVER A BUNCH THAT ARE ALREADY ARCHIVED – MAYBE BEST TO GET ALL FROM DAYTONA AND THEN RUN THE ARCHIVE ONLY ON THE ONES THAT MEET THE CRITERIA (STOPPED STATE) + import asyncio import sys import os @@ -81,7 +83,7 @@ async def get_old_projects(days_threshold: int = 1) -> List[Dict[str, Any]]: 'created_at', 'account_id', 'sandbox' - ).range(start_range, end_range).execute() + ).order('created_at', desc=True).range(start_range, end_range).execute() # Debug info - print raw response print(f"Response data length: {len(result.data)}") diff --git a/frontend/src/app/(dashboard)/agents/[threadId]/page.tsx b/frontend/src/app/(dashboard)/agents/[threadId]/page.tsx index 6183eef9..3c701e20 100644 --- a/frontend/src/app/(dashboard)/agents/[threadId]/page.tsx +++ b/frontend/src/app/(dashboard)/agents/[threadId]/page.tsx @@ -487,12 +487,7 @@ export default function ThreadPage({ const handleStreamError = useCallback((errorMessage: string) => { console.error(`[PAGE] Stream hook error: ${errorMessage}`); - if ( - !errorMessage.toLowerCase().includes('not found') && - !errorMessage.toLowerCase().includes('agent run is not running') - ) { - toast.error(`Stream Error: ${errorMessage}`); - } + toast.error(errorMessage, { duration: 15000 }); }, []); const handleStreamClose = useCallback(() => { diff --git a/frontend/src/app/share/[threadId]/page.tsx b/frontend/src/app/share/[threadId]/page.tsx index 53d7eb87..b49b9bb8 100644 --- a/frontend/src/app/share/[threadId]/page.tsx +++ b/frontend/src/app/share/[threadId]/page.tsx @@ -428,10 +428,7 @@ export default function ThreadPage({ const handleStreamError = useCallback((errorMessage: string) => { console.error(`[PAGE] Stream hook error: ${errorMessage}`); - if (!errorMessage.toLowerCase().includes('not found') && - !errorMessage.toLowerCase().includes('agent run is not running')) { - toast.error(`Stream Error: ${errorMessage}`); - } + toast.error(errorMessage, { duration: 15000 }); }, []); const handleStreamClose = useCallback(() => { @@ -930,7 +927,7 @@ export default function ThreadPage({ try { const metadata = JSON.parse(toolMsg.metadata); return metadata.assistant_message_id === assistantMsg.message_id; - } catch (e) { + } catch { return false; } }); diff --git a/frontend/src/hooks/useAgentStream.ts b/frontend/src/hooks/useAgentStream.ts index 8d830bcf..74406cb0 100644 --- a/frontend/src/hooks/useAgentStream.ts +++ b/frontend/src/hooks/useAgentStream.ts @@ -252,6 +252,21 @@ export function useAgentStream( return; } + // --- Check for error messages first --- + try { + const jsonData = JSON.parse(processedData); + if (jsonData.status === 'error') { + console.error('[useAgentStream] Received error status message:', jsonData); + const errorMessage = jsonData.message || 'Unknown error occurred'; + setError(errorMessage); + toast.error(errorMessage, { duration: 15000 }); + callbacks.onError?.(errorMessage); + return; + } + } catch (jsonError) { + // Not JSON or could not parse as JSON, continue processing + } + // --- Process JSON messages --- const message: UnifiedMessage = safeJsonParse(processedData, null); if (!message) { @@ -379,6 +394,9 @@ export function useAgentStream( console.error('[useAgentStream] Streaming error:', errorMessage, err); setError(errorMessage); + + // Show error toast with longer duration + toast.error(errorMessage, { duration: 15000 }); const runId = currentRunIdRef.current; if (!runId) { @@ -389,53 +407,6 @@ export function useAgentStream( return; } - // Check agent status immediately after an error - getAgentStatus(runId) - .then((agentStatus) => { - if (!isMountedRef.current) return; // Check mount status again after async call - - if (agentStatus.status === 'running') { - console.warn( - `[useAgentStream] Stream error for ${runId}, but agent is still running. Finalizing with error.`, - ); - finalizeStream('error', runId); // Stream failed, even if agent might still be running backend-side - toast.warning('Stream interrupted. Agent might still be running.'); - } else { - // Map backend terminal status to hook terminal status - const finalStatus = mapAgentStatus(agentStatus.status); - console.log( - `[useAgentStream] Stream error for ${runId}, agent status is ${agentStatus.status}. Finalizing stream as ${finalStatus}.`, - ); - finalizeStream(finalStatus, runId); - } - }) - .catch((statusError) => { - if (!isMountedRef.current) return; - - const statusErrorMessage = - statusError instanceof Error - ? statusError.message - : String(statusError); - console.error( - `[useAgentStream] Error checking agent status for ${runId} after stream error: ${statusErrorMessage}`, - ); - - const isNotFoundError = - statusErrorMessage.includes('not found') || - statusErrorMessage.includes('404') || - statusErrorMessage.includes('does not exist'); - - if (isNotFoundError) { - console.log( - `[useAgentStream] Agent run ${runId} not found after stream error. Finalizing.`, - ); - // Revert to agent_not_running for this specific case - finalizeStream('agent_not_running', runId); - } else { - // For other status check errors, finalize with the original stream error - finalizeStream('error', runId); - } - }); }, [finalizeStream], ); diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 18b2fa32..d52e0b5c 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -859,6 +859,22 @@ export const streamAgent = ( return; } + // Check for error status messages + try { + const jsonData = JSON.parse(rawData); + if (jsonData.status === 'error') { + console.error(`[STREAM] Error status received for ${agentRunId}:`, jsonData); + + // Pass the error message to the callback + callbacks.onError(jsonData.message || 'Unknown error occurred'); + + // Don't close the stream for error status messages as they may continue + return; + } + } catch (jsonError) { + // Not JSON or invalid JSON, continue with normal processing + } + // Check for "Agent run not found" error if ( rawData.includes('Agent run') &&