Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"Weaviate",
"XAILLM",
"Zilliz"
"SubModel",
],
"eslint.experimental.useFlatConfig": true,
"docker.languageserver.formatter.ignoreMultilineInstructions": true
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ AnythingLLM divides your documents into objects called `workspaces`. A Workspace
- [PPIO](https://ppinfra.com?utm_source=github_anything-llm)
- [Moonshot AI](https://www.moonshot.ai/)
- [CometAPI (chat models)](https://api.cometapi.com/)
- [SubModel](https://submodel.ai)

**Embedder models:**

- [AnythingLLM Native Embedder](/server/storage/models/README.md) (default)
Expand Down
4 changes: 4 additions & 0 deletions docker/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ GID='1000'
# MOONSHOT_AI_API_KEY='your-moonshot-api-key-here'
# MOONSHOT_AI_MODEL_PREF='moonshot-v1-32k'

# LLM_PROVIDER='submodel'
# SUBMODEL_INSTAGEN_ACCESS_KEY='your-submodel-instagen-access-key-here'
# SUBMODEL_MODEL_PREF=deepseek-ai/DeepSeek-V3-0324

###########################################
######## Embedding API SElECTION ##########
###########################################
Expand Down
154 changes: 154 additions & 0 deletions frontend/src/components/LLMSelection/SubModelLLMOptions/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import System from "@/models/system";
import { useState, useEffect } from "react";

export default function SubModelLLMOptions({ settings }) {
return (
<div className="w-full flex flex-col gap-y-7">
<div className="w-full flex items-start gap-[36px] mt-1.5">
<div className="flex flex-col w-60">
<label className="text-theme-text-primary text-sm font-semibold block mb-3">
SubModel Instagen Access Key
</label>
<input
type="password"
name="SubModelLLMAccessKey"
className="border-none bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
placeholder="SubModel Instagen Access Key"
defaultValue={settings?.SubModelLLMAccessKey ? "*".repeat(20) : ""}
required={true}
autoComplete="off"
spellCheck={false}
/>
</div>
{!settings?.credentialsOnly && (
<SubModelModelSelection settings={settings} />
)}
</div>
</div>
);
}

function SubModelModelSelection({ settings }) {
const [groupedModels, setGroupedModels] = useState({});
const [loading, setLoading] = useState(true);
const [selectedModelId, setSelectedModelId] = useState(settings?.SubModelModelPref);

useEffect(() => {
async function fetchModels() {
setLoading(true);
const { models } = await System.customModels("submodel");
if (models?.length > 0) {
const modelsByOrganization = models.reduce((acc, model) => {
acc[model.organization] = acc[model.organization] || [];
acc[model.organization].push(model);
return acc;
}, {});
setGroupedModels(modelsByOrganization);
}
setLoading(false);
}
fetchModels();
}, []);

// Update selected model when settings change
useEffect(() => {
setSelectedModelId(settings?.SubModelModelPref);
}, [settings?.SubModelModelPref]);

if (loading || Object.keys(groupedModels).length === 0) {
return (
<div className="flex flex-col w-60">
<label className="text-theme-text-primary text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select
name="SubModelModelPref"
required={true}
disabled={true}
className="bg-theme-settings-input-bg text-theme-text-primary text-sm rounded-lg focus:ring-primary-button focus:border-primary-button block w-full p-2.5"
>
<option disabled={true} selected={true}>
-- loading available models --
</option>
</select>
</div>
);
}

return (
<div className="flex flex-col">
<label className="text-theme-text-primary text-sm font-semibold block mb-3">
Chat Model Selection
</label>
<select
name="SubModelModelPref"
required={true}
value={selectedModelId || ""}
onChange={(e) => setSelectedModelId(e.target.value)}
className="border-none bg-theme-settings-input-bg text-theme-text-primary border-theme-border text-sm rounded-lg block w-full p-2.5"
>
{Object.keys(groupedModels)
.sort()
.map((organization) => (
<optgroup key={organization} label={organization}>
{groupedModels[organization].map((model) => (
<option
key={model.id}
value={model.id}
>
{model.name}
</option>
))}
</optgroup>
))}
</select>

<FreeQuotaInfo
groupedModels={groupedModels}
selectedModelId={selectedModelId}
/>

</div>
);
}

function FreeQuotaInfo({ groupedModels, selectedModelId }) {
// Find the currently selected model
const selectedModel = Object.values(groupedModels)
.flat()
.find(model => model.id === selectedModelId);

// Only show models with free_quota structure
if (!selectedModel?.free_quota) {
return null;
}

return (
<div className="mt-4 p-4 bg-theme-bg-secondary rounded-lg border border-theme-modal-border">
<div className="flex items-center gap-x-2 mb-3">
<div className="w-2 h-2 bg-green-500 rounded-full"></div>
<h4 className="text-theme-text-primary text-xs font-semibold">
Free Quota Available
</h4>
</div>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-theme-text-secondary text-xs">
Daily Tokens:
</span>
<span className="text-theme-text-primary text-xs font-medium">
{selectedModel.free_quota.day_token?.toLocaleString() || 'N/A'}
</span>
</div>
<div className="flex justify-between items-center">
<span className="text-theme-text-secondary text-xs">
Daily Requests:
</span>
<span className="text-theme-text-primary text-xs font-medium">
{selectedModel.free_quota.day_request?.toLocaleString() || 'N/A'}
</span>
</div>
</div>
</div>
);
}
1 change: 1 addition & 0 deletions frontend/src/hooks/useGetProvidersModels.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const groupedProviders = [
"novita",
"openrouter",
"ppio",
"submodel",
];
export default function useGetProviderModels(provider = null) {
const [defaultModels, setDefaultModels] = useState([]);
Expand Down
Binary file added frontend/src/media/llmprovider/submodel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions frontend/src/pages/GeneralSettings/LLMPreference/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import APIPieLogo from "@/media/llmprovider/apipie.png";
import XAILogo from "@/media/llmprovider/xai.png";
import NvidiaNimLogo from "@/media/llmprovider/nvidia-nim.png";
import PPIOLogo from "@/media/llmprovider/ppio.png";
import SubModelLogo from "@/media/llmprovider/submodel.png";
import DellProAiStudioLogo from "@/media/llmprovider/dpais.png";
import MoonshotAiLogo from "@/media/llmprovider/moonshotai.png";
import CometApiLogo from "@/media/llmprovider/cometapi.png";
Expand Down Expand Up @@ -63,6 +64,7 @@ import ApiPieLLMOptions from "@/components/LLMSelection/ApiPieOptions";
import XAILLMOptions from "@/components/LLMSelection/XAiLLMOptions";
import NvidiaNimOptions from "@/components/LLMSelection/NvidiaNimOptions";
import PPIOLLMOptions from "@/components/LLMSelection/PPIOLLMOptions";
import SubModelLLMOptions from "@/components/LLMSelection/SubModelLLMOptions";
import DellProAiStudioOptions from "@/components/LLMSelection/DPAISOptions";
import MoonshotAiOptions from "@/components/LLMSelection/MoonshotAiOptions";

Expand Down Expand Up @@ -335,6 +337,14 @@ export const AVAILABLE_LLM_PROVIDERS = [
"GenericOpenAiKey",
],
},
{
name: "SubModel",
value: "submodel",
logo: SubModelLogo,
options: (settings) => <SubModelLLMOptions settings={settings} />,
description: "Powerful AI Cloud for Startups.",
requiredConfig: ["SubModelLLMAccessKey"],
},
];

export default function GeneralLLMPreference() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import QDrantLogo from "@/media/vectordbs/qdrant.png";
import MilvusLogo from "@/media/vectordbs/milvus.png";
import VoyageAiLogo from "@/media/embeddingprovider/voyageai.png";
import PPIOLogo from "@/media/llmprovider/ppio.png";
import SubModelLogo from "@/media/llmprovider/submodel.png";
import PGVectorLogo from "@/media/vectordbs/pgvector.png";
import DPAISLogo from "@/media/llmprovider/dpais.png";
import MoonshotAiLogo from "@/media/llmprovider/moonshotai.png";
Expand Down Expand Up @@ -261,6 +262,14 @@ export const LLM_SELECTION_PRIVACY = {
],
logo: CometApiLogo,
},
submodel: {
name: "SubModel",
description: [
"Your chats will not be used for training",
"Your prompts and document text used in response creation are visible to SubModel",
],
logo: SubModelLogo,
},
};

export const VECTOR_DB_PRIVACY = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import XAILogo from "@/media/llmprovider/xai.png";
import NvidiaNimLogo from "@/media/llmprovider/nvidia-nim.png";
import CohereLogo from "@/media/llmprovider/cohere.png";
import PPIOLogo from "@/media/llmprovider/ppio.png";
import SubModelLogo from "@/media/llmprovider/submodel.png";
import DellProAiStudioLogo from "@/media/llmprovider/dpais.png";
import MoonshotAiLogo from "@/media/llmprovider/moonshotai.png";
import CometApiLogo from "@/media/llmprovider/cometapi.png";
Expand Down Expand Up @@ -56,6 +57,7 @@ import NovitaLLMOptions from "@/components/LLMSelection/NovitaLLMOptions";
import XAILLMOptions from "@/components/LLMSelection/XAiLLMOptions";
import NvidiaNimOptions from "@/components/LLMSelection/NvidiaNimOptions";
import PPIOLLMOptions from "@/components/LLMSelection/PPIOLLMOptions";
import SubModelLLMOptions from "@/components/LLMSelection/SubModelLLMOptions";
import DellProAiStudioOptions from "@/components/LLMSelection/DPAISOptions";
import MoonshotAiOptions from "@/components/LLMSelection/MoonshotAiOptions";
import CometApiLLMOptions from "@/components/LLMSelection/CometApiLLMOptions";
Expand Down Expand Up @@ -281,6 +283,13 @@ const LLMS = [
options: (settings) => <CometApiLLMOptions settings={settings} />,
description: "500+ AI Models all in one API.",
},
{
name: "SubModel",
value: "submodel",
logo: SubModelLogo,
options: (settings) => <SubModelLLMOptions settings={settings} />,
description: "Powerful AI Cloud for Startups.",
},
];

export default function LLMPreference({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const ENABLED_PROVIDERS = [
"gemini",
"moonshotai",
"cometapi",
"submodel",
// TODO: More agent support.
// "cohere", // Has tool calling and will need to build explicit support
// "huggingface" // Can be done but already has issues with no-chat templated. Needs to be tested.
Expand Down
1 change: 1 addition & 0 deletions locales/README.fa-IR.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ AnythingLLM Ψ§Ψ³Ω†Ψ§Ψ― Ψ΄Ω…Ψ§ Ψ±Ψ§ Ψ¨Ω‡ اشیایی Ψ¨Ω‡ Ω†Ψ§Ω… `workspaces` Ψͺ
- [xAI](https://x.ai/)
- [Novita AI (chat models)](https://novita.ai/model-api/product/llm-api?utm_source=github_anything-llm&utm_medium=github_readme&utm_campaign=link)
- [PPIO](https://ppinfra.com?utm_source=github_anything-llm)
- [SubModel](https://submodel.ai)

<div dir="rtl">

Expand Down
1 change: 1 addition & 0 deletions locales/README.ja-JP.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ AnythingLLMは、ドキγƒ₯γƒ‘γƒ³γƒˆγ‚’`γƒ―γƒΌγ‚―γ‚ΉγƒšγƒΌγ‚Ή`γ¨ε‘Όγ°γ‚Œγ‚‹γ‚ͺ
- [KoboldCPP](https://github.com/LostRuins/koboldcpp)
- [PPIO](https://ppinfra.com?utm_source=github_anything-llm)
- [CometAPI (γƒγƒ£γƒƒγƒˆγƒ’γƒ‡γƒ«)](https://api.cometapi.com/)
- [SubModel](https://submodel.ai)

**εŸ‹γ‚θΎΌγΏγƒ’γƒ‡γƒ«οΌš**

Expand Down
1 change: 1 addition & 0 deletions locales/README.tr-TR.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ AnythingLLM, belgelerinizi **"çalışma alanları" (workspaces)** adı verilen
- [xAI](https://x.ai/)
- [Novita AI (chat models)](https://novita.ai/model-api/product/llm-api?utm_source=github_anything-llm&utm_medium=github_readme&utm_campaign=link)
- [PPIO](https://ppinfra.com?utm_source=github_anything-llm)
- [SubModel](https://submodel.ai)

**Embedder modelleri:**

Expand Down
1 change: 1 addition & 0 deletions locales/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ AnythingLLMε°†ζ‚¨ηš„ζ–‡ζ‘£εˆ’εˆ†δΈΊη§°δΈΊ`workspaces` (ε·₯作区)ηš„ε―Ήθ±‘γ€‚ε·₯
- [Novita AI (θŠε€©ζ¨‘εž‹)](https://novita.ai/model-api/product/llm-api?utm_source=github_anything-llm&utm_medium=github_readme&utm_campaign=link)
- [PPIO (θŠε€©ζ¨‘εž‹)](https://ppinfra.com?utm_source=github_anything-llm)
- [CometAPI (θŠε€©ζ¨‘εž‹)](https://api.cometapi.com/)
- [SubModel](https://submodel.ai)

**ζ”―ζŒηš„ε΅Œε…₯ζ¨‘εž‹οΌš**

Expand Down
4 changes: 4 additions & 0 deletions server/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ SIG_SALT='salt' # Please generate random string at least 32 chars long.
# MOONSHOT_AI_API_KEY='your-moonshot-api-key-here'
# MOONSHOT_AI_MODEL_PREF='moonshot-v1-32k'

# LLM_PROVIDER='submodel'
# SUBMODEL_INSTAGEN_ACCESS_KEY='your-submodel-instagen-access-key-here'
# SUBMODEL_MODEL_PREF=deepseek-ai/DeepSeek-V3-0324

###########################################
######## Embedding API SElECTION ##########
###########################################
Expand Down
3 changes: 3 additions & 0 deletions server/endpoints/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ function getModelTag() {
case "moonshotai":
model = process.env.MOONSHOT_AI_MODEL_PREF;
break;
case "submodel":
model = process.env.SUBMODEL_MODEL_PREF;
break;
default:
model = "--";
break;
Expand Down
4 changes: 4 additions & 0 deletions server/models/systemSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,10 @@ const SystemSettings = {
CometApiLLMApiKey: !!process.env.COMETAPI_LLM_API_KEY,
CometApiLLMModelPref: process.env.COMETAPI_LLM_MODEL_PREF,
CometApiLLMTimeout: process.env.COMETAPI_LLM_TIMEOUT_MS,

// SubModel InstaGen Access keys
SubModelLLMAccessKey: !!process.env.SUBMODEL_INSTAGEN_ACCESS_KEY,
SubModelModelPref: process.env.SUBMODEL_MODEL_PREF,
};
},

Expand Down
Loading