diff --git a/apps/web/src/components/ui/alert.tsx b/apps/web/src/components/ui/alert.tsx
index aa7de24d..8bdbbe3f 100644
--- a/apps/web/src/components/ui/alert.tsx
+++ b/apps/web/src/components/ui/alert.tsx
@@ -8,9 +8,14 @@ const alertVariants = cva(
{
variants: {
variant: {
- default: "bg-card text-card-foreground",
+ default: "bg-card text-card-foreground border-border",
destructive:
- "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90",
+ "border-destructive/50 bg-destructive/10 text-destructive dark:border-red-400 dark:bg-red-950/50 dark:text-red-300 [&>svg]:text-destructive dark:[&>svg]:text-red-400",
+ warning:
+ "border-yellow-500/50 bg-yellow-50 text-yellow-900 dark:border-yellow-500 dark:bg-yellow-950 dark:text-yellow-100 [&>svg]:text-yellow-600 dark:[&>svg]:text-yellow-400",
+ info: "border-blue-500/50 bg-blue-50 text-blue-900 dark:border-blue-500 dark:bg-blue-950 dark:text-blue-100 [&>svg]:text-blue-600 dark:[&>svg]:text-blue-400",
+ success:
+ "border-green-500/50 bg-green-50 text-green-900 dark:border-green-500 dark:bg-green-950 dark:text-green-100 [&>svg]:text-green-600 dark:[&>svg]:text-green-400",
},
},
defaultVariants: {
@@ -27,6 +32,7 @@ function Alert({
return (
({
);
const joinedRunId = useRef
(undefined);
const [streamLoading, setStreamLoading] = useState(false);
+ const [errorMessage, setErrorMessage] = useState("");
const stream = useStream({
apiUrl: process.env.NEXT_PUBLIC_API_URL,
@@ -130,6 +133,18 @@ export function ActionsRenderer({
fetchStateHistory: false,
});
+ useEffect(() => {
+ if (stream.error) {
+ const errorMessage =
+ typeof stream.error === "object" && "message" in stream.error
+ ? (stream.error.message as string)
+ : "An unknown error occurred in the manager";
+ setErrorMessage(errorMessage);
+ } else {
+ setErrorMessage("");
+ }
+ }, [stream.error]);
+
const { cancelRun } = useCancelStream({
stream,
threadId,
@@ -304,6 +319,13 @@ export function ActionsRenderer({
thread={stream as UseStream>}
/>
) : null}
+ {errorMessage ? (
+
+
+ An error occurred:
+ {errorMessage}
+
+ ) : null}
);
}
diff --git a/apps/web/src/components/v2/manager-chat.tsx b/apps/web/src/components/v2/manager-chat.tsx
index 0c3fb6a9..45950b1e 100644
--- a/apps/web/src/components/v2/manager-chat.tsx
+++ b/apps/web/src/components/v2/manager-chat.tsx
@@ -5,12 +5,21 @@ import { useState } from "react";
import { StickToBottom } from "use-stick-to-bottom";
import { TooltipIconButton } from "../ui/tooltip-icon-button";
import { AnimatePresence, motion } from "framer-motion";
-import { Bot, Copy, CopyCheck, Send, User, Loader2 } from "lucide-react";
+import {
+ Bot,
+ Copy,
+ CopyCheck,
+ Send,
+ User,
+ Loader2,
+ AlertCircle,
+} from "lucide-react";
import { Textarea } from "../ui/textarea";
import { Button } from "../ui/button";
import { cn } from "@/lib/utils";
import { isAIMessageSDK } from "@/lib/langchain-messages";
import { BasicMarkdownText } from "../thread/markdown-text";
+import { Alert, AlertDescription, AlertTitle } from "../ui/alert";
function MessageCopyButton({ content }: { content: string }) {
const [copied, setCopied] = useState(false);
@@ -66,6 +75,7 @@ interface ManagerChatProps {
handleSendMessage: () => void;
isLoading: boolean;
cancelRun: () => void;
+ errorMessage?: string;
}
function extractResponseFromMessage(message: Message): string {
@@ -88,6 +98,7 @@ export function ManagerChat({
handleSendMessage,
isLoading,
cancelRun,
+ errorMessage,
}: ManagerChatProps) {
return (
@@ -136,6 +147,13 @@ export function ManagerChat({
);
})}
+ {errorMessage ? (
+
+
+ An error occurred:
+ {errorMessage}
+
+ ) : null}
>
}
footer={
diff --git a/apps/web/src/components/v2/thread-view.tsx b/apps/web/src/components/v2/thread-view.tsx
index 12f0f252..46ced88b 100644
--- a/apps/web/src/components/v2/thread-view.tsx
+++ b/apps/web/src/components/v2/thread-view.tsx
@@ -52,6 +52,7 @@ export function ThreadView({
useState();
const [programmerSession, setProgrammerSession] =
useState();
+ const [errorMessage, setErrorMessage] = useState("");
useEffect(() => {
if (
@@ -69,6 +70,18 @@ export function ThreadView({
}
}, [stream?.values]);
+ useEffect(() => {
+ if (stream.error) {
+ const errorMessage =
+ typeof stream.error === "object" && "message" in stream.error
+ ? (stream.error.message as string)
+ : "An unknown error occurred in the manager";
+ setErrorMessage(errorMessage);
+ } else {
+ setErrorMessage("");
+ }
+ }, [stream.error]);
+
const { status: realTimeStatus } = useThreadStatus(displayThread.id);
const getStatusDotColor = (status: string) => {
@@ -170,6 +183,7 @@ export function ThreadView({
handleSendMessage={handleSendMessage}
isLoading={stream.isLoading}
cancelRun={cancelRun}
+ errorMessage={errorMessage}
/>
{/* Right Side - Actions & Plan */}