mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-11-19 20:50:09 +01:00
Breakout Chat/Query mode as a workspace setting (#734)
Remove useless icons in prompt bar Add chatMode column to workspaces that defaults to chat Add UI for toggle of chat mode with hint Update UI for workspace settings to match designs
This commit is contained in:
parent
32233974c2
commit
51dbff0dcb
@ -1,21 +1,10 @@
|
|||||||
import {
|
import { CircleNotch, PaperPlaneRight } from "@phosphor-icons/react";
|
||||||
Chats,
|
|
||||||
CircleNotch,
|
|
||||||
Gear,
|
|
||||||
PaperPlaneRight,
|
|
||||||
Quotes,
|
|
||||||
} from "@phosphor-icons/react";
|
|
||||||
import React, { useState, useRef } from "react";
|
import React, { useState, useRef } from "react";
|
||||||
import ManageWorkspace, {
|
|
||||||
useManageWorkspaceModal,
|
|
||||||
} from "../../../Modals/MangeWorkspace";
|
|
||||||
import useUser from "@/hooks/useUser";
|
|
||||||
import SlashCommandsButton, {
|
import SlashCommandsButton, {
|
||||||
SlashCommands,
|
SlashCommands,
|
||||||
useSlashCommands,
|
useSlashCommands,
|
||||||
} from "./SlashCommands";
|
} from "./SlashCommands";
|
||||||
import { isMobile } from "react-device-detect";
|
import { isMobile } from "react-device-detect";
|
||||||
import { Tooltip } from "react-tooltip";
|
|
||||||
|
|
||||||
export default function PromptInput({
|
export default function PromptInput({
|
||||||
workspace,
|
workspace,
|
||||||
@ -27,10 +16,8 @@ export default function PromptInput({
|
|||||||
sendCommand,
|
sendCommand,
|
||||||
}) {
|
}) {
|
||||||
const { showSlashCommand, setShowSlashCommand } = useSlashCommands();
|
const { showSlashCommand, setShowSlashCommand } = useSlashCommands();
|
||||||
const { showing, showModal, hideModal } = useManageWorkspaceModal();
|
|
||||||
const formRef = useRef(null);
|
const formRef = useRef(null);
|
||||||
const [_, setFocused] = useState(false);
|
const [_, setFocused] = useState(false);
|
||||||
const { user } = useUser();
|
|
||||||
|
|
||||||
const handleSubmit = (e) => {
|
const handleSubmit = (e) => {
|
||||||
setFocused(false);
|
setFocused(false);
|
||||||
@ -100,24 +87,6 @@ export default function PromptInput({
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between py-3.5">
|
<div className="flex justify-between py-3.5">
|
||||||
<div className="flex gap-x-2">
|
<div className="flex gap-x-2">
|
||||||
{user?.role !== "default" && (
|
|
||||||
<div>
|
|
||||||
<Gear
|
|
||||||
onClick={showModal}
|
|
||||||
data-tooltip-id="tooltip-workspace-settings-prompt"
|
|
||||||
data-tooltip-content={`Open the ${workspace.name} workspace settings`}
|
|
||||||
className="w-7 h-7 text-white/60 hover:text-white cursor-pointer"
|
|
||||||
weight="fill"
|
|
||||||
/>
|
|
||||||
<Tooltip
|
|
||||||
id="tooltip-workspace-settings-prompt"
|
|
||||||
place="top"
|
|
||||||
delayShow={300}
|
|
||||||
className="tooltip !text-xs z-99"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<ChatModeSelector workspace={workspace} />
|
|
||||||
<SlashCommandsButton
|
<SlashCommandsButton
|
||||||
showing={showSlashCommand}
|
showing={showSlashCommand}
|
||||||
setShowSlashCommand={setShowSlashCommand}
|
setShowSlashCommand={setShowSlashCommand}
|
||||||
@ -127,44 +96,6 @@ export default function PromptInput({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{showing && (
|
|
||||||
<ManageWorkspace hideModal={hideModal} providedSlug={workspace.slug} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ChatModeSelector({ workspace }) {
|
|
||||||
const STORAGE_KEY = `workspace_chat_mode_${workspace.slug}`;
|
|
||||||
const [chatMode, setChatMode] = useState(
|
|
||||||
window.localStorage.getItem(STORAGE_KEY) ?? "chat"
|
|
||||||
);
|
|
||||||
|
|
||||||
function toggleMode() {
|
|
||||||
const newChatMode = chatMode === "chat" ? "query" : "chat";
|
|
||||||
setChatMode(newChatMode);
|
|
||||||
window.localStorage.setItem(STORAGE_KEY, newChatMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ModeIcon = chatMode === "chat" ? Chats : Quotes;
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
data-tooltip-id="chat-mode-toggle"
|
|
||||||
data-tooltip-content={`You are currently in ${chatMode} mode. Click to switch to ${
|
|
||||||
chatMode === "chat" ? "query" : "chat"
|
|
||||||
} mode.`}
|
|
||||||
>
|
|
||||||
<ModeIcon
|
|
||||||
onClick={toggleMode}
|
|
||||||
className="w-7 h-7 text-white/60 hover:text-white cursor-pointer"
|
|
||||||
weight="fill"
|
|
||||||
/>
|
|
||||||
<Tooltip
|
|
||||||
id="chat-mode-toggle"
|
|
||||||
place="top"
|
|
||||||
delayShow={300}
|
|
||||||
className="tooltip !text-xs z-99"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -77,9 +77,6 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
|
|||||||
await Workspace.threads.streamChat(
|
await Workspace.threads.streamChat(
|
||||||
{ workspaceSlug: workspace.slug, threadSlug },
|
{ workspaceSlug: workspace.slug, threadSlug },
|
||||||
promptMessage.userMessage,
|
promptMessage.userMessage,
|
||||||
window.localStorage.getItem(
|
|
||||||
`workspace_chat_mode_${workspace.slug}`
|
|
||||||
) ?? "chat",
|
|
||||||
(chatResult) =>
|
(chatResult) =>
|
||||||
handleChat(
|
handleChat(
|
||||||
chatResult,
|
chatResult,
|
||||||
@ -93,9 +90,6 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
|
|||||||
await Workspace.streamChat(
|
await Workspace.streamChat(
|
||||||
workspace,
|
workspace,
|
||||||
promptMessage.userMessage,
|
promptMessage.userMessage,
|
||||||
window.localStorage.getItem(
|
|
||||||
`workspace_chat_mode_${workspace.slug}`
|
|
||||||
) ?? "chat",
|
|
||||||
(chatResult) =>
|
(chatResult) =>
|
||||||
handleChat(
|
handleChat(
|
||||||
chatResult,
|
chatResult,
|
||||||
|
@ -439,3 +439,7 @@ dialog::backdrop {
|
|||||||
.slide-up {
|
.slide-up {
|
||||||
animation: slideUp 0.3s ease-out forwards;
|
animation: slideUp 0.3s ease-out forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-label {
|
||||||
|
@apply text-[14px] font-bold text-white;
|
||||||
|
}
|
||||||
|
@ -73,11 +73,11 @@ const Workspace = {
|
|||||||
.catch(() => false);
|
.catch(() => false);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
streamChat: async function ({ slug }, message, mode = "query", handleChat) {
|
streamChat: async function ({ slug }, message, handleChat) {
|
||||||
const ctrl = new AbortController();
|
const ctrl = new AbortController();
|
||||||
await fetchEventSource(`${API_BASE}/workspace/${slug}/stream-chat`, {
|
await fetchEventSource(`${API_BASE}/workspace/${slug}/stream-chat`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify({ message, mode }),
|
body: JSON.stringify({ message }),
|
||||||
headers: baseHeaders(),
|
headers: baseHeaders(),
|
||||||
signal: ctrl.signal,
|
signal: ctrl.signal,
|
||||||
openWhenHidden: true,
|
openWhenHidden: true,
|
||||||
|
@ -77,7 +77,6 @@ const WorkspaceThread = {
|
|||||||
streamChat: async function (
|
streamChat: async function (
|
||||||
{ workspaceSlug, threadSlug },
|
{ workspaceSlug, threadSlug },
|
||||||
message,
|
message,
|
||||||
mode = "query",
|
|
||||||
handleChat
|
handleChat
|
||||||
) {
|
) {
|
||||||
const ctrl = new AbortController();
|
const ctrl = new AbortController();
|
||||||
@ -85,7 +84,7 @@ const WorkspaceThread = {
|
|||||||
`${API_BASE}/workspace/${workspaceSlug}/thread/${threadSlug}/stream-chat`,
|
`${API_BASE}/workspace/${workspaceSlug}/thread/${threadSlug}/stream-chat`,
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify({ message, mode }),
|
body: JSON.stringify({ message }),
|
||||||
headers: baseHeaders(),
|
headers: baseHeaders(),
|
||||||
signal: ctrl.signal,
|
signal: ctrl.signal,
|
||||||
openWhenHidden: true,
|
openWhenHidden: true,
|
||||||
|
@ -2,10 +2,7 @@ export default function ChatHistorySettings({ workspace, setHasChanges }) {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="flex flex-col gap-y-1 mb-4">
|
<div className="flex flex-col gap-y-1 mb-4">
|
||||||
<label
|
<label htmlFor="name" className="block mb-2 input-label">
|
||||||
htmlFor="name"
|
|
||||||
className="block mb-2 text-sm font-medium text-white"
|
|
||||||
>
|
|
||||||
Chat History
|
Chat History
|
||||||
</label>
|
</label>
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium">
|
<p className="text-white text-opacity-60 text-xs font-medium">
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
export default function ChatModeSelection({ workspace, setHasChanges }) {
|
||||||
|
const [chatMode, setChatMode] = useState(workspace?.chatMode || "chat");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<label htmlFor="chatMode" className="block input-label">
|
||||||
|
Chat mode
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-y-1 mt-2">
|
||||||
|
<div className="w-fit flex gap-x-1 items-center p-1 rounded-lg bg-zinc-800 ">
|
||||||
|
<input type="hidden" name="chatMode" value={chatMode} />
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
disabled={chatMode === "chat"}
|
||||||
|
onClick={() => {
|
||||||
|
setChatMode("chat");
|
||||||
|
setHasChanges(true);
|
||||||
|
}}
|
||||||
|
className="transition-bg duration-200 px-6 py-1 text-md text-white/60 disabled:text-white bg-transparent disabled:bg-[#687280] rounded-md"
|
||||||
|
>
|
||||||
|
Chat
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
disabled={chatMode === "query"}
|
||||||
|
onClick={() => {
|
||||||
|
setChatMode("query");
|
||||||
|
setHasChanges(true);
|
||||||
|
}}
|
||||||
|
className="transition-bg duration-200 px-6 py-1 text-md text-white/60 disabled:text-white bg-transparent disabled:bg-[#687280] rounded-md"
|
||||||
|
>
|
||||||
|
Query
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm text-white/60">
|
||||||
|
{chatMode === "chat" ? (
|
||||||
|
<>
|
||||||
|
<b>Chat</b> will provide answers with the LLM's general knowledge{" "}
|
||||||
|
<i className="font-semibold">and</i> document context that is
|
||||||
|
found.
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<b>Query</b> will provide answers{" "}
|
||||||
|
<i className="font-semibold">only</i> if document context is
|
||||||
|
found.
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -16,10 +16,7 @@ export default function ChatModelSelection({
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<label
|
<label htmlFor="name" className="block input-label">
|
||||||
htmlFor="name"
|
|
||||||
className="block text-sm font-medium text-white"
|
|
||||||
>
|
|
||||||
Chat model
|
Chat model
|
||||||
</label>
|
</label>
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
||||||
@ -44,7 +41,7 @@ export default function ChatModelSelection({
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<label htmlFor="name" className="block text-sm font-medium text-white">
|
<label htmlFor="name" className="block input-label">
|
||||||
Chat model{" "}
|
Chat model{" "}
|
||||||
<span className="font-normal">({settings?.LLMProvider})</span>
|
<span className="font-normal">({settings?.LLMProvider})</span>
|
||||||
</label>
|
</label>
|
||||||
|
@ -4,7 +4,7 @@ export default function ChatPromptSettings({ workspace, setHasChanges }) {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<label htmlFor="name" className="block text-sm font-medium text-white">
|
<label htmlFor="name" className="block input-label">
|
||||||
Prompt
|
Prompt
|
||||||
</label>
|
</label>
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
||||||
|
@ -16,7 +16,7 @@ export default function ChatTemperatureSettings({
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<label htmlFor="name" className="block text-sm font-medium text-white">
|
<label htmlFor="name" className="block input-label">
|
||||||
LLM Temperature
|
LLM Temperature
|
||||||
</label>
|
</label>
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
||||||
|
@ -7,6 +7,7 @@ import ChatModelSelection from "./ChatModelSelection";
|
|||||||
import ChatHistorySettings from "./ChatHistorySettings";
|
import ChatHistorySettings from "./ChatHistorySettings";
|
||||||
import ChatPromptSettings from "./ChatPromptSettings";
|
import ChatPromptSettings from "./ChatPromptSettings";
|
||||||
import ChatTemperatureSettings from "./ChatTemperatureSettings";
|
import ChatTemperatureSettings from "./ChatTemperatureSettings";
|
||||||
|
import ChatModeSelection from "./ChatModeSelection";
|
||||||
|
|
||||||
export default function ChatSettings({ workspace }) {
|
export default function ChatSettings({ workspace }) {
|
||||||
const [settings, setSettings] = useState({});
|
const [settings, setSettings] = useState({});
|
||||||
@ -48,6 +49,7 @@ export default function ChatSettings({ workspace }) {
|
|||||||
onSubmit={handleUpdate}
|
onSubmit={handleUpdate}
|
||||||
className="w-1/2 flex flex-col gap-y-6"
|
className="w-1/2 flex flex-col gap-y-6"
|
||||||
>
|
>
|
||||||
|
<ChatModeSelection workspace={workspace} setHasChanges={setHasChanges} />
|
||||||
<ChatModelSelection
|
<ChatModelSelection
|
||||||
settings={settings}
|
settings={settings}
|
||||||
workspace={workspace}
|
workspace={workspace}
|
||||||
|
@ -91,9 +91,7 @@ export default function SuggestedChatMessages({ slug }) {
|
|||||||
if (loading)
|
if (loading)
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<label className="block text-sm font-medium text-white">
|
<label className="block input-label">Suggested Chat Messages</label>
|
||||||
Suggested Chat Messages
|
|
||||||
</label>
|
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
||||||
Customize the messages that will be suggested to your workspace users.
|
Customize the messages that will be suggested to your workspace users.
|
||||||
</p>
|
</p>
|
||||||
@ -105,9 +103,7 @@ export default function SuggestedChatMessages({ slug }) {
|
|||||||
return (
|
return (
|
||||||
<div className="w-screen">
|
<div className="w-screen">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<label className="block text-sm font-medium text-white">
|
<label className="block input-label">Suggested Chat Messages</label>
|
||||||
Suggested Chat Messages
|
|
||||||
</label>
|
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
||||||
Customize the messages that will be suggested to your workspace users.
|
Customize the messages that will be suggested to your workspace users.
|
||||||
</p>
|
</p>
|
||||||
|
@ -16,7 +16,7 @@ export default function VectorCount({ reload, workspace }) {
|
|||||||
if (totalVectors === null)
|
if (totalVectors === null)
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-white text-sm font-semibold">Number of vectors</h3>
|
<h3 className="input-label">Number of vectors</h3>
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium py-1">
|
<p className="text-white text-opacity-60 text-xs font-medium py-1">
|
||||||
Total number of vectors in your vector database.
|
Total number of vectors in your vector database.
|
||||||
</p>
|
</p>
|
||||||
@ -27,7 +27,7 @@ export default function VectorCount({ reload, workspace }) {
|
|||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-white text-sm font-semibold">Number of vectors</h3>
|
<h3 className="input-label">Number of vectors</h3>
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium py-1">
|
<p className="text-white text-opacity-60 text-xs font-medium py-1">
|
||||||
Total number of vectors in your vector database.
|
Total number of vectors in your vector database.
|
||||||
</p>
|
</p>
|
||||||
|
@ -2,7 +2,7 @@ export default function WorkspaceName({ workspace, setHasChanges }) {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<label htmlFor="name" className="block text-sm font-medium text-white">
|
<label htmlFor="name" className="block input-label">
|
||||||
Workspace Name
|
Workspace Name
|
||||||
</label>
|
</label>
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
||||||
|
@ -5,7 +5,7 @@ export default function DocumentSimilarityThreshold({
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<label htmlFor="name" className="block text-sm font-medium text-white">
|
<label htmlFor="name" className="block input-label">
|
||||||
Document similarity threshold
|
Document similarity threshold
|
||||||
</label>
|
</label>
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
||||||
|
@ -2,7 +2,7 @@ export default function MaxContextSnippets({ workspace, setHasChanges }) {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<label htmlFor="name" className="block text-sm font-medium text-white">
|
<label htmlFor="name" className="block input-label">
|
||||||
Max Context Snippets
|
Max Context Snippets
|
||||||
</label>
|
</label>
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
export default function VectorDBIdentifier({ workspace }) {
|
export default function VectorDBIdentifier({ workspace }) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-white text-sm font-semibold">
|
<h3 className="input-label">Vector database identifier</h3>
|
||||||
Vector database identifier
|
<p className="text-white/60 text-xs font-medium py-1"> </p>
|
||||||
</h3>
|
<p className="text-white/60 text-sm">{workspace?.slug}</p>
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium py-1"> </p>
|
|
||||||
<p className="text-white text-opacity-60 text-sm font-medium">
|
|
||||||
{workspace?.slug}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
const { v4: uuidv4 } = require("uuid");
|
const { v4: uuidv4 } = require("uuid");
|
||||||
const { reqBody, userFromSession, multiUserMode } = require("../utils/http");
|
const { reqBody, userFromSession, multiUserMode } = require("../utils/http");
|
||||||
const { Workspace } = require("../models/workspace");
|
|
||||||
const { validatedRequest } = require("../utils/middleware/validatedRequest");
|
const { validatedRequest } = require("../utils/middleware/validatedRequest");
|
||||||
const { WorkspaceChats } = require("../models/workspaceChats");
|
const { WorkspaceChats } = require("../models/workspaceChats");
|
||||||
const { SystemSettings } = require("../models/systemSettings");
|
const { SystemSettings } = require("../models/systemSettings");
|
||||||
const { Telemetry } = require("../models/telemetry");
|
const { Telemetry } = require("../models/telemetry");
|
||||||
const {
|
const { streamChatWithWorkspace } = require("../utils/chats/stream");
|
||||||
streamChatWithWorkspace,
|
|
||||||
VALID_CHAT_MODE,
|
|
||||||
} = require("../utils/chats/stream");
|
|
||||||
const {
|
const {
|
||||||
ROLES,
|
ROLES,
|
||||||
flexUserRoleValid,
|
flexUserRoleValid,
|
||||||
@ -16,6 +12,7 @@ const {
|
|||||||
const { EventLogs } = require("../models/eventLogs");
|
const { EventLogs } = require("../models/eventLogs");
|
||||||
const {
|
const {
|
||||||
validWorkspaceAndThreadSlug,
|
validWorkspaceAndThreadSlug,
|
||||||
|
validWorkspaceSlug,
|
||||||
} = require("../utils/middleware/validWorkspace");
|
} = require("../utils/middleware/validWorkspace");
|
||||||
const { writeResponseChunk } = require("../utils/helpers/chat/responses");
|
const { writeResponseChunk } = require("../utils/helpers/chat/responses");
|
||||||
|
|
||||||
@ -24,32 +21,21 @@ function chatEndpoints(app) {
|
|||||||
|
|
||||||
app.post(
|
app.post(
|
||||||
"/workspace/:slug/stream-chat",
|
"/workspace/:slug/stream-chat",
|
||||||
[validatedRequest, flexUserRoleValid([ROLES.all])],
|
[validatedRequest, flexUserRoleValid([ROLES.all]), validWorkspaceSlug],
|
||||||
async (request, response) => {
|
async (request, response) => {
|
||||||
try {
|
try {
|
||||||
const user = await userFromSession(request, response);
|
const user = await userFromSession(request, response);
|
||||||
const { slug } = request.params;
|
const { message } = reqBody(request);
|
||||||
const { message, mode = "query" } = reqBody(request);
|
const workspace = response.locals.workspace;
|
||||||
|
|
||||||
const workspace = multiUserMode(response)
|
if (!message?.length) {
|
||||||
? await Workspace.getWithUser(user, { slug })
|
|
||||||
: await Workspace.get({ slug });
|
|
||||||
|
|
||||||
if (!workspace) {
|
|
||||||
response.sendStatus(400).end();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!message?.length || !VALID_CHAT_MODE.includes(mode)) {
|
|
||||||
response.status(400).json({
|
response.status(400).json({
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
type: "abort",
|
type: "abort",
|
||||||
textResponse: null,
|
textResponse: null,
|
||||||
sources: [],
|
sources: [],
|
||||||
close: true,
|
close: true,
|
||||||
error: !message?.length
|
error: !message?.length ? "Message is empty." : null,
|
||||||
? "Message is empty."
|
|
||||||
: `${mode} is not a valid mode.`,
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -95,7 +81,13 @@ function chatEndpoints(app) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await streamChatWithWorkspace(response, workspace, message, mode, user);
|
await streamChatWithWorkspace(
|
||||||
|
response,
|
||||||
|
workspace,
|
||||||
|
message,
|
||||||
|
workspace?.chatMode,
|
||||||
|
user
|
||||||
|
);
|
||||||
await Telemetry.sendTelemetry("sent_chat", {
|
await Telemetry.sendTelemetry("sent_chat", {
|
||||||
multiUserMode: multiUserMode(response),
|
multiUserMode: multiUserMode(response),
|
||||||
LLMSelection: process.env.LLM_PROVIDER || "openai",
|
LLMSelection: process.env.LLM_PROVIDER || "openai",
|
||||||
@ -137,20 +129,18 @@ function chatEndpoints(app) {
|
|||||||
async (request, response) => {
|
async (request, response) => {
|
||||||
try {
|
try {
|
||||||
const user = await userFromSession(request, response);
|
const user = await userFromSession(request, response);
|
||||||
const { message, mode = "query" } = reqBody(request);
|
const { message } = reqBody(request);
|
||||||
const workspace = response.locals.workspace;
|
const workspace = response.locals.workspace;
|
||||||
const thread = response.locals.thread;
|
const thread = response.locals.thread;
|
||||||
|
|
||||||
if (!message?.length || !VALID_CHAT_MODE.includes(mode)) {
|
if (!message?.length) {
|
||||||
response.status(400).json({
|
response.status(400).json({
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
type: "abort",
|
type: "abort",
|
||||||
textResponse: null,
|
textResponse: null,
|
||||||
sources: [],
|
sources: [],
|
||||||
close: true,
|
close: true,
|
||||||
error: !message?.length
|
error: !message?.length ? "Message is empty." : null,
|
||||||
? "Message is empty."
|
|
||||||
: `${mode} is not a valid mode.`,
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -202,7 +192,7 @@ function chatEndpoints(app) {
|
|||||||
response,
|
response,
|
||||||
workspace,
|
workspace,
|
||||||
message,
|
message,
|
||||||
mode,
|
workspace?.chatMode,
|
||||||
user,
|
user,
|
||||||
thread
|
thread
|
||||||
);
|
);
|
||||||
|
@ -18,6 +18,7 @@ const Workspace = {
|
|||||||
"similarityThreshold",
|
"similarityThreshold",
|
||||||
"chatModel",
|
"chatModel",
|
||||||
"topN",
|
"topN",
|
||||||
|
"chatMode",
|
||||||
],
|
],
|
||||||
|
|
||||||
new: async function (name = null, creatorId = null) {
|
new: async function (name = null, creatorId = null) {
|
||||||
@ -59,7 +60,7 @@ const Workspace = {
|
|||||||
try {
|
try {
|
||||||
const workspace = await prisma.workspaces.update({
|
const workspace = await prisma.workspaces.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data,
|
data, // TODO: strict validation on writables here.
|
||||||
});
|
});
|
||||||
return { workspace, message: null };
|
return { workspace, message: null };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "workspaces" ADD COLUMN "chatMode" TEXT DEFAULT 'chat';
|
@ -98,6 +98,7 @@ model workspaces {
|
|||||||
similarityThreshold Float? @default(0.25)
|
similarityThreshold Float? @default(0.25)
|
||||||
chatModel String?
|
chatModel String?
|
||||||
topN Int? @default(4)
|
topN Int? @default(4)
|
||||||
|
chatMode String? @default("chat")
|
||||||
workspace_users workspace_users[]
|
workspace_users workspace_users[]
|
||||||
documents workspace_documents[]
|
documents workspace_documents[]
|
||||||
workspace_suggested_messages workspace_suggested_messages[]
|
workspace_suggested_messages workspace_suggested_messages[]
|
||||||
|
Loading…
Reference in New Issue
Block a user