这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions embed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ REQUIRED data attributes:

- `data-username` - A specific readable name or identifier for the client for your reference. Will be shown in AnythingLLM chat logs. If empty it will not be reported.

- `data-default-messages` - A string of comma-separated messages you want to display to the user when the chat widget has no history. Example: `"How are you?, What is so interesting about this project?, Tell me a joke."`

**Behavior Overrides**

- `data-open-on-load` — Once loaded, open the chat as default. It can still be closed by the user. To enable set this attribute to `on`. All other values will be ignored.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import HistoricalMessage from "./HistoricalMessage";
import PromptReply from "./PromptReply";
import { useEffect, useRef, useState } from "react";
import { ArrowDown, CircleNotch } from "@phosphor-icons/react";
import { embedderSettings } from "@/main";
import debounce from "lodash.debounce";
import { SEND_TEXT_EVENT } from "..";

export default function ChatHistory({ settings = {}, history = [] }) {
const replyRef = useRef(null);
Expand Down Expand Up @@ -51,6 +53,7 @@ export default function ChatHistory({ settings = {}, history = [] }) {
<p className="allm-text-slate-400 allm-text-sm allm-font-sans allm-py-4 allm-text-center">
{settings?.greeting ?? "Send a chat to get started."}
</p>
<SuggestedMessages settings={settings} />
</div>
</div>
);
Expand Down Expand Up @@ -129,3 +132,32 @@ export function ChatHistoryLoading() {
</div>
);
}

function SuggestedMessages({ settings }) {
if (!settings?.defaultMessages?.length) return null;

return (
<div className="allm-flex allm-flex-col allm-gap-y-2 allm-w-[75%]">
{settings.defaultMessages.map((content, i) => (
<button
key={i}
style={{
opacity: 0,
wordBreak: "break-word",
backgroundColor: embedderSettings.USER_STYLES.msgBg,
fontSize: settings.textSize,
}}
type="button"
onClick={() => {
window.dispatchEvent(
new CustomEvent(SEND_TEXT_EVENT, { detail: { command: content } })
);
}}
className={`msg-suggestion allm-border-none hover:allm-shadow-[0_4px_14px_rgba(0,0,0,0.5)] allm-cursor-pointer allm-px-2 allm-py-2 allm-rounded-lg allm-text-white allm-w-full allm-shadow-[0_4px_14px_rgba(0,0,0,0.25)]`}
>
{content}
</button>
))}
</div>
);
}
52 changes: 52 additions & 0 deletions embed/src/components/ChatWindow/ChatContainer/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ChatHistory from "./ChatHistory";
import PromptInput from "./PromptInput";
import handleChat from "@/utils/chat";
import ChatService from "@/models/chatService";
export const SEND_TEXT_EVENT = "anythingllm-embed-send-prompt";

export default function ChatContainer({
sessionId,
Expand Down Expand Up @@ -45,6 +46,45 @@ export default function ChatContainer({
setLoadingResponse(true);
};

const sendCommand = (command, history = [], attachments = []) => {
if (!command || command === "") return false;

let prevChatHistory;
if (history.length > 0) {
// use pre-determined history chain.
prevChatHistory = [
...history,
{
content: "",
role: "assistant",
pending: true,
userMessage: command,
attachments,
animate: true,
},
];
} else {
prevChatHistory = [
...chatHistory,
{
content: command,
role: "user",
attachments,
},
{
content: "",
role: "assistant",
pending: true,
userMessage: command,
animate: true,
},
];
}

setChatHistory(prevChatHistory);
setLoadingResponse(true);
};

useEffect(() => {
async function fetchReply() {
const promptMessage =
Expand Down Expand Up @@ -76,6 +116,18 @@ export default function ChatContainer({
loadingResponse === true && fetchReply();
}, [loadingResponse, chatHistory]);

const handleAutofillEvent = (event) => {
if (!event.detail.command) return;
sendCommand(event.detail.command, [], []);
};

useEffect(() => {
window.addEventListener(SEND_TEXT_EVENT, handleAutofillEvent);
return () => {
window.removeEventListener(SEND_TEXT_EVENT, handleAutofillEvent);
};
}, []);

return (
<div className="allm-h-full allm-w-full allm-flex allm-flex-col">
<div className="allm-flex-grow allm-overflow-y-auto">
Expand Down
43 changes: 42 additions & 1 deletion embed/src/hooks/useScriptAttributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const DEFAULT_SETTINGS = {
openOnLoad: "off", // or "on"
supportEmail: null, // string of email for contact
username: null, // The display or readable name set on a script
defaultMessages: [], // list of strings for default messages.
};

export default function useGetScriptAttributes() {
Expand All @@ -52,7 +53,7 @@ export default function useGetScriptAttributes() {

setSettings({
...DEFAULT_SETTINGS,
...embedderSettings.settings,
...parseAndValidateEmbedSettings(embedderSettings.settings),
loaded: true,
});
}
Expand All @@ -61,3 +62,43 @@ export default function useGetScriptAttributes() {

return settings;
}

const validations = {
_fallbacks: {
defaultMessages: [],
},

defaultMessages: function (value = null) {
if (typeof value !== "string") return this._fallbacks.defaultMessages;
try {
const list = value.split(",");
if (
!Array.isArray(list) ||
list.length === 0 ||
!list.every((v) => typeof v === "string" && v.length > 0)
)
throw new Error(
"Invalid default-messages attribute value. Must be array of strings"
);
return list.map((v) => v.trim());
} catch (e) {
console.error("AnythingLLMEmbed", e);
return this._fallbacks.defaultMessages;
}
},
};

function parseAndValidateEmbedSettings(settings = {}) {
const validated = {};
for (let [key, value] of Object.entries(settings)) {
if (!validations.hasOwnProperty(key)) {
validated[key] = value;
continue;
}

const validatedValue = validations[key](value);
validated[key] = validatedValue;
}

return validated;
}
29 changes: 29 additions & 0 deletions embed/src/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

.msg-suggestion {
animation-name: fadeIn;
animation-duration: 300ms;
animation-timing-function: linear;
animation-fill-mode: forwards;
}

@keyframes fadeIn {
0% {
opacity: 0%;
}

25% {
opacity: 25%;
}

50% {
opacity: 50%;
}

75% {
opacity: 75%;
}

100% {
opacity: 100%;
}
}
2 changes: 1 addition & 1 deletion frontend/public/embed/anythingllm-chat-widget.min.css

Large diffs are not rendered by default.

Loading