mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-03 21:29:08 +00:00
Merge branch 'master' of github.com:khoj-ai/khoj into features/new-sign-in-page
This commit is contained in:
@@ -54,6 +54,12 @@ function TrainOfThoughtComponent(props: TrainOfThoughtComponentProps) {
|
||||
const lastIndex = props.trainOfThought.length - 1;
|
||||
const [collapsed, setCollapsed] = useState(props.completed);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.completed) {
|
||||
setCollapsed(true);
|
||||
}
|
||||
}, [props.completed]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${!collapsed ? styles.trainOfThought + " shadow-sm" : ""}`}
|
||||
@@ -410,6 +416,9 @@ export default function ChatHistory(props: ChatHistoryProps) {
|
||||
"inferred-queries": message.inferredQueries || [],
|
||||
},
|
||||
conversationId: props.conversationId,
|
||||
images: message.generatedImages,
|
||||
queryFiles: message.generatedFiles,
|
||||
excalidrawDiagram: message.generatedExcalidrawDiagram,
|
||||
turnId: messageTurnId,
|
||||
}}
|
||||
conversationId={props.conversationId}
|
||||
|
||||
@@ -77,6 +77,21 @@ div.imageWrapper img {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
div.khoj div.imageWrapper img {
|
||||
height: 512px;
|
||||
}
|
||||
|
||||
div.khoj div.imageWrapper {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
div.khoj div.imagesContainer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
div.chatMessageContainer > img {
|
||||
width: auto;
|
||||
height: auto;
|
||||
@@ -178,4 +193,9 @@ div.trainOfThoughtElement ul {
|
||||
div.youfullHistory {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
div.khoj div.imageWrapper img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,6 +163,7 @@ export interface SingleChatMessage {
|
||||
conversationId: string;
|
||||
turnId?: string;
|
||||
queryFiles?: AttachedFileText[];
|
||||
excalidrawDiagram?: string;
|
||||
}
|
||||
|
||||
export interface StreamMessage {
|
||||
@@ -180,6 +181,10 @@ export interface StreamMessage {
|
||||
inferredQueries?: string[];
|
||||
turnId?: string;
|
||||
queryFiles?: AttachedFileText[];
|
||||
excalidrawDiagram?: string;
|
||||
generatedFiles?: AttachedFileText[];
|
||||
generatedImages?: string[];
|
||||
generatedExcalidrawDiagram?: string;
|
||||
}
|
||||
|
||||
export interface ChatHistoryData {
|
||||
@@ -264,6 +269,9 @@ interface ChatMessageProps {
|
||||
onDeleteMessage: (turnId?: string) => void;
|
||||
conversationId: string;
|
||||
turnId?: string;
|
||||
generatedImage?: string;
|
||||
excalidrawDiagram?: string;
|
||||
generatedFiles?: AttachedFileText[];
|
||||
}
|
||||
|
||||
interface TrainOfThoughtProps {
|
||||
@@ -389,9 +397,8 @@ const ChatMessage = forwardRef<HTMLDivElement, ChatMessageProps>((props, ref) =>
|
||||
// Prepare initial message for rendering
|
||||
let message = props.chatMessage.message;
|
||||
|
||||
if (props.chatMessage.intent && props.chatMessage.intent.type == "excalidraw") {
|
||||
message = props.chatMessage.intent["inferred-queries"][0];
|
||||
setExcalidrawData(props.chatMessage.message);
|
||||
if (props.chatMessage.excalidrawDiagram) {
|
||||
setExcalidrawData(props.chatMessage.excalidrawDiagram);
|
||||
}
|
||||
|
||||
// Replace LaTeX delimiters with placeholders
|
||||
@@ -401,27 +408,6 @@ const ChatMessage = forwardRef<HTMLDivElement, ChatMessageProps>((props, ref) =>
|
||||
.replace(/\\\[/g, "LEFTBRACKET")
|
||||
.replace(/\\\]/g, "RIGHTBRACKET");
|
||||
|
||||
const intentTypeHandlers = {
|
||||
"text-to-image": (msg: string) => ``,
|
||||
"text-to-image2": (msg: string) => ``,
|
||||
"text-to-image-v3": (msg: string) =>
|
||||
``,
|
||||
excalidraw: (msg: string) => msg,
|
||||
};
|
||||
|
||||
// Handle intent-specific rendering
|
||||
if (props.chatMessage.intent) {
|
||||
const { type, "inferred-queries": inferredQueries } = props.chatMessage.intent;
|
||||
|
||||
if (type in intentTypeHandlers) {
|
||||
message = intentTypeHandlers[type as keyof typeof intentTypeHandlers](message);
|
||||
}
|
||||
|
||||
if (type.includes("text-to-image") && inferredQueries?.length > 0) {
|
||||
message += `\n\n${inferredQueries[0]}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace file links with base64 data
|
||||
message = renderCodeGenImageInline(message, props.chatMessage.codeContext);
|
||||
|
||||
|
||||
35
src/interface/web/app/components/chatWoot/ChatwootWidget.tsx
Normal file
35
src/interface/web/app/components/chatWoot/ChatwootWidget.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
"use client";
|
||||
|
||||
import Script from "next/script";
|
||||
|
||||
export function ChatwootWidget() {
|
||||
return (
|
||||
<Script
|
||||
id="chatwoot-widget"
|
||||
strategy="afterInteractive"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
window.chatwootSettings = {
|
||||
position: "right",
|
||||
type: "standard",
|
||||
launcherTitle: "Chat with us"
|
||||
};
|
||||
(function(d,t) {
|
||||
var BASE_URL="https://app.chatwoot.com";
|
||||
var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
|
||||
g.src=BASE_URL+"/packs/js/sdk.js";
|
||||
g.defer = true;
|
||||
g.async = true;
|
||||
s.parentNode.insertBefore(g,s);
|
||||
g.onload=function(){
|
||||
window.chatwootSDK.run({
|
||||
websiteToken: '5uV59Ay2pvMJenJary2hvvVM',
|
||||
baseUrl: BASE_URL
|
||||
})
|
||||
}
|
||||
})(document,"script");
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -52,7 +52,7 @@ div.settingsMenuOptions {
|
||||
grid-auto-flow: row;
|
||||
position: absolute;
|
||||
background-color: var(--background-color);
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
|
||||
top: 64px;
|
||||
text-align: left;
|
||||
padding: 8px;
|
||||
@@ -69,6 +69,6 @@ div.settingsMenuOptions {
|
||||
}
|
||||
|
||||
div.titleBar {
|
||||
padding: 8px;
|
||||
padding: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Moon, Sun, UserCircle, Question, GearFine, ArrowRight } from "@phosphor-icons/react";
|
||||
import { Moon, Sun, UserCircle, Question, GearFine, ArrowRight, Code } from "@phosphor-icons/react";
|
||||
import { KhojAgentLogo, KhojAutomationLogo, KhojSearchLogo } from "../logo/khojLogo";
|
||||
import { useIsMobileWidth } from "@/app/common/utils";
|
||||
|
||||
@@ -37,6 +37,15 @@ function SubscriptionBadge({ is_active }: { is_active: boolean }) {
|
||||
);
|
||||
}
|
||||
|
||||
function VersionBadge({ version }: { version: string }) {
|
||||
return (
|
||||
<div className="flex flex-row items-center">
|
||||
<div className="w-3 h-3 rounded-full bg-green-500 mr-1"></div>
|
||||
<p className="text-xs">{version}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function NavMenu() {
|
||||
const userData = useAuthenticatedData();
|
||||
const [darkMode, setDarkMode] = useState(false);
|
||||
@@ -99,6 +108,9 @@ export default function NavMenu() {
|
||||
<div className="flex flex-col">
|
||||
<p className="font-semibold">{userData?.email}</p>
|
||||
<SubscriptionBadge is_active={userData?.is_active ?? false} />
|
||||
{userData?.khoj_version && (
|
||||
<VersionBadge version={userData?.khoj_version} />
|
||||
)}
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
@@ -143,18 +155,18 @@ export default function NavMenu() {
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{userData && (
|
||||
<DropdownMenuItem>
|
||||
<Link href="/settings" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<GearFine className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Settings</p>
|
||||
</div>
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
{userData && (
|
||||
<DropdownMenuItem>
|
||||
<Link href="/settings" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<GearFine className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Settings</p>
|
||||
</div>
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuItem>
|
||||
<Link href="https://docs.khoj.dev" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
@@ -163,6 +175,17 @@ export default function NavMenu() {
|
||||
</div>
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Link
|
||||
href="https://github.com/khoj-ai/khoj/releases"
|
||||
className="no-underline w-full"
|
||||
>
|
||||
<div className="flex flex-rows">
|
||||
<Code className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Releases</p>
|
||||
</div>
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
{userData ? (
|
||||
<DropdownMenuItem>
|
||||
<Link href="/auth/logout" className="no-underline w-full">
|
||||
@@ -207,6 +230,9 @@ export default function NavMenu() {
|
||||
<div className="flex flex-col">
|
||||
<p className="font-semibold">{userData?.email}</p>
|
||||
<SubscriptionBadge is_active={userData?.is_active ?? false} />
|
||||
{userData?.khoj_version && (
|
||||
<VersionBadge version={userData?.khoj_version} />
|
||||
)}
|
||||
</div>
|
||||
</MenubarItem>
|
||||
<MenubarSeparator className="dark:bg-white height-[2px] bg-black" />
|
||||
@@ -251,6 +277,16 @@ export default function NavMenu() {
|
||||
</Link>
|
||||
</MenubarItem>
|
||||
)}
|
||||
{userData && (
|
||||
<MenubarItem>
|
||||
<Link href="/settings" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<GearFine className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Settings</p>
|
||||
</div>
|
||||
</Link>
|
||||
</MenubarItem>
|
||||
)}
|
||||
<>
|
||||
<MenubarSeparator className="dark:bg-white height-[2px] bg-black" />
|
||||
<MenubarItem>
|
||||
@@ -264,16 +300,18 @@ export default function NavMenu() {
|
||||
</div>
|
||||
</Link>
|
||||
</MenubarItem>
|
||||
{userData && (
|
||||
<MenubarItem>
|
||||
<Link href="/settings" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<GearFine className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Settings</p>
|
||||
</div>
|
||||
</Link>
|
||||
</MenubarItem>
|
||||
)}
|
||||
|
||||
<MenubarItem>
|
||||
<Link
|
||||
href="https://github.com/khoj-ai/khoj/releases"
|
||||
className="no-underline w-full"
|
||||
>
|
||||
<div className="flex flex-rows">
|
||||
<Code className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Releases</p>
|
||||
</div>
|
||||
</Link>
|
||||
</MenubarItem>
|
||||
{userData ? (
|
||||
<MenubarItem>
|
||||
<Link href="/auth/logout" className="no-underline w-full">
|
||||
|
||||
@@ -105,7 +105,6 @@ import { ScrollAreaScrollbar } from "@radix-ui/react-scroll-area";
|
||||
import { KhojLogoType } from "@/app/components/logo/khojLogo";
|
||||
import NavMenu from "@/app/components/navMenu/navMenu";
|
||||
import { getIconFromIconName } from "@/app/common/iconUtils";
|
||||
import AgentProfileCard from "../profileCard/profileCard";
|
||||
|
||||
// Define a fetcher function
|
||||
const fetcher = (url: string) =>
|
||||
@@ -627,43 +626,56 @@ export function ChatSessionActionMenu(props: ChatSessionActionMenuProps) {
|
||||
const size = sizeClass();
|
||||
|
||||
return (
|
||||
<DropdownMenu onOpenChange={(open) => setIsOpen(open)} open={isOpen}>
|
||||
<DropdownMenuTrigger>
|
||||
<DotsThreeVertical className={`${size}`} />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem>
|
||||
<Button
|
||||
className="p-0 text-sm h-auto"
|
||||
variant={"ghost"}
|
||||
onClick={() => setIsRenaming(true)}
|
||||
>
|
||||
<Pencil className={`mr-2 ${size}`} />
|
||||
Rename
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Button
|
||||
className="p-0 text-sm h-auto"
|
||||
variant={"ghost"}
|
||||
onClick={() => setIsSharing(true)}
|
||||
>
|
||||
<Share className={`mr-2 ${size}`} />
|
||||
Share
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Button
|
||||
className="p-0 text-sm h-auto text-rose-300 hover:text-rose-400"
|
||||
variant={"ghost"}
|
||||
onClick={() => setIsDeleting(true)}
|
||||
>
|
||||
<Trash className={`mr-2 ${size}`} />
|
||||
Delete
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<div className="flex items-center gap-2">
|
||||
{(props.sizing === "lg" || props.sizing === "md") && (
|
||||
<Button
|
||||
className="p-0 text-sm h-auto"
|
||||
variant={"ghost"}
|
||||
onClick={() => setIsSharing(true)}
|
||||
>
|
||||
<Share className={`${size}`} />
|
||||
</Button>
|
||||
)}
|
||||
<DropdownMenu onOpenChange={(open) => setIsOpen(open)} open={isOpen}>
|
||||
<DropdownMenuTrigger>
|
||||
<DotsThreeVertical className={`${size}`} />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem>
|
||||
<Button
|
||||
className="p-0 text-sm h-auto"
|
||||
variant={"ghost"}
|
||||
onClick={() => setIsRenaming(true)}
|
||||
>
|
||||
<Pencil className={`mr-2 ${size}`} />
|
||||
Rename
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
{props.sizing === "sm" && (
|
||||
<DropdownMenuItem>
|
||||
<Button
|
||||
className="p-0 text-sm h-auto"
|
||||
variant={"ghost"}
|
||||
onClick={() => setIsSharing(true)}
|
||||
>
|
||||
<Share className={`mr-2 ${size}`} />
|
||||
Share
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuItem>
|
||||
<Button
|
||||
className="p-0 text-sm h-auto text-rose-300 hover:text-rose-400"
|
||||
variant={"ghost"}
|
||||
onClick={() => setIsDeleting(true)}
|
||||
>
|
||||
<Trash className={`mr-2 ${size}`} />
|
||||
Delete
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -685,7 +697,11 @@ function ChatSession(props: ChatHistory) {
|
||||
>
|
||||
<p className={styles.session}>{title}</p>
|
||||
</Link>
|
||||
<ChatSessionActionMenu conversationId={props.conversation_id} setTitle={setTitle} />
|
||||
<ChatSessionActionMenu
|
||||
conversationId={props.conversation_id}
|
||||
setTitle={setTitle}
|
||||
sizing="sm"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -726,7 +742,6 @@ function ChatSessionsModal({ data, showSidePanel }: ChatSessionsModalProps) {
|
||||
}
|
||||
});
|
||||
});
|
||||
console.log(agentNameToStyleMapLocal);
|
||||
setAgentNameToStyleMap(agentNameToStyleMapLocal);
|
||||
setAgentOptions(agents);
|
||||
}
|
||||
@@ -950,7 +965,7 @@ export default function SidePanel(props: SidePanelProps) {
|
||||
}}
|
||||
>
|
||||
<DrawerTrigger>
|
||||
<Sidebar className="h-8 w-8 mx-2" weight="thin" />
|
||||
<Sidebar className="h-6 w-6 mx-2" weight="thin" />
|
||||
</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
<DrawerHeader>
|
||||
@@ -1022,7 +1037,7 @@ export default function SidePanel(props: SidePanelProps) {
|
||||
</div>
|
||||
)}
|
||||
{props.isMobileWidth && (
|
||||
<Link href="/" className="content-center">
|
||||
<Link href="/" className="content-center h-fit self-center">
|
||||
<KhojLogoType />
|
||||
</Link>
|
||||
)}
|
||||
|
||||
@@ -724,12 +724,6 @@ export const suggestionsData: Suggestion[] = [
|
||||
description: "Draw a diagram illustrating the structure of the United States government.",
|
||||
link: "",
|
||||
},
|
||||
{
|
||||
type: SuggestionType.Health,
|
||||
color: suggestionToColorMap[SuggestionType.Health] || DEFAULT_COLOR,
|
||||
description: "Draw a diagram of the human skeletal system.",
|
||||
link: "",
|
||||
},
|
||||
{
|
||||
type: SuggestionType.Code,
|
||||
color: suggestionToColorMap[SuggestionType.Code] || DEFAULT_COLOR,
|
||||
|
||||
Reference in New Issue
Block a user