@@ -129,6 +131,7 @@ export function AgentThreadView({ thread }: AgentThreadViewProps) {
diff --git a/ui/src/components/agents/ported/MessageView.tsx b/ui/src/components/agents/ported/MessageView.tsx
index 64541f25..ca9e211e 100644
--- a/ui/src/components/agents/ported/MessageView.tsx
+++ b/ui/src/components/agents/ported/MessageView.tsx
@@ -297,6 +297,7 @@ export type MessageViewScrollControl = {
interface MessageViewProps extends ApprovalCallbacks {
messages: Message[];
isStreaming: boolean;
+ settingUpSandbox?: boolean;
project?: Project | null;
contentWidthClass?: string;
/** Horizontal padding on centered content (scroll track stays edge-to-edge). */
@@ -654,12 +655,19 @@ const MessageBubble = memo(function MessageBubble({
);
});
-function ThinkingSpinner({ isStreaming }: { isStreaming: boolean }) {
+function ThinkingSpinner({
+ isStreaming,
+ settingUpSandbox,
+}: {
+ isStreaming: boolean;
+ settingUpSandbox: boolean;
+}) {
const [textIdx, setTextIdx] = useState(0);
const [done, setDone] = useState<{ past: string; elapsed: string } | null>(null);
const startTimeRef = useRef(0);
const textIdxRef = useRef(textIdx);
const wasStreamingRef = useRef(false);
+ const settingUpSandboxRef = useRef(settingUpSandbox);
textIdxRef.current = textIdx;
useEffect(() => {
@@ -670,18 +678,24 @@ function ThinkingSpinner({ isStreaming }: { isStreaming: boolean }) {
setDone(null);
} else if (wasStreamingRef.current) {
setDone({
- past: BUSY_TEXTS[textIdxRef.current].past,
+ past: settingUpSandboxRef.current
+ ? "Set up sandbox"
+ : BUSY_TEXTS[textIdxRef.current].past,
elapsed: formatElapsed(Date.now() - startTimeRef.current),
});
}
}, [isStreaming]);
useEffect(() => {
- if (!isStreaming) return;
+ settingUpSandboxRef.current = settingUpSandbox;
+ }, [settingUpSandbox]);
+
+ useEffect(() => {
+ if (!isStreaming || settingUpSandbox) return;
const BUSY_TEXT_ROTATE_INTERVAL_MS = 12000;
const id = setInterval(() => setTextIdx((i) => (i + 1) % BUSY_TEXTS.length), BUSY_TEXT_ROTATE_INTERVAL_MS);
return () => clearInterval(id);
- }, [isStreaming]);
+ }, [isStreaming, settingUpSandbox]);
if (!isStreaming && !done) return null;
@@ -696,7 +710,9 @@ function ThinkingSpinner({ isStreaming }: { isStreaming: boolean }) {
return (
- {BUSY_TEXTS[textIdx].present}
+
+ {settingUpSandbox ? "Setting up sandbox..." : BUSY_TEXTS[textIdx].present}
+
);
}
@@ -706,6 +722,7 @@ const BOTTOM_LOCK_THRESHOLD_PX = 24;
export const MessageView = memo(function MessageView({
messages,
isStreaming,
+ settingUpSandbox = false,
project,
contentWidthClass = "max-w-[42rem]",
contentPaddingClass = "px-6",
@@ -885,7 +902,10 @@ export const MessageView = memo(function MessageView({
onOpenDiff={onOpenDiff}
/>
))}
-
+