mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-09-16 06:47:13 +00:00
e631da0073
* fix(runner): align SDK pin and workspace-aware integration fixtures * fix(ci): format sources and resolve current migration head * test(persistence): align standalone migration fixtures with current models * test(web): align smoke fixtures with current processor UI --------- Co-authored-by: dadachann <185672915+dadachann@users.noreply.github.com>
85 lines
3.3 KiB
Python
85 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
import quart
|
|
|
|
from ....authz import Permission
|
|
from ....context import RequestContext
|
|
from ... import group
|
|
from ......pipeline.extension_preferences import normalize_extension_preferences
|
|
|
|
|
|
@group.group_class('tools', '/api/v1/tools')
|
|
class ToolsRouterGroup(group.RouterGroup):
|
|
async def _get_scoped_tool_catalog(
|
|
self,
|
|
request_context: RequestContext,
|
|
) -> list[dict] | None:
|
|
pipeline_uuid = quart.request.args.get('pipeline_uuid') or quart.request.args.get('pipeline_id')
|
|
bound_plugins: list[str] | None = None
|
|
bound_mcp_servers: list[str] | None = None
|
|
|
|
if pipeline_uuid:
|
|
pipeline = await self.ap.pipeline_service.get_pipeline(
|
|
request_context,
|
|
pipeline_uuid,
|
|
)
|
|
if pipeline is None:
|
|
return None
|
|
|
|
extensions_prefs = normalize_extension_preferences(pipeline.get('extensions_preferences'))
|
|
if not extensions_prefs['enable_all_plugins']:
|
|
bound_plugins = [f'{plugin["author"]}/{plugin["name"]}' for plugin in extensions_prefs['plugins']]
|
|
if not extensions_prefs['enable_all_mcp_servers']:
|
|
bound_mcp_servers = extensions_prefs['mcp_servers']
|
|
|
|
return await self.ap.tool_mgr.get_resolved_tool_catalog(
|
|
request_context,
|
|
bound_plugins,
|
|
bound_mcp_servers,
|
|
include_skill_authoring=True,
|
|
)
|
|
|
|
async def initialize(self) -> None:
|
|
@self.route(
|
|
'',
|
|
methods=['GET'],
|
|
auth_type=group.AuthType.USER_TOKEN,
|
|
permission=Permission.RESOURCE_VIEW,
|
|
)
|
|
async def _(request_context: RequestContext) -> str:
|
|
"""获取所有可用工具列表"""
|
|
catalog = await self._get_scoped_tool_catalog(request_context)
|
|
if catalog is None:
|
|
return self.http_status(404, -1, 'pipeline not found')
|
|
return self.success(data={'tools': catalog})
|
|
|
|
@self.route(
|
|
'/<path:tool_name>',
|
|
methods=['GET'],
|
|
auth_type=group.AuthType.USER_TOKEN,
|
|
permission=Permission.RESOURCE_VIEW,
|
|
)
|
|
async def _(tool_name: str, request_context: RequestContext) -> str:
|
|
"""获取特定工具详情"""
|
|
catalog = await self._get_scoped_tool_catalog(request_context)
|
|
if catalog is None:
|
|
return self.http_status(404, -1, 'pipeline not found')
|
|
|
|
for tool in catalog:
|
|
if tool.get('name') == tool_name:
|
|
return self.success(
|
|
data={
|
|
'tool': {
|
|
'name': tool['name'],
|
|
'description': tool.get('description') or '',
|
|
'human_desc': tool.get('human_desc') or '',
|
|
'parameters': tool.get('parameters') or {},
|
|
'source': tool.get('source'),
|
|
'source_name': tool.get('source_name'),
|
|
'source_id': tool.get('source_id'),
|
|
}
|
|
}
|
|
)
|
|
|
|
return self.http_status(404, -1, f'Tool not found: {tool_name}')
|