Merge branch 'master' of github.com:Mintplex-Labs/anything-llm into render

This commit is contained in:
timothycarambat 2024-04-20 18:22:41 -07:00
commit e1372a81d4
23 changed files with 456 additions and 111 deletions

View File

@ -17,6 +17,7 @@ body:
- Docker (remote machine)
- Local development
- AnythingLLM desktop app
- All versions
- Not listed
default: 0
validations:

View File

@ -5,8 +5,8 @@
</p>
<p align="center">
<b>AnythingLLM: A private ChatGPT to chat with <i>anything!</i></b>. <br />
An efficient, customizable, and open-source enterprise-ready document chatbot solution.
<b>AnythingLLM: The all-in-one AI app you were looking for.<br />
Chat with your docs, use AI Agents, hyper-configurable, multi-user, & no fustrating set up required.
</p>
<p align="center">
@ -25,7 +25,7 @@
</p>
<p align="center">
👉 AnythingLLM for desktop is in <b>public beta</b>! <a href="https://useanything.com/download" target="_blank"> Download Now</a>
👉 AnythingLLM for desktop (Mac, Windows, & Linux)! <a href="https://useanything.com/download" target="_blank"> Download Now</a>
</p>
A full-stack application that enables you to turn any document, resource, or piece of content into context that any LLM can use as references during chatting. This application allows you to pick and choose which LLM or Vector Database you want to use as well as supporting multi-user management and permissions.
@ -48,7 +48,8 @@ AnythingLLM divides your documents into objects called `workspaces`. A Workspace
Some cool features of AnythingLLM
- **Multi-user instance support and permissioning**
- **_New_** [Custom Embeddable Chat widget for your website](./embed/README.md)
- Agents inside your workspace (browse the web, run code, etc)
- [Custom Embeddable Chat widget for your website](./embed/README.md)
- Multiple document type support (PDF, TXT, DOCX, etc)
- Manage documents in your vector database from a simple UI
- Two chat modes `conversation` and `query`. Conversation retains previous questions and amendments. Query is simple QA against your documents
@ -82,9 +83,9 @@ Some cool features of AnythingLLM
- [AnythingLLM Native Embedder](/server/storage/models/README.md) (default)
- [OpenAI](https://openai.com)
- [Azure OpenAI](https://azure.microsoft.com/en-us/products/ai-services/openai-service)
- [LM Studio (all)](https://lmstudio.ai)
- [LocalAi (all)](https://localai.io/)
- [Ollama (all)](https://ollama.ai/)
- [LM Studio (all)](https://lmstudio.ai)
**Supported Transcription models:**

View File

@ -22,7 +22,7 @@ async function asPDF({ fullFilePath = "", filename = "" }) {
doc.metadata?.loc?.pageNumber || "unknown"
} --`
);
if (!doc.pageContent.length) continue;
if (!doc.pageContent || !doc.pageContent.length) continue;
pageContent.push(doc.pageContent);
}

View File

@ -85,10 +85,15 @@ GID='1000'
# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=1000 # The max chunk size in chars a string to embed can be
# EMBEDDING_ENGINE='ollama'
# EMBEDDING_BASE_PATH='http://127.0.0.1:11434'
# EMBEDDING_BASE_PATH='http://host.docker.internal:11434'
# EMBEDDING_MODEL_PREF='nomic-embed-text:latest'
# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=8192
# EMBEDDING_ENGINE='lmstudio'
# EMBEDDING_BASE_PATH='https://host.docker.internal:1234/v1'
# EMBEDDING_MODEL_PREF='nomic-ai/nomic-embed-text-v1.5-GGUF/nomic-embed-text-v1.5.Q4_0.gguf'
# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=8192
###########################################
######## Vector Database Selection ########
###########################################

View File

@ -0,0 +1,120 @@
import React, { useEffect, useState } from "react";
import System from "@/models/system";
export default function LMStudioEmbeddingOptions({ settings }) {
const [basePathValue, setBasePathValue] = useState(
settings?.EmbeddingBasePath
);
const [basePath, setBasePath] = useState(settings?.EmbeddingBasePath);
return (
<div className="w-full flex flex-col gap-y-4">
<div className="w-full flex items-center gap-4">
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
LMStudio Base URL
</label>
<input
type="url"
name="EmbeddingBasePath"
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
placeholder="http://localhost:1234/v1"
defaultValue={settings?.EmbeddingBasePath}
onChange={(e) => setBasePathValue(e.target.value)}
onBlur={() => setBasePath(basePathValue)}
required={true}
autoComplete="off"
spellCheck={false}
/>
</div>
<LMStudioModelSelection settings={settings} basePath={basePath} />
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
Max embedding chunk length
</label>
<input
type="number"
name="EmbeddingModelMaxChunkLength"
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
placeholder="8192"
min={1}
onScroll={(e) => e.target.blur()}
defaultValue={settings?.EmbeddingModelMaxChunkLength}
required={false}
autoComplete="off"
/>
</div>
</div>
</div>
);
}
function LMStudioModelSelection({ settings, basePath = null }) {
const [customModels, setCustomModels] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function findCustomModels() {
if (!basePath || !basePath.includes("/v1")) {
setCustomModels([]);
setLoading(false);
return;
}
setLoading(true);
const { models } = await System.customModels("lmstudio", null, basePath);
setCustomModels(models || []);
setLoading(false);
}
findCustomModels();
}, [basePath]);
if (loading || customModels.length == 0) {
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
Chat Model Selection
</label>
<select
name="EmbeddingModelPref"
disabled={true}
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
>
<option disabled={true} selected={true}>
{basePath?.includes("/v1")
? "-- loading available models --"
: "-- waiting for URL --"}
</option>
</select>
</div>
);
}
return (
<div className="flex flex-col w-60">
<label className="text-white text-sm font-semibold block mb-4">
Chat Model Selection
</label>
<select
name="EmbeddingModelPref"
required={true}
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
>
{customModels.length > 0 && (
<optgroup label="Your loaded models">
{customModels.map((model) => {
return (
<option
key={model.id}
value={model.id}
selected={settings.EmbeddingModelPref === model.id}
>
{model.id}
</option>
);
})}
</optgroup>
)}
</select>
</div>
);
}

View File

@ -29,7 +29,7 @@ export default function GeminiLLMOptions({ settings }) {
required={true}
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
>
{["gemini-pro"].map((model) => {
{["gemini-pro", "gemini-1.5-pro-latest"].map((model) => {
return (
<option key={model} value={model}>
{model}

View File

@ -5,7 +5,7 @@ import { useEffect, useState } from "react";
export const DISABLED_PROVIDERS = ["azure", "lmstudio", "native"];
const PROVIDER_DEFAULT_MODELS = {
openai: [],
gemini: ["gemini-pro"],
gemini: ["gemini-pro", "gemini-1.5-pro-latest"],
anthropic: [
"claude-instant-1.2",
"claude-2.0",

View File

@ -8,6 +8,7 @@ import OpenAiLogo from "@/media/llmprovider/openai.png";
import AzureOpenAiLogo from "@/media/llmprovider/azure.png";
import LocalAiLogo from "@/media/llmprovider/localai.png";
import OllamaLogo from "@/media/llmprovider/ollama.png";
import LMStudioLogo from "@/media/llmprovider/lmstudio.png";
import PreLoader from "@/components/Preloader";
import ChangeWarningModal from "@/components/ChangeWarning";
import OpenAiOptions from "@/components/EmbeddingSelection/OpenAiOptions";
@ -15,16 +16,65 @@ import AzureAiOptions from "@/components/EmbeddingSelection/AzureAiOptions";
import LocalAiOptions from "@/components/EmbeddingSelection/LocalAiOptions";
import NativeEmbeddingOptions from "@/components/EmbeddingSelection/NativeEmbeddingOptions";
import OllamaEmbeddingOptions from "@/components/EmbeddingSelection/OllamaOptions";
import LMStudioEmbeddingOptions from "@/components/EmbeddingSelection/LMStudioOptions";
import EmbedderItem from "@/components/EmbeddingSelection/EmbedderItem";
import { CaretUpDown, MagnifyingGlass, X } from "@phosphor-icons/react";
import { useModal } from "@/hooks/useModal";
import ModalWrapper from "@/components/ModalWrapper";
import CTAButton from "@/components/lib/CTAButton";
const EMBEDDERS = [
{
name: "AnythingLLM Embedder",
value: "native",
logo: AnythingLLMIcon,
options: (settings) => <NativeEmbeddingOptions settings={settings} />,
description:
"Use the built-in embedding engine for AnythingLLM. Zero setup!",
},
{
name: "OpenAI",
value: "openai",
logo: OpenAiLogo,
options: (settings) => <OpenAiOptions settings={settings} />,
description: "The standard option for most non-commercial use.",
},
{
name: "Azure OpenAI",
value: "azure",
logo: AzureOpenAiLogo,
options: (settings) => <AzureAiOptions settings={settings} />,
description: "The enterprise option of OpenAI hosted on Azure services.",
},
{
name: "Local AI",
value: "localai",
logo: LocalAiLogo,
options: (settings) => <LocalAiOptions settings={settings} />,
description: "Run embedding models locally on your own machine.",
},
{
name: "Ollama",
value: "ollama",
logo: OllamaLogo,
options: (settings) => <OllamaEmbeddingOptions settings={settings} />,
description: "Run embedding models locally on your own machine.",
},
{
name: "LM Studio",
value: "lmstudio",
logo: LMStudioLogo,
options: (settings) => <LMStudioEmbeddingOptions settings={settings} />,
description:
"Discover, download, and run thousands of cutting edge LLMs in a few clicks.",
},
];
export default function GeneralEmbeddingPreference() {
const [saving, setSaving] = useState(false);
const [hasChanges, setHasChanges] = useState(false);
const [hasEmbeddings, setHasEmbeddings] = useState(false);
const [hasCachedEmbeddings, setHasCachedEmbeddings] = useState(false);
const [settings, setSettings] = useState(null);
const [loading, setLoading] = useState(true);
const [searchQuery, setSearchQuery] = useState("");
@ -34,12 +84,24 @@ export default function GeneralEmbeddingPreference() {
const searchInputRef = useRef(null);
const { isOpen, openModal, closeModal } = useModal();
function embedderModelChanged(formEl) {
try {
const newModel = new FormData(formEl).get("EmbeddingModelPref") ?? null;
if (newModel === null) return false;
return settings?.EmbeddingModelPref !== newModel;
} catch (error) {
console.error(error);
}
return false;
}
const handleSubmit = async (e) => {
e.preventDefault();
if (
selectedEmbedder !== settings?.EmbeddingEngine &&
(selectedEmbedder !== settings?.EmbeddingEngine ||
embedderModelChanged(e.target)) &&
hasChanges &&
hasEmbeddings
(hasEmbeddings || hasCachedEmbeddings)
) {
openModal();
} else {
@ -89,50 +151,12 @@ export default function GeneralEmbeddingPreference() {
setSettings(_settings);
setSelectedEmbedder(_settings?.EmbeddingEngine || "native");
setHasEmbeddings(_settings?.HasExistingEmbeddings || false);
setHasCachedEmbeddings(_settings?.HasCachedEmbeddings || false);
setLoading(false);
}
fetchKeys();
}, []);
const EMBEDDERS = [
{
name: "AnythingLLM Embedder",
value: "native",
logo: AnythingLLMIcon,
options: <NativeEmbeddingOptions settings={settings} />,
description:
"Use the built-in embedding engine for AnythingLLM. Zero setup!",
},
{
name: "OpenAI",
value: "openai",
logo: OpenAiLogo,
options: <OpenAiOptions settings={settings} />,
description: "The standard option for most non-commercial use.",
},
{
name: "Azure OpenAI",
value: "azure",
logo: AzureOpenAiLogo,
options: <AzureAiOptions settings={settings} />,
description: "The enterprise option of OpenAI hosted on Azure services.",
},
{
name: "Local AI",
value: "localai",
logo: LocalAiLogo,
options: <LocalAiOptions settings={settings} />,
description: "Run embedding models locally on your own machine.",
},
{
name: "Ollama",
value: "ollama",
logo: OllamaLogo,
options: <OllamaEmbeddingOptions settings={settings} />,
description: "Run embedding models locally on your own machine.",
},
];
useEffect(() => {
const filtered = EMBEDDERS.filter((embedder) =>
embedder.name.toLowerCase().includes(searchQuery.toLowerCase())
@ -282,7 +306,7 @@ export default function GeneralEmbeddingPreference() {
{selectedEmbedder &&
EMBEDDERS.find(
(embedder) => embedder.value === selectedEmbedder
)?.options}
)?.options(settings)}
</div>
</div>
</form>
@ -290,7 +314,7 @@ export default function GeneralEmbeddingPreference() {
)}
<ModalWrapper isOpen={isOpen}>
<ChangeWarningModal
warningText="Switching the vector database will ignore previously embedded documents and future similarity search results. They will need to be re-added to each workspace."
warningText="Switching the embedding model will break previously embedded documents from working during chat. They will need to un-embed from every workspace and fully removed and re-uploaded so they can be embed by the new embedding model."
onClose={closeModal}
onConfirm={handleSaveSettings}
/>

View File

@ -237,6 +237,13 @@ export const EMBEDDING_ENGINE_PRIVACY = {
],
logo: OllamaLogo,
},
lmstudio: {
name: "LMStudio",
description: [
"Your document text is embedded privately on the server running LMStudio",
],
logo: LMStudioLogo,
},
};
export default function DataHandling({ setHeader, setForwardBtn, setBackBtn }) {

View File

@ -5,11 +5,13 @@ import OpenAiLogo from "@/media/llmprovider/openai.png";
import AzureOpenAiLogo from "@/media/llmprovider/azure.png";
import LocalAiLogo from "@/media/llmprovider/localai.png";
import OllamaLogo from "@/media/llmprovider/ollama.png";
import LMStudioLogo from "@/media/llmprovider/lmstudio.png";
import NativeEmbeddingOptions from "@/components/EmbeddingSelection/NativeEmbeddingOptions";
import OpenAiOptions from "@/components/EmbeddingSelection/OpenAiOptions";
import AzureAiOptions from "@/components/EmbeddingSelection/AzureAiOptions";
import LocalAiOptions from "@/components/EmbeddingSelection/LocalAiOptions";
import OllamaEmbeddingOptions from "@/components/EmbeddingSelection/OllamaOptions";
import LMStudioEmbeddingOptions from "@/components/EmbeddingSelection/LMStudioOptions";
import EmbedderItem from "@/components/EmbeddingSelection/EmbedderItem";
import System from "@/models/system";
import paths from "@/utils/paths";
@ -19,6 +21,52 @@ import { useNavigate } from "react-router-dom";
const TITLE = "Embedding Preference";
const DESCRIPTION =
"AnythingLLM can work with many embedding models. This will be the model which turns documents into vectors.";
const EMBEDDERS = [
{
name: "AnythingLLM Embedder",
value: "native",
logo: AnythingLLMIcon,
options: (settings) => <NativeEmbeddingOptions settings={settings} />,
description:
"Use the built-in embedding engine for AnythingLLM. Zero setup!",
},
{
name: "OpenAI",
value: "openai",
logo: OpenAiLogo,
options: (settings) => <OpenAiOptions settings={settings} />,
description: "The standard option for most non-commercial use.",
},
{
name: "Azure OpenAI",
value: "azure",
logo: AzureOpenAiLogo,
options: (settings) => <AzureAiOptions settings={settings} />,
description: "The enterprise option of OpenAI hosted on Azure services.",
},
{
name: "Local AI",
value: "localai",
logo: LocalAiLogo,
options: (settings) => <LocalAiOptions settings={settings} />,
description: "Run embedding models locally on your own machine.",
},
{
name: "Ollama",
value: "ollama",
logo: OllamaLogo,
options: (settings) => <OllamaEmbeddingOptions settings={settings} />,
description: "Run embedding models locally on your own machine.",
},
{
name: "LM Studio",
value: "lmstudio",
logo: LMStudioLogo,
options: (settings) => <LMStudioEmbeddingOptions settings={settings} />,
description:
"Discover, download, and run thousands of cutting edge LLMs in a few clicks.",
},
];
export default function EmbeddingPreference({
setHeader,
@ -42,45 +90,6 @@ export default function EmbeddingPreference({
fetchKeys();
}, []);
const EMBEDDERS = [
{
name: "AnythingLLM Embedder",
value: "native",
logo: AnythingLLMIcon,
options: <NativeEmbeddingOptions settings={settings} />,
description:
"Use the built-in embedding engine for AnythingLLM. Zero setup!",
},
{
name: "OpenAI",
value: "openai",
logo: OpenAiLogo,
options: <OpenAiOptions settings={settings} />,
description: "The standard option for most non-commercial use.",
},
{
name: "Azure OpenAI",
value: "azure",
logo: AzureOpenAiLogo,
options: <AzureAiOptions settings={settings} />,
description: "The enterprise option of OpenAI hosted on Azure services.",
},
{
name: "Local AI",
value: "localai",
logo: LocalAiLogo,
options: <LocalAiOptions settings={settings} />,
description: "Run embedding models locally on your own machine.",
},
{
name: "Ollama",
value: "ollama",
logo: OllamaLogo,
options: <OllamaEmbeddingOptions settings={settings} />,
description: "Run embedding models locally on your own machine.",
},
];
function handleForward() {
if (hiddenSubmitButtonRef.current) {
hiddenSubmitButtonRef.current.click();
@ -161,8 +170,9 @@ export default function EmbeddingPreference({
</div>
<div className="mt-4 flex flex-col gap-y-1">
{selectedEmbedder &&
EMBEDDERS.find((embedder) => embedder.value === selectedEmbedder)
?.options}
EMBEDDERS.find(
(embedder) => embedder.value === selectedEmbedder
)?.options(settings)}
</div>
<button
type="submit"

View File

@ -19,12 +19,12 @@ resolves #xxx
### What is in this change?
Describe the changes in this PR that are impactful to the repo.
<!-- Describe the changes in this PR that are impactful to the repo. -->
### Additional Information
Add any other context about the Pull Request here that was not captured above.
<!-- Add any other context about the Pull Request here that was not captured above. -->
### Developer Validations

View File

@ -86,6 +86,11 @@ JWT_SECRET="my-random-string-for-seeding" # Please generate random string at lea
# EMBEDDING_MODEL_PREF='nomic-embed-text:latest'
# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=8192
# EMBEDDING_ENGINE='lmstudio'
# EMBEDDING_BASE_PATH='https://localhost:1234/v1'
# EMBEDDING_MODEL_PREF='nomic-ai/nomic-embed-text-v1.5-GGUF/nomic-embed-text-v1.5.Q4_0.gguf'
# EMBEDDING_MODEL_MAX_CHUNK_LENGTH=8192
###########################################
######## Vector Database Selection ########
###########################################

View File

@ -91,6 +91,7 @@ const SystemSettings = {
},
},
currentSettings: async function () {
const { hasVectorCachedFiles } = require("../utils/files");
const llmProvider = process.env.LLM_PROVIDER;
const vectorDB = process.env.VECTOR_DB;
return {
@ -108,7 +109,8 @@ const SystemSettings = {
// Embedder Provider Selection Settings & Configs
// --------------------------------------------------------
EmbeddingEngine: process.env.EMBEDDING_ENGINE,
HasExistingEmbeddings: await this.hasEmbeddings(),
HasExistingEmbeddings: await this.hasEmbeddings(), // check if they have any currently embedded documents active in workspaces.
HasCachedEmbeddings: hasVectorCachedFiles(), // check if they any currently cached embedded docs.
EmbeddingBasePath: process.env.EMBEDDING_BASE_PATH,
EmbeddingModelPref: process.env.EMBEDDING_MODEL_PREF,
EmbeddingModelMaxChunkLength:

View File

@ -23,7 +23,7 @@
"@anthropic-ai/sdk": "^0.16.1",
"@azure/openai": "1.0.0-beta.10",
"@datastax/astra-db-ts": "^0.1.3",
"@google/generative-ai": "^0.1.3",
"@google/generative-ai": "^0.7.1",
"@googleapis/youtube": "^9.0.0",
"@pinecone-database/pinecone": "^2.0.1",
"@prisma/client": "5.3.1",

View File

@ -14,7 +14,13 @@ class GeminiLLM {
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
this.model =
modelPreference || process.env.GEMINI_LLM_MODEL_PREF || "gemini-pro";
this.gemini = genAI.getGenerativeModel({ model: this.model });
this.gemini = genAI.getGenerativeModel(
{ model: this.model },
{
// Gemini-1.5-pro is only available on the v1beta API.
apiVersion: this.model === "gemini-1.5-pro-latest" ? "v1beta" : "v1",
}
);
this.limits = {
history: this.promptWindowLimit() * 0.15,
system: this.promptWindowLimit() * 0.15,
@ -49,13 +55,15 @@ class GeminiLLM {
switch (this.model) {
case "gemini-pro":
return 30_720;
case "gemini-1.5-pro-latest":
return 1_048_576;
default:
return 30_720; // assume a gemini-pro model
}
}
isValidChatCompletionModel(modelName = "") {
const validModels = ["gemini-pro"];
const validModels = ["gemini-pro", "gemini-1.5-pro-latest"];
return validModels.includes(modelName);
}
@ -90,11 +98,11 @@ class GeminiLLM {
const allMessages = messages
.map((message) => {
if (message.role === "system")
return { role: "user", parts: message.content };
return { role: "user", parts: [{ text: message.content }] };
if (message.role === "user")
return { role: "user", parts: message.content };
return { role: "user", parts: [{ text: message.content }] };
if (message.role === "assistant")
return { role: "model", parts: message.content };
return { role: "model", parts: [{ text: message.content }] };
return null;
})
.filter((msg) => !!msg);

View File

@ -39,7 +39,7 @@ const MODELS = {
id: "databricks/dbrx-instruct",
organization: "databricks",
name: "DBRX Instruct",
maxLength: 32000,
maxLength: 32768,
},
"deepseek-ai/deepseek-coder-33b-instruct": {
id: "deepseek-ai/deepseek-coder-33b-instruct",
@ -131,6 +131,24 @@ const MODELS = {
name: "LLaMA-2 Chat (7B)",
maxLength: 4096,
},
"meta-llama/Llama-3-8b-chat-hf": {
id: "meta-llama/Llama-3-8b-chat-hf",
organization: "Meta",
name: "LLaMA-3 Chat (8B)",
maxLength: 8000,
},
"meta-llama/Llama-3-70b-chat-hf": {
id: "meta-llama/Llama-3-70b-chat-hf",
organization: "Meta",
name: "LLaMA-3 Chat (70B)",
maxLength: 8000,
},
"microsoft/WizardLM-2-8x22B": {
id: "microsoft/WizardLM-2-8x22B",
organization: "Microsoft",
name: "WizardLM-2 (8x22B)",
maxLength: 65536,
},
"mistralai/Mistral-7B-Instruct-v0.1": {
id: "mistralai/Mistral-7B-Instruct-v0.1",
organization: "mistralai",
@ -149,6 +167,12 @@ const MODELS = {
name: "Mixtral-8x7B Instruct (46.7B)",
maxLength: 32768,
},
"mistralai/Mixtral-8x22B-Instruct-v0.1": {
id: "mistralai/Mixtral-8x22B-Instruct-v0.1",
organization: "mistralai",
name: "Mixtral-8x22B Instruct (141B)",
maxLength: 65536,
},
"NousResearch/Nous-Capybara-7B-V1p9": {
id: "NousResearch/Nous-Capybara-7B-V1p9",
organization: "NousResearch",

View File

@ -6,7 +6,7 @@
| Allen AI | OLMo (7B) | allenai/OLMo-7B | 2048 |
| Austism | Chronos Hermes (13B) | Austism/chronos-hermes-13b | 2048 |
| cognitivecomputations | Dolphin 2.5 Mixtral 8x7b | cognitivecomputations/dolphin-2.5-mixtral-8x7b | 32768 |
| databricks | DBRX Instruct | databricks/dbrx-instruct | 32000 |
| databricks | DBRX Instruct | databricks/dbrx-instruct | 32768 |
| DeepSeek | Deepseek Coder Instruct (33B) | deepseek-ai/deepseek-coder-33b-instruct | 16384 |
| DeepSeek | DeepSeek LLM Chat (67B) | deepseek-ai/deepseek-llm-67b-chat | 4096 |
| garage-bAInd | Platypus2 Instruct (70B) | garage-bAInd/Platypus2-70B-instruct | 4096 |
@ -22,9 +22,13 @@
| Meta | LLaMA-2 Chat (70B) | meta-llama/Llama-2-70b-chat-hf | 4096 |
| Meta | LLaMA-2 Chat (13B) | meta-llama/Llama-2-13b-chat-hf | 4096 |
| Meta | LLaMA-2 Chat (7B) | meta-llama/Llama-2-7b-chat-hf | 4096 |
| Meta | LLaMA-3 Chat (8B) | meta-llama/Llama-3-8b-chat-hf | 8000 |
| Meta | LLaMA-3 Chat (70B) | meta-llama/Llama-3-70b-chat-hf | 8000 |
| Microsoft | WizardLM-2 (8x22B) | microsoft/WizardLM-2-8x22B | 65536 |
| mistralai | Mistral (7B) Instruct | mistralai/Mistral-7B-Instruct-v0.1 | 8192 |
| mistralai | Mistral (7B) Instruct v0.2 | mistralai/Mistral-7B-Instruct-v0.2 | 32768 |
| mistralai | Mixtral-8x7B Instruct (46.7B) | mistralai/Mixtral-8x7B-Instruct-v0.1 | 32768 |
| mistralai | Mixtral-8x22B Instruct (141B) | mistralai/Mixtral-8x22B-Instruct-v0.1 | 65536 |
| NousResearch | Nous Capybara v1.9 (7B) | NousResearch/Nous-Capybara-7B-V1p9 | 8192 |
| NousResearch | Nous Hermes 2 - Mistral DPO (7B) | NousResearch/Nous-Hermes-2-Mistral-7B-DPO | 32768 |
| NousResearch | Nous Hermes 2 - Mixtral 8x7B-DPO (46.7B) | NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO | 32768 |

View File

@ -8,7 +8,7 @@
// copy outputs into the export in ../models.js
// Update the date below if you run this again because TogetherAI added new models.
// Last Collected: Apr 14, 2024
// Last Collected: Apr 18, 2024
// Since last collection Together's docs are broken. I just copied the HTML table
// and had claude3 convert to markdown and it works well enough.

View File

@ -0,0 +1,110 @@
const { maximumChunkLength } = require("../../helpers");
class LMStudioEmbedder {
constructor() {
if (!process.env.EMBEDDING_BASE_PATH)
throw new Error("No embedding base path was set.");
if (!process.env.EMBEDDING_MODEL_PREF)
throw new Error("No embedding model was set.");
this.basePath = `${process.env.EMBEDDING_BASE_PATH}/embeddings`;
this.model = process.env.EMBEDDING_MODEL_PREF;
// Limit of how many strings we can process in a single pass to stay with resource or network limits
// Limit of how many strings we can process in a single pass to stay with resource or network limits
this.maxConcurrentChunks = 1;
this.embeddingMaxChunkLength = maximumChunkLength();
}
log(text, ...args) {
console.log(`\x1b[36m[${this.constructor.name}]\x1b[0m ${text}`, ...args);
}
async #isAlive() {
return await fetch(`${this.basePath}/models`, {
method: "HEAD",
})
.then((res) => res.ok)
.catch((e) => {
this.log(e.message);
return false;
});
}
async embedTextInput(textInput) {
const result = await this.embedChunks(textInput);
return result?.[0] || [];
}
async embedChunks(textChunks = []) {
if (!(await this.#isAlive()))
throw new Error(
`LMStudio service could not be reached. Is LMStudio running?`
);
this.log(
`Embedding ${textChunks.length} chunks of text with ${this.model}.`
);
// LMStudio will drop all queued requests now? So if there are many going on
// we need to do them sequentially or else only the first resolves and the others
// get dropped or go unanswered >:(
let results = [];
let hasError = false;
for (const chunk of textChunks) {
if (hasError) break; // If an error occurred don't continue and exit early.
results.push(
await fetch(this.basePath, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
model: this.model,
input: chunk,
}),
})
.then((res) => res.json())
.then((json) => {
const embedding = json.data[0].embedding;
if (!Array.isArray(embedding) || !embedding.length)
throw {
type: "EMPTY_ARR",
message: "The embedding was empty from LMStudio",
};
return { data: embedding, error: null };
})
.catch((error) => {
hasError = true;
return { data: [], error };
})
);
}
// Accumulate errors from embedding.
// If any are present throw an abort error.
const errors = results
.filter((res) => !!res.error)
.map((res) => res.error)
.flat();
if (errors.length > 0) {
let uniqueErrors = new Set();
console.log(errors);
errors.map((error) =>
uniqueErrors.add(`[${error.type}]: ${error.message}`)
);
if (errors.length > 0)
throw new Error(
`LMStudio Failed to embed: ${Array.from(uniqueErrors).join(", ")}`
);
}
const data = results.map((res) => res?.data || []);
return data.length > 0 ? data : null;
}
}
module.exports = {
LMStudioEmbedder,
};

View File

@ -192,6 +192,19 @@ function normalizePath(filepath = "") {
return result;
}
// Check if the vector-cache folder is empty or not
// useful for it the user is changing embedders as this will
// break the previous cache.
function hasVectorCachedFiles() {
try {
return (
fs.readdirSync(vectorCachePath)?.filter((name) => name.endsWith(".json"))
.length !== 0
);
} catch {}
return false;
}
module.exports = {
findDocumentInDocuments,
cachedVectorInformation,
@ -203,4 +216,5 @@ module.exports = {
normalizePath,
isWithin,
documentsPath,
hasVectorCachedFiles,
};

View File

@ -102,6 +102,9 @@ function getEmbeddingEngineSelection() {
case "native":
const { NativeEmbedder } = require("../EmbeddingEngines/native");
return new NativeEmbedder();
case "lmstudio":
const { LMStudioEmbedder } = require("../EmbeddingEngines/lmstudio");
return new LMStudioEmbedder();
default:
return null;
}

View File

@ -387,7 +387,7 @@ function supportedTranscriptionProvider(input = "") {
}
function validGeminiModel(input = "") {
const validModels = ["gemini-pro"];
const validModels = ["gemini-pro", "gemini-1.5-pro-latest"];
return validModels.includes(input)
? null
: `Invalid Model type. Must be one of ${validModels.join(", ")}.`;
@ -408,7 +408,14 @@ function validAnthropicModel(input = "") {
}
function supportedEmbeddingModel(input = "") {
const supported = ["openai", "azure", "localai", "native", "ollama"];
const supported = [
"openai",
"azure",
"localai",
"native",
"ollama",
"lmstudio",
];
return supported.includes(input)
? null
: `Invalid Embedding model type. Must be one of ${supported.join(", ")}.`;

View File

@ -220,10 +220,10 @@
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==
"@google/generative-ai@^0.1.3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@google/generative-ai/-/generative-ai-0.1.3.tgz#8e529d4d86c85b64d297b4abf1a653d613a09a9f"
integrity sha512-Cm4uJX1sKarpm1mje/MiOIinM7zdUUrQp/5/qGPAgznbdd/B9zup5ehT6c1qGqycFcSopTA1J1HpqHS5kJR8hQ==
"@google/generative-ai@^0.7.1":
version "0.7.1"
resolved "https://registry.yarnpkg.com/@google/generative-ai/-/generative-ai-0.7.1.tgz#eb187c75080c0706245699dbc06816c830d8c6a7"
integrity sha512-WTjMLLYL/xfA5BW6xAycRPiAX7FNHKAxrid/ayqC1QMam0KAK0NbMeS9Lubw80gVg5xFMLE+H7pw4wdNzTOlxw==
"@googleapis/youtube@^9.0.0":
version "9.0.0"