@answerai/answeragent-mcp 1.0.1
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/README.md +254 -0
- package/dist/index.js +100 -0
- package/dist/prompts/chatflow-analysis.js +205 -0
- package/dist/prompts/document-store-analysis.js +327 -0
- package/dist/prompts/index.js +3 -0
- package/dist/services/api-client.js +13 -0
- package/dist/services/assistants.js +29 -0
- package/dist/services/chatflows.js +94 -0
- package/dist/services/document-loader.js +24 -0
- package/dist/services/document-store.js +41 -0
- package/dist/services/tools-api.js +29 -0
- package/dist/tools/assistants.js +68 -0
- package/dist/tools/chatflows.js +72 -0
- package/dist/tools/document-loaders.js +70 -0
- package/dist/tools/document-stores.js +117 -0
- package/dist/tools/registry.js +109 -0
- package/dist/tools/tools-api.js +69 -0
- package/dist/types/assistant.js +20 -0
- package/dist/types/chatflow.js +44 -0
- package/dist/types/document-loader.js +11 -0
- package/dist/types/document-store.js +14 -0
- package/dist/types/tool.js +12 -0
- package/package.json +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# @answerai/answeragent-mcp
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/@answerai%2Fansweragent-mcp)
|
|
4
|
+
|
|
5
|
+
A lightweight Model Context Protocol (MCP) server for Answer AI chatflow and document store management. This server exposes Answer AI's powerful features through standardized MCP tools and prompts, allowing you to manage chatflows, document stores, assistants, and more directly from your MCP-compatible AI clients.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Install globally via npm:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g @answerai/answeragent-mcp
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or use with npx (no installation required):
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx @answerai/answeragent-mcp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
1. **Get Your Answer AI Credentials**:
|
|
24
|
+
- API Base URL (e.g., `https://your-instance.studio.theanswer.ai`)
|
|
25
|
+
- API Token (JWT token from your Answer AI instance)
|
|
26
|
+
|
|
27
|
+
2. **Test the Server**:
|
|
28
|
+
```bash
|
|
29
|
+
npx @modelcontextprotocol/inspector @answerai/answeragent-mcp
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Client Configuration
|
|
33
|
+
|
|
34
|
+
### Cursor IDE
|
|
35
|
+
|
|
36
|
+
Add this configuration to your `~/.cursor/mcp.json` file:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"mcpServers": {
|
|
41
|
+
"answerai-mcp": {
|
|
42
|
+
"command": "node",
|
|
43
|
+
"args": [
|
|
44
|
+
"/path/to/your/project/dist/index.js"
|
|
45
|
+
],
|
|
46
|
+
"env": {
|
|
47
|
+
"ANSWERAGENT_AI_API_BASE_URL": "https://your-instance.studio.theanswer.ai",
|
|
48
|
+
"ANSWERAGENT_AI_API_TOKEN": "your-jwt-token-here"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**For NPM installed version:**
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"answerai-mcp": {
|
|
60
|
+
"command": "npx",
|
|
61
|
+
"args": ["@answerai/answeragent-mcp"],
|
|
62
|
+
"env": {
|
|
63
|
+
"ANSWERAGENT_AI_API_BASE_URL": "https://your-instance.studio.theanswer.ai",
|
|
64
|
+
"ANSWERAGENT_AI_API_TOKEN": "your-jwt-token-here"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Claude Desktop
|
|
72
|
+
|
|
73
|
+
Add this to your Claude Desktop MCP settings file:
|
|
74
|
+
|
|
75
|
+
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
76
|
+
**Windows**: `%APPDATA%/Claude/claude_desktop_config.json`
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"mcpServers": {
|
|
81
|
+
"answerai": {
|
|
82
|
+
"command": "npx",
|
|
83
|
+
"args": ["@answerai/answeragent-mcp"],
|
|
84
|
+
"env": {
|
|
85
|
+
"ANSWERAGENT_AI_API_BASE_URL": "https://your-instance.studio.theanswer.ai",
|
|
86
|
+
"ANSWERAGENT_AI_API_TOKEN": "your-jwt-token-here"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Other MCP Clients (Cline, etc.)
|
|
94
|
+
|
|
95
|
+
Most MCP clients follow the same pattern:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"command": "npx",
|
|
100
|
+
"args": ["@answerai/answeragent-mcp"],
|
|
101
|
+
"env": {
|
|
102
|
+
"ANSWERAGENT_AI_API_BASE_URL": "https://your-instance.studio.theanswer.ai",
|
|
103
|
+
"ANSWERAGENT_AI_API_TOKEN": "your-jwt-token-here"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Configuration
|
|
109
|
+
|
|
110
|
+
The server requires two environment variables:
|
|
111
|
+
|
|
112
|
+
- `ANSWERAGENT_AI_API_BASE_URL`: Your Answer AI instance base URL (without `/api/v1`)
|
|
113
|
+
- `ANSWERAGENT_AI_API_TOKEN`: Your Answer AI JWT authentication token
|
|
114
|
+
|
|
115
|
+
**Important**:
|
|
116
|
+
- Don't include `/api/v1` in the base URL - the server adds this automatically
|
|
117
|
+
- Make sure you're using a JWT token, not an API key
|
|
118
|
+
- The token must have appropriate permissions for the operations you want to perform
|
|
119
|
+
|
|
120
|
+
## Available Tools
|
|
121
|
+
|
|
122
|
+
### Chatflow Management
|
|
123
|
+
- `create_chatflow` - Create new chatflows
|
|
124
|
+
- `get_chatflow` - Retrieve chatflow details
|
|
125
|
+
- `update_chatflow` - Update existing chatflows
|
|
126
|
+
- `delete_chatflow` - Remove chatflows
|
|
127
|
+
- `list_chatflows` - List all chatflows
|
|
128
|
+
|
|
129
|
+
### Document Store Management
|
|
130
|
+
- `create_document_store` - Create document stores
|
|
131
|
+
- `get_document_store` - Get store details
|
|
132
|
+
- `delete_document_store` - Remove document stores
|
|
133
|
+
- `list_document_stores` - List all stores
|
|
134
|
+
- `query_vector_store` - Query document stores
|
|
135
|
+
- `upsert_document` - Add/update documents
|
|
136
|
+
- `refresh_document_store` - Refresh store contents
|
|
137
|
+
|
|
138
|
+
### Assistant Management
|
|
139
|
+
- `create_assistant` - Create AI assistants
|
|
140
|
+
- `get_assistant` - Get assistant details
|
|
141
|
+
- `update_assistant` - Update assistants
|
|
142
|
+
- `delete_assistant` - Remove assistants
|
|
143
|
+
- `list_assistants` - List all assistants
|
|
144
|
+
|
|
145
|
+
### Tool Management
|
|
146
|
+
- `create_tool` - Create custom tools
|
|
147
|
+
- `get_tool` - Get tool details
|
|
148
|
+
- `update_tool` - Update tools
|
|
149
|
+
- `delete_tool` - Remove tools
|
|
150
|
+
- `list_tools` - List all tools
|
|
151
|
+
|
|
152
|
+
### Document Loader Management
|
|
153
|
+
- `get_loader_chunks` - Get document chunks
|
|
154
|
+
- `update_loader_chunk` - Update chunks
|
|
155
|
+
- `delete_loader_chunk` - Remove chunks
|
|
156
|
+
- `delete_loader` - Remove loaders
|
|
157
|
+
|
|
158
|
+
## Intelligent Prompts
|
|
159
|
+
|
|
160
|
+
The server provides AI-powered prompts for advanced analysis and management:
|
|
161
|
+
|
|
162
|
+
### `analyze_chatflow`
|
|
163
|
+
Analyzes chatflow configuration and provides optimization recommendations.
|
|
164
|
+
|
|
165
|
+
**Arguments:**
|
|
166
|
+
- `chatflowId` (required): The chatflow ID to analyze
|
|
167
|
+
- `focusAreas` (optional): Array of specific areas to focus on
|
|
168
|
+
|
|
169
|
+
### `analyze_document_store`
|
|
170
|
+
Analyzes document store configuration, loaders, and usage patterns.
|
|
171
|
+
|
|
172
|
+
**Arguments:**
|
|
173
|
+
- `documentStoreId` (required): The document store ID to analyze
|
|
174
|
+
- `focusAreas` (optional): Array of specific areas to focus on
|
|
175
|
+
|
|
176
|
+
### `manage_document_store`
|
|
177
|
+
Provides step-by-step guidance for document store operations.
|
|
178
|
+
|
|
179
|
+
**Arguments:**
|
|
180
|
+
- `action` (required): One of "setup", "optimize", "troubleshoot", "migrate"
|
|
181
|
+
- `documentStoreId` (optional): Target document store ID
|
|
182
|
+
- `context` (optional): Additional context for the operation
|
|
183
|
+
|
|
184
|
+
## Usage Examples
|
|
185
|
+
|
|
186
|
+
### With Cursor IDE
|
|
187
|
+
|
|
188
|
+
After configuring in Cursor, you can use natural language commands:
|
|
189
|
+
|
|
190
|
+
1. **List your chatflows**:
|
|
191
|
+
> "Show me all my Answer AI chatflows"
|
|
192
|
+
|
|
193
|
+
2. **Analyze a specific chatflow**:
|
|
194
|
+
> "Analyze the 'RDS Call Analysis' chatflow and suggest optimizations"
|
|
195
|
+
|
|
196
|
+
3. **Create a document store**:
|
|
197
|
+
> "Create a new document store called 'Customer Support KB' for storing help articles"
|
|
198
|
+
|
|
199
|
+
4. **Query documents**:
|
|
200
|
+
> "Search my 'Contracts' document store for information about payment terms"
|
|
201
|
+
|
|
202
|
+
### With Claude Desktop
|
|
203
|
+
|
|
204
|
+
After adding to your Claude Desktop configuration:
|
|
205
|
+
|
|
206
|
+
1. **Analyze a chatflow**:
|
|
207
|
+
> "Please analyze my chatflow with ID 'df23d39c-a25b-4842-8997-dce3afed88f4' and focus on performance optimization"
|
|
208
|
+
|
|
209
|
+
2. **Document store management**:
|
|
210
|
+
> "Help me troubleshoot my document store that's not syncing properly"
|
|
211
|
+
|
|
212
|
+
3. **Assistant management**:
|
|
213
|
+
> "Show me details about my 'Document Reader' assistant and suggest improvements"
|
|
214
|
+
|
|
215
|
+
### With MCP Inspector
|
|
216
|
+
|
|
217
|
+
Test and explore the server capabilities:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
npx @modelcontextprotocol/inspector @answerai/answeragent-mcp
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Troubleshooting
|
|
224
|
+
|
|
225
|
+
### Common Issues
|
|
226
|
+
|
|
227
|
+
1. **401 Unauthorized Error**:
|
|
228
|
+
- Check that your JWT token is valid and not expired
|
|
229
|
+
- Ensure you're using a JWT token, not an API key
|
|
230
|
+
- Verify the token has the necessary permissions
|
|
231
|
+
|
|
232
|
+
2. **Connection Issues**:
|
|
233
|
+
- Confirm your base URL is correct (without `/api/v1`)
|
|
234
|
+
- Check that your Answer AI instance is accessible
|
|
235
|
+
- Verify environment variables are set correctly
|
|
236
|
+
|
|
237
|
+
3. **Tool Not Found**:
|
|
238
|
+
- Restart your MCP client after configuration changes
|
|
239
|
+
- Check the server logs for any startup errors
|
|
240
|
+
- Verify the package is properly installed
|
|
241
|
+
|
|
242
|
+
## Requirements
|
|
243
|
+
|
|
244
|
+
- Node.js 18+
|
|
245
|
+
- Valid Answer AI JWT token with appropriate permissions
|
|
246
|
+
- MCP-compatible client (Claude Desktop, Cursor, Cline, etc.)
|
|
247
|
+
|
|
248
|
+
## Support
|
|
249
|
+
|
|
250
|
+
For issues and feature requests, visit our [GitHub repository](https://github.com/bradtaylor/answerai-mcp).
|
|
251
|
+
|
|
252
|
+
## License
|
|
253
|
+
|
|
254
|
+
ISC
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import * as prompts from "./prompts/index.js";
|
|
6
|
+
import { getAllTools, handleToolCall } from "./tools/registry.js";
|
|
7
|
+
// Create MCP server
|
|
8
|
+
const server = new Server({
|
|
9
|
+
name: "answerai-mcp",
|
|
10
|
+
version: "1.0.0",
|
|
11
|
+
}, {
|
|
12
|
+
capabilities: {
|
|
13
|
+
tools: {},
|
|
14
|
+
prompts: {},
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
// Register tools
|
|
18
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
19
|
+
return { tools: getAllTools() };
|
|
20
|
+
});
|
|
21
|
+
// Register prompts
|
|
22
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
23
|
+
return {
|
|
24
|
+
prompts: [
|
|
25
|
+
{
|
|
26
|
+
name: prompts.analyzeChatflowPrompt.name,
|
|
27
|
+
description: prompts.analyzeChatflowPrompt.description,
|
|
28
|
+
schema: prompts.analyzeChatflowPrompt.schema,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: prompts.analyzeDocumentStorePrompt.name,
|
|
32
|
+
description: prompts.analyzeDocumentStorePrompt.description,
|
|
33
|
+
schema: prompts.analyzeDocumentStorePrompt.schema,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: prompts.manageDocumentStorePrompt.name,
|
|
37
|
+
description: prompts.manageDocumentStorePrompt.description,
|
|
38
|
+
schema: prompts.manageDocumentStorePrompt.schema,
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
// Handle prompt requests
|
|
44
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
45
|
+
const { name, arguments: args = {} } = request.params;
|
|
46
|
+
try {
|
|
47
|
+
switch (name) {
|
|
48
|
+
case prompts.analyzeChatflowPrompt.name:
|
|
49
|
+
return await prompts.analyzeChatflowPrompt.handler({
|
|
50
|
+
chatflowId: args.chatflowId,
|
|
51
|
+
focusAreas: Array.isArray(args.focusAreas)
|
|
52
|
+
? args.focusAreas
|
|
53
|
+
: undefined,
|
|
54
|
+
});
|
|
55
|
+
case prompts.analyzeDocumentStorePrompt.name:
|
|
56
|
+
return await prompts.analyzeDocumentStorePrompt.handler({
|
|
57
|
+
documentStoreId: args.documentStoreId,
|
|
58
|
+
focusAreas: Array.isArray(args.focusAreas)
|
|
59
|
+
? args.focusAreas
|
|
60
|
+
: undefined,
|
|
61
|
+
});
|
|
62
|
+
case prompts.manageDocumentStorePrompt.name:
|
|
63
|
+
return await prompts.manageDocumentStorePrompt.handler({
|
|
64
|
+
action: args.action,
|
|
65
|
+
documentStoreId: args.documentStoreId,
|
|
66
|
+
context: args.context,
|
|
67
|
+
});
|
|
68
|
+
default:
|
|
69
|
+
throw new Error(`Unknown prompt: ${name}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
const err = error;
|
|
74
|
+
throw new Error(`Prompt error: ${err.message || "An unexpected error occurred"} ${err.statusCode ? `(Status: ${err.statusCode})` : ""}`);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// Handle tool calls
|
|
78
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
79
|
+
const { name, arguments: args = {} } = request.params;
|
|
80
|
+
try {
|
|
81
|
+
const result = (await handleToolCall(name, args));
|
|
82
|
+
return {
|
|
83
|
+
_meta: {},
|
|
84
|
+
content: result.content,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
console.error(`Error executing tool ${name}:`, error);
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
// Start the server
|
|
93
|
+
async function main() {
|
|
94
|
+
const transport = new StdioServerTransport();
|
|
95
|
+
await server.connect(transport);
|
|
96
|
+
}
|
|
97
|
+
main().catch((error) => {
|
|
98
|
+
console.error("Server error:", error);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
});
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ChatflowsService } from "../services/chatflows.js";
|
|
3
|
+
const chatflowsService = ChatflowsService.getInstance();
|
|
4
|
+
/**
|
|
5
|
+
* Chatflow Analysis Prompt
|
|
6
|
+
*
|
|
7
|
+
* This prompt analyzes a chatflow and provides structured insights
|
|
8
|
+
* about its configuration, nodes, and potential improvements.
|
|
9
|
+
*/
|
|
10
|
+
export const analyzeChatflowPrompt = {
|
|
11
|
+
name: "analyze_chatflow",
|
|
12
|
+
description: "Analyzes a chatflow and provides structured insights about its configuration and nodes",
|
|
13
|
+
schema: {
|
|
14
|
+
chatflowId: z.string().describe("The ID of the chatflow to analyze"),
|
|
15
|
+
focusAreas: z
|
|
16
|
+
.array(z.string())
|
|
17
|
+
.optional()
|
|
18
|
+
.default([])
|
|
19
|
+
.describe("Specific areas to focus on in the analysis (e.g., 'prompts', 'nodes', 'credentials')"),
|
|
20
|
+
},
|
|
21
|
+
handler: async ({ chatflowId, focusAreas = [], }) => {
|
|
22
|
+
// Fetch the chatflow data
|
|
23
|
+
const chatflow = await chatflowsService.getChatflow(chatflowId, true);
|
|
24
|
+
if (!chatflow) {
|
|
25
|
+
throw new Error(`Chatflow with ID ${chatflowId} not found`);
|
|
26
|
+
}
|
|
27
|
+
// Extract key information from the chatflow
|
|
28
|
+
const { name, description, deployed, isPublic, category, type, parsedFlowData, createdDate, updatedDate, } = chatflow;
|
|
29
|
+
// Analyze the flow data
|
|
30
|
+
const nodeAnalysis = [];
|
|
31
|
+
const credentialAnalysis = [];
|
|
32
|
+
const promptAnalysis = [];
|
|
33
|
+
if (parsedFlowData) {
|
|
34
|
+
// Analyze nodes
|
|
35
|
+
for (const node of parsedFlowData.nodes) {
|
|
36
|
+
nodeAnalysis.push({
|
|
37
|
+
id: node.id,
|
|
38
|
+
type: node.type,
|
|
39
|
+
label: node.label,
|
|
40
|
+
description: node.description,
|
|
41
|
+
category: node.category,
|
|
42
|
+
hasPrompts: !!node.prompts,
|
|
43
|
+
hasCredentials: !!node.credential,
|
|
44
|
+
});
|
|
45
|
+
// Analyze prompts within nodes
|
|
46
|
+
if (node.prompts && (focusAreas.length === 0 || focusAreas.includes("prompts"))) {
|
|
47
|
+
const { systemMessagePrompt, humanMessagePrompt, agentInstructions } = node.prompts;
|
|
48
|
+
if (systemMessagePrompt) {
|
|
49
|
+
promptAnalysis.push({
|
|
50
|
+
nodeId: node.id,
|
|
51
|
+
nodeLabel: node.label,
|
|
52
|
+
type: "system",
|
|
53
|
+
content: systemMessagePrompt,
|
|
54
|
+
length: systemMessagePrompt.length,
|
|
55
|
+
hasVariables: systemMessagePrompt.includes("{") || systemMessagePrompt.includes("{{"),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (humanMessagePrompt) {
|
|
59
|
+
promptAnalysis.push({
|
|
60
|
+
nodeId: node.id,
|
|
61
|
+
nodeLabel: node.label,
|
|
62
|
+
type: "human",
|
|
63
|
+
content: humanMessagePrompt,
|
|
64
|
+
length: humanMessagePrompt.length,
|
|
65
|
+
hasVariables: humanMessagePrompt.includes("{") || humanMessagePrompt.includes("{{"),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
if (agentInstructions) {
|
|
69
|
+
promptAnalysis.push({
|
|
70
|
+
nodeId: node.id,
|
|
71
|
+
nodeLabel: node.label,
|
|
72
|
+
type: "agent",
|
|
73
|
+
content: agentInstructions,
|
|
74
|
+
length: agentInstructions.length,
|
|
75
|
+
hasVariables: agentInstructions.includes("{") || agentInstructions.includes("{{"),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Analyze credentials
|
|
81
|
+
for (const credentialId of parsedFlowData.credentialIds) {
|
|
82
|
+
credentialAnalysis.push({
|
|
83
|
+
id: credentialId,
|
|
84
|
+
usedByNodes: parsedFlowData.nodes.filter(n => n.credential === credentialId).length,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Generate insights
|
|
89
|
+
const insights = [];
|
|
90
|
+
// Node insights
|
|
91
|
+
if (nodeAnalysis.length > 0) {
|
|
92
|
+
insights.push(`Flow contains ${nodeAnalysis.length} nodes`);
|
|
93
|
+
const nodeTypes = [...new Set(nodeAnalysis.map(n => n.type))];
|
|
94
|
+
insights.push(`Node types: ${nodeTypes.join(", ")}`);
|
|
95
|
+
const nodesWithPrompts = nodeAnalysis.filter(n => n.hasPrompts).length;
|
|
96
|
+
if (nodesWithPrompts > 0) {
|
|
97
|
+
insights.push(`${nodesWithPrompts} nodes have custom prompts`);
|
|
98
|
+
}
|
|
99
|
+
const nodesWithCredentials = nodeAnalysis.filter(n => n.hasCredentials).length;
|
|
100
|
+
if (nodesWithCredentials > 0) {
|
|
101
|
+
insights.push(`${nodesWithCredentials} nodes use credentials`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Prompt insights
|
|
105
|
+
if (promptAnalysis.length > 0) {
|
|
106
|
+
const avgPromptLength = promptAnalysis.reduce((sum, p) => sum + p.length, 0) / promptAnalysis.length;
|
|
107
|
+
insights.push(`Average prompt length: ${Math.round(avgPromptLength)} characters`);
|
|
108
|
+
const promptsWithVariables = promptAnalysis.filter(p => p.hasVariables).length;
|
|
109
|
+
if (promptsWithVariables > 0) {
|
|
110
|
+
insights.push(`${promptsWithVariables} prompts use variables`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Credential insights
|
|
114
|
+
if (credentialAnalysis.length > 0) {
|
|
115
|
+
insights.push(`Uses ${credentialAnalysis.length} different credentials`);
|
|
116
|
+
}
|
|
117
|
+
// Generate recommendations
|
|
118
|
+
const recommendations = [];
|
|
119
|
+
if (nodeAnalysis.length > 10) {
|
|
120
|
+
recommendations.push("Consider breaking down complex flows into smaller, more manageable components");
|
|
121
|
+
}
|
|
122
|
+
if (promptAnalysis.length > 0) {
|
|
123
|
+
const longPrompts = promptAnalysis.filter(p => p.length > 1000);
|
|
124
|
+
if (longPrompts.length > 0) {
|
|
125
|
+
recommendations.push(`${longPrompts.length} prompts are quite long (>1000 chars) - consider breaking them down`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (!deployed && isPublic) {
|
|
129
|
+
recommendations.push("Chatflow is public but not deployed - consider deploying or making it private");
|
|
130
|
+
}
|
|
131
|
+
if (!description) {
|
|
132
|
+
recommendations.push("Add a description to help users understand the chatflow's purpose");
|
|
133
|
+
}
|
|
134
|
+
// Filter analysis based on focus areas
|
|
135
|
+
let filteredNodeAnalysis = nodeAnalysis;
|
|
136
|
+
let filteredPromptAnalysis = promptAnalysis;
|
|
137
|
+
let filteredCredentialAnalysis = credentialAnalysis;
|
|
138
|
+
if (focusAreas.length > 0) {
|
|
139
|
+
if (!focusAreas.includes("nodes")) {
|
|
140
|
+
filteredNodeAnalysis = [];
|
|
141
|
+
}
|
|
142
|
+
if (!focusAreas.includes("prompts")) {
|
|
143
|
+
filteredPromptAnalysis = [];
|
|
144
|
+
}
|
|
145
|
+
if (!focusAreas.includes("credentials")) {
|
|
146
|
+
filteredCredentialAnalysis = [];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Construct the analysis response
|
|
150
|
+
return {
|
|
151
|
+
messages: [
|
|
152
|
+
{
|
|
153
|
+
role: "assistant",
|
|
154
|
+
content: {
|
|
155
|
+
type: "text",
|
|
156
|
+
text: `# Chatflow Analysis: ${name}
|
|
157
|
+
|
|
158
|
+
## Overview
|
|
159
|
+
- **Name**: ${name}
|
|
160
|
+
- **Description**: ${description || "No description provided"}
|
|
161
|
+
- **Status**: ${deployed ? "Deployed" : "Not deployed"}
|
|
162
|
+
- **Visibility**: ${isPublic ? "Public" : "Private"}
|
|
163
|
+
- **Category**: ${category || "Uncategorized"}
|
|
164
|
+
- **Type**: ${type || "Unknown"}
|
|
165
|
+
- **Created**: ${createdDate ? new Date(createdDate).toLocaleDateString() : "Unknown"}
|
|
166
|
+
- **Updated**: ${updatedDate ? new Date(updatedDate).toLocaleDateString() : "Unknown"}
|
|
167
|
+
|
|
168
|
+
## Key Insights
|
|
169
|
+
${insights.map(i => `- ${i}`).join("\n")}
|
|
170
|
+
|
|
171
|
+
${filteredNodeAnalysis.length > 0 ? `## Node Analysis
|
|
172
|
+
${filteredNodeAnalysis.map(node => `
|
|
173
|
+
### ${node.label} (${node.type})
|
|
174
|
+
- **ID**: ${node.id}
|
|
175
|
+
- **Description**: ${node.description || "No description"}
|
|
176
|
+
- **Category**: ${node.category || "Uncategorized"}
|
|
177
|
+
- **Has Prompts**: ${node.hasPrompts ? "Yes" : "No"}
|
|
178
|
+
- **Uses Credentials**: ${node.hasCredentials ? "Yes" : "No"}
|
|
179
|
+
`).join("\n")}` : ""}
|
|
180
|
+
|
|
181
|
+
${filteredPromptAnalysis.length > 0 ? `## Prompt Analysis
|
|
182
|
+
${filteredPromptAnalysis.map(prompt => `
|
|
183
|
+
### ${prompt.nodeLabel} - ${prompt.type.toUpperCase()} Prompt
|
|
184
|
+
- **Length**: ${prompt.length} characters
|
|
185
|
+
- **Uses Variables**: ${prompt.hasVariables ? "Yes" : "No"}
|
|
186
|
+
- **Content Preview**: ${prompt.content.substring(0, 100)}${prompt.content.length > 100 ? "..." : ""}
|
|
187
|
+
`).join("\n")}` : ""}
|
|
188
|
+
|
|
189
|
+
${filteredCredentialAnalysis.length > 0 ? `## Credential Analysis
|
|
190
|
+
${filteredCredentialAnalysis.map(cred => `
|
|
191
|
+
### Credential: ${cred.id}
|
|
192
|
+
- **Used by**: ${cred.usedByNodes} node(s)
|
|
193
|
+
`).join("\n")}` : ""}
|
|
194
|
+
|
|
195
|
+
## Recommendations
|
|
196
|
+
${recommendations.map(r => `- ${r}`).join("\n")}
|
|
197
|
+
|
|
198
|
+
## Summary
|
|
199
|
+
This chatflow ${deployed ? "is deployed and ready for use" : "is not yet deployed"}. ${recommendations.length > 0 ? `Consider implementing the ${recommendations.length} recommendations above to improve the flow.` : "The flow appears to be well-configured."}`,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
};
|
|
204
|
+
},
|
|
205
|
+
};
|