2afa7bb103
- 新增 ServiceConfig 类型和 services 配置字段 - 添加 getServiceApiKey/saveServiceConfig/deleteServiceConfig API - 更新 web_search 和 web_extract 工具使用配置系统 - 新增 /api/services REST 端点管理第三方服务配置
156 lines
3.3 KiB
TypeScript
156 lines
3.3 KiB
TypeScript
/**
|
||
* Services API Routes
|
||
*
|
||
* 第三方服务配置管理 REST API(如 Tavily)
|
||
*/
|
||
|
||
import { Hono } from 'hono';
|
||
import type { ServiceConfig, ServiceType } from '@ai-assistant/core';
|
||
import {
|
||
loadProvidersConfig,
|
||
getServiceConfig,
|
||
saveServiceConfig,
|
||
deleteServiceConfig,
|
||
} from '@ai-assistant/core';
|
||
|
||
export const servicesRouter = new Hono();
|
||
|
||
/** 服务元信息 */
|
||
interface ServiceInfo {
|
||
id: ServiceType;
|
||
name: string;
|
||
description: string;
|
||
website: string;
|
||
}
|
||
|
||
/** 已知服务列表 */
|
||
const KNOWN_SERVICES: ServiceInfo[] = [
|
||
{
|
||
id: 'tavily',
|
||
name: 'Tavily',
|
||
description: '网络搜索和网页内容提取 API',
|
||
website: 'https://tavily.com',
|
||
},
|
||
];
|
||
|
||
/**
|
||
* GET /services - List all services
|
||
*/
|
||
servicesRouter.get('/', async (c) => {
|
||
try {
|
||
const config = await loadProvidersConfig();
|
||
const services = config.services ?? {};
|
||
|
||
const data = KNOWN_SERVICES.map((info) => {
|
||
const serviceConfig = services[info.id];
|
||
return {
|
||
...info,
|
||
enabled: serviceConfig?.enabled ?? false,
|
||
hasApiKey: !!serviceConfig?.apiKey,
|
||
};
|
||
});
|
||
|
||
return c.json({
|
||
success: true,
|
||
data,
|
||
});
|
||
} catch (error) {
|
||
return c.json(
|
||
{
|
||
success: false,
|
||
error: error instanceof Error ? error.message : 'Failed to list services',
|
||
},
|
||
500
|
||
);
|
||
}
|
||
});
|
||
|
||
/**
|
||
* GET /services/:id - Get service config
|
||
*/
|
||
servicesRouter.get('/:id', async (c) => {
|
||
const id = c.req.param('id') as ServiceType;
|
||
|
||
try {
|
||
const info = KNOWN_SERVICES.find((s) => s.id === id);
|
||
if (!info) {
|
||
return c.json({ success: false, error: `Unknown service: ${id}` }, 404);
|
||
}
|
||
|
||
const serviceConfig = await getServiceConfig(id);
|
||
|
||
return c.json({
|
||
success: true,
|
||
data: {
|
||
...info,
|
||
enabled: serviceConfig?.enabled ?? false,
|
||
hasApiKey: !!serviceConfig?.apiKey,
|
||
},
|
||
});
|
||
} catch (error) {
|
||
return c.json(
|
||
{
|
||
success: false,
|
||
error: error instanceof Error ? error.message : 'Failed to get service',
|
||
},
|
||
500
|
||
);
|
||
}
|
||
});
|
||
|
||
/**
|
||
* PUT /services/:id - Update service config
|
||
*/
|
||
servicesRouter.put('/:id', async (c) => {
|
||
const id = c.req.param('id') as ServiceType;
|
||
|
||
try {
|
||
const info = KNOWN_SERVICES.find((s) => s.id === id);
|
||
if (!info) {
|
||
return c.json({ success: false, error: `Unknown service: ${id}` }, 404);
|
||
}
|
||
|
||
const body = await c.req.json();
|
||
const { apiKey, enabled } = body as { apiKey?: string; enabled?: boolean };
|
||
|
||
await saveServiceConfig(id, { apiKey, enabled });
|
||
|
||
return c.json({
|
||
success: true,
|
||
message: `Service ${id} config updated`,
|
||
});
|
||
} catch (error) {
|
||
return c.json(
|
||
{
|
||
success: false,
|
||
error: error instanceof Error ? error.message : 'Failed to update service config',
|
||
},
|
||
400
|
||
);
|
||
}
|
||
});
|
||
|
||
/**
|
||
* DELETE /services/:id - Delete service config
|
||
*/
|
||
servicesRouter.delete('/:id', async (c) => {
|
||
const id = c.req.param('id') as ServiceType;
|
||
|
||
try {
|
||
await deleteServiceConfig(id);
|
||
|
||
return c.json({
|
||
success: true,
|
||
message: `Service ${id} config removed`,
|
||
});
|
||
} catch (error) {
|
||
return c.json(
|
||
{
|
||
success: false,
|
||
error: error instanceof Error ? error.message : 'Failed to remove service config',
|
||
},
|
||
400
|
||
);
|
||
}
|
||
});
|