feat: Tools Atomic PR of #20243 (#20370)

* feat: Add read-only access support for Tools

- Backend: Add write_access field to ToolAccessResponse
- Backend: Update /tools/list to return tools with write_access
- Frontend: Display Read Only badge in Tools list
- Frontend: Disable inputs and save button when no write access
- Frontend: Add readOnly prop to CodeEditor component

* Update Tools.svelte

* fix: Return write_access from getToolById endpoint

fix: Return write_access from getToolById endpoint

- Use ToolAccessResponse instead of raw dict
- Remove inefficient getToolList call in edit page

* refactor: Rename write_access to disabled in ToolkitEditor

- Rename prop from write_access to disabled
- Invert logic where needed
- Update edit page to pass disabled instead of write_access

* rem

* Update +page.svelte

* fix

* Update ToolkitEditor.svelte

* Update CodeEditor.svelte

* Update ToolkitEditor.svelte
This commit is contained in:
Classic298
2026-01-06 03:00:48 +04:00
committed by GitHub
parent 5921a19519
commit c87031e9a6
3 changed files with 102 additions and 36 deletions
+4
View File
@@ -97,6 +97,10 @@ class ToolUserResponse(ToolResponse):
model_config = ConfigDict(extra="allow")
class ToolAccessResponse(ToolUserResponse):
write_access: Optional[bool] = False
class ToolForm(BaseModel):
id: str
name: str
+24 -5
View File
@@ -17,6 +17,7 @@ from open_webui.models.tools import (
ToolModel,
ToolResponse,
ToolUserResponse,
ToolAccessResponse,
Tools,
)
from open_webui.utils.plugin import (
@@ -157,13 +158,24 @@ async def get_tools(request: Request, user=Depends(get_verified_user), db: Sessi
############################
@router.get("/list", response_model=list[ToolUserResponse])
@router.get("/list", response_model=list[ToolAccessResponse])
async def get_tool_list(user=Depends(get_verified_user), db: Session = Depends(get_session)):
if user.role == "admin" and BYPASS_ADMIN_ACCESS_CONTROL:
tools = Tools.get_tools(db=db)
else:
tools = Tools.get_tools_by_user_id(user.id, "write", db=db)
return tools
tools = Tools.get_tools_by_user_id(user.id, "read", db=db)
return [
ToolAccessResponse(
**tool.model_dump(),
write_access=(
(user.role == "admin" and BYPASS_ADMIN_ACCESS_CONTROL)
or user.id == tool.user_id
or has_access(user.id, "write", tool.access_control, db=db)
),
)
for tool in tools
]
############################
@@ -338,7 +350,7 @@ async def create_new_tools(
############################
@router.get("/id/{id}", response_model=Optional[ToolModel])
@router.get("/id/{id}", response_model=Optional[ToolAccessResponse])
async def get_tools_by_id(id: str, user=Depends(get_verified_user), db: Session = Depends(get_session)):
tools = Tools.get_tool_by_id(id, db=db)
@@ -348,7 +360,14 @@ async def get_tools_by_id(id: str, user=Depends(get_verified_user), db: Session
or tools.user_id == user.id
or has_access(user.id, "read", tools.access_control, db=db)
):
return tools
return ToolAccessResponse(
**tools.model_dump(),
write_access=(
(user.role == "admin" and BYPASS_ADMIN_ACCESS_CONTROL)
or user.id == tools.user_id
or has_access(user.id, "write", tools.access_control, db=db)
),
)
else:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,