diff --git a/app/auth/page.tsx b/app/auth/page.tsx
deleted file mode 100644
index 6656e99..0000000
--- a/app/auth/page.tsx
+++ /dev/null
@@ -1,199 +0,0 @@
-"use client"
-import { memo, useEffect, useState, useCallback } from 'react';
-import { useRouter } from 'next/navigation';
-import Cookies from 'js-cookie';
-import { usePrivy } from '@privy-io/react-auth';
-import { Providers } from '@/components/providers/privy-provider';
-import { Mail, ArrowRight, Hexagon, LucideIcon } from 'lucide-react';
-
-interface LoginButtonProps {
- icon: LucideIcon;
- text: string;
- onClick: () => void;
-}
-
-interface FeatureCardProps {
- text: string;
-}
-
-// Futuristic geometric background
-const BackgroundEffect = memo(function BackgroundEffect() {
- return (
-
- {/* Base gradient */}
-
-
- {/* Geometric patterns */}
-
-
- {Array.from({ length: 5 }).map((_, i) => (
-
-
-
- ))}
-
-
-
- {/* Modern gradient orbs */}
-
-
-
- );
-});
-
-// Enhanced loading animation
-const LoadingSpinner = memo(function LoadingSpinner() {
- return (
-
- );
-});
-
-// Enhanced button with modern hover effects
-const LoginButton = memo(function LoginButton({ icon: Icon, text, onClick }: LoginButtonProps) {
- return (
-
-
-
-
-
-
-
- );
-});
-
-// Modern feature card
-const FeatureCard = memo(function FeatureCard({ text }: FeatureCardProps) {
- return (
-
- );
-});
-
-const LoginContent = memo(function LoginContent() {
- const router = useRouter();
- const [isLoading, setIsLoading] = useState(true);
- const privy = usePrivy();
-
- const handleLogin = useCallback(() => privy.login(), [privy]);
- // const handleWalletConnect = useCallback(() => privy.connectWallet(), [privy]);
-
- useEffect(() => {
- if (privy?.ready) {
- setIsLoading(false);
- if (privy.authenticated) {
- localStorage.setItem('useremail', privy.user?.email?.address ?? "Guest");
- Cookies.set('privy-authenticated', 'true', { path: '/', expires: 1 });
- router.push('/dashboard');
- }
- }
- }, [privy.ready, privy.authenticated, router]);
-
- if (isLoading) return ;
-
- return (
-
-
-
-
-
-
- {/* Card backdrop blur effect */}
-
-
- {/* Content */}
-
-
-
- ALMAZE
-
-
-
- Secure
-
- Seamless
-
- Smart
-
-
-
-
-
- {/* */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-});
-
-const Home = memo(function Home() {
- return (
-
-
-
- );
-});
-
-export default Home;
\ No newline at end of file
diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx
index bea9a2a..122dbc1 100644
--- a/app/dashboard/page.tsx
+++ b/app/dashboard/page.tsx
@@ -1,592 +1,592 @@
-'use client'
-
-import React, { useState, useEffect, useRef, useCallback } from 'react';
-import { v4 as uuidv4 } from 'uuid';
-import Cookies from 'js-cookie';
-import { usePrivy, useWallets } from '@privy-io/react-auth';
-import { useRouter } from 'next/navigation';
-import { Providers } from '@/components/providers/privy-provider';
-import { StarredChat } from '@/components/chat/sidebar/StarredChat';
-import { SidebarHeader } from '@/components/chat/sidebar/SidebarHeader';
-import { IntegrationButton } from '@/components/chat/IntegrationButton';
-import { ChatInput } from '@/components/chat/ChatInput';
-import { WelcomeHeader } from '@/components/chat/WelcomeHeader';
-import MessageBubble from '@/components/chat/MessageBubble';
-import { motion, AnimatePresence } from 'framer-motion';
-import { Settings, LogOut, Compass ,Landmark, Wrench, ScanSearch, Computer } from 'lucide-react';
-import Avatar, { genConfig } from 'react-nice-avatar';
-import logo from "@/public/assets/logo/landing-logo-blue.png"
-import { NICKNAMES } from '@/components/chat/constants/nicknames';
-
-interface Message {
- id: string;
- role: 'user' | 'assistant' | 'system';
- content: string;
- timestamp: string;
-}
-
-interface Conversation {
- id: string;
- title: string;
- date: string;
- messages: Message[];
- isStarred: boolean;
-}
-
-function DashboardContent() {
- const [conversations, setConversations] = useState([]);
- const [messages, setMessages] = useState([]);
- const [input, setInput] = useState('');
- const [isLoading, setIsLoading] = useState(false);
- const [sessionId, setSessionId] = useState(() => uuidv4());
- const [currentConversation, setCurrentConversation] = useState(null);
- const [isMobile, setIsMobile] = useState(false);
- const [isSidebarOpen, setSidebarOpen] = useState(false);
- const messagesEndRef = useRef(null);
- const [showLogout, setShowLogout] = useState(false);
- const [userName, setUserName] = useState('ALMAZE');
- const [avatarConfig, setAvatarConfig] = useState(() => genConfig());
- const { ready, authenticated, logout: privyLogout } = usePrivy();
- const router = useRouter();
- const { wallets } = useWallets();
- const sidebarTimeoutRef = useRef();
- const [isLongResponse, setIsLongResponse] = useState(false);
-
- //Random Username Generator
- useEffect(() => {
- const randomIndex = Math.floor(Math.random() * NICKNAMES.length);
- const selectedName = NICKNAMES[randomIndex];
- setUserName(selectedName);
- setAvatarConfig(genConfig(selectedName));
- }, []);
- useEffect(() => {
- const handleResize = () => {
- const mobile = window.innerWidth <= 768;
- setIsMobile(mobile);
- setSidebarOpen(false);
- };
-
- handleResize();
- window.addEventListener('resize', handleResize);
- return () => window.removeEventListener('resize', handleResize);
-
- }, []);
-
- const scrollToBottom = useCallback(() => {
- messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
- }, []);
-
- const startNewChat = useCallback(() => {
- const newSessionId = uuidv4();
- setSessionId(newSessionId);
- setMessages([]);
- setCurrentConversation(null);
- setSidebarOpen(false);
- // Force scroll to input
- setTimeout(() => {
- const inputElement = document.querySelector('input[type="text"]');
- (inputElement as HTMLInputElement)?.focus();
- }, 100);
- }, [isMobile]);
-
- const handleStarChat = useCallback((id: string) => {
- setConversations(prev => prev.map(conv =>
- conv.id === id ? { ...conv, isStarred: !conv.isStarred } : conv
- ));
- }, []);
-
- const loadConversation = useCallback((conversation: Conversation) => {
- setSessionId(conversation.id);
- setMessages(conversation.messages);
- setCurrentConversation(conversation);
- if (isMobile) setSidebarOpen(false);
- }, [isMobile]);
-
- // Removed unused deleteConversation function
- const handleSidebarHover = (isHovering: boolean) => {
- if (isMobile) return;
-
- if (sidebarTimeoutRef.current) {
- clearTimeout(sidebarTimeoutRef.current);
- }
-
- if (isHovering) {
- setSidebarOpen(true);
- } else {
- sidebarTimeoutRef.current = setTimeout(() => {
- setSidebarOpen(false);
- }, 300); // Small delay before closing
- }
- };
-
- useEffect(() => {
- if (ready && !authenticated) {
- router.push('/');
- }
- }, [ready, authenticated, router]);
-
- const handleLogout = useCallback(async () => {
- try {
- // Disconnect any connected wallets first
- for (const wallet of wallets) {
- try {
- await wallet.disconnect();
- } catch (e) {
- console.error('Error disconnecting wallet:', e);
- }
- }
-
- // Remove cookie before Privy logout to prevent race conditions
- Cookies.remove('privy-authenticated', { path: '/' });
-
- // Perform Privy logout
- await privyLogout();
-
- // Clear any local storage items
- localStorage.removeItem('privy:embedded-wallet:iframe-ready');
- localStorage.removeItem('privy:embedded-wallet:ready');
-
- // Redirect to auth page
- router.push('/');
- } catch (error) {
- console.error('Logout error:', error);
- // Ensure redirect happens even if there's an error
- router.push('/');
- }
- }, [privyLogout, router, wallets]);
-
- // console.log("Cook: ",Cookies.get("privy-authenticated"))
- const handleSubmit = async (e: React.FormEvent) => {
- e.preventDefault();
- if (!input.trim() || isLoading) return;
-
- const userMessage: Message = {
- id: uuidv4(),
- role: 'user',
- content: input,
- timestamp: new Date().toISOString()
- };
-
- setMessages(prev => [...prev, userMessage]);
- setInput('');
- setIsLoading(true);
- const timer = setTimeout(() => {
- setIsLongResponse(true);
- }, 10000);
- scrollToBottom();
-
- try {
- const response = await fetch('/api/chat', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({
- message: input,
- sessionId: sessionId,
- }),
- });
-
- if (!response.ok) throw new Error('Failed to get response');
-
- const data = await response.json();
- const messageContent = processResponse(data);
-
- const assistantMessage: Message = {
- id: uuidv4(),
- role: 'assistant',
- content: messageContent,
- timestamp: new Date().toISOString()
- };
-
- setMessages(prev => [...prev, assistantMessage]);
-
- if (!currentConversation) {
- const newConversation: Conversation = {
- id: sessionId,
- title: input.slice(0, 30) + (input.length > 30 ? '...' : ''),
- date: new Date().toLocaleDateString(),
- messages: [userMessage, assistantMessage],
- isStarred: false
- };
- setConversations(prev => [newConversation, ...prev]);
- setCurrentConversation(newConversation);
- }
- } catch (error) {
- console.error('Error:', error);
- setMessages(prev => [...prev, {
- id: uuidv4(),
- role: 'system',
- content: 'Sorry, something went wrong. Please try again.',
- timestamp: new Date().toISOString()
- }]);
- } finally {
- setIsLoading(false);
- setIsLongResponse(false);
- clearTimeout(timer);
- scrollToBottom();
- }
- };
-
- return (
-
-
- {/* Always visible sidebar strip */}
-
handleSidebarHover(true)}
- onMouseLeave={() => handleSidebarHover(false)}
- >
- {/* Thin visible strip when sidebar is closed */}
-
-
-
- {isSidebarOpen && (
-
-
-
-
- {/* Starred Chats */}
-
-
STARRED CHATS
-
- {conversations
- .filter(chat => chat.isStarred)
- .map(chat => (
- loadConversation(chat)}
- onStar={() => handleStarChat(chat.id)}
- />
- ))}
-
-
-
- {/* Regular Conversations */}
-
-
CONVERSATIONS
-
- {conversations
- .filter(chat => !chat.isStarred)
- .map(chat => (
- loadConversation(chat)}
- onStar={() => handleStarChat(chat.id)}
- />
- ))}
-
-
-
-
- {/* User Section with Logout */}
-
-
setShowLogout(true)}
- onMouseLeave={() => setShowLogout(false)}
- >
-
-
-
-
-
- {userName}
-
-
-
- {sessionId}
-
-
-
-
-
-
- {showLogout && (
-
-
- Logout
-
- )}
-
-
-
-
-
-
- )}
-
-
-
- {/* Main Content Area with proper margin for sidebar strip */}
-
- {/* Main Chat Area */}
-
- {isMobile && (
-
setSidebarOpen(!isSidebarOpen)}
- className="absolute top-4 left-4 z-50 p-2 bg-white rounded-lg shadow-lg"
- >
- ☰
-
- )}
-
-
- {messages.length === 0 ? (
- <>
-
-
- Ready to help you with your tasks and questions.
-
-
-
-
-
-
- {/* Integration Buttons */}
-
-
- EXPLORE INTEGRATIONS
-
-
- {}}
- />
- {}}
- />
- {}}
- />
- {}}
- />
- {}}
- />
-
-
- >
- ) : (
-
- {messages.map((message, i) => (
-
- ))}
- {isLoading && (
-
- {/* Dots animation */}
-
-
-
-
-
-
- {/* Processing message that appears after delay */}
- {isLongResponse && (
-
-
- Hold on a moment...
-
-
- )}
-
-)}
-
-
-
-
-
- )}
-
-
-
-
-
-
- );
-}
-
-// Helper function to process API response
-function processResponse(data: { response: string; agent_responses?: { agent: string; response: string }[] }): string {
-try {
-const responseObj = JSON.parse(data.response);
-let messageContent = '';
-const compassResponse = responseObj.agent_responses?.find(
-(response: { agent: string }) => response.agent === "compass"
-);
-
-if (compassResponse) {
-messageContent = compassResponse.response;
-} else {
-
-// Process Scout Response
-const scoutResponse = responseObj.agent_responses?.find(
-(response: { agent: string }) => response.agent === "scout"
-);
-
-if (scoutResponse) {
-try {
-const researchData = JSON.parse(scoutResponse.response);
-messageContent = researchData.message || scoutResponse.response;
-} catch {
-messageContent = scoutResponse.response;
-}
-messageContent = messageContent
-.replace(/\b(bound)\b/gi, '**$1**')
-.replace(/(bound)/gi, '**$1**');
-}
-
-// Process Tech Sage Response
-const techSageResponse = responseObj.agent_responses?.find(
-(response: { agent: string }) => response.agent === "techsage"
-);
-
-if (techSageResponse) {
-try {
-const engineerData = JSON.parse(techSageResponse.response);
-messageContent = formatEngineerResponse(engineerData);
-} catch (parseError) {
-console.error('Error parsing techsage response:', parseError);
-messageContent = techSageResponse.response;
-}
-}
-}
-return messageContent || 'Received a response but couldn\'t process it properly.';
-} catch (error) {
-console.error('Error processing response:', error);
-return data.response;
-}
-}
-
-// Helper function to format engineer response
-function formatEngineerResponse(engineerData: { status: string; message: string; suggestions?: string[]; query: string; analysis: { task_type: string; language: string; technologies: string[] }; implementation: { files: { filename: string; language: string; content: string }[]; setup?: string; usage?: string; api_docs?: string; configuration?: string }; files_created?: string[] }): string {
-if (engineerData.status === "error") {
-let content = `⚠️ Error: ${engineerData.message}\n\n`;
-if (engineerData.suggestions?.length) {
-content += "Suggestions:\n";
-engineerData.suggestions.forEach((suggestion: string) => {
-content += `- ${suggestion}\n`;
-});
-}
-return content;
-}
-
-let content = `# ${engineerData.query}\n\n`;
-
-content += `## Project Analysis\n`;
-content += `- Type: ${engineerData.analysis.task_type}\n`;
-content += `- Language: ${engineerData.analysis.language}\n`;
-content += `- Technologies: ${engineerData.analysis.technologies.join(", ")}\n\n`;
-
-content += `## Implementation\n\n`;
-engineerData.implementation.files.forEach((file: { filename: string; language: string; content: string }) => {
-content += `### File: ${file.filename}\n`;
-content += `\`\`\`${file.language}\n${file.content}\n\`\`\`\n\n`;
-});
-
-if (engineerData.implementation.setup) {
-content += `## Setup Instructions\n${engineerData.implementation.setup}\n\n`;
-}
-
-if (engineerData.implementation.usage) {
-content += `## Usage Examples\n${engineerData.implementation.usage}\n\n`;
-}
-
-if (engineerData.implementation.api_docs) {
-content += `## API Documentation\n${engineerData.implementation.api_docs}\n\n`;
-}
-
-if (engineerData.implementation.configuration) {
-content += `## Configuration\n${engineerData.implementation.configuration}\n\n`;
-}
-
-if (engineerData.files_created?.length) {
-content += `## Files Created\n`;
-engineerData.files_created.forEach((file: string) => {
-content += `- \`${file}\`\n`;
-});
-}
-
-return content;
-}
-
-export default function Dashboard() {
- return (
-
-
-
- );
+'use client'
+
+import React, { useState, useEffect, useRef, useCallback } from 'react';
+import { v4 as uuidv4 } from 'uuid';
+import Cookies from 'js-cookie';
+import { usePrivy, useWallets } from '@privy-io/react-auth';
+import { useRouter } from 'next/navigation';
+import { Providers } from '@/components/providers/privy-provider';
+import { StarredChat } from '@/components/chat/sidebar/StarredChat';
+import { SidebarHeader } from '@/components/chat/sidebar/SidebarHeader';
+import { IntegrationButton } from '@/components/chat/IntegrationButton';
+import { ChatInput } from '@/components/chat/ChatInput';
+import { WelcomeHeader } from '@/components/chat/WelcomeHeader';
+import MessageBubble from '@/components/chat/MessageBubble';
+import { motion, AnimatePresence } from 'framer-motion';
+import { Settings, LogOut, Compass ,Landmark, Wrench, ScanSearch, Computer } from 'lucide-react';
+import Avatar, { genConfig } from 'react-nice-avatar';
+import logo from "@/public/assets/logo/landing-logo-blue.png"
+import { NICKNAMES } from '@/components/chat/constants/nicknames';
+
+interface Message {
+ id: string;
+ role: 'user' | 'assistant' | 'system';
+ content: string;
+ timestamp: string;
+}
+
+interface Conversation {
+ id: string;
+ title: string;
+ date: string;
+ messages: Message[];
+ isStarred: boolean;
+}
+
+function DashboardContent() {
+ const [conversations, setConversations] = useState([]);
+ const [messages, setMessages] = useState([]);
+ const [input, setInput] = useState('');
+ const [isLoading, setIsLoading] = useState(false);
+ const [sessionId, setSessionId] = useState(() => uuidv4());
+ const [currentConversation, setCurrentConversation] = useState(null);
+ const [isMobile, setIsMobile] = useState(false);
+ const [isSidebarOpen, setSidebarOpen] = useState(false);
+ const messagesEndRef = useRef(null);
+ const [showLogout, setShowLogout] = useState(false);
+ const [userName, setUserName] = useState('ALMAZE');
+ const [avatarConfig, setAvatarConfig] = useState(() => genConfig());
+ const { ready, authenticated, logout: privyLogout } = usePrivy();
+ const router = useRouter();
+ const { wallets } = useWallets();
+ const sidebarTimeoutRef = useRef();
+ const [isLongResponse, setIsLongResponse] = useState(false);
+
+ //Random Username Generator
+ useEffect(() => {
+ const randomIndex = Math.floor(Math.random() * NICKNAMES.length);
+ const selectedName = NICKNAMES[randomIndex];
+ setUserName(selectedName);
+ setAvatarConfig(genConfig(selectedName));
+ }, []);
+ useEffect(() => {
+ const handleResize = () => {
+ const mobile = window.innerWidth <= 768;
+ setIsMobile(mobile);
+ setSidebarOpen(false);
+ };
+
+ handleResize();
+ window.addEventListener('resize', handleResize);
+ return () => window.removeEventListener('resize', handleResize);
+
+ }, []);
+
+ const scrollToBottom = useCallback(() => {
+ messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
+ }, []);
+
+ const startNewChat = useCallback(() => {
+ const newSessionId = uuidv4();
+ setSessionId(newSessionId);
+ setMessages([]);
+ setCurrentConversation(null);
+ setSidebarOpen(false);
+ // Force scroll to input
+ setTimeout(() => {
+ const inputElement = document.querySelector('input[type="text"]');
+ (inputElement as HTMLInputElement)?.focus();
+ }, 100);
+ }, [isMobile]);
+
+ const handleStarChat = useCallback((id: string) => {
+ setConversations(prev => prev.map(conv =>
+ conv.id === id ? { ...conv, isStarred: !conv.isStarred } : conv
+ ));
+ }, []);
+
+ const loadConversation = useCallback((conversation: Conversation) => {
+ setSessionId(conversation.id);
+ setMessages(conversation.messages);
+ setCurrentConversation(conversation);
+ if (isMobile) setSidebarOpen(false);
+ }, [isMobile]);
+
+ // Removed unused deleteConversation function
+ const handleSidebarHover = (isHovering: boolean) => {
+ if (isMobile) return;
+
+ if (sidebarTimeoutRef.current) {
+ clearTimeout(sidebarTimeoutRef.current);
+ }
+
+ if (isHovering) {
+ setSidebarOpen(true);
+ } else {
+ sidebarTimeoutRef.current = setTimeout(() => {
+ setSidebarOpen(false);
+ }, 300); // Small delay before closing
+ }
+ };
+
+ useEffect(() => {
+ if (ready && !authenticated) {
+ router.push('/');
+ }
+ }, [ready, authenticated, router]);
+
+ const handleLogout = useCallback(async () => {
+ try {
+ // Disconnect any connected wallets first
+ for (const wallet of wallets) {
+ try {
+ await wallet.disconnect();
+ } catch (e) {
+ console.error('Error disconnecting wallet:', e);
+ }
+ }
+
+ // Remove cookie before Privy logout to prevent race conditions
+ Cookies.remove('privy-authenticated', { path: '/' });
+
+ // Perform Privy logout
+ await privyLogout();
+
+ // Clear any local storage items
+ localStorage.removeItem('privy:embedded-wallet:iframe-ready');
+ localStorage.removeItem('privy:embedded-wallet:ready');
+
+ // Redirect to auth page
+ router.push('/');
+ } catch (error) {
+ console.error('Logout error:', error);
+ // Ensure redirect happens even if there's an error
+ router.push('/');
+ }
+ }, [privyLogout, router, wallets]);
+
+ // console.log("Cook: ",Cookies.get("privy-authenticated"))
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ if (!input.trim() || isLoading) return;
+
+ const userMessage: Message = {
+ id: uuidv4(),
+ role: 'user',
+ content: input,
+ timestamp: new Date().toISOString()
+ };
+
+ setMessages(prev => [...prev, userMessage]);
+ setInput('');
+ setIsLoading(true);
+ const timer = setTimeout(() => {
+ setIsLongResponse(true);
+ }, 10000);
+ scrollToBottom();
+
+ try {
+ const response = await fetch('/api/chat', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ message: input,
+ sessionId: sessionId,
+ }),
+ });
+
+ if (!response.ok) throw new Error('Failed to get response');
+
+ const data = await response.json();
+ const messageContent = processResponse(data);
+
+ const assistantMessage: Message = {
+ id: uuidv4(),
+ role: 'assistant',
+ content: messageContent,
+ timestamp: new Date().toISOString()
+ };
+
+ setMessages(prev => [...prev, assistantMessage]);
+
+ if (!currentConversation) {
+ const newConversation: Conversation = {
+ id: sessionId,
+ title: input.slice(0, 30) + (input.length > 30 ? '...' : ''),
+ date: new Date().toLocaleDateString(),
+ messages: [userMessage, assistantMessage],
+ isStarred: false
+ };
+ setConversations(prev => [newConversation, ...prev]);
+ setCurrentConversation(newConversation);
+ }
+ } catch (error) {
+ console.error('Error:', error);
+ setMessages(prev => [...prev, {
+ id: uuidv4(),
+ role: 'system',
+ content: 'Sorry, something went wrong. Please try again.',
+ timestamp: new Date().toISOString()
+ }]);
+ } finally {
+ setIsLoading(false);
+ setIsLongResponse(false);
+ clearTimeout(timer);
+ scrollToBottom();
+ }
+ };
+
+ return (
+
+
+ {/* Always visible sidebar strip */}
+
handleSidebarHover(true)}
+ onMouseLeave={() => handleSidebarHover(false)}
+ >
+ {/* Thin visible strip when sidebar is closed */}
+
+
+
+ {isSidebarOpen && (
+
+
+
+
+ {/* Starred Chats */}
+
+
STARRED CHATS
+
+ {conversations
+ .filter(chat => chat.isStarred)
+ .map(chat => (
+ loadConversation(chat)}
+ onStar={() => handleStarChat(chat.id)}
+ />
+ ))}
+
+
+
+ {/* Regular Conversations */}
+
+
CONVERSATIONS
+
+ {conversations
+ .filter(chat => !chat.isStarred)
+ .map(chat => (
+ loadConversation(chat)}
+ onStar={() => handleStarChat(chat.id)}
+ />
+ ))}
+
+
+
+
+ {/* User Section with Logout */}
+
+
setShowLogout(true)}
+ onMouseLeave={() => setShowLogout(false)}
+ >
+
+
+
+
+
+ {userName}
+
+
+
+ {sessionId}
+
+
+
+
+
+
+ {showLogout && (
+
+
+ Logout
+
+ )}
+
+
+
+
+
+
+ )}
+
+
+
+ {/* Main Content Area with proper margin for sidebar strip */}
+
+ {/* Main Chat Area */}
+
+ {isMobile && (
+
setSidebarOpen(!isSidebarOpen)}
+ className="absolute top-4 left-4 z-50 p-2 bg-white rounded-lg shadow-lg"
+ >
+ ☰
+
+ )}
+
+
+ {messages.length === 0 ? (
+ <>
+
+
+ Ready to help you with your tasks and questions.
+
+
+
+
+
+
+ {/* Integration Buttons */}
+
+
+ EXPLORE INTEGRATIONS
+
+
+ setInput("How Almaze actually works?")}
+ />
+ setInput("Help me design a learning path for becoming a full-stack developer")}
+ />
+ setInput("What tools and resources would you recommend for learning data science?")}
+ />
+ setInput("What are the latest trends in artificial intelligence and machine learning?")}
+ />
+ setInput("Create an HTML/CSS template for a responsive portfolio website")}
+ />
+
+
+ >
+ ) : (
+
+ {messages.map((message, i) => (
+
+ ))}
+ {isLoading && (
+
+ {/* Dots animation */}
+
+
+
+
+
+
+ {/* Processing message that appears after delay */}
+ {isLongResponse && (
+
+
+ Hold on a moment...
+
+
+ )}
+
+)}
+
+
+
+
+
+ )}
+
+
+
+
+
+
+ );
+}
+
+// Helper function to process API response
+function processResponse(data: { response: string; agent_responses?: { agent: string; response: string }[] }): string {
+try {
+const responseObj = JSON.parse(data.response);
+let messageContent = '';
+const compassResponse = responseObj.agent_responses?.find(
+(response: { agent: string }) => response.agent === "compass"
+);
+
+if (compassResponse) {
+messageContent = compassResponse.response;
+} else {
+
+// Process Scout Response
+const scoutResponse = responseObj.agent_responses?.find(
+(response: { agent: string }) => response.agent === "scout"
+);
+
+if (scoutResponse) {
+try {
+const researchData = JSON.parse(scoutResponse.response);
+messageContent = researchData.message || scoutResponse.response;
+} catch {
+messageContent = scoutResponse.response;
+}
+messageContent = messageContent
+.replace(/\b(bound)\b/gi, '**$1**')
+.replace(/(bound)/gi, '**$1**');
+}
+
+// Process Tech Sage Response
+const techSageResponse = responseObj.agent_responses?.find(
+(response: { agent: string }) => response.agent === "techsage"
+);
+
+if (techSageResponse) {
+try {
+const engineerData = JSON.parse(techSageResponse.response);
+messageContent = formatEngineerResponse(engineerData);
+} catch (parseError) {
+console.error('Error parsing techsage response:', parseError);
+messageContent = techSageResponse.response;
+}
+}
+}
+return messageContent || 'Received a response but couldn\'t process it properly.';
+} catch (error) {
+console.error('Error processing response:', error);
+return data.response;
+}
+}
+
+// Helper function to format engineer response
+function formatEngineerResponse(engineerData: { status: string; message: string; suggestions?: string[]; query: string; analysis: { task_type: string; language: string; technologies: string[] }; implementation: { files: { filename: string; language: string; content: string }[]; setup?: string; usage?: string; api_docs?: string; configuration?: string }; files_created?: string[] }): string {
+if (engineerData.status === "error") {
+let content = `⚠️ Error: ${engineerData.message}\n\n`;
+if (engineerData.suggestions?.length) {
+content += "Suggestions:\n";
+engineerData.suggestions.forEach((suggestion: string) => {
+content += `- ${suggestion}\n`;
+});
+}
+return content;
+}
+
+let content = `# ${engineerData.query}\n\n`;
+
+content += `## Project Analysis\n`;
+content += `- Type: ${engineerData.analysis.task_type}\n`;
+content += `- Language: ${engineerData.analysis.language}\n`;
+content += `- Technologies: ${engineerData.analysis.technologies.join(", ")}\n\n`;
+
+content += `## Implementation\n\n`;
+engineerData.implementation.files.forEach((file: { filename: string; language: string; content: string }) => {
+content += `### File: ${file.filename}\n`;
+content += `\`\`\`${file.language}\n${file.content}\n\`\`\`\n\n`;
+});
+
+if (engineerData.implementation.setup) {
+content += `## Setup Instructions\n${engineerData.implementation.setup}\n\n`;
+}
+
+if (engineerData.implementation.usage) {
+content += `## Usage Examples\n${engineerData.implementation.usage}\n\n`;
+}
+
+if (engineerData.implementation.api_docs) {
+content += `## API Documentation\n${engineerData.implementation.api_docs}\n\n`;
+}
+
+if (engineerData.implementation.configuration) {
+content += `## Configuration\n${engineerData.implementation.configuration}\n\n`;
+}
+
+if (engineerData.files_created?.length) {
+content += `## Files Created\n`;
+engineerData.files_created.forEach((file: string) => {
+content += `- \`${file}\`\n`;
+});
+}
+
+return content;
+}
+
+export default function Dashboard() {
+ return (
+
+
+
+ );
}
\ No newline at end of file
diff --git a/components/providers/privy-provider.tsx b/components/providers/privy-provider.tsx
index 19f7469..1d1f1d9 100644
--- a/components/providers/privy-provider.tsx
+++ b/components/providers/privy-provider.tsx
@@ -2,7 +2,8 @@
import { PrivyProvider } from '@privy-io/react-auth';
import { ReactNode , useEffect } from 'react';
-import {toSolanaWalletConnectors} from '@privy-io/react-auth/solana';
+// Replace this with any of the networks listed at https://github.com/wevm/viem/blob/main/src/chains/index.ts
+import {bsc} from 'viem/chains';
export function Providers({ children }: { children: ReactNode }) {
useEffect(() => {
@@ -10,12 +11,6 @@ export function Providers({ children }: { children: ReactNode }) {
localStorage.removeItem('privy:embedded-wallet:ready');
}, []);
- const solanaConnectors = toSolanaWalletConnectors({
- // By default, shouldAutoConnect is enabled
- shouldAutoConnect: true,
- });
-
-
return (
{children}
diff --git a/package-lock.json b/package-lock.json
index 68de648..1554ced 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -34,7 +34,8 @@
"tailwind-merge": "^2.6.0",
"tailwindcss-animate": "^1.0.7",
"three": "^0.172.0",
- "uuid": "^11.0.5"
+ "uuid": "^11.0.5",
+ "viem": "^2.23.2"
},
"devDependencies": {
"@types/js-cookie": "^3.0.6",
@@ -51,7 +52,8 @@
"node_modules/@adraffy/ens-normalize": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz",
- "integrity": "sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg=="
+ "integrity": "sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==",
+ "license": "MIT"
},
"node_modules/@ai-sdk/provider": {
"version": "1.0.4",
@@ -1601,11 +1603,12 @@
}
},
"node_modules/@noble/curves": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.0.tgz",
- "integrity": "sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==",
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz",
+ "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==",
+ "license": "MIT",
"dependencies": {
- "@noble/hashes": "1.7.0"
+ "@noble/hashes": "1.7.1"
},
"engines": {
"node": "^14.21.3 || >=16"
@@ -1615,9 +1618,10 @@
}
},
"node_modules/@noble/hashes": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.0.tgz",
- "integrity": "sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==",
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz",
+ "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==",
+ "license": "MIT",
"engines": {
"node": "^14.21.3 || >=16"
},
@@ -4330,9 +4334,10 @@
"integrity": "sha512-x+BLw/opaz9LiVyrMsP75nO1Rg0QfrACUYIbVSfGwY/w0DiWIPYYrpte6us//KZXinxFAOJl0+C17L1Vi2vmDw=="
},
"node_modules/abitype": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.7.tgz",
- "integrity": "sha512-ZfYYSktDQUwc2eduYu8C4wOs+RDPmnRYMh7zNfzeMtGGgb0U+6tLGjixUic6mXf5xKKCcgT5Qp6cv39tOARVFw==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.8.tgz",
+ "integrity": "sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==",
+ "license": "MIT",
"funding": {
"url": "https://github.com/sponsors/wevm"
},
@@ -9512,15 +9517,16 @@
}
},
"node_modules/ox": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.0.tgz",
- "integrity": "sha512-blUzTLidvUlshv0O02CnLFqBLidNzPoAZdIth894avUAotTuWziznv6IENv5idRuOSSP3dH8WzcYw84zVdu0Aw==",
+ "version": "0.6.7",
+ "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.7.tgz",
+ "integrity": "sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/wevm"
}
],
+ "license": "MIT",
"dependencies": {
"@adraffy/ens-normalize": "^1.10.1",
"@noble/curves": "^1.6.0",
@@ -9540,33 +9546,36 @@
}
},
"node_modules/ox/node_modules/@scure/base": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.1.tgz",
- "integrity": "sha512-DGmGtC8Tt63J5GfHgfl5CuAXh96VF/LD8K9Hr/Gv0J2lAoRGlPOMpqMpMbCTOoOJMZCk2Xt+DskdDyn6dEFdzQ==",
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.4.tgz",
+ "integrity": "sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==",
+ "license": "MIT",
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/ox/node_modules/@scure/bip32": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.1.tgz",
- "integrity": "sha512-jSO+5Ud1E588Y+LFo8TaB8JVPNAZw/lGGao+1SepHDeTs2dFLurdNIAgUuDlwezqEjRjElkCJajVrtrZaBxvaQ==",
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.2.tgz",
+ "integrity": "sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==",
+ "license": "MIT",
"dependencies": {
- "@noble/curves": "~1.8.0",
- "@noble/hashes": "~1.7.0",
- "@scure/base": "~1.2.1"
+ "@noble/curves": "~1.8.1",
+ "@noble/hashes": "~1.7.1",
+ "@scure/base": "~1.2.2"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/ox/node_modules/@scure/bip39": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.1.tgz",
- "integrity": "sha512-GnlufVSP9UdAo/H2Patfv22VTtpNTyfi+I3qCKpvuB5l1KWzEYx+l2TNpBy9Ksh4xTs3Rn06tBlpWCi/1Vz8gw==",
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.4.tgz",
+ "integrity": "sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==",
+ "license": "MIT",
"dependencies": {
- "@noble/hashes": "~1.7.0",
- "@scure/base": "~1.2.1"
+ "@noble/hashes": "~1.7.1",
+ "@scure/base": "~1.2.4"
},
"funding": {
"url": "https://paulmillr.com/funding/"
@@ -12110,24 +12119,24 @@
}
},
"node_modules/viem": {
- "version": "2.22.8",
- "resolved": "https://registry.npmjs.org/viem/-/viem-2.22.8.tgz",
- "integrity": "sha512-iB3PW/a/qzpYbpjo3R662u6a/zo6piZHez/N/bOC25C79FYXBCs8mQDqwiHk3FYErUhS4KVZLabKV9zGMd+EgQ==",
+ "version": "2.23.2",
+ "resolved": "https://registry.npmjs.org/viem/-/viem-2.23.2.tgz",
+ "integrity": "sha512-NVmW/E0c5crMOtbEAqMF0e3NmvQykFXhLOc/CkLIXOlzHSA6KXVz3CYVmaKqBF8/xtjsjHAGjdJN3Ru1kFJLaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/wevm"
}
],
+ "license": "MIT",
"dependencies": {
- "@noble/curves": "1.7.0",
- "@noble/hashes": "1.6.1",
- "@scure/bip32": "1.6.0",
- "@scure/bip39": "1.5.0",
- "abitype": "1.0.7",
+ "@noble/curves": "1.8.1",
+ "@noble/hashes": "1.7.1",
+ "@scure/bip32": "1.6.2",
+ "@scure/bip39": "1.5.4",
+ "abitype": "1.0.8",
"isows": "1.0.6",
- "ox": "0.6.0",
- "webauthn-p256": "0.0.10",
+ "ox": "0.6.7",
"ws": "8.18.0"
},
"peerDependencies": {
@@ -12139,70 +12148,37 @@
}
}
},
- "node_modules/viem/node_modules/@noble/curves": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.7.0.tgz",
- "integrity": "sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==",
- "dependencies": {
- "@noble/hashes": "1.6.0"
- },
- "engines": {
- "node": "^14.21.3 || >=16"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- }
- },
- "node_modules/viem/node_modules/@noble/curves/node_modules/@noble/hashes": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.0.tgz",
- "integrity": "sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ==",
- "engines": {
- "node": "^14.21.3 || >=16"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- }
- },
- "node_modules/viem/node_modules/@noble/hashes": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.1.tgz",
- "integrity": "sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==",
- "engines": {
- "node": "^14.21.3 || >=16"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- }
- },
"node_modules/viem/node_modules/@scure/base": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.1.tgz",
- "integrity": "sha512-DGmGtC8Tt63J5GfHgfl5CuAXh96VF/LD8K9Hr/Gv0J2lAoRGlPOMpqMpMbCTOoOJMZCk2Xt+DskdDyn6dEFdzQ==",
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.4.tgz",
+ "integrity": "sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==",
+ "license": "MIT",
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/viem/node_modules/@scure/bip32": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.0.tgz",
- "integrity": "sha512-82q1QfklrUUdXJzjuRU7iG7D7XiFx5PHYVS0+oeNKhyDLT7WPqs6pBcM2W5ZdwOwKCwoE1Vy1se+DHjcXwCYnA==",
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.6.2.tgz",
+ "integrity": "sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==",
+ "license": "MIT",
"dependencies": {
- "@noble/curves": "~1.7.0",
- "@noble/hashes": "~1.6.0",
- "@scure/base": "~1.2.1"
+ "@noble/curves": "~1.8.1",
+ "@noble/hashes": "~1.7.1",
+ "@scure/base": "~1.2.2"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/viem/node_modules/@scure/bip39": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.0.tgz",
- "integrity": "sha512-Dop+ASYhnrwm9+HA/HwXg7j2ZqM6yk2fyLWb5znexjctFY3+E+eU8cIWI0Pql0Qx4hPZCijlGq4OL71g+Uz30A==",
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.5.4.tgz",
+ "integrity": "sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==",
+ "license": "MIT",
"dependencies": {
- "@noble/hashes": "~1.6.0",
- "@scure/base": "~1.2.1"
+ "@noble/hashes": "~1.7.1",
+ "@scure/base": "~1.2.4"
},
"funding": {
"url": "https://paulmillr.com/funding/"
@@ -12456,21 +12432,6 @@
"node": ">=8.0.0"
}
},
- "node_modules/webauthn-p256": {
- "version": "0.0.10",
- "resolved": "https://registry.npmjs.org/webauthn-p256/-/webauthn-p256-0.0.10.tgz",
- "integrity": "sha512-EeYD+gmIT80YkSIDb2iWq0lq2zbHo1CxHlQTeJ+KkCILWpVy3zASH3ByD4bopzfk0uCwXxLqKGLqp2W4O28VFA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/wevm"
- }
- ],
- "dependencies": {
- "@noble/curves": "^1.4.0",
- "@noble/hashes": "^1.4.0"
- }
- },
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
diff --git a/package.json b/package.json
index 518d419..a7f5ecf 100644
--- a/package.json
+++ b/package.json
@@ -35,7 +35,8 @@
"tailwind-merge": "^2.6.0",
"tailwindcss-animate": "^1.0.7",
"three": "^0.172.0",
- "uuid": "^11.0.5"
+ "uuid": "^11.0.5",
+ "viem": "^2.23.2"
},
"devDependencies": {
"@types/js-cookie": "^3.0.6",