@equinor/fusion-framework-cli-plugin-ai-mcp 1.0.0
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/CHANGELOG.md +76 -0
- package/LICENSE +21 -0
- package/README.md +131 -0
- package/dist/esm/index.js +11 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/mcp.js +66 -0
- package/dist/esm/mcp.js.map +1 -0
- package/dist/esm/tools/fusion-search-api.js +65 -0
- package/dist/esm/tools/fusion-search-api.js.map +1 -0
- package/dist/esm/tools/fusion-search-cookbook.js +65 -0
- package/dist/esm/tools/fusion-search-cookbook.js.map +1 -0
- package/dist/esm/tools/fusion-search-eds.js +65 -0
- package/dist/esm/tools/fusion-search-eds.js.map +1 -0
- package/dist/esm/tools/fusion-search-markdown.js +65 -0
- package/dist/esm/tools/fusion-search-markdown.js.map +1 -0
- package/dist/esm/tools/fusion-search.tool.js +152 -0
- package/dist/esm/tools/fusion-search.tool.js.map +1 -0
- package/dist/esm/version.js +3 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/mcp.d.ts +2 -0
- package/dist/types/tools/fusion-search-api.d.ts +37 -0
- package/dist/types/tools/fusion-search-cookbook.d.ts +37 -0
- package/dist/types/tools/fusion-search-eds.d.ts +37 -0
- package/dist/types/tools/fusion-search-markdown.d.ts +37 -0
- package/dist/types/tools/fusion-search.tool.d.ts +52 -0
- package/dist/types/version.d.ts +1 -0
- package/package.json +61 -0
- package/src/index.ts +13 -0
- package/src/mcp.ts +130 -0
- package/src/tools/fusion-search-api.ts +90 -0
- package/src/tools/fusion-search-cookbook.ts +90 -0
- package/src/tools/fusion-search-eds.ts +91 -0
- package/src/tools/fusion-search-markdown.ts +90 -0
- package/src/tools/fusion-search.tool.ts +187 -0
- package/src/version.ts +2 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { FrameworkInstance } from '@equinor/fusion-framework-cli-plugin-ai-base';
|
|
2
|
+
import type { AiOptions } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
|
|
3
|
+
/**
|
|
4
|
+
* Tool definition for searching Fusion Framework cookbooks.
|
|
5
|
+
* This tool enables semantic search across example implementations, tutorials, and how-to guides.
|
|
6
|
+
*/
|
|
7
|
+
export declare const toolDefinition: {
|
|
8
|
+
readonly name: "fusion_search_cookbook";
|
|
9
|
+
readonly description: "Search the Fusion Framework cookbooks using semantic search. Use this for finding example implementations, tutorials, guides, and how-to content.";
|
|
10
|
+
readonly inputSchema: {
|
|
11
|
+
readonly type: "object";
|
|
12
|
+
readonly properties: {
|
|
13
|
+
readonly query: {
|
|
14
|
+
readonly type: "string";
|
|
15
|
+
readonly description: "The search query to find relevant cookbook examples and tutorials";
|
|
16
|
+
};
|
|
17
|
+
readonly limit: {
|
|
18
|
+
readonly type: "number";
|
|
19
|
+
readonly description: "Maximum number of results to return (default: 5)";
|
|
20
|
+
readonly default: 5;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
readonly required: readonly ["query"];
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Tool handler for fusion_search_cookbook
|
|
28
|
+
*/
|
|
29
|
+
export declare function handleTool(args: Record<string, unknown>, framework: FrameworkInstance, options: AiOptions & {
|
|
30
|
+
verbose?: boolean;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
content: Array<{
|
|
33
|
+
type: 'text';
|
|
34
|
+
text: string;
|
|
35
|
+
}>;
|
|
36
|
+
isError?: boolean;
|
|
37
|
+
}>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { FrameworkInstance } from '@equinor/fusion-framework-cli-plugin-ai-base';
|
|
2
|
+
import type { AiOptions } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
|
|
3
|
+
/**
|
|
4
|
+
* Tool definition for searching EDS (Equinor Design System) components from Storybook.
|
|
5
|
+
* This tool enables semantic search across component examples, props, usage patterns, and Storybook stories.
|
|
6
|
+
*/
|
|
7
|
+
export declare const toolDefinition: {
|
|
8
|
+
readonly name: "fusion_search_eds";
|
|
9
|
+
readonly description: "Search EDS (Equinor Design System) components from Storybook using semantic search. Use this for finding component examples, props, usage patterns, and Storybook stories.";
|
|
10
|
+
readonly inputSchema: {
|
|
11
|
+
readonly type: "object";
|
|
12
|
+
readonly properties: {
|
|
13
|
+
readonly query: {
|
|
14
|
+
readonly type: "string";
|
|
15
|
+
readonly description: "The search query to find relevant EDS component examples and Storybook stories";
|
|
16
|
+
};
|
|
17
|
+
readonly limit: {
|
|
18
|
+
readonly type: "number";
|
|
19
|
+
readonly description: "Maximum number of results to return (default: 5)";
|
|
20
|
+
readonly default: 5;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
readonly required: readonly ["query"];
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Tool handler for fusion_search_eds
|
|
28
|
+
*/
|
|
29
|
+
export declare function handleTool(args: Record<string, unknown>, framework: FrameworkInstance, options: AiOptions & {
|
|
30
|
+
verbose?: boolean;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
content: Array<{
|
|
33
|
+
type: 'text';
|
|
34
|
+
text: string;
|
|
35
|
+
}>;
|
|
36
|
+
isError?: boolean;
|
|
37
|
+
}>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { FrameworkInstance } from '@equinor/fusion-framework-cli-plugin-ai-base';
|
|
2
|
+
import type { AiOptions } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
|
|
3
|
+
/**
|
|
4
|
+
* Tool definition for searching Fusion Framework markdown documentation.
|
|
5
|
+
* This tool enables semantic search across markdown files, guides, and documentation.
|
|
6
|
+
*/
|
|
7
|
+
export declare const toolDefinition: {
|
|
8
|
+
readonly name: "fusion_search_markdown";
|
|
9
|
+
readonly description: "Search the Fusion Framework markdown documentation using semantic search. Use this for finding documentation, guides, and explanatory content.";
|
|
10
|
+
readonly inputSchema: {
|
|
11
|
+
readonly type: "object";
|
|
12
|
+
readonly properties: {
|
|
13
|
+
readonly query: {
|
|
14
|
+
readonly type: "string";
|
|
15
|
+
readonly description: "The search query to find relevant markdown documentation";
|
|
16
|
+
};
|
|
17
|
+
readonly limit: {
|
|
18
|
+
readonly type: "number";
|
|
19
|
+
readonly description: "Maximum number of results to return (default: 5)";
|
|
20
|
+
readonly default: 5;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
readonly required: readonly ["query"];
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Tool handler for fusion_search_markdown
|
|
28
|
+
*/
|
|
29
|
+
export declare function handleTool(args: Record<string, unknown>, framework: FrameworkInstance, options: AiOptions & {
|
|
30
|
+
verbose?: boolean;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
content: Array<{
|
|
33
|
+
type: 'text';
|
|
34
|
+
text: string;
|
|
35
|
+
}>;
|
|
36
|
+
isError?: boolean;
|
|
37
|
+
}>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { FrameworkInstance } from '@equinor/fusion-framework-cli-plugin-ai-base';
|
|
3
|
+
import type { AiOptions } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
|
|
4
|
+
import type { ToolCallback } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
/** Valid documentation categories that can be searched */
|
|
6
|
+
export type FusionSearchCategory = 'api' | 'cookbook' | 'markdown' | 'eds' | 'all';
|
|
7
|
+
export declare const inputSchema: z.ZodObject<{
|
|
8
|
+
query: z.ZodString;
|
|
9
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
10
|
+
category: z.ZodDefault<z.ZodOptional<z.ZodEnum<["all"]>>>;
|
|
11
|
+
}, "strip", z.ZodTypeAny, {
|
|
12
|
+
query: string;
|
|
13
|
+
limit: number;
|
|
14
|
+
category: "all";
|
|
15
|
+
}, {
|
|
16
|
+
query: string;
|
|
17
|
+
limit?: number | undefined;
|
|
18
|
+
category?: "all" | undefined;
|
|
19
|
+
}>;
|
|
20
|
+
/**
|
|
21
|
+
* Tool configuration for McpServer.registerTool().
|
|
22
|
+
*/
|
|
23
|
+
export declare const toolConfig: {
|
|
24
|
+
readonly description: string;
|
|
25
|
+
readonly inputSchema: z.ZodObject<{
|
|
26
|
+
query: z.ZodString;
|
|
27
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
28
|
+
category: z.ZodDefault<z.ZodOptional<z.ZodEnum<["all"]>>>;
|
|
29
|
+
}, "strip", z.ZodTypeAny, {
|
|
30
|
+
query: string;
|
|
31
|
+
limit: number;
|
|
32
|
+
category: "all";
|
|
33
|
+
}, {
|
|
34
|
+
query: string;
|
|
35
|
+
limit?: number | undefined;
|
|
36
|
+
category?: "all" | undefined;
|
|
37
|
+
}>;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Main handler for the `fusion_search` tool.
|
|
41
|
+
*
|
|
42
|
+
* Returns a curried function that takes tool input arguments and returns search results.
|
|
43
|
+
*
|
|
44
|
+
* @param framework - Active Fusion Framework instance
|
|
45
|
+
* @param options - AI plugin options, optionally with `{ verbose: true }`
|
|
46
|
+
* @returns A function that takes validated tool arguments and returns search results
|
|
47
|
+
*
|
|
48
|
+
* @throws {Error} If AI module or Azure Search index is not configured
|
|
49
|
+
*/
|
|
50
|
+
export declare function handleTool(framework: FrameworkInstance, options: AiOptions & {
|
|
51
|
+
verbose?: boolean;
|
|
52
|
+
}): ToolCallback<typeof inputSchema>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const version = "1.0.0";
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@equinor/fusion-framework-cli-plugin-ai-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server plugin for Fusion Framework CLI providing Model Context Protocol server capabilities",
|
|
5
|
+
"main": "dist/esm/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "dist/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/esm/index.js",
|
|
11
|
+
"types": "./dist/types/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"typesVersions": {
|
|
15
|
+
"*": {
|
|
16
|
+
".": [
|
|
17
|
+
"dist/types/index.d.ts"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"fusion-framework",
|
|
23
|
+
"cli",
|
|
24
|
+
"plugin",
|
|
25
|
+
"llm",
|
|
26
|
+
"ai",
|
|
27
|
+
"mcp",
|
|
28
|
+
"model-context-protocol"
|
|
29
|
+
],
|
|
30
|
+
"author": "",
|
|
31
|
+
"license": "ISC",
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/equinor/fusion-framework.git",
|
|
38
|
+
"directory": "packages/cli-plugins/ai-mcp"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
42
|
+
"commander": "^14.0.1",
|
|
43
|
+
"zod": "^3.23.8",
|
|
44
|
+
"@equinor/fusion-framework-cli-plugin-ai-base": "1.0.0",
|
|
45
|
+
"@equinor/fusion-framework-module": "5.0.5",
|
|
46
|
+
"@equinor/fusion-framework-module-ai": "2.0.0"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"@equinor/fusion-framework-cli": "13.0.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"typescript": "^5.8.2",
|
|
53
|
+
"vitest": "^3.2.4"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "tsc -b",
|
|
57
|
+
"build:types": "tsc -b",
|
|
58
|
+
"watch": "tsc -b --watch",
|
|
59
|
+
"test": "vitest"
|
|
60
|
+
}
|
|
61
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import { registerAiPlugin as registerAiPluginBase } from '@equinor/fusion-framework-cli-plugin-ai-base';
|
|
3
|
+
import { command as mcpCommand } from './mcp.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Registers the AI MCP server plugin command with the CLI program
|
|
7
|
+
* @param program - The Commander program instance to register commands with
|
|
8
|
+
*/
|
|
9
|
+
export function registerAiPlugin(program: Command): void {
|
|
10
|
+
registerAiPluginBase(program, mcpCommand);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default registerAiPlugin;
|
package/src/mcp.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { createCommand, createOption } from 'commander';
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { setupFramework } from '@equinor/fusion-framework-cli-plugin-ai-base';
|
|
5
|
+
import {
|
|
6
|
+
type AiOptions,
|
|
7
|
+
withOptions as withAiOptions,
|
|
8
|
+
} from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
|
|
9
|
+
import {
|
|
10
|
+
handleTool as handleSearchTool,
|
|
11
|
+
toolConfig as searchToolConfig,
|
|
12
|
+
} from './tools/fusion-search.tool.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* CLI command: `ai mcp`
|
|
16
|
+
*
|
|
17
|
+
* Starts a Model Context Protocol (MCP) server that provides tools and resources
|
|
18
|
+
* for AI assistants to interact with the Fusion Framework.
|
|
19
|
+
*
|
|
20
|
+
* The MCP server exposes:
|
|
21
|
+
* - Tools for querying and searching the Fusion Framework codebase:
|
|
22
|
+
* - fusion_search: Unified search across all documentation types (API, cookbooks, markdown, EDS)
|
|
23
|
+
* - Resources for accessing framework documentation and context
|
|
24
|
+
* - Capabilities for AI assistants to understand and work with Fusion Framework
|
|
25
|
+
*
|
|
26
|
+
* Usage:
|
|
27
|
+
* $ ffc ai mcp [options]
|
|
28
|
+
*
|
|
29
|
+
* Options:
|
|
30
|
+
* --openai-api-key <key> API key for Azure OpenAI
|
|
31
|
+
* --openai-api-version <version> API version (default: 2024-02-15-preview)
|
|
32
|
+
* --openai-instance <name> Azure OpenAI instance name
|
|
33
|
+
* --openai-chat-deployment <name> Azure OpenAI chat deployment name
|
|
34
|
+
* --openai-embedding-deployment <name> Azure OpenAI embedding deployment name
|
|
35
|
+
* --azure-search-endpoint <url> Azure Search endpoint URL
|
|
36
|
+
* --azure-search-api-key <key> Azure Search API key
|
|
37
|
+
* --azure-search-index-name <name> Azure Search index name
|
|
38
|
+
* --verbose Enable verbose output
|
|
39
|
+
*
|
|
40
|
+
* Environment Variables:
|
|
41
|
+
* AZURE_OPENAI_API_KEY API key for Azure OpenAI
|
|
42
|
+
* AZURE_OPENAI_API_VERSION API version
|
|
43
|
+
* AZURE_OPENAI_INSTANCE_NAME Instance name
|
|
44
|
+
* AZURE_OPENAI_CHAT_DEPLOYMENT_NAME Chat deployment name
|
|
45
|
+
* AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME Embedding deployment name
|
|
46
|
+
* AZURE_SEARCH_ENDPOINT Azure Search endpoint
|
|
47
|
+
* AZURE_SEARCH_API_KEY Azure Search API key
|
|
48
|
+
* AZURE_SEARCH_INDEX_NAME Azure Search index name
|
|
49
|
+
*
|
|
50
|
+
* Examples:
|
|
51
|
+
* $ ffc ai mcp
|
|
52
|
+
* $ ffc ai mcp --verbose
|
|
53
|
+
* $ ffc ai mcp --azure-search-endpoint https://my-search.search.windows.net
|
|
54
|
+
*/
|
|
55
|
+
type CommandOptions = AiOptions & {
|
|
56
|
+
/** Enable verbose output for debugging */
|
|
57
|
+
verbose?: boolean;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const _command = createCommand('mcp')
|
|
61
|
+
.description('Start a Model Context Protocol (MCP) server for Fusion Framework')
|
|
62
|
+
.addOption(createOption('--verbose', 'Enable verbose output').default(false))
|
|
63
|
+
.action(async (options: CommandOptions) => {
|
|
64
|
+
if (options.verbose) {
|
|
65
|
+
console.error('🚀 Starting MCP server for Fusion Framework...');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Initialize the framework
|
|
69
|
+
const framework = await setupFramework(options);
|
|
70
|
+
|
|
71
|
+
if (options.verbose) {
|
|
72
|
+
console.error('✅ Framework initialized successfully');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Create MCP server instance
|
|
76
|
+
const server = new McpServer({
|
|
77
|
+
name: 'fusion-framework-mcp',
|
|
78
|
+
version: '1.0.0',
|
|
79
|
+
title: 'Fusion Framework MCP Server',
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Register search tool (will return error if not configured)
|
|
83
|
+
server.registerTool('fusion_search', searchToolConfig, handleSearchTool(framework, options));
|
|
84
|
+
|
|
85
|
+
if (options.verbose) {
|
|
86
|
+
if (options.azureSearchIndexName && framework.ai) {
|
|
87
|
+
console.error('✅ Registered tool: fusion_search');
|
|
88
|
+
} else {
|
|
89
|
+
console.error(
|
|
90
|
+
'⚠️ Registered tool: fusion_search (configuration missing - will return error when called)',
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Start the server using stdio transport (standard for MCP)
|
|
96
|
+
const transport = new StdioServerTransport();
|
|
97
|
+
await server.connect(transport);
|
|
98
|
+
|
|
99
|
+
if (options.verbose) {
|
|
100
|
+
console.error('✅ MCP server started and ready');
|
|
101
|
+
console.error('📡 Listening on stdio for MCP protocol messages');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Keep the process alive
|
|
105
|
+
process.on('SIGINT', async () => {
|
|
106
|
+
if (options.verbose) {
|
|
107
|
+
console.error('\n🛑 Shutting down MCP server...');
|
|
108
|
+
}
|
|
109
|
+
await server.close();
|
|
110
|
+
process.exit(0);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
process.on('SIGTERM', async () => {
|
|
114
|
+
if (options.verbose) {
|
|
115
|
+
console.error('\n🛑 Shutting down MCP server...');
|
|
116
|
+
}
|
|
117
|
+
await server.close();
|
|
118
|
+
process.exit(0);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Export the command with AI options
|
|
123
|
+
// Note: Search tools require embedding deployment, so we include it
|
|
124
|
+
export const command = withAiOptions(_command, {
|
|
125
|
+
includeChat: false,
|
|
126
|
+
includeEmbedding: true,
|
|
127
|
+
includeSearch: true,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
export default command;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { FrameworkInstance } from '@equinor/fusion-framework-cli-plugin-ai-base';
|
|
2
|
+
import type { AiOptions } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Tool definition for searching Fusion Framework API reference.
|
|
6
|
+
* This tool enables semantic search across TypeScript/TSDoc code documentation, function signatures, and class definitions.
|
|
7
|
+
*/
|
|
8
|
+
export const toolDefinition = {
|
|
9
|
+
name: 'fusion_search_api',
|
|
10
|
+
description:
|
|
11
|
+
'Search the Fusion Framework API reference using semantic search. Use this for finding TypeScript/TSDoc code documentation, function signatures, class definitions, and API details.',
|
|
12
|
+
inputSchema: {
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {
|
|
15
|
+
query: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
description: 'The search query to find relevant API reference documentation',
|
|
18
|
+
},
|
|
19
|
+
limit: {
|
|
20
|
+
type: 'number',
|
|
21
|
+
description: 'Maximum number of results to return (default: 5)',
|
|
22
|
+
default: 5,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
required: ['query'],
|
|
26
|
+
},
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Tool handler for fusion_search_api
|
|
31
|
+
*/
|
|
32
|
+
export async function handleTool(
|
|
33
|
+
args: Record<string, unknown>,
|
|
34
|
+
framework: FrameworkInstance,
|
|
35
|
+
options: AiOptions & { verbose?: boolean },
|
|
36
|
+
): Promise<{
|
|
37
|
+
content: Array<{ type: 'text'; text: string }>;
|
|
38
|
+
isError?: boolean;
|
|
39
|
+
}> {
|
|
40
|
+
if (!options.azureSearchIndexName || !framework.ai) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
'Vector store is not configured. Azure Search is required for search functionality.',
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const query = args?.query as string;
|
|
47
|
+
const limit = (args?.limit as number) || 5;
|
|
48
|
+
|
|
49
|
+
if (!query || typeof query !== 'string') {
|
|
50
|
+
throw new Error('Query parameter is required and must be a string');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (options.verbose) {
|
|
54
|
+
console.error(`🔍 Searching API reference for: ${query}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const vectorStoreService = framework.ai.getService('search', options.azureSearchIndexName);
|
|
58
|
+
const retriever = vectorStoreService.asRetriever({
|
|
59
|
+
k: limit,
|
|
60
|
+
searchType: 'similarity',
|
|
61
|
+
filter: {
|
|
62
|
+
filterExpression: "metadata/attributes/any(x: x/key eq 'type' and x/value eq 'tsdoc')",
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const docs = await retriever.invoke(query);
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
content: [
|
|
70
|
+
{
|
|
71
|
+
type: 'text',
|
|
72
|
+
text: JSON.stringify(
|
|
73
|
+
{
|
|
74
|
+
query,
|
|
75
|
+
type: 'api',
|
|
76
|
+
results: docs.map(
|
|
77
|
+
(doc: { pageContent: string; metadata: Record<string, unknown> }) => ({
|
|
78
|
+
content: doc.pageContent,
|
|
79
|
+
metadata: doc.metadata,
|
|
80
|
+
}),
|
|
81
|
+
),
|
|
82
|
+
count: docs.length,
|
|
83
|
+
},
|
|
84
|
+
null,
|
|
85
|
+
2,
|
|
86
|
+
),
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { FrameworkInstance } from '@equinor/fusion-framework-cli-plugin-ai-base';
|
|
2
|
+
import type { AiOptions } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Tool definition for searching Fusion Framework cookbooks.
|
|
6
|
+
* This tool enables semantic search across example implementations, tutorials, and how-to guides.
|
|
7
|
+
*/
|
|
8
|
+
export const toolDefinition = {
|
|
9
|
+
name: 'fusion_search_cookbook',
|
|
10
|
+
description:
|
|
11
|
+
'Search the Fusion Framework cookbooks using semantic search. Use this for finding example implementations, tutorials, guides, and how-to content.',
|
|
12
|
+
inputSchema: {
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {
|
|
15
|
+
query: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
description: 'The search query to find relevant cookbook examples and tutorials',
|
|
18
|
+
},
|
|
19
|
+
limit: {
|
|
20
|
+
type: 'number',
|
|
21
|
+
description: 'Maximum number of results to return (default: 5)',
|
|
22
|
+
default: 5,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
required: ['query'],
|
|
26
|
+
},
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Tool handler for fusion_search_cookbook
|
|
31
|
+
*/
|
|
32
|
+
export async function handleTool(
|
|
33
|
+
args: Record<string, unknown>,
|
|
34
|
+
framework: FrameworkInstance,
|
|
35
|
+
options: AiOptions & { verbose?: boolean },
|
|
36
|
+
): Promise<{
|
|
37
|
+
content: Array<{ type: 'text'; text: string }>;
|
|
38
|
+
isError?: boolean;
|
|
39
|
+
}> {
|
|
40
|
+
if (!options.azureSearchIndexName || !framework.ai) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
'Vector store is not configured. Azure Search is required for search functionality.',
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const query = args?.query as string;
|
|
47
|
+
const limit = (args?.limit as number) || 5;
|
|
48
|
+
|
|
49
|
+
if (!query || typeof query !== 'string') {
|
|
50
|
+
throw new Error('Query parameter is required and must be a string');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (options.verbose) {
|
|
54
|
+
console.error(`🔍 Searching cookbooks for: ${query}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const vectorStoreService = framework.ai.getService('search', options.azureSearchIndexName);
|
|
58
|
+
const retriever = vectorStoreService.asRetriever({
|
|
59
|
+
k: limit,
|
|
60
|
+
searchType: 'similarity',
|
|
61
|
+
filter: {
|
|
62
|
+
filterExpression: "metadata/attributes/any(x: x/key eq 'type' and x/value eq 'cookbook')",
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const docs = await retriever.invoke(query);
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
content: [
|
|
70
|
+
{
|
|
71
|
+
type: 'text',
|
|
72
|
+
text: JSON.stringify(
|
|
73
|
+
{
|
|
74
|
+
query,
|
|
75
|
+
type: 'cookbook',
|
|
76
|
+
results: docs.map(
|
|
77
|
+
(doc: { pageContent: string; metadata: Record<string, unknown> }) => ({
|
|
78
|
+
content: doc.pageContent,
|
|
79
|
+
metadata: doc.metadata,
|
|
80
|
+
}),
|
|
81
|
+
),
|
|
82
|
+
count: docs.length,
|
|
83
|
+
},
|
|
84
|
+
null,
|
|
85
|
+
2,
|
|
86
|
+
),
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { FrameworkInstance } from '@equinor/fusion-framework-cli-plugin-ai-base';
|
|
2
|
+
import type { AiOptions } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Tool definition for searching EDS (Equinor Design System) components from Storybook.
|
|
6
|
+
* This tool enables semantic search across component examples, props, usage patterns, and Storybook stories.
|
|
7
|
+
*/
|
|
8
|
+
export const toolDefinition = {
|
|
9
|
+
name: 'fusion_search_eds',
|
|
10
|
+
description:
|
|
11
|
+
'Search EDS (Equinor Design System) components from Storybook using semantic search. Use this for finding component examples, props, usage patterns, and Storybook stories.',
|
|
12
|
+
inputSchema: {
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {
|
|
15
|
+
query: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
description:
|
|
18
|
+
'The search query to find relevant EDS component examples and Storybook stories',
|
|
19
|
+
},
|
|
20
|
+
limit: {
|
|
21
|
+
type: 'number',
|
|
22
|
+
description: 'Maximum number of results to return (default: 5)',
|
|
23
|
+
default: 5,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
required: ['query'],
|
|
27
|
+
},
|
|
28
|
+
} as const;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Tool handler for fusion_search_eds
|
|
32
|
+
*/
|
|
33
|
+
export async function handleTool(
|
|
34
|
+
args: Record<string, unknown>,
|
|
35
|
+
framework: FrameworkInstance,
|
|
36
|
+
options: AiOptions & { verbose?: boolean },
|
|
37
|
+
): Promise<{
|
|
38
|
+
content: Array<{ type: 'text'; text: string }>;
|
|
39
|
+
isError?: boolean;
|
|
40
|
+
}> {
|
|
41
|
+
if (!options.azureSearchIndexName || !framework.ai) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
'Vector store is not configured. Azure Search is required for search functionality.',
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const query = args?.query as string;
|
|
48
|
+
const limit = (args?.limit as number) || 5;
|
|
49
|
+
|
|
50
|
+
if (!query || typeof query !== 'string') {
|
|
51
|
+
throw new Error('Query parameter is required and must be a string');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (options.verbose) {
|
|
55
|
+
console.error(`🔍 Searching EDS components/Storybook for: ${query}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const vectorStoreService = framework.ai.getService('search', options.azureSearchIndexName);
|
|
59
|
+
const retriever = vectorStoreService.asRetriever({
|
|
60
|
+
k: limit,
|
|
61
|
+
searchType: 'similarity',
|
|
62
|
+
filter: {
|
|
63
|
+
filterExpression: "metadata/attributes/any(x: x/key eq 'type' and x/value eq 'storybook')",
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const docs = await retriever.invoke(query);
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
content: [
|
|
71
|
+
{
|
|
72
|
+
type: 'text',
|
|
73
|
+
text: JSON.stringify(
|
|
74
|
+
{
|
|
75
|
+
query,
|
|
76
|
+
type: 'eds-component',
|
|
77
|
+
results: docs.map(
|
|
78
|
+
(doc: { pageContent: string; metadata: Record<string, unknown> }) => ({
|
|
79
|
+
content: doc.pageContent,
|
|
80
|
+
metadata: doc.metadata,
|
|
81
|
+
}),
|
|
82
|
+
),
|
|
83
|
+
count: docs.length,
|
|
84
|
+
},
|
|
85
|
+
null,
|
|
86
|
+
2,
|
|
87
|
+
),
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
};
|
|
91
|
+
}
|