Add tool duplication functionality and enhance ComponentsToolsPage
- Implement a new API endpoint for duplicating tools in the backend. - Add a duplicate_tool function in ComponentsToolsPage to handle tool duplication requests. - Update the UI to include a dropdown menu option for duplicating tools, improving user experience. - Refactor the remove function to accept a resource object instead of an ID for better clarity and maintainability.
This commit is contained in:
@@ -52,6 +52,13 @@ def _payload(body: ToolUpsert, stored_secrets: dict | None = None) -> dict:
|
||||
}
|
||||
|
||||
|
||||
def _duplicate_function_name(source: str) -> str:
|
||||
candidate = f"{source}_copy"
|
||||
if len(candidate) <= 64:
|
||||
return candidate
|
||||
return f"{source[:57]}_copy"
|
||||
|
||||
|
||||
async def _commit(session: AsyncSession, tool: Tool) -> ToolOut:
|
||||
try:
|
||||
await session.commit()
|
||||
@@ -99,6 +106,33 @@ async def update_tool(
|
||||
return await _commit(session, tool)
|
||||
|
||||
|
||||
@router.post("/{tool_id}/duplicate", response_model=ToolOut)
|
||||
async def duplicate_tool(tool_id: str, session: AsyncSession = Depends(get_session)):
|
||||
source = await session.get(Tool, tool_id)
|
||||
if not source:
|
||||
raise HTTPException(404, "工具不存在")
|
||||
function_name = _duplicate_function_name(source.function_name)
|
||||
existing = (
|
||||
await session.execute(select(Tool).where(Tool.function_name == function_name))
|
||||
).scalar_one_or_none()
|
||||
if existing:
|
||||
suffix = uuid.uuid4().hex[:6]
|
||||
max_base = 64 - len(suffix) - 1
|
||||
function_name = f"{source.function_name[:max_base]}_{suffix}"
|
||||
tool = Tool(
|
||||
id=f"tool_{uuid.uuid4().hex[:12]}",
|
||||
name=f"{source.name} 副本",
|
||||
function_name=function_name,
|
||||
type=source.type,
|
||||
description=source.description,
|
||||
definition=dict(source.definition or {}),
|
||||
secrets=dict(source.secrets or {}),
|
||||
status=source.status,
|
||||
)
|
||||
session.add(tool)
|
||||
return await _commit(session, tool)
|
||||
|
||||
|
||||
@router.delete("/{tool_id}")
|
||||
async def delete_tool(tool_id: str, session: AsyncSession = Depends(get_session)):
|
||||
tool = await session.get(Tool, tool_id)
|
||||
|
||||
Reference in New Issue
Block a user