@vfarcic/dot-ai 0.138.0 → 0.140.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.
Files changed (39) hide show
  1. package/dist/core/capability-scan-workflow.d.ts.map +1 -1
  2. package/dist/core/capability-scan-workflow.js +3 -2
  3. package/dist/core/command-executor.d.ts +39 -0
  4. package/dist/core/command-executor.d.ts.map +1 -0
  5. package/dist/core/command-executor.js +111 -0
  6. package/dist/core/deploy-operation.d.ts.map +1 -1
  7. package/dist/core/deploy-operation.js +3 -5
  8. package/dist/core/pattern-vector-service.d.ts +1 -1
  9. package/dist/core/pattern-vector-service.d.ts.map +1 -1
  10. package/dist/core/pattern-vector-service.js +2 -2
  11. package/dist/core/schema.js +1 -1
  12. package/dist/interfaces/mcp.d.ts.map +1 -1
  13. package/dist/interfaces/mcp.js +9 -1
  14. package/dist/tools/answer-question.d.ts.map +1 -1
  15. package/dist/tools/answer-question.js +27 -142
  16. package/dist/tools/choose-solution.d.ts.map +1 -1
  17. package/dist/tools/choose-solution.js +22 -85
  18. package/dist/tools/deploy-manifests.js +1 -1
  19. package/dist/tools/generate-manifests.d.ts.map +1 -1
  20. package/dist/tools/generate-manifests.js +33 -71
  21. package/dist/tools/operate-analysis.d.ts +15 -0
  22. package/dist/tools/operate-analysis.d.ts.map +1 -0
  23. package/dist/tools/operate-analysis.js +238 -0
  24. package/dist/tools/operate-execution.d.ts +18 -0
  25. package/dist/tools/operate-execution.d.ts.map +1 -0
  26. package/dist/tools/operate-execution.js +122 -0
  27. package/dist/tools/operate.d.ts +133 -0
  28. package/dist/tools/operate.d.ts.map +1 -0
  29. package/dist/tools/operate.js +237 -0
  30. package/dist/tools/recommend.d.ts +23 -1
  31. package/dist/tools/recommend.d.ts.map +1 -1
  32. package/dist/tools/recommend.js +14 -116
  33. package/dist/tools/remediate.d.ts +7 -4
  34. package/dist/tools/remediate.d.ts.map +1 -1
  35. package/dist/tools/remediate.js +38 -81
  36. package/dist/tools/version.js +1 -1
  37. package/package.json +1 -1
  38. package/prompts/operate-system.md +322 -0
  39. package/prompts/operate-user.md +25 -0
@@ -2,39 +2,6 @@
2
2
  /**
3
3
  * Recommend Tool - AI-powered Kubernetes resource recommendations
4
4
  */
5
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- var desc = Object.getOwnPropertyDescriptor(m, k);
8
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
- desc = { enumerable: true, get: function() { return m[k]; } };
10
- }
11
- Object.defineProperty(o, k2, desc);
12
- }) : (function(o, m, k, k2) {
13
- if (k2 === undefined) k2 = k;
14
- o[k2] = m[k];
15
- }));
16
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
- Object.defineProperty(o, "default", { enumerable: true, value: v });
18
- }) : function(o, v) {
19
- o["default"] = v;
20
- });
21
- var __importStar = (this && this.__importStar) || (function () {
22
- var ownKeys = function(o) {
23
- ownKeys = Object.getOwnPropertyNames || function (o) {
24
- var ar = [];
25
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
- return ar;
27
- };
28
- return ownKeys(o);
29
- };
30
- return function (mod) {
31
- if (mod && mod.__esModule) return mod;
32
- var result = {};
33
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
- __setModuleDefault(result, mod);
35
- return result;
36
- };
37
- })();
38
5
  Object.defineProperty(exports, "__esModule", { value: true });
39
6
  exports.RECOMMEND_TOOL_INPUT_SCHEMA = exports.RECOMMEND_TOOL_DESCRIPTION = exports.RECOMMEND_TOOL_NAME = void 0;
40
7
  exports.handleRecommendTool = handleRecommendTool;
@@ -42,10 +9,7 @@ const zod_1 = require("zod");
42
9
  const error_handling_1 = require("../core/error-handling");
43
10
  const schema_1 = require("../core/schema");
44
11
  const cluster_utils_1 = require("../core/cluster-utils");
45
- const fs = __importStar(require("fs"));
46
- const path = __importStar(require("path"));
47
- const crypto = __importStar(require("crypto"));
48
- const session_utils_1 = require("../core/session-utils");
12
+ const generic_session_manager_1 = require("../core/generic-session-manager");
49
13
  const choose_solution_1 = require("./choose-solution");
50
14
  const answer_question_1 = require("./answer-question");
51
15
  const generate_manifests_1 = require("./generate-manifests");
@@ -54,7 +18,7 @@ const shared_prompt_loader_1 = require("../core/shared-prompt-loader");
54
18
  const platform_utils_1 = require("../core/platform-utils");
55
19
  // Tool metadata for direct MCP registration
56
20
  exports.RECOMMEND_TOOL_NAME = 'recommend';
57
- exports.RECOMMEND_TOOL_DESCRIPTION = 'Deploy, create, setup, install, or run applications, infrastructure, and services on Kubernetes with AI recommendations. Describe what you want to deploy. Does NOT handle policy creation, organizational patterns, or resource capabilities - use manageOrgData for those.';
21
+ exports.RECOMMEND_TOOL_DESCRIPTION = 'Deploy applications, infrastructure, and services using Kubernetes resources with AI recommendations. Supports cloud resources via operators like Crossplane, cluster management via CAPI, and traditional Kubernetes workloads. Describe what you want to deploy. Does NOT handle policy creation, organizational patterns, or resource capabilities - use manageOrgData for those.';
58
22
  // Zod schema for MCP registration (unified tool with stage routing)
59
23
  exports.RECOMMEND_TOOL_INPUT_SCHEMA = {
60
24
  stage: zod_1.z.string().optional().describe('Deployment workflow stage: "recommend" (default), "chooseSolution", "answerQuestion:required", "answerQuestion:basic", "answerQuestion:advanced", "answerQuestion:open", "generateManifests", "deployManifests". Defaults to "recommend" if omitted.'),
@@ -117,41 +81,7 @@ async function analyzeIntentForClarification(intent, aiProvider, logger, organiz
117
81
  };
118
82
  }
119
83
  }
120
- /**
121
- * Generate unique solution ID with timestamp and random component
122
- */
123
- function generateSolutionId() {
124
- const timestamp = new Date().toISOString().replace(/[:.]/g, '').split('T');
125
- const dateTime = timestamp[0] + 'T' + timestamp[1].substring(0, 6);
126
- const randomHex = crypto.randomBytes(6).toString('hex');
127
- return `sol_${dateTime}_${randomHex}`;
128
- }
129
- /**
130
- * Write solution data to file atomically (temp file + rename)
131
- */
132
- function writeSolutionFile(sessionDir, solutionId, solutionData) {
133
- const fileName = `${solutionId}.json`;
134
- const filePath = path.join(sessionDir, fileName);
135
- const tempPath = filePath + '.tmp';
136
- try {
137
- // Write to temporary file first
138
- fs.writeFileSync(tempPath, JSON.stringify(solutionData, null, 2));
139
- // Atomically rename to final location
140
- fs.renameSync(tempPath, filePath);
141
- }
142
- catch (error) {
143
- // Clean up temp file if it exists
144
- try {
145
- if (fs.existsSync(tempPath)) {
146
- fs.unlinkSync(tempPath);
147
- }
148
- }
149
- catch (cleanupError) {
150
- // Ignore cleanup errors
151
- }
152
- throw new Error(`Failed to write solution file ${fileName}: ${error}`);
153
- }
154
- }
84
+ // Session management now handled by GenericSessionManager
155
85
  /**
156
86
  * Direct MCP tool handler for recommend functionality (unified with stage routing)
157
87
  */
@@ -184,24 +114,9 @@ async function handleRecommendTool(args, dotAI, logger, requestId) {
184
114
  // Input validation is handled automatically by MCP SDK with Zod schema
185
115
  // args are already validated and typed when we reach this point
186
116
  // AI provider is already initialized and validated in dotAI.ai
187
- // Validate session directory configuration
188
- let sessionDir;
189
- try {
190
- sessionDir = (0, session_utils_1.getAndValidateSessionDirectory)(true); // requireWrite=true
191
- logger.debug('Session directory validated', { requestId, sessionDir });
192
- }
193
- catch (error) {
194
- throw error_handling_1.ErrorHandler.createError(error_handling_1.ErrorCategory.VALIDATION, error_handling_1.ErrorSeverity.HIGH, `Session directory validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, {
195
- operation: 'session_directory_validation',
196
- component: 'RecommendTool',
197
- requestId,
198
- suggestedActions: [
199
- 'Ensure session directory exists and is writable',
200
- 'Set --session-dir parameter or DOT_AI_SESSION_DIR environment variable',
201
- 'Check directory permissions'
202
- ]
203
- }, error instanceof Error ? error : new Error(String(error)));
204
- }
117
+ // Initialize session manager
118
+ const sessionManager = new generic_session_manager_1.GenericSessionManager('sol');
119
+ logger.debug('Session manager initialized', { requestId });
205
120
  logger.info('Starting resource recommendation process', {
206
121
  requestId,
207
122
  intent: args.intent,
@@ -284,10 +199,8 @@ async function handleRecommendTool(args, dotAI, logger, requestId) {
284
199
  // Limit to top 5 solutions (respecting quality thresholds from AI ranking)
285
200
  const topSolutions = solutions.slice(0, 5);
286
201
  for (const solution of topSolutions) {
287
- const solutionId = generateSolutionId();
288
- // Create complete solution file with all data
289
- const solutionFileData = {
290
- solutionId,
202
+ // Create complete solution data
203
+ const solutionData = {
291
204
  intent: args.intent,
292
205
  type: solution.type,
293
206
  score: solution.score,
@@ -304,24 +217,10 @@ async function handleRecommendTool(args, dotAI, logger, requestId) {
304
217
  answers: {}, // Empty initially - will be filled by answerQuestion tool
305
218
  timestamp
306
219
  };
307
- // Write solution to file
308
- try {
309
- writeSolutionFile(sessionDir, solutionId, solutionFileData);
310
- logger.debug('Solution file created', { requestId, solutionId, fileName: `${solutionId}.json` });
311
- }
312
- catch (error) {
313
- throw error_handling_1.ErrorHandler.createError(error_handling_1.ErrorCategory.STORAGE, error_handling_1.ErrorSeverity.HIGH, `Failed to store solution file: ${error instanceof Error ? error.message : 'Unknown error'}`, {
314
- operation: 'solution_file_creation',
315
- component: 'RecommendTool',
316
- requestId,
317
- input: { solutionId },
318
- suggestedActions: [
319
- 'Check session directory write permissions',
320
- 'Ensure sufficient disk space',
321
- 'Verify session directory is accessible'
322
- ]
323
- }, error instanceof Error ? error : new Error(String(error)));
324
- }
220
+ // Create solution session
221
+ const session = sessionManager.createSession(solutionData);
222
+ const solutionId = session.sessionId;
223
+ logger.debug('Solution session created', { requestId, solutionId, fileName: `${solutionId}.json` });
325
224
  // Add to response summary (decision-making data only)
326
225
  solutionSummaries.push({
327
226
  solutionId,
@@ -358,10 +257,9 @@ async function handleRecommendTool(args, dotAI, logger, requestId) {
358
257
  guidance: "🔴 CRITICAL: You MUST present these solutions to the user and ask them to choose. DO NOT automatically call chooseSolution() without user input. Stop here and wait for user selection. IMPORTANT: Show the list of Kubernetes resources (from the 'resources' field) that each solution will use - this helps users understand what gets deployed. ALSO: Include pattern usage information in your response - show which solutions used organizational patterns and which did not.",
359
258
  timestamp
360
259
  };
361
- logger.info('Solution files created and response prepared', {
260
+ logger.info('Solution sessions created and response prepared', {
362
261
  requestId,
363
- solutionCount: solutionSummaries.length,
364
- sessionDir
262
+ solutionCount: solutionSummaries.length
365
263
  });
366
264
  return {
367
265
  content: [{
@@ -24,17 +24,20 @@ export interface RemediateInput {
24
24
  executedCommands?: string[];
25
25
  interaction_id?: string;
26
26
  }
27
- export interface RemediateSession {
28
- sessionId: string;
27
+ export interface RemediateSessionData {
29
28
  issue: string;
30
29
  mode: 'manual' | 'automatic';
31
30
  interaction_id?: string;
32
31
  finalAnalysis?: RemediateOutput;
33
- created: Date;
34
- updated: Date;
35
32
  status: 'investigating' | 'analysis_complete' | 'failed' | 'executed_successfully' | 'executed_with_errors' | 'cancelled';
36
33
  executionResults?: ExecutionResult[];
37
34
  }
35
+ export type RemediateSession = {
36
+ sessionId: string;
37
+ createdAt: string;
38
+ updatedAt: string;
39
+ data: RemediateSessionData;
40
+ };
38
41
  export interface RemediationAction {
39
42
  description: string;
40
43
  command?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"remediate.d.ts","sourceRoot":"","sources":["../../src/tools/remediate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remediate.d.ts","sourceRoot":"","sources":["../../src/tools/remediate.ts"],"names":[],"mappings":"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"}
@@ -42,11 +42,10 @@ exports.handleRemediateTool = handleRemediateTool;
42
42
  const zod_1 = require("zod");
43
43
  const error_handling_1 = require("../core/error-handling");
44
44
  const ai_provider_factory_1 = require("../core/ai-provider-factory");
45
- const session_utils_1 = require("../core/session-utils");
45
+ const generic_session_manager_1 = require("../core/generic-session-manager");
46
46
  const kubectl_tools_1 = require("../core/kubectl-tools");
47
47
  const fs = __importStar(require("fs"));
48
48
  const path = __importStar(require("path"));
49
- const crypto = __importStar(require("crypto"));
50
49
  // PRD #143 Milestone 1: Hybrid approach - AI can use kubectl_api_resources tool OR continue with JSON dataRequests
51
50
  // Tool metadata for direct MCP registration
52
51
  exports.REMEDIATE_TOOL_NAME = 'remediate';
@@ -62,54 +61,16 @@ exports.REMEDIATE_TOOL_INPUT_SCHEMA = {
62
61
  executedCommands: zod_1.z.array(zod_1.z.string()).optional().describe('Commands that were executed to remediate the issue'),
63
62
  interaction_id: zod_1.z.string().optional().describe('INTERNAL ONLY - Do not populate. Used for evaluation dataset generation.')
64
63
  };
65
- /**
66
- * Generate unique session ID for investigation tracking
67
- */
68
- function generateSessionId() {
69
- const timestamp = new Date().toISOString().replace(/[:.]/g, '').slice(0, 15);
70
- const random = crypto.randomBytes(8).toString('hex');
71
- return `rem_${timestamp}_${random}`;
72
- }
73
- /**
74
- * Write session file to session directory
75
- */
76
- function writeSessionFile(sessionDir, sessionId, sessionData) {
77
- const sessionPath = path.join(sessionDir, `${sessionId}.json`);
78
- const sessionJson = JSON.stringify(sessionData, null, 2);
79
- fs.writeFileSync(sessionPath, sessionJson, 'utf8');
80
- }
81
- /**
82
- * Read session file from session directory
83
- */
84
- function readSessionFile(sessionDir, sessionId) {
85
- const sessionPath = path.join(sessionDir, `${sessionId}.json`);
86
- if (!fs.existsSync(sessionPath)) {
87
- throw new Error(`Session file not found: ${sessionId}`);
88
- }
89
- const sessionJson = fs.readFileSync(sessionPath, 'utf8');
90
- return JSON.parse(sessionJson);
91
- }
92
- /**
93
- * Update existing session file
94
- */
95
- function updateSessionFile(sessionDir, sessionId, updates) {
96
- const session = readSessionFile(sessionDir, sessionId);
97
- const updatedSession = {
98
- ...session,
99
- ...updates,
100
- updated: new Date()
101
- };
102
- writeSessionFile(sessionDir, sessionId, updatedSession);
103
- }
64
+ // Session management now handled by GenericSessionManager
104
65
  /**
105
66
  * AI-driven investigation - uses toolLoop for single-phase investigation and analysis
106
67
  */
107
- async function conductInvestigation(session, sessionDir, aiProvider, logger, requestId, isValidation = false, interactionId) {
68
+ async function conductInvestigation(session, sessionManager, aiProvider, logger, requestId, isValidation = false, interactionId) {
108
69
  const maxIterations = 30; // Increased for thorough models like Mistral
109
70
  logger.info('Starting AI investigation with toolLoop', {
110
71
  requestId,
111
72
  sessionId: session.sessionId,
112
- issue: session.issue
73
+ issue: session.data.issue
113
74
  });
114
75
  try {
115
76
  // Load investigation system prompt (static, cacheable)
@@ -125,13 +86,13 @@ async function conductInvestigation(session, sessionDir, aiProvider, logger, req
125
86
  const operationName = isValidation ? 'remediate-validation' : 'remediate-investigation';
126
87
  const result = await aiProvider.toolLoop({
127
88
  systemPrompt: systemPrompt,
128
- userMessage: `Investigate this Kubernetes issue: ${session.issue}`,
89
+ userMessage: `Investigate this Kubernetes issue: ${session.data.issue}`,
129
90
  tools: kubectl_tools_1.KUBECTL_INVESTIGATION_TOOLS,
130
91
  toolExecutor: kubectl_tools_1.executeKubectlTools,
131
92
  maxIterations: maxIterations,
132
93
  operation: operationName,
133
94
  evaluationContext: {
134
- user_intent: session.issue
95
+ user_intent: session.data.issue
135
96
  },
136
97
  interaction_id: interactionId
137
98
  });
@@ -160,7 +121,7 @@ async function conductInvestigation(session, sessionDir, aiProvider, logger, req
160
121
  remediation: finalAnalysis.remediation,
161
122
  validationIntent: finalAnalysis.validationIntent,
162
123
  executed: false,
163
- mode: session.mode
124
+ mode: session.data.mode
164
125
  };
165
126
  // Add guidance based on issue status
166
127
  if (finalAnalysis.issueStatus === 'resolved' || finalAnalysis.issueStatus === 'non_existent') {
@@ -184,12 +145,12 @@ async function conductInvestigation(session, sessionDir, aiProvider, logger, req
184
145
  "All actions are designed to be safe kubectl operations (no destructive commands)"
185
146
  ].join('. ');
186
147
  output.guidance = `🔴 CRITICAL: Present the kubectl commands to the user and ask them to choose execution method. DO NOT execute commands without user approval.\n\n${commandsSummary}\n\nRisk Assessment: ${riskSummary}`;
187
- output.agentInstructions = `1. Show the user the root cause analysis and confidence level\n2. Display the kubectl commands that will be executed\n3. Explain the risk assessment\n4. Present the two execution choices and wait for user selection\n5. When user selects option 1 or 2, call the remediate tool again with: executeChoice: [1 or 2], sessionId: "${session.sessionId}", mode: "${session.mode}"\n6. DO NOT automatically execute any commands until user makes their choice`;
148
+ output.agentInstructions = `1. Show the user the root cause analysis and confidence level\n2. Display the kubectl commands that will be executed\n3. Explain the risk assessment\n4. Present the two execution choices and wait for user selection\n5. When user selects option 1 or 2, call the remediate tool again with: executeChoice: [1 or 2], sessionId: "${session.sessionId}", mode: "${session.data.mode}"\n6. DO NOT automatically execute any commands until user makes their choice`;
188
149
  output.nextAction = 'remediate';
189
150
  output.message = `AI analysis identified the root cause with ${Math.round(finalAnalysis.confidence * 100)}% confidence. ${finalAnalysis.remediation.actions.length} remediation actions are recommended.`;
190
151
  }
191
152
  // Update session with final analysis
192
- updateSessionFile(sessionDir, session.sessionId, {
153
+ sessionManager.updateSession(session.sessionId, {
193
154
  finalAnalysis: output,
194
155
  status: 'analysis_complete'
195
156
  });
@@ -207,7 +168,7 @@ async function conductInvestigation(session, sessionDir, aiProvider, logger, req
207
168
  sessionId: session.sessionId
208
169
  });
209
170
  // Mark session as failed
210
- updateSessionFile(sessionDir, session.sessionId, { status: 'failed' });
171
+ sessionManager.updateSession(session.sessionId, { status: 'failed' });
211
172
  throw error_handling_1.ErrorHandler.createError(error_handling_1.ErrorCategory.AI_SERVICE, error_handling_1.ErrorSeverity.HIGH, `Investigation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, {
212
173
  operation: 'investigation_loop',
213
174
  component: 'RemediateTool',
@@ -307,26 +268,29 @@ function parseAIFinalAnalysis(aiResponse) {
307
268
  /**
308
269
  * Execute user choice from previous session
309
270
  */
310
- async function executeUserChoice(sessionDir, sessionId, choice, logger, requestId, currentInteractionId) {
271
+ async function executeUserChoice(sessionManager, sessionId, choice, logger, requestId, currentInteractionId) {
311
272
  try {
312
273
  // Load previous session
313
- const session = readSessionFile(sessionDir, sessionId);
314
- if (!session.finalAnalysis) {
274
+ const session = sessionManager.getSession(sessionId);
275
+ if (!session) {
276
+ throw new Error(`Session file not found: ${sessionId}`);
277
+ }
278
+ if (!session.data.finalAnalysis) {
315
279
  throw error_handling_1.ErrorHandler.createError(error_handling_1.ErrorCategory.VALIDATION, error_handling_1.ErrorSeverity.HIGH, 'Session does not have final analysis - cannot execute choice', { operation: 'choice_execution', component: 'RemediateTool', sessionId });
316
280
  }
317
281
  logger.info('Loaded session for choice execution', {
318
282
  requestId,
319
283
  sessionId,
320
284
  choice,
321
- actionCount: session.finalAnalysis.remediation.actions.length
285
+ actionCount: session.data.finalAnalysis.remediation.actions.length
322
286
  });
323
287
  // Handle different choices
324
288
  switch (choice) {
325
289
  case 1: // Execute automatically via MCP
326
- return await executeRemediationCommands(session, sessionDir, logger, requestId, currentInteractionId);
290
+ return await executeRemediationCommands(session, sessionManager, logger, requestId, currentInteractionId);
327
291
  case 2: { // Execute via agent
328
292
  // Use validation intent directly from final analysis
329
- const validationIntent = session.finalAnalysis.validationIntent || 'Check the status of the affected resources to verify the issue has been resolved';
293
+ const validationIntent = session.data.finalAnalysis.validationIntent || 'Check the status of the affected resources to verify the issue has been resolved';
330
294
  return {
331
295
  content: [
332
296
  {
@@ -335,7 +299,7 @@ async function executeUserChoice(sessionDir, sessionId, choice, logger, requestI
335
299
  status: 'success',
336
300
  sessionId: sessionId,
337
301
  message: 'Ready for agent execution',
338
- remediation: session.finalAnalysis.remediation,
302
+ remediation: session.data.finalAnalysis.remediation,
339
303
  instructions: {
340
304
  nextSteps: [
341
305
  'STEP 1: Execute the kubectl commands shown in the remediation section using your Bash tool',
@@ -365,9 +329,9 @@ async function executeUserChoice(sessionDir, sessionId, choice, logger, requestI
365
329
  /**
366
330
  * Execute remediation commands via kubectl
367
331
  */
368
- async function executeRemediationCommands(session, sessionDir, logger, requestId, currentInteractionId) {
332
+ async function executeRemediationCommands(session, sessionManager, logger, requestId, currentInteractionId) {
369
333
  const results = [];
370
- const finalAnalysis = session.finalAnalysis;
334
+ const finalAnalysis = session.data.finalAnalysis;
371
335
  let overallSuccess = true;
372
336
  logger.info('Starting remediation command execution', {
373
337
  requestId,
@@ -437,9 +401,8 @@ async function executeRemediationCommands(session, sessionDir, logger, requestId
437
401
  const executedCommands = results.map(r => r.action);
438
402
  const validationInput = {
439
403
  issue: validationIntent,
440
- sessionDir: sessionDir,
441
404
  executedCommands: executedCommands,
442
- interaction_id: currentInteractionId || session.interaction_id // Use current interaction_id for validation
405
+ interaction_id: currentInteractionId || session.data.interaction_id // Use current interaction_id for validation
443
406
  };
444
407
  // Recursive call to main function for validation
445
408
  const validationResponse = await handleRemediateTool(validationInput);
@@ -521,7 +484,7 @@ async function executeRemediationCommands(session, sessionDir, logger, requestId
521
484
  }
522
485
  }
523
486
  // Update session with execution results
524
- updateSessionFile(sessionDir, session.sessionId, {
487
+ sessionManager.updateSession(session.sessionId, {
525
488
  status: overallSuccess ? 'executed_successfully' : 'executed_with_errors',
526
489
  executionResults: results
527
490
  });
@@ -587,9 +550,9 @@ async function handleRemediateTool(args) {
587
550
  const requestId = `remediate_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
588
551
  const logger = new error_handling_1.ConsoleLogger('RemediateTool');
589
552
  try {
590
- // Validate and get session directory
591
- const sessionDir = (0, session_utils_1.getAndValidateSessionDirectory)(true);
592
- logger.debug('Session directory validated', { requestId, sessionDir });
553
+ // Initialize session manager
554
+ const sessionManager = new generic_session_manager_1.GenericSessionManager('rem');
555
+ logger.debug('Session manager initialized', { requestId });
593
556
  // Validate input
594
557
  const validatedInput = validateRemediateInput(args);
595
558
  // Handle choice execution if provided
@@ -599,34 +562,28 @@ async function handleRemediateTool(args) {
599
562
  choice: validatedInput.executeChoice,
600
563
  sessionId: validatedInput.sessionId
601
564
  });
602
- return await executeUserChoice(sessionDir, validatedInput.sessionId, validatedInput.executeChoice, logger, requestId, validatedInput.interaction_id);
565
+ return await executeUserChoice(sessionManager, validatedInput.sessionId, validatedInput.executeChoice, logger, requestId, validatedInput.interaction_id);
603
566
  }
604
567
  // Validate that we have an issue for new investigations
605
568
  if (!validatedInput.issue) {
606
569
  throw error_handling_1.ErrorHandler.createError(error_handling_1.ErrorCategory.VALIDATION, error_handling_1.ErrorSeverity.HIGH, 'Issue description is required for new investigations', { operation: 'input_validation', component: 'RemediateTool' });
607
570
  }
608
- // Generate session ID and create initial session
609
- const sessionId = generateSessionId();
610
- const session = {
611
- sessionId,
571
+ // Create initial session using session manager
572
+ const session = sessionManager.createSession({
612
573
  issue: validatedInput.issue,
613
574
  mode: validatedInput.mode || 'manual',
614
575
  interaction_id: validatedInput.interaction_id,
615
- created: new Date(),
616
- updated: new Date(),
617
576
  status: 'investigating'
618
- };
619
- // Write initial session file
620
- writeSessionFile(sessionDir, sessionId, session);
621
- logger.info('Investigation session created', { requestId, sessionId });
577
+ });
578
+ logger.info('Investigation session created', { requestId, sessionId: session.sessionId });
622
579
  // Initialize AI provider (will validate API key automatically)
623
580
  const aiProvider = (0, ai_provider_factory_1.createAIProvider)();
624
581
  // Conduct AI-driven investigation (detect if this is post-execution validation)
625
582
  const isValidation = validatedInput.executedCommands && validatedInput.executedCommands.length > 0;
626
- const finalAnalysis = await conductInvestigation(session, sessionDir, aiProvider, logger, requestId, isValidation, validatedInput.interaction_id);
583
+ const finalAnalysis = await conductInvestigation(session, sessionManager, aiProvider, logger, requestId, isValidation, validatedInput.interaction_id);
627
584
  logger.info('Remediation analysis completed', {
628
585
  requestId,
629
- sessionId,
586
+ sessionId: session.sessionId,
630
587
  rootCause: finalAnalysis.analysis.rootCause,
631
588
  actionCount: finalAnalysis.remediation.actions.length,
632
589
  riskLevel: finalAnalysis.remediation.risk
@@ -635,7 +592,7 @@ async function handleRemediateTool(args) {
635
592
  if (finalAnalysis.status === 'success') {
636
593
  logger.info('Issue resolved/non-existent - returning success without execution decision', {
637
594
  requestId,
638
- sessionId,
595
+ sessionId: session.sessionId,
639
596
  status: finalAnalysis.status
640
597
  });
641
598
  // Return MCP-compliant response for resolved issues
@@ -652,7 +609,7 @@ async function handleRemediateTool(args) {
652
609
  const executionDecision = makeExecutionDecision(validatedInput.mode || 'manual', finalAnalysis.analysis.confidence, finalAnalysis.remediation.risk, validatedInput.confidenceThreshold, validatedInput.maxRiskLevel);
653
610
  logger.info('Execution decision made', {
654
611
  requestId,
655
- sessionId,
612
+ sessionId: session.sessionId,
656
613
  mode: validatedInput.mode,
657
614
  shouldExecute: executionDecision.shouldExecute,
658
615
  reason: executionDecision.reason,
@@ -685,9 +642,9 @@ async function handleRemediateTool(args) {
685
642
  // Execute remediation actions if automatic mode approves it
686
643
  if (executionDecision.shouldExecute) {
687
644
  // Update session object with final analysis for execution
688
- session.finalAnalysis = finalAnalysis;
645
+ session.data.finalAnalysis = finalAnalysis;
689
646
  // Execute commands and return the complete result (includes post-execution validation)
690
- return await executeRemediationCommands(session, sessionDir, logger, requestId, validatedInput.interaction_id);
647
+ return await executeRemediationCommands(session, sessionManager, logger, requestId, validatedInput.interaction_id);
691
648
  }
692
649
  // Return MCP-compliant response
693
650
  return {
@@ -85,7 +85,7 @@ async function getVectorDBStatus() {
85
85
  // Test patterns collection
86
86
  const patternsStatus = await testCollectionStatus('patterns', () => {
87
87
  const patternVectorDB = new index_1.VectorDBService({ collectionName: 'patterns' });
88
- const patternService = new index_1.PatternVectorService(patternVectorDB, embeddingService);
88
+ const patternService = new index_1.PatternVectorService('patterns', patternVectorDB, embeddingService);
89
89
  return patternService.getPatternsCount();
90
90
  });
91
91
  // Test policies collection
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vfarcic/dot-ai",
3
- "version": "0.138.0",
3
+ "version": "0.140.0",
4
4
  "description": "AI-powered development productivity platform that enhances software development workflows through intelligent automation and AI-driven assistance",
5
5
  "mcpName": "io.github.vfarcic/dot-ai",
6
6
  "main": "dist/index.js",