mirror of
https://github.com/open-webui/open-webui
synced 2025-04-27 17:51:31 +00:00
enh: tools & functions frontmatter
This commit is contained in:
parent
8b99870189
commit
abf212c28f
@ -109,7 +109,9 @@ async def get_pipe_models():
|
|||||||
for pipe in pipes:
|
for pipe in pipes:
|
||||||
# Check if function is already loaded
|
# Check if function is already loaded
|
||||||
if pipe.id not in app.state.FUNCTIONS:
|
if pipe.id not in app.state.FUNCTIONS:
|
||||||
function_module, function_type = load_function_module_by_id(pipe.id)
|
function_module, function_type, frontmatter = load_function_module_by_id(
|
||||||
|
pipe.id
|
||||||
|
)
|
||||||
app.state.FUNCTIONS[pipe.id] = function_module
|
app.state.FUNCTIONS[pipe.id] = function_module
|
||||||
else:
|
else:
|
||||||
function_module = app.state.FUNCTIONS[pipe.id]
|
function_module = app.state.FUNCTIONS[pipe.id]
|
||||||
|
@ -39,6 +39,7 @@ class Function(Model):
|
|||||||
|
|
||||||
class FunctionMeta(BaseModel):
|
class FunctionMeta(BaseModel):
|
||||||
description: Optional[str] = None
|
description: Optional[str] = None
|
||||||
|
manifest: Optional[dict] = {}
|
||||||
|
|
||||||
|
|
||||||
class FunctionModel(BaseModel):
|
class FunctionModel(BaseModel):
|
||||||
|
@ -38,6 +38,7 @@ class Tool(Model):
|
|||||||
|
|
||||||
class ToolMeta(BaseModel):
|
class ToolMeta(BaseModel):
|
||||||
description: Optional[str] = None
|
description: Optional[str] = None
|
||||||
|
manifest: Optional[dict] = {}
|
||||||
|
|
||||||
|
|
||||||
class ToolModel(BaseModel):
|
class ToolModel(BaseModel):
|
||||||
|
@ -69,7 +69,10 @@ async def create_new_function(
|
|||||||
with open(function_path, "w") as function_file:
|
with open(function_path, "w") as function_file:
|
||||||
function_file.write(form_data.content)
|
function_file.write(form_data.content)
|
||||||
|
|
||||||
function_module, function_type = load_function_module_by_id(form_data.id)
|
function_module, function_type, frontmatter = load_function_module_by_id(
|
||||||
|
form_data.id
|
||||||
|
)
|
||||||
|
form_data.meta.manifest = frontmatter
|
||||||
|
|
||||||
FUNCTIONS = request.app.state.FUNCTIONS
|
FUNCTIONS = request.app.state.FUNCTIONS
|
||||||
FUNCTIONS[form_data.id] = function_module
|
FUNCTIONS[form_data.id] = function_module
|
||||||
@ -117,6 +120,97 @@ async def get_function_by_id(id: str, user=Depends(get_admin_user)):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# ToggleFunctionById
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/id/{id}/toggle", response_model=Optional[FunctionModel])
|
||||||
|
async def toggle_function_by_id(id: str, user=Depends(get_admin_user)):
|
||||||
|
function = Functions.get_function_by_id(id)
|
||||||
|
if function:
|
||||||
|
function = Functions.update_function_by_id(
|
||||||
|
id, {"is_active": not function.is_active}
|
||||||
|
)
|
||||||
|
|
||||||
|
if function:
|
||||||
|
return function
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=ERROR_MESSAGES.DEFAULT("Error updating function"),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# UpdateFunctionById
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/id/{id}/update", response_model=Optional[FunctionModel])
|
||||||
|
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")
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(function_path, "w") as function_file:
|
||||||
|
function_file.write(form_data.content)
|
||||||
|
|
||||||
|
function_module, function_type, frontmatter = load_function_module_by_id(id)
|
||||||
|
form_data.meta.manifest = frontmatter
|
||||||
|
|
||||||
|
FUNCTIONS = request.app.state.FUNCTIONS
|
||||||
|
FUNCTIONS[id] = function_module
|
||||||
|
|
||||||
|
updated = {**form_data.model_dump(exclude={"id"}), "type": function_type}
|
||||||
|
print(updated)
|
||||||
|
|
||||||
|
function = Functions.update_function_by_id(id, updated)
|
||||||
|
|
||||||
|
if function:
|
||||||
|
return function
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=ERROR_MESSAGES.DEFAULT("Error updating function"),
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=ERROR_MESSAGES.DEFAULT(e),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# DeleteFunctionById
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/id/{id}/delete", response_model=bool)
|
||||||
|
async def delete_function_by_id(
|
||||||
|
request: Request, id: str, user=Depends(get_admin_user)
|
||||||
|
):
|
||||||
|
result = Functions.delete_function_by_id(id)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
FUNCTIONS = request.app.state.FUNCTIONS
|
||||||
|
if id in FUNCTIONS:
|
||||||
|
del FUNCTIONS[id]
|
||||||
|
|
||||||
|
# delete the function file
|
||||||
|
function_path = os.path.join(FUNCTIONS_DIR, f"{id}.py")
|
||||||
|
os.remove(function_path)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# GetFunctionValves
|
# GetFunctionValves
|
||||||
############################
|
############################
|
||||||
@ -155,7 +249,7 @@ async def get_function_valves_spec_by_id(
|
|||||||
if id in request.app.state.FUNCTIONS:
|
if id in request.app.state.FUNCTIONS:
|
||||||
function_module = request.app.state.FUNCTIONS[id]
|
function_module = request.app.state.FUNCTIONS[id]
|
||||||
else:
|
else:
|
||||||
function_module, function_type = load_function_module_by_id(id)
|
function_module, function_type, frontmatter = load_function_module_by_id(id)
|
||||||
request.app.state.FUNCTIONS[id] = function_module
|
request.app.state.FUNCTIONS[id] = function_module
|
||||||
|
|
||||||
if hasattr(function_module, "Valves"):
|
if hasattr(function_module, "Valves"):
|
||||||
@ -184,7 +278,7 @@ async def update_function_valves_by_id(
|
|||||||
if id in request.app.state.FUNCTIONS:
|
if id in request.app.state.FUNCTIONS:
|
||||||
function_module = request.app.state.FUNCTIONS[id]
|
function_module = request.app.state.FUNCTIONS[id]
|
||||||
else:
|
else:
|
||||||
function_module, function_type = load_function_module_by_id(id)
|
function_module, function_type, frontmatter = load_function_module_by_id(id)
|
||||||
request.app.state.FUNCTIONS[id] = function_module
|
request.app.state.FUNCTIONS[id] = function_module
|
||||||
|
|
||||||
if hasattr(function_module, "Valves"):
|
if hasattr(function_module, "Valves"):
|
||||||
@ -247,7 +341,7 @@ async def get_function_user_valves_spec_by_id(
|
|||||||
if id in request.app.state.FUNCTIONS:
|
if id in request.app.state.FUNCTIONS:
|
||||||
function_module = request.app.state.FUNCTIONS[id]
|
function_module = request.app.state.FUNCTIONS[id]
|
||||||
else:
|
else:
|
||||||
function_module, function_type = load_function_module_by_id(id)
|
function_module, function_type, frontmatter = load_function_module_by_id(id)
|
||||||
request.app.state.FUNCTIONS[id] = function_module
|
request.app.state.FUNCTIONS[id] = function_module
|
||||||
|
|
||||||
if hasattr(function_module, "UserValves"):
|
if hasattr(function_module, "UserValves"):
|
||||||
@ -271,7 +365,7 @@ async def update_function_user_valves_by_id(
|
|||||||
if id in request.app.state.FUNCTIONS:
|
if id in request.app.state.FUNCTIONS:
|
||||||
function_module = request.app.state.FUNCTIONS[id]
|
function_module = request.app.state.FUNCTIONS[id]
|
||||||
else:
|
else:
|
||||||
function_module, function_type = load_function_module_by_id(id)
|
function_module, function_type, frontmatter = load_function_module_by_id(id)
|
||||||
request.app.state.FUNCTIONS[id] = function_module
|
request.app.state.FUNCTIONS[id] = function_module
|
||||||
|
|
||||||
if hasattr(function_module, "UserValves"):
|
if hasattr(function_module, "UserValves"):
|
||||||
@ -300,93 +394,3 @@ async def update_function_user_valves_by_id(
|
|||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
############################
|
|
||||||
# ToggleFunctionById
|
|
||||||
############################
|
|
||||||
|
|
||||||
|
|
||||||
@router.post("/id/{id}/toggle", response_model=Optional[FunctionModel])
|
|
||||||
async def toggle_function_by_id(id: str, user=Depends(get_admin_user)):
|
|
||||||
function = Functions.get_function_by_id(id)
|
|
||||||
if function:
|
|
||||||
function = Functions.update_function_by_id(
|
|
||||||
id, {"is_active": not function.is_active}
|
|
||||||
)
|
|
||||||
|
|
||||||
if function:
|
|
||||||
return function
|
|
||||||
else:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
detail=ERROR_MESSAGES.DEFAULT("Error updating function"),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
||||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
############################
|
|
||||||
# UpdateFunctionById
|
|
||||||
############################
|
|
||||||
|
|
||||||
|
|
||||||
@router.post("/id/{id}/update", response_model=Optional[FunctionModel])
|
|
||||||
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")
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(function_path, "w") as function_file:
|
|
||||||
function_file.write(form_data.content)
|
|
||||||
|
|
||||||
function_module, function_type = load_function_module_by_id(id)
|
|
||||||
|
|
||||||
FUNCTIONS = request.app.state.FUNCTIONS
|
|
||||||
FUNCTIONS[id] = function_module
|
|
||||||
|
|
||||||
updated = {**form_data.model_dump(exclude={"id"}), "type": function_type}
|
|
||||||
print(updated)
|
|
||||||
|
|
||||||
function = Functions.update_function_by_id(id, updated)
|
|
||||||
|
|
||||||
if function:
|
|
||||||
return function
|
|
||||||
else:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
detail=ERROR_MESSAGES.DEFAULT("Error updating function"),
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
detail=ERROR_MESSAGES.DEFAULT(e),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
############################
|
|
||||||
# DeleteFunctionById
|
|
||||||
############################
|
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/id/{id}/delete", response_model=bool)
|
|
||||||
async def delete_function_by_id(
|
|
||||||
request: Request, id: str, user=Depends(get_admin_user)
|
|
||||||
):
|
|
||||||
result = Functions.delete_function_by_id(id)
|
|
||||||
|
|
||||||
if result:
|
|
||||||
FUNCTIONS = request.app.state.FUNCTIONS
|
|
||||||
if id in FUNCTIONS:
|
|
||||||
del FUNCTIONS[id]
|
|
||||||
|
|
||||||
# delete the function file
|
|
||||||
function_path = os.path.join(FUNCTIONS_DIR, f"{id}.py")
|
|
||||||
os.remove(function_path)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
@ -74,7 +74,8 @@ async def create_new_toolkit(
|
|||||||
with open(toolkit_path, "w") as tool_file:
|
with open(toolkit_path, "w") as tool_file:
|
||||||
tool_file.write(form_data.content)
|
tool_file.write(form_data.content)
|
||||||
|
|
||||||
toolkit_module = load_toolkit_module_by_id(form_data.id)
|
toolkit_module, frontmatter = load_toolkit_module_by_id(form_data.id)
|
||||||
|
form_data.meta.manifest = frontmatter
|
||||||
|
|
||||||
TOOLS = request.app.state.TOOLS
|
TOOLS = request.app.state.TOOLS
|
||||||
TOOLS[form_data.id] = toolkit_module
|
TOOLS[form_data.id] = toolkit_module
|
||||||
@ -123,6 +124,73 @@ async def get_toolkit_by_id(id: str, user=Depends(get_admin_user)):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# UpdateToolkitById
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/id/{id}/update", response_model=Optional[ToolModel])
|
||||||
|
async def update_toolkit_by_id(
|
||||||
|
request: Request, id: str, form_data: ToolForm, user=Depends(get_admin_user)
|
||||||
|
):
|
||||||
|
toolkit_path = os.path.join(TOOLS_DIR, f"{id}.py")
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(toolkit_path, "w") as tool_file:
|
||||||
|
tool_file.write(form_data.content)
|
||||||
|
|
||||||
|
toolkit_module, frontmatter = load_toolkit_module_by_id(id)
|
||||||
|
form_data.meta.manifest = frontmatter
|
||||||
|
|
||||||
|
TOOLS = request.app.state.TOOLS
|
||||||
|
TOOLS[id] = toolkit_module
|
||||||
|
|
||||||
|
specs = get_tools_specs(TOOLS[id])
|
||||||
|
|
||||||
|
updated = {
|
||||||
|
**form_data.model_dump(exclude={"id"}),
|
||||||
|
"specs": specs,
|
||||||
|
}
|
||||||
|
|
||||||
|
print(updated)
|
||||||
|
toolkit = Tools.update_tool_by_id(id, updated)
|
||||||
|
|
||||||
|
if toolkit:
|
||||||
|
return toolkit
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=ERROR_MESSAGES.DEFAULT("Error updating toolkit"),
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=ERROR_MESSAGES.DEFAULT(e),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# DeleteToolkitById
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/id/{id}/delete", response_model=bool)
|
||||||
|
async def delete_toolkit_by_id(request: Request, id: str, user=Depends(get_admin_user)):
|
||||||
|
result = Tools.delete_tool_by_id(id)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
TOOLS = request.app.state.TOOLS
|
||||||
|
if id in TOOLS:
|
||||||
|
del TOOLS[id]
|
||||||
|
|
||||||
|
# delete the toolkit file
|
||||||
|
toolkit_path = os.path.join(TOOLS_DIR, f"{id}.py")
|
||||||
|
os.remove(toolkit_path)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# GetToolValves
|
# GetToolValves
|
||||||
############################
|
############################
|
||||||
@ -161,7 +229,7 @@ async def get_toolkit_valves_spec_by_id(
|
|||||||
if id in request.app.state.TOOLS:
|
if id in request.app.state.TOOLS:
|
||||||
toolkit_module = request.app.state.TOOLS[id]
|
toolkit_module = request.app.state.TOOLS[id]
|
||||||
else:
|
else:
|
||||||
toolkit_module = load_toolkit_module_by_id(id)
|
toolkit_module, frontmatter = load_toolkit_module_by_id(id)
|
||||||
request.app.state.TOOLS[id] = toolkit_module
|
request.app.state.TOOLS[id] = toolkit_module
|
||||||
|
|
||||||
if hasattr(toolkit_module, "Valves"):
|
if hasattr(toolkit_module, "Valves"):
|
||||||
@ -189,7 +257,7 @@ async def update_toolkit_valves_by_id(
|
|||||||
if id in request.app.state.TOOLS:
|
if id in request.app.state.TOOLS:
|
||||||
toolkit_module = request.app.state.TOOLS[id]
|
toolkit_module = request.app.state.TOOLS[id]
|
||||||
else:
|
else:
|
||||||
toolkit_module = load_toolkit_module_by_id(id)
|
toolkit_module, frontmatter = load_toolkit_module_by_id(id)
|
||||||
request.app.state.TOOLS[id] = toolkit_module
|
request.app.state.TOOLS[id] = toolkit_module
|
||||||
|
|
||||||
if hasattr(toolkit_module, "Valves"):
|
if hasattr(toolkit_module, "Valves"):
|
||||||
@ -252,7 +320,7 @@ async def get_toolkit_user_valves_spec_by_id(
|
|||||||
if id in request.app.state.TOOLS:
|
if id in request.app.state.TOOLS:
|
||||||
toolkit_module = request.app.state.TOOLS[id]
|
toolkit_module = request.app.state.TOOLS[id]
|
||||||
else:
|
else:
|
||||||
toolkit_module = load_toolkit_module_by_id(id)
|
toolkit_module, frontmatter = load_toolkit_module_by_id(id)
|
||||||
request.app.state.TOOLS[id] = toolkit_module
|
request.app.state.TOOLS[id] = toolkit_module
|
||||||
|
|
||||||
if hasattr(toolkit_module, "UserValves"):
|
if hasattr(toolkit_module, "UserValves"):
|
||||||
@ -276,7 +344,7 @@ async def update_toolkit_user_valves_by_id(
|
|||||||
if id in request.app.state.TOOLS:
|
if id in request.app.state.TOOLS:
|
||||||
toolkit_module = request.app.state.TOOLS[id]
|
toolkit_module = request.app.state.TOOLS[id]
|
||||||
else:
|
else:
|
||||||
toolkit_module = load_toolkit_module_by_id(id)
|
toolkit_module, frontmatter = load_toolkit_module_by_id(id)
|
||||||
request.app.state.TOOLS[id] = toolkit_module
|
request.app.state.TOOLS[id] = toolkit_module
|
||||||
|
|
||||||
if hasattr(toolkit_module, "UserValves"):
|
if hasattr(toolkit_module, "UserValves"):
|
||||||
@ -305,69 +373,3 @@ async def update_toolkit_user_valves_by_id(
|
|||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
detail=ERROR_MESSAGES.NOT_FOUND,
|
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
############################
|
|
||||||
# UpdateToolkitById
|
|
||||||
############################
|
|
||||||
|
|
||||||
|
|
||||||
@router.post("/id/{id}/update", response_model=Optional[ToolModel])
|
|
||||||
async def update_toolkit_by_id(
|
|
||||||
request: Request, id: str, form_data: ToolForm, user=Depends(get_admin_user)
|
|
||||||
):
|
|
||||||
toolkit_path = os.path.join(TOOLS_DIR, f"{id}.py")
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(toolkit_path, "w") as tool_file:
|
|
||||||
tool_file.write(form_data.content)
|
|
||||||
|
|
||||||
toolkit_module = load_toolkit_module_by_id(id)
|
|
||||||
|
|
||||||
TOOLS = request.app.state.TOOLS
|
|
||||||
TOOLS[id] = toolkit_module
|
|
||||||
|
|
||||||
specs = get_tools_specs(TOOLS[id])
|
|
||||||
|
|
||||||
updated = {
|
|
||||||
**form_data.model_dump(exclude={"id"}),
|
|
||||||
"specs": specs,
|
|
||||||
}
|
|
||||||
|
|
||||||
print(updated)
|
|
||||||
toolkit = Tools.update_tool_by_id(id, updated)
|
|
||||||
|
|
||||||
if toolkit:
|
|
||||||
return toolkit
|
|
||||||
else:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
detail=ERROR_MESSAGES.DEFAULT("Error updating toolkit"),
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
detail=ERROR_MESSAGES.DEFAULT(e),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
############################
|
|
||||||
# DeleteToolkitById
|
|
||||||
############################
|
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/id/{id}/delete", response_model=bool)
|
|
||||||
async def delete_toolkit_by_id(request: Request, id: str, user=Depends(get_admin_user)):
|
|
||||||
result = Tools.delete_tool_by_id(id)
|
|
||||||
|
|
||||||
if result:
|
|
||||||
TOOLS = request.app.state.TOOLS
|
|
||||||
if id in TOOLS:
|
|
||||||
del TOOLS[id]
|
|
||||||
|
|
||||||
# delete the toolkit file
|
|
||||||
toolkit_path = os.path.join(TOOLS_DIR, f"{id}.py")
|
|
||||||
os.remove(toolkit_path)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
@ -1,19 +1,41 @@
|
|||||||
from importlib import util
|
from importlib import util
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
from config import TOOLS_DIR, FUNCTIONS_DIR
|
from config import TOOLS_DIR, FUNCTIONS_DIR
|
||||||
|
|
||||||
|
|
||||||
|
def extract_frontmatter(file_path):
|
||||||
|
"""
|
||||||
|
Extract frontmatter as a dictionary from the specified file path.
|
||||||
|
"""
|
||||||
|
frontmatter = {}
|
||||||
|
frontmatter_pattern = re.compile(r"^([a-z_]+):\s*(.*)\s*$", re.IGNORECASE)
|
||||||
|
|
||||||
|
with open(file_path, "r", encoding="utf-8") as file:
|
||||||
|
for line in file:
|
||||||
|
if line.strip() == '"""':
|
||||||
|
# End of frontmatter section
|
||||||
|
break
|
||||||
|
match = frontmatter_pattern.match(line)
|
||||||
|
if match:
|
||||||
|
key, value = match.groups()
|
||||||
|
frontmatter[key] = value
|
||||||
|
|
||||||
|
return frontmatter
|
||||||
|
|
||||||
|
|
||||||
def load_toolkit_module_by_id(toolkit_id):
|
def load_toolkit_module_by_id(toolkit_id):
|
||||||
toolkit_path = os.path.join(TOOLS_DIR, f"{toolkit_id}.py")
|
toolkit_path = os.path.join(TOOLS_DIR, f"{toolkit_id}.py")
|
||||||
spec = util.spec_from_file_location(toolkit_id, toolkit_path)
|
spec = util.spec_from_file_location(toolkit_id, toolkit_path)
|
||||||
module = util.module_from_spec(spec)
|
module = util.module_from_spec(spec)
|
||||||
|
frontmatter = extract_frontmatter(toolkit_path)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
spec.loader.exec_module(module)
|
spec.loader.exec_module(module)
|
||||||
print(f"Loaded module: {module.__name__}")
|
print(f"Loaded module: {module.__name__}")
|
||||||
if hasattr(module, "Tools"):
|
if hasattr(module, "Tools"):
|
||||||
return module.Tools()
|
return module.Tools(), frontmatter
|
||||||
else:
|
else:
|
||||||
raise Exception("No Tools class found")
|
raise Exception("No Tools class found")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -28,14 +50,15 @@ def load_function_module_by_id(function_id):
|
|||||||
|
|
||||||
spec = util.spec_from_file_location(function_id, function_path)
|
spec = util.spec_from_file_location(function_id, function_path)
|
||||||
module = util.module_from_spec(spec)
|
module = util.module_from_spec(spec)
|
||||||
|
frontmatter = extract_frontmatter(function_path)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
spec.loader.exec_module(module)
|
spec.loader.exec_module(module)
|
||||||
print(f"Loaded module: {module.__name__}")
|
print(f"Loaded module: {module.__name__}")
|
||||||
if hasattr(module, "Pipe"):
|
if hasattr(module, "Pipe"):
|
||||||
return module.Pipe(), "pipe"
|
return module.Pipe(), "pipe", frontmatter
|
||||||
elif hasattr(module, "Filter"):
|
elif hasattr(module, "Filter"):
|
||||||
return module.Filter(), "filter"
|
return module.Filter(), "filter", frontmatter
|
||||||
else:
|
else:
|
||||||
raise Exception("No Function class found")
|
raise Exception("No Function class found")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -258,7 +258,7 @@ async def get_function_call_response(
|
|||||||
if tool_id in webui_app.state.TOOLS:
|
if tool_id in webui_app.state.TOOLS:
|
||||||
toolkit_module = webui_app.state.TOOLS[tool_id]
|
toolkit_module = webui_app.state.TOOLS[tool_id]
|
||||||
else:
|
else:
|
||||||
toolkit_module = load_toolkit_module_by_id(tool_id)
|
toolkit_module, frontmatter = load_toolkit_module_by_id(tool_id)
|
||||||
webui_app.state.TOOLS[tool_id] = toolkit_module
|
webui_app.state.TOOLS[tool_id] = toolkit_module
|
||||||
|
|
||||||
file_handler = False
|
file_handler = False
|
||||||
@ -415,8 +415,8 @@ class ChatCompletionMiddleware(BaseHTTPMiddleware):
|
|||||||
if filter_id in webui_app.state.FUNCTIONS:
|
if filter_id in webui_app.state.FUNCTIONS:
|
||||||
function_module = webui_app.state.FUNCTIONS[filter_id]
|
function_module = webui_app.state.FUNCTIONS[filter_id]
|
||||||
else:
|
else:
|
||||||
function_module, function_type = load_function_module_by_id(
|
function_module, function_type, frontmatter = (
|
||||||
filter_id
|
load_function_module_by_id(filter_id)
|
||||||
)
|
)
|
||||||
webui_app.state.FUNCTIONS[filter_id] = function_module
|
webui_app.state.FUNCTIONS[filter_id] = function_module
|
||||||
|
|
||||||
@ -909,7 +909,9 @@ async def generate_chat_completions(form_data: dict, user=Depends(get_verified_u
|
|||||||
|
|
||||||
# Check if function is already loaded
|
# Check if function is already loaded
|
||||||
if pipe_id not in webui_app.state.FUNCTIONS:
|
if pipe_id not in webui_app.state.FUNCTIONS:
|
||||||
function_module, function_type = load_function_module_by_id(pipe_id)
|
function_module, function_type, frontmatter = (
|
||||||
|
load_function_module_by_id(pipe_id)
|
||||||
|
)
|
||||||
webui_app.state.FUNCTIONS[pipe_id] = function_module
|
webui_app.state.FUNCTIONS[pipe_id] = function_module
|
||||||
else:
|
else:
|
||||||
function_module = webui_app.state.FUNCTIONS[pipe_id]
|
function_module = webui_app.state.FUNCTIONS[pipe_id]
|
||||||
@ -1155,7 +1157,9 @@ async def chat_completed(form_data: dict, user=Depends(get_verified_user)):
|
|||||||
if filter_id in webui_app.state.FUNCTIONS:
|
if filter_id in webui_app.state.FUNCTIONS:
|
||||||
function_module = webui_app.state.FUNCTIONS[filter_id]
|
function_module = webui_app.state.FUNCTIONS[filter_id]
|
||||||
else:
|
else:
|
||||||
function_module, function_type = load_function_module_by_id(filter_id)
|
function_module, function_type, frontmatter = (
|
||||||
|
load_function_module_by_id(filter_id)
|
||||||
|
)
|
||||||
webui_app.state.FUNCTIONS[filter_id] = function_module
|
webui_app.state.FUNCTIONS[filter_id] = function_module
|
||||||
|
|
||||||
if hasattr(function_module, "valves") and hasattr(
|
if hasattr(function_module, "valves") and hasattr(
|
||||||
|
Loading…
Reference in New Issue
Block a user