diff --git a/web/src/app/admin/configuration/llm/interfaces.ts b/web/src/app/admin/configuration/llm/interfaces.ts
index 2d0d49196..33fa94d7f 100644
--- a/web/src/app/admin/configuration/llm/interfaces.ts
+++ b/web/src/app/admin/configuration/llm/interfaces.ts
@@ -1,3 +1,13 @@
+import {
+ AnthropicIcon,
+ AWSIcon,
+ AzureIcon,
+ CPUIcon,
+ OpenAIIcon,
+ OpenSourceIcon,
+} from "@/components/icons/icons";
+import { FaRobot } from "react-icons/fa";
+
export interface CustomConfigKey {
name: string;
description: string | null;
@@ -53,3 +63,18 @@ export interface LLMProviderDescriptor {
groups: number[];
display_model_names: string[] | null;
}
+
+export const getProviderIcon = (providerName: string) => {
+ switch (providerName) {
+ case "openai":
+ return OpenAIIcon;
+ case "anthropic":
+ return AnthropicIcon;
+ case "bedrock":
+ return AWSIcon;
+ case "azure":
+ return AzureIcon;
+ default:
+ return CPUIcon;
+ }
+};
diff --git a/web/src/app/admin/indexing/status/CCPairIndexingStatusTable.tsx b/web/src/app/admin/indexing/status/CCPairIndexingStatusTable.tsx
index 705f76079..b62074a72 100644
--- a/web/src/app/admin/indexing/status/CCPairIndexingStatusTable.tsx
+++ b/web/src/app/admin/indexing/status/CCPairIndexingStatusTable.tsx
@@ -482,7 +482,7 @@ export function CCPairIndexingStatusTable({
if (sourceMatches || matchingConnectors.length > 0) {
return (
-
+
@@ -65,6 +66,7 @@ export function ChatBanner() {
className="absolute top-0 left-0 invisible w-full"
>
diff --git a/web/src/app/chat/input/ChatInputBar.tsx b/web/src/app/chat/input/ChatInputBar.tsx
index b579abefe..66fe490c0 100644
--- a/web/src/app/chat/input/ChatInputBar.tsx
+++ b/web/src/app/chat/input/ChatInputBar.tsx
@@ -338,10 +338,10 @@ export function ChatInputBar({
updateInputPrompt(currentPrompt);
}}
>
- {currentPrompt.prompt}
-
+
{currentPrompt.prompt}:
+
{currentPrompt.id == selectedAssistant.id && "(default) "}
- {currentPrompt.content}
+ {currentPrompt.content?.trim()}
))}
diff --git a/web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx b/web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx
index df7ddee95..669a183d7 100644
--- a/web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx
+++ b/web/src/app/chat/sessionSidebar/ChatSessionDisplay.tsx
@@ -46,6 +46,7 @@ export function ChatSessionDisplay({
showDeleteModal?: (chatSession: ChatSession) => void;
}) {
const router = useRouter();
+ const [isHovering, setIsHovering] = useState(false);
const [isRenamingChat, setIsRenamingChat] = useState(false);
const [isMoreOptionsDropdownOpen, setIsMoreOptionsDropdownOpen] =
useState(false);
@@ -97,6 +98,11 @@ export function ChatSessionDisplay({
setIsHovering(true)}
+ onMouseLeave={() => {
+ setIsMoreOptionsDropdownOpen(false);
+ setIsHovering(false);
+ }}
onClick={() => {
if (settings?.isMobile && closeSidebar) {
closeSidebar();
@@ -145,7 +151,7 @@ export function ChatSessionDisplay({
)}
- {isSelected &&
+ {isHovering &&
(isRenamingChat ? (
-
{
- setIsMoreOptionsDropdownOpen(
- !isMoreOptionsDropdownOpen
- );
- }}
- className={"-my-1"}
- >
-
- setIsMoreOptionsDropdownOpen(open)
- }
- content={
-
-
-
- }
- popover={
-
- {showShareModal && (
- showShareModal(chatSession)}
- />
- )}
- setIsRenamingChat(true)}
- />
-
- }
- requiresContentPadding
- sideOffset={6}
- triggerMaxWidth
- />
-
+ {search ? (
+ showDeleteModal && (
+
showDeleteModal(chatSession)}
+ className={`p-1 -m-1 rounded ml-1`}
+ >
+
+
+ )
+ ) : (
+
{
+ setIsMoreOptionsDropdownOpen(
+ !isMoreOptionsDropdownOpen
+ );
+ }}
+ className="-my-1"
+ >
+
+ setIsMoreOptionsDropdownOpen(open)
+ }
+ content={
+
+
+
+ }
+ popover={
+
+ {showShareModal && (
+ showShareModal(chatSession)}
+ />
+ )}
+ {!search && (
+ setIsRenamingChat(true)}
+ />
+ )}
+ {showDeleteModal && (
+
+ showDeleteModal(chatSession)
+ }
+ />
+ )}
+
+ }
+ requiresContentPadding
+ sideOffset={6}
+ triggerMaxWidth
+ />
+
+ )}
- {showDeleteModal && (
-
showDeleteModal(chatSession)}
- className={`hover:bg-black/10 p-1 -m-1 rounded ml-1`}
- >
-
-
- )}
))}
diff --git a/web/src/app/chat/shared_chat_search/FunctionalWrapper.tsx b/web/src/app/chat/shared_chat_search/FunctionalWrapper.tsx
index a5693ab47..4f8d31d39 100644
--- a/web/src/app/chat/shared_chat_search/FunctionalWrapper.tsx
+++ b/web/src/app/chat/shared_chat_search/FunctionalWrapper.tsx
@@ -53,9 +53,14 @@ const ToggleSwitch = () => {
onClick={() => handleTabChange("search")}
>
-
+
Search
-
{commandSymbol}S
+
+
+ {commandSymbol}
+
+ S
+
diff --git a/web/src/app/globals.css b/web/src/app/globals.css
index fdb9d7985..e0e618e46 100644
--- a/web/src/app/globals.css
+++ b/web/src/app/globals.css
@@ -36,7 +36,7 @@
.include-scrollbar {
scrollbar-width: thin;
- scrollbar-color: #888 #f1f1f1;
+ scrollbar-color: #888 transparent;
}
.inputscroll::-webkit-scrollbar-track {
diff --git a/web/src/components/chat_search/MinimalMarkdown.tsx b/web/src/components/chat_search/MinimalMarkdown.tsx
index 6fadc979c..9df0260f4 100644
--- a/web/src/components/chat_search/MinimalMarkdown.tsx
+++ b/web/src/components/chat_search/MinimalMarkdown.tsx
@@ -1,3 +1,4 @@
+import { CodeBlock } from "@/app/chat/message/CodeBlock";
import React from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
@@ -5,11 +6,13 @@ import remarkGfm from "remark-gfm";
interface MinimalMarkdownProps {
content: string;
className?: string;
+ useCodeBlock?: boolean;
}
export const MinimalMarkdown: React.FC = ({
content,
className = "",
+ useCodeBlock = false,
}) => {
return (
= ({
p: ({ node, ...props }) => (
),
+ code: useCodeBlock
+ ? (props) => (
+
+ )
+ : (props) =>
,
}}
remarkPlugins={[remarkGfm]}
>
diff --git a/web/src/components/llm/LLMList.tsx b/web/src/components/llm/LLMList.tsx
index 90c904c58..191a89485 100644
--- a/web/src/components/llm/LLMList.tsx
+++ b/web/src/components/llm/LLMList.tsx
@@ -1,7 +1,10 @@
import React from "react";
import { getDisplayNameForModel } from "@/lib/hooks";
import { structureValue } from "@/lib/llm/utils";
-import { LLMProviderDescriptor } from "@/app/admin/configuration/llm/interfaces";
+import {
+ getProviderIcon,
+ LLMProviderDescriptor,
+} from "@/app/admin/configuration/llm/interfaces";
interface LlmListProps {
llmProviders: LLMProviderDescriptor[];
@@ -9,6 +12,7 @@ interface LlmListProps {
onSelect: (value: string | null) => void;
userDefault?: string | null;
scrollable?: boolean;
+ hideProviderIcon?: boolean;
}
export const LlmList: React.FC = ({
@@ -19,7 +23,11 @@ export const LlmList: React.FC = ({
scrollable,
}) => {
const llmOptionsByProvider: {
- [provider: string]: { name: string; value: string }[];
+ [provider: string]: {
+ name: string;
+ value: string;
+ icon: React.FC<{ size?: number; className?: string }>;
+ }[];
} = {};
const uniqueModelNames = new Set();
@@ -39,6 +47,7 @@ export const LlmList: React.FC = ({
llmProvider.provider,
modelName
),
+ icon: getProviderIcon(llmProvider.provider),
});
}
}
@@ -67,17 +76,18 @@ export const LlmList: React.FC = ({
User Default (currently {getDisplayNameForModel(userDefault)})
)}
- {llmOptions.map(({ name, value }, index) => (
+ {llmOptions.map(({ name, icon, value }, index) => (
))}
diff --git a/web/src/components/search/SearchBar.tsx b/web/src/components/search/SearchBar.tsx
index 98533ffea..7d62b0992 100644
--- a/web/src/components/search/SearchBar.tsx
+++ b/web/src/components/search/SearchBar.tsx
@@ -71,7 +71,7 @@ export const AnimatedToggle = ({
Get quality results immediately, best suited for instant access to
your documents.
- Shortcut: ({commandSymbol}/)
+ Shortcut: ({commandSymbol}/)
}
>
diff --git a/web/src/components/search/SearchSection.tsx b/web/src/components/search/SearchSection.tsx
index feae79cdf..0827cbab7 100644
--- a/web/src/components/search/SearchSection.tsx
+++ b/web/src/components/search/SearchSection.tsx
@@ -34,8 +34,9 @@ import FixedLogo from "@/app/chat/shared_chat_search/FixedLogo";
import { usePopup } from "../admin/connectors/Popup";
import { FeedbackType } from "@/app/chat/types";
import { FeedbackModal } from "@/app/chat/modal/FeedbackModal";
-import { handleChatFeedback } from "@/app/chat/lib";
+import { deleteChatSession, handleChatFeedback } from "@/app/chat/lib";
import SearchAnswer from "./SearchAnswer";
+import { DeleteEntityModal } from "../modals/DeleteEntityModal";
export type searchState =
| "input"
@@ -511,7 +512,12 @@ export const SearchSection = ({
};
const [firstSearch, setFirstSearch] = useState(true);
const [searchState, setSearchState] = useState("input");
+ const [deletingChatSession, setDeletingChatSession] =
+ useState();
+ const showDeleteModal = (chatSession: ChatSession) => {
+ setDeletingChatSession(chatSession);
+ };
// Used to maintain a "time out" for history sidebar so our existing refs can have time to process change
const [untoggled, setUntoggled] = useState(false);
@@ -591,6 +597,24 @@ export const SearchSection = ({
<>
{popup}
+
+ {deletingChatSession && (
+
setDeletingChatSession(null)}
+ onSubmit={async () => {
+ const response = await deleteChatSession(deletingChatSession.id);
+ if (response.ok) {
+ setDeletingChatSession(null);
+ // go back to the main page
+ router.push("/search");
+ } else {
+ alert("Failed to delete chat session");
+ }
+ }}
+ />
+ )}
{currentFeedback && (
setQuery("")}
page="search"
@@ -672,7 +697,7 @@ export const SearchSection = ({
(ccPairs.length > 0 || documentSets.length > 0) && (
Tags
-
+
{filteredTags.length > 0 ? (
filteredTags.map((tag) => (
{
header = <>>;
body = (
-
- {replaceNewlines(props.answer || "")}
-
+
);
// error while building answer (NOTE: if error occurs during quote generation
@@ -63,12 +62,7 @@ export const AnswerSection = (props: AnswerSectionProps) => {
status = "success";
header = <>>;
body = (
-
- {replaceNewlines(props.answer)}
-
+
);
}
diff --git a/web/src/lib/assistants/fetchPersonaEditorInfoSS.ts b/web/src/lib/assistants/fetchPersonaEditorInfoSS.ts
index f779b2ed6..9873e0a25 100644
--- a/web/src/lib/assistants/fetchPersonaEditorInfoSS.ts
+++ b/web/src/lib/assistants/fetchPersonaEditorInfoSS.ts
@@ -2,7 +2,10 @@ import { Persona } from "@/app/admin/assistants/interfaces";
import { CCPairBasicInfo, DocumentSet, User } from "../types";
import { getCurrentUserSS } from "../userSS";
import { fetchSS } from "../utilsSS";
-import { FullLLMProvider } from "@/app/admin/configuration/llm/interfaces";
+import {
+ FullLLMProvider,
+ getProviderIcon,
+} from "@/app/admin/configuration/llm/interfaces";
import { ToolSnapshot } from "../tools/interfaces";
import { fetchToolsSS } from "../tools/fetchTools";
import {
@@ -94,17 +97,7 @@ export async function fetchAssistantEditorInfoSS(
}
for (const provider of llmProviders) {
- if (provider.provider == "openai") {
- provider.icon = OpenAIIcon;
- } else if (provider.provider == "anthropic") {
- provider.icon = AnthropicIcon;
- } else if (provider.provider == "bedrock") {
- provider.icon = AWSIcon;
- } else if (provider.provider == "azure") {
- provider.icon = AzureIcon;
- } else {
- provider.icon = OpenSourceIcon;
- }
+ provider.icon = getProviderIcon(provider.provider);
}
const existingPersona = personaResponse