diff --git a/backend/open_webui/models/functions.py b/backend/open_webui/models/functions.py index 8cbfc5de7..e98771fa0 100644 --- a/backend/open_webui/models/functions.py +++ b/backend/open_webui/models/functions.py @@ -108,6 +108,54 @@ class FunctionsTable: log.exception(f"Error creating a new function: {e}") return None + def sync_functions( + self, user_id: str, functions: list[FunctionModel] + ) -> list[FunctionModel]: + # Synchronize functions for a user by updating existing ones, inserting new ones, and removing those that are no longer present. + try: + with get_db() as db: + # Get existing functions + existing_functions = db.query(Function).all() + existing_ids = {func.id for func in existing_functions} + + # Prepare a set of new function IDs + new_function_ids = {func.id for func in functions} + + # Update or insert functions + for func in functions: + if func.id in existing_ids: + db.query(Function).filter_by(id=func.id).update( + { + **func.model_dump(), + "user_id": user_id, + "updated_at": int(time.time()), + } + ) + else: + new_func = Function( + **{ + **func.model_dump(), + "user_id": user_id, + "updated_at": int(time.time()), + } + ) + db.add(new_func) + + # Remove functions that are no longer present + for func in existing_functions: + if func.id not in new_function_ids: + db.delete(func) + + db.commit() + + return [ + FunctionModel.model_validate(func) + for func in db.query(Function).all() + ] + except Exception as e: + log.exception(f"Error syncing functions for user {user_id}: {e}") + return [] + def get_function_by_id(self, id: str) -> Optional[FunctionModel]: try: with get_db() as db: diff --git a/backend/open_webui/routers/functions.py b/backend/open_webui/routers/functions.py index bfbedcbe3..aec75f75a 100644 --- a/backend/open_webui/routers/functions.py +++ b/backend/open_webui/routers/functions.py @@ -42,6 +42,22 @@ async def get_functions(user=Depends(get_admin_user)): return Functions.get_functions() +############################ +# SyncFunctions +############################ + + +class SyncFunctionsForm(FunctionForm): + functions: list[FunctionModel] = [] + + +@router.post("/sync", response_model=Optional[FunctionModel]) +async def sync_functions( + request: Request, form_data: SyncFunctionsForm, user=Depends(get_admin_user) +): + return Functions.sync_functions(user.id, form_data.functions) + + ############################ # CreateNewFunction ############################