Files
hunjing/frontend/src/app/admin/tools/page.tsx
T
2026-08-21 16:00:13 +08:00

125 lines
4.1 KiB
TypeScript

import { PageContainer } from "@/components/layout/PageContainer";
import { ErrorState, EmptyState } from "@/components/shared/StateViews";
import { ToolRegistry } from "@/components/admin/ToolRegistry";
import { McpServerPanel } from "@/components/admin/mcp/McpServerPanel";
import { GatewayPanel } from "@/components/admin/mcp/GatewayPanel";
import { ToolRuntimeTabs } from "@/components/admin/mcp/ToolRuntimeTabs";
import { SkillManager } from "@/components/tools/SkillManager";
import { serverApi } from "@/lib/api/server-client";
import { describeError } from "@/lib/utils/error";
import type { McpServer, Skill, ToolInfo } from "@/types/api";
export const dynamic = "force-dynamic";
/**
* 百工枢 · 器用技艺治理(对应设计稿 admin-preview.html 百工枢 视图)。
*
* 四标签页:
* ① 工具注册表 — 清单与管理
* ② MCP 服务器 — 外部能力接入
* ③ 玄关网关 — 路由与代理
* ④ Skill 能力包 — 可插拔能力
*/
export default async function AdminToolsPage() {
let tools: ToolInfo[] = [];
let skills: Skill[] = [];
let mcpServers: McpServer[] = [];
let error: string | null = null;
try {
[tools, skills, mcpServers] = await Promise.all([
serverApi.get<ToolInfo[]>("/tools"),
serverApi.get<Skill[]>("/tools/skills"),
serverApi.get<McpServer[]>("/tools/mcp-servers"),
]);
} catch (e) {
error = describeError(e);
}
return (
<PageContainer
title="百工枢"
description="器用技艺 · 能力注册、工具、MCP 与 Skill 统一治理"
maxWidth="max-w-5xl"
>
{error ? (
<ErrorState message={error} />
) : (
<div className="space-y-6">
<ToolRuntimeTabs
tabs={[
{
key: "tools",
label: "工具",
badge: tools.length,
content: (
<section>
<h2 className="mb-3 font-serif text-sm font-semibold text-fg">
工具注册表
</h2>
{tools.length === 0 ? (
<EmptyState
title="暂无注册工具"
description="当前没有注册的工具。"
/>
) : (
<ToolRegistry tools={tools} />
)}
</section>
),
},
{
key: "mcp",
label: "MCP 服务器",
badge: mcpServers.length,
content: (
<section>
<h2 className="mb-3 font-serif text-sm font-semibold text-fg">
MCP 服务器
</h2>
<McpServerPanel initialServers={mcpServers} />
</section>
),
},
{
key: "gateway",
label: "玄关网关",
content: (
<section>
<h2 className="mb-3 font-serif text-sm font-semibold text-fg">
玄关网关管理
</h2>
<GatewayPanel />
</section>
),
},
{
key: "skills",
label: "Skill 能力包",
badge: skills.length,
content: (
<section>
<h2 className="mb-3 font-serif text-sm font-semibold text-fg">
Skill 能力包
</h2>
{skills.length === 0 ? (
<EmptyState
title="暂无 Skill"
description="当前没有安装 Skill 能力包。"
/>
) : (
<SkillManager initial={skills} />
)}
</section>
),
},
]}
defaultTab="tools"
/>
</div>
)}
</PageContainer>
);
}