From d362fd027e5873271dbb4f50acde1202ee7465d2 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 22 Jun 2024 12:08:32 -0700 Subject: [PATCH] feat: user valves integration --- backend/apps/webui/models/functions.py | 28 ++-- backend/apps/webui/models/tools.py | 28 ++-- backend/apps/webui/routers/functions.py | 7 +- src/lib/apis/functions/index.ts | 99 ++++++++++++ src/lib/apis/tools/index.ts | 99 ++++++++++++ .../components/chat/Settings/Valves.svelte | 151 ++++++++++++++++-- 6 files changed, 375 insertions(+), 37 deletions(-) diff --git a/backend/apps/webui/models/functions.py b/backend/apps/webui/models/functions.py index c1e0dc5dd..cd6320f95 100644 --- a/backend/apps/webui/models/functions.py +++ b/backend/apps/webui/models/functions.py @@ -8,6 +8,8 @@ from apps.webui.internal.db import DB, JSONField from apps.webui.models.users import Users import json +import copy + from config import SRC_LOG_LEVELS @@ -121,14 +123,15 @@ class FunctionsTable: ) -> Optional[dict]: try: user = Users.get_user_by_id(user_id) + user_settings = user.settings.model_dump() # Check if user has "functions" and "valves" settings - if "functions" not in user.settings: - user.settings["functions"] = {} - if "valves" not in user.settings["functions"]: - user.settings["functions"]["valves"] = {} + if "functions" not in user_settings: + user_settings["functions"] = {} + if "valves" not in user_settings["functions"]: + user_settings["functions"]["valves"] = {} - return user.settings["functions"]["valves"].get(id, {}) + return user_settings["functions"]["valves"].get(id, {}) except Exception as e: print(f"An error occurred: {e}") return None @@ -138,20 +141,21 @@ class FunctionsTable: ) -> Optional[dict]: try: user = Users.get_user_by_id(user_id) + user_settings = user.settings.model_dump() # Check if user has "functions" and "valves" settings - if "functions" not in user.settings: - user.settings["functions"] = {} - if "valves" not in user.settings["functions"]: - user.settings["functions"]["valves"] = {} + if "functions" not in user_settings: + user_settings["functions"] = {} + if "valves" not in user_settings["functions"]: + user_settings["functions"]["valves"] = {} - user.settings["functions"]["valves"][id] = valves + user_settings["functions"]["valves"][id] = valves # Update the user settings in the database - query = Users.update_user_by_id(user_id, {"settings": user.settings}) + query = Users.update_user_by_id(user_id, {"settings": user_settings}) query.execute() - return user.settings["functions"]["valves"][id] + return user_settings["functions"]["valves"][id] except Exception as e: print(f"An error occurred: {e}") return None diff --git a/backend/apps/webui/models/tools.py b/backend/apps/webui/models/tools.py index 1592c228f..ab322ac14 100644 --- a/backend/apps/webui/models/tools.py +++ b/backend/apps/webui/models/tools.py @@ -8,6 +8,8 @@ from apps.webui.internal.db import DB, JSONField from apps.webui.models.users import Users import json +import copy + from config import SRC_LOG_LEVELS @@ -112,14 +114,15 @@ class ToolsTable: ) -> Optional[dict]: try: user = Users.get_user_by_id(user_id) + user_settings = user.settings.model_dump() # Check if user has "tools" and "valves" settings - if "tools" not in user.settings: - user.settings["tools"] = {} - if "valves" not in user.settings["tools"]: - user.settings["tools"]["valves"] = {} + if "tools" not in user_settings: + user_settings["tools"] = {} + if "valves" not in user_settings["tools"]: + user_settings["tools"]["valves"] = {} - return user.settings["tools"]["valves"].get(id, {}) + return user_settings["tools"]["valves"].get(id, {}) except Exception as e: print(f"An error occurred: {e}") return None @@ -129,20 +132,21 @@ class ToolsTable: ) -> Optional[dict]: try: user = Users.get_user_by_id(user_id) + user_settings = user.settings.model_dump() # Check if user has "tools" and "valves" settings - if "tools" not in user.settings: - user.settings["tools"] = {} - if "valves" not in user.settings["tools"]: - user.settings["tools"]["valves"] = {} + if "tools" not in user_settings: + user_settings["tools"] = {} + if "valves" not in user_settings["tools"]: + user_settings["tools"]["valves"] = {} - user.settings["tools"]["valves"][id] = valves + user_settings["tools"]["valves"][id] = valves # Update the user settings in the database - query = Users.update_user_by_id(user_id, {"settings": user.settings}) + query = Users.update_user_by_id(user_id, {"settings": user_settings}) query.execute() - return user.settings["tools"]["valves"][id] + return user_settings["tools"]["valves"][id] except Exception as e: print(f"An error occurred: {e}") return None diff --git a/backend/apps/webui/routers/functions.py b/backend/apps/webui/routers/functions.py index 53b9ab130..acf1894fd 100644 --- a/backend/apps/webui/routers/functions.py +++ b/backend/apps/webui/routers/functions.py @@ -145,7 +145,7 @@ async def get_function_user_valves_by_id(id: str, user=Depends(get_verified_user async def get_function_user_valves_spec_by_id( request: Request, id: str, user=Depends(get_verified_user) ): - function = Functions.get_tool_by_id(id) + function = Functions.get_function_by_id(id) if function: if id in request.app.state.FUNCTIONS: function_module = request.app.state.FUNCTIONS[id] @@ -168,8 +168,7 @@ async def get_function_user_valves_spec_by_id( async def update_function_user_valves_by_id( request: Request, id: str, form_data: dict, user=Depends(get_verified_user) ): - - function = Functions.get_tool_by_id(id) + function = Functions.get_function_by_id(id) if function: if id in request.app.state.FUNCTIONS: @@ -211,7 +210,7 @@ async def update_function_user_valves_by_id( @router.post("/id/{id}/update", response_model=Optional[FunctionModel]) -async def update_toolkit_by_id( +async def update_function_by_id( request: Request, id: str, form_data: FunctionForm, user=Depends(get_admin_user) ): function_path = os.path.join(FUNCTIONS_DIR, f"{id}.py") diff --git a/src/lib/apis/functions/index.ts b/src/lib/apis/functions/index.ts index e035ef1c1..530702a3e 100644 --- a/src/lib/apis/functions/index.ts +++ b/src/lib/apis/functions/index.ts @@ -191,3 +191,102 @@ export const deleteFunctionById = async (token: string, id: string) => { return res; }; + +export const getUserValvesById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/user`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getUserValvesSpecById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/user/spec`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateUserValvesById = async (token: string, id: string, valves: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/functions/id/${id}/valves/user/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...valves + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/apis/tools/index.ts b/src/lib/apis/tools/index.ts index 9c620e7b5..25d543feb 100644 --- a/src/lib/apis/tools/index.ts +++ b/src/lib/apis/tools/index.ts @@ -191,3 +191,102 @@ export const deleteToolById = async (token: string, id: string) => { return res; }; + +export const getUserValvesById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/user`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const getUserValvesSpecById = async (token: string, id: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/user/spec`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const updateUserValvesById = async (token: string, id: string, valves: object) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/tools/id/${id}/valves/user/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + ...valves + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .then((json) => { + return json; + }) + .catch((err) => { + error = err.detail; + + console.log(err); + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/lib/components/chat/Settings/Valves.svelte b/src/lib/components/chat/Settings/Valves.svelte index cfa03d907..f41d0e672 100644 --- a/src/lib/components/chat/Settings/Valves.svelte +++ b/src/lib/components/chat/Settings/Valves.svelte @@ -1,12 +1,24 @@
{ + submitHandler(); dispatch('save'); }} > @@ -82,11 +164,62 @@ -
+ {#if selectedId} +
-
-
-
+
+ {#if !loading} + {#if valvesSpec} + {#each Object.keys(valvesSpec.properties) as property, idx} +
+
+
+ {valvesSpec.properties[property].title} + + {#if (valvesSpec?.required ?? []).includes(property)} + *required + {/if} +
+ + +
+ + {#if (valves[property] ?? null) !== null} +
+
+ +
+
+ {/if} +
+ {/each} + {:else} +
No valves
+ {/if} + {:else} + + {/if} +
+ {/if}