UNPKG

@vfarcic/dot-ai

Version:

AI-powered development productivity platform that enhances software development workflows through intelligent automation and AI-driven assistance

147 lines (146 loc) 7.28 kB
"use strict"; /** * Choose Solution Tool - Select a solution and return its questions */ Object.defineProperty(exports, "__esModule", { value: true }); exports.CHOOSESOLUTION_TOOL_INPUT_SCHEMA = exports.CHOOSESOLUTION_TOOL_DESCRIPTION = exports.CHOOSESOLUTION_TOOL_NAME = void 0; exports.handleChooseSolutionTool = handleChooseSolutionTool; const zod_1 = require("zod"); const error_handling_1 = require("../core/error-handling"); const generic_session_manager_1 = require("../core/generic-session-manager"); // Tool metadata for direct MCP registration exports.CHOOSESOLUTION_TOOL_NAME = 'chooseSolution'; exports.CHOOSESOLUTION_TOOL_DESCRIPTION = 'Select a solution by ID and return its questions for configuration'; // Zod schema for MCP registration exports.CHOOSESOLUTION_TOOL_INPUT_SCHEMA = { solutionId: zod_1.z.string().regex(/^sol-\d+-[a-f0-9]{8}$/).describe('The solution ID to choose (e.g., sol-1762983784617-9ddae2b8)') }; // Session management now handled by GenericSessionManager /** * Direct MCP tool handler for chooseSolution functionality */ async function handleChooseSolutionTool(args, dotAI, logger, requestId) { return await error_handling_1.ErrorHandler.withErrorHandling(async () => { logger.debug('Handling chooseSolution request', { requestId, solutionId: args?.solutionId }); // Input validation is handled automatically by MCP SDK with Zod schema // args are already validated and typed when we reach this point // Initialize session manager const sessionManager = new generic_session_manager_1.GenericSessionManager('sol'); logger.debug('Session manager initialized', { requestId }); // Load solution session const session = sessionManager.getSession(args.solutionId); if (!session) { throw error_handling_1.ErrorHandler.createError(error_handling_1.ErrorCategory.VALIDATION, error_handling_1.ErrorSeverity.HIGH, `Solution not found: ${args.solutionId}`, { operation: 'solution_loading', component: 'ChooseSolutionTool', requestId, input: { solutionId: args.solutionId }, suggestedActions: [ 'Verify the solution ID is correct', 'Ensure the solution was created by the recommend tool', 'Check that the session has not expired' ] }); } const solution = session.data; // For Helm solutions, generate questions if not already present if (solution.type === 'helm' && solution.chart) { const hasQuestions = (solution.questions?.required?.length ?? 0) > 0 || (solution.questions?.basic?.length ?? 0) > 0 || (solution.questions?.advanced?.length ?? 0) > 0; if (!hasQuestions) { logger.info('Generating questions for Helm solution', { requestId, solutionId: args.solutionId, chart: solution.chart.chartName }); const questions = await dotAI.schema.generateQuestionsForHelmChart(solution.intent, solution.chart, solution.description, `choose_solution_${args.solutionId}`); solution.questions = questions; // Update the session with generated questions sessionManager.updateSession(args.solutionId, solution); logger.info('Helm questions generated and saved', { requestId, solutionId: args.solutionId, questionCounts: { required: questions.required?.length || 0, basic: questions.basic?.length || 0, advanced: questions.advanced?.length || 0 } }); } } logger.debug('Solution file loaded successfully', { solutionId: args.solutionId, type: solution.type, hasQuestions: !!solution.questions, questionCategories: { required: solution.questions?.required?.length || 0, basic: solution.questions?.basic?.length || 0, advanced: solution.questions?.advanced?.length || 0, hasOpen: !!solution.questions?.open } }); // Determine next stage based on what questions exist const hasBasic = solution.questions?.basic && solution.questions.basic.length > 0; const hasAdvanced = solution.questions?.advanced && solution.questions.advanced.length > 0; const hasOpen = !!solution.questions?.open; const isHelm = solution.type === 'helm'; let nextStage = null; if (hasBasic) { nextStage = 'basic'; } else if (hasAdvanced) { nextStage = 'advanced'; } else if (!isHelm && hasOpen) { nextStage = 'open'; } // Update session with workflow state for UI page refresh support sessionManager.updateSession(args.solutionId, { stage: 'questions', currentQuestionStage: 'required', nextQuestionStage: nextStage }); // Prepare response with solution details and questions const response = { status: 'stage_questions', solutionId: args.solutionId, currentStage: 'required', questions: solution.questions.required || [], nextStage: nextStage || 'complete', message: 'Please provide the required configuration for your application.', nextAction: 'Call recommend tool with stage: answerQuestion:required', guidance: 'Present ALL required questions to the user. All must be answered before proceeding.', agentInstructions: `MANDATORY: Present ALL questions from this stage to the user - do not skip any. For each question, show the default value if one exists and ask user to confirm or change it. Wait for explicit user response on EVERY question before calling answerQuestion. NEVER auto-fill answers without user confirmation, even if you can deduce values. NEVER assume what the user wants - always ask.`, timestamp: new Date().toISOString() }; logger.info('Choose solution completed successfully', { solutionId: args.solutionId, questionCategories: { required: solution.questions.required?.length || 0, basic: solution.questions.basic?.length || 0, advanced: solution.questions.advanced?.length || 0, hasOpen: !!solution.questions.open }, totalQuestions: (solution.questions.required?.length || 0) + (solution.questions.basic?.length || 0) + (solution.questions.advanced?.length || 0) + (solution.questions.open ? 1 : 0) }); return { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] }; }, { operation: 'choose_solution', component: 'ChooseSolutionTool', requestId, input: args }); }