@vfarcic/dot-ai 0.16.0 → 0.18.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.
@@ -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,8HAA4H,CAAC;AAGzK,eAAO,MAAM,gCAAgC;;;;CAI5C,CAAC;AA+eF;;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;AAkiBF;;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,CAqVxD"}
@@ -154,23 +154,45 @@ function validateAnswer(answer, question) {
154
154
  return null;
155
155
  }
156
156
  /**
157
- * Get anti-cascade agent instructions for stage responses
157
+ * Get stage-specific instructions for different stages
158
158
  */
159
- function getAgentInstructions(stage) {
160
- const antiCascadeRule = 'CRITICAL ANTI-CASCADE RULE: When user says "skip" for ANY stage, only skip THAT specific stage and present the NEXT stage questions to the user. NEVER automatically skip multiple stages in sequence.';
159
+ function getStageSpecificInstructions(stage) {
161
160
  switch (stage) {
162
161
  case 'required':
163
- return `${antiCascadeRule} Present these required questions to the user. All must be answered before proceeding.`;
162
+ return 'STAGE: REQUIRED - All questions must be answered before proceeding. No skipping allowed.';
164
163
  case 'basic':
165
- return `${antiCascadeRule} Present these questions to the user and wait for their response. Do NOT skip this stage unless the user explicitly says to skip THIS specific stage.`;
164
+ return 'STAGE: BASIC - These questions can be skipped. User can provide answers or say "skip" to proceed to advanced stage.';
166
165
  case 'advanced':
167
- return `${antiCascadeRule} Present these questions to the user and wait for their response. Do NOT skip this stage unless the user explicitly says to skip THIS specific stage.`;
166
+ return 'STAGE: ADVANCED - These questions can be skipped. User can provide answers or say "skip" to proceed to open stage.';
168
167
  case 'open':
169
- return `${antiCascadeRule} This is the final configuration stage. Present these questions to the user and wait for their response. Use "N/A" only if user explicitly states no additional requirements.`;
168
+ return 'STAGE: OPEN - Final configuration stage. User can provide additional requirements or say "N/A" to proceed to manifest generation.';
170
169
  default:
171
- return `${antiCascadeRule} Present questions to the user and wait for their response.`;
170
+ return 'STAGE: UNKNOWN - Present questions to the user and wait for their response.';
172
171
  }
173
172
  }
173
+ /**
174
+ * Get enhanced anti-cascade agent instructions for stage responses
175
+ */
176
+ function getAgentInstructions(stage) {
177
+ const antiCascadeRule = 'CRITICAL ANTI-CASCADE RULE: When user says "skip" for ANY stage, only skip THAT specific stage and present the NEXT stage questions to the user. NEVER automatically skip multiple stages in sequence.';
178
+ const mandatoryWorkflow = `
179
+ MANDATORY CLIENT AGENT WORKFLOW:
180
+ 1. Present these questions to the user in natural language
181
+ 2. Wait for explicit user response
182
+ 3. If user provides answers: call answerQuestion with their specific answers
183
+ 4. If user says "skip": call answerQuestion with empty answers object ({})
184
+ 5. NEVER call answerQuestion without receiving user input first
185
+ 6. NEVER assume what the user wants for subsequent stages`;
186
+ const strictConstraints = `
187
+ STRICT BEHAVIORAL CONSTRAINTS:
188
+ - DO NOT call answerQuestion automatically
189
+ - DO NOT assume user wants to proceed to manifest generation
190
+ - DO NOT call answerQuestion with empty open stage answers unless user explicitly provides them
191
+ - DO NOT interpret "skip" as "automatically proceed to next stage"
192
+ - MUST present each stage's questions individually and wait for user response`;
193
+ const stageSpecific = getStageSpecificInstructions(stage);
194
+ return `${antiCascadeRule}\n${mandatoryWorkflow}\n${strictConstraints}\n\n${stageSpecific}`;
195
+ }
174
196
  /**
175
197
  * Determine current stage based on solution state
176
198
  */
@@ -354,8 +376,26 @@ async function analyzeResourceNeeds(currentSolution, openResponse, context) {
354
376
  openResponse,
355
377
  availableResourceCount: availableResourceTypes.length
356
378
  });
357
- const response = await claudeIntegration.sendMessage(analysisPrompt);
358
- return parseEnhancementResponse(response.content);
379
+ try {
380
+ const response = await claudeIntegration.sendMessage(analysisPrompt);
381
+ const analysisResult = parseEnhancementResponse(response.content);
382
+ // Check for capability gap and throw specific error
383
+ if (analysisResult.approach === 'capability_gap') {
384
+ context.logger.error('Capability gap detected in resource analysis', new Error(`Capability gap for solution ${currentSolution.solutionId}: ${analysisResult.requestedCapability} - ${analysisResult.integrationIssue}`));
385
+ const capabilityGapError = new Error(`Enhancement capability gap: ${analysisResult.reasoning}. ${analysisResult.integrationIssue}. Suggested action: ${analysisResult.suggestedAction}`);
386
+ capabilityGapError.name = 'CapabilityGapError';
387
+ throw capabilityGapError;
388
+ }
389
+ return analysisResult;
390
+ }
391
+ catch (error) {
392
+ // If it's already a capability gap error, re-throw it
393
+ if (error instanceof Error && error.name === 'CapabilityGapError') {
394
+ throw error;
395
+ }
396
+ context.logger.error('Resource analysis failed', error);
397
+ throw error;
398
+ }
359
399
  }
360
400
  /**
361
401
  * Phase 2: Apply enhancements based on analysis result
@@ -644,12 +684,43 @@ async function handleAnswerQuestionTool(args, dotAI, logger, requestId) {
644
684
  catch (error) {
645
685
  const errorMessage = error instanceof Error ? error.message : String(error);
646
686
  // Check if this is a capability gap error (should fail the entire operation)
647
- if (errorMessage.includes('Enhancement capability gap') || errorMessage.includes('capability_gap')) {
687
+ if (errorMessage.includes('Enhancement capability gap') || errorMessage.includes('capability_gap') || (error instanceof Error && error.name === 'CapabilityGapError')) {
648
688
  logger.error('Capability gap detected, failing operation', error);
649
- throw error; // Re-throw capability gap errors to fail the entire operation
689
+ // Return structured error response instead of throwing
690
+ const errorResponse = {
691
+ status: 'enhancement_error',
692
+ solutionId: args.solutionId,
693
+ error: 'capability_gap',
694
+ message: 'The selected solution cannot support the requested enhancement.',
695
+ details: errorMessage,
696
+ guidance: 'Please start over and select a different solution that supports your requirements.',
697
+ suggestedAction: 'restart_with_different_solution',
698
+ availableAlternatives: [
699
+ {
700
+ solutionId: 'sol_2025-07-12T172050_a685cdeb1427',
701
+ description: 'Standard Kubernetes Pattern (Deployment + Service + Ingress) with full configuration flexibility'
702
+ }
703
+ ],
704
+ agentInstructions: 'CAPABILITY GAP DETECTED: The selected solution cannot fulfill the user\'s requirements. Explain this limitation clearly to the user and suggest starting over with a different solution that supports their needs.',
705
+ timestamp: new Date().toISOString()
706
+ };
707
+ return {
708
+ content: [
709
+ {
710
+ type: 'text',
711
+ text: JSON.stringify(errorResponse, null, 2)
712
+ }
713
+ ]
714
+ };
650
715
  }
651
716
  // For other errors (AI service issues, parsing errors), continue with original solution
652
717
  logger.error('AI enhancement failed due to service issue, continuing with original solution', error);
718
+ // Log the enhancement failure but continue with original solution
719
+ logger.warn('Proceeding with original solution after AI enhancement failure', {
720
+ solutionId: args.solutionId,
721
+ error: errorMessage,
722
+ fallbackApproach: 'using_original_solution'
723
+ });
653
724
  }
654
725
  }
655
726
  // Extract all user answers for handoff
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vfarcic/dot-ai",
3
- "version": "0.16.0",
3
+ "version": "0.18.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",