From 4e2c0f04b4cce4d7618145658292dcd35862c038 Mon Sep 17 00:00:00 2001 From: Timothy Carambat Date: Wed, 10 Jan 2024 13:18:48 -0800 Subject: [PATCH] Dynamic vector count on workspace settings (#567) * Dynamic vector count on workspace settings Add count to be workspace specific, fallback to system count Update layout of data in settings Update OpenAI per-token embedding price * linting --- .../Modals/MangeWorkspace/Documents/index.jsx | 4 +- .../Modals/MangeWorkspace/Settings/index.jsx | 76 +++++++++++-------- .../Modals/MangeWorkspace/index.jsx | 5 +- frontend/src/models/system.js | 6 +- server/endpoints/invite.js | 4 +- server/endpoints/system.js | 26 ++++--- 6 files changed, 76 insertions(+), 45 deletions(-) diff --git a/frontend/src/components/Modals/MangeWorkspace/Documents/index.jsx b/frontend/src/components/Modals/MangeWorkspace/Documents/index.jsx index 52b818ff..ff7f0dd6 100644 --- a/frontend/src/components/Modals/MangeWorkspace/Documents/index.jsx +++ b/frontend/src/components/Modals/MangeWorkspace/Documents/index.jsx @@ -6,7 +6,9 @@ import Directory from "./Directory"; import showToast from "../../../../utils/toast"; import WorkspaceDirectory from "./WorkspaceDirectory"; -const COST_PER_TOKEN = 0.0004; +// OpenAI Cost per token for text-ada-embedding +// ref: https://openai.com/pricing#:~:text=%C2%A0/%201K%20tokens-,Embedding%20models,-Build%20advanced%20search +const COST_PER_TOKEN = 0.0000001; // $0.0001 / 1K tokens export default function DocumentSettings({ workspace, diff --git a/frontend/src/components/Modals/MangeWorkspace/Settings/index.jsx b/frontend/src/components/Modals/MangeWorkspace/Settings/index.jsx index 29d2bfa7..2fce91e1 100644 --- a/frontend/src/components/Modals/MangeWorkspace/Settings/index.jsx +++ b/frontend/src/components/Modals/MangeWorkspace/Settings/index.jsx @@ -26,24 +26,11 @@ function castToType(key, value) { return definitions[key].cast(value); } -export default function WorkspaceSettings({ workspace }) { +export default function WorkspaceSettings({ active, workspace }) { const { slug } = useParams(); const formEl = useRef(null); const [saving, setSaving] = useState(false); const [hasChanges, setHasChanges] = useState(false); - const [totalVectors, setTotalVectors] = useState(null); - const [canDelete, setCanDelete] = useState(false); - - useEffect(() => { - async function fetchKeys() { - const canDelete = await System.getCanDeleteWorkspaces(); - setCanDelete(canDelete); - - const totalVectors = await System.totalIndexes(); - setTotalVectors(totalVectors); - } - fetchKeys(); - }, []); const handleUpdate = async (e) => { setSaving(true); @@ -89,6 +76,9 @@ export default function WorkspaceSettings({ workspace }) {

Vector database identifier

+

+ {" "} +

{workspace?.slug}

@@ -101,13 +91,7 @@ export default function WorkspaceSettings({ workspace }) {

Total number of vectors in your vector database.

- {totalVectors !== null ? ( -

- {totalVectors} -

- ) : ( - - )} + @@ -275,15 +259,7 @@ export default function WorkspaceSettings({ workspace }) {
- {canDelete && ( - - )} + {hasChanges && ( + ); +} + +function VectorCount({ reload, workspace }) { + const [totalVectors, setTotalVectors] = useState(null); + useEffect(() => { + async function fetchVectorCount() { + const totalVectors = await System.totalIndexes(workspace.slug); + setTotalVectors(totalVectors); + } + fetchVectorCount(); + }, [workspace?.slug, reload]); + + if (totalVectors === null) return ; + return ( +

+ {totalVectors} +

+ ); +} diff --git a/frontend/src/components/Modals/MangeWorkspace/index.jsx b/frontend/src/components/Modals/MangeWorkspace/index.jsx index 946e96d2..9092d0d5 100644 --- a/frontend/src/components/Modals/MangeWorkspace/index.jsx +++ b/frontend/src/components/Modals/MangeWorkspace/index.jsx @@ -114,7 +114,10 @@ const ManageWorkspace = ({ hideModal = noop, providedSlug = null }) => { />
- +
diff --git a/frontend/src/models/system.js b/frontend/src/models/system.js index 9b71a605..c64ac66a 100644 --- a/frontend/src/models/system.js +++ b/frontend/src/models/system.js @@ -9,8 +9,10 @@ const System = { .then((res) => res?.online || false) .catch(() => false); }, - totalIndexes: async function () { - return await fetch(`${API_BASE}/system/system-vectors`, { + totalIndexes: async function (slug = null) { + const url = new URL(`${API_BASE}/system/system-vectors`); + if (!!slug) url.searchParams.append("slug", encodeURIComponent(slug)); + return await fetch(url.toString(), { headers: baseHeaders(), }) .then((res) => { diff --git a/server/endpoints/invite.js b/server/endpoints/invite.js index c5c34451..4fd8d154 100644 --- a/server/endpoints/invite.js +++ b/server/endpoints/invite.js @@ -42,11 +42,11 @@ function inviteEndpoints(app) { return; } - const { user, error } = await User.create(({ + const { user, error } = await User.create({ username, password, role: "default", - })); + }); if (!user) { console.error("Accepting invite:", error); response diff --git a/server/endpoints/system.js b/server/endpoints/system.js index 982d5eca..a6acf47e 100644 --- a/server/endpoints/system.js +++ b/server/endpoints/system.js @@ -15,6 +15,7 @@ const { makeJWT, userFromSession, multiUserMode, + queryParams, } = require("../utils/http"); const { setupDataImports, @@ -180,16 +181,23 @@ function systemEndpoints(app) { } }); - app.get("/system/system-vectors", [validatedRequest], async (_, response) => { - try { - const VectorDb = getVectorDbClass(); - const vectorCount = await VectorDb.totalVectors(); - response.status(200).json({ vectorCount }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); + app.get( + "/system/system-vectors", + [validatedRequest], + async (request, response) => { + try { + const query = queryParams(request); + const VectorDb = getVectorDbClass(); + const vectorCount = !!query.slug + ? await VectorDb.namespaceCount(query.slug) + : await VectorDb.totalVectors(); + response.status(200).json({ vectorCount }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); + } } - }); + ); app.delete( "/system/remove-document",