diff --git a/public/next.svg b/public/next.svg
deleted file mode 100644
index 5174b28c..00000000
--- a/public/next.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/vercel.svg b/public/vercel.svg
deleted file mode 100644
index 77053960..00000000
--- a/public/vercel.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/window.svg b/public/window.svg
deleted file mode 100644
index b2b2a44f..00000000
--- a/public/window.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/app/globals.css b/src/app/globals.css
index a52855ec..dc0cf2bf 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -986,6 +986,33 @@
/* indigo-500 */
}
+.markdown-content hr {
+ border: none;
+ height: 1px;
+ background-color: rgba(0, 0, 0, 0.1);
+ margin: 1.5rem 0;
+}
+
+.dark .markdown-content hr {
+ background-color: rgba(255, 255, 255, 0.1);
+}
+
+.markdown-content[data-message-mode="sentinel"] hr {
+ background-color: rgba(99, 102, 241, 0.3);
+}
+
+.dark .markdown-content[data-message-mode="sentinel"] hr {
+ background-color: rgba(99, 102, 241, 0.3);
+}
+
+.markdown-content[data-message-mode="morpheus"] hr {
+ background-color: rgba(71, 216, 163, 0.3);
+}
+
+.dark .markdown-content[data-message-mode="morpheus"] hr {
+ background-color: rgba(71, 216, 163, 0.3);
+}
+
.markdown-content ul,
.markdown-content ul:first-child,
.markdown-content ul:last-child {
@@ -1014,7 +1041,7 @@
background-color: white !important;
border-bottom: 1px solid rgba(0, 0, 0, 0.1) !important;
}
-
+
.dark .header-transparent header {
background-color: black !important;
border-bottom: 1px solid rgba(255, 255, 255, 0.1) !important;
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 05278150..380cc1c7 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -61,7 +61,7 @@ export default function RootLayout({
`}
{children}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index bc389992..2005cee8 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -13,7 +13,7 @@ import { useDisconnectedDarkMode } from "@/hooks/useDisconnectedDarkMode";
import { useChat } from "@/contexts/chat-context";
export default function HomePage() {
- const { isConnected, isConnecting, isReconnecting } = useAccount();
+ const { isConnected } = useAccount();
const { handleNavigateToRoot } = useChat();
React.useEffect(() => {
@@ -22,16 +22,18 @@ export default function HomePage() {
useDisconnectedDarkMode(isConnected);
- if (!isConnected && !isConnecting && !isReconnecting) {
- return ;
- }
-
return (
<>
-
-
-
-
+
+
+ {!isConnected && (
+ <>
+
+
+ >
+ )}
+
+ {isConnected && }
>
);
}
diff --git a/src/app/template.tsx b/src/app/template.tsx
index f19be732..7c211c81 100644
--- a/src/app/template.tsx
+++ b/src/app/template.tsx
@@ -25,7 +25,7 @@ export default function AppTemplate({
}, []);
return (
-
+
+
{showInput && (
{/* Dynamic title */}
{modeTitle}
@@ -108,7 +108,6 @@ export function RootLayout() {
/>
- {/* Example queries */}
void;
onSubmit?: (e: FormEvent) => Promise;
- isInChatMode?: boolean;
showReloadButton?: boolean;
className?: string;
}
@@ -52,7 +51,6 @@ export default function BaseChatInput({
initialMode = "morpheus",
onSubmitMessage,
onSubmit,
- isInChatMode = false,
showReloadButton = false,
className = "",
}: BaseChatInputProps) {
@@ -232,7 +230,7 @@ export default function BaseChatInput({
variants={containerVariants}
initial="hidden"
animate="visible"
- className={`relative ${isInChatMode ? "mb-[1px]" : ""} ${className}`}
+ className={`relative ${className}`}
>
{/* Action Buttons - Positioned inside the chat input */}
@@ -376,20 +374,19 @@ export default function BaseChatInput({
{/* Input field with glow effect */}
{/* Mode Toggle Buttons - Bottom left */}
diff --git a/src/components/chat/chat-input.tsx b/src/components/chat/chat-input.tsx
index 08bbd421..30a39197 100644
--- a/src/components/chat/chat-input.tsx
+++ b/src/components/chat/chat-input.tsx
@@ -81,7 +81,6 @@ export default function ChatInput({
initialMode={initialMode}
onSubmitMessage={onSubmitMessage}
onSubmit={onSubmit}
- isInChatMode={true}
showReloadButton={!isPendingResponse}
className={className}
/>
diff --git a/src/components/chat/example-queries.tsx b/src/components/chat/example-queries.tsx
index f7a711fa..4d96b34d 100644
--- a/src/components/chat/example-queries.tsx
+++ b/src/components/chat/example-queries.tsx
@@ -1,14 +1,16 @@
"use client";
import * as React from "react";
-import { useState } from "react";
+import { useEffect, useRef, useState } from "react";
-import { AnimatePresence, motion } from "framer-motion";
-import { ArrowRight, BookOpen, Database, Info } from "lucide-react";
+import { motion } from "framer-motion";
+import { ArrowRight, BookOpen, Database, Info, X } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
+import { cn } from "@/lib/utils";
+
interface ExampleQueriesProps {
onSelect: (query: string) => void;
activeMode?: "morpheus" | "sentinel";
@@ -23,12 +25,29 @@ export function ExampleQueries({
const [currentMode, setCurrentMode] = useState<"morpheus" | "sentinel">(
activeMode
);
+ const [activeMenu, setActiveMenu] = useState<"morpheus" | "sentinel" | null>(
+ null
+ );
+ const containerRef = useRef
(null);
+ const menuRef = useRef(null);
- // Sync with parent component's activeMode
- React.useEffect(() => {
+ useEffect(() => {
setCurrentMode(activeMode);
}, [activeMode]);
+ useEffect(() => {
+ const handleClickOutside = (event: MouseEvent) => {
+ if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
+ setActiveMenu(null);
+ }
+ };
+
+ document.addEventListener("mousedown", handleClickOutside);
+ return () => {
+ document.removeEventListener("mousedown", handleClickOutside);
+ };
+ }, []);
+
const queries = {
morpheus: [
"What is the sentiment around $BTC this week?",
@@ -48,324 +67,295 @@ export function ExampleQueries({
],
};
- const QueryButton = ({ query }: { query: string }) => {
- if (!query) return ;
-
- const handleClick = () => {
- onSelect(query);
- };
-
- // Determine style based on active mode
- const activeStyles =
- currentMode === "morpheus"
- ? {
- buttonBg: "bg-white/30 dark:bg-black/30 backdrop-blur-sm",
- buttonHoverBg:
- "hover:bg-emerald-50/40 dark:hover:bg-emerald-950/20",
- buttonBorder:
- "border border-emerald-300/70 dark:border-emerald-500/20",
- buttonHoverBorder:
- "hover:border-emerald-400/80 dark:hover:border-emerald-400/30",
- buttonText: "text-gray-800 dark:text-gray-200",
- buttonHoverText:
- "hover:text-emerald-800 dark:hover:text-emerald-300",
- gradientFrom: "from-emerald-100/40 dark:from-emerald-400/20",
- }
- : {
- buttonBg: "bg-white/30 dark:bg-black/30 backdrop-blur-sm",
- buttonHoverBg: "hover:bg-indigo-50/40 dark:hover:bg-indigo-950/20",
- buttonBorder:
- "border border-indigo-300/70 dark:border-indigo-500/20",
- buttonHoverBorder:
- "hover:border-indigo-400/80 dark:hover:border-indigo-400/30",
- buttonText: "text-gray-800 dark:text-gray-200",
- buttonHoverText: "hover:text-indigo-800 dark:hover:text-indigo-300",
- gradientFrom: "from-indigo-100/40 dark:from-indigo-400/20",
- };
+ const QueryItem = ({ query }: { query: string }) => {
+ if (!query) return null;
return (
{
+ if (activeMenu && onModeSelect && currentMode !== activeMenu) {
+ onModeSelect(activeMenu);
+ }
+ onSelect(query);
+ setActiveMenu(null);
+ }}
+ className={`text-left px-3 py-2 text-sm rounded-md w-full transition-colors cursor-pointer ${
+ activeMenu === "sentinel"
+ ? "hover:bg-indigo-50/30 dark:hover:bg-indigo-900/10"
+ : "hover:bg-emerald-50/30 dark:hover:bg-emerald-900/10"
+ }`}
+ whileHover={{ x: 4 }}
+ whileTap={{ scale: 0.98 }}
>
-
-
+
-
);
};
+ const handleMenuToggle = (mode: "morpheus" | "sentinel") => {
+ setActiveMenu(activeMenu === mode ? null : mode);
+ };
+
return (
-
-
-
-
- Example queries
-
+
+ {/* Info Button */}
+
-
- {currentMode === "morpheus" ? (
-
- {queries.morpheus.map((query, idx) => (
-
- ))}
-
- ) : (
-
- {queries.sentinel.map((query, idx) => (
-
- ))}
-
- )}
-
+ {/* Morpheus Button */}
+
handleMenuToggle("morpheus")}
+ whileHover={{ scale: 1.02 }}
+ whileTap={{ scale: 0.98 }}
+ >
+
+ Morpheus
+
+
+ {/* Sentinel Button */}
+
handleMenuToggle("sentinel")}
+ whileHover={{ scale: 1.02 }}
+ whileTap={{ scale: 0.98 }}
+ >
+
+ Sentinel
+
+
+ {/* Centered menu */}
+ {activeMenu && (
+
+
+
+
+ {activeMenu === "morpheus"
+ ? "Morpheus Intelligence"
+ : "Sentinel Commands"}
+
+
+
+
+ {queries[activeMenu].map((query, idx) => (
+
+ ))}
+
+
+
+ )}
);
}
diff --git a/src/components/chat/messages.tsx b/src/components/chat/messages.tsx
index 3478d84c..f800fb74 100644
--- a/src/components/chat/messages.tsx
+++ b/src/components/chat/messages.tsx
@@ -252,44 +252,46 @@ function MessagesComponent() {
const buttonMode = q.mode || defaultMode;
return (
-
-
-
+
+
+ {colorizeQuestionModes(q.question)}
+
+
+
+
+
+
);
})}
@@ -360,7 +362,7 @@ function MessagesComponent() {
}
return (
-
+
{mainContent && (
-
- YOU
-
total +
@@ -594,15 +592,8 @@ function MessagesComponent() {
-
-
-
+
+
{group.messages.map(
(message: UIMessage, messageIndex: number) => {
@@ -622,15 +613,20 @@ function MessagesComponent() {
: ""
}
>
-
+
{message.parts?.map(
- (part: Part, partIndex: number) =>
- renderMessagePart(
- part,
- partIndex,
- oracleMessageKey, // Pass unique seed for IDs
- message
- )
+ (part: Part, partIndex: number) => (
+
+ {renderMessagePart(
+ part,
+ partIndex,
+ oracleMessageKey,
+ message
+ )}
+
+ )
)}
diff --git a/src/components/header/header.tsx b/src/components/header/header.tsx
index e11b7cb3..4d10b137 100644
--- a/src/components/header/header.tsx
+++ b/src/components/header/header.tsx
@@ -68,7 +68,7 @@ export function Header() {
return (