enh: external tool server custom name/description support

This commit is contained in:
Timothy Jaeryang Baek 2025-05-27 00:10:33 +04:00
parent 20f54616e7
commit a38e44e870
3 changed files with 69 additions and 7 deletions

View File

@ -51,11 +51,11 @@ async def get_tools(request: Request, user=Depends(get_verified_user)):
**{
"id": f"server:{server['idx']}",
"user_id": f"server:{server['idx']}",
"name": server["openapi"]
"name": server.get("openapi", {})
.get("info", {})
.get("title", "Tool Server"),
"meta": {
"description": server["openapi"]
"description": server.get("openapi", {})
.get("info", {})
.get("description", ""),
},

View File

@ -493,6 +493,8 @@ async def get_tool_servers_data(
url_path = server.get("path", "openapi.json")
full_url = f"{server.get('url')}/{url_path}"
info = server.get("info", {})
auth_type = server.get("auth_type", "bearer")
token = None
@ -500,26 +502,37 @@ async def get_tool_servers_data(
token = server.get("key", "")
elif auth_type == "session":
token = session_token
server_entries.append((idx, server, full_url, token))
server_entries.append((idx, server, full_url, info, token))
# Create async tasks to fetch data
tasks = [get_tool_server_data(token, url) for (_, _, url, token) in server_entries]
tasks = [
get_tool_server_data(token, url) for (_, _, url, _, token) in server_entries
]
# Execute tasks concurrently
responses = await asyncio.gather(*tasks, return_exceptions=True)
# Build final results with index and server metadata
results = []
for (idx, server, url, _), response in zip(server_entries, responses):
for (idx, server, url, info, _), response in zip(server_entries, responses):
if isinstance(response, Exception):
log.error(f"Failed to connect to {url} OpenAPI tool server")
continue
openapi_data = response.get("openapi", {})
if info and isinstance(openapi_data, dict):
if "name" in info:
openapi_data["info"]["title"] = info.get("name", "Tool Server")
if "description" in info:
openapi_data["info"]["description"] = info.get("description", "")
results.append(
{
"idx": idx,
"url": server.get("url"),
"openapi": response.get("openapi"),
"openapi": openapi_data,
"info": response.get("info"),
"specs": response.get("specs"),
}

View File

@ -22,7 +22,6 @@
export let edit = false;
export let direct = false;
export let connection = null;
let url = '';
@ -33,6 +32,9 @@
let accessControl = {};
let name = '';
let description = '';
let enable = true;
let loading = false;
@ -69,6 +71,10 @@
config: {
enable: enable,
access_control: accessControl
},
info: {
name,
description
}
}).catch((err) => {
toast.error($i18n.t('Connection failed'));
@ -95,6 +101,10 @@
config: {
enable: enable,
access_control: accessControl
},
info: {
name: name,
description: description
}
};
@ -108,6 +118,9 @@
key = '';
auth_type = 'bearer';
name = '';
description = '';
enable = true;
accessControl = null;
};
@ -120,6 +133,9 @@
auth_type = connection?.auth_type ?? 'bearer';
key = connection?.key ?? '';
name = connection.info?.name ?? '';
description = connection.info?.description ?? '';
enable = connection.config?.enable ?? true;
accessControl = connection.config?.access_control ?? null;
}
@ -276,6 +292,39 @@
{#if !direct}
<hr class=" border-gray-100 dark:border-gray-700/10 my-2.5 w-full" />
<div class="flex gap-2">
<div class="flex flex-col w-full">
<div class=" mb-0.5 text-xs text-gray-500">{$i18n.t('Name')}</div>
<div class="flex-1">
<input
class="w-full text-sm bg-transparent placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden"
type="text"
bind:value={name}
placeholder={$i18n.t('Enter name')}
autocomplete="off"
required
/>
</div>
</div>
</div>
<div class="flex flex-col w-full mt-2">
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Description')}</div>
<div class="flex-1">
<input
class="w-full text-sm bg-transparent placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden"
type="text"
bind:value={description}
placeholder={$i18n.t('Enter description')}
autocomplete="off"
/>
</div>
</div>
<hr class=" border-gray-100 dark:border-gray-700/10 my-2.5 w-full" />
<div class="my-2 -mx-2">
<div class="px-3 py-2 bg-gray-50 dark:bg-gray-950 rounded-lg">
<AccessControl bind:accessControl />