@open-mercato/ai-assistant 0.4.2-canary-c02407ff85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1090 -0
- package/README.md +607 -0
- package/build.mjs +92 -0
- package/dist/di.js +8 -0
- package/dist/di.js.map +7 -0
- package/dist/frontend/components/CommandPalette/CommandFooter.js +80 -0
- package/dist/frontend/components/CommandPalette/CommandFooter.js.map +7 -0
- package/dist/frontend/components/CommandPalette/CommandHeader.js +53 -0
- package/dist/frontend/components/CommandPalette/CommandHeader.js.map +7 -0
- package/dist/frontend/components/CommandPalette/CommandInput.js +29 -0
- package/dist/frontend/components/CommandPalette/CommandInput.js.map +7 -0
- package/dist/frontend/components/CommandPalette/CommandItem.js +92 -0
- package/dist/frontend/components/CommandPalette/CommandItem.js.map +7 -0
- package/dist/frontend/components/CommandPalette/CommandPalette.js +244 -0
- package/dist/frontend/components/CommandPalette/CommandPalette.js.map +7 -0
- package/dist/frontend/components/CommandPalette/CommandPaletteProvider.js +42 -0
- package/dist/frontend/components/CommandPalette/CommandPaletteProvider.js.map +7 -0
- package/dist/frontend/components/CommandPalette/CommandPaletteWrapper.js +18 -0
- package/dist/frontend/components/CommandPalette/CommandPaletteWrapper.js.map +7 -0
- package/dist/frontend/components/CommandPalette/DebugPanel.js +215 -0
- package/dist/frontend/components/CommandPalette/DebugPanel.js.map +7 -0
- package/dist/frontend/components/CommandPalette/MessageBubble.js +64 -0
- package/dist/frontend/components/CommandPalette/MessageBubble.js.map +7 -0
- package/dist/frontend/components/CommandPalette/ToolCallConfirmation.js +91 -0
- package/dist/frontend/components/CommandPalette/ToolCallConfirmation.js.map +7 -0
- package/dist/frontend/components/CommandPalette/ToolCallDisplay.js +47 -0
- package/dist/frontend/components/CommandPalette/ToolCallDisplay.js.map +7 -0
- package/dist/frontend/components/CommandPalette/ToolChatPage.js +74 -0
- package/dist/frontend/components/CommandPalette/ToolChatPage.js.map +7 -0
- package/dist/frontend/components/CommandPalette/index.js +28 -0
- package/dist/frontend/components/CommandPalette/index.js.map +7 -0
- package/dist/frontend/constants.js +41 -0
- package/dist/frontend/constants.js.map +7 -0
- package/dist/frontend/hooks/index.js +13 -0
- package/dist/frontend/hooks/index.js.map +7 -0
- package/dist/frontend/hooks/useCommandPalette.js +1094 -0
- package/dist/frontend/hooks/useCommandPalette.js.map +7 -0
- package/dist/frontend/hooks/useMcpTools.js +66 -0
- package/dist/frontend/hooks/useMcpTools.js.map +7 -0
- package/dist/frontend/hooks/usePageContext.js +48 -0
- package/dist/frontend/hooks/usePageContext.js.map +7 -0
- package/dist/frontend/hooks/useRecentActions.js +56 -0
- package/dist/frontend/hooks/useRecentActions.js.map +7 -0
- package/dist/frontend/hooks/useRecentTools.js +55 -0
- package/dist/frontend/hooks/useRecentTools.js.map +7 -0
- package/dist/frontend/index.js +35 -0
- package/dist/frontend/index.js.map +7 -0
- package/dist/frontend/types.js +1 -0
- package/dist/frontend/types.js.map +7 -0
- package/dist/frontend/utils/index.js +7 -0
- package/dist/frontend/utils/index.js.map +7 -0
- package/dist/frontend/utils/toolMatcher.js +95 -0
- package/dist/frontend/utils/toolMatcher.js.map +7 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +7 -0
- package/dist/modules/ai_assistant/acl.js +14 -0
- package/dist/modules/ai_assistant/acl.js.map +7 -0
- package/dist/modules/ai_assistant/api/chat/route.js +152 -0
- package/dist/modules/ai_assistant/api/chat/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/health/route.js +27 -0
- package/dist/modules/ai_assistant/api/health/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/route/route.js +123 -0
- package/dist/modules/ai_assistant/api/route/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/settings/route.js +60 -0
- package/dist/modules/ai_assistant/api/settings/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/tools/execute/route.js +58 -0
- package/dist/modules/ai_assistant/api/tools/execute/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/tools/route.js +48 -0
- package/dist/modules/ai_assistant/api/tools/route.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/page.js +10 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/page.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/page.meta.js +28 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/page.meta.js.map +7 -0
- package/dist/modules/ai_assistant/cli.js +192 -0
- package/dist/modules/ai_assistant/cli.js.map +7 -0
- package/dist/modules/ai_assistant/di.js +11 -0
- package/dist/modules/ai_assistant/di.js.map +7 -0
- package/dist/modules/ai_assistant/frontend/components/AiAssistantSettingsPageClient.js +257 -0
- package/dist/modules/ai_assistant/frontend/components/AiAssistantSettingsPageClient.js.map +7 -0
- package/dist/modules/ai_assistant/index.js +13 -0
- package/dist/modules/ai_assistant/index.js.map +7 -0
- package/dist/modules/ai_assistant/lib/ai-sdk.js +13 -0
- package/dist/modules/ai_assistant/lib/ai-sdk.js.map +7 -0
- package/dist/modules/ai_assistant/lib/api-discovery-tools.js +249 -0
- package/dist/modules/ai_assistant/lib/api-discovery-tools.js.map +7 -0
- package/dist/modules/ai_assistant/lib/api-endpoint-index-config.js +177 -0
- package/dist/modules/ai_assistant/lib/api-endpoint-index-config.js.map +7 -0
- package/dist/modules/ai_assistant/lib/api-endpoint-index.js +210 -0
- package/dist/modules/ai_assistant/lib/api-endpoint-index.js.map +7 -0
- package/dist/modules/ai_assistant/lib/auth.js +87 -0
- package/dist/modules/ai_assistant/lib/auth.js.map +7 -0
- package/dist/modules/ai_assistant/lib/chat-config.js +117 -0
- package/dist/modules/ai_assistant/lib/chat-config.js.map +7 -0
- package/dist/modules/ai_assistant/lib/client-factory.js +60 -0
- package/dist/modules/ai_assistant/lib/client-factory.js.map +7 -0
- package/dist/modules/ai_assistant/lib/http-server.js +367 -0
- package/dist/modules/ai_assistant/lib/http-server.js.map +7 -0
- package/dist/modules/ai_assistant/lib/in-process-client.js +126 -0
- package/dist/modules/ai_assistant/lib/in-process-client.js.map +7 -0
- package/dist/modules/ai_assistant/lib/mcp-client.js +146 -0
- package/dist/modules/ai_assistant/lib/mcp-client.js.map +7 -0
- package/dist/modules/ai_assistant/lib/mcp-dev-server.js +283 -0
- package/dist/modules/ai_assistant/lib/mcp-dev-server.js.map +7 -0
- package/dist/modules/ai_assistant/lib/mcp-server-config.js +160 -0
- package/dist/modules/ai_assistant/lib/mcp-server-config.js.map +7 -0
- package/dist/modules/ai_assistant/lib/mcp-server.js +156 -0
- package/dist/modules/ai_assistant/lib/mcp-server.js.map +7 -0
- package/dist/modules/ai_assistant/lib/mcp-tool-adapter.js +44 -0
- package/dist/modules/ai_assistant/lib/mcp-tool-adapter.js.map +7 -0
- package/dist/modules/ai_assistant/lib/opencode-client.js +247 -0
- package/dist/modules/ai_assistant/lib/opencode-client.js.map +7 -0
- package/dist/modules/ai_assistant/lib/opencode-handlers.js +398 -0
- package/dist/modules/ai_assistant/lib/opencode-handlers.js.map +7 -0
- package/dist/modules/ai_assistant/lib/schema-utils.js +94 -0
- package/dist/modules/ai_assistant/lib/schema-utils.js.map +7 -0
- package/dist/modules/ai_assistant/lib/tool-executor.js +55 -0
- package/dist/modules/ai_assistant/lib/tool-executor.js.map +7 -0
- package/dist/modules/ai_assistant/lib/tool-index-config.js +125 -0
- package/dist/modules/ai_assistant/lib/tool-index-config.js.map +7 -0
- package/dist/modules/ai_assistant/lib/tool-loader.js +88 -0
- package/dist/modules/ai_assistant/lib/tool-loader.js.map +7 -0
- package/dist/modules/ai_assistant/lib/tool-registry.js +65 -0
- package/dist/modules/ai_assistant/lib/tool-registry.js.map +7 -0
- package/dist/modules/ai_assistant/lib/tool-search.js +192 -0
- package/dist/modules/ai_assistant/lib/tool-search.js.map +7 -0
- package/dist/modules/ai_assistant/lib/types.js +1 -0
- package/dist/modules/ai_assistant/lib/types.js.map +7 -0
- package/package.json +108 -0
- package/src/di.ts +11 -0
- package/src/frontend/components/CommandPalette/CommandFooter.tsx +113 -0
- package/src/frontend/components/CommandPalette/CommandHeader.tsx +76 -0
- package/src/frontend/components/CommandPalette/CommandInput.tsx +50 -0
- package/src/frontend/components/CommandPalette/CommandItem.tsx +111 -0
- package/src/frontend/components/CommandPalette/CommandPalette.tsx +276 -0
- package/src/frontend/components/CommandPalette/CommandPaletteProvider.tsx +60 -0
- package/src/frontend/components/CommandPalette/CommandPaletteWrapper.tsx +21 -0
- package/src/frontend/components/CommandPalette/DebugPanel.tsx +257 -0
- package/src/frontend/components/CommandPalette/MessageBubble.tsx +73 -0
- package/src/frontend/components/CommandPalette/ToolCallConfirmation.tsx +130 -0
- package/src/frontend/components/CommandPalette/ToolCallDisplay.tsx +57 -0
- package/src/frontend/components/CommandPalette/ToolChatPage.tsx +125 -0
- package/src/frontend/components/CommandPalette/index.ts +14 -0
- package/src/frontend/constants.ts +35 -0
- package/src/frontend/hooks/index.ts +5 -0
- package/src/frontend/hooks/useCommandPalette.ts +1389 -0
- package/src/frontend/hooks/useMcpTools.ts +73 -0
- package/src/frontend/hooks/usePageContext.ts +61 -0
- package/src/frontend/hooks/useRecentActions.ts +64 -0
- package/src/frontend/hooks/useRecentTools.ts +69 -0
- package/src/frontend/index.ts +39 -0
- package/src/frontend/types.ts +260 -0
- package/src/frontend/utils/index.ts +1 -0
- package/src/frontend/utils/toolMatcher.ts +127 -0
- package/src/index.ts +92 -0
- package/src/modules/ai_assistant/acl.ts +10 -0
- package/src/modules/ai_assistant/api/chat/route.ts +213 -0
- package/src/modules/ai_assistant/api/health/route.ts +30 -0
- package/src/modules/ai_assistant/api/route/route.ts +149 -0
- package/src/modules/ai_assistant/api/settings/route.ts +73 -0
- package/src/modules/ai_assistant/api/tools/execute/route.ts +71 -0
- package/src/modules/ai_assistant/api/tools/route.ts +57 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/page.meta.ts +26 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/page.tsx +12 -0
- package/src/modules/ai_assistant/cli.ts +233 -0
- package/src/modules/ai_assistant/di.ts +9 -0
- package/src/modules/ai_assistant/frontend/components/AiAssistantSettingsPageClient.tsx +418 -0
- package/src/modules/ai_assistant/index.ts +11 -0
- package/src/modules/ai_assistant/lib/ai-sdk.ts +5 -0
- package/src/modules/ai_assistant/lib/api-discovery-tools.ts +334 -0
- package/src/modules/ai_assistant/lib/api-endpoint-index-config.ts +243 -0
- package/src/modules/ai_assistant/lib/api-endpoint-index.ts +381 -0
- package/src/modules/ai_assistant/lib/auth.ts +185 -0
- package/src/modules/ai_assistant/lib/chat-config.ts +152 -0
- package/src/modules/ai_assistant/lib/client-factory.ts +130 -0
- package/src/modules/ai_assistant/lib/http-server.ts +498 -0
- package/src/modules/ai_assistant/lib/in-process-client.ts +205 -0
- package/src/modules/ai_assistant/lib/mcp-client.ts +221 -0
- package/src/modules/ai_assistant/lib/mcp-dev-server.ts +373 -0
- package/src/modules/ai_assistant/lib/mcp-server-config.ts +287 -0
- package/src/modules/ai_assistant/lib/mcp-server.ts +214 -0
- package/src/modules/ai_assistant/lib/mcp-tool-adapter.ts +76 -0
- package/src/modules/ai_assistant/lib/opencode-client.ts +426 -0
- package/src/modules/ai_assistant/lib/opencode-handlers.ts +676 -0
- package/src/modules/ai_assistant/lib/schema-utils.ts +142 -0
- package/src/modules/ai_assistant/lib/tool-executor.ts +71 -0
- package/src/modules/ai_assistant/lib/tool-index-config.ts +178 -0
- package/src/modules/ai_assistant/lib/tool-loader.ts +149 -0
- package/src/modules/ai_assistant/lib/tool-registry.ts +114 -0
- package/src/modules/ai_assistant/lib/tool-search.ts +308 -0
- package/src/modules/ai_assistant/lib/types.ts +147 -0
- package/test-schema.ts +37 -0
- package/tsconfig.json +10 -0
- package/watch.mjs +6 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
3
|
+
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
|
|
4
|
+
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
|
|
5
|
+
import { getToolRegistry } from "../../lib/tool-registry.js";
|
|
6
|
+
import { loadAllModuleTools } from "../../lib/tool-loader.js";
|
|
7
|
+
import { hasRequiredFeatures } from "../../lib/auth.js";
|
|
8
|
+
const metadata = {
|
|
9
|
+
GET: { requireAuth: true, requireFeatures: ["ai_assistant.view"] }
|
|
10
|
+
};
|
|
11
|
+
async function GET(req) {
|
|
12
|
+
const auth = await getAuthFromRequest(req);
|
|
13
|
+
if (!auth) {
|
|
14
|
+
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const container = await createRequestContainer();
|
|
18
|
+
const rbacService = container.resolve("rbacService");
|
|
19
|
+
const acl = await rbacService.loadAcl(auth.sub, {
|
|
20
|
+
tenantId: auth.tenantId,
|
|
21
|
+
organizationId: auth.orgId
|
|
22
|
+
});
|
|
23
|
+
await loadAllModuleTools();
|
|
24
|
+
const registry = getToolRegistry();
|
|
25
|
+
const allTools = Array.from(registry.getTools().values());
|
|
26
|
+
const accessibleTools = allTools.filter(
|
|
27
|
+
(tool) => hasRequiredFeatures(tool.requiredFeatures, acl.features, acl.isSuperAdmin)
|
|
28
|
+
);
|
|
29
|
+
const tools = accessibleTools.map((tool) => {
|
|
30
|
+
const nameParts = tool.name.split(".");
|
|
31
|
+
return {
|
|
32
|
+
name: tool.name,
|
|
33
|
+
description: tool.description,
|
|
34
|
+
inputSchema: zodToJsonSchema(tool.inputSchema),
|
|
35
|
+
module: nameParts[0] || "other"
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
return NextResponse.json({ tools });
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error("[AI Tools] Error listing tools:", error);
|
|
41
|
+
return NextResponse.json({ error: "Failed to list tools" }, { status: 500 });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
GET,
|
|
46
|
+
metadata
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/ai_assistant/api/tools/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { NextResponse, type NextRequest } from 'next/server'\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getToolRegistry } from '../../lib/tool-registry'\nimport { loadAllModuleTools } from '../../lib/tool-loader'\nimport { hasRequiredFeatures } from '../../lib/auth'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['ai_assistant.view'] },\n}\n\nexport async function GET(req: NextRequest) {\n const auth = await getAuthFromRequest(req)\n\n if (!auth) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n\n try {\n const container = await createRequestContainer()\n const rbacService = container.resolve<RbacService>('rbacService')\n\n // Load ACL for user\n const acl = await rbacService.loadAcl(auth.sub, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n })\n\n // Ensure tools are loaded\n await loadAllModuleTools()\n\n // Get tools filtered by ACL\n const registry = getToolRegistry()\n const allTools = Array.from(registry.getTools().values())\n\n const accessibleTools = allTools.filter((tool) =>\n hasRequiredFeatures(tool.requiredFeatures, acl.features, acl.isSuperAdmin)\n )\n\n const tools = accessibleTools.map((tool) => {\n const nameParts = tool.name.split('.')\n return {\n name: tool.name,\n description: tool.description,\n inputSchema: zodToJsonSchema(tool.inputSchema as any) as Record<string, unknown>,\n module: nameParts[0] || 'other',\n }\n })\n\n return NextResponse.json({ tools })\n } catch (error) {\n console.error('[AI Tools] Error listing tools:', error)\n return NextResponse.json({ error: 'Failed to list tools' }, { status: 500 })\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,oBAAsC;AAC/C,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,2BAA2B;AAG7B,MAAM,WAAW;AAAA,EACtB,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,mBAAmB,EAAE;AACnE;AAEA,eAAsB,IAAI,KAAkB;AAC1C,QAAM,OAAO,MAAM,mBAAmB,GAAG;AAEzC,MAAI,CAAC,MAAM;AACT,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AAEA,MAAI;AACF,UAAM,YAAY,MAAM,uBAAuB;AAC/C,UAAM,cAAc,UAAU,QAAqB,aAAa;AAGhE,UAAM,MAAM,MAAM,YAAY,QAAQ,KAAK,KAAK;AAAA,MAC9C,UAAU,KAAK;AAAA,MACf,gBAAgB,KAAK;AAAA,IACvB,CAAC;AAGD,UAAM,mBAAmB;AAGzB,UAAM,WAAW,gBAAgB;AACjC,UAAM,WAAW,MAAM,KAAK,SAAS,SAAS,EAAE,OAAO,CAAC;AAExD,UAAM,kBAAkB,SAAS;AAAA,MAAO,CAAC,SACvC,oBAAoB,KAAK,kBAAkB,IAAI,UAAU,IAAI,YAAY;AAAA,IAC3E;AAEA,UAAM,QAAQ,gBAAgB,IAAI,CAAC,SAAS;AAC1C,YAAM,YAAY,KAAK,KAAK,MAAM,GAAG;AACrC,aAAO;AAAA,QACL,MAAM,KAAK;AAAA,QACX,aAAa,KAAK;AAAA,QAClB,aAAa,gBAAgB,KAAK,WAAkB;AAAA,QACpD,QAAQ,UAAU,CAAC,KAAK;AAAA,MAC1B;AAAA,IACF,CAAC;AAED,WAAO,aAAa,KAAK,EAAE,MAAM,CAAC;AAAA,EACpC,SAAS,OAAO;AACd,YAAQ,MAAM,mCAAmC,KAAK;AACtD,WAAO,aAAa,KAAK,EAAE,OAAO,uBAAuB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC7E;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Page, PageBody } from "@open-mercato/ui/backend/Page";
|
|
3
|
+
import { AiAssistantSettingsPageClient } from "../../../frontend/components/AiAssistantSettingsPageClient.js";
|
|
4
|
+
async function AiAssistantSettingsPage() {
|
|
5
|
+
return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsx(AiAssistantSettingsPageClient, {}) }) });
|
|
6
|
+
}
|
|
7
|
+
export {
|
|
8
|
+
AiAssistantSettingsPage as default
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=page.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/ai_assistant/backend/config/ai-assistant/page.tsx"],
|
|
4
|
+
"sourcesContent": ["import { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { AiAssistantSettingsPageClient } from '../../../frontend/components/AiAssistantSettingsPageClient'\n\nexport default async function AiAssistantSettingsPage() {\n return (\n <Page>\n <PageBody>\n <AiAssistantSettingsPageClient />\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "AAOQ;AAPR,SAAS,MAAM,gBAAgB;AAC/B,SAAS,qCAAqC;AAE9C,eAAO,0BAAiD;AACtD,SACE,oBAAC,QACC,8BAAC,YACC,8BAAC,iCAA8B,GACjC,GACF;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
const aiIcon = React.createElement(
|
|
3
|
+
"svg",
|
|
4
|
+
{ width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" },
|
|
5
|
+
React.createElement("path", { d: "M12 8V4H8" }),
|
|
6
|
+
React.createElement("rect", { width: 16, height: 12, x: 4, y: 8, rx: 2 }),
|
|
7
|
+
React.createElement("path", { d: "M2 14h2" }),
|
|
8
|
+
React.createElement("path", { d: "M20 14h2" }),
|
|
9
|
+
React.createElement("path", { d: "M15 13v2" }),
|
|
10
|
+
React.createElement("path", { d: "M9 13v2" })
|
|
11
|
+
);
|
|
12
|
+
const metadata = {
|
|
13
|
+
requireAuth: true,
|
|
14
|
+
requireFeatures: ["ai_assistant.view"],
|
|
15
|
+
pageTitle: "AI Assistant",
|
|
16
|
+
pageTitleKey: "ai_assistant.config.nav.settings",
|
|
17
|
+
pageGroup: "Configuration",
|
|
18
|
+
pageGroupKey: "backend.nav.configuration",
|
|
19
|
+
pageOrder: 430,
|
|
20
|
+
icon: aiIcon,
|
|
21
|
+
breadcrumb: [
|
|
22
|
+
{ label: "AI Assistant", labelKey: "ai_assistant.config.nav.settings" }
|
|
23
|
+
]
|
|
24
|
+
};
|
|
25
|
+
export {
|
|
26
|
+
metadata
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=page.meta.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/ai_assistant/backend/config/ai-assistant/page.meta.ts"],
|
|
4
|
+
"sourcesContent": ["import React from 'react'\n\nconst aiIcon = React.createElement(\n 'svg',\n { width: 16, height: 16, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' },\n React.createElement('path', { d: 'M12 8V4H8' }),\n React.createElement('rect', { width: 16, height: 12, x: 4, y: 8, rx: 2 }),\n React.createElement('path', { d: 'M2 14h2' }),\n React.createElement('path', { d: 'M20 14h2' }),\n React.createElement('path', { d: 'M15 13v2' }),\n React.createElement('path', { d: 'M9 13v2' }),\n)\n\nexport const metadata = {\n requireAuth: true,\n requireFeatures: ['ai_assistant.view'],\n pageTitle: 'AI Assistant',\n pageTitleKey: 'ai_assistant.config.nav.settings',\n pageGroup: 'Configuration',\n pageGroupKey: 'backend.nav.configuration',\n pageOrder: 430,\n icon: aiIcon,\n breadcrumb: [\n { label: 'AI Assistant', labelKey: 'ai_assistant.config.nav.settings' },\n ],\n} as const\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,WAAW;AAElB,MAAM,SAAS,MAAM;AAAA,EACnB;AAAA,EACA,EAAE,OAAO,IAAI,QAAQ,IAAI,SAAS,aAAa,MAAM,QAAQ,QAAQ,gBAAgB,aAAa,GAAG,eAAe,SAAS,gBAAgB,QAAQ;AAAA,EACrJ,MAAM,cAAc,QAAQ,EAAE,GAAG,YAAY,CAAC;AAAA,EAC9C,MAAM,cAAc,QAAQ,EAAE,OAAO,IAAI,QAAQ,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC;AAAA,EACxE,MAAM,cAAc,QAAQ,EAAE,GAAG,UAAU,CAAC;AAAA,EAC5C,MAAM,cAAc,QAAQ,EAAE,GAAG,WAAW,CAAC;AAAA,EAC7C,MAAM,cAAc,QAAQ,EAAE,GAAG,WAAW,CAAC;AAAA,EAC7C,MAAM,cAAc,QAAQ,EAAE,GAAG,UAAU,CAAC;AAC9C;AAEO,MAAM,WAAW;AAAA,EACtB,aAAa;AAAA,EACb,iBAAiB,CAAC,mBAAmB;AAAA,EACrC,WAAW;AAAA,EACX,cAAc;AAAA,EACd,WAAW;AAAA,EACX,cAAc;AAAA,EACd,WAAW;AAAA,EACX,MAAM;AAAA,EACN,YAAY;AAAA,IACV,EAAE,OAAO,gBAAgB,UAAU,mCAAmC;AAAA,EACxE;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
async function ensureBootstrap() {
|
|
6
|
+
try {
|
|
7
|
+
const { getDiRegistrars } = await import("@open-mercato/shared/lib/di/container");
|
|
8
|
+
getDiRegistrars();
|
|
9
|
+
return;
|
|
10
|
+
} catch {
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = dirname(__filename);
|
|
15
|
+
const bootstrapPath = resolve(__dirname, "../../../../../../apps/mercato/src/bootstrap.ts");
|
|
16
|
+
const bootstrapUrl = pathToFileURL(bootstrapPath).href;
|
|
17
|
+
const { bootstrap, isBootstrapped } = await import(bootstrapUrl);
|
|
18
|
+
if (!isBootstrapped()) {
|
|
19
|
+
bootstrap();
|
|
20
|
+
}
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.error("[MCP] Bootstrap failed:", error instanceof Error ? error.message : error);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function parseArgs(rest) {
|
|
26
|
+
const args = {};
|
|
27
|
+
for (let i = 0; i < rest.length; i++) {
|
|
28
|
+
const arg = rest[i];
|
|
29
|
+
if (!arg?.startsWith("--")) continue;
|
|
30
|
+
const [key, value] = arg.replace(/^--/, "").split("=");
|
|
31
|
+
if (value !== void 0) {
|
|
32
|
+
args[key] = value;
|
|
33
|
+
} else if (rest[i + 1] && !rest[i + 1].startsWith("--")) {
|
|
34
|
+
args[key] = rest[i + 1];
|
|
35
|
+
i++;
|
|
36
|
+
} else {
|
|
37
|
+
args[key] = true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return args;
|
|
41
|
+
}
|
|
42
|
+
const mcpServe = {
|
|
43
|
+
command: "mcp:serve",
|
|
44
|
+
async run(rest) {
|
|
45
|
+
const args = parseArgs(rest);
|
|
46
|
+
const apiKey = String(args["api-key"] ?? args.apiKey ?? "") || null;
|
|
47
|
+
const tenantId = String(args.tenant ?? args.tenantId ?? "") || null;
|
|
48
|
+
const organizationId = String(args.org ?? args.organizationId ?? "") || null;
|
|
49
|
+
const userId = String(args.user ?? args.userId ?? "") || null;
|
|
50
|
+
const debug = args.debug === true || args.debug === "true";
|
|
51
|
+
if (!apiKey && !tenantId) {
|
|
52
|
+
console.error("Usage: mercato ai_assistant mcp:serve [options]");
|
|
53
|
+
console.error("");
|
|
54
|
+
console.error("Authentication (choose one):");
|
|
55
|
+
console.error(" --api-key <secret> API key secret for authentication (recommended)");
|
|
56
|
+
console.error(" --tenant <id> Tenant ID (for manual context)");
|
|
57
|
+
console.error("");
|
|
58
|
+
console.error("Options (with --tenant):");
|
|
59
|
+
console.error(" --org <id> Organization ID (optional)");
|
|
60
|
+
console.error(" --user <id> User ID for ACL (optional, uses superadmin if not set)");
|
|
61
|
+
console.error("");
|
|
62
|
+
console.error("Common options:");
|
|
63
|
+
console.error(" --debug Enable debug logging");
|
|
64
|
+
console.error("");
|
|
65
|
+
console.error("Examples:");
|
|
66
|
+
console.error(" mercato ai_assistant mcp:serve --api-key omk_xxxx.yyyy...");
|
|
67
|
+
console.error(" mercato ai_assistant mcp:serve --tenant 123e4567-e89b-12d3-a456-426614174000");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
await ensureBootstrap();
|
|
71
|
+
const container = await createRequestContainer();
|
|
72
|
+
const { runMcpServer } = await import("./lib/mcp-server.js");
|
|
73
|
+
if (apiKey) {
|
|
74
|
+
await runMcpServer({
|
|
75
|
+
config: {
|
|
76
|
+
name: "open-mercato-mcp",
|
|
77
|
+
version: "0.1.0",
|
|
78
|
+
debug
|
|
79
|
+
},
|
|
80
|
+
container,
|
|
81
|
+
apiKeySecret: apiKey
|
|
82
|
+
});
|
|
83
|
+
} else {
|
|
84
|
+
await runMcpServer({
|
|
85
|
+
config: {
|
|
86
|
+
name: "open-mercato-mcp",
|
|
87
|
+
version: "0.1.0",
|
|
88
|
+
debug
|
|
89
|
+
},
|
|
90
|
+
container,
|
|
91
|
+
context: {
|
|
92
|
+
tenantId,
|
|
93
|
+
organizationId,
|
|
94
|
+
userId
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const mcpServeHttp = {
|
|
101
|
+
command: "mcp:serve-http",
|
|
102
|
+
async run(rest) {
|
|
103
|
+
const args = parseArgs(rest);
|
|
104
|
+
const port = parseInt(String(args.port ?? ""), 10);
|
|
105
|
+
const debug = args.debug === true || args.debug === "true";
|
|
106
|
+
if (!port || isNaN(port)) {
|
|
107
|
+
console.error("Usage: mercato ai_assistant mcp:serve-http --port <port> [options]");
|
|
108
|
+
console.error("");
|
|
109
|
+
console.error("Options:");
|
|
110
|
+
console.error(" --port <number> Port to listen on (required)");
|
|
111
|
+
console.error(" --debug Enable debug logging");
|
|
112
|
+
console.error("");
|
|
113
|
+
console.error("Authentication:");
|
|
114
|
+
console.error(" Clients must provide API key via x-api-key header");
|
|
115
|
+
console.error("");
|
|
116
|
+
console.error("Example:");
|
|
117
|
+
console.error(" mercato ai_assistant mcp:serve-http --port 3001");
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
await ensureBootstrap();
|
|
121
|
+
const container = await createRequestContainer();
|
|
122
|
+
const { runMcpHttpServer } = await import("./lib/http-server.js");
|
|
123
|
+
await runMcpHttpServer({
|
|
124
|
+
config: {
|
|
125
|
+
name: "open-mercato-mcp",
|
|
126
|
+
version: "0.1.0",
|
|
127
|
+
debug
|
|
128
|
+
},
|
|
129
|
+
container,
|
|
130
|
+
port
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const mcpDev = {
|
|
135
|
+
command: "mcp:dev",
|
|
136
|
+
async run() {
|
|
137
|
+
await ensureBootstrap();
|
|
138
|
+
const { runMcpDevServer } = await import("./lib/mcp-dev-server.js");
|
|
139
|
+
await runMcpDevServer();
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const listTools = {
|
|
143
|
+
command: "mcp:list-tools",
|
|
144
|
+
async run(rest) {
|
|
145
|
+
const args = parseArgs(rest);
|
|
146
|
+
const verbose = args.verbose === true || args.verbose === "true";
|
|
147
|
+
const { loadAllModuleTools } = await import("./lib/tool-loader.js");
|
|
148
|
+
await loadAllModuleTools();
|
|
149
|
+
const { getToolRegistry } = await import("./lib/tool-registry.js");
|
|
150
|
+
const registry = getToolRegistry();
|
|
151
|
+
const toolNames = registry.listToolNames();
|
|
152
|
+
if (toolNames.length === 0) {
|
|
153
|
+
console.log("\nNo MCP tools registered.");
|
|
154
|
+
console.log("Tools can be registered by modules using registerMcpTool().\n");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
console.log(`
|
|
158
|
+
Registered MCP Tools (${toolNames.length}):
|
|
159
|
+
`);
|
|
160
|
+
const byModule = /* @__PURE__ */ new Map();
|
|
161
|
+
for (const name of toolNames) {
|
|
162
|
+
const [module] = name.split(".");
|
|
163
|
+
const list = byModule.get(module) ?? [];
|
|
164
|
+
list.push(name);
|
|
165
|
+
byModule.set(module, list);
|
|
166
|
+
}
|
|
167
|
+
const sortedModules = Array.from(byModule.keys()).sort();
|
|
168
|
+
for (const module of sortedModules) {
|
|
169
|
+
const tools = byModule.get(module);
|
|
170
|
+
console.log(`${module} (${tools.length} tools):`);
|
|
171
|
+
for (const name of tools.sort()) {
|
|
172
|
+
const tool = registry.getTool(name);
|
|
173
|
+
if (!tool) continue;
|
|
174
|
+
if (verbose) {
|
|
175
|
+
console.log(` ${name}`);
|
|
176
|
+
console.log(` ${tool.description}`);
|
|
177
|
+
if (tool.requiredFeatures?.length) {
|
|
178
|
+
console.log(` Requires: ${tool.requiredFeatures.join(", ")}`);
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
console.log(` - ${name}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
console.log("");
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
var cli_default = [mcpServe, mcpServeHttp, mcpDev, listTools];
|
|
189
|
+
export {
|
|
190
|
+
cli_default as default
|
|
191
|
+
};
|
|
192
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/ai_assistant/cli.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ModuleCli } from '@open-mercato/shared/modules/registry'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\n\n/**\n * Ensure app bootstrap is called before creating DI container.\n * Uses import.meta.url for runtime path resolution since @/ alias\n * doesn't work with dynamic imports (TypeScript path aliases are\n * compile-time only, not available to Node.js at runtime).\n */\nasync function ensureBootstrap(): Promise<void> {\n // First check if DI is already available\n try {\n const { getDiRegistrars } = await import('@open-mercato/shared/lib/di/container')\n getDiRegistrars()\n return // DI already available\n } catch {\n // DI not available, need to bootstrap\n }\n\n // Construct absolute path to bootstrap using import.meta.url\n try {\n const __filename = fileURLToPath(import.meta.url)\n const __dirname = dirname(__filename)\n // From packages/ai-assistant/src/modules/ai_assistant/cli.ts\n // to apps/mercato/src/bootstrap.ts:\n // ai_assistant \u2192 modules \u2192 src \u2192 ai-assistant \u2192 packages \u2192 root (6 levels)\n // then into apps/mercato/src/bootstrap.ts\n const bootstrapPath = resolve(__dirname, '../../../../../../apps/mercato/src/bootstrap.ts')\n\n // Dynamic import using file URL\n const bootstrapUrl = pathToFileURL(bootstrapPath).href\n const { bootstrap, isBootstrapped } = await import(bootstrapUrl)\n\n if (!isBootstrapped()) {\n bootstrap()\n }\n } catch (error) {\n console.error('[MCP] Bootstrap failed:', error instanceof Error ? error.message : error)\n // Continue - some contexts may not have bootstrap available\n }\n}\n\nfunction parseArgs(rest: string[]): Record<string, string | boolean> {\n const args: Record<string, string | boolean> = {}\n for (let i = 0; i < rest.length; i++) {\n const arg = rest[i]\n if (!arg?.startsWith('--')) continue\n\n const [key, value] = arg.replace(/^--/, '').split('=')\n if (value !== undefined) {\n args[key] = value\n } else if (rest[i + 1] && !rest[i + 1]!.startsWith('--')) {\n args[key] = rest[i + 1]!\n i++\n } else {\n args[key] = true\n }\n }\n return args\n}\n\nconst mcpServe: ModuleCli = {\n command: 'mcp:serve',\n async run(rest) {\n const args = parseArgs(rest)\n const apiKey = String(args['api-key'] ?? args.apiKey ?? '') || null\n const tenantId = String(args.tenant ?? args.tenantId ?? '') || null\n const organizationId = String(args.org ?? args.organizationId ?? '') || null\n const userId = String(args.user ?? args.userId ?? '') || null\n const debug = args.debug === true || args.debug === 'true'\n\n // Either API key or tenant is required\n if (!apiKey && !tenantId) {\n console.error('Usage: mercato ai_assistant mcp:serve [options]')\n console.error('')\n console.error('Authentication (choose one):')\n console.error(' --api-key <secret> API key secret for authentication (recommended)')\n console.error(' --tenant <id> Tenant ID (for manual context)')\n console.error('')\n console.error('Options (with --tenant):')\n console.error(' --org <id> Organization ID (optional)')\n console.error(' --user <id> User ID for ACL (optional, uses superadmin if not set)')\n console.error('')\n console.error('Common options:')\n console.error(' --debug Enable debug logging')\n console.error('')\n console.error('Examples:')\n console.error(' mercato ai_assistant mcp:serve --api-key omk_xxxx.yyyy...')\n console.error(' mercato ai_assistant mcp:serve --tenant 123e4567-e89b-12d3-a456-426614174000')\n return\n }\n\n await ensureBootstrap()\n const container = await createRequestContainer()\n\n const { runMcpServer } = await import('./lib/mcp-server')\n\n if (apiKey) {\n await runMcpServer({\n config: {\n name: 'open-mercato-mcp',\n version: '0.1.0',\n debug,\n },\n container,\n apiKeySecret: apiKey,\n })\n } else {\n await runMcpServer({\n config: {\n name: 'open-mercato-mcp',\n version: '0.1.0',\n debug,\n },\n container,\n context: {\n tenantId,\n organizationId,\n userId,\n },\n })\n }\n },\n}\n\nconst mcpServeHttp: ModuleCli = {\n command: 'mcp:serve-http',\n async run(rest) {\n const args = parseArgs(rest)\n const port = parseInt(String(args.port ?? ''), 10)\n const debug = args.debug === true || args.debug === 'true'\n\n if (!port || isNaN(port)) {\n console.error('Usage: mercato ai_assistant mcp:serve-http --port <port> [options]')\n console.error('')\n console.error('Options:')\n console.error(' --port <number> Port to listen on (required)')\n console.error(' --debug Enable debug logging')\n console.error('')\n console.error('Authentication:')\n console.error(' Clients must provide API key via x-api-key header')\n console.error('')\n console.error('Example:')\n console.error(' mercato ai_assistant mcp:serve-http --port 3001')\n return\n }\n\n await ensureBootstrap()\n const container = await createRequestContainer()\n\n const { runMcpHttpServer } = await import('./lib/http-server')\n\n await runMcpHttpServer({\n config: {\n name: 'open-mercato-mcp',\n version: '0.1.0',\n debug,\n },\n container,\n port,\n })\n },\n}\n\nconst mcpDev: ModuleCli = {\n command: 'mcp:dev',\n async run() {\n await ensureBootstrap()\n const { runMcpDevServer } = await import('./lib/mcp-dev-server')\n await runMcpDevServer()\n },\n}\n\nconst listTools: ModuleCli = {\n command: 'mcp:list-tools',\n async run(rest) {\n const args = parseArgs(rest)\n const verbose = args.verbose === true || args.verbose === 'true'\n\n const { loadAllModuleTools } = await import('./lib/tool-loader')\n await loadAllModuleTools()\n\n const { getToolRegistry } = await import('./lib/tool-registry')\n const registry = getToolRegistry()\n const toolNames = registry.listToolNames()\n\n if (toolNames.length === 0) {\n console.log('\\nNo MCP tools registered.')\n console.log('Tools can be registered by modules using registerMcpTool().\\n')\n return\n }\n\n console.log(`\\nRegistered MCP Tools (${toolNames.length}):\\n`)\n\n // Group tools by module\n const byModule = new Map<string, string[]>()\n for (const name of toolNames) {\n const [module] = name.split('.')\n const list = byModule.get(module) ?? []\n list.push(name)\n byModule.set(module, list)\n }\n\n // Sort modules alphabetically\n const sortedModules = Array.from(byModule.keys()).sort()\n\n for (const module of sortedModules) {\n const tools = byModule.get(module)!\n console.log(`${module} (${tools.length} tools):`)\n\n for (const name of tools.sort()) {\n const tool = registry.getTool(name)\n if (!tool) continue\n\n if (verbose) {\n console.log(` ${name}`)\n console.log(` ${tool.description}`)\n if (tool.requiredFeatures?.length) {\n console.log(` Requires: ${tool.requiredFeatures.join(', ')}`)\n }\n } else {\n console.log(` - ${name}`)\n }\n }\n console.log('')\n }\n },\n}\n\nexport default [mcpServe, mcpServeHttp, mcpDev, listTools]\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { asValue } from "awilix";
|
|
2
|
+
import { toolRegistry } from "./lib/tool-registry.js";
|
|
3
|
+
function register(container) {
|
|
4
|
+
container.register({
|
|
5
|
+
mcpToolRegistry: asValue(toolRegistry)
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
register
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=di.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/ai_assistant/di.ts"],
|
|
4
|
+
"sourcesContent": ["import { asValue } from 'awilix'\nimport type { AwilixContainer } from 'awilix'\nimport { toolRegistry } from './lib/tool-registry'\n\nexport function register(container: AwilixContainer): void {\n container.register({\n mcpToolRegistry: asValue(toolRegistry),\n })\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,eAAe;AAExB,SAAS,oBAAoB;AAEtB,SAAS,SAAS,WAAkC;AACzD,YAAU,SAAS;AAAA,IACjB,iBAAiB,QAAQ,YAAY;AAAA,EACvC,CAAC;AACH;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { useQuery } from "@tanstack/react-query";
|
|
5
|
+
import { Bot, Loader2, CheckCircle2, XCircle, ChevronDown, ChevronRight, Server, Wrench, AlertTriangle } from "lucide-react";
|
|
6
|
+
import { Button } from "@open-mercato/ui/primitives/button";
|
|
7
|
+
import {
|
|
8
|
+
CommandPaletteProvider,
|
|
9
|
+
CommandPalette,
|
|
10
|
+
useCommandPaletteContext
|
|
11
|
+
} from "../../../../frontend/index.js";
|
|
12
|
+
async function fetchHealth() {
|
|
13
|
+
const res = await fetch("/api/ai_assistant/health");
|
|
14
|
+
if (!res.ok) throw new Error("Failed to fetch health");
|
|
15
|
+
return res.json();
|
|
16
|
+
}
|
|
17
|
+
async function fetchSettings() {
|
|
18
|
+
const res = await fetch("/api/ai_assistant/settings");
|
|
19
|
+
if (!res.ok) throw new Error("Failed to fetch settings");
|
|
20
|
+
return res.json();
|
|
21
|
+
}
|
|
22
|
+
async function fetchTools() {
|
|
23
|
+
const res = await fetch("/api/ai_assistant/tools");
|
|
24
|
+
if (!res.ok) throw new Error("Failed to fetch tools");
|
|
25
|
+
return res.json();
|
|
26
|
+
}
|
|
27
|
+
function AiAssistantSettingsContent() {
|
|
28
|
+
const [toolsExpanded, setToolsExpanded] = useState(false);
|
|
29
|
+
const { setIsOpen } = useCommandPaletteContext();
|
|
30
|
+
const healthQuery = useQuery({
|
|
31
|
+
queryKey: ["ai-assistant", "health"],
|
|
32
|
+
queryFn: fetchHealth,
|
|
33
|
+
refetchInterval: 1e4,
|
|
34
|
+
staleTime: 5e3
|
|
35
|
+
});
|
|
36
|
+
const settingsQuery = useQuery({
|
|
37
|
+
queryKey: ["ai-assistant", "settings"],
|
|
38
|
+
queryFn: fetchSettings,
|
|
39
|
+
staleTime: 6e4
|
|
40
|
+
});
|
|
41
|
+
const toolsQuery = useQuery({
|
|
42
|
+
queryKey: ["ai-assistant", "tools"],
|
|
43
|
+
queryFn: fetchTools,
|
|
44
|
+
staleTime: 6e4
|
|
45
|
+
});
|
|
46
|
+
const openAiAssistant = () => {
|
|
47
|
+
setIsOpen(true);
|
|
48
|
+
};
|
|
49
|
+
const isLoading = healthQuery.isLoading || settingsQuery.isLoading || toolsQuery.isLoading;
|
|
50
|
+
if (isLoading) {
|
|
51
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground py-8", children: [
|
|
52
|
+
/* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
53
|
+
"Loading settings..."
|
|
54
|
+
] });
|
|
55
|
+
}
|
|
56
|
+
const health = healthQuery.data;
|
|
57
|
+
const settings = settingsQuery.data;
|
|
58
|
+
const tools = toolsQuery.data?.tools || [];
|
|
59
|
+
const toolsByModule = tools.reduce((acc, tool) => {
|
|
60
|
+
const module = tool.module || "other";
|
|
61
|
+
if (!acc[module]) acc[module] = [];
|
|
62
|
+
acc[module].push(tool);
|
|
63
|
+
return acc;
|
|
64
|
+
}, {});
|
|
65
|
+
const provider = settings?.provider;
|
|
66
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
|
|
67
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
68
|
+
/* @__PURE__ */ jsxs("h1", { className: "text-2xl font-bold flex items-center gap-2", children: [
|
|
69
|
+
/* @__PURE__ */ jsx(Bot, { className: "h-6 w-6" }),
|
|
70
|
+
"AI Assistant Settings"
|
|
71
|
+
] }),
|
|
72
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "Configure and monitor the AI assistant" })
|
|
73
|
+
] }),
|
|
74
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card p-6", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
|
|
75
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
76
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-lg font-semibold flex items-center gap-2", children: [
|
|
77
|
+
/* @__PURE__ */ jsx(Bot, { className: "h-5 w-5" }),
|
|
78
|
+
"Test AI Assistant"
|
|
79
|
+
] }),
|
|
80
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Click the button to open the AI Assistant command palette." })
|
|
81
|
+
] }),
|
|
82
|
+
/* @__PURE__ */ jsxs(Button, { onClick: openAiAssistant, size: "lg", className: "gap-2", children: [
|
|
83
|
+
/* @__PURE__ */ jsx(Bot, { className: "h-4 w-4" }),
|
|
84
|
+
"Open AI Assistant"
|
|
85
|
+
] })
|
|
86
|
+
] }) }),
|
|
87
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-6", children: [
|
|
88
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-sm font-semibold mb-4 flex items-center gap-2", children: [
|
|
89
|
+
/* @__PURE__ */ jsx(Server, { className: "h-4 w-4" }),
|
|
90
|
+
"Configuration"
|
|
91
|
+
] }),
|
|
92
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-muted/50 rounded-md p-4 space-y-2", children: [
|
|
93
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
94
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Provider:" }),
|
|
95
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: provider?.name || "Anthropic" }),
|
|
96
|
+
provider?.configured ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-emerald-600 dark:text-emerald-400 text-xs", children: [
|
|
97
|
+
/* @__PURE__ */ jsx(CheckCircle2, { className: "h-3 w-3" }),
|
|
98
|
+
"Configured"
|
|
99
|
+
] }) : /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-amber-600 dark:text-amber-400 text-xs", children: [
|
|
100
|
+
/* @__PURE__ */ jsx(XCircle, { className: "h-3 w-3" }),
|
|
101
|
+
"Not configured"
|
|
102
|
+
] })
|
|
103
|
+
] }),
|
|
104
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
105
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Model:" }),
|
|
106
|
+
/* @__PURE__ */ jsx("code", { className: "font-mono text-xs bg-background px-1.5 py-0.5 rounded", children: provider?.model || "claude-haiku-4-5-20251001" })
|
|
107
|
+
] }),
|
|
108
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
109
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Required:" }),
|
|
110
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
111
|
+
"Set ",
|
|
112
|
+
/* @__PURE__ */ jsx("code", { className: "font-mono text-xs bg-background px-1.5 py-0.5 rounded", children: provider?.envKey || "OPENCODE_ANTHROPIC_API_KEY" }),
|
|
113
|
+
" in .env"
|
|
114
|
+
] })
|
|
115
|
+
] })
|
|
116
|
+
] }),
|
|
117
|
+
settings?.availableProviders && settings.availableProviders.length > 1 && /* @__PURE__ */ jsxs("div", { className: "mt-4", children: [
|
|
118
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mb-2", children: "Available Providers:" }),
|
|
119
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: settings.availableProviders.map((p) => /* @__PURE__ */ jsxs(
|
|
120
|
+
"div",
|
|
121
|
+
{
|
|
122
|
+
className: `px-2 py-1 rounded text-xs ${p.id === provider?.id ? "bg-primary text-primary-foreground" : p.configured ? "bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400" : "bg-muted text-muted-foreground"}`,
|
|
123
|
+
children: [
|
|
124
|
+
p.name,
|
|
125
|
+
p.id === provider?.id && " (active)",
|
|
126
|
+
p.id !== provider?.id && p.configured && " (ready)"
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
p.id
|
|
130
|
+
)) })
|
|
131
|
+
] }),
|
|
132
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground mt-3", children: [
|
|
133
|
+
"Set ",
|
|
134
|
+
/* @__PURE__ */ jsx("code", { className: "font-mono text-[10px] bg-muted px-1 rounded", children: "OPENCODE_PROVIDER" }),
|
|
135
|
+
" in .env to change provider (anthropic, openai, google)."
|
|
136
|
+
] })
|
|
137
|
+
] }),
|
|
138
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-6", children: [
|
|
139
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-sm font-semibold mb-4 flex items-center gap-2", children: [
|
|
140
|
+
/* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4" }),
|
|
141
|
+
"Requirements"
|
|
142
|
+
] }),
|
|
143
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-muted/50 rounded-md p-4 space-y-3", children: [
|
|
144
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
145
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Full-Text Search:" }),
|
|
146
|
+
health?.search?.available ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-emerald-600 dark:text-emerald-400", children: [
|
|
147
|
+
/* @__PURE__ */ jsx(CheckCircle2, { className: "h-3 w-3" }),
|
|
148
|
+
"Meilisearch connected"
|
|
149
|
+
] }) : /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-amber-600 dark:text-amber-400", children: [
|
|
150
|
+
/* @__PURE__ */ jsx(XCircle, { className: "h-3 w-3" }),
|
|
151
|
+
"Not available"
|
|
152
|
+
] })
|
|
153
|
+
] }),
|
|
154
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "A full-text search driver (Meilisearch) is required for API endpoint discovery. Endpoints are indexed automatically when the MCP server starts." })
|
|
155
|
+
] })
|
|
156
|
+
] }),
|
|
157
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-6", children: [
|
|
158
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
|
|
159
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-sm font-semibold flex items-center gap-2", children: [
|
|
160
|
+
/* @__PURE__ */ jsx(Server, { className: "h-4 w-4" }),
|
|
161
|
+
"OpenCode Connection"
|
|
162
|
+
] }),
|
|
163
|
+
healthQuery.isFetching && !healthQuery.isLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 animate-spin text-muted-foreground" })
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [
|
|
166
|
+
/* @__PURE__ */ jsx("div", { className: `p-4 rounded-lg border-2 ${health?.status === "ok" && health.opencode?.healthy ? "border-emerald-500/50 bg-emerald-50/50 dark:bg-emerald-900/10" : "border-destructive/50 bg-destructive/5"}`, children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
|
|
167
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
168
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "OpenCode Server" }),
|
|
169
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: health?.status === "ok" && health.opencode?.healthy ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-emerald-600 dark:text-emerald-400", children: [
|
|
170
|
+
/* @__PURE__ */ jsx(CheckCircle2, { className: "h-3 w-3" }),
|
|
171
|
+
"Connected"
|
|
172
|
+
] }) : /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-destructive", children: [
|
|
173
|
+
/* @__PURE__ */ jsx(XCircle, { className: "h-3 w-3" }),
|
|
174
|
+
health?.message || "Disconnected"
|
|
175
|
+
] }) }),
|
|
176
|
+
health?.opencode?.version && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground mt-1", children: [
|
|
177
|
+
"Version: ",
|
|
178
|
+
health.opencode.version
|
|
179
|
+
] }),
|
|
180
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: health?.url || "http://localhost:4096" })
|
|
181
|
+
] }),
|
|
182
|
+
health?.status === "ok" && health.opencode?.healthy && /* @__PURE__ */ jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-emerald-100 text-emerald-600 dark:bg-emerald-900/40 dark:text-emerald-400", children: /* @__PURE__ */ jsx("svg", { className: "h-3 w-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 3, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }) }) })
|
|
183
|
+
] }) }),
|
|
184
|
+
health?.mcp && Object.entries(health.mcp).map(([name, mcpStatus]) => /* @__PURE__ */ jsx(
|
|
185
|
+
"div",
|
|
186
|
+
{
|
|
187
|
+
className: `p-4 rounded-lg border-2 ${mcpStatus.status === "connected" ? "border-emerald-500/50 bg-emerald-50/50 dark:bg-emerald-900/10" : mcpStatus.status === "connecting" ? "border-amber-500/50 bg-amber-50/50 dark:bg-amber-900/10" : "border-destructive/50 bg-destructive/5"}`,
|
|
188
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
|
|
189
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
190
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "MCP Server" }),
|
|
191
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: mcpStatus.status === "connected" ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-emerald-600 dark:text-emerald-400", children: [
|
|
192
|
+
/* @__PURE__ */ jsx(CheckCircle2, { className: "h-3 w-3" }),
|
|
193
|
+
"Connected"
|
|
194
|
+
] }) : mcpStatus.status === "connecting" ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-amber-600 dark:text-amber-400", children: [
|
|
195
|
+
/* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 animate-spin" }),
|
|
196
|
+
"Connecting..."
|
|
197
|
+
] }) : /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-destructive", children: [
|
|
198
|
+
/* @__PURE__ */ jsx(XCircle, { className: "h-3 w-3" }),
|
|
199
|
+
mcpStatus.error || "Failed"
|
|
200
|
+
] }) }),
|
|
201
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: name }),
|
|
202
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "localhost:3001" })
|
|
203
|
+
] }),
|
|
204
|
+
mcpStatus.status === "connected" && /* @__PURE__ */ jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-emerald-100 text-emerald-600 dark:bg-emerald-900/40 dark:text-emerald-400", children: /* @__PURE__ */ jsx("svg", { className: "h-3 w-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 3, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }) }) })
|
|
205
|
+
] })
|
|
206
|
+
},
|
|
207
|
+
name
|
|
208
|
+
)),
|
|
209
|
+
(!health?.mcp || Object.keys(health.mcp).length === 0) && /* @__PURE__ */ jsx("div", { className: "p-4 rounded-lg border-2 border-border bg-muted/20", children: /* @__PURE__ */ jsxs("div", { children: [
|
|
210
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "MCP Server" }),
|
|
211
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
212
|
+
/* @__PURE__ */ jsx(XCircle, { className: "h-3 w-3" }),
|
|
213
|
+
"Not connected"
|
|
214
|
+
] }) }),
|
|
215
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "localhost:3001" })
|
|
216
|
+
] }) })
|
|
217
|
+
] })
|
|
218
|
+
] }),
|
|
219
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-6", children: [
|
|
220
|
+
/* @__PURE__ */ jsxs(
|
|
221
|
+
"button",
|
|
222
|
+
{
|
|
223
|
+
onClick: () => setToolsExpanded(!toolsExpanded),
|
|
224
|
+
className: "w-full flex items-center justify-between text-left",
|
|
225
|
+
children: [
|
|
226
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-sm font-semibold flex items-center gap-2", children: [
|
|
227
|
+
/* @__PURE__ */ jsx(Wrench, { className: "h-4 w-4" }),
|
|
228
|
+
"MCP Tools (",
|
|
229
|
+
tools.length,
|
|
230
|
+
" tools)"
|
|
231
|
+
] }),
|
|
232
|
+
toolsExpanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 text-muted-foreground" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 text-muted-foreground" })
|
|
233
|
+
]
|
|
234
|
+
}
|
|
235
|
+
),
|
|
236
|
+
toolsExpanded && /* @__PURE__ */ jsx("div", { className: "mt-4 space-y-4", children: Object.entries(toolsByModule).map(([module, moduleTools]) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
237
|
+
/* @__PURE__ */ jsx("h3", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: module }),
|
|
238
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-1", children: moduleTools.map((tool) => /* @__PURE__ */ jsxs("div", { className: "pl-2 border-l-2 border-muted py-1", children: [
|
|
239
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: tool.name }),
|
|
240
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: tool.description })
|
|
241
|
+
] }, tool.name)) })
|
|
242
|
+
] }, module)) })
|
|
243
|
+
] })
|
|
244
|
+
] });
|
|
245
|
+
}
|
|
246
|
+
function AiAssistantSettingsPageClient() {
|
|
247
|
+
return /* @__PURE__ */ jsxs(CommandPaletteProvider, { tenantId: "", organizationId: null, children: [
|
|
248
|
+
/* @__PURE__ */ jsx(AiAssistantSettingsContent, {}),
|
|
249
|
+
/* @__PURE__ */ jsx(CommandPalette, {})
|
|
250
|
+
] });
|
|
251
|
+
}
|
|
252
|
+
var AiAssistantSettingsPageClient_default = AiAssistantSettingsPageClient;
|
|
253
|
+
export {
|
|
254
|
+
AiAssistantSettingsPageClient,
|
|
255
|
+
AiAssistantSettingsPageClient_default as default
|
|
256
|
+
};
|
|
257
|
+
//# sourceMappingURL=AiAssistantSettingsPageClient.js.map
|