diff --git a/.github/workflows/dev-build.yaml b/.github/workflows/dev-build.yaml
index 18873afe4..e699a630f 100644
--- a/.github/workflows/dev-build.yaml
+++ b/.github/workflows/dev-build.yaml
@@ -6,7 +6,7 @@ concurrency:
on:
push:
- branches: ['3982-disable-login-simple-sso'] # put your current branch to create a build. Core team only.
+ branches: ['4034-version-control'] # put your current branch to create a build. Core team only.
paths-ignore:
- '**.md'
- 'cloud-deployments/*'
diff --git a/collector/package.json b/collector/package.json
index 628501e7f..19c29848b 100644
--- a/collector/package.json
+++ b/collector/package.json
@@ -1,6 +1,6 @@
{
"name": "anything-llm-document-collector",
- "version": "0.2.0",
+ "version": "1.8.2",
"description": "Document collector server endpoints",
"main": "index.js",
"author": "Timothy Carambat (Mintplex Labs)",
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 221d2e400..f9ffbd55e 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -169,6 +169,7 @@ USER anythingllm
# Setup the environment
ENV NODE_ENV=production
ENV ANYTHING_LLM_RUNTIME=docker
+ENV DEPLOYMENT_VERSION=1.8.2
# Setup the healthcheck
HEALTHCHECK --interval=1m --timeout=10s --start-period=1m \
diff --git a/frontend/src/components/SettingsSidebar/index.jsx b/frontend/src/components/SettingsSidebar/index.jsx
index 03d39d463..ad7024110 100644
--- a/frontend/src/components/SettingsSidebar/index.jsx
+++ b/frontend/src/components/SettingsSidebar/index.jsx
@@ -22,6 +22,7 @@ import showToast from "@/utils/toast";
import System from "@/models/system";
import Option from "./MenuOption";
import { CanViewChatHistoryProvider } from "../CanViewChatHistory";
+import useAppVersion from "@/hooks/useAppVersion";
export default function SettingsSidebar() {
const { t } = useTranslation();
@@ -119,6 +120,7 @@ export default function SettingsSidebar() {
>
{t("settings.privacy")}
+
@@ -169,6 +171,7 @@ export default function SettingsSidebar() {
>
{t("settings.privacy")}
+
@@ -451,3 +454,18 @@ function HoldToReveal({ children, holdForMs = 3_000 }) {
if (!showing) return null;
return children;
}
+
+function AppVersion() {
+ const { version, isLoading } = useAppVersion();
+ if (isLoading) return null;
+ return (
+
+ v{version}
+
+ );
+}
diff --git a/frontend/src/hooks/useAppVersion.js b/frontend/src/hooks/useAppVersion.js
new file mode 100644
index 000000000..e0cbb28b8
--- /dev/null
+++ b/frontend/src/hooks/useAppVersion.js
@@ -0,0 +1,20 @@
+import { useEffect, useState } from "react";
+import System from "../models/system";
+
+/**
+ * Hook to fetch the app version.
+ * @returns {Object} The app version.
+ * @returns {string | null} version - The app version.
+ * @returns {boolean} isLoading - Whether the app version is loading.
+ */
+export default function useAppVersion() {
+ const [version, setVersion] = useState(null);
+ const [isLoading, setIsLoading] = useState(true);
+
+ useEffect(() => {
+ System.fetchAppVersion()
+ .then(setVersion)
+ .finally(() => setIsLoading(false));
+ }, []);
+ return { version, isLoading };
+}
diff --git a/frontend/src/models/system.js b/frontend/src/models/system.js
index ddb9d8209..6dd30a6b5 100644
--- a/frontend/src/models/system.js
+++ b/frontend/src/models/system.js
@@ -11,6 +11,7 @@ const System = {
supportEmail: "anythingllm_support_email",
customAppName: "anythingllm_custom_app_name",
canViewChatHistory: "anythingllm_can_view_chat_history",
+ deploymentVersion: "anythingllm_deployment_version",
},
ping: async function () {
return await fetch(`${API_BASE}/ping`)
@@ -742,6 +743,36 @@ const System = {
});
},
+ /**
+ * Fetches the app version from the server.
+ * @returns {Promise} The app version.
+ */
+ fetchAppVersion: async function () {
+ const cache = window.localStorage.getItem(this.cacheKeys.deploymentVersion);
+ const { version, lastFetched } = cache
+ ? safeJsonParse(cache, { version: null, lastFetched: 0 })
+ : { version: null, lastFetched: 0 };
+
+ if (!!version && Date.now() - lastFetched < 3_600_000) return version;
+ const newVersion = await fetch(`${API_BASE}/utils/metrics`, {
+ method: "GET",
+ cache: "no-cache",
+ })
+ .then((res) => {
+ if (!res.ok) throw new Error("Could not fetch app version.");
+ return res.json();
+ })
+ .then((res) => res?.version)
+ .catch(() => null);
+
+ if (!newVersion) return null;
+ window.localStorage.setItem(
+ this.cacheKeys.deploymentVersion,
+ JSON.stringify({ version: newVersion, lastFetched: Date.now() })
+ );
+ return newVersion;
+ },
+
experimentalFeatures: {
liveSync: LiveDocumentSync,
agentPlugins: AgentPlugins,
diff --git a/package.json b/package.json
index e9f50319f..b4ce57f3b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "anything-llm",
- "version": "0.2.0",
+ "version": "1.8.2",
"description": "The best solution for turning private documents into a chat bot using off-the-shelf tools and commercially viable AI technologies.",
"main": "index.js",
"type": "module",
diff --git a/server/endpoints/utils.js b/server/endpoints/utils.js
index 399d8cf5f..cf4183251 100644
--- a/server/endpoints/utils.js
+++ b/server/endpoints/utils.js
@@ -13,6 +13,7 @@ function utilEndpoints(app) {
: "single-user",
vectorDB: process.env.VECTOR_DB || "lancedb",
storage: await getDiskStorage(),
+ version: getDeploymentVersion(),
};
response.status(200).json(metrics);
} catch (e) {
@@ -148,6 +149,20 @@ function getModelTag() {
return model;
}
+/**
+ * Returns the deployment version.
+ * - Dev: reads from package.json
+ * - Prod: reads from ENV
+ * expected format: major.minor.patch
+ * @returns {string|null} The deployment version.
+ */
+function getDeploymentVersion() {
+ if (process.env.NODE_ENV === "development")
+ return require("../../package.json").version;
+ if (process.env.DEPLOYMENT_VERSION) return process.env.DEPLOYMENT_VERSION;
+ return null;
+}
+
module.exports = {
utilEndpoints,
getGitVersion,
diff --git a/server/package.json b/server/package.json
index f226239d8..7fb19a9bb 100644
--- a/server/package.json
+++ b/server/package.json
@@ -1,6 +1,6 @@
{
"name": "anything-llm-server",
- "version": "0.2.0",
+ "version": "1.8.2",
"description": "Server endpoints to process or create content for chatting",
"main": "index.js",
"author": "Timothy Carambat (Mintplex Labs)",