From 6d625800b5f3e0dc24fa4a354e530b8b3a7e9aa3 Mon Sep 17 00:00:00 2001 From: Max-Reisinger <84220930+Max-Reisinger@users.noreply.github.com> Date: Wed, 26 Aug 2026 01:17:00 +0800 Subject: [PATCH] feat(localai): support multiple concurrent connections --- .../LocalAiConnectionSelector/index.jsx | 43 +++++ .../LLMSelection/LocalAiOptions/index.jsx | 159 ++++++++++++++++ .../LLMSelector/ChatModelSelection/index.jsx | 3 +- .../PromptInput/LLMSelector/index.jsx | 36 +++- frontend/src/hooks/useGetProvidersModels.js | 13 +- frontend/src/models/localAiConnection.js | 52 +++++ .../LLMProviderModelPicker/index.jsx | 33 +++- .../ModelRouters/NewRouterModal/index.jsx | 3 + .../RuleBuilder/RuleForm/index.jsx | 3 + .../ChatModelSelection/index.jsx | 3 +- .../WorkspaceLLMSelection/index.jsx | 40 ++++ server/__tests__/localAiConnection.test.js | 102 ++++++++++ server/__tests__/models/workspace.test.js | 14 ++ .../AiProviders/localAi/connections.test.js | 49 +++++ server/endpoints/localAiConnections.js | 71 +++++++ server/index.js | 4 + server/models/localAiConnection.js | 180 ++++++++++++++++++ server/models/modelRouter.js | 30 +++ server/models/modelRouterRule.js | 26 +++ server/models/workspace.js | 38 +++- .../20260826000000_init/migration.sql | 19 ++ server/prisma/schema.prisma | 67 ++++--- server/utils/AiProviders/localAi/index.js | 17 +- server/utils/AiProviders/modelRouter/index.js | 32 +++- server/utils/agents/aibitat/index.js | 6 +- .../aibitat/plugins/router-classifier.js | 13 ++ .../utils/agents/aibitat/providers/localai.js | 6 +- server/utils/agents/ephemeral.js | 16 +- server/utils/agents/index.js | 24 ++- server/utils/helpers/index.js | 18 +- server/utils/router/index.js | 1 + 31 files changed, 1054 insertions(+), 67 deletions(-) create mode 100644 frontend/src/components/LLMSelection/LocalAiConnectionSelector/index.jsx create mode 100644 frontend/src/models/localAiConnection.js create mode 100644 server/__tests__/localAiConnection.test.js create mode 100644 server/__tests__/utils/AiProviders/localAi/connections.test.js create mode 100644 server/endpoints/localAiConnections.js create mode 100644 server/models/localAiConnection.js create mode 100644 server/prisma/migrations/20260826000000_init/migration.sql diff --git a/frontend/src/components/LLMSelection/LocalAiConnectionSelector/index.jsx b/frontend/src/components/LLMSelection/LocalAiConnectionSelector/index.jsx new file mode 100644 index 00000000000..af07b6492ad --- /dev/null +++ b/frontend/src/components/LLMSelection/LocalAiConnectionSelector/index.jsx @@ -0,0 +1,43 @@ +import { useEffect, useState } from "react"; +import LocalAiConnection from "@/models/localAiConnection"; + +export default function LocalAiConnectionSelector({ + name = "chatConnectionId", + value = "", + onChange, + onConnectionChange, + required = false, + className = "border-none bg-theme-settings-input-bg text-white text-sm rounded-lg block w-full p-2.5", +}) { + const [connections, setConnections] = useState([]); + + useEffect(() => { + LocalAiConnection.all().then(setConnections); + }, []); + + function handleChange(event) { + const nextValue = event.target.value; + onChange?.(nextValue); + onConnectionChange?.( + connections.find((connection) => String(connection.id) === nextValue) || + null + ); + } + + return ( + + ); +} diff --git a/frontend/src/components/LLMSelection/LocalAiOptions/index.jsx b/frontend/src/components/LLMSelection/LocalAiOptions/index.jsx index 96e1048db5b..3d50cd20b0f 100644 --- a/frontend/src/components/LLMSelection/LocalAiOptions/index.jsx +++ b/frontend/src/components/LLMSelection/LocalAiOptions/index.jsx @@ -5,6 +5,8 @@ import System from "@/models/system"; import PreLoader from "@/components/Preloader"; import { LOCALAI_COMMON_URLS } from "@/utils/constants"; import useProviderEndpointAutoDiscovery from "@/hooks/useProviderEndpointAutoDiscovery"; +import LocalAiConnection from "@/models/localAiConnection"; +import showToast from "@/utils/toast"; export default function LocalAiOptions({ settings, showAlert = false }) { const { @@ -24,6 +26,7 @@ export default function LocalAiOptions({ settings, showAlert = false }) { return (
Saved connections
++ Workspaces and model routers can use these LocalAI endpoints + concurrently. +
++ Choose a saved connection or use the system LocalAI settings. +
+