feat(mcp): add preset setup and capability mentions

This commit is contained in:
Xubin Ren
2026-05-24 19:43:20 +08:00
parent 8be258212e
commit 704ac558f6
54 changed files with 8425 additions and 708 deletions
+106
View File
@@ -1,15 +1,21 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import {
createModelConfiguration,
deleteSession,
fetchCliApps,
fetchMcpPresets,
fetchSidebarState,
fetchWebuiThread,
importMcpConfig,
listSessions,
listSlashCommands,
runCliAppAction,
runMcpPresetAction,
saveCustomMcpServer,
updateSidebarState,
updateImageGenerationSettings,
updateMcpServerTools,
updateProviderSettings,
updateSettings,
updateWebSearchSettings,
@@ -68,6 +74,21 @@ describe("webui API helpers", () => {
);
});
it("serializes model configuration creation", async () => {
await createModelConfiguration("tok", {
label: "Fast writing",
provider: "openai",
model: "openai/gpt-4.1-mini",
});
expect(fetch).toHaveBeenCalledWith(
"/api/settings/model-configurations/create?label=Fast+writing&provider=openai&model=openai%2Fgpt-4.1-mini",
expect.objectContaining({
headers: { Authorization: "Bearer tok" },
}),
);
});
it("serializes provider settings updates without returning secrets", async () => {
await updateProviderSettings("tok", {
provider: "openrouter",
@@ -145,6 +166,91 @@ describe("webui API helpers", () => {
);
});
it("reads MCP presets and serializes actions", async () => {
vi.mocked(fetch).mockResolvedValueOnce({
ok: true,
json: async () => ({
presets: [],
installed_count: 0,
}),
} as Response);
await expect(fetchMcpPresets("tok")).resolves.toMatchObject({ presets: [] });
expect(fetch).toHaveBeenCalledWith(
"/api/settings/mcp-presets",
expect.objectContaining({
headers: { Authorization: "Bearer tok" },
}),
);
await runMcpPresetAction("tok", "enable", "browserbase", {
browserbase_api_key: "bb_live_test",
});
expect(fetch).toHaveBeenCalledWith(
"/api/settings/mcp-presets/enable?name=browserbase",
expect.objectContaining({
headers: expect.objectContaining({
Authorization: "Bearer tok",
"X-Nanobot-MCP-Values": JSON.stringify({
browserbase_api_key: "bb_live_test",
}),
}),
}),
);
});
it("serializes custom MCP, mcp.json import, and tool allowlist actions", async () => {
await saveCustomMcpServer("tok", {
name: "docs",
transport: "stdio",
command: "npx",
args: '["-y","docs-mcp"]',
env: '{"API_KEY":"secret"}',
});
expect(fetch).toHaveBeenCalledWith(
"/api/settings/mcp-presets/custom",
expect.objectContaining({
headers: expect.objectContaining({
Authorization: "Bearer tok",
"X-Nanobot-MCP-Values": JSON.stringify({
name: "docs",
transport: "stdio",
command: "npx",
args: '["-y","docs-mcp"]',
env: '{"API_KEY":"secret"}',
}),
}),
}),
);
await importMcpConfig("tok", '{"mcpServers":{"docs":{"command":"npx"}}}');
expect(fetch).toHaveBeenCalledWith(
"/api/settings/mcp-presets/import",
expect.objectContaining({
headers: expect.objectContaining({
Authorization: "Bearer tok",
"X-Nanobot-MCP-Values": JSON.stringify({
config: '{"mcpServers":{"docs":{"command":"npx"}}}',
}),
}),
}),
);
await updateMcpServerTools("tok", "docs", ["search", "fetch"]);
expect(fetch).toHaveBeenCalledWith(
"/api/settings/mcp-presets/tools",
expect.objectContaining({
headers: expect.objectContaining({
Authorization: "Bearer tok",
"X-Nanobot-MCP-Values": JSON.stringify({
name: "docs",
enabled_tools: ["search", "fetch"],
}),
}),
}),
);
});
it("reads and writes persisted sidebar state", async () => {
const state = {
schema_version: 1,