@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
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { DocumentStoreService } from "../services/document-store.js";
|
|
3
|
+
const documentStoreService = DocumentStoreService.getInstance();
|
|
4
|
+
/**
|
|
5
|
+
* Document Store Analysis Prompt
|
|
6
|
+
*
|
|
7
|
+
* This prompt analyzes a document store and provides structured insights
|
|
8
|
+
* about its configuration, loaders, and usage patterns.
|
|
9
|
+
*/
|
|
10
|
+
export const analyzeDocumentStorePrompt = {
|
|
11
|
+
name: "analyze_document_store",
|
|
12
|
+
description: "Analyzes a document store and provides structured insights about its configuration and usage",
|
|
13
|
+
schema: {
|
|
14
|
+
documentStoreId: z.string().describe("The ID of the document store 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., 'loaders', 'config', 'usage')"),
|
|
20
|
+
},
|
|
21
|
+
handler: async ({ documentStoreId, focusAreas = [], }) => {
|
|
22
|
+
// Fetch the document store data
|
|
23
|
+
const documentStore = await documentStoreService.getDocumentStore(documentStoreId);
|
|
24
|
+
if (!documentStore) {
|
|
25
|
+
throw new Error(`Document store with ID ${documentStoreId} not found`);
|
|
26
|
+
}
|
|
27
|
+
// Extract key information from the document store
|
|
28
|
+
const { name, description, loaders, whereUsed, status, vectorStoreConfig, embeddingConfig, recordManagerConfig, createdDate, updatedDate, } = documentStore;
|
|
29
|
+
// Parse configuration objects
|
|
30
|
+
let parsedLoaders = [];
|
|
31
|
+
let parsedVectorStoreConfig = null;
|
|
32
|
+
let parsedEmbeddingConfig = null;
|
|
33
|
+
let parsedRecordManagerConfig = null;
|
|
34
|
+
try {
|
|
35
|
+
if (loaders) {
|
|
36
|
+
parsedLoaders = JSON.parse(loaders);
|
|
37
|
+
}
|
|
38
|
+
if (vectorStoreConfig) {
|
|
39
|
+
parsedVectorStoreConfig = JSON.parse(vectorStoreConfig);
|
|
40
|
+
}
|
|
41
|
+
if (embeddingConfig) {
|
|
42
|
+
parsedEmbeddingConfig = JSON.parse(embeddingConfig);
|
|
43
|
+
}
|
|
44
|
+
if (recordManagerConfig) {
|
|
45
|
+
parsedRecordManagerConfig = JSON.parse(recordManagerConfig);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.warn("Failed to parse configuration objects:", error);
|
|
50
|
+
}
|
|
51
|
+
// Analyze loaders
|
|
52
|
+
const loaderAnalysis = [];
|
|
53
|
+
if (Array.isArray(parsedLoaders)) {
|
|
54
|
+
for (const loader of parsedLoaders) {
|
|
55
|
+
loaderAnalysis.push({
|
|
56
|
+
id: loader.id || "unknown",
|
|
57
|
+
type: loader.type || "unknown",
|
|
58
|
+
source: loader.source || "unknown",
|
|
59
|
+
status: loader.status || "unknown",
|
|
60
|
+
credential: loader.credential || null,
|
|
61
|
+
hasConfig: !!loader.config,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Analyze vector store configuration
|
|
66
|
+
const vectorStoreAnalysis = {
|
|
67
|
+
configured: !!parsedVectorStoreConfig,
|
|
68
|
+
type: parsedVectorStoreConfig?.type || "unknown",
|
|
69
|
+
provider: parsedVectorStoreConfig?.provider || "unknown",
|
|
70
|
+
dimensions: parsedVectorStoreConfig?.dimensions || "unknown",
|
|
71
|
+
indexName: parsedVectorStoreConfig?.indexName || "unknown",
|
|
72
|
+
};
|
|
73
|
+
// Analyze embedding configuration
|
|
74
|
+
const embeddingAnalysis = {
|
|
75
|
+
configured: !!parsedEmbeddingConfig,
|
|
76
|
+
model: parsedEmbeddingConfig?.model || "unknown",
|
|
77
|
+
provider: parsedEmbeddingConfig?.provider || "unknown",
|
|
78
|
+
dimensions: parsedEmbeddingConfig?.dimensions || "unknown",
|
|
79
|
+
maxTokens: parsedEmbeddingConfig?.maxTokens || "unknown",
|
|
80
|
+
};
|
|
81
|
+
// Generate insights
|
|
82
|
+
const insights = [];
|
|
83
|
+
// Basic insights
|
|
84
|
+
insights.push(`Document store status: ${status || "unknown"}`);
|
|
85
|
+
if (loaderAnalysis.length > 0) {
|
|
86
|
+
insights.push(`Contains ${loaderAnalysis.length} loader(s)`);
|
|
87
|
+
const loaderTypes = [...new Set(loaderAnalysis.map(l => l.type))];
|
|
88
|
+
insights.push(`Loader types: ${loaderTypes.join(", ")}`);
|
|
89
|
+
const activeLoaders = loaderAnalysis.filter(l => l.status === "active" || l.status === "ready").length;
|
|
90
|
+
if (activeLoaders > 0) {
|
|
91
|
+
insights.push(`${activeLoaders} loader(s) are active`);
|
|
92
|
+
}
|
|
93
|
+
const loadersWithCredentials = loaderAnalysis.filter(l => l.credential).length;
|
|
94
|
+
if (loadersWithCredentials > 0) {
|
|
95
|
+
insights.push(`${loadersWithCredentials} loader(s) use credentials`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (vectorStoreAnalysis.configured) {
|
|
99
|
+
insights.push(`Vector store configured: ${vectorStoreAnalysis.type} (${vectorStoreAnalysis.provider})`);
|
|
100
|
+
}
|
|
101
|
+
if (embeddingAnalysis.configured) {
|
|
102
|
+
insights.push(`Embedding model: ${embeddingAnalysis.model} (${embeddingAnalysis.provider})`);
|
|
103
|
+
}
|
|
104
|
+
if (whereUsed) {
|
|
105
|
+
try {
|
|
106
|
+
const usage = JSON.parse(whereUsed);
|
|
107
|
+
if (Array.isArray(usage)) {
|
|
108
|
+
insights.push(`Used by ${usage.length} chatflow(s)`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
insights.push(`Usage information available but not parseable`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Generate recommendations
|
|
116
|
+
const recommendations = [];
|
|
117
|
+
if (!description) {
|
|
118
|
+
recommendations.push("Add a description to help users understand the document store's purpose");
|
|
119
|
+
}
|
|
120
|
+
if (loaderAnalysis.length === 0) {
|
|
121
|
+
recommendations.push("No loaders configured - add document loaders to populate the store");
|
|
122
|
+
}
|
|
123
|
+
if (!vectorStoreAnalysis.configured) {
|
|
124
|
+
recommendations.push("Configure vector store settings for optimal document retrieval");
|
|
125
|
+
}
|
|
126
|
+
if (!embeddingAnalysis.configured) {
|
|
127
|
+
recommendations.push("Configure embedding model for document vectorization");
|
|
128
|
+
}
|
|
129
|
+
const inactiveLoaders = loaderAnalysis.filter(l => l.status !== "active" && l.status !== "ready").length;
|
|
130
|
+
if (inactiveLoaders > 0) {
|
|
131
|
+
recommendations.push(`${inactiveLoaders} loader(s) are not active - check their configuration`);
|
|
132
|
+
}
|
|
133
|
+
if (status === "error" || status === "failed") {
|
|
134
|
+
recommendations.push("Document store has errors - check logs and configuration");
|
|
135
|
+
}
|
|
136
|
+
// Filter analysis based on focus areas
|
|
137
|
+
let showLoaderAnalysis = focusAreas.length === 0 || focusAreas.includes("loaders");
|
|
138
|
+
let showConfigAnalysis = focusAreas.length === 0 || focusAreas.includes("config");
|
|
139
|
+
let showUsageAnalysis = focusAreas.length === 0 || focusAreas.includes("usage");
|
|
140
|
+
// Construct the analysis response
|
|
141
|
+
return {
|
|
142
|
+
messages: [
|
|
143
|
+
{
|
|
144
|
+
role: "assistant",
|
|
145
|
+
content: {
|
|
146
|
+
type: "text",
|
|
147
|
+
text: `# Document Store Analysis: ${name}
|
|
148
|
+
|
|
149
|
+
## Overview
|
|
150
|
+
- **Name**: ${name}
|
|
151
|
+
- **Description**: ${description || "No description provided"}
|
|
152
|
+
- **Status**: ${status || "Unknown"}
|
|
153
|
+
- **Created**: ${createdDate ? new Date(createdDate).toLocaleDateString() : "Unknown"}
|
|
154
|
+
- **Updated**: ${updatedDate ? new Date(updatedDate).toLocaleDateString() : "Unknown"}
|
|
155
|
+
|
|
156
|
+
## Key Insights
|
|
157
|
+
${insights.map(i => `- ${i}`).join("\n")}
|
|
158
|
+
|
|
159
|
+
${showLoaderAnalysis && loaderAnalysis.length > 0 ? `## Loader Analysis
|
|
160
|
+
${loaderAnalysis.map(loader => `
|
|
161
|
+
### ${loader.type} Loader
|
|
162
|
+
- **ID**: ${loader.id}
|
|
163
|
+
- **Source**: ${loader.source}
|
|
164
|
+
- **Status**: ${loader.status}
|
|
165
|
+
- **Uses Credentials**: ${loader.credential ? "Yes" : "No"}
|
|
166
|
+
- **Has Configuration**: ${loader.hasConfig ? "Yes" : "No"}
|
|
167
|
+
`).join("\n")}` : ""}
|
|
168
|
+
|
|
169
|
+
${showConfigAnalysis ? `## Configuration Analysis
|
|
170
|
+
|
|
171
|
+
### Vector Store Configuration
|
|
172
|
+
- **Configured**: ${vectorStoreAnalysis.configured ? "Yes" : "No"}
|
|
173
|
+
${vectorStoreAnalysis.configured ? `- **Type**: ${vectorStoreAnalysis.type}
|
|
174
|
+
- **Provider**: ${vectorStoreAnalysis.provider}
|
|
175
|
+
- **Dimensions**: ${vectorStoreAnalysis.dimensions}
|
|
176
|
+
- **Index Name**: ${vectorStoreAnalysis.indexName}` : ""}
|
|
177
|
+
|
|
178
|
+
### Embedding Configuration
|
|
179
|
+
- **Configured**: ${embeddingAnalysis.configured ? "Yes" : "No"}
|
|
180
|
+
${embeddingAnalysis.configured ? `- **Model**: ${embeddingAnalysis.model}
|
|
181
|
+
- **Provider**: ${embeddingAnalysis.provider}
|
|
182
|
+
- **Dimensions**: ${embeddingAnalysis.dimensions}
|
|
183
|
+
- **Max Tokens**: ${embeddingAnalysis.maxTokens}` : ""}
|
|
184
|
+
|
|
185
|
+
### Record Manager Configuration
|
|
186
|
+
- **Configured**: ${!!parsedRecordManagerConfig ? "Yes" : "No"}
|
|
187
|
+
${parsedRecordManagerConfig ? `- **Type**: ${parsedRecordManagerConfig.type || "Unknown"}` : ""}` : ""}
|
|
188
|
+
|
|
189
|
+
${showUsageAnalysis && whereUsed ? `## Usage Analysis
|
|
190
|
+
**Where Used**: ${whereUsed}` : ""}
|
|
191
|
+
|
|
192
|
+
## Recommendations
|
|
193
|
+
${recommendations.length > 0 ? recommendations.map(r => `- ${r}`).join("\n") : "- No specific recommendations - document store appears to be well-configured"}
|
|
194
|
+
|
|
195
|
+
## Summary
|
|
196
|
+
This document store ${status === "active" || status === "ready" ? "is active and ready for use" : "may need attention"}. ${recommendations.length > 0 ? `Consider implementing the ${recommendations.length} recommendations above to improve the store.` : "The store appears to be well-configured."}`,
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
};
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
/**
|
|
204
|
+
* Document Store Management Prompt
|
|
205
|
+
*
|
|
206
|
+
* This prompt provides guidance for managing document stores,
|
|
207
|
+
* including setup, configuration, and optimization suggestions.
|
|
208
|
+
*/
|
|
209
|
+
export const manageDocumentStorePrompt = {
|
|
210
|
+
name: "manage_document_store",
|
|
211
|
+
description: "Provides guidance for managing document stores including setup and configuration",
|
|
212
|
+
schema: {
|
|
213
|
+
action: z.enum(["setup", "optimize", "troubleshoot", "migrate"]).describe("The management action to perform"),
|
|
214
|
+
documentStoreId: z.string().optional().describe("The ID of the document store (required for optimize/troubleshoot)"),
|
|
215
|
+
context: z.string().optional().describe("Additional context about the situation"),
|
|
216
|
+
},
|
|
217
|
+
handler: async ({ action, documentStoreId, context, }) => {
|
|
218
|
+
let guidance = "";
|
|
219
|
+
let actionSteps = [];
|
|
220
|
+
switch (action) {
|
|
221
|
+
case "setup":
|
|
222
|
+
guidance = "Setting up a new document store requires careful planning of your data sources and retrieval requirements.";
|
|
223
|
+
actionSteps = [
|
|
224
|
+
"Define your document types and sources",
|
|
225
|
+
"Choose appropriate loaders for your data sources",
|
|
226
|
+
"Configure vector store settings based on your use case",
|
|
227
|
+
"Select an embedding model that matches your content",
|
|
228
|
+
"Set up record management for deduplication",
|
|
229
|
+
"Test with a small dataset first",
|
|
230
|
+
"Configure access controls and permissions",
|
|
231
|
+
"Monitor performance and adjust as needed",
|
|
232
|
+
];
|
|
233
|
+
break;
|
|
234
|
+
case "optimize":
|
|
235
|
+
guidance = "Optimizing your document store can improve retrieval quality and performance.";
|
|
236
|
+
actionSteps = [
|
|
237
|
+
"Analyze current retrieval performance metrics",
|
|
238
|
+
"Review and tune embedding model parameters",
|
|
239
|
+
"Optimize vector store configuration",
|
|
240
|
+
"Clean up duplicate or outdated documents",
|
|
241
|
+
"Adjust chunking strategies for better retrieval",
|
|
242
|
+
"Fine-tune similarity search parameters",
|
|
243
|
+
"Implement caching for frequently accessed documents",
|
|
244
|
+
"Monitor and adjust based on usage patterns",
|
|
245
|
+
];
|
|
246
|
+
break;
|
|
247
|
+
case "troubleshoot":
|
|
248
|
+
guidance = "Troubleshooting document store issues requires systematic diagnosis.";
|
|
249
|
+
actionSteps = [
|
|
250
|
+
"Check document store status and error logs",
|
|
251
|
+
"Verify loader configurations and credentials",
|
|
252
|
+
"Test vector store connectivity",
|
|
253
|
+
"Validate embedding model availability",
|
|
254
|
+
"Review recent changes to configuration",
|
|
255
|
+
"Check for data source connectivity issues",
|
|
256
|
+
"Verify permissions and access controls",
|
|
257
|
+
"Test with known good documents",
|
|
258
|
+
];
|
|
259
|
+
break;
|
|
260
|
+
case "migrate":
|
|
261
|
+
guidance = "Migrating document stores requires careful planning to avoid data loss.";
|
|
262
|
+
actionSteps = [
|
|
263
|
+
"Backup existing document store data",
|
|
264
|
+
"Plan migration strategy and timeline",
|
|
265
|
+
"Set up new document store configuration",
|
|
266
|
+
"Test migration process with subset of data",
|
|
267
|
+
"Migrate documents in batches",
|
|
268
|
+
"Validate data integrity after migration",
|
|
269
|
+
"Update chatflow configurations",
|
|
270
|
+
"Monitor performance post-migration",
|
|
271
|
+
];
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
// If a specific document store is provided, fetch its details
|
|
275
|
+
let storeDetails = "";
|
|
276
|
+
if (documentStoreId) {
|
|
277
|
+
try {
|
|
278
|
+
const store = await documentStoreService.getDocumentStore(documentStoreId);
|
|
279
|
+
storeDetails = `
|
|
280
|
+
## Current Document Store Details
|
|
281
|
+
- **Name**: ${store.name}
|
|
282
|
+
- **Status**: ${store.status || "Unknown"}
|
|
283
|
+
- **Description**: ${store.description || "No description"}
|
|
284
|
+
`;
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
storeDetails = `
|
|
288
|
+
## Document Store Status
|
|
289
|
+
- **Error**: Could not fetch details for store ${documentStoreId}
|
|
290
|
+
`;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
messages: [
|
|
295
|
+
{
|
|
296
|
+
role: "assistant",
|
|
297
|
+
content: {
|
|
298
|
+
type: "text",
|
|
299
|
+
text: `# Document Store Management: ${action.toUpperCase()}
|
|
300
|
+
|
|
301
|
+
## Overview
|
|
302
|
+
${guidance}
|
|
303
|
+
|
|
304
|
+
${context ? `## Context
|
|
305
|
+
${context}` : ""}
|
|
306
|
+
|
|
307
|
+
${storeDetails}
|
|
308
|
+
|
|
309
|
+
## Action Steps
|
|
310
|
+
${actionSteps.map((step, index) => `${index + 1}. ${step}`).join("\n")}
|
|
311
|
+
|
|
312
|
+
## Best Practices
|
|
313
|
+
- Always backup before making significant changes
|
|
314
|
+
- Test changes in a development environment first
|
|
315
|
+
- Monitor performance metrics after changes
|
|
316
|
+
- Document your configuration decisions
|
|
317
|
+
- Keep track of data sources and their update frequencies
|
|
318
|
+
- Regularly review and clean up unused documents
|
|
319
|
+
|
|
320
|
+
## Next Steps
|
|
321
|
+
${action === "setup" ? "Start with a small pilot dataset to validate your configuration." : ""}${action === "optimize" ? "Focus on the areas that will have the biggest impact on your use case." : ""}${action === "troubleshoot" ? "Work through the steps systematically to identify the root cause." : ""}${action === "migrate" ? "Plan your migration carefully and have a rollback strategy ready." : ""}`,
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
};
|
|
326
|
+
},
|
|
327
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import dotenv from "dotenv";
|
|
3
|
+
dotenv.config();
|
|
4
|
+
if (!process.env.ANSWERAGENT_AI_API_BASE_URL || !process.env.ANSWERAGENT_AI_API_TOKEN) {
|
|
5
|
+
throw new Error("Missing AnswerAgent API configuration");
|
|
6
|
+
}
|
|
7
|
+
export const apiClient = axios.create({
|
|
8
|
+
baseURL: `${process.env.ANSWERAGENT_AI_API_BASE_URL}/api/v1`,
|
|
9
|
+
timeout: process.env.API_TIMEOUT ? Number(process.env.API_TIMEOUT) : 5000,
|
|
10
|
+
headers: {
|
|
11
|
+
Authorization: `Bearer ${process.env.ANSWERAGENT_AI_API_TOKEN}`,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { apiClient } from "./api-client.js";
|
|
2
|
+
export class AssistantsService {
|
|
3
|
+
constructor() { }
|
|
4
|
+
static getInstance() {
|
|
5
|
+
if (!AssistantsService.instance) {
|
|
6
|
+
AssistantsService.instance = new AssistantsService();
|
|
7
|
+
}
|
|
8
|
+
return AssistantsService.instance;
|
|
9
|
+
}
|
|
10
|
+
async listAssistants() {
|
|
11
|
+
const { data } = await apiClient.get("/assistants");
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
async getAssistant(id) {
|
|
15
|
+
const { data } = await apiClient.get(`/assistants/${id}`);
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
18
|
+
async createAssistant(assistant) {
|
|
19
|
+
const { data } = await apiClient.post("/assistants", assistant);
|
|
20
|
+
return data;
|
|
21
|
+
}
|
|
22
|
+
async updateAssistant(id, assistant) {
|
|
23
|
+
const { data } = await apiClient.put(`/assistants/${id}`, assistant);
|
|
24
|
+
return data;
|
|
25
|
+
}
|
|
26
|
+
async deleteAssistant(id) {
|
|
27
|
+
await apiClient.delete(`/assistants/${id}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { apiClient } from "./api-client.js";
|
|
2
|
+
export class ChatflowsService {
|
|
3
|
+
constructor() { }
|
|
4
|
+
static getInstance() {
|
|
5
|
+
if (!ChatflowsService.instance) {
|
|
6
|
+
ChatflowsService.instance = new ChatflowsService();
|
|
7
|
+
}
|
|
8
|
+
return ChatflowsService.instance;
|
|
9
|
+
}
|
|
10
|
+
async listChatflows() {
|
|
11
|
+
const { data } = await apiClient.get("/chatflows");
|
|
12
|
+
return data.map((chatflow) => ({
|
|
13
|
+
id: chatflow.id,
|
|
14
|
+
name: chatflow.name,
|
|
15
|
+
description: chatflow.description,
|
|
16
|
+
visibility: chatflow.visibility,
|
|
17
|
+
isPublic: chatflow.isPublic,
|
|
18
|
+
category: chatflow.category,
|
|
19
|
+
type: chatflow.type,
|
|
20
|
+
userId: chatflow.userId,
|
|
21
|
+
organizationId: chatflow.organizationId,
|
|
22
|
+
createdDate: chatflow.createdDate,
|
|
23
|
+
updatedDate: chatflow.updatedDate,
|
|
24
|
+
deleteDate: chatflow.deleteDate,
|
|
25
|
+
badge: chatflow.badge,
|
|
26
|
+
isOwner: chatflow.isOwner,
|
|
27
|
+
canEdit: chatflow.canEdit,
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
async getChatflow(id, includeFullFlowData = false) {
|
|
31
|
+
const { data } = await apiClient.get(`/chatflows/${id}`);
|
|
32
|
+
// Parse flowData if it exists
|
|
33
|
+
if (data.flowData) {
|
|
34
|
+
try {
|
|
35
|
+
const flowDataObj = JSON.parse(data.flowData);
|
|
36
|
+
// Extract relevant node information and credentials
|
|
37
|
+
const nodesInfo = flowDataObj.nodes.map((node) => {
|
|
38
|
+
const nodeInfo = {
|
|
39
|
+
id: node.id,
|
|
40
|
+
type: node.data.type,
|
|
41
|
+
label: node.data.label,
|
|
42
|
+
description: node.data.description,
|
|
43
|
+
category: node.data.category,
|
|
44
|
+
credential: node.data.credential || node.data.inputs?.credential,
|
|
45
|
+
};
|
|
46
|
+
// Extract prompt templates and agent instructions if they exist
|
|
47
|
+
const systemPrompt = node.data.inputs?.systemMessagePrompt;
|
|
48
|
+
const humanPrompt = node.data.inputs?.humanMessagePrompt;
|
|
49
|
+
const agentInstructions = node.data.inputs?.agentInstructions;
|
|
50
|
+
if (systemPrompt || humanPrompt || agentInstructions) {
|
|
51
|
+
nodeInfo.prompts = {
|
|
52
|
+
systemMessagePrompt: systemPrompt,
|
|
53
|
+
humanMessagePrompt: humanPrompt,
|
|
54
|
+
agentInstructions: agentInstructions,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return nodeInfo;
|
|
58
|
+
});
|
|
59
|
+
// Extract all credential IDs
|
|
60
|
+
const credentialIds = flowDataObj.nodes
|
|
61
|
+
.map((node) => node.data.credential || node.data.inputs?.credential)
|
|
62
|
+
.filter(Boolean);
|
|
63
|
+
// Add parsed data to the response
|
|
64
|
+
data.parsedFlowData = {
|
|
65
|
+
nodes: nodesInfo,
|
|
66
|
+
credentialIds: [...new Set(credentialIds)], // Remove duplicates
|
|
67
|
+
};
|
|
68
|
+
// Create a new object without flowData if not requested
|
|
69
|
+
if (!includeFullFlowData) {
|
|
70
|
+
const { flowData: _, ...dataWithoutFlowData } = data;
|
|
71
|
+
return {
|
|
72
|
+
...dataWithoutFlowData,
|
|
73
|
+
parsedFlowData: data.parsedFlowData,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.error("Error parsing flowData:", error);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return data;
|
|
82
|
+
}
|
|
83
|
+
async createChatflow(chatflow) {
|
|
84
|
+
const { data } = await apiClient.post("/chatflows", chatflow);
|
|
85
|
+
return data;
|
|
86
|
+
}
|
|
87
|
+
async updateChatflow(id, chatflow) {
|
|
88
|
+
const { data } = await apiClient.put(`/chatflows/${id}`, chatflow);
|
|
89
|
+
return data;
|
|
90
|
+
}
|
|
91
|
+
async deleteChatflow(id) {
|
|
92
|
+
await apiClient.delete(`/chatflows/${id}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { apiClient } from "./api-client.js";
|
|
2
|
+
export class DocumentLoaderService {
|
|
3
|
+
constructor() { }
|
|
4
|
+
static getInstance() {
|
|
5
|
+
if (!DocumentLoaderService.instance) {
|
|
6
|
+
DocumentLoaderService.instance = new DocumentLoaderService();
|
|
7
|
+
}
|
|
8
|
+
return DocumentLoaderService.instance;
|
|
9
|
+
}
|
|
10
|
+
async deleteLoader(storeId, loaderId) {
|
|
11
|
+
await apiClient.delete(`/document-store/loader/${storeId}/${loaderId}`);
|
|
12
|
+
}
|
|
13
|
+
async getChunks(storeId, loaderId, pageNo) {
|
|
14
|
+
const { data } = await apiClient.get(`/document-store/chunks/${storeId}/${loaderId}/${pageNo}`);
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
async updateChunk(storeId, loaderId, chunkId, payload) {
|
|
18
|
+
const { data } = await apiClient.put(`/document-store/chunks/${storeId}/${loaderId}/${chunkId}`, payload);
|
|
19
|
+
return data;
|
|
20
|
+
}
|
|
21
|
+
async deleteChunk(storeId, loaderId, chunkId) {
|
|
22
|
+
await apiClient.delete(`/document-store/chunks/${storeId}/${loaderId}/${chunkId}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { apiClient } from "./api-client.js";
|
|
2
|
+
export class DocumentStoreService {
|
|
3
|
+
constructor() { }
|
|
4
|
+
static getInstance() {
|
|
5
|
+
if (!DocumentStoreService.instance) {
|
|
6
|
+
DocumentStoreService.instance = new DocumentStoreService();
|
|
7
|
+
}
|
|
8
|
+
return DocumentStoreService.instance;
|
|
9
|
+
}
|
|
10
|
+
async listDocumentStores() {
|
|
11
|
+
const { data } = await apiClient.get("/document-store/store");
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
async getDocumentStore(id) {
|
|
15
|
+
const { data } = await apiClient.get(`/document-store/store/${id}`);
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
18
|
+
async createDocumentStore(data) {
|
|
19
|
+
const { data: res } = await apiClient.post("/document-store/store", data);
|
|
20
|
+
return res;
|
|
21
|
+
}
|
|
22
|
+
async updateDocumentStore(id, updates) {
|
|
23
|
+
const { data } = await apiClient.put(`/document-store/store/${id}`, updates);
|
|
24
|
+
return data;
|
|
25
|
+
}
|
|
26
|
+
async deleteDocumentStore(id) {
|
|
27
|
+
await apiClient.delete(`/document-store/store/${id}`);
|
|
28
|
+
}
|
|
29
|
+
async upsertDocument(id, payload) {
|
|
30
|
+
const { data } = await apiClient.post(`/document-store/upsert/${id}`, payload);
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
33
|
+
async refreshDocumentStore(id, payload) {
|
|
34
|
+
const { data } = await apiClient.post(`/document-store/refresh/${id}`, payload);
|
|
35
|
+
return data;
|
|
36
|
+
}
|
|
37
|
+
async queryVectorStore(payload) {
|
|
38
|
+
const { data } = await apiClient.post(`/document-store/vectorstore/query`, payload);
|
|
39
|
+
return data;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { apiClient } from "./api-client.js";
|
|
2
|
+
export class ToolsApiService {
|
|
3
|
+
constructor() { }
|
|
4
|
+
static getInstance() {
|
|
5
|
+
if (!ToolsApiService.instance) {
|
|
6
|
+
ToolsApiService.instance = new ToolsApiService();
|
|
7
|
+
}
|
|
8
|
+
return ToolsApiService.instance;
|
|
9
|
+
}
|
|
10
|
+
async listTools() {
|
|
11
|
+
const { data } = await apiClient.get("/tools");
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
async getTool(id) {
|
|
15
|
+
const { data } = await apiClient.get(`/tools/${id}`);
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
18
|
+
async createTool(tool) {
|
|
19
|
+
const { data } = await apiClient.post("/tools", tool);
|
|
20
|
+
return data;
|
|
21
|
+
}
|
|
22
|
+
async updateTool(id, tool) {
|
|
23
|
+
const { data } = await apiClient.put(`/tools/${id}`, tool);
|
|
24
|
+
return data;
|
|
25
|
+
}
|
|
26
|
+
async deleteTool(id) {
|
|
27
|
+
await apiClient.delete(`/tools/${id}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { AssistantsService } from "../services/assistants.js";
|
|
2
|
+
const service = AssistantsService.getInstance();
|
|
3
|
+
export const listAssistantsTool = {
|
|
4
|
+
name: "list_assistants",
|
|
5
|
+
description: "List assistants",
|
|
6
|
+
inputSchema: { type: "object", properties: {} },
|
|
7
|
+
handler: async () => {
|
|
8
|
+
const result = await service.listAssistants();
|
|
9
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
export const getAssistantTool = {
|
|
13
|
+
name: "get_assistant",
|
|
14
|
+
description: "Get assistant by ID",
|
|
15
|
+
inputSchema: {
|
|
16
|
+
type: "object",
|
|
17
|
+
properties: { id: { type: "string" } },
|
|
18
|
+
required: ["id"],
|
|
19
|
+
},
|
|
20
|
+
handler: async ({ id }) => {
|
|
21
|
+
const result = await service.getAssistant(id);
|
|
22
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
export const createAssistantTool = {
|
|
26
|
+
name: "create_assistant",
|
|
27
|
+
description: "Create assistant",
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: "object",
|
|
30
|
+
properties: {
|
|
31
|
+
details: { type: "object" },
|
|
32
|
+
},
|
|
33
|
+
required: ["details"],
|
|
34
|
+
},
|
|
35
|
+
handler: async (data) => {
|
|
36
|
+
const result = await service.createAssistant(data);
|
|
37
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
export const updateAssistantTool = {
|
|
41
|
+
name: "update_assistant",
|
|
42
|
+
description: "Update assistant",
|
|
43
|
+
inputSchema: {
|
|
44
|
+
type: "object",
|
|
45
|
+
properties: {
|
|
46
|
+
id: { type: "string" },
|
|
47
|
+
updates: { type: "object" },
|
|
48
|
+
},
|
|
49
|
+
required: ["id", "updates"],
|
|
50
|
+
},
|
|
51
|
+
handler: async ({ id, updates }) => {
|
|
52
|
+
const result = await service.updateAssistant(id, updates);
|
|
53
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
export const deleteAssistantTool = {
|
|
57
|
+
name: "delete_assistant",
|
|
58
|
+
description: "Delete assistant",
|
|
59
|
+
inputSchema: {
|
|
60
|
+
type: "object",
|
|
61
|
+
properties: { id: { type: "string" } },
|
|
62
|
+
required: ["id"],
|
|
63
|
+
},
|
|
64
|
+
handler: async ({ id }) => {
|
|
65
|
+
await service.deleteAssistant(id);
|
|
66
|
+
return { content: [{ type: "text", text: JSON.stringify({ success: true }) }] };
|
|
67
|
+
},
|
|
68
|
+
};
|