diff --git a/apps/web/src/components/chat/ChatComposer.tsx b/apps/web/src/components/chat/ChatComposer.tsx
index d7878cc29a165..66b575360f5e5 100644
--- a/apps/web/src/components/chat/ChatComposer.tsx
+++ b/apps/web/src/components/chat/ChatComposer.tsx
@@ -276,6 +276,7 @@ import {
usePreparingComposerImages,
} from "./preparingComposerImages";
import { ComposerControlsBar } from "./ComposerControlsBar";
+import { ComposerInteractionModeToggle } from "./ComposerInteractionModeToggle";
import { composerCommandKeyHandler } from "./composerCommandKey";
function consumePasteAsTextShortcut(deadline: { current: number }): boolean {
@@ -3429,7 +3430,17 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
showMobilePendingAnswerActions && "hidden sm:flex",
)}
>
- {composerAttachButton ?
{composerAttachButton}
: null}
+ {composerAttachButton || planModeUiEnabled ? (
+
+ {composerAttachButton}
+ {planModeUiEnabled ? (
+
+ ) : null}
+
+ ) : null}
option.mode === props.runtimeMode) ??
supervisedRuntimeModeOption;
const RuntimeModeIcon = runtimeModeOption.icon;
- const interactionModeTooltip =
- props.interactionMode === "plan"
- ? "Plan mode. Click to return to normal build mode"
- : "Default mode. Click to enter plan mode";
-
const interactionModeToggle = props.showInteractionModeToggle ? (
-
-
- }
- >
- {props.interactionMode === "plan" ? (
-
- ) : (
-
- )}
- {/* The compacted row (xs) keeps this icon-only, like the other controls there. */}
-
- {props.interactionMode === "plan" ? "Plan" : "Build"}
-
-
- {interactionModeTooltip}
-
+
) : null;
// The chip opens the same Permissions toggle used in the effort menu.
diff --git a/apps/web/src/components/chat/ComposerInteractionModeToggle.tsx b/apps/web/src/components/chat/ComposerInteractionModeToggle.tsx
new file mode 100644
index 0000000000000..24a4517a77d70
--- /dev/null
+++ b/apps/web/src/components/chat/ComposerInteractionModeToggle.tsx
@@ -0,0 +1,56 @@
+import type { ProviderInteractionMode } from "@t3tools/contracts";
+import { BotIcon, PencilRulerIcon } from "lucide-react";
+import { memo } from "react";
+
+import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
+import { ComposerControl, ComposerControlIcon, type ComposerControlSize } from "./ComposerControl";
+
+/** Build shows only its icon; Plan also names itself, so the non-default mode is never missed. */
+export const ComposerInteractionModeToggle = memo(function ComposerInteractionModeToggle(props: {
+ interactionMode: ProviderInteractionMode;
+ size?: ComposerControlSize;
+ onToggle: () => void;
+}) {
+ const size = props.size ?? "sm";
+ const isPlan = props.interactionMode === "plan";
+ const tooltip = isPlan
+ ? "Plan mode. Click to return to normal build mode"
+ : "Build mode. Click to enter plan mode";
+ return (
+
+
+ }
+ >
+ {isPlan ? (
+
+ ) : (
+
+ )}
+ {/* The compacted row (xs) keeps this icon-only, like the other controls there. */}
+ {isPlan ? (
+
+ Plan
+
+ ) : null}
+
+ {tooltip}
+
+ );
+});