UNPKG

@answerai/answeragent-mcp

Version:

A lightweight Model Context Protocol (MCP) server for Answer AI chatflow and document store management

328 lines (311 loc) 14.8 kB
import { z } from "zod"; import { DocumentStoreService } from "../services/document-store.js"; const documentStoreService = DocumentStoreService.getInstance(); /** * Document Store Analysis Prompt * * This prompt analyzes a document store and provides structured insights * about its configuration, loaders, and usage patterns. */ export const analyzeDocumentStorePrompt = { name: "analyze_document_store", description: "Analyzes a document store and provides structured insights about its configuration and usage", schema: { documentStoreId: z.string().describe("The ID of the document store to analyze"), focusAreas: z .array(z.string()) .optional() .default([]) .describe("Specific areas to focus on in the analysis (e.g., 'loaders', 'config', 'usage')"), }, handler: async ({ documentStoreId, focusAreas = [], }) => { // Fetch the document store data const documentStore = await documentStoreService.getDocumentStore(documentStoreId); if (!documentStore) { throw new Error(`Document store with ID ${documentStoreId} not found`); } // Extract key information from the document store const { name, description, loaders, whereUsed, status, vectorStoreConfig, embeddingConfig, recordManagerConfig, createdDate, updatedDate, } = documentStore; // Parse configuration objects let parsedLoaders = []; let parsedVectorStoreConfig = null; let parsedEmbeddingConfig = null; let parsedRecordManagerConfig = null; try { if (loaders) { parsedLoaders = JSON.parse(loaders); } if (vectorStoreConfig) { parsedVectorStoreConfig = JSON.parse(vectorStoreConfig); } if (embeddingConfig) { parsedEmbeddingConfig = JSON.parse(embeddingConfig); } if (recordManagerConfig) { parsedRecordManagerConfig = JSON.parse(recordManagerConfig); } } catch (error) { console.warn("Failed to parse configuration objects:", error); } // Analyze loaders const loaderAnalysis = []; if (Array.isArray(parsedLoaders)) { for (const loader of parsedLoaders) { loaderAnalysis.push({ id: loader.id || "unknown", type: loader.type || "unknown", source: loader.source || "unknown", status: loader.status || "unknown", credential: loader.credential || null, hasConfig: !!loader.config, }); } } // Analyze vector store configuration const vectorStoreAnalysis = { configured: !!parsedVectorStoreConfig, type: parsedVectorStoreConfig?.type || "unknown", provider: parsedVectorStoreConfig?.provider || "unknown", dimensions: parsedVectorStoreConfig?.dimensions || "unknown", indexName: parsedVectorStoreConfig?.indexName || "unknown", }; // Analyze embedding configuration const embeddingAnalysis = { configured: !!parsedEmbeddingConfig, model: parsedEmbeddingConfig?.model || "unknown", provider: parsedEmbeddingConfig?.provider || "unknown", dimensions: parsedEmbeddingConfig?.dimensions || "unknown", maxTokens: parsedEmbeddingConfig?.maxTokens || "unknown", }; // Generate insights const insights = []; // Basic insights insights.push(`Document store status: ${status || "unknown"}`); if (loaderAnalysis.length > 0) { insights.push(`Contains ${loaderAnalysis.length} loader(s)`); const loaderTypes = [...new Set(loaderAnalysis.map(l => l.type))]; insights.push(`Loader types: ${loaderTypes.join(", ")}`); const activeLoaders = loaderAnalysis.filter(l => l.status === "active" || l.status === "ready").length; if (activeLoaders > 0) { insights.push(`${activeLoaders} loader(s) are active`); } const loadersWithCredentials = loaderAnalysis.filter(l => l.credential).length; if (loadersWithCredentials > 0) { insights.push(`${loadersWithCredentials} loader(s) use credentials`); } } if (vectorStoreAnalysis.configured) { insights.push(`Vector store configured: ${vectorStoreAnalysis.type} (${vectorStoreAnalysis.provider})`); } if (embeddingAnalysis.configured) { insights.push(`Embedding model: ${embeddingAnalysis.model} (${embeddingAnalysis.provider})`); } if (whereUsed) { try { const usage = JSON.parse(whereUsed); if (Array.isArray(usage)) { insights.push(`Used by ${usage.length} chatflow(s)`); } } catch (error) { insights.push(`Usage information available but not parseable`); } } // Generate recommendations const recommendations = []; if (!description) { recommendations.push("Add a description to help users understand the document store's purpose"); } if (loaderAnalysis.length === 0) { recommendations.push("No loaders configured - add document loaders to populate the store"); } if (!vectorStoreAnalysis.configured) { recommendations.push("Configure vector store settings for optimal document retrieval"); } if (!embeddingAnalysis.configured) { recommendations.push("Configure embedding model for document vectorization"); } const inactiveLoaders = loaderAnalysis.filter(l => l.status !== "active" && l.status !== "ready").length; if (inactiveLoaders > 0) { recommendations.push(`${inactiveLoaders} loader(s) are not active - check their configuration`); } if (status === "error" || status === "failed") { recommendations.push("Document store has errors - check logs and configuration"); } // Filter analysis based on focus areas let showLoaderAnalysis = focusAreas.length === 0 || focusAreas.includes("loaders"); let showConfigAnalysis = focusAreas.length === 0 || focusAreas.includes("config"); let showUsageAnalysis = focusAreas.length === 0 || focusAreas.includes("usage"); // Construct the analysis response return { messages: [ { role: "assistant", content: { type: "text", text: `# Document Store Analysis: ${name} ## Overview - **Name**: ${name} - **Description**: ${description || "No description provided"} - **Status**: ${status || "Unknown"} - **Created**: ${createdDate ? new Date(createdDate).toLocaleDateString() : "Unknown"} - **Updated**: ${updatedDate ? new Date(updatedDate).toLocaleDateString() : "Unknown"} ## Key Insights ${insights.map(i => `- ${i}`).join("\n")} ${showLoaderAnalysis && loaderAnalysis.length > 0 ? `## Loader Analysis ${loaderAnalysis.map(loader => ` ### ${loader.type} Loader - **ID**: ${loader.id} - **Source**: ${loader.source} - **Status**: ${loader.status} - **Uses Credentials**: ${loader.credential ? "Yes" : "No"} - **Has Configuration**: ${loader.hasConfig ? "Yes" : "No"} `).join("\n")}` : ""} ${showConfigAnalysis ? `## Configuration Analysis ### Vector Store Configuration - **Configured**: ${vectorStoreAnalysis.configured ? "Yes" : "No"} ${vectorStoreAnalysis.configured ? `- **Type**: ${vectorStoreAnalysis.type} - **Provider**: ${vectorStoreAnalysis.provider} - **Dimensions**: ${vectorStoreAnalysis.dimensions} - **Index Name**: ${vectorStoreAnalysis.indexName}` : ""} ### Embedding Configuration - **Configured**: ${embeddingAnalysis.configured ? "Yes" : "No"} ${embeddingAnalysis.configured ? `- **Model**: ${embeddingAnalysis.model} - **Provider**: ${embeddingAnalysis.provider} - **Dimensions**: ${embeddingAnalysis.dimensions} - **Max Tokens**: ${embeddingAnalysis.maxTokens}` : ""} ### Record Manager Configuration - **Configured**: ${!!parsedRecordManagerConfig ? "Yes" : "No"} ${parsedRecordManagerConfig ? `- **Type**: ${parsedRecordManagerConfig.type || "Unknown"}` : ""}` : ""} ${showUsageAnalysis && whereUsed ? `## Usage Analysis **Where Used**: ${whereUsed}` : ""} ## Recommendations ${recommendations.length > 0 ? recommendations.map(r => `- ${r}`).join("\n") : "- No specific recommendations - document store appears to be well-configured"} ## Summary 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."}`, }, }, ], }; }, }; /** * Document Store Management Prompt * * This prompt provides guidance for managing document stores, * including setup, configuration, and optimization suggestions. */ export const manageDocumentStorePrompt = { name: "manage_document_store", description: "Provides guidance for managing document stores including setup and configuration", schema: { action: z.enum(["setup", "optimize", "troubleshoot", "migrate"]).describe("The management action to perform"), documentStoreId: z.string().optional().describe("The ID of the document store (required for optimize/troubleshoot)"), context: z.string().optional().describe("Additional context about the situation"), }, handler: async ({ action, documentStoreId, context, }) => { let guidance = ""; let actionSteps = []; switch (action) { case "setup": guidance = "Setting up a new document store requires careful planning of your data sources and retrieval requirements."; actionSteps = [ "Define your document types and sources", "Choose appropriate loaders for your data sources", "Configure vector store settings based on your use case", "Select an embedding model that matches your content", "Set up record management for deduplication", "Test with a small dataset first", "Configure access controls and permissions", "Monitor performance and adjust as needed", ]; break; case "optimize": guidance = "Optimizing your document store can improve retrieval quality and performance."; actionSteps = [ "Analyze current retrieval performance metrics", "Review and tune embedding model parameters", "Optimize vector store configuration", "Clean up duplicate or outdated documents", "Adjust chunking strategies for better retrieval", "Fine-tune similarity search parameters", "Implement caching for frequently accessed documents", "Monitor and adjust based on usage patterns", ]; break; case "troubleshoot": guidance = "Troubleshooting document store issues requires systematic diagnosis."; actionSteps = [ "Check document store status and error logs", "Verify loader configurations and credentials", "Test vector store connectivity", "Validate embedding model availability", "Review recent changes to configuration", "Check for data source connectivity issues", "Verify permissions and access controls", "Test with known good documents", ]; break; case "migrate": guidance = "Migrating document stores requires careful planning to avoid data loss."; actionSteps = [ "Backup existing document store data", "Plan migration strategy and timeline", "Set up new document store configuration", "Test migration process with subset of data", "Migrate documents in batches", "Validate data integrity after migration", "Update chatflow configurations", "Monitor performance post-migration", ]; break; } // If a specific document store is provided, fetch its details let storeDetails = ""; if (documentStoreId) { try { const store = await documentStoreService.getDocumentStore(documentStoreId); storeDetails = ` ## Current Document Store Details - **Name**: ${store.name} - **Status**: ${store.status || "Unknown"} - **Description**: ${store.description || "No description"} `; } catch (error) { storeDetails = ` ## Document Store Status - **Error**: Could not fetch details for store ${documentStoreId} `; } } return { messages: [ { role: "assistant", content: { type: "text", text: `# Document Store Management: ${action.toUpperCase()} ## Overview ${guidance} ${context ? `## Context ${context}` : ""} ${storeDetails} ## Action Steps ${actionSteps.map((step, index) => `${index + 1}. ${step}`).join("\n")} ## Best Practices - Always backup before making significant changes - Test changes in a development environment first - Monitor performance metrics after changes - Document your configuration decisions - Keep track of data sources and their update frequencies - Regularly review and clean up unused documents ## Next Steps ${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." : ""}`, }, }, ], }; }, };