patch with master

This commit is contained in:
timothycarambat 2024-04-05 09:45:28 -07:00
commit 2638098d49
21 changed files with 169 additions and 227 deletions

View File

@ -135,30 +135,27 @@ Mintplex Labs & the community maintain a number of deployment methods, scripts,
- create PR with branch name format of `<issue number>-<short name>`
- yee haw let's merge
<details>
<summary><kbd>Telemetry for AnythingLLM</kbd></summary>
## Telemetry
## Telemetry & Privacy
AnythingLLM by Mintplex Labs Inc contains a telemetry feature that collects anonymous usage information.
<details>
<summary><kbd>More about Telemetry & Privacy for AnythingLLM</kbd></summary>
### Why?
We use this information to help us understand how AnythingLLM is used, to help us prioritize work on new features and bug fixes, and to help us improve AnythingLLM's performance and stability.
### Opting out
Set `DISABLE_TELEMETRY` in your server or docker .env settings to "true" to opt out of telemetry.
```
DISABLE_TELEMETRY="true"
```
Set `DISABLE_TELEMETRY` in your server or docker .env settings to "true" to opt out of telemetry. You can also do this in-app by going to the sidebar > `Privacy` and disabling telemetry.
### What do you explicitly track?
We will only track usage details that help us make product and roadmap decisions, specifically:
- Version of your installation
- Typ of your installation (Docker or Desktop)
- When a document is added or removed. No information _about_ the document. Just that the event occurred. This gives us an idea of use.
- Type of vector database in use. Let's us know which vector database provider is the most used to prioritize changes when updates arrive for that provider.
- Type of LLM in use. Let's us know the most popular choice and prioritize changes when updates arrive for that provider.
@ -166,6 +163,8 @@ We will only track usage details that help us make product and roadmap decisions
You can verify these claims by finding all locations `Telemetry.sendTelemetry` is called. Additionally these events are written to the output log so you can also see the specific data which was sent - if enabled. No IP or other identifying information is collected. The Telemetry provider is [PostHog](https://posthog.com/) - an open-source telemetry collection service.
[View all telemetry events in source code](https://github.com/search?q=repo%3AMintplex-Labs%2Fanything-llm%20.sendTelemetry\(&type=code)
</details>
## 🔗 More Products

View File

@ -1,11 +1,14 @@
const crypto = require("crypto");
const fs = require("fs");
const path = require("path");
const keyPath =
process.env.NODE_ENV === "development"
? path.resolve(__dirname, `../../../server/storage/comkey`)
: path.resolve(process.env.STORAGE_DIR, `comkey`);
: path.resolve(
process.env.STORAGE_DIR ??
path.resolve(__dirname, `../../../server/storage`),
`comkey`
);
class CommunicationKey {
#pubKeyName = "ipc-pub.pem";

View File

@ -34,6 +34,7 @@ export default function App() {
<div className={`fixed inset-0 z-50 ${isChatOpen ? "block" : "hidden"}`}>
<div
className={`w-full h-full bg-white md:max-w-[400px] md:max-h-[700px] md:fixed md:bottom-0 md:right-0 md:mb-4 md:mr-4 md:rounded-2xl md:border md:border-gray-300 md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] ${positionClasses[position]}`}
id="anything-llm-chat"
>
{isChatOpen && (
<ChatWindow

View File

@ -34,6 +34,7 @@ const HistoricalMessage = forwardRef(
src={AnythingLLMIcon}
alt="Anything LLM Icon"
className="w-9 h-9 flex-shrink-0 ml-2 mt-2"
id="anything-llm-icon"
/>
)}
<div
@ -42,8 +43,8 @@ const HistoricalMessage = forwardRef(
error
? "bg-red-200 rounded-lg mr-[37px] ml-[9px]"
: role === "user"
? embedderSettings.USER_STYLES
: embedderSettings.ASSISTANT_STYLES
? `${embedderSettings.USER_STYLES} anything-llm-user-message`
: `${embedderSettings.ASSISTANT_STYLES} anything-llm-assistant-message`
} shadow-[0_4px_14px_rgba(0,0,0,0.25)]`}
>
<div className="flex">

View File

@ -104,6 +104,8 @@ export default function ChatHistory({ settings = {}, history = [] }) {
weight="bold"
className="text-white/50 w-5 h-5"
onClick={scrollToBottom}
id="scroll-to-bottom-button"
aria-label="Scroll to bottom"
/>
</div>
</div>

View File

@ -69,12 +69,15 @@ export default function PromptInput({
value={message}
className="cursor-text max-h-[100px] text-[14px] mx-2 py-2 w-full text-black bg-transparent placeholder:text-slate-800/60 resize-none active:outline-none focus:outline-none flex-grow"
placeholder={"Send a message"}
id="message-input"
/>
<button
ref={formRef}
type="submit"
disabled={buttonDisabled}
className="inline-flex justify-center rounded-2xl cursor-pointer text-black group ml-4"
id="send-message-button"
aria-label="Send message"
>
{buttonDisabled ? (
<CircleNotch className="w-4 h-4 animate-spin" />

View File

@ -44,7 +44,10 @@ export default function ChatWindowHeader({
}, [menuRef]);
return (
<div className="flex items-center relative rounded-t-2xl bg-black/10">
<div
className="flex items-center relative rounded-t-2xl bg-black/10"
id="anything-llm-header"
>
<div className="flex justify-center items-center w-full h-[76px]">
<img
style={{ maxWidth: 48, maxHeight: 48 }}
@ -59,6 +62,7 @@ export default function ChatWindowHeader({
type="button"
onClick={() => setShowOptions(!showingOptions)}
className="hover:bg-gray-100 rounded-sm text-slate-800"
aria-label="Options"
>
<DotsThreeOutlineVertical size={20} weight="fill" />
</button>
@ -67,6 +71,7 @@ export default function ChatWindowHeader({
type="button"
onClick={closeChat}
className="hover:bg-gray-100 rounded-sm text-slate-800"
aria-label="Close"
>
<X size={20} weight="bold" />
</button>

File diff suppressed because one or more lines are too long

View File

@ -52,6 +52,7 @@ export default function Footer() {
target="_blank"
rel="noreferrer"
className="transition-all duration-300 p-2 rounded-full text-white bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
aria-label="Find us on Github"
>
<GithubLogo weight="fill" className="h-5 w-5 " />
</a>
@ -60,6 +61,7 @@ export default function Footer() {
target="_blank"
rel="noreferrer"
className="transition-all duration-300 p-2 rounded-full text-white bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
aria-label="Docs"
>
<BookOpen weight="fill" className="h-5 w-5 " />
</a>
@ -68,6 +70,7 @@ export default function Footer() {
target="_blank"
rel="noreferrer"
className="transition-all duration-300 p-2 rounded-full text-white bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
aria-label="Join our Discord server"
>
<DiscordLogo
weight="fill"

View File

@ -15,6 +15,7 @@ export default function SettingsButton() {
<Link
to={paths.home()}
className="transition-all duration-300 p-2 rounded-full text-white bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
aria-label="Home"
>
<ArrowUUpLeft className="h-5 w-5" weight="fill" />
</Link>
@ -24,6 +25,7 @@ export default function SettingsButton() {
<Link
to={!!user?.role ? paths.settings.system() : paths.settings.appearance()}
className="transition-all duration-300 p-2 rounded-full text-white bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
aria-label="Settings"
>
<Wrench className="h-5 w-5" weight="fill" />
</Link>

View File

@ -25,7 +25,10 @@ export default function ThreadItem({
: paths.workspace.thread(slug, thread.slug);
return (
<div className="w-full relative flex h-[38px] items-center border-none hover:bg-slate-600/20 rounded-lg">
<div
className="w-full relative flex h-[38px] items-center border-none hover:bg-slate-600/20 rounded-lg"
role="listitem"
>
{/* Curved line Element and leader if required */}
<div
style={{ width: THREAD_CALLOUT_DETAIL_WIDTH / 2 }}
@ -63,6 +66,7 @@ export default function ThreadItem({
<a
href={window.location.pathname === linkTo ? "#" : linkTo}
className="w-full"
aria-current={isActive ? "page" : ""}
>
<p
className={`text-left text-sm ${
@ -79,6 +83,7 @@ export default function ThreadItem({
<button
type="button"
onClick={() => setShowOptions(!showOptions)}
aria-label="Thread options"
>
<DotsThree className="text-slate-300" size={25} />
</button>

View File

@ -46,7 +46,7 @@ export default function ThreadContainer({ workspace }) {
? threads.findIndex((thread) => thread?.slug === threadSlug) + 1
: 0;
return (
<div className="flex flex-col">
<div className="flex flex-col" role="list" aria-label="Threads">
<ThreadItem
idx={0}
activeIdx={activeThreadIdx}

View File

@ -72,7 +72,7 @@ export default function ActiveWorkspaces() {
}
return (
<>
<div role="list" aria-label="Workspaces">
{workspaces.map((workspace) => {
const isActive = workspace.slug === slug;
const isHovered = hoverStates[workspace.id];
@ -82,6 +82,7 @@ export default function ActiveWorkspaces() {
onMouseEnter={() => handleMouseEnter(workspace.id)}
onMouseLeave={() => handleMouseLeave(workspace.id)}
key={workspace.id}
role="listitem"
>
<div
key={workspace.id}
@ -89,6 +90,7 @@ export default function ActiveWorkspaces() {
>
<a
href={isActive ? null : paths.workspace.chat(workspace.slug)}
aria-current={isActive ? "page" : ""}
className={`
transition-all duration-[200ms]
flex flex-grow w-[75%] gap-x-2 py-[6px] px-[12px] rounded-[4px] text-white justify-start items-center
@ -154,6 +156,7 @@ export default function ActiveWorkspaces() {
onMouseEnter={() => handleGearMouseEnter(workspace.id)}
onMouseLeave={() => handleGearMouseLeave(workspace.id)}
className="rounded-md flex items-center justify-center text-[#A7A8A9] hover:text-white ml-auto"
aria-label="General appearance settings"
>
<div className="flex hover:bg-[#646768] p-[2px] rounded-[4px]">
<GearSix
@ -186,6 +189,6 @@ export default function ActiveWorkspaces() {
providedSlug={selectedWs ? selectedWs.slug : null}
/>
)}
</>
</div>
);
}

View File

@ -27,6 +27,7 @@ export default function Sidebar() {
<Link
to={paths.home()}
className="flex shrink-0 max-w-[55%] items-center justify-start mx-[38px] my-[18px]"
aria-label="Home"
>
<img
src={logo}
@ -104,6 +105,7 @@ export function SidebarMobileHeader() {
className="rounded-md p-2 flex items-center justify-center text-slate-200"
>
<List className="h-6 w-6" />
aria-label="Show sidebar"
</button>
<div className="flex items-center justify-center flex-grow">
<img

View File

@ -58,6 +58,7 @@ function FeedbackButton({
data-tooltip-id={tooltipId}
data-tooltip-content={tooltipContent}
className="text-zinc-300"
aria-label={tooltipContent}
>
<IconComponent
size={18}
@ -86,6 +87,7 @@ function CopyMessage({ message }) {
data-tooltip-id="copy-assistant-text"
data-tooltip-content="Copy"
className="text-zinc-300"
aria-label="Copy"
>
{copied ? (
<Check size={18} className="mb-1" />

View File

@ -14,6 +14,7 @@ export default function StopGenerationButton() {
data-tooltip-id="stop-generation-button"
data-tooltip-content="Stop generating response"
className="border-none text-white/60 cursor-pointer group"
aria-label="Stop generating"
>
<svg
width="28"

View File

@ -100,6 +100,7 @@ export function OnboardingLayout({ children }) {
disabled={backBtn.disabled}
onClick={backBtn.onClick}
className="group p-2 rounded-lg border-2 border-zinc-300 disabled:border-zinc-600 h-fit w-fit disabled:not-allowed hover:bg-zinc-100 disabled:hover:bg-transparent"
aria-label="Back"
>
<ArrowLeft
className="text-white group-hover:text-black group-disabled:text-gray-500"
@ -127,6 +128,7 @@ export function OnboardingLayout({ children }) {
disabled={forwardBtn.disabled}
onClick={forwardBtn.onClick}
className="group p-2 rounded-lg border-2 border-zinc-300 disabled:border-zinc-600 h-fit w-fit disabled:not-allowed hover:bg-zinc-100 disabled:hover:bg-transparent"
aria-label="Continue"
>
<ArrowRight
className="text-white group-hover:text-black group-disabled:text-gray-500"

View File

@ -37,236 +37,133 @@ const SystemSettings = {
const llmProvider = process.env.LLM_PROVIDER;
const vectorDB = process.env.VECTOR_DB;
return {
// --------------------------------------------------------
// General Settings
// --------------------------------------------------------
RequiresAuth: !!process.env.AUTH_TOKEN,
AuthToken: !!process.env.AUTH_TOKEN,
JWTSecret: !!process.env.JWT_SECRET,
StorageDir: process.env.STORAGE_DIR,
MultiUserMode: await this.isMultiUserMode(),
VectorDB: vectorDB,
HasExistingEmbeddings: await this.hasEmbeddings(),
DisableTelemetry: process.env.DISABLE_TELEMETRY || "false",
// --------------------------------------------------------
// Embedder Provider Selection Settings & Configs
// --------------------------------------------------------
EmbeddingEngine: process.env.EMBEDDING_ENGINE,
HasExistingEmbeddings: await this.hasEmbeddings(),
EmbeddingBasePath: process.env.EMBEDDING_BASE_PATH,
EmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
EmbeddingModelMaxChunkLength:
process.env.EMBEDDING_MODEL_MAX_CHUNK_LENGTH,
LocalAiApiKey: !!process.env.LOCAL_AI_API_KEY,
DisableTelemetry: process.env.DISABLE_TELEMETRY || "false",
...(vectorDB === "pinecone"
? {
PineConeKey: !!process.env.PINECONE_API_KEY,
PineConeIndex: process.env.PINECONE_INDEX,
}
: {}),
...(vectorDB === "chroma"
? {
ChromaEndpoint: process.env.CHROMA_ENDPOINT,
ChromaApiHeader: process.env.CHROMA_API_HEADER,
ChromaApiKey: !!process.env.CHROMA_API_KEY,
}
: {}),
...(vectorDB === "weaviate"
? {
WeaviateEndpoint: process.env.WEAVIATE_ENDPOINT,
WeaviateApiKey: process.env.WEAVIATE_API_KEY,
}
: {}),
...(vectorDB === "qdrant"
? {
QdrantEndpoint: process.env.QDRANT_ENDPOINT,
QdrantApiKey: process.env.QDRANT_API_KEY,
}
: {}),
...(vectorDB === "milvus"
? {
MilvusAddress: process.env.MILVUS_ADDRESS,
MilvusUsername: process.env.MILVUS_USERNAME,
MilvusPassword: !!process.env.MILVUS_PASSWORD,
}
: {}),
...(vectorDB === "zilliz"
? {
ZillizEndpoint: process.env.ZILLIZ_ENDPOINT,
ZillizApiToken: process.env.ZILLIZ_API_TOKEN,
}
: {}),
...(vectorDB === "astra"
? {
AstraDBApplicationToken: process?.env?.ASTRA_DB_APPLICATION_TOKEN,
AstraDBEndpoint: process?.env?.ASTRA_DB_ENDPOINT,
}
: {}),
// --------------------------------------------------------
// VectorDB Provider Selection Settings & Configs
// --------------------------------------------------------
VectorDB: vectorDB,
// Pinecone DB Keys
PineConeKey: !!process.env.PINECONE_API_KEY,
PineConeIndex: process.env.PINECONE_INDEX,
// Chroma DB Keys
ChromaEndpoint: process.env.CHROMA_ENDPOINT,
ChromaApiHeader: process.env.CHROMA_API_HEADER,
ChromaApiKey: !!process.env.CHROMA_API_KEY,
// Weaviate DB Keys
WeaviateEndpoint: process.env.WEAVIATE_ENDPOINT,
WeaviateApiKey: process.env.WEAVIATE_API_KEY,
// QDrant DB Keys
QdrantEndpoint: process.env.QDRANT_ENDPOINT,
QdrantApiKey: process.env.QDRANT_API_KEY,
// Milvus DB Keys
MilvusAddress: process.env.MILVUS_ADDRESS,
MilvusUsername: process.env.MILVUS_USERNAME,
MilvusPassword: !!process.env.MILVUS_PASSWORD,
// Zilliz DB Keys
ZillizEndpoint: process.env.ZILLIZ_ENDPOINT,
ZillizApiToken: process.env.ZILLIZ_API_TOKEN,
// AstraDB Keys
AstraDBApplicationToken: process?.env?.ASTRA_DB_APPLICATION_TOKEN,
AstraDBEndpoint: process?.env?.ASTRA_DB_ENDPOINT,
// --------------------------------------------------------
// LLM Provider Selection Settings & Configs
// --------------------------------------------------------
LLMProvider: llmProvider,
...(llmProvider === "openai"
? {
OpenAiKey: !!process.env.OPEN_AI_KEY,
OpenAiModelPref: process.env.OPEN_MODEL_PREF || "gpt-3.5-turbo",
}
: {}),
// OpenAI Keys
OpenAiKey: !!process.env.OPEN_AI_KEY,
OpenAiModelPref: process.env.OPEN_MODEL_PREF || "gpt-3.5-turbo",
...(llmProvider === "azure"
? {
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiModelPref: process.env.OPEN_MODEL_PREF,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
AzureOpenAiTokenLimit: process.env.AZURE_OPENAI_TOKEN_LIMIT || 4096,
}
: {}),
// Azure + OpenAI Keys
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiModelPref: process.env.OPEN_MODEL_PREF,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
AzureOpenAiTokenLimit: process.env.AZURE_OPENAI_TOKEN_LIMIT || 4096,
...(llmProvider === "anthropic"
? {
AnthropicApiKey: !!process.env.ANTHROPIC_API_KEY,
AnthropicModelPref: process.env.ANTHROPIC_MODEL_PREF || "claude-2",
// Anthropic Keys
AnthropicApiKey: !!process.env.ANTHROPIC_API_KEY,
AnthropicModelPref: process.env.ANTHROPIC_MODEL_PREF || "claude-2",
// For embedding credentials when Anthropic is selected.
OpenAiKey: !!process.env.OPEN_AI_KEY,
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
}
: {}),
// Gemini Keys
GeminiLLMApiKey: !!process.env.GEMINI_API_KEY,
GeminiLLMModelPref: process.env.GEMINI_LLM_MODEL_PREF || "gemini-pro",
...(llmProvider === "gemini"
? {
GeminiLLMApiKey: !!process.env.GEMINI_API_KEY,
GeminiLLMModelPref:
process.env.GEMINI_LLM_MODEL_PREF || "gemini-pro",
// LMStudio Keys
LMStudioBasePath: process.env.LMSTUDIO_BASE_PATH,
LMStudioTokenLimit: process.env.LMSTUDIO_MODEL_TOKEN_LIMIT,
LMStudioModelPref: process.env.LMSTUDIO_MODEL_PREF,
// For embedding credentials when Gemini is selected.
OpenAiKey: !!process.env.OPEN_AI_KEY,
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
}
: {}),
// LocalAI Keys
LocalAiApiKey: !!process.env.LOCAL_AI_API_KEY,
LocalAiBasePath: process.env.LOCAL_AI_BASE_PATH,
LocalAiModelPref: process.env.LOCAL_AI_MODEL_PREF,
LocalAiTokenLimit: process.env.LOCAL_AI_MODEL_TOKEN_LIMIT,
...(llmProvider === "lmstudio"
? {
LMStudioBasePath: process.env.LMSTUDIO_BASE_PATH,
LMStudioTokenLimit: process.env.LMSTUDIO_MODEL_TOKEN_LIMIT,
LMStudioModelPref: process.env.LMSTUDIO_MODEL_PREF,
// Ollama LLM Keys
OllamaLLMBasePath: process.env.OLLAMA_BASE_PATH,
OllamaLLMModelPref: process.env.OLLAMA_MODEL_PREF,
OllamaLLMTokenLimit: process.env.OLLAMA_MODEL_TOKEN_LIMIT,
// For embedding credentials when lmstudio is selected.
OpenAiKey: !!process.env.OPEN_AI_KEY,
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
}
: {}),
...(llmProvider === "localai"
? {
LocalAiBasePath: process.env.LOCAL_AI_BASE_PATH,
LocalAiModelPref: process.env.LOCAL_AI_MODEL_PREF,
LocalAiTokenLimit: process.env.LOCAL_AI_MODEL_TOKEN_LIMIT,
// TogetherAI Keys
TogetherAiApiKey: !!process.env.TOGETHER_AI_API_KEY,
TogetherAiModelPref: process.env.TOGETHER_AI_MODEL_PREF,
// For embedding credentials when localai is selected.
OpenAiKey: !!process.env.OPEN_AI_KEY,
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
}
: {}),
// Perplexity AI Keys
PerplexityApiKey: !!process.env.PERPLEXITY_API_KEY,
PerplexityModelPref: process.env.PERPLEXITY_MODEL_PREF,
...(llmProvider === "ollama"
? {
OllamaLLMBasePath: process.env.OLLAMA_BASE_PATH,
OllamaLLMModelPref: process.env.OLLAMA_MODEL_PREF,
OllamaLLMTokenLimit: process.env.OLLAMA_MODEL_TOKEN_LIMIT,
// OpenRouter Keys
OpenRouterApiKey: !!process.env.OPENROUTER_API_KEY,
OpenRouterModelPref: process.env.OPENROUTER_MODEL_PREF,
// For embedding credentials when ollama is selected.
OpenAiKey: !!process.env.OPEN_AI_KEY,
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
}
: {}),
...(llmProvider === "togetherai"
? {
TogetherAiApiKey: !!process.env.TOGETHER_AI_API_KEY,
TogetherAiModelPref: process.env.TOGETHER_AI_MODEL_PREF,
// Mistral AI (API) Keys
MistralApiKey: !!process.env.MISTRAL_API_KEY,
MistralModelPref: process.env.MISTRAL_MODEL_PREF,
// For embedding credentials when ollama is selected.
OpenAiKey: !!process.env.OPEN_AI_KEY,
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
}
: {}),
...(llmProvider === "perplexity"
? {
PerplexityApiKey: !!process.env.PERPLEXITY_API_KEY,
PerplexityModelPref: process.env.PERPLEXITY_MODEL_PREF,
// Groq AI API Keys
GroqApiKey: !!process.env.GROQ_API_KEY,
GroqModelPref: process.env.GROQ_MODEL_PREF,
// For embedding credentials when ollama is selected.
OpenAiKey: !!process.env.OPEN_AI_KEY,
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
}
: {}),
...(llmProvider === "openrouter"
? {
OpenRouterApiKey: !!process.env.OPENROUTER_API_KEY,
OpenRouterModelPref: process.env.OPENROUTER_MODEL_PREF,
// Native LLM Keys
NativeLLMModelPref: process.env.NATIVE_LLM_MODEL_PREF,
NativeLLMTokenLimit: process.env.NATIVE_LLM_MODEL_TOKEN_LIMIT,
// For embedding credentials when ollama is selected.
OpenAiKey: !!process.env.OPEN_AI_KEY,
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
}
: {}),
...(llmProvider === "mistral"
? {
MistralApiKey: !!process.env.MISTRAL_API_KEY,
MistralModelPref: process.env.MISTRAL_MODEL_PREF,
// HuggingFace Dedicated Inference
HuggingFaceLLMEndpoint: process.env.HUGGING_FACE_LLM_ENDPOINT,
HuggingFaceLLMAccessToken: !!process.env.HUGGING_FACE_LLM_API_KEY,
HuggingFaceLLMTokenLimit: process.env.HUGGING_FACE_LLM_TOKEN_LIMIT,
// For embedding credentials when mistral is selected.
OpenAiKey: !!process.env.OPEN_AI_KEY,
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
}
: {}),
...(llmProvider === "groq"
? {
GroqApiKey: !!process.env.GROQ_API_KEY,
GroqModelPref: process.env.GROQ_MODEL_PREF,
// For embedding credentials when groq is selected.
OpenAiKey: !!process.env.OPEN_AI_KEY,
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
}
: {}),
...(llmProvider === "native"
? {
NativeLLMModelPref: process.env.NATIVE_LLM_MODEL_PREF,
NativeLLMTokenLimit: process.env.NATIVE_LLM_MODEL_TOKEN_LIMIT,
// For embedding credentials when native is selected.
OpenAiKey: !!process.env.OPEN_AI_KEY,
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
}
: {}),
...(llmProvider === "huggingface"
? {
HuggingFaceLLMEndpoint: process.env.HUGGING_FACE_LLM_ENDPOINT,
HuggingFaceLLMAccessToken: !!process.env.HUGGING_FACE_LLM_API_KEY,
HuggingFaceLLMTokenLimit: process.env.HUGGING_FACE_LLM_TOKEN_LIMIT,
// For embedding credentials when Anthropic is selected.
OpenAiKey: !!process.env.OPEN_AI_KEY,
AzureOpenAiEndpoint: process.env.AZURE_OPENAI_ENDPOINT,
AzureOpenAiKey: !!process.env.AZURE_OPENAI_KEY,
AzureOpenAiEmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
}
: {}),
// --------------------------------------------------------
// Whisper (Audio transcription) Selection Settings & Configs
// - Currently the only 3rd party is OpenAI, so is OPEN_AI_KEY is set
// - then it can be shared.
// --------------------------------------------------------
WhisperProvider: process.env.WHISPER_PROVIDER || "local",
};
},

View File

@ -4,7 +4,10 @@ const path = require("path");
const keyPath =
process.env.NODE_ENV === "development"
? path.resolve(__dirname, `../../storage/comkey`)
: path.resolve(process.env.STORAGE_DIR, `comkey`);
: path.resolve(
process.env.STORAGE_DIR ?? path.resolve(__dirname, `../../storage`),
`comkey`
);
// What does this class do?
// This class generates a hashed version of some text (typically a JSON payload) using a rolling RSA key

View File

@ -18,8 +18,12 @@ const Milvus = {
// Milvus/Zilliz only allows letters, numbers, and underscores in collection names
// so we need to enforce that by re-normalizing the names when communicating with
// the DB.
// If the first char of the collection is not an underscore or letter the collection name will be invalid.
normalize: function (inputString) {
return inputString.replace(/[^a-zA-Z0-9_]/g, "_");
let normalized = inputString.replace(/[^a-zA-Z0-9_]/g, "_");
if (new RegExp(/^[a-zA-Z_]/).test(normalized.slice(0, 1)))
normalized = `anythingllm_${normalized}`;
return normalized;
},
connect: async function () {
if (process.env.VECTOR_DB !== "milvus")

View File

@ -20,8 +20,12 @@ const Zilliz = {
// Milvus/Zilliz only allows letters, numbers, and underscores in collection names
// so we need to enforce that by re-normalizing the names when communicating with
// the DB.
// If the first char of the collection is not an underscore or letter the collection name will be invalid.
normalize: function (inputString) {
return inputString.replace(/[^a-zA-Z0-9_]/g, "_");
let normalized = inputString.replace(/[^a-zA-Z0-9_]/g, "_");
if (new RegExp(/^[a-zA-Z_]/).test(normalized.slice(0, 1)))
normalized = `anythingllm_${normalized}`;
return normalized;
},
connect: async function () {
if (process.env.VECTOR_DB !== "zilliz")