- Pro includes 5,000 memories (vs 200 in free), 10 connections to
+ Pro includes unlimited memories (vs 200 in free), 10 connections to
external services like Google Drive and Notion, advanced search
features, and priority support.
diff --git a/apps/web/components/chat-input.tsx b/apps/web/components/chat-input.tsx
index 8a6edbf8..38f89815 100644
--- a/apps/web/components/chat-input.tsx
+++ b/apps/web/components/chat-input.tsx
@@ -1,20 +1,44 @@
"use client"
-import { useState } from "react"
+import { useState, useEffect } from "react"
import { useRouter } from "next/navigation"
import { generateId } from "@lib/generate-id"
import { usePersistentChat } from "@/stores/chat"
import { ArrowUp } from "lucide-react"
import { Button } from "@ui/components/button"
import { ProjectSelector } from "./project-selector"
+import { ModelSelector } from "./model-selector"
import { useAuth } from "@lib/auth-context"
export function ChatInput() {
const [message, setMessage] = useState("")
+ const [selectedModel, setSelectedModel] = useState<
+ "gpt-5" | "claude-sonnet-4.5" | "gemini-2.5-pro"
+ >("gemini-2.5-pro")
const router = useRouter()
const { setCurrentChatId } = usePersistentChat()
const { user } = useAuth()
+ useEffect(() => {
+ const savedModel = localStorage.getItem("selectedModel") as
+ | "gpt-5"
+ | "claude-sonnet-4.5"
+ | "gemini-2.5-pro"
+ if (
+ savedModel &&
+ ["gpt-5", "claude-sonnet-4.5", "gemini-2.5-pro"].includes(savedModel)
+ ) {
+ setSelectedModel(savedModel)
+ }
+ }, [])
+
+ const handleModelChange = (
+ modelId: "gpt-5" | "claude-sonnet-4.5" | "gemini-2.5-pro",
+ ) => {
+ setSelectedModel(modelId)
+ localStorage.setItem("selectedModel", modelId)
+ }
+
const handleSend = () => {
if (!message.trim()) return
@@ -22,8 +46,8 @@ export function ChatInput() {
setCurrentChatId(newChatId)
- // Store the initial message in sessionStorage for the chat page to pick up
sessionStorage.setItem(`chat-initial-${newChatId}`, message.trim())
+ sessionStorage.setItem(`chat-model-${newChatId}`, selectedModel)
router.push(`/chat/${newChatId}`)
@@ -64,15 +88,21 @@ export function ChatInput() {
/>
-
+
+
+
+
diff --git a/apps/web/components/chrome-extension-button.tsx b/apps/web/components/chrome-extension-button.tsx
index 8f2b74c8..3f7510e3 100644
--- a/apps/web/components/chrome-extension-button.tsx
+++ b/apps/web/components/chrome-extension-button.tsx
@@ -26,7 +26,11 @@ export function ChromeExtensionButton() {
useEffect(() => {
const dismissed =
localStorage.getItem("chrome-extension-dismissed") === "true"
+ const minimized =
+ localStorage.getItem("chrome-extension-minimized") === "true"
+
setIsDismissed(dismissed)
+ setIsMinimized(minimized)
const checkExtension = () => {
const message = { action: "check-extension" }
@@ -35,9 +39,10 @@ export function ChromeExtensionButton() {
setIsExtensionInstalled(false)
setIsChecking(false)
// Auto-minimize after 3 seconds if extension is not installed and not dismissed
- if (!dismissed) {
+ if (!dismissed && !minimized) {
setTimeout(() => {
setIsMinimized(true)
+ localStorage.setItem("chrome-extension-minimized", "true")
}, 3000)
}
}, 1000)
@@ -79,6 +84,7 @@ export function ChromeExtensionButton() {
const handleDismiss = () => {
localStorage.setItem("chrome-extension-dismissed", "true")
+ localStorage.removeItem("chrome-extension-minimized")
setIsDismissed(true)
}
diff --git a/apps/web/components/header.tsx b/apps/web/components/header.tsx
index 0d3682c0..7e6c800a 100644
--- a/apps/web/components/header.tsx
+++ b/apps/web/components/header.tsx
@@ -22,6 +22,7 @@ import {
import { DropdownMenuItem } from "@ui/components/dropdown-menu"
import { DropdownMenu } from "@ui/components/dropdown-menu"
import { Avatar, AvatarFallback, AvatarImage } from "@ui/components/avatar"
+import { Tooltip, TooltipContent, TooltipTrigger } from "@ui/components/tooltip"
import { useAuth } from "@lib/auth-context"
import { ConnectAIModal } from "./connect-ai-modal"
import { useTheme } from "next-themes"
@@ -86,19 +87,31 @@ export function Header({ onAddMemory }: { onAddMemory?: () => void }) {
c
-
+
+
+
+
+
+