mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-11-19 20:50:09 +01:00
merge with master
This commit is contained in:
commit
d25933930b
@ -188,7 +188,7 @@ You can verify these claims by finding all locations `Telemetry.sendTelemetry` i
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Copyright © 2023 [Mintplex Labs][profile-link]. <br />
|
Copyright © 2024 [Mintplex Labs][profile-link]. <br />
|
||||||
This project is [MIT](./LICENSE) licensed.
|
This project is [MIT](./LICENSE) licensed.
|
||||||
|
|
||||||
<!-- LINK GROUP -->
|
<!-- LINK GROUP -->
|
||||||
|
@ -66,6 +66,12 @@ GID='1000'
|
|||||||
# GROQ_API_KEY=gsk_abcxyz
|
# GROQ_API_KEY=gsk_abcxyz
|
||||||
# GROQ_MODEL_PREF=llama2-70b-4096
|
# GROQ_MODEL_PREF=llama2-70b-4096
|
||||||
|
|
||||||
|
# LLM_PROVIDER='generic-openai'
|
||||||
|
# GENERIC_OPEN_AI_BASE_PATH='http://proxy.url.openai.com/v1'
|
||||||
|
# GENERIC_OPEN_AI_MODEL_PREF='gpt-3.5-turbo'
|
||||||
|
# GENERIC_OPEN_AI_MODEL_TOKEN_LIMIT=4096
|
||||||
|
# GENERIC_OPEN_AI_API_KEY=sk-123abc
|
||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
######## Embedding API SElECTION ##########
|
######## Embedding API SElECTION ##########
|
||||||
###########################################
|
###########################################
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
export default function GenericOpenAiOptions({ settings }) {
|
||||||
|
return (
|
||||||
|
<div className="flex gap-4 flex-wrap">
|
||||||
|
<div className="flex flex-col w-60">
|
||||||
|
<label className="text-white text-sm font-semibold block mb-4">
|
||||||
|
Base URL
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="url"
|
||||||
|
name="GenericOpenAiBasePath"
|
||||||
|
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
|
||||||
|
placeholder="eg: https://proxy.openai.com"
|
||||||
|
defaultValue={settings?.GenericOpenAiBasePath}
|
||||||
|
required={true}
|
||||||
|
autoComplete="off"
|
||||||
|
spellCheck={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col w-60">
|
||||||
|
<label className="text-white text-sm font-semibold block mb-4">
|
||||||
|
API Key
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
name="GenericOpenAiKey"
|
||||||
|
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
|
||||||
|
placeholder="Generic service API Key"
|
||||||
|
defaultValue={settings?.GenericOpenAiKey ? "*".repeat(20) : ""}
|
||||||
|
required={false}
|
||||||
|
autoComplete="off"
|
||||||
|
spellCheck={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col w-60">
|
||||||
|
<label className="text-white text-sm font-semibold block mb-4">
|
||||||
|
Chat Model Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="GenericOpenAiModelPref"
|
||||||
|
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
|
||||||
|
placeholder="Model id used for chat requests"
|
||||||
|
defaultValue={settings?.GenericOpenAiModelPref}
|
||||||
|
required={true}
|
||||||
|
autoComplete="off"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col w-60">
|
||||||
|
<label className="text-white text-sm font-semibold block mb-4">
|
||||||
|
Token context window
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
name="GenericOpenAiTokenLimit"
|
||||||
|
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
|
||||||
|
placeholder="Content window limit (eg: 4096)"
|
||||||
|
min={1}
|
||||||
|
onScroll={(e) => e.target.blur()}
|
||||||
|
defaultValue={settings?.GenericOpenAiTokenLimit}
|
||||||
|
required={true}
|
||||||
|
autoComplete="off"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -28,7 +28,13 @@ export default function GroqAiOptions({ settings }) {
|
|||||||
required={true}
|
required={true}
|
||||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||||
>
|
>
|
||||||
{["llama2-70b-4096", "mixtral-8x7b-32768"].map((model) => {
|
{[
|
||||||
|
"llama2-70b-4096",
|
||||||
|
"mixtral-8x7b-32768",
|
||||||
|
"llama3-8b-8192",
|
||||||
|
"llama3-70b-8192",
|
||||||
|
"gemma-7b-it",
|
||||||
|
].map((model) => {
|
||||||
return (
|
return (
|
||||||
<option key={model} value={model}>
|
<option key={model} value={model}>
|
||||||
{model}
|
{model}
|
||||||
|
@ -44,7 +44,7 @@ const HistoricalMessage = ({
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<span
|
<span
|
||||||
className={`flex flex-col gap-y-1 mt-2`}
|
className={`flex flex-col gap-y-1`}
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: DOMPurify.sanitize(renderMarkdown(message)),
|
__html: DOMPurify.sanitize(renderMarkdown(message)),
|
||||||
}}
|
}}
|
||||||
|
@ -21,7 +21,7 @@ const PromptReply = ({
|
|||||||
<div
|
<div
|
||||||
className={`flex justify-center items-end w-full ${assistantBackgroundColor}`}
|
className={`flex justify-center items-end w-full ${assistantBackgroundColor}`}
|
||||||
>
|
>
|
||||||
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col">
|
<div className="py-6 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col">
|
||||||
<div className="flex gap-x-5">
|
<div className="flex gap-x-5">
|
||||||
<WorkspaceProfileImage workspace={workspace} />
|
<WorkspaceProfileImage workspace={workspace} />
|
||||||
<div className="mt-3 ml-5 dot-falling"></div>
|
<div className="mt-3 ml-5 dot-falling"></div>
|
||||||
@ -36,7 +36,7 @@ const PromptReply = ({
|
|||||||
<div
|
<div
|
||||||
className={`flex justify-center items-end w-full ${assistantBackgroundColor}`}
|
className={`flex justify-center items-end w-full ${assistantBackgroundColor}`}
|
||||||
>
|
>
|
||||||
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col">
|
<div className="py-6 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col">
|
||||||
<div className="flex gap-x-5">
|
<div className="flex gap-x-5">
|
||||||
<WorkspaceProfileImage workspace={workspace} />
|
<WorkspaceProfileImage workspace={workspace} />
|
||||||
<span
|
<span
|
||||||
@ -57,7 +57,7 @@ const PromptReply = ({
|
|||||||
key={uuid}
|
key={uuid}
|
||||||
className={`flex justify-center items-end w-full ${assistantBackgroundColor}`}
|
className={`flex justify-center items-end w-full ${assistantBackgroundColor}`}
|
||||||
>
|
>
|
||||||
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col">
|
<div className="py-6 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col">
|
||||||
<div className="flex gap-x-5">
|
<div className="flex gap-x-5">
|
||||||
<WorkspaceProfileImage workspace={workspace} />
|
<WorkspaceProfileImage workspace={workspace} />
|
||||||
<span
|
<span
|
||||||
|
@ -12,9 +12,39 @@ export default function ChatHistory({ history = [], workspace, sendCommand }) {
|
|||||||
const { showing, showModal, hideModal } = useManageWorkspaceModal();
|
const { showing, showModal, hideModal } = useManageWorkspaceModal();
|
||||||
const [isAtBottom, setIsAtBottom] = useState(true);
|
const [isAtBottom, setIsAtBottom] = useState(true);
|
||||||
const chatHistoryRef = useRef(null);
|
const chatHistoryRef = useRef(null);
|
||||||
|
const [textSize, setTextSize] = useState("normal");
|
||||||
|
|
||||||
|
const getTextSizeClass = (size) => {
|
||||||
|
switch (size) {
|
||||||
|
case "small":
|
||||||
|
return "text-[12px]";
|
||||||
|
case "large":
|
||||||
|
return "text-[18px]";
|
||||||
|
default:
|
||||||
|
return "text-[14px]";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
scrollToBottom();
|
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);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isAtBottom) scrollToBottom();
|
||||||
}, [history]);
|
}, [history]);
|
||||||
|
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
@ -91,7 +121,7 @@ export default function ChatHistory({ history = [], workspace, sendCommand }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="markdown text-white/80 font-light text-sm 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 no-scroll"
|
className={`markdown text-white/80 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 no-scroll`}
|
||||||
id="chat-history"
|
id="chat-history"
|
||||||
ref={chatHistoryRef}
|
ref={chatHistoryRef}
|
||||||
>
|
>
|
||||||
|
@ -0,0 +1,124 @@
|
|||||||
|
import { useState, useRef, useEffect } from "react";
|
||||||
|
import { TextT } from "@phosphor-icons/react";
|
||||||
|
import { Tooltip } from "react-tooltip";
|
||||||
|
|
||||||
|
export default function TextSizeButton() {
|
||||||
|
const [showTextSizeMenu, setShowTextSizeMenu] = useState(false);
|
||||||
|
const buttonRef = useRef(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
ref={buttonRef}
|
||||||
|
id="text-size-btn"
|
||||||
|
data-tooltip-id="tooltip-text-size-btn"
|
||||||
|
data-tooltip-content="Change text size"
|
||||||
|
aria-label="Change text size"
|
||||||
|
onClick={() => setShowTextSizeMenu(!showTextSizeMenu)}
|
||||||
|
className={`relative flex justify-center items-center opacity-60 hover:opacity-100 cursor-pointer ${
|
||||||
|
showTextSizeMenu ? "!opacity-100" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<TextT
|
||||||
|
weight="fill"
|
||||||
|
className="w-6 h-6 pointer-events-none text-white"
|
||||||
|
/>
|
||||||
|
<Tooltip
|
||||||
|
id="tooltip-text-size-btn"
|
||||||
|
place="top"
|
||||||
|
delayShow={300}
|
||||||
|
className="tooltip !text-xs z-99"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<TextSizeMenu
|
||||||
|
showing={showTextSizeMenu}
|
||||||
|
setShowing={setShowTextSizeMenu}
|
||||||
|
buttonRef={buttonRef}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TextSizeMenu({ showing, setShowing, buttonRef }) {
|
||||||
|
const formRef = useRef(null);
|
||||||
|
const [selectedSize, setSelectedSize] = useState(
|
||||||
|
window.localStorage.getItem("anythingllm_text_size") || "normal"
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function listenForOutsideClick() {
|
||||||
|
if (!showing || !formRef.current) return false;
|
||||||
|
document.addEventListener("click", closeIfOutside);
|
||||||
|
}
|
||||||
|
listenForOutsideClick();
|
||||||
|
}, [showing, formRef.current]);
|
||||||
|
|
||||||
|
const closeIfOutside = ({ target }) => {
|
||||||
|
if (target.id === "text-size-btn") return;
|
||||||
|
const isOutside = !formRef?.current?.contains(target);
|
||||||
|
if (!isOutside) return;
|
||||||
|
setShowing(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTextSizeChange = (size) => {
|
||||||
|
setSelectedSize(size);
|
||||||
|
window.localStorage.setItem("anythingllm_text_size", size);
|
||||||
|
window.dispatchEvent(new CustomEvent("textSizeChange", { detail: size }));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!buttonRef.current) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div hidden={!showing}>
|
||||||
|
<div
|
||||||
|
ref={formRef}
|
||||||
|
className="absolute bottom-16 -ml-8 w-[140px] p-2 bg-zinc-800 rounded-lg shadow-md flex flex-col justify-center items-start gap-2 z-50"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setShowing(false);
|
||||||
|
handleTextSizeChange("small");
|
||||||
|
}}
|
||||||
|
className={`w-full hover:cursor-pointer px-2 py-1 rounded-md flex flex-col justify-start group ${
|
||||||
|
selectedSize === "small" ? "bg-zinc-700" : "hover:bg-zinc-700"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="w-full flex-col text-left flex pointer-events-none">
|
||||||
|
<div className="text-white text-xs">Small</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setShowing(false);
|
||||||
|
handleTextSizeChange("normal");
|
||||||
|
}}
|
||||||
|
className={`w-full hover:cursor-pointer px-2 py-1 rounded-md flex flex-col justify-start group ${
|
||||||
|
selectedSize === "normal" ? "bg-zinc-700" : "hover:bg-zinc-700"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="w-full flex-col text-left flex pointer-events-none">
|
||||||
|
<div className="text-white text-sm">Normal</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setShowing(false);
|
||||||
|
handleTextSizeChange("large");
|
||||||
|
}}
|
||||||
|
className={`w-full hover:cursor-pointer px-2 py-1 rounded-md flex flex-col justify-start group ${
|
||||||
|
selectedSize === "large" ? "bg-zinc-700" : "hover:bg-zinc-700"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="w-full flex-col text-left flex pointer-events-none">
|
||||||
|
<div className="text-white text-[16px]">Large</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -11,6 +11,7 @@ import AvailableAgentsButton, {
|
|||||||
AvailableAgents,
|
AvailableAgents,
|
||||||
useAvailableAgents,
|
useAvailableAgents,
|
||||||
} from "./AgentMenu";
|
} from "./AgentMenu";
|
||||||
|
import TextSizeButton from "./TextSizeMenu";
|
||||||
export default function PromptInput({
|
export default function PromptInput({
|
||||||
message,
|
message,
|
||||||
submit,
|
submit,
|
||||||
@ -137,6 +138,7 @@ export default function PromptInput({
|
|||||||
showing={showAgents}
|
showing={showAgents}
|
||||||
setShowAgents={setShowAgents}
|
setShowAgents={setShowAgents}
|
||||||
/>
|
/>
|
||||||
|
<TextSizeButton />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,7 +19,13 @@ const PROVIDER_DEFAULT_MODELS = {
|
|||||||
localai: [],
|
localai: [],
|
||||||
ollama: [],
|
ollama: [],
|
||||||
togetherai: [],
|
togetherai: [],
|
||||||
groq: ["llama2-70b-4096", "mixtral-8x7b-32768"],
|
groq: [
|
||||||
|
"llama2-70b-4096",
|
||||||
|
"mixtral-8x7b-32768",
|
||||||
|
"llama3-8b-8192",
|
||||||
|
"llama3-70b-8192",
|
||||||
|
"gemma-7b-it",
|
||||||
|
],
|
||||||
native: [],
|
native: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -34,7 +40,7 @@ function groupModels(models) {
|
|||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupedProviders = ["togetherai", "openai"];
|
const groupedProviders = ["togetherai", "openai", "openrouter"];
|
||||||
export default function useGetProviderModels(provider = null) {
|
export default function useGetProviderModels(provider = null) {
|
||||||
const [defaultModels, setDefaultModels] = useState([]);
|
const [defaultModels, setDefaultModels] = useState([]);
|
||||||
const [customModels, setCustomModels] = useState([]);
|
const [customModels, setCustomModels] = useState([]);
|
||||||
|
BIN
frontend/src/media/llmprovider/generic-openai.png
Normal file
BIN
frontend/src/media/llmprovider/generic-openai.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
@ -30,7 +30,7 @@ const EMBEDDERS = [
|
|||||||
logo: AnythingLLMIcon,
|
logo: AnythingLLMIcon,
|
||||||
options: (settings) => <NativeEmbeddingOptions settings={settings} />,
|
options: (settings) => <NativeEmbeddingOptions settings={settings} />,
|
||||||
description:
|
description:
|
||||||
"Use the built-in embedding engine for AnythingLLM. Zero setup!",
|
"Use the built-in embedding provider for AnythingLLM. Zero setup!",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OpenAI",
|
name: "OpenAI",
|
||||||
|
@ -4,6 +4,7 @@ import { isMobile } from "react-device-detect";
|
|||||||
import System from "@/models/system";
|
import System from "@/models/system";
|
||||||
import showToast from "@/utils/toast";
|
import showToast from "@/utils/toast";
|
||||||
import OpenAiLogo from "@/media/llmprovider/openai.png";
|
import OpenAiLogo from "@/media/llmprovider/openai.png";
|
||||||
|
import GenericOpenAiLogo from "@/media/llmprovider/generic-openai.png";
|
||||||
import AzureOpenAiLogo from "@/media/llmprovider/azure.png";
|
import AzureOpenAiLogo from "@/media/llmprovider/azure.png";
|
||||||
import AnthropicLogo from "@/media/llmprovider/anthropic.png";
|
import AnthropicLogo from "@/media/llmprovider/anthropic.png";
|
||||||
import GeminiLogo from "@/media/llmprovider/gemini.png";
|
import GeminiLogo from "@/media/llmprovider/gemini.png";
|
||||||
@ -18,6 +19,7 @@ import OpenRouterLogo from "@/media/llmprovider/openrouter.jpeg";
|
|||||||
import GroqLogo from "@/media/llmprovider/groq.png";
|
import GroqLogo from "@/media/llmprovider/groq.png";
|
||||||
import PreLoader from "@/components/Preloader";
|
import PreLoader from "@/components/Preloader";
|
||||||
import OpenAiOptions from "@/components/LLMSelection/OpenAiOptions";
|
import OpenAiOptions from "@/components/LLMSelection/OpenAiOptions";
|
||||||
|
import GenericOpenAiOptions from "@/components/LLMSelection/GenericOpenAiOptions";
|
||||||
import AzureAiOptions from "@/components/LLMSelection/AzureAiOptions";
|
import AzureAiOptions from "@/components/LLMSelection/AzureAiOptions";
|
||||||
import AnthropicAiOptions from "@/components/LLMSelection/AnthropicAiOptions";
|
import AnthropicAiOptions from "@/components/LLMSelection/AnthropicAiOptions";
|
||||||
import LMStudioOptions from "@/components/LLMSelection/LMStudioOptions";
|
import LMStudioOptions from "@/components/LLMSelection/LMStudioOptions";
|
||||||
@ -148,6 +150,20 @@ export const AVAILABLE_LLM_PROVIDERS = [
|
|||||||
"The fastest LLM inferencing available for real-time AI applications.",
|
"The fastest LLM inferencing available for real-time AI applications.",
|
||||||
requiredConfig: ["GroqApiKey"],
|
requiredConfig: ["GroqApiKey"],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Generic OpenAI",
|
||||||
|
value: "generic-openai",
|
||||||
|
logo: GenericOpenAiLogo,
|
||||||
|
options: (settings) => <GenericOpenAiOptions settings={settings} />,
|
||||||
|
description:
|
||||||
|
"Connect to any OpenAi-compatible service via a custom configuration",
|
||||||
|
requiredConfig: [
|
||||||
|
"GenericOpenAiBasePath",
|
||||||
|
"GenericOpenAiModelPref",
|
||||||
|
"GenericOpenAiTokenLimit",
|
||||||
|
"GenericOpenAiKey",
|
||||||
|
],
|
||||||
|
},
|
||||||
// {
|
// {
|
||||||
// name: "Native",
|
// name: "Native",
|
||||||
// value: "native",
|
// value: "native",
|
||||||
|
@ -88,7 +88,9 @@ function ThirdParty({ settings }) {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-y-2 border-b border-zinc-500/50 pb-4">
|
<div className="flex flex-col gap-y-2 border-b border-zinc-500/50 pb-4">
|
||||||
<div className="text-white text-base font-bold">Embedding Engine</div>
|
<div className="text-white text-base font-bold">
|
||||||
|
Embedding Preference
|
||||||
|
</div>
|
||||||
<div className="flex items-center gap-2.5">
|
<div className="flex items-center gap-2.5">
|
||||||
<img
|
<img
|
||||||
src={EMBEDDING_ENGINE_PRIVACY[embeddingEngine].logo}
|
src={EMBEDDING_ENGINE_PRIVACY[embeddingEngine].logo}
|
||||||
|
@ -18,7 +18,7 @@ export default function CustomLogo({ setHeader, setForwardBtn, setBackBtn }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleBack() {
|
function handleBack() {
|
||||||
navigate(paths.onboarding.vectorDatabase());
|
navigate(paths.onboarding.llmPreference());
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -2,6 +2,7 @@ import PreLoader from "@/components/Preloader";
|
|||||||
import System from "@/models/system";
|
import System from "@/models/system";
|
||||||
import AnythingLLMIcon from "@/media/logo/anything-llm-icon.png";
|
import AnythingLLMIcon from "@/media/logo/anything-llm-icon.png";
|
||||||
import OpenAiLogo from "@/media/llmprovider/openai.png";
|
import OpenAiLogo from "@/media/llmprovider/openai.png";
|
||||||
|
import GenericOpenAiLogo from "@/media/llmprovider/generic-openai.png";
|
||||||
import AzureOpenAiLogo from "@/media/llmprovider/azure.png";
|
import AzureOpenAiLogo from "@/media/llmprovider/azure.png";
|
||||||
import AnthropicLogo from "@/media/llmprovider/anthropic.png";
|
import AnthropicLogo from "@/media/llmprovider/anthropic.png";
|
||||||
import GeminiLogo from "@/media/llmprovider/gemini.png";
|
import GeminiLogo from "@/media/llmprovider/gemini.png";
|
||||||
@ -136,6 +137,13 @@ export const LLM_SELECTION_PRIVACY = {
|
|||||||
],
|
],
|
||||||
logo: GroqLogo,
|
logo: GroqLogo,
|
||||||
},
|
},
|
||||||
|
"generic-openai": {
|
||||||
|
name: "Generic OpenAI compatible service",
|
||||||
|
description: [
|
||||||
|
"Data is shared according to the terms of service applicable with your generic endpoint provider.",
|
||||||
|
],
|
||||||
|
logo: GenericOpenAiLogo,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const VECTOR_DB_PRIVACY = {
|
export const VECTOR_DB_PRIVACY = {
|
||||||
@ -305,7 +313,9 @@ export default function DataHandling({ setHeader, setForwardBtn, setBackBtn }) {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-y-2 border-b border-zinc-500/50 pb-4">
|
<div className="flex flex-col gap-y-2 border-b border-zinc-500/50 pb-4">
|
||||||
<div className="text-white text-base font-bold">Embedding Engine</div>
|
<div className="text-white text-base font-bold">
|
||||||
|
Embedding Preference
|
||||||
|
</div>
|
||||||
<div className="flex items-center gap-2.5">
|
<div className="flex items-center gap-2.5">
|
||||||
<img
|
<img
|
||||||
src={EMBEDDING_ENGINE_PRIVACY[embeddingEngine].logo}
|
src={EMBEDDING_ENGINE_PRIVACY[embeddingEngine].logo}
|
||||||
@ -344,6 +354,9 @@ export default function DataHandling({ setHeader, setForwardBtn, setBackBtn }) {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<p className="text-white/60 text-sm font-medium py-1">
|
||||||
|
These settings can be reconfigured at any time in the settings.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,186 +0,0 @@
|
|||||||
import { MagnifyingGlass } from "@phosphor-icons/react";
|
|
||||||
import { useEffect, useState, useRef } from "react";
|
|
||||||
import AnythingLLMIcon from "@/media/logo/anything-llm-icon.png";
|
|
||||||
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";
|
|
||||||
import showToast from "@/utils/toast";
|
|
||||||
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,
|
|
||||||
setForwardBtn,
|
|
||||||
setBackBtn,
|
|
||||||
}) {
|
|
||||||
const [searchQuery, setSearchQuery] = useState("");
|
|
||||||
const [filteredEmbedders, setFilteredEmbedders] = useState([]);
|
|
||||||
const [selectedEmbedder, setSelectedEmbedder] = useState(null);
|
|
||||||
const [settings, setSettings] = useState(null);
|
|
||||||
const formRef = useRef(null);
|
|
||||||
const hiddenSubmitButtonRef = useRef(null);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
async function fetchKeys() {
|
|
||||||
const _settings = await System.keys();
|
|
||||||
setSettings(_settings);
|
|
||||||
setSelectedEmbedder(_settings?.EmbeddingEngine || "native");
|
|
||||||
}
|
|
||||||
fetchKeys();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
function handleForward() {
|
|
||||||
if (hiddenSubmitButtonRef.current) {
|
|
||||||
hiddenSubmitButtonRef.current.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleBack() {
|
|
||||||
navigate(paths.onboarding.llmPreference());
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSubmit = async (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const form = e.target;
|
|
||||||
const data = {};
|
|
||||||
const formData = new FormData(form);
|
|
||||||
data.EmbeddingEngine = selectedEmbedder;
|
|
||||||
for (var [key, value] of formData.entries()) data[key] = value;
|
|
||||||
|
|
||||||
const { error } = await System.updateSystem(data);
|
|
||||||
if (error) {
|
|
||||||
showToast(`Failed to save embedding settings: ${error}`, "error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
navigate(paths.onboarding.vectorDatabase());
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setHeader({ title: TITLE, description: DESCRIPTION });
|
|
||||||
setForwardBtn({ showing: true, disabled: false, onClick: handleForward });
|
|
||||||
setBackBtn({ showing: true, disabled: false, onClick: handleBack });
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const filtered = EMBEDDERS.filter((embedder) =>
|
|
||||||
embedder.name.toLowerCase().includes(searchQuery.toLowerCase())
|
|
||||||
);
|
|
||||||
setFilteredEmbedders(filtered);
|
|
||||||
}, [searchQuery, selectedEmbedder]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<form ref={formRef} onSubmit={handleSubmit} className="w-full">
|
|
||||||
<div className="w-full relative border-slate-300/40 shadow border-2 rounded-lg text-white">
|
|
||||||
<div className="w-full p-4 absolute top-0 rounded-t-lg backdrop-blur-sm">
|
|
||||||
<div className="w-full flex items-center sticky top-0 z-20">
|
|
||||||
<MagnifyingGlass
|
|
||||||
size={16}
|
|
||||||
weight="bold"
|
|
||||||
className="absolute left-4 z-30 text-white"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder="Search Embedding providers"
|
|
||||||
className="bg-zinc-600 z-20 pl-10 h-[38px] rounded-full w-full px-4 py-1 text-sm border-2 border-slate-300/40 outline-none focus:border-white text-white"
|
|
||||||
onChange={(e) => setSearchQuery(e.target.value)}
|
|
||||||
autoComplete="off"
|
|
||||||
onKeyDown={(e) => {
|
|
||||||
if (e.key === "Enter") e.preventDefault();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="px-4 pt-[70px] flex flex-col gap-y-1 max-h-[390px] overflow-y-auto no-scroll pb-4">
|
|
||||||
{filteredEmbedders.map((embedder) => {
|
|
||||||
return (
|
|
||||||
<EmbedderItem
|
|
||||||
key={embedder.name}
|
|
||||||
name={embedder.name}
|
|
||||||
value={embedder.value}
|
|
||||||
image={embedder.logo}
|
|
||||||
description={embedder.description}
|
|
||||||
checked={selectedEmbedder === embedder.value}
|
|
||||||
onClick={() => setSelectedEmbedder(embedder.value)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mt-4 flex flex-col gap-y-1">
|
|
||||||
{selectedEmbedder &&
|
|
||||||
EMBEDDERS.find(
|
|
||||||
(embedder) => embedder.value === selectedEmbedder
|
|
||||||
)?.options(settings)}
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
ref={hiddenSubmitButtonRef}
|
|
||||||
hidden
|
|
||||||
aria-hidden="true"
|
|
||||||
></button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
import { MagnifyingGlass } from "@phosphor-icons/react";
|
import { MagnifyingGlass } from "@phosphor-icons/react";
|
||||||
import { useEffect, useState, useRef } from "react";
|
import { useEffect, useState, useRef } from "react";
|
||||||
import OpenAiLogo from "@/media/llmprovider/openai.png";
|
import OpenAiLogo from "@/media/llmprovider/openai.png";
|
||||||
|
import GenericOpenAiLogo from "@/media/llmprovider/generic-openai.png";
|
||||||
import AzureOpenAiLogo from "@/media/llmprovider/azure.png";
|
import AzureOpenAiLogo from "@/media/llmprovider/azure.png";
|
||||||
import AnthropicLogo from "@/media/llmprovider/anthropic.png";
|
import AnthropicLogo from "@/media/llmprovider/anthropic.png";
|
||||||
import GeminiLogo from "@/media/llmprovider/gemini.png";
|
import GeminiLogo from "@/media/llmprovider/gemini.png";
|
||||||
@ -14,6 +15,7 @@ import PerplexityLogo from "@/media/llmprovider/perplexity.png";
|
|||||||
import OpenRouterLogo from "@/media/llmprovider/openrouter.jpeg";
|
import OpenRouterLogo from "@/media/llmprovider/openrouter.jpeg";
|
||||||
import GroqLogo from "@/media/llmprovider/groq.png";
|
import GroqLogo from "@/media/llmprovider/groq.png";
|
||||||
import OpenAiOptions from "@/components/LLMSelection/OpenAiOptions";
|
import OpenAiOptions from "@/components/LLMSelection/OpenAiOptions";
|
||||||
|
import GenericOpenAiOptions from "@/components/LLMSelection/GenericOpenAiOptions";
|
||||||
import AzureAiOptions from "@/components/LLMSelection/AzureAiOptions";
|
import AzureAiOptions from "@/components/LLMSelection/AzureAiOptions";
|
||||||
import AnthropicAiOptions from "@/components/LLMSelection/AnthropicAiOptions";
|
import AnthropicAiOptions from "@/components/LLMSelection/AnthropicAiOptions";
|
||||||
import LMStudioOptions from "@/components/LLMSelection/LMStudioOptions";
|
import LMStudioOptions from "@/components/LLMSelection/LMStudioOptions";
|
||||||
@ -36,6 +38,120 @@ const TITLE = "LLM Preference";
|
|||||||
const DESCRIPTION =
|
const DESCRIPTION =
|
||||||
"AnythingLLM can work with many LLM providers. This will be the service which handles chatting.";
|
"AnythingLLM can work with many LLM providers. This will be the service which handles chatting.";
|
||||||
|
|
||||||
|
const LLMS = [
|
||||||
|
{
|
||||||
|
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: "Anthropic",
|
||||||
|
value: "anthropic",
|
||||||
|
logo: AnthropicLogo,
|
||||||
|
options: (settings) => <AnthropicAiOptions settings={settings} />,
|
||||||
|
description: "A friendly AI Assistant hosted by Anthropic.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Gemini",
|
||||||
|
value: "gemini",
|
||||||
|
logo: GeminiLogo,
|
||||||
|
options: (settings) => <GeminiLLMOptions settings={settings} />,
|
||||||
|
description: "Google's largest and most capable AI model",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "HuggingFace",
|
||||||
|
value: "huggingface",
|
||||||
|
logo: HuggingFaceLogo,
|
||||||
|
options: (settings) => <HuggingFaceOptions settings={settings} />,
|
||||||
|
description:
|
||||||
|
"Access 150,000+ open-source LLMs and the world's AI community",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ollama",
|
||||||
|
value: "ollama",
|
||||||
|
logo: OllamaLogo,
|
||||||
|
options: (settings) => <OllamaLLMOptions settings={settings} />,
|
||||||
|
description: "Run LLMs locally on your own machine.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "LM Studio",
|
||||||
|
value: "lmstudio",
|
||||||
|
logo: LMStudioLogo,
|
||||||
|
options: (settings) => <LMStudioOptions settings={settings} />,
|
||||||
|
description:
|
||||||
|
"Discover, download, and run thousands of cutting edge LLMs in a few clicks.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Local AI",
|
||||||
|
value: "localai",
|
||||||
|
logo: LocalAiLogo,
|
||||||
|
options: (settings) => <LocalAiOptions settings={settings} />,
|
||||||
|
description: "Run LLMs locally on your own machine.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Together AI",
|
||||||
|
value: "togetherai",
|
||||||
|
logo: TogetherAILogo,
|
||||||
|
options: (settings) => <TogetherAiOptions settings={settings} />,
|
||||||
|
description: "Run open source models from Together AI.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Mistral",
|
||||||
|
value: "mistral",
|
||||||
|
logo: MistralLogo,
|
||||||
|
options: (settings) => <MistralOptions settings={settings} />,
|
||||||
|
description: "Run open source models from Mistral AI.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Perplexity AI",
|
||||||
|
value: "perplexity",
|
||||||
|
logo: PerplexityLogo,
|
||||||
|
options: (settings) => <PerplexityOptions settings={settings} />,
|
||||||
|
description:
|
||||||
|
"Run powerful and internet-connected models hosted by Perplexity AI.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OpenRouter",
|
||||||
|
value: "openrouter",
|
||||||
|
logo: OpenRouterLogo,
|
||||||
|
options: (settings) => <OpenRouterOptions settings={settings} />,
|
||||||
|
description: "A unified interface for LLMs.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Groq",
|
||||||
|
value: "groq",
|
||||||
|
logo: GroqLogo,
|
||||||
|
options: (settings) => <GroqAiOptions settings={settings} />,
|
||||||
|
description:
|
||||||
|
"The fastest LLM inferencing available for real-time AI applications.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Generic OpenAI",
|
||||||
|
value: "generic-openai",
|
||||||
|
logo: GenericOpenAiLogo,
|
||||||
|
options: (settings) => <GenericOpenAiOptions settings={settings} />,
|
||||||
|
description:
|
||||||
|
"Connect to any OpenAi-compatible service via a custom configuration",
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// name: "Native",
|
||||||
|
// value: "native",
|
||||||
|
// logo: AnythingLLMIcon,
|
||||||
|
// options: (settings) => <NativeLLMOptions settings={settings} />,
|
||||||
|
// description:
|
||||||
|
// "Use a downloaded custom Llama model for chatting on this AnythingLLM instance.",
|
||||||
|
// },
|
||||||
|
];
|
||||||
|
|
||||||
export default function LLMPreference({
|
export default function LLMPreference({
|
||||||
setHeader,
|
setHeader,
|
||||||
setForwardBtn,
|
setForwardBtn,
|
||||||
@ -59,104 +175,6 @@ export default function LLMPreference({
|
|||||||
fetchKeys();
|
fetchKeys();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const LLMS = [
|
|
||||||
{
|
|
||||||
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: "Anthropic",
|
|
||||||
value: "anthropic",
|
|
||||||
logo: AnthropicLogo,
|
|
||||||
options: <AnthropicAiOptions settings={settings} />,
|
|
||||||
description: "A friendly AI Assistant hosted by Anthropic.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Gemini",
|
|
||||||
value: "gemini",
|
|
||||||
logo: GeminiLogo,
|
|
||||||
options: <GeminiLLMOptions settings={settings} />,
|
|
||||||
description: "Google's largest and most capable AI model",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "HuggingFace",
|
|
||||||
value: "huggingface",
|
|
||||||
logo: HuggingFaceLogo,
|
|
||||||
options: <HuggingFaceOptions settings={settings} />,
|
|
||||||
description:
|
|
||||||
"Access 150,000+ open-source LLMs and the world's AI community",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Ollama",
|
|
||||||
value: "ollama",
|
|
||||||
logo: OllamaLogo,
|
|
||||||
options: <OllamaLLMOptions settings={settings} />,
|
|
||||||
description: "Run LLMs locally on your own machine.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "LM Studio",
|
|
||||||
value: "lmstudio",
|
|
||||||
logo: LMStudioLogo,
|
|
||||||
options: <LMStudioOptions settings={settings} />,
|
|
||||||
description:
|
|
||||||
"Discover, download, and run thousands of cutting edge LLMs in a few clicks.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Local AI",
|
|
||||||
value: "localai",
|
|
||||||
logo: LocalAiLogo,
|
|
||||||
options: <LocalAiOptions settings={settings} />,
|
|
||||||
description: "Run LLMs locally on your own machine.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Together AI",
|
|
||||||
value: "togetherai",
|
|
||||||
logo: TogetherAILogo,
|
|
||||||
options: <TogetherAiOptions settings={settings} />,
|
|
||||||
description: "Run open source models from Together AI.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Mistral",
|
|
||||||
value: "mistral",
|
|
||||||
logo: MistralLogo,
|
|
||||||
options: <MistralOptions settings={settings} />,
|
|
||||||
description: "Run open source models from Mistral AI.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Perplexity AI",
|
|
||||||
value: "perplexity",
|
|
||||||
logo: PerplexityLogo,
|
|
||||||
options: <PerplexityOptions settings={settings} />,
|
|
||||||
description:
|
|
||||||
"Run powerful and internet-connected models hosted by Perplexity AI.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "OpenRouter",
|
|
||||||
value: "openrouter",
|
|
||||||
logo: OpenRouterLogo,
|
|
||||||
options: <OpenRouterOptions settings={settings} />,
|
|
||||||
description: "A unified interface for LLMs.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Groq",
|
|
||||||
value: "groq",
|
|
||||||
logo: GroqLogo,
|
|
||||||
options: <GroqAiOptions settings={settings} />,
|
|
||||||
description:
|
|
||||||
"The fastest LLM inferencing available for real-time AI applications.",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
function handleForward() {
|
function handleForward() {
|
||||||
if (hiddenSubmitButtonRef.current) {
|
if (hiddenSubmitButtonRef.current) {
|
||||||
hiddenSubmitButtonRef.current.click();
|
hiddenSubmitButtonRef.current.click();
|
||||||
@ -172,6 +190,9 @@ export default function LLMPreference({
|
|||||||
const data = {};
|
const data = {};
|
||||||
const formData = new FormData(form);
|
const formData = new FormData(form);
|
||||||
data.LLMProvider = selectedLLM;
|
data.LLMProvider = selectedLLM;
|
||||||
|
// Default to AnythingLLM embedder and LanceDB
|
||||||
|
data.EmbeddingEngine = "native";
|
||||||
|
data.VectorDB = "lancedb";
|
||||||
for (var [key, value] of formData.entries()) data[key] = value;
|
for (var [key, value] of formData.entries()) data[key] = value;
|
||||||
|
|
||||||
const { error } = await System.updateSystem(data);
|
const { error } = await System.updateSystem(data);
|
||||||
@ -179,7 +200,7 @@ export default function LLMPreference({
|
|||||||
showToast(`Failed to save LLM settings: ${error}`, "error");
|
showToast(`Failed to save LLM settings: ${error}`, "error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
navigate(paths.onboarding.embeddingPreference());
|
navigate(paths.onboarding.customLogo());
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -236,7 +257,7 @@ export default function LLMPreference({
|
|||||||
</div>
|
</div>
|
||||||
<div className="mt-4 flex flex-col gap-y-1">
|
<div className="mt-4 flex flex-col gap-y-1">
|
||||||
{selectedLLM &&
|
{selectedLLM &&
|
||||||
LLMS.find((llm) => llm.value === selectedLLM)?.options}
|
LLMS.find((llm) => llm.value === selectedLLM)?.options(settings)}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
@ -1,202 +0,0 @@
|
|||||||
import React, { useEffect, useState, useRef } from "react";
|
|
||||||
import { MagnifyingGlass } from "@phosphor-icons/react";
|
|
||||||
import ChromaLogo from "@/media/vectordbs/chroma.png";
|
|
||||||
import PineconeLogo from "@/media/vectordbs/pinecone.png";
|
|
||||||
import LanceDbLogo from "@/media/vectordbs/lancedb.png";
|
|
||||||
import WeaviateLogo from "@/media/vectordbs/weaviate.png";
|
|
||||||
import QDrantLogo from "@/media/vectordbs/qdrant.png";
|
|
||||||
import MilvusLogo from "@/media/vectordbs/milvus.png";
|
|
||||||
import ZillizLogo from "@/media/vectordbs/zilliz.png";
|
|
||||||
import AstraDBLogo from "@/media/vectordbs/astraDB.png";
|
|
||||||
import System from "@/models/system";
|
|
||||||
import paths from "@/utils/paths";
|
|
||||||
import PineconeDBOptions from "@/components/VectorDBSelection/PineconeDBOptions";
|
|
||||||
import ChromaDBOptions from "@/components/VectorDBSelection/ChromaDBOptions";
|
|
||||||
import QDrantDBOptions from "@/components/VectorDBSelection/QDrantDBOptions";
|
|
||||||
import WeaviateDBOptions from "@/components/VectorDBSelection/WeaviateDBOptions";
|
|
||||||
import LanceDBOptions from "@/components/VectorDBSelection/LanceDBOptions";
|
|
||||||
import MilvusOptions from "@/components/VectorDBSelection/MilvusDBOptions";
|
|
||||||
import ZillizCloudOptions from "@/components/VectorDBSelection/ZillizCloudOptions";
|
|
||||||
import AstraDBOptions from "@/components/VectorDBSelection/AstraDBOptions";
|
|
||||||
import showToast from "@/utils/toast";
|
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import VectorDBItem from "@/components/VectorDBSelection/VectorDBItem";
|
|
||||||
|
|
||||||
const TITLE = "Vector Database Connection";
|
|
||||||
const DESCRIPTION =
|
|
||||||
"These are the credentials and settings for your vector database of choice.";
|
|
||||||
|
|
||||||
export default function VectorDatabaseConnection({
|
|
||||||
setHeader,
|
|
||||||
setForwardBtn,
|
|
||||||
setBackBtn,
|
|
||||||
}) {
|
|
||||||
const [searchQuery, setSearchQuery] = useState("");
|
|
||||||
const [filteredVDBs, setFilteredVDBs] = useState([]);
|
|
||||||
const [selectedVDB, setSelectedVDB] = useState(null);
|
|
||||||
const [settings, setSettings] = useState(null);
|
|
||||||
const formRef = useRef(null);
|
|
||||||
const hiddenSubmitButtonRef = useRef(null);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
async function fetchKeys() {
|
|
||||||
const _settings = await System.keys();
|
|
||||||
setSettings(_settings);
|
|
||||||
setSelectedVDB(_settings?.VectorDB || "lancedb");
|
|
||||||
}
|
|
||||||
fetchKeys();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const VECTOR_DBS = [
|
|
||||||
{
|
|
||||||
name: "LanceDB",
|
|
||||||
value: "lancedb",
|
|
||||||
logo: LanceDbLogo,
|
|
||||||
options: <LanceDBOptions />,
|
|
||||||
description:
|
|
||||||
"100% local vector DB that runs on the same instance as AnythingLLM.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Chroma",
|
|
||||||
value: "chroma",
|
|
||||||
logo: ChromaLogo,
|
|
||||||
options: <ChromaDBOptions settings={settings} />,
|
|
||||||
description:
|
|
||||||
"Open source vector database you can host yourself or on the cloud.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Pinecone",
|
|
||||||
value: "pinecone",
|
|
||||||
logo: PineconeLogo,
|
|
||||||
options: <PineconeDBOptions settings={settings} />,
|
|
||||||
description: "100% cloud-based vector database for enterprise use cases.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Zilliz Cloud",
|
|
||||||
value: "zilliz",
|
|
||||||
logo: ZillizLogo,
|
|
||||||
options: <ZillizCloudOptions settings={settings} />,
|
|
||||||
description:
|
|
||||||
"Cloud hosted vector database built for enterprise with SOC 2 compliance.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "QDrant",
|
|
||||||
value: "qdrant",
|
|
||||||
logo: QDrantLogo,
|
|
||||||
options: <QDrantDBOptions settings={settings} />,
|
|
||||||
description: "Open source local and distributed cloud vector database.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Weaviate",
|
|
||||||
value: "weaviate",
|
|
||||||
logo: WeaviateLogo,
|
|
||||||
options: <WeaviateDBOptions settings={settings} />,
|
|
||||||
description:
|
|
||||||
"Open source local and cloud hosted multi-modal vector database.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Milvus",
|
|
||||||
value: "milvus",
|
|
||||||
logo: MilvusLogo,
|
|
||||||
options: <MilvusOptions settings={settings} />,
|
|
||||||
description: "Open-source, highly scalable, and blazing fast.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "AstraDB",
|
|
||||||
value: "astra",
|
|
||||||
logo: AstraDBLogo,
|
|
||||||
options: <AstraDBOptions settings={settings} />,
|
|
||||||
description: "Vector Search for Real-world GenAI.",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
function handleForward() {
|
|
||||||
if (hiddenSubmitButtonRef.current) {
|
|
||||||
hiddenSubmitButtonRef.current.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleBack() {
|
|
||||||
navigate(paths.onboarding.embeddingPreference());
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSubmit = async (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const form = e.target;
|
|
||||||
const data = {};
|
|
||||||
const formData = new FormData(form);
|
|
||||||
data.VectorDB = selectedVDB;
|
|
||||||
for (var [key, value] of formData.entries()) data[key] = value;
|
|
||||||
const { error } = await System.updateSystem(data);
|
|
||||||
if (error) {
|
|
||||||
showToast(`Failed to save Vector Database settings: ${error}`, "error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
navigate(paths.onboarding.customLogo());
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setHeader({ title: TITLE, description: DESCRIPTION });
|
|
||||||
setForwardBtn({ showing: true, disabled: false, onClick: handleForward });
|
|
||||||
setBackBtn({ showing: true, disabled: false, onClick: handleBack });
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const filtered = VECTOR_DBS.filter((vdb) =>
|
|
||||||
vdb.name.toLowerCase().includes(searchQuery.toLowerCase())
|
|
||||||
);
|
|
||||||
setFilteredVDBs(filtered);
|
|
||||||
}, [searchQuery, selectedVDB]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<form ref={formRef} onSubmit={handleSubmit} className="w-full">
|
|
||||||
<div className="w-full relative border-slate-300/40 shadow border-2 rounded-lg text-white pb-4">
|
|
||||||
<div className="w-full p-4 absolute top-0 rounded-t-lg backdrop-blur-sm">
|
|
||||||
<div className="w-full flex items-center sticky top-0 z-20">
|
|
||||||
<MagnifyingGlass
|
|
||||||
size={16}
|
|
||||||
weight="bold"
|
|
||||||
className="absolute left-4 z-30 text-white"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder="Search vector databases"
|
|
||||||
className="bg-zinc-600 z-20 pl-10 h-[38px] rounded-full w-full px-4 py-1 text-sm border-2 border-slate-300/40 outline-none focus:border-white text-white"
|
|
||||||
onChange={(e) => setSearchQuery(e.target.value)}
|
|
||||||
autoComplete="off"
|
|
||||||
onKeyDown={(e) => {
|
|
||||||
if (e.key === "Enter") e.preventDefault();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="px-4 pt-[70px] flex flex-col gap-y-1 max-h-[390px] overflow-y-auto no-scroll">
|
|
||||||
{filteredVDBs.map((vdb) => (
|
|
||||||
<VectorDBItem
|
|
||||||
key={vdb.name}
|
|
||||||
name={vdb.name}
|
|
||||||
value={vdb.value}
|
|
||||||
image={vdb.logo}
|
|
||||||
description={vdb.description}
|
|
||||||
checked={selectedVDB === vdb.value}
|
|
||||||
onClick={setSelectedVDB}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mt-4 flex flex-col gap-y-1">
|
|
||||||
{selectedVDB &&
|
|
||||||
VECTOR_DBS.find((vdb) => vdb.value === selectedVDB)?.options}
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
ref={hiddenSubmitButtonRef}
|
|
||||||
hidden
|
|
||||||
aria-hidden="true"
|
|
||||||
></button>
|
|
||||||
</form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -3,8 +3,6 @@ import { useState } from "react";
|
|||||||
import { isMobile } from "react-device-detect";
|
import { isMobile } from "react-device-detect";
|
||||||
import Home from "./Home";
|
import Home from "./Home";
|
||||||
import LLMPreference from "./LLMPreference";
|
import LLMPreference from "./LLMPreference";
|
||||||
import EmbeddingPreference from "./EmbeddingPreference";
|
|
||||||
import VectorDatabaseConnection from "./VectorDatabaseConnection";
|
|
||||||
import CustomLogo from "./CustomLogo";
|
import CustomLogo from "./CustomLogo";
|
||||||
import UserSetup from "./UserSetup";
|
import UserSetup from "./UserSetup";
|
||||||
import DataHandling from "./DataHandling";
|
import DataHandling from "./DataHandling";
|
||||||
@ -14,8 +12,6 @@ import CreateWorkspace from "./CreateWorkspace";
|
|||||||
const OnboardingSteps = {
|
const OnboardingSteps = {
|
||||||
home: Home,
|
home: Home,
|
||||||
"llm-preference": LLMPreference,
|
"llm-preference": LLMPreference,
|
||||||
"embedding-preference": EmbeddingPreference,
|
|
||||||
"vector-database": VectorDatabaseConnection,
|
|
||||||
"custom-logo": CustomLogo,
|
"custom-logo": CustomLogo,
|
||||||
"user-setup": UserSetup,
|
"user-setup": UserSetup,
|
||||||
"data-handling": DataHandling,
|
"data-handling": DataHandling,
|
||||||
|
@ -5,6 +5,9 @@ import { AVAILABLE_LLM_PROVIDERS } from "@/pages/GeneralSettings/LLMPreference";
|
|||||||
import { CaretUpDown, MagnifyingGlass, X } from "@phosphor-icons/react";
|
import { CaretUpDown, MagnifyingGlass, X } from "@phosphor-icons/react";
|
||||||
import ChatModelSelection from "../ChatModelSelection";
|
import ChatModelSelection from "../ChatModelSelection";
|
||||||
|
|
||||||
|
// Some providers can only be associated with a single model.
|
||||||
|
// In that case there is no selection to be made so we can just move on.
|
||||||
|
const NO_MODEL_SELECTION = ["default", "huggingface", "generic-openai"];
|
||||||
const DISABLED_PROVIDERS = ["azure", "lmstudio", "native"];
|
const DISABLED_PROVIDERS = ["azure", "lmstudio", "native"];
|
||||||
const LLM_DEFAULT = {
|
const LLM_DEFAULT = {
|
||||||
name: "System default",
|
name: "System default",
|
||||||
@ -145,7 +148,7 @@ export default function WorkspaceLLMSelection({
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{selectedLLM !== "default" && (
|
{!NO_MODEL_SELECTION.includes(selectedLLM) && (
|
||||||
<div className="mt-4 flex flex-col gap-y-1">
|
<div className="mt-4 flex flex-col gap-y-1">
|
||||||
<ChatModelSelection
|
<ChatModelSelection
|
||||||
provider={selectedLLM}
|
provider={selectedLLM}
|
||||||
|
@ -63,6 +63,12 @@ JWT_SECRET="my-random-string-for-seeding" # Please generate random string at lea
|
|||||||
# GROQ_API_KEY=gsk_abcxyz
|
# GROQ_API_KEY=gsk_abcxyz
|
||||||
# GROQ_MODEL_PREF=llama2-70b-4096
|
# GROQ_MODEL_PREF=llama2-70b-4096
|
||||||
|
|
||||||
|
# LLM_PROVIDER='generic-openai'
|
||||||
|
# GENERIC_OPEN_AI_BASE_PATH='http://proxy.url.openai.com/v1'
|
||||||
|
# GENERIC_OPEN_AI_MODEL_PREF='gpt-3.5-turbo'
|
||||||
|
# GENERIC_OPEN_AI_MODEL_TOKEN_LIMIT=4096
|
||||||
|
# GENERIC_OPEN_AI_API_KEY=sk-123abc
|
||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
######## Embedding API SElECTION ##########
|
######## Embedding API SElECTION ##########
|
||||||
###########################################
|
###########################################
|
||||||
|
@ -436,9 +436,9 @@ function apiWorkspaceEndpoints(app) {
|
|||||||
|
|
||||||
await Document.removeDocuments(currWorkspace, deletes);
|
await Document.removeDocuments(currWorkspace, deletes);
|
||||||
await Document.addDocuments(currWorkspace, adds);
|
await Document.addDocuments(currWorkspace, adds);
|
||||||
const updatedWorkspace = await Workspace.get(
|
const updatedWorkspace = await Workspace.get({
|
||||||
`id = ${Number(currWorkspace.id)}`
|
id: Number(currWorkspace.id),
|
||||||
);
|
});
|
||||||
response.status(200).json({ workspace: updatedWorkspace });
|
response.status(200).json({ workspace: updatedWorkspace });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e.message, e);
|
console.log(e.message, e);
|
||||||
|
@ -362,6 +362,12 @@ const SystemSettings = {
|
|||||||
HuggingFaceLLMEndpoint: process.env.HUGGING_FACE_LLM_ENDPOINT,
|
HuggingFaceLLMEndpoint: process.env.HUGGING_FACE_LLM_ENDPOINT,
|
||||||
HuggingFaceLLMAccessToken: !!process.env.HUGGING_FACE_LLM_API_KEY,
|
HuggingFaceLLMAccessToken: !!process.env.HUGGING_FACE_LLM_API_KEY,
|
||||||
HuggingFaceLLMTokenLimit: process.env.HUGGING_FACE_LLM_TOKEN_LIMIT,
|
HuggingFaceLLMTokenLimit: process.env.HUGGING_FACE_LLM_TOKEN_LIMIT,
|
||||||
|
|
||||||
|
// Generic OpenAI Keys
|
||||||
|
GenericOpenAiBasePath: process.env.GENERIC_OPEN_AI_BASE_PATH,
|
||||||
|
GenericOpenAiModelPref: process.env.GENERIC_OPEN_AI_MODEL_PREF,
|
||||||
|
GenericOpenAiTokenLimit: process.env.GENERIC_OPEN_AI_MODEL_TOKEN_LIMIT,
|
||||||
|
GenericOpenAiKey: !!process.env.GENERIC_OPEN_AI_API_KEY,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,9 @@ const { v4: uuidv4 } = require("uuid");
|
|||||||
|
|
||||||
const WorkspaceAgentInvocation = {
|
const WorkspaceAgentInvocation = {
|
||||||
// returns array of strings with their @ handle.
|
// returns array of strings with their @ handle.
|
||||||
|
// must start with @
|
||||||
parseAgents: function (promptString) {
|
parseAgents: function (promptString) {
|
||||||
|
if (!promptString.startsWith("@")) return [];
|
||||||
return promptString.split(/\s+/).filter((v) => v.startsWith("@"));
|
return promptString.split(/\s+/).filter((v) => v.startsWith("@"));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
3
server/storage/models/.gitignore
vendored
3
server/storage/models/.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
Xenova
|
Xenova
|
||||||
downloaded/*
|
downloaded/*
|
||||||
!downloaded/.placeholder
|
!downloaded/.placeholder
|
||||||
|
openrouter
|
193
server/utils/AiProviders/genericOpenAi/index.js
Normal file
193
server/utils/AiProviders/genericOpenAi/index.js
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
const { NativeEmbedder } = require("../../EmbeddingEngines/native");
|
||||||
|
const { chatPrompt } = require("../../chats");
|
||||||
|
const { handleDefaultStreamResponse } = require("../../helpers/chat/responses");
|
||||||
|
|
||||||
|
class GenericOpenAiLLM {
|
||||||
|
constructor(embedder = null, modelPreference = null) {
|
||||||
|
const { Configuration, OpenAIApi } = require("openai");
|
||||||
|
if (!process.env.GENERIC_OPEN_AI_BASE_PATH)
|
||||||
|
throw new Error(
|
||||||
|
"GenericOpenAI must have a valid base path to use for the api."
|
||||||
|
);
|
||||||
|
|
||||||
|
this.basePath = process.env.GENERIC_OPEN_AI_BASE_PATH;
|
||||||
|
const config = new Configuration({
|
||||||
|
basePath: this.basePath,
|
||||||
|
apiKey: process.env.GENERIC_OPEN_AI_API_KEY ?? null,
|
||||||
|
});
|
||||||
|
this.openai = new OpenAIApi(config);
|
||||||
|
this.model =
|
||||||
|
modelPreference ?? process.env.GENERIC_OPEN_AI_MODEL_PREF ?? null;
|
||||||
|
if (!this.model)
|
||||||
|
throw new Error("GenericOpenAI must have a valid model set.");
|
||||||
|
this.limits = {
|
||||||
|
history: this.promptWindowLimit() * 0.15,
|
||||||
|
system: this.promptWindowLimit() * 0.15,
|
||||||
|
user: this.promptWindowLimit() * 0.7,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!embedder)
|
||||||
|
console.warn(
|
||||||
|
"No embedding provider defined for GenericOpenAiLLM - falling back to NativeEmbedder for embedding!"
|
||||||
|
);
|
||||||
|
this.embedder = !embedder ? new NativeEmbedder() : embedder;
|
||||||
|
this.defaultTemp = 0.7;
|
||||||
|
this.log(`Inference API: ${this.basePath} Model: ${this.model}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
log(text, ...args) {
|
||||||
|
console.log(`\x1b[36m[${this.constructor.name}]\x1b[0m ${text}`, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
#appendContext(contextTexts = []) {
|
||||||
|
if (!contextTexts || !contextTexts.length) return "";
|
||||||
|
return (
|
||||||
|
"\nContext:\n" +
|
||||||
|
contextTexts
|
||||||
|
.map((text, i) => {
|
||||||
|
return `[CONTEXT ${i}]:\n${text}\n[END CONTEXT ${i}]\n\n`;
|
||||||
|
})
|
||||||
|
.join("")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
streamingEnabled() {
|
||||||
|
return "streamChat" in this && "streamGetChatCompletion" in this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the user set a value for the token limit
|
||||||
|
// and if undefined - assume 4096 window.
|
||||||
|
promptWindowLimit() {
|
||||||
|
const limit = process.env.GENERIC_OPEN_AI_MODEL_TOKEN_LIMIT || 4096;
|
||||||
|
if (!limit || isNaN(Number(limit)))
|
||||||
|
throw new Error("No token context limit was set.");
|
||||||
|
return Number(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Short circuit since we have no idea if the model is valid or not
|
||||||
|
// in pre-flight for generic endpoints
|
||||||
|
isValidChatCompletionModel(_modelName = "") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructPrompt({
|
||||||
|
systemPrompt = "",
|
||||||
|
contextTexts = [],
|
||||||
|
chatHistory = [],
|
||||||
|
userPrompt = "",
|
||||||
|
}) {
|
||||||
|
const prompt = {
|
||||||
|
role: "system",
|
||||||
|
content: `${systemPrompt}${this.#appendContext(contextTexts)}`,
|
||||||
|
};
|
||||||
|
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
|
||||||
|
}
|
||||||
|
|
||||||
|
async isSafe(_input = "") {
|
||||||
|
// Not implemented so must be stubbed
|
||||||
|
return { safe: true, reasons: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
async sendChat(chatHistory = [], prompt, workspace = {}, rawHistory = []) {
|
||||||
|
const textResponse = await this.openai
|
||||||
|
.createChatCompletion({
|
||||||
|
model: this.model,
|
||||||
|
temperature: Number(workspace?.openAiTemp ?? this.defaultTemp),
|
||||||
|
n: 1,
|
||||||
|
messages: await this.compressMessages(
|
||||||
|
{
|
||||||
|
systemPrompt: chatPrompt(workspace),
|
||||||
|
userPrompt: prompt,
|
||||||
|
chatHistory,
|
||||||
|
},
|
||||||
|
rawHistory
|
||||||
|
),
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
const res = json.data;
|
||||||
|
if (!res.hasOwnProperty("choices"))
|
||||||
|
throw new Error("GenericOpenAI chat: No results!");
|
||||||
|
if (res.choices.length === 0)
|
||||||
|
throw new Error("GenericOpenAI chat: No results length!");
|
||||||
|
return res.choices[0].message.content;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
throw new Error(
|
||||||
|
`GenericOpenAI::createChatCompletion failed with: ${error.message}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return textResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
async streamChat(chatHistory = [], prompt, workspace = {}, rawHistory = []) {
|
||||||
|
const streamRequest = await this.openai.createChatCompletion(
|
||||||
|
{
|
||||||
|
model: this.model,
|
||||||
|
stream: true,
|
||||||
|
temperature: Number(workspace?.openAiTemp ?? this.defaultTemp),
|
||||||
|
n: 1,
|
||||||
|
messages: await this.compressMessages(
|
||||||
|
{
|
||||||
|
systemPrompt: chatPrompt(workspace),
|
||||||
|
userPrompt: prompt,
|
||||||
|
chatHistory,
|
||||||
|
},
|
||||||
|
rawHistory
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{ responseType: "stream" }
|
||||||
|
);
|
||||||
|
return streamRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getChatCompletion(messages = null, { temperature = 0.7 }) {
|
||||||
|
const { data } = await this.openai
|
||||||
|
.createChatCompletion({
|
||||||
|
model: this.model,
|
||||||
|
messages,
|
||||||
|
temperature,
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
throw new Error(e.response.data.error.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!data.hasOwnProperty("choices")) return null;
|
||||||
|
return data.choices[0].message.content;
|
||||||
|
}
|
||||||
|
|
||||||
|
async streamGetChatCompletion(messages = null, { temperature = 0.7 }) {
|
||||||
|
const streamRequest = await this.openai.createChatCompletion(
|
||||||
|
{
|
||||||
|
model: this.model,
|
||||||
|
stream: true,
|
||||||
|
messages,
|
||||||
|
temperature,
|
||||||
|
},
|
||||||
|
{ responseType: "stream" }
|
||||||
|
);
|
||||||
|
return streamRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleStream(response, stream, responseProps) {
|
||||||
|
return handleDefaultStreamResponse(response, stream, responseProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple wrapper for dynamic embedder & normalize interface for all LLM implementations
|
||||||
|
async embedTextInput(textInput) {
|
||||||
|
return await this.embedder.embedTextInput(textInput);
|
||||||
|
}
|
||||||
|
async embedChunks(textChunks = []) {
|
||||||
|
return await this.embedder.embedChunks(textChunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
async compressMessages(promptArgs = {}, rawHistory = []) {
|
||||||
|
const { messageArrayCompressor } = require("../../helpers/chat");
|
||||||
|
const messageArray = this.constructPrompt(promptArgs);
|
||||||
|
return await messageArrayCompressor(this, messageArray, rawHistory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
GenericOpenAiLLM,
|
||||||
|
};
|
@ -40,20 +40,31 @@ class GroqLLM {
|
|||||||
streamingEnabled() {
|
streamingEnabled() {
|
||||||
return "streamChat" in this && "streamGetChatCompletion" in this;
|
return "streamChat" in this && "streamGetChatCompletion" in this;
|
||||||
}
|
}
|
||||||
|
|
||||||
promptWindowLimit() {
|
promptWindowLimit() {
|
||||||
switch (this.model) {
|
switch (this.model) {
|
||||||
case "llama2-70b-4096":
|
case "llama2-70b-4096":
|
||||||
return 4096;
|
return 4096;
|
||||||
case "mixtral-8x7b-32768":
|
case "mixtral-8x7b-32768":
|
||||||
return 32_768;
|
return 32_768;
|
||||||
|
case "llama3-8b-8192":
|
||||||
|
return 8192;
|
||||||
|
case "llama3-70b-8192":
|
||||||
|
return 8192;
|
||||||
|
case "gemma-7b-it":
|
||||||
|
return 8192;
|
||||||
default:
|
default:
|
||||||
return 4096;
|
return 4096;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async isValidChatCompletionModel(modelName = "") {
|
async isValidChatCompletionModel(modelName = "") {
|
||||||
const validModels = ["llama2-70b-4096", "mixtral-8x7b-32768"];
|
const validModels = [
|
||||||
|
"llama2-70b-4096",
|
||||||
|
"mixtral-8x7b-32768",
|
||||||
|
"llama3-8b-8192",
|
||||||
|
"llama3-70b-8192",
|
||||||
|
"gemma-7b-it",
|
||||||
|
];
|
||||||
const isPreset = validModels.some((model) => modelName === model);
|
const isPreset = validModels.some((model) => modelName === model);
|
||||||
if (isPreset) return true;
|
if (isPreset) return true;
|
||||||
|
|
||||||
|
@ -5,11 +5,9 @@ const {
|
|||||||
writeResponseChunk,
|
writeResponseChunk,
|
||||||
clientAbortedHandler,
|
clientAbortedHandler,
|
||||||
} = require("../../helpers/chat/responses");
|
} = require("../../helpers/chat/responses");
|
||||||
|
const fs = require("fs");
|
||||||
function openRouterModels() {
|
const path = require("path");
|
||||||
const { MODELS } = require("./models.js");
|
const { safeJsonParse } = require("../../http");
|
||||||
return MODELS || {};
|
|
||||||
}
|
|
||||||
|
|
||||||
class OpenRouterLLM {
|
class OpenRouterLLM {
|
||||||
constructor(embedder = null, modelPreference = null) {
|
constructor(embedder = null, modelPreference = null) {
|
||||||
@ -17,8 +15,9 @@ class OpenRouterLLM {
|
|||||||
if (!process.env.OPENROUTER_API_KEY)
|
if (!process.env.OPENROUTER_API_KEY)
|
||||||
throw new Error("No OpenRouter API key was set.");
|
throw new Error("No OpenRouter API key was set.");
|
||||||
|
|
||||||
|
this.basePath = "https://openrouter.ai/api/v1";
|
||||||
const config = new Configuration({
|
const config = new Configuration({
|
||||||
basePath: "https://openrouter.ai/api/v1",
|
basePath: this.basePath,
|
||||||
apiKey: process.env.OPENROUTER_API_KEY,
|
apiKey: process.env.OPENROUTER_API_KEY,
|
||||||
baseOptions: {
|
baseOptions: {
|
||||||
headers: {
|
headers: {
|
||||||
@ -38,6 +37,81 @@ class OpenRouterLLM {
|
|||||||
|
|
||||||
this.embedder = !embedder ? new NativeEmbedder() : embedder;
|
this.embedder = !embedder ? new NativeEmbedder() : embedder;
|
||||||
this.defaultTemp = 0.7;
|
this.defaultTemp = 0.7;
|
||||||
|
|
||||||
|
const cacheFolder = path.resolve(
|
||||||
|
process.env.STORAGE_DIR
|
||||||
|
? path.resolve(process.env.STORAGE_DIR, "models", "openrouter")
|
||||||
|
: path.resolve(__dirname, `../../../storage/models/openrouter`)
|
||||||
|
);
|
||||||
|
fs.mkdirSync(cacheFolder, { recursive: true });
|
||||||
|
this.cacheModelPath = path.resolve(cacheFolder, "models.json");
|
||||||
|
this.cacheAtPath = path.resolve(cacheFolder, ".cached_at");
|
||||||
|
}
|
||||||
|
|
||||||
|
log(text, ...args) {
|
||||||
|
console.log(`\x1b[36m[${this.constructor.name}]\x1b[0m ${text}`, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
await this.#syncModels();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This checks if the .cached_at file has a timestamp that is more than 1Week (in millis)
|
||||||
|
// from the current date. If it is, then we will refetch the API so that all the models are up
|
||||||
|
// to date.
|
||||||
|
#cacheIsStale() {
|
||||||
|
const MAX_STALE = 6.048e8; // 1 Week in MS
|
||||||
|
if (!fs.existsSync(this.cacheAtPath)) return true;
|
||||||
|
const now = Number(new Date());
|
||||||
|
const timestampMs = Number(fs.readFileSync(this.cacheAtPath));
|
||||||
|
return now - timestampMs > MAX_STALE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The OpenRouter model API has a lot of models, so we cache this locally in the directory
|
||||||
|
// as if the cache directory JSON file is stale or does not exist we will fetch from API and store it.
|
||||||
|
// This might slow down the first request, but we need the proper token context window
|
||||||
|
// for each model and this is a constructor property - so we can really only get it if this cache exists.
|
||||||
|
// We used to have this as a chore, but given there is an API to get the info - this makes little sense.
|
||||||
|
async #syncModels() {
|
||||||
|
if (fs.existsSync(this.cacheModelPath) && !this.#cacheIsStale())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
this.log(
|
||||||
|
"Model cache is not present or stale. Fetching from OpenRouter API."
|
||||||
|
);
|
||||||
|
await fetch(`${this.basePath}/models`, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then(({ data = [] }) => {
|
||||||
|
const models = {};
|
||||||
|
data.forEach((model) => {
|
||||||
|
models[model.id] = {
|
||||||
|
id: model.id,
|
||||||
|
name: model.name,
|
||||||
|
organization:
|
||||||
|
model.id.split("/")[0].charAt(0).toUpperCase() +
|
||||||
|
model.id.split("/")[0].slice(1),
|
||||||
|
maxLength: model.context_length,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
fs.writeFileSync(this.cacheModelPath, JSON.stringify(models), {
|
||||||
|
encoding: "utf-8",
|
||||||
|
});
|
||||||
|
fs.writeFileSync(this.cacheAtPath, String(Number(new Date())), {
|
||||||
|
encoding: "utf-8",
|
||||||
|
});
|
||||||
|
return models;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.error(e);
|
||||||
|
return {};
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#appendContext(contextTexts = []) {
|
#appendContext(contextTexts = []) {
|
||||||
@ -52,8 +126,12 @@ class OpenRouterLLM {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
allModelInformation() {
|
models() {
|
||||||
return openRouterModels();
|
if (!fs.existsSync(this.cacheModelPath)) return {};
|
||||||
|
return safeJsonParse(
|
||||||
|
fs.readFileSync(this.cacheModelPath, { encoding: "utf-8" }),
|
||||||
|
{}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
streamingEnabled() {
|
streamingEnabled() {
|
||||||
@ -61,12 +139,13 @@ class OpenRouterLLM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
promptWindowLimit() {
|
promptWindowLimit() {
|
||||||
const availableModels = this.allModelInformation();
|
const availableModels = this.models();
|
||||||
return availableModels[this.model]?.maxLength || 4096;
|
return availableModels[this.model]?.maxLength || 4096;
|
||||||
}
|
}
|
||||||
|
|
||||||
async isValidChatCompletionModel(model = "") {
|
async isValidChatCompletionModel(model = "") {
|
||||||
const availableModels = this.allModelInformation();
|
await this.#syncModels();
|
||||||
|
const availableModels = this.models();
|
||||||
return availableModels.hasOwnProperty(model);
|
return availableModels.hasOwnProperty(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,5 +422,4 @@ class OpenRouterLLM {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
OpenRouterLLM,
|
OpenRouterLLM,
|
||||||
openRouterModels,
|
|
||||||
};
|
};
|
||||||
|
@ -1,778 +0,0 @@
|
|||||||
const MODELS = {
|
|
||||||
"openrouter/auto": {
|
|
||||||
id: "openrouter/auto",
|
|
||||||
name: "Auto (best for prompt)",
|
|
||||||
organization: "Openrouter",
|
|
||||||
maxLength: 128000,
|
|
||||||
},
|
|
||||||
"nousresearch/nous-capybara-7b:free": {
|
|
||||||
id: "nousresearch/nous-capybara-7b:free",
|
|
||||||
name: "Nous: Capybara 7B (free)",
|
|
||||||
organization: "Nousresearch",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"mistralai/mistral-7b-instruct:free": {
|
|
||||||
id: "mistralai/mistral-7b-instruct:free",
|
|
||||||
name: "Mistral 7B Instruct (free)",
|
|
||||||
organization: "Mistralai",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"openchat/openchat-7b:free": {
|
|
||||||
id: "openchat/openchat-7b:free",
|
|
||||||
name: "OpenChat 3.5 (free)",
|
|
||||||
organization: "Openchat",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"gryphe/mythomist-7b:free": {
|
|
||||||
id: "gryphe/mythomist-7b:free",
|
|
||||||
name: "MythoMist 7B (free)",
|
|
||||||
organization: "Gryphe",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"undi95/toppy-m-7b:free": {
|
|
||||||
id: "undi95/toppy-m-7b:free",
|
|
||||||
name: "Toppy M 7B (free)",
|
|
||||||
organization: "Undi95",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"openrouter/cinematika-7b:free": {
|
|
||||||
id: "openrouter/cinematika-7b:free",
|
|
||||||
name: "Cinematika 7B (alpha) (free)",
|
|
||||||
organization: "Openrouter",
|
|
||||||
maxLength: 8000,
|
|
||||||
},
|
|
||||||
"google/gemma-7b-it:free": {
|
|
||||||
id: "google/gemma-7b-it:free",
|
|
||||||
name: "Google: Gemma 7B (free)",
|
|
||||||
organization: "Google",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"jebcarter/psyfighter-13b": {
|
|
||||||
id: "jebcarter/psyfighter-13b",
|
|
||||||
name: "Psyfighter 13B",
|
|
||||||
organization: "Jebcarter",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"koboldai/psyfighter-13b-2": {
|
|
||||||
id: "koboldai/psyfighter-13b-2",
|
|
||||||
name: "Psyfighter v2 13B",
|
|
||||||
organization: "Koboldai",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"intel/neural-chat-7b": {
|
|
||||||
id: "intel/neural-chat-7b",
|
|
||||||
name: "Neural Chat 7B v3.1",
|
|
||||||
organization: "Intel",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"haotian-liu/llava-13b": {
|
|
||||||
id: "haotian-liu/llava-13b",
|
|
||||||
name: "Llava 13B",
|
|
||||||
organization: "Haotian-liu",
|
|
||||||
maxLength: 2048,
|
|
||||||
},
|
|
||||||
"nousresearch/nous-hermes-2-vision-7b": {
|
|
||||||
id: "nousresearch/nous-hermes-2-vision-7b",
|
|
||||||
name: "Nous: Hermes 2 Vision 7B (alpha)",
|
|
||||||
organization: "Nousresearch",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"meta-llama/llama-2-13b-chat": {
|
|
||||||
id: "meta-llama/llama-2-13b-chat",
|
|
||||||
name: "Meta: Llama v2 13B Chat",
|
|
||||||
organization: "Meta-llama",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"migtissera/synthia-70b": {
|
|
||||||
id: "migtissera/synthia-70b",
|
|
||||||
name: "Synthia 70B",
|
|
||||||
organization: "Migtissera",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"pygmalionai/mythalion-13b": {
|
|
||||||
id: "pygmalionai/mythalion-13b",
|
|
||||||
name: "Pygmalion: Mythalion 13B",
|
|
||||||
organization: "Pygmalionai",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"xwin-lm/xwin-lm-70b": {
|
|
||||||
id: "xwin-lm/xwin-lm-70b",
|
|
||||||
name: "Xwin 70B",
|
|
||||||
organization: "Xwin-lm",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"alpindale/goliath-120b": {
|
|
||||||
id: "alpindale/goliath-120b",
|
|
||||||
name: "Goliath 120B",
|
|
||||||
organization: "Alpindale",
|
|
||||||
maxLength: 6144,
|
|
||||||
},
|
|
||||||
"neversleep/noromaid-20b": {
|
|
||||||
id: "neversleep/noromaid-20b",
|
|
||||||
name: "Noromaid 20B",
|
|
||||||
organization: "Neversleep",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"gryphe/mythomist-7b": {
|
|
||||||
id: "gryphe/mythomist-7b",
|
|
||||||
name: "MythoMist 7B",
|
|
||||||
organization: "Gryphe",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"sophosympatheia/midnight-rose-70b": {
|
|
||||||
id: "sophosympatheia/midnight-rose-70b",
|
|
||||||
name: "Midnight Rose 70B",
|
|
||||||
organization: "Sophosympatheia",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"undi95/remm-slerp-l2-13b:extended": {
|
|
||||||
id: "undi95/remm-slerp-l2-13b:extended",
|
|
||||||
name: "ReMM SLERP 13B (extended)",
|
|
||||||
organization: "Undi95",
|
|
||||||
maxLength: 6144,
|
|
||||||
},
|
|
||||||
"mancer/weaver": {
|
|
||||||
id: "mancer/weaver",
|
|
||||||
name: "Mancer: Weaver (alpha)",
|
|
||||||
organization: "Mancer",
|
|
||||||
maxLength: 8000,
|
|
||||||
},
|
|
||||||
"nousresearch/nous-hermes-llama2-13b": {
|
|
||||||
id: "nousresearch/nous-hermes-llama2-13b",
|
|
||||||
name: "Nous: Hermes 13B",
|
|
||||||
organization: "Nousresearch",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"nousresearch/nous-capybara-7b": {
|
|
||||||
id: "nousresearch/nous-capybara-7b",
|
|
||||||
name: "Nous: Capybara 7B",
|
|
||||||
organization: "Nousresearch",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"meta-llama/codellama-34b-instruct": {
|
|
||||||
id: "meta-llama/codellama-34b-instruct",
|
|
||||||
name: "Meta: CodeLlama 34B Instruct",
|
|
||||||
organization: "Meta-llama",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"codellama/codellama-70b-instruct": {
|
|
||||||
id: "codellama/codellama-70b-instruct",
|
|
||||||
name: "Meta: CodeLlama 70B Instruct",
|
|
||||||
organization: "Codellama",
|
|
||||||
maxLength: 2048,
|
|
||||||
},
|
|
||||||
"phind/phind-codellama-34b": {
|
|
||||||
id: "phind/phind-codellama-34b",
|
|
||||||
name: "Phind: CodeLlama 34B v2",
|
|
||||||
organization: "Phind",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"teknium/openhermes-2-mistral-7b": {
|
|
||||||
id: "teknium/openhermes-2-mistral-7b",
|
|
||||||
name: "OpenHermes 2 Mistral 7B",
|
|
||||||
organization: "Teknium",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"teknium/openhermes-2.5-mistral-7b": {
|
|
||||||
id: "teknium/openhermes-2.5-mistral-7b",
|
|
||||||
name: "OpenHermes 2.5 Mistral 7B",
|
|
||||||
organization: "Teknium",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"undi95/remm-slerp-l2-13b": {
|
|
||||||
id: "undi95/remm-slerp-l2-13b",
|
|
||||||
name: "ReMM SLERP 13B",
|
|
||||||
organization: "Undi95",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"openrouter/cinematika-7b": {
|
|
||||||
id: "openrouter/cinematika-7b",
|
|
||||||
name: "Cinematika 7B (alpha)",
|
|
||||||
organization: "Openrouter",
|
|
||||||
maxLength: 8000,
|
|
||||||
},
|
|
||||||
"01-ai/yi-34b-chat": {
|
|
||||||
id: "01-ai/yi-34b-chat",
|
|
||||||
name: "Yi 34B Chat",
|
|
||||||
organization: "01-ai",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"01-ai/yi-34b": {
|
|
||||||
id: "01-ai/yi-34b",
|
|
||||||
name: "Yi 34B (base)",
|
|
||||||
organization: "01-ai",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"01-ai/yi-6b": {
|
|
||||||
id: "01-ai/yi-6b",
|
|
||||||
name: "Yi 6B (base)",
|
|
||||||
organization: "01-ai",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"togethercomputer/stripedhyena-nous-7b": {
|
|
||||||
id: "togethercomputer/stripedhyena-nous-7b",
|
|
||||||
name: "StripedHyena Nous 7B",
|
|
||||||
organization: "Togethercomputer",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"togethercomputer/stripedhyena-hessian-7b": {
|
|
||||||
id: "togethercomputer/stripedhyena-hessian-7b",
|
|
||||||
name: "StripedHyena Hessian 7B (base)",
|
|
||||||
organization: "Togethercomputer",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"mistralai/mixtral-8x7b": {
|
|
||||||
id: "mistralai/mixtral-8x7b",
|
|
||||||
name: "Mixtral 8x7B (base)",
|
|
||||||
organization: "Mistralai",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"nousresearch/nous-hermes-yi-34b": {
|
|
||||||
id: "nousresearch/nous-hermes-yi-34b",
|
|
||||||
name: "Nous: Hermes 2 Yi 34B",
|
|
||||||
organization: "Nousresearch",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"nousresearch/nous-hermes-2-mixtral-8x7b-sft": {
|
|
||||||
id: "nousresearch/nous-hermes-2-mixtral-8x7b-sft",
|
|
||||||
name: "Nous: Hermes 2 Mixtral 8x7B SFT",
|
|
||||||
organization: "Nousresearch",
|
|
||||||
maxLength: 32000,
|
|
||||||
},
|
|
||||||
"nousresearch/nous-hermes-2-mistral-7b-dpo": {
|
|
||||||
id: "nousresearch/nous-hermes-2-mistral-7b-dpo",
|
|
||||||
name: "Nous: Hermes 2 Mistral 7B DPO",
|
|
||||||
organization: "Nousresearch",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"open-orca/mistral-7b-openorca": {
|
|
||||||
id: "open-orca/mistral-7b-openorca",
|
|
||||||
name: "Mistral OpenOrca 7B",
|
|
||||||
organization: "Open-orca",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"huggingfaceh4/zephyr-7b-beta": {
|
|
||||||
id: "huggingfaceh4/zephyr-7b-beta",
|
|
||||||
name: "Hugging Face: Zephyr 7B",
|
|
||||||
organization: "Huggingfaceh4",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"openai/gpt-3.5-turbo": {
|
|
||||||
id: "openai/gpt-3.5-turbo",
|
|
||||||
name: "OpenAI: GPT-3.5 Turbo",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 16385,
|
|
||||||
},
|
|
||||||
"openai/gpt-3.5-turbo-0125": {
|
|
||||||
id: "openai/gpt-3.5-turbo-0125",
|
|
||||||
name: "OpenAI: GPT-3.5 Turbo 16k",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 16385,
|
|
||||||
},
|
|
||||||
"openai/gpt-3.5-turbo-1106": {
|
|
||||||
id: "openai/gpt-3.5-turbo-1106",
|
|
||||||
name: "OpenAI: GPT-3.5 Turbo 16k (older v1106)",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 16385,
|
|
||||||
},
|
|
||||||
"openai/gpt-3.5-turbo-0613": {
|
|
||||||
id: "openai/gpt-3.5-turbo-0613",
|
|
||||||
name: "OpenAI: GPT-3.5 Turbo (older v0613)",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 4095,
|
|
||||||
},
|
|
||||||
"openai/gpt-3.5-turbo-0301": {
|
|
||||||
id: "openai/gpt-3.5-turbo-0301",
|
|
||||||
name: "OpenAI: GPT-3.5 Turbo (older v0301)",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 4095,
|
|
||||||
},
|
|
||||||
"openai/gpt-3.5-turbo-16k": {
|
|
||||||
id: "openai/gpt-3.5-turbo-16k",
|
|
||||||
name: "OpenAI: GPT-3.5 Turbo 16k",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 16385,
|
|
||||||
},
|
|
||||||
"openai/gpt-4-turbo": {
|
|
||||||
id: "openai/gpt-4-turbo",
|
|
||||||
name: "OpenAI: GPT-4 Turbo",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 128000,
|
|
||||||
},
|
|
||||||
"openai/gpt-4-turbo-preview": {
|
|
||||||
id: "openai/gpt-4-turbo-preview",
|
|
||||||
name: "OpenAI: GPT-4 Turbo Preview",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 128000,
|
|
||||||
},
|
|
||||||
"openai/gpt-4-1106-preview": {
|
|
||||||
id: "openai/gpt-4-1106-preview",
|
|
||||||
name: "OpenAI: GPT-4 Turbo (older v1106)",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 128000,
|
|
||||||
},
|
|
||||||
"openai/gpt-4": {
|
|
||||||
id: "openai/gpt-4",
|
|
||||||
name: "OpenAI: GPT-4",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 8191,
|
|
||||||
},
|
|
||||||
"openai/gpt-4-0314": {
|
|
||||||
id: "openai/gpt-4-0314",
|
|
||||||
name: "OpenAI: GPT-4 (older v0314)",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 8191,
|
|
||||||
},
|
|
||||||
"openai/gpt-4-32k": {
|
|
||||||
id: "openai/gpt-4-32k",
|
|
||||||
name: "OpenAI: GPT-4 32k",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 32767,
|
|
||||||
},
|
|
||||||
"openai/gpt-4-32k-0314": {
|
|
||||||
id: "openai/gpt-4-32k-0314",
|
|
||||||
name: "OpenAI: GPT-4 32k (older v0314)",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 32767,
|
|
||||||
},
|
|
||||||
"openai/gpt-4-vision-preview": {
|
|
||||||
id: "openai/gpt-4-vision-preview",
|
|
||||||
name: "OpenAI: GPT-4 Vision",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 128000,
|
|
||||||
},
|
|
||||||
"openai/gpt-3.5-turbo-instruct": {
|
|
||||||
id: "openai/gpt-3.5-turbo-instruct",
|
|
||||||
name: "OpenAI: GPT-3.5 Turbo Instruct",
|
|
||||||
organization: "Openai",
|
|
||||||
maxLength: 4095,
|
|
||||||
},
|
|
||||||
"google/palm-2-chat-bison": {
|
|
||||||
id: "google/palm-2-chat-bison",
|
|
||||||
name: "Google: PaLM 2 Chat",
|
|
||||||
organization: "Google",
|
|
||||||
maxLength: 25804,
|
|
||||||
},
|
|
||||||
"google/palm-2-codechat-bison": {
|
|
||||||
id: "google/palm-2-codechat-bison",
|
|
||||||
name: "Google: PaLM 2 Code Chat",
|
|
||||||
organization: "Google",
|
|
||||||
maxLength: 20070,
|
|
||||||
},
|
|
||||||
"google/palm-2-chat-bison-32k": {
|
|
||||||
id: "google/palm-2-chat-bison-32k",
|
|
||||||
name: "Google: PaLM 2 Chat 32k",
|
|
||||||
organization: "Google",
|
|
||||||
maxLength: 91750,
|
|
||||||
},
|
|
||||||
"google/palm-2-codechat-bison-32k": {
|
|
||||||
id: "google/palm-2-codechat-bison-32k",
|
|
||||||
name: "Google: PaLM 2 Code Chat 32k",
|
|
||||||
organization: "Google",
|
|
||||||
maxLength: 91750,
|
|
||||||
},
|
|
||||||
"google/gemini-pro": {
|
|
||||||
id: "google/gemini-pro",
|
|
||||||
name: "Google: Gemini Pro 1.0",
|
|
||||||
organization: "Google",
|
|
||||||
maxLength: 91728,
|
|
||||||
},
|
|
||||||
"google/gemini-pro-vision": {
|
|
||||||
id: "google/gemini-pro-vision",
|
|
||||||
name: "Google: Gemini Pro Vision 1.0",
|
|
||||||
organization: "Google",
|
|
||||||
maxLength: 45875,
|
|
||||||
},
|
|
||||||
"google/gemini-pro-1.5": {
|
|
||||||
id: "google/gemini-pro-1.5",
|
|
||||||
name: "Google: Gemini Pro 1.5 (preview)",
|
|
||||||
organization: "Google",
|
|
||||||
maxLength: 2800000,
|
|
||||||
},
|
|
||||||
"perplexity/pplx-70b-online": {
|
|
||||||
id: "perplexity/pplx-70b-online",
|
|
||||||
name: "Perplexity: PPLX 70B Online",
|
|
||||||
organization: "Perplexity",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"perplexity/pplx-7b-online": {
|
|
||||||
id: "perplexity/pplx-7b-online",
|
|
||||||
name: "Perplexity: PPLX 7B Online",
|
|
||||||
organization: "Perplexity",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"perplexity/pplx-7b-chat": {
|
|
||||||
id: "perplexity/pplx-7b-chat",
|
|
||||||
name: "Perplexity: PPLX 7B Chat",
|
|
||||||
organization: "Perplexity",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"perplexity/pplx-70b-chat": {
|
|
||||||
id: "perplexity/pplx-70b-chat",
|
|
||||||
name: "Perplexity: PPLX 70B Chat",
|
|
||||||
organization: "Perplexity",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"perplexity/sonar-small-chat": {
|
|
||||||
id: "perplexity/sonar-small-chat",
|
|
||||||
name: "Perplexity: Sonar 7B",
|
|
||||||
organization: "Perplexity",
|
|
||||||
maxLength: 16384,
|
|
||||||
},
|
|
||||||
"perplexity/sonar-medium-chat": {
|
|
||||||
id: "perplexity/sonar-medium-chat",
|
|
||||||
name: "Perplexity: Sonar 8x7B",
|
|
||||||
organization: "Perplexity",
|
|
||||||
maxLength: 16384,
|
|
||||||
},
|
|
||||||
"perplexity/sonar-small-online": {
|
|
||||||
id: "perplexity/sonar-small-online",
|
|
||||||
name: "Perplexity: Sonar 7B Online",
|
|
||||||
organization: "Perplexity",
|
|
||||||
maxLength: 12000,
|
|
||||||
},
|
|
||||||
"perplexity/sonar-medium-online": {
|
|
||||||
id: "perplexity/sonar-medium-online",
|
|
||||||
name: "Perplexity: Sonar 8x7B Online",
|
|
||||||
organization: "Perplexity",
|
|
||||||
maxLength: 12000,
|
|
||||||
},
|
|
||||||
"fireworks/mixtral-8x22b-instruct-preview": {
|
|
||||||
id: "fireworks/mixtral-8x22b-instruct-preview",
|
|
||||||
name: "Fireworks Mixtral 8x22B Instruct OH (preview)",
|
|
||||||
organization: "Fireworks",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"anthropic/claude-3-opus": {
|
|
||||||
id: "anthropic/claude-3-opus",
|
|
||||||
name: "Anthropic: Claude 3 Opus",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 200000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-3-sonnet": {
|
|
||||||
id: "anthropic/claude-3-sonnet",
|
|
||||||
name: "Anthropic: Claude 3 Sonnet",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 200000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-3-haiku": {
|
|
||||||
id: "anthropic/claude-3-haiku",
|
|
||||||
name: "Anthropic: Claude 3 Haiku",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 200000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-3-opus:beta": {
|
|
||||||
id: "anthropic/claude-3-opus:beta",
|
|
||||||
name: "Anthropic: Claude 3 Opus (self-moderated)",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 200000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-3-sonnet:beta": {
|
|
||||||
id: "anthropic/claude-3-sonnet:beta",
|
|
||||||
name: "Anthropic: Claude 3 Sonnet (self-moderated)",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 200000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-3-haiku:beta": {
|
|
||||||
id: "anthropic/claude-3-haiku:beta",
|
|
||||||
name: "Anthropic: Claude 3 Haiku (self-moderated)",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 200000,
|
|
||||||
},
|
|
||||||
"meta-llama/llama-2-70b-chat": {
|
|
||||||
id: "meta-llama/llama-2-70b-chat",
|
|
||||||
name: "Meta: Llama v2 70B Chat",
|
|
||||||
organization: "Meta-llama",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"nousresearch/nous-capybara-34b": {
|
|
||||||
id: "nousresearch/nous-capybara-34b",
|
|
||||||
name: "Nous: Capybara 34B",
|
|
||||||
organization: "Nousresearch",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"jondurbin/airoboros-l2-70b": {
|
|
||||||
id: "jondurbin/airoboros-l2-70b",
|
|
||||||
name: "Airoboros 70B",
|
|
||||||
organization: "Jondurbin",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"jondurbin/bagel-34b": {
|
|
||||||
id: "jondurbin/bagel-34b",
|
|
||||||
name: "Bagel 34B v0.2",
|
|
||||||
organization: "Jondurbin",
|
|
||||||
maxLength: 8000,
|
|
||||||
},
|
|
||||||
"austism/chronos-hermes-13b": {
|
|
||||||
id: "austism/chronos-hermes-13b",
|
|
||||||
name: "Chronos Hermes 13B v2",
|
|
||||||
organization: "Austism",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"mistralai/mistral-7b-instruct": {
|
|
||||||
id: "mistralai/mistral-7b-instruct",
|
|
||||||
name: "Mistral 7B Instruct",
|
|
||||||
organization: "Mistralai",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"gryphe/mythomax-l2-13b": {
|
|
||||||
id: "gryphe/mythomax-l2-13b",
|
|
||||||
name: "MythoMax 13B",
|
|
||||||
organization: "Gryphe",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"openchat/openchat-7b": {
|
|
||||||
id: "openchat/openchat-7b",
|
|
||||||
name: "OpenChat 3.5",
|
|
||||||
organization: "Openchat",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"undi95/toppy-m-7b": {
|
|
||||||
id: "undi95/toppy-m-7b",
|
|
||||||
name: "Toppy M 7B",
|
|
||||||
organization: "Undi95",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"lizpreciatior/lzlv-70b-fp16-hf": {
|
|
||||||
id: "lizpreciatior/lzlv-70b-fp16-hf",
|
|
||||||
name: "lzlv 70B",
|
|
||||||
organization: "Lizpreciatior",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"mistralai/mixtral-8x7b-instruct": {
|
|
||||||
id: "mistralai/mixtral-8x7b-instruct",
|
|
||||||
name: "Mixtral 8x7B Instruct",
|
|
||||||
organization: "Mistralai",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"cognitivecomputations/dolphin-mixtral-8x7b": {
|
|
||||||
id: "cognitivecomputations/dolphin-mixtral-8x7b",
|
|
||||||
name: "Dolphin 2.6 Mixtral 8x7B 🐬",
|
|
||||||
organization: "Cognitivecomputations",
|
|
||||||
maxLength: 32000,
|
|
||||||
},
|
|
||||||
"neversleep/noromaid-mixtral-8x7b-instruct": {
|
|
||||||
id: "neversleep/noromaid-mixtral-8x7b-instruct",
|
|
||||||
name: "Noromaid Mixtral 8x7B Instruct",
|
|
||||||
organization: "Neversleep",
|
|
||||||
maxLength: 8000,
|
|
||||||
},
|
|
||||||
"nousresearch/nous-hermes-2-mixtral-8x7b-dpo": {
|
|
||||||
id: "nousresearch/nous-hermes-2-mixtral-8x7b-dpo",
|
|
||||||
name: "Nous: Hermes 2 Mixtral 8x7B DPO",
|
|
||||||
organization: "Nousresearch",
|
|
||||||
maxLength: 32000,
|
|
||||||
},
|
|
||||||
"rwkv/rwkv-5-world-3b": {
|
|
||||||
id: "rwkv/rwkv-5-world-3b",
|
|
||||||
name: "RWKV v5 World 3B",
|
|
||||||
organization: "Rwkv",
|
|
||||||
maxLength: 10000,
|
|
||||||
},
|
|
||||||
"recursal/rwkv-5-3b-ai-town": {
|
|
||||||
id: "recursal/rwkv-5-3b-ai-town",
|
|
||||||
name: "RWKV v5 3B AI Town",
|
|
||||||
organization: "Recursal",
|
|
||||||
maxLength: 10000,
|
|
||||||
},
|
|
||||||
"recursal/eagle-7b": {
|
|
||||||
id: "recursal/eagle-7b",
|
|
||||||
name: "RWKV v5: Eagle 7B",
|
|
||||||
organization: "Recursal",
|
|
||||||
maxLength: 10000,
|
|
||||||
},
|
|
||||||
"google/gemma-7b-it": {
|
|
||||||
id: "google/gemma-7b-it",
|
|
||||||
name: "Google: Gemma 7B",
|
|
||||||
organization: "Google",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"databricks/dbrx-instruct": {
|
|
||||||
id: "databricks/dbrx-instruct",
|
|
||||||
name: "Databricks: DBRX 132B Instruct",
|
|
||||||
organization: "Databricks",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"huggingfaceh4/zephyr-orpo-141b-a35b": {
|
|
||||||
id: "huggingfaceh4/zephyr-orpo-141b-a35b",
|
|
||||||
name: "Zephyr 141B-A35B",
|
|
||||||
organization: "Huggingfaceh4",
|
|
||||||
maxLength: 65536,
|
|
||||||
},
|
|
||||||
"anthropic/claude-2": {
|
|
||||||
id: "anthropic/claude-2",
|
|
||||||
name: "Anthropic: Claude v2",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 200000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-2.1": {
|
|
||||||
id: "anthropic/claude-2.1",
|
|
||||||
name: "Anthropic: Claude v2.1",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 200000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-2.0": {
|
|
||||||
id: "anthropic/claude-2.0",
|
|
||||||
name: "Anthropic: Claude v2.0",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 100000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-instant-1": {
|
|
||||||
id: "anthropic/claude-instant-1",
|
|
||||||
name: "Anthropic: Claude Instant v1",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 100000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-instant-1.2": {
|
|
||||||
id: "anthropic/claude-instant-1.2",
|
|
||||||
name: "Anthropic: Claude Instant v1.2",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 100000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-1": {
|
|
||||||
id: "anthropic/claude-1",
|
|
||||||
name: "Anthropic: Claude v1",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 100000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-1.2": {
|
|
||||||
id: "anthropic/claude-1.2",
|
|
||||||
name: "Anthropic: Claude (older v1)",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 100000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-instant-1.0": {
|
|
||||||
id: "anthropic/claude-instant-1.0",
|
|
||||||
name: "Anthropic: Claude Instant (older v1)",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 100000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-instant-1.1": {
|
|
||||||
id: "anthropic/claude-instant-1.1",
|
|
||||||
name: "Anthropic: Claude Instant (older v1.1)",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 100000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-2:beta": {
|
|
||||||
id: "anthropic/claude-2:beta",
|
|
||||||
name: "Anthropic: Claude v2 (self-moderated)",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 200000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-2.1:beta": {
|
|
||||||
id: "anthropic/claude-2.1:beta",
|
|
||||||
name: "Anthropic: Claude v2.1 (self-moderated)",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 200000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-2.0:beta": {
|
|
||||||
id: "anthropic/claude-2.0:beta",
|
|
||||||
name: "Anthropic: Claude v2.0 (self-moderated)",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 100000,
|
|
||||||
},
|
|
||||||
"anthropic/claude-instant-1:beta": {
|
|
||||||
id: "anthropic/claude-instant-1:beta",
|
|
||||||
name: "Anthropic: Claude Instant v1 (self-moderated)",
|
|
||||||
organization: "Anthropic",
|
|
||||||
maxLength: 100000,
|
|
||||||
},
|
|
||||||
"mistralai/mixtral-8x22b": {
|
|
||||||
id: "mistralai/mixtral-8x22b",
|
|
||||||
name: "Mistral: Mixtral 8x22B (base)",
|
|
||||||
organization: "Mistralai",
|
|
||||||
maxLength: 65536,
|
|
||||||
},
|
|
||||||
"huggingfaceh4/zephyr-7b-beta:free": {
|
|
||||||
id: "huggingfaceh4/zephyr-7b-beta:free",
|
|
||||||
name: "Hugging Face: Zephyr 7B (free)",
|
|
||||||
organization: "Huggingfaceh4",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"mistralai/mixtral-8x7b-instruct:nitro": {
|
|
||||||
id: "mistralai/mixtral-8x7b-instruct:nitro",
|
|
||||||
name: "Mixtral 8x7B Instruct (nitro)",
|
|
||||||
organization: "Mistralai",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"meta-llama/llama-2-70b-chat:nitro": {
|
|
||||||
id: "meta-llama/llama-2-70b-chat:nitro",
|
|
||||||
name: "Meta: Llama v2 70B Chat (nitro)",
|
|
||||||
organization: "Meta-llama",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"gryphe/mythomax-l2-13b:nitro": {
|
|
||||||
id: "gryphe/mythomax-l2-13b:nitro",
|
|
||||||
name: "MythoMax 13B (nitro)",
|
|
||||||
organization: "Gryphe",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"mistralai/mistral-7b-instruct:nitro": {
|
|
||||||
id: "mistralai/mistral-7b-instruct:nitro",
|
|
||||||
name: "Mistral 7B Instruct (nitro)",
|
|
||||||
organization: "Mistralai",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"google/gemma-7b-it:nitro": {
|
|
||||||
id: "google/gemma-7b-it:nitro",
|
|
||||||
name: "Google: Gemma 7B (nitro)",
|
|
||||||
organization: "Google",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"databricks/dbrx-instruct:nitro": {
|
|
||||||
id: "databricks/dbrx-instruct:nitro",
|
|
||||||
name: "Databricks: DBRX 132B Instruct (nitro)",
|
|
||||||
organization: "Databricks",
|
|
||||||
maxLength: 32768,
|
|
||||||
},
|
|
||||||
"gryphe/mythomax-l2-13b:extended": {
|
|
||||||
id: "gryphe/mythomax-l2-13b:extended",
|
|
||||||
name: "MythoMax 13B (extended)",
|
|
||||||
organization: "Gryphe",
|
|
||||||
maxLength: 8192,
|
|
||||||
},
|
|
||||||
"mistralai/mistral-tiny": {
|
|
||||||
id: "mistralai/mistral-tiny",
|
|
||||||
name: "Mistral Tiny",
|
|
||||||
organization: "Mistralai",
|
|
||||||
maxLength: 32000,
|
|
||||||
},
|
|
||||||
"mistralai/mistral-small": {
|
|
||||||
id: "mistralai/mistral-small",
|
|
||||||
name: "Mistral Small",
|
|
||||||
organization: "Mistralai",
|
|
||||||
maxLength: 32000,
|
|
||||||
},
|
|
||||||
"mistralai/mistral-medium": {
|
|
||||||
id: "mistralai/mistral-medium",
|
|
||||||
name: "Mistral Medium",
|
|
||||||
organization: "Mistralai",
|
|
||||||
maxLength: 32000,
|
|
||||||
},
|
|
||||||
"mistralai/mistral-large": {
|
|
||||||
id: "mistralai/mistral-large",
|
|
||||||
name: "Mistral Large",
|
|
||||||
organization: "Mistralai",
|
|
||||||
maxLength: 32000,
|
|
||||||
},
|
|
||||||
"cohere/command": {
|
|
||||||
id: "cohere/command",
|
|
||||||
name: "Cohere: Command",
|
|
||||||
organization: "Cohere",
|
|
||||||
maxLength: 4096,
|
|
||||||
},
|
|
||||||
"cohere/command-r": {
|
|
||||||
id: "cohere/command-r",
|
|
||||||
name: "Cohere: Command R",
|
|
||||||
organization: "Cohere",
|
|
||||||
maxLength: 128000,
|
|
||||||
},
|
|
||||||
"cohere/command-r-plus": {
|
|
||||||
id: "cohere/command-r-plus",
|
|
||||||
name: "Cohere: Command R+",
|
|
||||||
organization: "Cohere",
|
|
||||||
maxLength: 128000,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.MODELS = MODELS;
|
|
@ -1 +0,0 @@
|
|||||||
*.json
|
|
@ -1,37 +0,0 @@
|
|||||||
// OpenRouter has lots of models we can use so we use this script
|
|
||||||
// to cache all the models. We can see the list of all the models
|
|
||||||
// here: https://openrouter.ai/docs#models
|
|
||||||
|
|
||||||
// To run, cd into this directory and run `node parse.mjs`
|
|
||||||
// copy outputs into the export in ../models.js
|
|
||||||
|
|
||||||
// Update the date below if you run this again because OpenRouter added new models.
|
|
||||||
// Last Collected: Apr 14, 2024
|
|
||||||
|
|
||||||
import fs from "fs";
|
|
||||||
|
|
||||||
async function parseChatModels() {
|
|
||||||
const models = {};
|
|
||||||
const response = await fetch("https://openrouter.ai/api/v1/models");
|
|
||||||
const data = await response.json();
|
|
||||||
data.data.forEach((model) => {
|
|
||||||
models[model.id] = {
|
|
||||||
id: model.id,
|
|
||||||
name: model.name,
|
|
||||||
// capitalize first letter
|
|
||||||
organization:
|
|
||||||
model.id.split("/")[0].charAt(0).toUpperCase() +
|
|
||||||
model.id.split("/")[0].slice(1),
|
|
||||||
maxLength: model.context_length,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
"chat_models.json",
|
|
||||||
JSON.stringify(models, null, 2),
|
|
||||||
"utf-8"
|
|
||||||
);
|
|
||||||
return models;
|
|
||||||
}
|
|
||||||
|
|
||||||
parseChatModels();
|
|
@ -19,6 +19,16 @@ const MODELS = {
|
|||||||
name: "sonar-medium-online",
|
name: "sonar-medium-online",
|
||||||
maxLength: 12000,
|
maxLength: 12000,
|
||||||
},
|
},
|
||||||
|
"llama-3-8b-instruct": {
|
||||||
|
id: "llama-3-8b-instruct",
|
||||||
|
name: "llama-3-8b-instruct",
|
||||||
|
maxLength: 8192,
|
||||||
|
},
|
||||||
|
"llama-3-70b-instruct": {
|
||||||
|
id: "llama-3-70b-instruct",
|
||||||
|
name: "llama-3-70b-instruct",
|
||||||
|
maxLength: 8192,
|
||||||
|
},
|
||||||
"codellama-70b-instruct": {
|
"codellama-70b-instruct": {
|
||||||
id: "codellama-70b-instruct",
|
id: "codellama-70b-instruct",
|
||||||
name: "codellama-70b-instruct",
|
name: "codellama-70b-instruct",
|
||||||
@ -34,6 +44,11 @@ const MODELS = {
|
|||||||
name: "mixtral-8x7b-instruct",
|
name: "mixtral-8x7b-instruct",
|
||||||
maxLength: 16384,
|
maxLength: 16384,
|
||||||
},
|
},
|
||||||
|
"mixtral-8x22b-instruct": {
|
||||||
|
id: "mixtral-8x22b-instruct",
|
||||||
|
name: "mixtral-8x22b-instruct",
|
||||||
|
maxLength: 16384,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.MODELS = MODELS;
|
module.exports.MODELS = MODELS;
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
| `sonar-small-online` | 7B | 12000 | Chat Completion |
|
| `sonar-small-online` | 7B | 12000 | Chat Completion |
|
||||||
| `sonar-medium-chat` | 8x7B | 16384 | Chat Completion |
|
| `sonar-medium-chat` | 8x7B | 16384 | Chat Completion |
|
||||||
| `sonar-medium-online` | 8x7B | 12000 | Chat Completion |
|
| `sonar-medium-online` | 8x7B | 12000 | Chat Completion |
|
||||||
|
| `llama-3-8b-instruct` | 8B | 8192 | Chat Completion |
|
||||||
|
| `llama-3-70b-instruct` | 70B | 8192 | Chat Completion |
|
||||||
| `codellama-70b-instruct` | 70B | 16384 | Chat Completion |
|
| `codellama-70b-instruct` | 70B | 16384 | Chat Completion |
|
||||||
| `mistral-7b-instruct` [1] | 7B | 16384 | Chat Completion |
|
| `mistral-7b-instruct` [1] | 7B | 16384 | Chat Completion |
|
||||||
| `mixtral-8x7b-instruct` | 8x7B | 16384 | Chat Completion |
|
| `mixtral-8x7b-instruct` | 8x7B | 16384 | Chat Completion |
|
||||||
|
| `mixtral-8x22b-instruct` | 8x22B | 16384 | Chat Completion |
|
@ -8,7 +8,7 @@
|
|||||||
// copy outputs into the export in ../models.js
|
// copy outputs into the export in ../models.js
|
||||||
|
|
||||||
// Update the date below if you run this again because Perplexity added new models.
|
// Update the date below if you run this again because Perplexity added new models.
|
||||||
// Last Collected: Apr 14, 2024
|
// Last Collected: Apr 25, 2024
|
||||||
|
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const { openRouterModels } = require("../AiProviders/openRouter");
|
const { OpenRouterLLM } = require("../AiProviders/openRouter");
|
||||||
const { perplexityModels } = require("../AiProviders/perplexity");
|
const { perplexityModels } = require("../AiProviders/perplexity");
|
||||||
const { togetherAiModels } = require("../AiProviders/togetherAi");
|
const { togetherAiModels } = require("../AiProviders/togetherAi");
|
||||||
const SUPPORT_CUSTOM_MODELS = [
|
const SUPPORT_CUSTOM_MODELS = [
|
||||||
@ -232,7 +232,8 @@ async function getPerplexityModels() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getOpenRouterModels() {
|
async function getOpenRouterModels() {
|
||||||
const knownModels = await openRouterModels();
|
const openrouter = await new OpenRouterLLM().init();
|
||||||
|
const knownModels = openrouter.models();
|
||||||
if (!Object.keys(knownModels).length === 0)
|
if (!Object.keys(knownModels).length === 0)
|
||||||
return { models: [], error: null };
|
return { models: [], error: null };
|
||||||
|
|
||||||
|
@ -77,8 +77,13 @@ function getLLMProvider({ provider = null, model = null } = {}) {
|
|||||||
case "groq":
|
case "groq":
|
||||||
const { GroqLLM } = require("../AiProviders/groq");
|
const { GroqLLM } = require("../AiProviders/groq");
|
||||||
return new GroqLLM(embedder, model);
|
return new GroqLLM(embedder, model);
|
||||||
|
case "generic-openai":
|
||||||
|
const { GenericOpenAiLLM } = require("../AiProviders/genericOpenAi");
|
||||||
|
return new GenericOpenAiLLM(embedder, model);
|
||||||
default:
|
default:
|
||||||
throw new Error("ENV: No LLM_PROVIDER value found in environment!");
|
throw new Error(
|
||||||
|
`ENV: No valid LLM_PROVIDER value found in environment! Using ${process.env.LLM_PROVIDER}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +132,24 @@ const KEY_MAPPING = {
|
|||||||
checks: [nonZero],
|
checks: [nonZero],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Generic OpenAI InferenceSettings
|
||||||
|
GenericOpenAiBasePath: {
|
||||||
|
envKey: "GENERIC_OPEN_AI_BASE_PATH",
|
||||||
|
checks: [isValidURL],
|
||||||
|
},
|
||||||
|
GenericOpenAiModelPref: {
|
||||||
|
envKey: "GENERIC_OPEN_AI_MODEL_PREF",
|
||||||
|
checks: [isNotEmpty],
|
||||||
|
},
|
||||||
|
GenericOpenAiTokenLimit: {
|
||||||
|
envKey: "GENERIC_OPEN_AI_MODEL_TOKEN_LIMIT",
|
||||||
|
checks: [nonZero],
|
||||||
|
},
|
||||||
|
GenericOpenAiKey: {
|
||||||
|
envKey: "GENERIC_OPEN_AI_API_KEY",
|
||||||
|
checks: [],
|
||||||
|
},
|
||||||
|
|
||||||
EmbeddingEngine: {
|
EmbeddingEngine: {
|
||||||
envKey: "EMBEDDING_ENGINE",
|
envKey: "EMBEDDING_ENGINE",
|
||||||
checks: [supportedEmbeddingModel],
|
checks: [supportedEmbeddingModel],
|
||||||
@ -375,6 +393,7 @@ function supportedLLM(input = "") {
|
|||||||
"perplexity",
|
"perplexity",
|
||||||
"openrouter",
|
"openrouter",
|
||||||
"groq",
|
"groq",
|
||||||
|
"generic-openai",
|
||||||
].includes(input);
|
].includes(input);
|
||||||
return validSelection ? null : `${input} is not a valid LLM provider.`;
|
return validSelection ? null : `${input} is not a valid LLM provider.`;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user