- added meta respons page

- added checkbox,toggleSwitch,textarea  generic components
This commit is contained in:
sherifButt 2024-03-20 00:37:38 +00:00
parent 872db95dfe
commit b7ee0b27f4
18 changed files with 586 additions and 238 deletions

View File

@ -0,0 +1,82 @@
import React from "react";
import Badge from "@/components/Generic/Badges/Badge";
import CheckBox from "../../Inputs/CheckBox";
export default function CheckBoxBlock({
initialChecked,
label,
onToggle,
description,
name,
badge = false,
badgeLabel,
badgeAnimated,
badgeBg,
border,
Icon,
contentLocation,
disabled,
inline = false,
}) {
const borderStyle = border ? "border border-gray-600 rounded-2xl p-4" : "";
const contentPosition = {
middle: "middle",
top: "top",
bottom: "bottom",
}[contentLocation];
return (
<div className={`relative w-full max-h-full ${borderStyle}`}>
<div className="relative rounded-lg">
<div className="space-y-6 flex h-full w-full">
<div className="w-full flex flex-col gap-y-4">
<div className="flex gap-4">
{Icon && (
<Icon className="w-16 h-16 text-white text-opacity-60" />
)}
<div>
<div className="flex flex-row gap-4">
{inline && (
<div>
<CheckBox
initialChecked={initialChecked}
onToggle={onToggle}
name={name}
disabled={disabled}
/>
</div>
)}
<label className="block input-label mb-4 first-letter:capitalize">
{label}
</label>
{badge && (
<Badge
showDot
animated={badgeAnimated}
label={badgeLabel}
bg={badgeBg}
/>
)}
</div>
{!inline && (
<CheckBox
initialChecked={initialChecked}
onToggle={onToggle}
name={name}
disabled={disabled}
/>
)}
</div>
</div>
</div>
</div>
<div className="flex items-center justify-between space-x-14">
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
{description}
</p>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,45 @@
import TextArea from "../../Inputs/TextArea";
export default function TextAreaBlock({
label,
description,
defaultValue,
required,
placeholder,
onChange,
name,
disabled,
initialRows,
className,
autoComplete,
wrap,
}) {
return (
<div>
<div className="flex flex-col">
{label && (
<label htmlFor="name" className="block input-label">
{label}
</label>
)}
{description && (
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
{description}
</p>
)}
</div>
<TextArea
defaultValue={defaultValue}
required={required}
placeholder={placeholder}
onChange={onChange}
name={name}
disabled={disabled}
initialRows={initialRows}
className={className}
autoComplete={autoComplete}
wrap={wrap}
/>
</div>
);
}

View File

@ -1,31 +1,73 @@
import React from "react";
import ToggleButton from "../../Buttons/ToggleButton";
import Badge from "../../Badges/Badge";
import Badge from "@/components/Generic/Badges/Badge";
import ToggleButton from "@/components/Generic/Inputs/ToggleSwitch";
// ToggleBlock: A component that includes a ToggleButton with additional context
export default function ToggleBlock({
content, // toggle content goes here
initialChecked,
label,
onToggle,
description,
name,
badge = false,
badgeLabel,
badgeAnimated,
badgeBg,
border,
Icon,
contentLocation,
disabled,
inline = false,
}) {
const borderStyle = border ? "border border-gray-600 rounded-2xl p-4" : "";
const contentPosition = {
middle: "middle",
top: "top",
bottom: "bottom",
}[contentLocation];
return (
<div className="relative w-full max-h-full">
<div className={`relative w-full max-h-full ${borderStyle}`}>
<div className="relative rounded-lg">
<div className="flex items-start justify-between px-6 py-4"></div>
<div className="space-y-6 flex h-full w-full">
<div className="w-full flex flex-col gap-y-4">
<div>
<div className="flex flex-row gap-3" >
<label className="block input-label mb-4">{label}</label>
<Badge showDot animated />
<div className="flex gap-4">
{Icon && (
<Icon className="w-16 h-16 text-white text-opacity-60" />
)}
<div>
<div className="flex flex-row gap-4">
{inline && (
<div>
<ToggleButton
initialChecked={initialChecked}
onToggle={onToggle}
name={name}
disabled={disabled}
/>
</div>
)}
<label className="block input-label mb-4 first-letter:capitalize">
{label}
</label>
{badge && (
<Badge
showDot
animated={badgeAnimated}
label={badgeLabel}
bg={badgeBg}
/>
)}
</div>
{!inline && (
<ToggleButton
initialChecked={initialChecked}
onToggle={onToggle}
name={name}
disabled={disabled}
/>
)}
</div>
<ToggleButton
initialChecked={initialChecked}
onToggle={onToggle}
name={name}
/>
</div>
</div>
</div>
@ -34,6 +76,7 @@ export default function ToggleBlock({
{description}
</p>
</div>
{content}
</div>
</div>
);

View File

@ -0,0 +1,29 @@
import React, { useState, useEffect } from "react";
export default function CheckBox({ initialChecked, onToggle, name, disabled }) {
const [isChecked, setIsChecked] = useState(initialChecked);
useEffect(() => {
setIsChecked(initialChecked);
}, [initialChecked]);
const handleChange = (e) => {
setIsChecked(e.target.checked);
if (onToggle) {
onToggle(e.target.checked);
}
};
return (
<label className="inline-flex cursor-pointer items-center">
<input
type="checkbox"
name={name}
onChange={handleChange}
checked={isChecked}
disabled={disabled}
className="cursor-pointer rounded text-sky-400 focus:ring-blue-800 focus:border-blue-800"
/>
</label>
);
}

View File

@ -0,0 +1,54 @@
import React, { useState } from "react";
export default function TextArea({
defaultValue,
required = true,
placeholder = "Place your text here...",
onChange,
name = "text-area",
disabled = false,
initialRows = 5,
className = "",
autoComplete = "off",
wrap = "soft",
}) {
const [rows, setRows] = useState(initialRows);
const handleChange = (e) => {
if (onChange) {
onChange(e);
}
// Dynamically adjust rows
const textareaLineHeight = 24;
const previousRows = e.target.rows;
e.target.rows = initialRows;
const currentRows = ~~(e.target.scrollHeight / textareaLineHeight);
if (currentRows === previousRows) {
e.target.rows = currentRows;
}
if (e.target.scrollHeight > e.target.clientHeight) {
e.target.rows = currentRows;
}
setRows(currentRows);
};
return (
<textarea
name={name}
rows={rows}
defaultValue={defaultValue}
className={`resize-none bg-zinc-900 placeholder:text-white/20 text-white text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 mt-2 ${className}`}
placeholder={placeholder}
required={required}
wrap={wrap}
autoComplete={autoComplete}
onChange={onChange || handleChange}
disabled={disabled}
/>
);
}

View File

@ -1,7 +1,6 @@
import React, { useState, useEffect } from "react";
// ToggleButton: A reusable and semi-controlled toggle button
export default function ToggleButton({ initialChecked, onToggle, name }) {
export default function ToggleButton({ initialChecked, onToggle, name, disabled }) {
const [isChecked, setIsChecked] = useState(initialChecked);
useEffect(() => {
@ -23,8 +22,9 @@ export default function ToggleButton({ initialChecked, onToggle, name }) {
onChange={handleToggle}
checked={isChecked}
className="peer sr-only pointer-events-none"
disabled={disabled}
/>
<div className="pointer-events-none peer h-6 w-11 rounded-full bg-stone-400 after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:shadow-xl after:border after:border-gray-600 after:bg-white after:box-shadow-md after:transition-all after:content-[''] peer-checked:bg-lime-300 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800"></div>
<div className="pointer-events-none peer h-6 w-11 rounded-full bg-stone-400 after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:shadow-xl after:border after:border-gray-600 after:bg-white after:box-shadow-md after:transition-all after:content-[''] peer-checked:bg-sky-400 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800"></div>
</label>
);
}

View File

@ -18,19 +18,7 @@ const MetaResponse = {
.catch(() => false);
return result;
},
new: async function (data = {}) {
const { workspace, message } = await fetch(`${API_BASE}/workspace/new`, {
method: "POST",
body: JSON.stringify(data),
headers: baseHeaders(),
})
.then((res) => res.json())
.catch((e) => {
return { workspace: null, message: e.message };
});
return { workspace, message };
},
update: async function (slug, data = {}) {
const { workspace, message } = await fetch(
`${API_BASE}/workspace/${slug}/update`,
@ -47,134 +35,9 @@ const MetaResponse = {
return { workspace, message };
},
modifyEmbeddings: async function (slug, changes = {}) {
const { workspace, message } = await fetch(
`${API_BASE}/workspace/${slug}/update-embeddings`,
{
method: "POST",
body: JSON.stringify(changes), // contains 'adds' and 'removes' keys that are arrays of filepaths
headers: baseHeaders(),
}
)
.then((res) => res.json())
.catch((e) => {
return { workspace: null, message: e.message };
});
return { workspace, message };
},
chatHistory: async function (slug) {
const history = await fetch(`${API_BASE}/workspace/${slug}/chats`, {
method: "GET",
headers: baseHeaders(),
})
.then((res) => res.json())
.then((res) => res.history || [])
.catch(() => []);
return history;
},
updateChatFeedback: async function (chatId, slug, feedback) {
const result = await fetch(
`${API_BASE}/workspace/${slug}/chat-feedback/${chatId}`,
{
method: "POST",
headers: baseHeaders(),
body: JSON.stringify({ feedback }),
}
)
.then((res) => res.ok)
.catch(() => false);
return result;
},
streamChat: async function ({ slug }, message, handleChat) {
const ctrl = new AbortController();
// Listen for the ABORT_STREAM_EVENT key to be emitted by the client
// to early abort the streaming response. On abort we send a special `stopGeneration`
// event to be handled which resets the UI for us to be able to send another message.
// The backend response abort handling is done in each LLM's handleStreamResponse.
window.addEventListener(ABORT_STREAM_EVENT, () => {
ctrl.abort();
handleChat({ id: v4(), type: "stopGeneration" });
});
await fetchEventSource(`${API_BASE}/workspace/${slug}/stream-chat`, {
method: "POST",
body: JSON.stringify({ message }),
headers: baseHeaders(),
signal: ctrl.signal,
openWhenHidden: true,
async onopen(response) {
if (response.ok) {
return; // everything's good
} else if (
response.status >= 400 &&
response.status < 500 &&
response.status !== 429
) {
handleChat({
id: v4(),
type: "abort",
textResponse: null,
sources: [],
close: true,
error: `An error occurred while streaming response. Code ${response.status}`,
});
ctrl.abort();
throw new Error("Invalid Status code response.");
} else {
handleChat({
id: v4(),
type: "abort",
textResponse: null,
sources: [],
close: true,
error: `An error occurred while streaming response. Unknown Error.`,
});
ctrl.abort();
throw new Error("Unknown error");
}
},
async onmessage(msg) {
try {
const chatResult = JSON.parse(msg.data);
handleChat(chatResult);
} catch { }
},
onerror(err) {
handleChat({
id: v4(),
type: "abort",
textResponse: null,
sources: [],
close: true,
error: `An error occurred while streaming response. ${err.message}`,
});
ctrl.abort();
throw new Error();
},
});
},
all: async function () {
const workspaces = await fetch(`${API_BASE}/workspaces`, {
method: "GET",
headers: baseHeaders(),
})
.then((res) => res.json())
.then((res) => res.workspaces || [])
.catch(() => []);
return workspaces;
},
bySlug: async function (slug = "") {
const workspace = await fetch(`${API_BASE}/workspace/${slug}`, {
headers: baseHeaders(),
})
.then((res) => res.json())
.then((res) => res.workspace)
.catch(() => null);
return workspace;
},
delete: async function (slug) {
const result = await fetch(`${API_BASE}/workspace/${slug}`, {
method: "DELETE",
@ -195,72 +58,31 @@ const MetaResponse = {
const data = await response.json();
return { response, data };
},
uploadLink: async function (slug, link) {
const response = await fetch(`${API_BASE}/workspace/${slug}/upload-link`, {
method: "POST",
body: JSON.stringify({ link }),
headers: baseHeaders(),
});
const data = await response.json();
return { response, data };
getMetaResponseSettings: async function (slug) {
const settings = await fetch(
`${API_BASE}/workspace/${slug}/metaResponse/settings`,
{
method: "GET",
headers: baseHeaders(),
}
)
.then((res) => res.json())
.catch(() => ({}));
return settings;
},
getSuggestedMessages: async function (slug) {
return await fetch(`${API_BASE}/workspace/${slug}/suggested-messages`, {
method: "GET",
cache: "no-cache",
headers: baseHeaders(),
})
.then((res) => {
if (!res.ok) throw new Error("Could not fetch suggested messages.");
return res.json();
})
.then((res) => res.suggestedMessages)
.catch((e) => {
console.error(e);
return null;
});
updateMetaResponseSettings: async function (slug, data) {
const settings = await fetch(
`${API_BASE}/workspace/${slug}/metaResponse/settings`,
{
method: "PATCH",
body: JSON.stringify(data),
headers: baseHeaders(),
}
)
.then((res) => res.json())
.catch(() => ({}));
return settings;
},
setSuggestedMessages: async function (slug, messages) {
return fetch(`${API_BASE}/workspace/${slug}/suggested-messages`, {
method: "POST",
headers: baseHeaders(),
body: JSON.stringify({ messages }),
})
.then((res) => {
if (!res.ok) {
throw new Error(
res.statusText || "Error setting suggested messages."
);
}
return { success: true, ...res.json() };
})
.catch((e) => {
console.error(e);
return { success: false, error: e.message };
});
},
setPinForDocument: async function (slug, docPath, pinStatus) {
return fetch(`${API_BASE}/workspace/${slug}/update-pin`, {
method: "POST",
headers: baseHeaders(),
body: JSON.stringify({ docPath, pinStatus }),
})
.then((res) => {
if (!res.ok) {
throw new Error(
res.statusText || "Error setting pin status for document."
);
}
return true;
})
.catch((e) => {
console.error(e);
return false;
});
},
threads: WorkspaceThread,
uploadPfp: async function (formData, slug) {
return await fetch(`${API_BASE}/workspace/${slug}/upload-pfp`, {

View File

@ -1,9 +1,6 @@
import GenericBadge from "@/components/Generic/Badges/Badge";
import ToggleBlock from "@/components/Generic/Blocks/ToggleBlock";
export default function ChatEnableMetaResponse({ workspace, setHasChanges }) {
// Toggle metaResponse value
const toggleMetaResponse = () => {
setHasChanges(true);
};
@ -19,6 +16,7 @@ export default function ChatEnableMetaResponse({ workspace, setHasChanges }) {
onToggle={toggleMetaResponse}
name="metaResponse"
description="Turn on this feature to dynamically adjust the chat interface based on conversation context, using options like dropdowns, sliders, and suggestions for a tailored user experience."
badge
/>
</div>
);

View File

@ -10,7 +10,7 @@ import ChatTemperatureSettings from "./ChatTemperatureSettings";
import ChatModeSelection from "./ChatModeSelection";
import ChatEnableMetaResponse from "./ChatEnableMetaResponse";
export default function ChatSettings({ workspace }) {
export default function ChatSettings({ workspace, setWorkspace }) {
const [settings, setSettings] = useState({});
const [hasChanges, setHasChanges] = useState(false);
const [saving, setSaving] = useState(false);
@ -43,6 +43,7 @@ export default function ChatSettings({ workspace }) {
);
if (!!updatedWorkspace) {
showToast("Workspace updated!", "success", { clear: true });
setWorkspace(updatedWorkspace);
} else {
showToast(`Error: ${message}`, "error", { clear: true });
}
@ -75,6 +76,7 @@ export default function ChatSettings({ workspace }) {
/>
<ChatEnableMetaResponse
workspace={workspace}
setHasChanges={setHasChanges}
/>
{hasChanges && (

View File

@ -0,0 +1,27 @@
import ToggleBlock from "@/components/Generic/Blocks/ToggleBlock";
export default function EnableFeatures({
feature,
isEnabled,
description,
onToggle,
Icon,
content,
disabled,
}) {
return (
<div className="relative w-full max-h-full ">
<ToggleBlock
initialChecked={isEnabled}
label={isEnabled ? `${feature} is Enabled` : `Enable ${feature}`}
onToggle={onToggle}
name={feature}
description={description}
border
Icon={Icon}
content={content}
disabled={disabled}
/>
</div>
);
}

View File

@ -0,0 +1,19 @@
import ToggleBlock from "@/components/Generic/Blocks/ToggleBlock";
import { List } from "@phosphor-icons/react";
export default function EnableInputs({ inputs, onToggle }) {
return (
<div className="relative w-full max-h-full ">
<ToggleBlock
initialChecked={inputs?.isEnabled}
label={inputs?.isEnabled ? "Inputs is Enabled" : "Enable Inputs"}
onToggle={onToggle}
name="inputs"
description="Traditionally, interaction with AnythingLLM occurs through a text area. Meta Inputs enhance this by offering alternative interaction methods, including option buttons, multi-select checkboxes, sliders, drop-down menus, and date/time selectors. To utilize these components, you'll need to guide the LLM on incorporating them into its responses with a specific schema"
badge
border
Icon={List}
/>
</div>
);
}

View File

@ -0,0 +1,26 @@
import ToggleBlock from "@/components/Generic/Blocks/ToggleBlock";
import { useState } from "react";
export default function EnableSystemPrompt({ workspace, config }) {
const [isEnabled, setIsEnabled] = useState(config.systemPrompt.isEnabled);
const toggleSystemPrompt = () => {
setIsEnabled(!isEnabled);
};
return (
<div className="relative w-full max-h-full ">
<ToggleBlock
initialChecked={config.systemPrompt.isEnabled}
label={
config.systemPrompt.isEnabled
? "System Prompt is Enabled - (optional)"
: "Enable System Prompt - (optional)"
}
onToggle={toggleSystemPrompt}
name="systemPrompt"
description="Specify the context and instructions for the AI in this workspace. A well-defined prompt ensures the AI delivers relevant and precise responses."
inline
/>
</div>
);
}

View File

@ -0,0 +1,16 @@
import TextAreaBlock from "@/components/Generic/Blocks/TextAreaBlock";
import EnableSystemPrompt from "./EnableSystemPrompt";
import { C } from "../../../../../dist/assets/index-cf7f0eac";
import CheckBoxBlock from "@/components/Generic/Blocks/CheckBoxBlock";
export default function InputsFeature({ workspace, config }) {
console.log("workspace: ", workspace);
console.log("config: ", config);
return (
<div className="flex flex-col gap-4 mt-4">
<EnableSystemPrompt workspace={workspace} config={config} />
<TextAreaBlock workspace={workspace} />
<CheckBoxBlock workspace={workspace} label="override workspace prompt" inline name="systemPrompt"/>
</div>
);
}

View File

@ -0,0 +1,86 @@
import MetaResponse from "@/models/metaResponse";
import { ChatText, Heart, UserCircle } from "@phosphor-icons/react";
import { useEffect, useState } from "react";
import EnableFeatures from "./EnableFeatures";
import InputsFeature from "./InputsFeature";
export default function MetaResponseSettings({ workspace }) {
const [settings, setSettings] = useState({});
useEffect(() => {
const fetchMetaResponseSettings = async () => {
const settings = await MetaResponse.getMetaResponseSettings(
workspace.slug
);
console.log(settings);
setSettings(settings);
};
fetchMetaResponseSettings();
}, []);
const handleToggleEnableFeatures = async (feature, enabled) => {
const updatedFeatureSettings = {
...settings[feature],
isEnabled: enabled,
};
const updatedSettings = await MetaResponse.updateMetaResponseSettings(
workspace.slug,
{
...settings,
[feature]: updatedFeatureSettings,
}
);
console.log("updatedSettings: ", updatedSettings);
setSettings(updatedSettings);
};
const mapIcons = {
inputs: ChatText,
sentiments: Heart,
avatars: UserCircle,
};
const mapFeatures = {
inputs: InputsFeature,
};
return (
<div className="relative w-full gap-4 max-h-full grid grid-cols-1 lg:grid-cols-2 2xl:grid-cols-3">
{Object.keys(settings).map((feature) => {
const featureSettings = settings[feature];
const IconComponent = mapIcons[feature];
const FeatureComponent = mapFeatures[feature];
return (
<div
key={feature}
className={
featureSettings.isEnabled ? "lg:col-span-2 2xl:col-span-3" : ""
}
>
<EnableFeatures
feature={feature}
isEnabled={featureSettings.isEnabled}
description={featureSettings.description}
onToggle={(enabled) =>
workspace.metaResponse &&
handleToggleEnableFeatures(feature, enabled)
}
disabled={!workspace.metaResponse}
Icon={IconComponent}
content={
featureSettings.isEnabled &&
FeatureComponent && (
<FeatureComponent
workspace={workspace}
config={featureSettings.config}
/>
)
}
/>
</div>
);
})}
</div>
);
}

View File

@ -1,27 +1,28 @@
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import PasswordModal, { usePasswordModal } from "@/components/Modals/Password";
import { FullScreenLoader } from "@/components/Preloader";
import Sidebar from "@/components/Sidebar";
import Workspace from "@/models/workspace";
import PasswordModal, { usePasswordModal } from "@/components/Modals/Password";
import { isMobile } from "react-device-detect";
import { FullScreenLoader } from "@/components/Preloader";
import paths from "@/utils/paths";
import {
ArrowUUpLeft,
ChatText,
Cube,
Database,
Wrench,
} from "@phosphor-icons/react";
import paths from "@/utils/paths";
import { Link } from "react-router-dom";
import { NavLink } from "react-router-dom";
import GeneralAppearance from "./GeneralAppearance";
import React, { useEffect, useState } from "react";
import { isMobile } from "react-device-detect";
import { Link, NavLink, useParams } from "react-router-dom";
import ChatSettings from "./ChatSettings";
import GeneralAppearance from "./GeneralAppearance";
import VectorDatabase from "./VectorDatabase";
import MetaResponse from "./MetaResponse";
const TABS = {
"general-appearance": GeneralAppearance,
"chat-settings": ChatSettings,
"vector-database": VectorDatabase,
"meta-response": MetaResponse,
};
export default function WorkspaceSettings() {
@ -91,9 +92,20 @@ function ShowWorkspaceChat() {
icon={<Database className="h-6 w-6" />}
to={paths.workspace.settings.vectorDatabase(slug)}
/>
{workspace.metaResponse && (
<TabItem
title="Meta Response"
icon={<Cube className="h-6 w-6" />}
to={paths.workspace.settings.metaResponse(slug)}
/>
)}
</div>
<div className="px-16 py-6">
<TabContent slug={slug} workspace={workspace} />
<TabContent
slug={slug}
workspace={workspace}
setWorkspace={setWorkspace}
/>
</div>
</div>
</div>

View File

@ -65,6 +65,9 @@ export default {
vectorDatabase: (slug) => {
return `/workspace/${slug}/settings/vector-database`;
},
metaResponse: (slug) => {
return `/workspace/${slug}/settings/meta-response`;
},
},
thread: (wsSlug, threadSlug) => {
return `/workspace/${wsSlug}/t/${threadSlug}`;

View File

@ -96,7 +96,7 @@ function workspaceMetaResponse(app) {
try {
const workspace = response.locals.workspace;
const data = request.body;
const result = await WorkspaceMetaResponse.update(workspace.id, JSON.stringify(data));
const result = await WorkspaceMetaResponse.update(workspace.id, data);
response.status(200).json(JSON.parse(result.metaResponseSettings));
} catch (e) {
console.log(e.message, e);
@ -268,6 +268,7 @@ const metaResponseDefaultSettings = {
},
},
permissions: ["user"],
description: "Traditionally, interaction with AnythingLLM occurs through a text area. Meta Inputs enhance this by offering alternative interaction methods, including option buttons, multi-select checkboxes, sliders, drop-down menus, and date/time selectors. To utilize these components, you'll need to guide the LLM on incorporating them into its responses with a specific schema",
},
sentiments: {
isEnabled: false,
@ -279,6 +280,7 @@ const metaResponseDefaultSettings = {
},
},
permissions: ["user"],
description:"Activate to enable the AI to analyze and adapt its responses based on the emotional tone of the conversation, enhancing interaction personalization"
},
avatars: {
isEnabled: false,
@ -288,6 +290,7 @@ const metaResponseDefaultSettings = {
avatarName: "user",
},
permissions: ["user"],
description:"Enable avatars to reflect user sentiments, allowing the AI to visually empathize and convey understanding through changes in its profile image based on the meta object's sentiment data."
},
};

View File

@ -633,26 +633,107 @@ const metaResponseDefaultSettings = {
},
},
permissions: ["user"],
description: "Traditionally, interaction with AnythingLLM occurs through a text area. Meta Inputs enhance this by offering alternative interaction methods, including option buttons, multi-select checkboxes, sliders, drop-down menus, and date/time selectors. To utilize these components, you'll need to guide the LLM on incorporating them into its responses with a specific schema",
},
sentiments: {
isEnabled: false,
config: {
sentimentAnalysis: {
systemPrompt: {
isEnabled: false,
content: "",
openAiPrompt: "",
overrideSystemPrompt: false,
suggestionsList: [
{
title: "",
content: "",
},
],
canEdit: ["admin", "manager"],
},
promptSchema: {
content: "",
suggestionsList: [
{
title: "",
content: "",
},
],
overrideWorkspacePrompt: false,
canEdit: ["admin", "manager"],
},
components: {
dropDownMenu: {
isEnabled: false,
options: [],
scoreThreshold: 0.5,
},
optionsList: {
isEnabled: false,
options: [],
},
optionsButtons: {
isEnabled: false,
options: [],
},
multiSelectCheckboxes: {
isEnabled: false,
options: [],
},
},
},
permissions: ["user"],
description: "Activate to enable the AI to analyze and adapt its responses based on the emotional tone of the conversation, enhancing interaction personalization",
},
avatars: {
isEnabled: false,
config: {
avatarType: "circle",
avatarSize: "medium",
avatarName: "user",
systemPrompt: {
isEnabled: false,
content: "",
openAiPrompt: "",
overrideSystemPrompt: false,
suggestionsList: [
{
title: "",
content: "",
},
],
canEdit: ["admin", "manager"],
},
promptSchema: {
content: "",
suggestionsList: [
{
title: "",
content: "",
},
],
overrideWorkspacePrompt: false,
canEdit: ["admin", "manager"],
},
components: {
dropDownMenu: {
isEnabled: false,
options: [],
},
optionsList: {
isEnabled: false,
options: [],
},
optionsButtons: {
isEnabled: false,
options: [],
},
multiSelectCheckboxes: {
isEnabled: false,
options: [],
},
},
},
permissions: ["user"],
description: "Enable avatars to reflect user sentiments, allowing the AI to visually empathize and convey understanding through changes in its profile image based on the meta object's sentiment data.",
},
};