mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2025-05-02 17:07:13 +00:00
Merge branch 'master' of github.com:Mintplex-Labs/anything-llm
This commit is contained in:
commit
56793ed9a0
18 changed files with 741 additions and 37 deletions
.github
docker
frontend/src
components
EmbeddingSelection
WorkspaceChat/ChatContainer
hooks
locales
pages
server
18
.github/dependabot.yml
vendored
Normal file
18
.github/dependabot.yml
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/frontend"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/server"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/collector"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
2
.github/workflows/dev-build.yaml
vendored
2
.github/workflows/dev-build.yaml
vendored
|
@ -6,7 +6,7 @@ concurrency:
|
|||
|
||||
on:
|
||||
push:
|
||||
branches: ['light-mode-1'] # put your current branch to create a build. Core team only.
|
||||
branches: ['2670-feat-can-the-font-size-of-the-chat-input-box-be-increased'] # put your current branch to create a build. Core team only.
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'cloud-deployments/*'
|
||||
|
|
|
@ -164,6 +164,7 @@ GID='1000'
|
|||
# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=8192
|
||||
# EMBEDDING_BASE_PATH='http://127.0.0.1:4000'
|
||||
# GENERIC_OPEN_AI_EMBEDDING_API_KEY='sk-123abc'
|
||||
# GENERIC_OPEN_AI_EMBEDDING_MAX_CONCURRENT_CHUNKS=500
|
||||
|
||||
###########################################
|
||||
######## Vector Database Selection ########
|
||||
|
@ -299,4 +300,4 @@ GID='1000'
|
|||
|
||||
# Enable simple SSO passthrough to pre-authenticate users from a third party service.
|
||||
# See https://docs.anythingllm.com/configuration#simple-sso-passthrough for more information.
|
||||
# SIMPLE_SSO_ENABLED=1
|
||||
# SIMPLE_SSO_ENABLED=1
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import React, { useState } from "react";
|
||||
import { CaretDown, CaretUp } from "@phosphor-icons/react";
|
||||
|
||||
export default function GenericOpenAiEmbeddingOptions({ settings }) {
|
||||
const [showAdvancedControls, setShowAdvancedControls] = useState(false);
|
||||
return (
|
||||
<div className="w-full flex flex-col gap-y-7">
|
||||
<div className="w-full flex items-center gap-[36px] mt-1.5 flex-wrap">
|
||||
|
@ -69,6 +73,46 @@ export default function GenericOpenAiEmbeddingOptions({ settings }) {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-start mt-4">
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setShowAdvancedControls(!showAdvancedControls);
|
||||
}}
|
||||
className="text-white hover:text-white/70 flex items-center text-sm"
|
||||
>
|
||||
{showAdvancedControls ? "Hide" : "Show"} advanced settings
|
||||
{showAdvancedControls ? (
|
||||
<CaretUp size={14} className="ml-1" />
|
||||
) : (
|
||||
<CaretDown size={14} className="ml-1" />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
<div hidden={!showAdvancedControls}>
|
||||
<div className="w-full flex items-start gap-4">
|
||||
<div className="flex flex-col w-60">
|
||||
<div className="flex flex-col gap-y-1 mb-4">
|
||||
<label className="text-white text-sm font-semibold flex items-center gap-x-2">
|
||||
Max concurrent Chunks
|
||||
<p className="!text-xs !italic !font-thin">optional</p>
|
||||
</label>
|
||||
</div>
|
||||
<input
|
||||
type="number"
|
||||
name="GenericOpenAiEmbeddingMaxConcurrentChunks"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="500"
|
||||
min={1}
|
||||
onScroll={(e) => e.target.blur()}
|
||||
defaultValue={settings?.GenericOpenAiEmbeddingMaxConcurrentChunks}
|
||||
required={false}
|
||||
autoComplete="off"
|
||||
spellCheck={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
export default function MistralAiOptions({ settings }) {
|
||||
return (
|
||||
<div className="w-full flex flex-col gap-y-4">
|
||||
<div className="w-full flex items-center gap-[36px] mt-1.5">
|
||||
<div className="flex flex-col w-60">
|
||||
<label className="text-white text-sm font-semibold block mb-3">
|
||||
API Key
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="MistralAiApiKey"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Mistral AI API Key"
|
||||
defaultValue={settings?.MistralApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
spellCheck={false}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col w-60">
|
||||
<label className="text-white text-sm font-semibold block mb-3">
|
||||
Model Preference
|
||||
</label>
|
||||
<select
|
||||
name="EmbeddingModelPref"
|
||||
required={true}
|
||||
defaultValue={settings?.EmbeddingModelPref}
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<optgroup label="Available embedding models">
|
||||
{[
|
||||
"mistral-embed",
|
||||
].map((model) => {
|
||||
return (
|
||||
<option key={model} value={model}>
|
||||
{model}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -11,6 +11,7 @@ import Workspace from "@/models/workspace";
|
|||
import { useParams } from "react-router-dom";
|
||||
import paths from "@/utils/paths";
|
||||
import Appearance from "@/models/appearance";
|
||||
import useTextSize from "@/hooks/useTextSize";
|
||||
|
||||
export default function ChatHistory({
|
||||
history = [],
|
||||
|
@ -26,39 +27,10 @@ export default function ChatHistory({
|
|||
const { showing, showModal, hideModal } = useManageWorkspaceModal();
|
||||
const [isAtBottom, setIsAtBottom] = useState(true);
|
||||
const chatHistoryRef = useRef(null);
|
||||
const [textSize, setTextSize] = useState("normal");
|
||||
const [isUserScrolling, setIsUserScrolling] = useState(false);
|
||||
const isStreaming = history[history.length - 1]?.animate;
|
||||
const { showScrollbar } = Appearance.getSettings();
|
||||
|
||||
const getTextSizeClass = (size) => {
|
||||
switch (size) {
|
||||
case "small":
|
||||
return "text-[12px]";
|
||||
case "large":
|
||||
return "text-[18px]";
|
||||
default:
|
||||
return "text-[14px]";
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const storedTextSize = window.localStorage.getItem("anythingllm_text_size");
|
||||
if (storedTextSize) {
|
||||
setTextSize(getTextSizeClass(storedTextSize));
|
||||
}
|
||||
|
||||
const handleTextSizeChange = (event) => {
|
||||
const size = event.detail;
|
||||
setTextSize(getTextSizeClass(size));
|
||||
};
|
||||
|
||||
window.addEventListener("textSizeChange", handleTextSizeChange);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("textSizeChange", handleTextSizeChange);
|
||||
};
|
||||
}, []);
|
||||
const { textSizeClass } = useTextSize();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isUserScrolling && (isAtBottom || isStreaming)) {
|
||||
|
@ -204,7 +176,7 @@ export default function ChatHistory({
|
|||
|
||||
return (
|
||||
<div
|
||||
className={`markdown text-white/80 light:text-theme-text-primary font-light ${textSize} h-full md:h-[83%] pb-[100px] pt-6 md:pt-0 md:pb-20 md:mx-0 overflow-y-scroll flex flex-col justify-start ${
|
||||
className={`markdown text-white/80 light:text-theme-text-primary font-light ${textSizeClass} h-full md:h-[83%] pb-[100px] pt-6 md:pt-0 md:pb-20 md:mx-0 overflow-y-scroll flex flex-col justify-start ${
|
||||
showScrollbar ? "show-scrollbar" : "no-scroll"
|
||||
}`}
|
||||
id="chat-history"
|
||||
|
|
|
@ -16,6 +16,7 @@ import { Tooltip } from "react-tooltip";
|
|||
import AttachmentManager from "./Attachments";
|
||||
import AttachItem from "./AttachItem";
|
||||
import { PASTE_ATTACHMENT_EVENT } from "../DnDWrapper";
|
||||
import useTextSize from "@/hooks/useTextSize";
|
||||
|
||||
export const PROMPT_INPUT_EVENT = "set_prompt_input";
|
||||
const MAX_EDIT_STACK_SIZE = 100;
|
||||
|
@ -36,6 +37,7 @@ export default function PromptInput({
|
|||
const [_, setFocused] = useState(false);
|
||||
const undoStack = useRef([]);
|
||||
const redoStack = useRef([]);
|
||||
const { textSizeClass } = useTextSize();
|
||||
|
||||
/**
|
||||
* To prevent too many re-renders we remotely listen for updates from the parent
|
||||
|
@ -269,7 +271,7 @@ export default function PromptInput({
|
|||
adjustTextArea(e);
|
||||
}}
|
||||
value={promptInput}
|
||||
className="cursor-text max-h-[50vh] md:max-h-[350px] md:min-h-[40px] mx-2 md:mx-0 pt-[12px] w-full text-[14px] leading-5 md:text-md text-white bg-transparent placeholder:text-white/60 light:placeholder:text-theme-text-primary resize-none active:outline-none focus:outline-none flex-grow"
|
||||
className={`cursor-text max-h-[50vh] md:max-h-[350px] md:min-h-[40px] mx-2 md:mx-0 pt-[12px] w-full leading-5 md:text-md text-white bg-transparent placeholder:text-white/60 light:placeholder:text-theme-text-primary resize-none active:outline-none focus:outline-none flex-grow ${textSizeClass}`}
|
||||
placeholder={"Send a message"}
|
||||
/>
|
||||
{buttonDisabled ? (
|
||||
|
|
38
frontend/src/hooks/useTextSize.js
Normal file
38
frontend/src/hooks/useTextSize.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
import { useState, useEffect } from "react";
|
||||
|
||||
export default function useTextSize() {
|
||||
const [textSize, setTextSize] = useState("normal");
|
||||
const [textSizeClass, setTextSizeClass] = useState("text-[14px]");
|
||||
|
||||
const getTextSizeClass = (size) => {
|
||||
switch (size) {
|
||||
case "small":
|
||||
return "text-[12px]";
|
||||
case "large":
|
||||
return "text-[18px]";
|
||||
default:
|
||||
return "text-[14px]";
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const storedTextSize = window.localStorage.getItem("anythingllm_text_size");
|
||||
if (storedTextSize) {
|
||||
setTextSize(storedTextSize);
|
||||
setTextSizeClass(getTextSizeClass(storedTextSize));
|
||||
}
|
||||
|
||||
const handleTextSizeChange = (event) => {
|
||||
const size = event.detail;
|
||||
setTextSize(size);
|
||||
setTextSizeClass(getTextSizeClass(size));
|
||||
};
|
||||
|
||||
window.addEventListener("textSizeChange", handleTextSizeChange);
|
||||
return () => {
|
||||
window.removeEventListener("textSizeChange", handleTextSizeChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return { textSize, textSizeClass };
|
||||
}
|
|
@ -25,6 +25,7 @@ import Italian from "./it/common.js";
|
|||
import Portuguese from "./pt_BR/common.js";
|
||||
import Hebrew from "./he/common.js";
|
||||
import Dutch from "./nl/common.js";
|
||||
import Vietnamese from "./vn/common.js";
|
||||
import TraditionalChinese from "./zh_TW/common.js";
|
||||
|
||||
export const defaultNS = "common";
|
||||
|
@ -65,4 +66,8 @@ export const resources = {
|
|||
nl: {
|
||||
common: Dutch,
|
||||
},
|
||||
vi: {
|
||||
common: Vietnamese,
|
||||
},
|
||||
|
||||
};
|
||||
|
|
495
frontend/src/locales/vn/common.js
Normal file
495
frontend/src/locales/vn/common.js
Normal file
|
@ -0,0 +1,495 @@
|
|||
const TRANSLATIONS = {
|
||||
common: {
|
||||
"workspaces-name": "Tên không gian làm việc",
|
||||
error: "Lỗi",
|
||||
success: "Thành công",
|
||||
user: "Người dùng",
|
||||
selection: "Lựa chọn mô hình",
|
||||
saving: "Đang lưu...",
|
||||
save: "Lưu thay đổi",
|
||||
previous: "Trang trước",
|
||||
next: "Trang tiếp theo",
|
||||
},
|
||||
|
||||
// Setting Sidebar menu items.
|
||||
settings: {
|
||||
title: "Cài đặt hệ thống",
|
||||
system: "Cài đặt chung",
|
||||
invites: "Lời mời",
|
||||
users: "Người dùngs",
|
||||
workspaces: "Không gian làm việc",
|
||||
"workspace-chats": "Hội thoại không gian làm việc",
|
||||
customization: "Tùy chỉnh",
|
||||
"api-keys": "API nhà phát triển",
|
||||
llm: "LLM",
|
||||
transcription: "Chuyển đổi giọng nói",
|
||||
embedder: "Nhúng dữ liệu",
|
||||
"text-splitting": "Chia nhỏ & Tách văn bản",
|
||||
"voice-speech": "Giọng nói & Phát âm",
|
||||
"vector-database": "Cơ sở dữ liệu Vector",
|
||||
embeds: "Nhúng hội thoại",
|
||||
"embed-chats": "Nhúng hội thoại History",
|
||||
security: "Bảo mật",
|
||||
"event-logs": "Nhật ký sự kiện",
|
||||
privacy: "Quyền riêng tư & Dữ liệu",
|
||||
"ai-providers": "Nhà cung cấp AI",
|
||||
"agent-skills": "Kỹ năng của Agent",
|
||||
admin: "Quản trị viên",
|
||||
tools: "Công cụ",
|
||||
"experimental-features": "Tính năng thử nghiệm",
|
||||
contact: "Liên hệ hỗ trợ",
|
||||
"browser-extension": "Tiện ích trình duyệt",
|
||||
},
|
||||
|
||||
// Page Definitions
|
||||
login: {
|
||||
"multi-user": {
|
||||
welcome: "Chào mừng đến với",
|
||||
"placeholder-username": "Người dùngname",
|
||||
"placeholder-password": "Mật khẩu",
|
||||
login: "Đăng nhập",
|
||||
validating: "Đang xác thực...",
|
||||
"forgot-pass": "Quên mật khẩu",
|
||||
reset: "Đặt lại",
|
||||
},
|
||||
"sign-in": {
|
||||
start: "Đăng nhập vào",
|
||||
end: "tài khoản của bạn.",
|
||||
},
|
||||
"password-reset": {
|
||||
title: "Mật khẩu Đặt lại",
|
||||
description:
|
||||
"Cung cấp thông tin cần thiết dưới đây để đặt lại mật khẩu.",
|
||||
"recovery-codes": "Mã khôi phục",
|
||||
"recovery-code": "Mã khôi phục {{index}}",
|
||||
"back-to-login": "Back to Đăng nhập",
|
||||
},
|
||||
},
|
||||
|
||||
welcomeMessage: {
|
||||
part1:
|
||||
"Chào mừng đến với AnythingLLM, AnythingLLM is an open-source AI tool by Mintplex Labs that turns anything into a trained chatbot you can query and chat with. AnythingLLM is a BYOK (bring-your-own-keys) software so there is no subscription, fee, or charges for this software outside of the services you want to use with it.",
|
||||
part2:
|
||||
"AnythingLLM is the easiest way to put powerful AI products like OpenAi, GPT-4, LangChain, PineconeDB, ChromaDB, and other services together in a neat package with no fuss to increase your productivity by 100x.",
|
||||
part3:
|
||||
"AnythingLLM can run totally locally on your machine with little overhead you wont even notice it's there! No GPU needed. Cloud and on-premises installation is available as well.\nThe AI tooling ecosystem gets more powerful everyday. AnythingLLM makes it easy to use.",
|
||||
githubIssue: "Create an issue on Github",
|
||||
user1: "How do I get started?!",
|
||||
part4:
|
||||
"It's simple. All collections are organized into buckets we call \"Không gian làm việc\". Không gian làm việc are buckets of files, documents, images, PDFs, and other files which will be transformed into something LLM's can understand and use in conversation.\n\nYou can add and remove files at anytime.",
|
||||
createWorkspace: "Create your first workspace",
|
||||
user2:
|
||||
"Is this like an AI dropbox or something? What about chatting? It is a chatbot isn't it?",
|
||||
part5:
|
||||
"AnythingLLM is more than a smarter Dropbox.\n\nAnythingLLM offers two ways of talking with your data:\n\n<i>Query:</i> Your chats will return data or inferences found with the documents in your workspace it has access to. Adding more documents to the Workspace make it smarter! \n\n<i>Conversational:</i> Your documents + your on-going chat history both contribute to the LLM knowledge at the same time. Great for appending real-time text-based info or corrections and misunderstandings the LLM might have. \n\nYou can toggle between either mode \n<i>in the middle of chatting!</i>",
|
||||
user3: "Wow, this sounds amazing, let me try it out already!",
|
||||
part6: "Have Fun!",
|
||||
starOnGithub: "Star on GitHub",
|
||||
contact: "Contact Mintplex Labs",
|
||||
},
|
||||
|
||||
"new-workspace": {
|
||||
title: "Không gian làm việc mới",
|
||||
placeholder: "Không gian làm việc của tôi",
|
||||
},
|
||||
|
||||
// Workspace Settings menu items
|
||||
"workspaces—settings": {
|
||||
general: "Cài đặt chung",
|
||||
chat: "Chat Settings",
|
||||
vector: "Cơ sở dữ liệu Vector",
|
||||
members: "Members",
|
||||
agent: "Agent Configuration",
|
||||
},
|
||||
|
||||
// General Giao diện
|
||||
general: {
|
||||
vector: {
|
||||
title: "Vector Count",
|
||||
description: "Total number of vectors in your vector database.",
|
||||
},
|
||||
names: {
|
||||
description: "This will only change the display name of your workspace.",
|
||||
},
|
||||
message: {
|
||||
title: "Tin nhắn trò chuyện được gợi ý",
|
||||
description:
|
||||
"Customize the messages that will be suggested to your workspace users.",
|
||||
add: "Add new message",
|
||||
save: "Save Messages",
|
||||
heading: "Explain to me",
|
||||
body: "the benefits of AnythingLLM",
|
||||
},
|
||||
pfp: {
|
||||
title: "Hình đại diện trợ lý",
|
||||
description:
|
||||
"Customize the profile image of the assistant for this workspace.",
|
||||
image: "Workspace Image",
|
||||
remove: "Remove Workspace Image",
|
||||
},
|
||||
delete: {
|
||||
title: "Xóa không gian làm việc",
|
||||
description:
|
||||
"Delete this workspace and all of its data. This will delete the workspace for all users.",
|
||||
delete: "Xóa không gian làm việc",
|
||||
deleting: "Deleting Workspace...",
|
||||
"confirm-start": "You are about to delete your entire",
|
||||
"confirm-end":
|
||||
"workspace. This will remove all vector embeddings in your vector database.\n\nThe original source files will remain untouched. This action is irreversible.",
|
||||
},
|
||||
},
|
||||
|
||||
// Chat Settings
|
||||
chat: {
|
||||
llm: {
|
||||
title: "Workspace LLM Provider",
|
||||
description:
|
||||
"The specific LLM provider & model that will be used for this workspace. By default, it uses the system LLM provider and settings.",
|
||||
search: "Search all LLM providers",
|
||||
},
|
||||
model: {
|
||||
title: "Workspace Chat model",
|
||||
description:
|
||||
"The specific chat model that will be used for this workspace. If empty, will use the system LLM preference.",
|
||||
wait: "-- waiting for models --",
|
||||
},
|
||||
mode: {
|
||||
title: "Chat mode",
|
||||
chat: {
|
||||
title: "Chat",
|
||||
"desc-start": "will provide answers with the LLM's general knowledge",
|
||||
and: "and",
|
||||
"desc-end": "document context that is found.",
|
||||
},
|
||||
query: {
|
||||
title: "Query",
|
||||
"desc-start": "will provide answers",
|
||||
only: "only",
|
||||
"desc-end": "if document context is found.",
|
||||
},
|
||||
},
|
||||
history: {
|
||||
title: "Chat History",
|
||||
"desc-start":
|
||||
"The number of previous chats that will be included in the response's short-term memory.",
|
||||
recommend: "Recommend 20. ",
|
||||
"desc-end":
|
||||
"Anything more than 45 is likely to lead to continuous chat failures depending on message size.",
|
||||
},
|
||||
prompt: {
|
||||
title: "Prompt",
|
||||
description:
|
||||
"The prompt that will be used on this workspace. Define the context and instructions for the AI to generate a response. You should to provide a carefully crafted prompt so the AI can generate a relevant and accurate response.",
|
||||
},
|
||||
refusal: {
|
||||
title: "Query mode refusal response",
|
||||
"desc-start": "When in",
|
||||
query: "query",
|
||||
"desc-end":
|
||||
"mode, you may want to return a custom refusal response when no context is found.",
|
||||
},
|
||||
temperature: {
|
||||
title: "LLM Temperature",
|
||||
"desc-start":
|
||||
'This setting controls how "creative" your LLM responses will be.',
|
||||
"desc-end":
|
||||
"The higher the number the more creative. For some models this can lead to incoherent responses when set too high.",
|
||||
hint: "Most LLMs have various acceptable ranges of valid values. Consult your LLM provider for that information.",
|
||||
},
|
||||
},
|
||||
|
||||
// Cơ sở dữ liệu Vector
|
||||
"vector-workspace": {
|
||||
identifier: "Vector database identifier",
|
||||
snippets: {
|
||||
title: "Max Context Snippets",
|
||||
description:
|
||||
"This setting controls the maximum amount of context snippets the will be sent to the LLM for per chat or query.",
|
||||
recommend: "Recommended: 4",
|
||||
},
|
||||
doc: {
|
||||
title: "Document similarity threshold",
|
||||
description:
|
||||
"The minimum similarity score required for a source to be considered related to the chat. The higher the number, the more similar the source must be to the chat.",
|
||||
zero: "No restriction",
|
||||
low: "Low (similarity score ≥ .25)",
|
||||
medium: "Medium (similarity score ≥ .50)",
|
||||
high: "High (similarity score ≥ .75)",
|
||||
},
|
||||
reset: {
|
||||
reset: "Đặt lại Cơ sở dữ liệu Vector",
|
||||
resetting: "Clearing vectors...",
|
||||
confirm:
|
||||
"You are about to reset this workspace's vector database. This will remove all vector embeddings currently embedded.\n\nThe original source files will remain untouched. This action is irreversible.",
|
||||
error: "Workspace vector database could not be reset!",
|
||||
success: "Workspace vector database was reset!",
|
||||
},
|
||||
},
|
||||
|
||||
// Agent Configuration
|
||||
agent: {
|
||||
"performance-warning":
|
||||
"Performance of LLMs that do not explicitly support tool-calling is highly dependent on the model's capabilities and accuracy. Some abilities may be limited or non-functional.",
|
||||
provider: {
|
||||
title: "Workspace Agent LLM Provider",
|
||||
description:
|
||||
"The specific LLM provider & model that will be used for this workspace's @agent agent.",
|
||||
},
|
||||
mode: {
|
||||
chat: {
|
||||
title: "Workspace Agent Chat model",
|
||||
description:
|
||||
"The specific chat model that will be used for this workspace's @agent agent.",
|
||||
},
|
||||
title: "Workspace Agent model",
|
||||
description:
|
||||
"The specific LLM model that will be used for this workspace's @agent agent.",
|
||||
wait: "-- waiting for models --",
|
||||
},
|
||||
|
||||
skill: {
|
||||
title: "Default agent skills",
|
||||
description:
|
||||
"Improve the natural abilities of the default agent with these pre-built skills. This set up applies to all workspaces.",
|
||||
rag: {
|
||||
title: "RAG & long-term memory",
|
||||
description:
|
||||
'Allow the agent to leverage your local documents to answer a query or ask the agent to "remember" pieces of content for long-term memory retrieval.',
|
||||
},
|
||||
view: {
|
||||
title: "View & summarize documents",
|
||||
description:
|
||||
"Allow the agent to list and summarize the content of workspace files currently embedded.",
|
||||
},
|
||||
scrape: {
|
||||
title: "Scrape websites",
|
||||
description:
|
||||
"Allow the agent to visit and scrape the content of websites.",
|
||||
},
|
||||
generate: {
|
||||
title: "Generate charts",
|
||||
description:
|
||||
"Enable the default agent to generate various types of charts from data provided or given in chat.",
|
||||
},
|
||||
save: {
|
||||
title: "Generate & save files to browser",
|
||||
description:
|
||||
"Enable the default agent to generate and write to files that save and can be downloaded in your browser.",
|
||||
},
|
||||
web: {
|
||||
title: "Live web search and browsing",
|
||||
"desc-start":
|
||||
"Enable your agent to search the web to answer your questions by connecting to a web-search (SERP) provider.",
|
||||
"desc-end":
|
||||
"Web search during agent sessions will not work until this is set up.",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Hội thoại không gian làm việc
|
||||
recorded: {
|
||||
title: "Hội thoại không gian làm việc",
|
||||
description:
|
||||
"These are all the recorded chats and messages that have been sent by users ordered by their creation date.",
|
||||
export: "Export",
|
||||
table: {
|
||||
id: "Id",
|
||||
by: "Sent By",
|
||||
workspace: "Workspace",
|
||||
prompt: "Prompt",
|
||||
response: "Response",
|
||||
at: "Sent At",
|
||||
},
|
||||
},
|
||||
|
||||
// Giao diện
|
||||
appearance: {
|
||||
title: "Giao diện",
|
||||
description: "Customize the appearance settings of your platform.",
|
||||
logo: {
|
||||
title: "Tùy chỉnh logo",
|
||||
description: "Upload your custom logo to make your chatbot yours.",
|
||||
add: "Add a custom logo",
|
||||
recommended: "Recommended size: 800 x 200",
|
||||
remove: "Remove",
|
||||
replace: "Replace",
|
||||
},
|
||||
message: {
|
||||
title: "Customize Messages",
|
||||
description: "Customize the automatic messages displayed to your users.",
|
||||
new: "New",
|
||||
system: "system",
|
||||
user: "user",
|
||||
message: "message",
|
||||
assistant: "AnythingLLM Chat Assistant",
|
||||
"double-click": "Double click to edit...",
|
||||
save: "Save Messages",
|
||||
},
|
||||
icons: {
|
||||
title: "Custom Footer Icons",
|
||||
description:
|
||||
"Customize the footer icons displayed on the bottom of the sidebar.",
|
||||
icon: "Icon",
|
||||
link: "Link",
|
||||
},
|
||||
},
|
||||
|
||||
// Khóa API
|
||||
api: {
|
||||
title: "Khóa API",
|
||||
description:
|
||||
"API keys allow the holder to programmatically access and manage this AnythingLLM instance.",
|
||||
link: "Read the API documentation",
|
||||
generate: "Generate New API Key",
|
||||
table: {
|
||||
key: "API Key",
|
||||
by: "Created By",
|
||||
created: "Created",
|
||||
},
|
||||
},
|
||||
|
||||
llm: {
|
||||
title: "LLM Preference",
|
||||
description:
|
||||
"These are the credentials and settings for your preferred LLM chat & embedding provider. Its important these keys are current and correct or else AnythingLLM will not function properly.",
|
||||
provider: "LLM Provider",
|
||||
},
|
||||
|
||||
transcription: {
|
||||
title: "Chuyển đổi giọng nói Model Preference",
|
||||
description:
|
||||
"These are the credentials and settings for your preferred transcription model provider. Its important these keys are current and correct or else media files and audio will not transcribe.",
|
||||
provider: "Chuyển đổi giọng nói Provider",
|
||||
"warn-start":
|
||||
"Using the local whisper model on machines with limited RAM or CPU can stall AnythingLLM when processing media files.",
|
||||
"warn-recommend":
|
||||
"We recommend at least 2GB of RAM and upload files <10Mb.",
|
||||
"warn-end":
|
||||
"The built-in model will automatically download on the first use.",
|
||||
},
|
||||
|
||||
embedding: {
|
||||
title: "Tùy chọn nhúng",
|
||||
"desc-start":
|
||||
"When using an LLM that does not natively support an embedding engine - you may need to additionally specify credentials to for embedding text.",
|
||||
"desc-end":
|
||||
"Embedding is the process of turning text into vectors. These credentials are required to turn your files and prompts into a format which AnythingLLM can use to process.",
|
||||
provider: {
|
||||
title: "Embedding Provider",
|
||||
description:
|
||||
"There is no set up required when using AnythingLLM's native embedding engine.",
|
||||
},
|
||||
},
|
||||
|
||||
text: {
|
||||
title: "Tùy chọn chia nhỏ và tách văn bản",
|
||||
"desc-start":
|
||||
"Sometimes, you may want to change the default way that new documents are split and chunked before being inserted into your vector database.",
|
||||
"desc-end":
|
||||
"You should only modify this setting if you understand how text splitting works and it's side effects.",
|
||||
"warn-start": "Changes here will only apply to",
|
||||
"warn-center": "newly embedded documents",
|
||||
"warn-end": ", not existing documents.",
|
||||
size: {
|
||||
title: "Text Chunk Size",
|
||||
description:
|
||||
"This is the maximum length of characters that can be present in a single vector.",
|
||||
recommend: "Embed model maximum length is",
|
||||
},
|
||||
|
||||
overlap: {
|
||||
title: "Text Chunk Overlap",
|
||||
description:
|
||||
"This is the maximum overlap of characters that occurs during chunking between two adjacent text chunks.",
|
||||
},
|
||||
},
|
||||
|
||||
// Cơ sở dữ liệu Vector
|
||||
vector: {
|
||||
title: "Cơ sở dữ liệu Vector",
|
||||
description:
|
||||
"These are the credentials and settings for how your AnythingLLM instance will function. It's important these keys are current and correct.",
|
||||
provider: {
|
||||
title: "Cơ sở dữ liệu Vector Provider",
|
||||
description: "There is no configuration needed for LanceDB.",
|
||||
},
|
||||
},
|
||||
|
||||
// Tiện ích hội thoại nhúng
|
||||
embeddable: {
|
||||
title: "Tiện ích hội thoại nhúng",
|
||||
description:
|
||||
"Embeddable chat widgets are public facing chat interfaces that are tied to a single workspace. These allow you to build workspaces that then you can publish to the world.",
|
||||
create: "Tạo nhúng",
|
||||
table: {
|
||||
workspace: "Workspace",
|
||||
chats: "Sent Chats",
|
||||
Active: "Active Domains",
|
||||
},
|
||||
},
|
||||
|
||||
"embed-chats": {
|
||||
title: "Embed Chats",
|
||||
export: "Export",
|
||||
description:
|
||||
"These are all the recorded chats and messages from any embed that you have published.",
|
||||
table: {
|
||||
embed: "Embed",
|
||||
sender: "Sender",
|
||||
message: "Message",
|
||||
response: "Response",
|
||||
at: "Sent At",
|
||||
},
|
||||
},
|
||||
|
||||
multi: {
|
||||
title: "Multi-Người dùng Mode",
|
||||
description:
|
||||
"Set up your instance to support your team by activating Multi-Người dùng Mode.",
|
||||
enable: {
|
||||
"is-enable": "Multi-Người dùng Mode is Enabled",
|
||||
enable: "Enable Multi-Người dùng Mode",
|
||||
description:
|
||||
"By default, you will be the only admin. As an admin you will need to create accounts for all new users or admins. Do not lose your password as only an Quản trị viên user can reset passwords.",
|
||||
username: "Quản trị viên account username",
|
||||
password: "Quản trị viên account password",
|
||||
},
|
||||
password: {
|
||||
title: "Mật khẩu Protection",
|
||||
description:
|
||||
"Protect your AnythingLLM instance with a password. If you forget this there is no recovery method so ensure you save this password.",
|
||||
},
|
||||
instance: {
|
||||
title: "Mật khẩu Protect Instance",
|
||||
description:
|
||||
"By default, you will be the only admin. As an admin you will need to create accounts for all new users or admins. Do not lose your password as only an Quản trị viên user can reset passwords.",
|
||||
password: "Instance password",
|
||||
},
|
||||
},
|
||||
|
||||
// Nhật ký sự kiện
|
||||
event: {
|
||||
title: "Nhật ký sự kiện",
|
||||
description:
|
||||
"View all actions and events happening on this instance for monitoring.",
|
||||
clear: "Clear Nhật ký sự kiện",
|
||||
table: {
|
||||
type: "Event Type",
|
||||
user: "Người dùng",
|
||||
occurred: "Occurred At",
|
||||
},
|
||||
},
|
||||
|
||||
// Quyền riêng tư & Dữ liệu-Handling
|
||||
privacy: {
|
||||
title: "Quyền riêng tư & Dữ liệu-Handling",
|
||||
description:
|
||||
"This is your configuration for how connected third party providers and AnythingLLM handle your data.",
|
||||
llm: "LLM Selection",
|
||||
embedding: "Tùy chọn nhúng",
|
||||
vector: "Cơ sở dữ liệu Vector",
|
||||
anonymous: "Anonymous Telemetry Enabled",
|
||||
},
|
||||
};
|
||||
|
||||
export default TRANSLATIONS;
|
|
@ -13,6 +13,7 @@ import CohereLogo from "@/media/llmprovider/cohere.png";
|
|||
import VoyageAiLogo from "@/media/embeddingprovider/voyageai.png";
|
||||
import LiteLLMLogo from "@/media/llmprovider/litellm.png";
|
||||
import GenericOpenAiLogo from "@/media/llmprovider/generic-openai.png";
|
||||
import MistralAiLogo from "@/media/llmprovider/mistral.jpeg";
|
||||
|
||||
import PreLoader from "@/components/Preloader";
|
||||
import ChangeWarningModal from "@/components/ChangeWarning";
|
||||
|
@ -33,6 +34,7 @@ import { useModal } from "@/hooks/useModal";
|
|||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import MistralAiOptions from "@/components/EmbeddingSelection/MistralAiOptions";
|
||||
|
||||
const EMBEDDERS = [
|
||||
{
|
||||
|
@ -100,6 +102,13 @@ const EMBEDDERS = [
|
|||
options: (settings) => <LiteLLMOptions settings={settings} />,
|
||||
description: "Run powerful embedding models from LiteLLM.",
|
||||
},
|
||||
{
|
||||
name: "Mistral AI",
|
||||
value: "mistral",
|
||||
logo: MistralAiLogo,
|
||||
options: (settings) => <MistralAiOptions settings={settings} />,
|
||||
description: "Run powerful embedding models from Mistral AI.",
|
||||
},
|
||||
{
|
||||
name: "Generic OpenAI",
|
||||
value: "generic-openai",
|
||||
|
|
|
@ -349,6 +349,13 @@ export const EMBEDDING_ENGINE_PRIVACY = {
|
|||
],
|
||||
logo: VoyageAiLogo,
|
||||
},
|
||||
mistral: {
|
||||
name: "Mistral AI",
|
||||
description: [
|
||||
"Data sent to Mistral AI's servers is shared according to the terms of service of https://mistral.ai.",
|
||||
],
|
||||
logo: MistralLogo,
|
||||
},
|
||||
litellm: {
|
||||
name: "LiteLLM",
|
||||
description: [
|
||||
|
|
|
@ -154,6 +154,7 @@ SIG_SALT='salt' # Please generate random string at least 32 chars long.
|
|||
# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=8192
|
||||
# EMBEDDING_BASE_PATH='http://127.0.0.1:4000'
|
||||
# GENERIC_OPEN_AI_EMBEDDING_API_KEY='sk-123abc'
|
||||
# GENERIC_OPEN_AI_EMBEDDING_MAX_CONCURRENT_CHUNKS=500
|
||||
|
||||
###########################################
|
||||
######## Vector Database Selection ########
|
||||
|
|
|
@ -193,6 +193,8 @@ const SystemSettings = {
|
|||
process.env.EMBEDDING_MODEL_MAX_CHUNK_LENGTH,
|
||||
GenericOpenAiEmbeddingApiKey:
|
||||
!!process.env.GENERIC_OPEN_AI_EMBEDDING_API_KEY,
|
||||
GenericOpenAiEmbeddingMaxConcurrentChunks:
|
||||
process.env.GENERIC_OPEN_AI_EMBEDDING_MAX_CONCURRENT_CHUNKS || 500,
|
||||
|
||||
// --------------------------------------------------------
|
||||
// VectorDB Provider Selection Settings & Configs
|
||||
|
|
|
@ -14,13 +14,26 @@ class GenericOpenAiEmbedder {
|
|||
});
|
||||
this.model = process.env.EMBEDDING_MODEL_PREF ?? null;
|
||||
|
||||
// Limit of how many strings we can process in a single pass to stay with resource or network limits
|
||||
this.maxConcurrentChunks = 500;
|
||||
|
||||
// this.maxConcurrentChunks is delegated to the getter below.
|
||||
// Refer to your specific model and provider you use this class with to determine a valid maxChunkLength
|
||||
this.embeddingMaxChunkLength = 8_191;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the `GENERIC_OPEN_AI_EMBEDDING_MAX_CONCURRENT_CHUNKS` env variable as a number
|
||||
* or 500 if the env variable is not set or is not a number.
|
||||
* @returns {number}
|
||||
*/
|
||||
get maxConcurrentChunks() {
|
||||
if (!process.env.GENERIC_OPEN_AI_EMBEDDING_MAX_CONCURRENT_CHUNKS)
|
||||
return 500;
|
||||
if (
|
||||
isNaN(Number(process.env.GENERIC_OPEN_AI_EMBEDDING_MAX_CONCURRENT_CHUNKS))
|
||||
)
|
||||
return 500;
|
||||
return Number(process.env.GENERIC_OPEN_AI_EMBEDDING_MAX_CONCURRENT_CHUNKS);
|
||||
}
|
||||
|
||||
async embedTextInput(textInput) {
|
||||
const result = await this.embedChunks(
|
||||
Array.isArray(textInput) ? textInput : [textInput]
|
||||
|
|
43
server/utils/EmbeddingEngines/mistral/index.js
Normal file
43
server/utils/EmbeddingEngines/mistral/index.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
class MistralEmbedder {
|
||||
constructor() {
|
||||
if (!process.env.MISTRAL_API_KEY)
|
||||
throw new Error("No Mistral API key was set.");
|
||||
|
||||
const { OpenAI: OpenAIApi } = require("openai");
|
||||
this.openai = new OpenAIApi({
|
||||
baseURL: "https://api.mistral.ai/v1",
|
||||
apiKey: process.env.MISTRAL_API_KEY ?? null,
|
||||
});
|
||||
this.model = process.env.EMBEDDING_MODEL_PREF || "mistral-embed";
|
||||
}
|
||||
|
||||
async embedTextInput(textInput) {
|
||||
try {
|
||||
const response = await this.openai.embeddings.create({
|
||||
model: this.model,
|
||||
input: textInput,
|
||||
});
|
||||
return response?.data[0]?.embedding || [];
|
||||
} catch (error) {
|
||||
console.error("Failed to get embedding from Mistral.", error.message);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async embedChunks(textChunks = []) {
|
||||
try {
|
||||
const response = await this.openai.embeddings.create({
|
||||
model: this.model,
|
||||
input: textChunks,
|
||||
});
|
||||
return response?.data?.map((emb) => emb.embedding) || [];
|
||||
} catch (error) {
|
||||
console.error("Failed to get embeddings from Mistral.", error.message);
|
||||
return new Array(textChunks.length).fill([]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
MistralEmbedder,
|
||||
};
|
|
@ -214,6 +214,9 @@ function getEmbeddingEngineSelection() {
|
|||
case "litellm":
|
||||
const { LiteLLMEmbedder } = require("../EmbeddingEngines/liteLLM");
|
||||
return new LiteLLMEmbedder();
|
||||
case "mistral":
|
||||
const { MistralEmbedder } = require("../EmbeddingEngines/mistral");
|
||||
return new MistralEmbedder();
|
||||
case "generic-openai":
|
||||
const {
|
||||
GenericOpenAiEmbedder,
|
||||
|
|
|
@ -267,6 +267,10 @@ const KEY_MAPPING = {
|
|||
envKey: "GENERIC_OPEN_AI_EMBEDDING_API_KEY",
|
||||
checks: [],
|
||||
},
|
||||
GenericOpenAiEmbeddingMaxConcurrentChunks: {
|
||||
envKey: "GENERIC_OPEN_AI_EMBEDDING_MAX_CONCURRENT_CHUNKS",
|
||||
checks: [nonZero],
|
||||
},
|
||||
|
||||
// Vector Database Selection Settings
|
||||
VectorDB: {
|
||||
|
@ -753,6 +757,7 @@ function supportedEmbeddingModel(input = "") {
|
|||
"voyageai",
|
||||
"litellm",
|
||||
"generic-openai",
|
||||
"mistral",
|
||||
];
|
||||
return supported.includes(input)
|
||||
? null
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue