Opt-in network discover

This commit is contained in:
timothycarambat
2024-08-27 15:58:14 -07:00
parent c60dda92d0
commit 9bfe477f10
7 changed files with 118 additions and 116 deletions

View File

@@ -135,16 +135,20 @@ app.all("*", function (_, response) {
});
app
.listen(process.env.COLLECTOR_PORT || 8888, async () => {
await wipeCollectorStorage();
console.log(
`[${
process.env.NODE_ENV || "development"
}] AnythingLLM Standalone Document processor listening on port ${
process.env.COLLECTOR_PORT || 8888
}`
);
})
.listen(
process.env.COLLECTOR_PORT || 8888,
"127.0.0.1", // Network discovery of document collector is always off.
async () => {
await wipeCollectorStorage();
console.log(
`[${
process.env.NODE_ENV || "development"
}] AnythingLLM Standalone Document processor listening on port ${
process.env.COLLECTOR_PORT || 8888
}.`
);
}
)
.on("error", function (_) {
process.once("SIGUSR2", function () {
process.kill(process.pid, "SIGUSR2");

View File

@@ -19,6 +19,7 @@ import Login from "./pages/Login";
import Main from "./pages/Main";
import WorkspaceChat from "./pages/WorkspaceChat";
import GeneralApiKeys from "./pages/GeneralSettings/ApiKeys";
import GeneralSettings from "@/pages/Admin/System";
import GeneralChats from "./pages/GeneralSettings/Chats";
import GeneralAppearance from "./pages/GeneralSettings/Appearance";
import GeneralLLMPreference from "./pages/GeneralSettings/LLMPreference";
@@ -111,6 +112,10 @@ export default function App() {
path="/settings/api-keys"
element={<ManagerRoute Component={GeneralApiKeys} />}
/>
<Route
path="/settings/system-preferences"
element={<ManagerRoute Component={GeneralSettings} />}
/>
<Route
path="/settings/workspace-chats"
element={<ManagerRoute Component={GeneralChats} />}

View File

@@ -138,6 +138,12 @@ const SidebarOptions = ({ user = null, t }) => (
icon={<UserCircleGear className="h-5 w-5 flex-shrink-0" />}
user={user}
childOptions={[
{
btnText: t("settings.system"),
href: paths.settings.system(),
flex: true,
roles: ["admin", "manager"],
},
{
btnText: t("settings.workspace-chats"),
href: paths.settings.chats(),

View File

@@ -1,23 +1,22 @@
import { useEffect, useState } from "react";
import Sidebar from "@/components/SettingsSidebar";
import Admin from "@/models/admin";
import showToast from "@/utils/toast";
import CTAButton from "@/components/lib/CTAButton";
import System from "@/models/system";
export default function AdminSystem() {
const [saving, setSaving] = useState(false);
const [hasChanges, setHasChanges] = useState(false);
const [messageLimit, setMessageLimit] = useState({
enabled: false,
limit: 10,
const [settings, setSettings] = useState({
loading: false,
NetworkDiscovery: false,
});
const handleSubmit = async (e) => {
e.preventDefault();
setSaving(true);
await Admin.updateSystemPreferences({
limit_user_messages: messageLimit.enabled,
message_limit: messageLimit.limit,
await System.updateSystem({
NetworkDiscovery: String(settings.NetworkDiscovery),
});
setSaving(false);
setHasChanges(false);
@@ -26,103 +25,81 @@ export default function AdminSystem() {
useEffect(() => {
async function fetchSettings() {
const settings = (await Admin.systemPreferences())?.settings;
const settings = await System.keys();
if (!settings) return;
setMessageLimit({
enabled: settings.limit_user_messages,
limit: settings.message_limit,
setSettings({
loading: false,
NetworkDiscovery: settings.NetworkDiscovery === "true",
});
}
fetchSettings();
}, []);
return (
<div className="w-screen h-screen overflow-hidden bg-sidebar flex">
<div
style={{ height: "calc(100vh - 40px)" }}
className="w-screen overflow-hidden bg-sidebar flex"
>
<Sidebar />
<div
style={{ height: "calc(100vh - 32px)" }}
className="relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full h-full overflow-y-scroll border-2 border-outline"
<form
onSubmit={handleSubmit}
onChange={() => setHasChanges(true)}
className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16"
>
<form
onSubmit={handleSubmit}
onChange={() => setHasChanges(true)}
className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16"
>
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
<div className="items-center">
<p className="text-lg leading-6 font-bold text-white">
System Preferences
</p>
</div>
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
These are the overall settings and configurations of your
instance.
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
<div className="items-center">
<p className="text-lg leading-6 font-bold text-white">
Application Preferences
</p>
</div>
{hasChanges && (
<div className="flex justify-end">
<CTAButton onClick={handleSubmit} className="mt-3 mr-0">
{saving ? "Saving..." : "Save changes"}
</CTAButton>
</div>
)}
<div className="mt-4 mb-8">
<div className="flex flex-col gap-y-1">
<h2 className="text-base leading-6 font-bold text-white">
Limit messages per user per day
</h2>
<p className="text-xs leading-[18px] font-base text-white/60">
Restrict non-admin users to a number of successful queries or
chats within a 24 hour window. Enable this to prevent users from
running up OpenAI costs.
</p>
<div className="mt-2">
<label className="relative inline-flex cursor-pointer items-center">
<input
type="checkbox"
name="limit_user_messages"
value="yes"
checked={messageLimit.enabled}
onChange={(e) => {
setMessageLimit({
...messageLimit,
enabled: e.target.checked,
});
}}
className="peer sr-only"
/>
<div className="pointer-events-none peer h-6 w-11 rounded-full bg-stone-400 after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:shadow-xl after:border after:border-gray-600 after:bg-white after:box-shadow-md after:transition-all after:content-[''] peer-checked:bg-lime-300 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800"></div>
<span className="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300"></span>
</label>
</div>
</div>
{messageLimit.enabled && (
<div className="mt-4">
<label className="text-white text-sm font-semibold block mb-4">
Message limit per day
</label>
<div className="relative mt-2">
<input
type="number"
name="message_limit"
onScroll={(e) => e.target.blur()}
onChange={(e) => {
setMessageLimit({
enabled: true,
limit: Number(e?.target?.value || 0),
});
}}
value={messageLimit.limit}
min={1}
max={300}
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-60 p-2.5"
/>
</div>
</div>
)}
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
These are the overall settings and configurations of your
AnythingLLM application.
</p>
</div>
{hasChanges && (
<div className="flex justify-end">
<CTAButton onClick={handleSubmit} className="mt-3 mr-0">
{saving ? "Saving..." : "Save changes"}
</CTAButton>
</div>
</form>
</div>
)}
<div className="mt-4 mb-8">
<div className="flex flex-col gap-y-1">
<h2 className="text-base leading-6 font-bold text-white">
Enable network discovery
</h2>
<p className="text-xs leading-[18px] font-base text-white/60">
Enable your AnythingLLM app and its API endpoints to be
discoverable over LAN so other computers or programs on the
network can access it.
<br />
Requires full restart of the app when changed to take effect.
</p>
<div className="mt-2">
<label className="relative inline-flex cursor-pointer items-center">
<input
type="checkbox"
name="NetworkDiscovery"
value="yes"
checked={settings.NetworkDiscovery}
onChange={() => {
setSettings((prev) => {
return {
...prev,
NetworkDiscovery: !prev.NetworkDiscovery,
};
});
}}
className="peer sr-only"
/>
<div className="pointer-events-none peer h-6 w-11 rounded-full bg-stone-400 after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:shadow-xl after:border after:border-gray-600 after:bg-white after:box-shadow-md after:transition-all after:content-[''] peer-checked:bg-lime-300 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800"></div>
<span className="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300"></span>
</label>
</div>
</div>
</div>
</form>
</div>
);
}

View File

@@ -78,20 +78,24 @@ app.all("*", function (_, response) {
});
app
.listen(process.env.SERVER_PORT || 3001, async () => {
await setupTelemetry();
await preloadOllamaService();
new CommunicationKey(true);
new EncryptionManager();
new BackgroundService().boot();
console.log(
`[${
process.env.NODE_ENV || "development"
}] AnythingLLM Standalone Backend listening on port ${
process.env.SERVER_PORT || 3001
}`
);
})
.listen(
process.env.SERVER_PORT || 3001,
process.env.APP_DISCOVERABLE === "true" ? "0.0.0.0" : "127.0.0.1",
async () => {
await setupTelemetry();
await preloadOllamaService();
new CommunicationKey(true);
new EncryptionManager();
new BackgroundService().boot();
console.log(
`[${
process.env.NODE_ENV || "development"
}] AnythingLLM Standalone Backend listening on port ${
process.env.SERVER_PORT || 3001
}. Network discovery is ${process.env.APP_DISCOVERABLE === "true" ? "enabled" : "disabled"}.`
);
}
)
.on("error", function (err) {
process.once("SIGUSR2", function () {
Telemetry.flush();

View File

@@ -167,6 +167,7 @@ const SystemSettings = {
StorageDir: process.env.STORAGE_DIR,
MultiUserMode: await this.isMultiUserMode(),
DisableTelemetry: process.env.DISABLE_TELEMETRY || "false",
NetworkDiscovery: process.env.APP_DISCOVERABLE || "false",
// --------------------------------------------------------
// Embedder Provider Selection Settings & Configs

View File

@@ -422,6 +422,10 @@ const KEY_MAPPING = {
envKey: "DISABLE_TELEMETRY",
checks: [],
},
NetworkDiscovery: {
envKey: "APP_DISCOVERABLE",
checks: [],
},
// Agent Integration ENVs
AgentGoogleSearchEngineId: {
@@ -826,6 +830,7 @@ function dumpENV() {
"STORAGE_DIR",
"SERVER_PORT",
"COLLECTOR_PORT",
"APP_DISCOVERABLE",
// For persistent data encryption
"SIG_KEY",
"SIG_SALT",