@vfarcic/dot-ai 0.12.0 → 0.14.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.
@@ -5,7 +5,7 @@ import { z } from 'zod';
5
5
  import { DotAI } from '../core/index';
6
6
  import { Logger } from '../core/error-handling';
7
7
  export declare const ANSWERQUESTION_TOOL_NAME = "answerQuestion";
8
- export declare const ANSWERQUESTION_TOOL_DESCRIPTION = "Process user answers and return remaining questions or completion status";
8
+ export declare const ANSWERQUESTION_TOOL_DESCRIPTION = "Process user answers and return remaining questions or completion status. For open stage, use \"open\" as the answer key.";
9
9
  export declare const ANSWERQUESTION_TOOL_INPUT_SCHEMA: {
10
10
  solutionId: z.ZodString;
11
11
  stage: z.ZodEnum<["required", "basic", "advanced", "open"]>;
@@ -1 +1 @@
1
- {"version":3,"file":"answer-question.d.ts","sourceRoot":"","sources":["../../src/tools/answer-question.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAMhD,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AACzD,eAAO,MAAM,+BAA+B,6EAA6E,CAAC;AAG1H,eAAO,MAAM,gCAAgC;;;;CAI5C,CAAC;AAodF;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,EAC7G,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC,CAmTxD"}
1
+ {"version":3,"file":"answer-question.d.ts","sourceRoot":"","sources":["../../src/tools/answer-question.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAMhD,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AACzD,eAAO,MAAM,+BAA+B,8HAA4H,CAAC;AAGzK,eAAO,MAAM,gCAAgC;;;;CAI5C,CAAC;AA6eF;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,EAC7G,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC,CAmTxD"}
@@ -46,12 +46,12 @@ const path = __importStar(require("path"));
46
46
  const session_utils_1 = require("../core/session-utils");
47
47
  // Tool metadata for direct MCP registration
48
48
  exports.ANSWERQUESTION_TOOL_NAME = 'answerQuestion';
49
- exports.ANSWERQUESTION_TOOL_DESCRIPTION = 'Process user answers and return remaining questions or completion status';
49
+ exports.ANSWERQUESTION_TOOL_DESCRIPTION = 'Process user answers and return remaining questions or completion status. For open stage, use "open" as the answer key.';
50
50
  // Zod schema for MCP registration
51
51
  exports.ANSWERQUESTION_TOOL_INPUT_SCHEMA = {
52
52
  solutionId: zod_1.z.string().regex(/^sol_[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{6}_[a-f0-9]+$/).describe('The solution ID to update (e.g., sol_2025-07-01T154349_1e1e242592ff)'),
53
53
  stage: zod_1.z.enum(['required', 'basic', 'advanced', 'open']).describe('The configuration stage being addressed'),
54
- answers: zod_1.z.record(zod_1.z.any()).describe('User answers to configuration questions for the specified stage')
54
+ answers: zod_1.z.record(zod_1.z.any()).describe('User answers to configuration questions for the specified stage. For required/basic/advanced stages, use questionId as key. For open stage, use "open" as key (e.g., {"open": "add persistent storage"})')
55
55
  };
56
56
  /**
57
57
  * Load solution file by ID
@@ -227,21 +227,50 @@ function getCurrentStage(solution) {
227
227
  /**
228
228
  * Validate stage transition is allowed
229
229
  */
230
- function validateStageTransition(currentStage, requestedStage) {
231
- const validTransitions = {
232
- 'required': ['basic', 'open'],
233
- 'basic': ['advanced', 'open'],
234
- 'advanced': ['open'],
235
- 'open': []
236
- };
230
+ function validateStageTransition(currentStage, requestedStage, solution) {
231
+ // Allow processing the same stage (for answering or skipping)
237
232
  if (currentStage === requestedStage) {
238
- return { valid: true }; // Same stage is always valid
233
+ return { valid: true };
234
+ }
235
+ // Determine the next stage based on what questions exist
236
+ let expectedNext = null;
237
+ if (currentStage === 'required') {
238
+ if (solution.questions.basic && solution.questions.basic.length > 0) {
239
+ expectedNext = 'basic';
240
+ }
241
+ else if (solution.questions.advanced && solution.questions.advanced.length > 0) {
242
+ expectedNext = 'advanced';
243
+ }
244
+ else {
245
+ expectedNext = 'open';
246
+ }
247
+ }
248
+ else if (currentStage === 'basic') {
249
+ if (solution.questions.advanced && solution.questions.advanced.length > 0) {
250
+ expectedNext = 'advanced';
251
+ }
252
+ else {
253
+ expectedNext = 'open';
254
+ }
255
+ }
256
+ else if (currentStage === 'advanced') {
257
+ expectedNext = 'open';
258
+ }
259
+ else {
260
+ expectedNext = null; // open stage is final
261
+ }
262
+ // If we're at the final stage, no transitions allowed
263
+ if (expectedNext === null) {
264
+ return {
265
+ valid: false,
266
+ error: `Cannot transition from '${currentStage}' stage. All stages completed.`
267
+ };
239
268
  }
240
- const allowedNext = validTransitions[currentStage] || [];
241
- if (!allowedNext.includes(requestedStage)) {
269
+ // Only allow transition to the immediate next stage
270
+ if (requestedStage !== expectedNext) {
242
271
  return {
243
272
  valid: false,
244
- error: `Cannot transition from '${currentStage}' to '${requestedStage}'. Valid options: ${allowedNext.join(', ')}`
273
+ error: `Cannot skip to '${requestedStage}' stage. Must process '${expectedNext}' stage next. Use empty answers to skip the current stage.`
245
274
  };
246
275
  }
247
276
  return { valid: true };
@@ -483,7 +512,7 @@ async function handleAnswerQuestionTool(args, dotAI, logger, requestId) {
483
512
  // Stage-based validation and workflow
484
513
  const stageState = getCurrentStage(solution);
485
514
  // Validate stage transition
486
- const transitionResult = validateStageTransition(stageState.currentStage, args.stage);
515
+ const transitionResult = validateStageTransition(stageState.currentStage, args.stage, solution);
487
516
  if (!transitionResult.valid) {
488
517
  const response = {
489
518
  status: 'stage_error',
@@ -512,7 +541,7 @@ async function handleAnswerQuestionTool(args, dotAI, logger, requestId) {
512
541
  if (args.stage === 'open') {
513
542
  // Only allow 'open' as the question ID for open stage
514
543
  if (questionId !== 'open') {
515
- validationErrors.push(`Unknown question ID '${questionId}' for stage '${args.stage}'. Open stage only accepts 'open' as question ID.`);
544
+ validationErrors.push(`Invalid question ID '${questionId}' for open stage. Use "open" as the key, e.g., {"open": "add persistent storage"}.`);
516
545
  continue;
517
546
  }
518
547
  // Skip further validation for open stage as it doesn't follow Question interface
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vfarcic/dot-ai",
3
- "version": "0.12.0",
3
+ "version": "0.14.0",
4
4
  "description": "Universal Kubernetes application deployment agent with CLI and MCP interfaces",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",