@vfarcic/dot-ai 0.79.0 → 0.81.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.
- package/dist/core/capability-operations.d.ts +42 -0
- package/dist/core/capability-operations.d.ts.map +1 -0
- package/dist/core/capability-operations.js +685 -0
- package/dist/core/capability-scan-workflow.d.ts +41 -0
- package/dist/core/capability-scan-workflow.d.ts.map +1 -0
- package/dist/core/capability-scan-workflow.js +753 -0
- package/dist/core/pattern-operations.d.ts +15 -1
- package/dist/core/pattern-operations.d.ts.map +1 -1
- package/dist/core/pattern-operations.js +375 -1
- package/dist/core/policy-operations.d.ts +48 -0
- package/dist/core/policy-operations.d.ts.map +1 -0
- package/dist/core/policy-operations.js +549 -0
- package/dist/core/schema.js +1 -1
- package/dist/core/unified-creation-session.js +1 -1
- package/dist/tools/organizational-data.d.ts.map +1 -1
- package/dist/tools/organizational-data.js +82 -2279
- package/dist/tools/recommend.d.ts +1 -1
- package/dist/tools/recommend.d.ts.map +1 -1
- package/dist/tools/recommend.js +1 -1
- package/package.json +1 -1
- package/prompts/kyverno-generation.md +108 -12
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Core Policy Operations
|
|
4
|
+
*
|
|
5
|
+
* Handles policy intent management operations including CRUD operations
|
|
6
|
+
* and Kyverno cluster policy cleanup
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.getPolicyService = getPolicyService;
|
|
10
|
+
exports.findKyvernoPoliciesByPolicyId = findKyvernoPoliciesByPolicyId;
|
|
11
|
+
exports.findAllKyvernoPoliciesForPolicyIntents = findAllKyvernoPoliciesForPolicyIntents;
|
|
12
|
+
exports.deleteKyvernoPoliciesByPolicyId = deleteKyvernoPoliciesByPolicyId;
|
|
13
|
+
exports.deleteAllKyvernoPoliciesForPolicyIntents = deleteAllKyvernoPoliciesForPolicyIntents;
|
|
14
|
+
exports.handlePolicyDelete = handlePolicyDelete;
|
|
15
|
+
exports.handlePolicyDeleteAll = handlePolicyDeleteAll;
|
|
16
|
+
exports.handlePolicyOperation = handlePolicyOperation;
|
|
17
|
+
const error_handling_1 = require("./error-handling");
|
|
18
|
+
const policy_vector_service_1 = require("./policy-vector-service");
|
|
19
|
+
const vector_db_service_1 = require("./vector-db-service");
|
|
20
|
+
const unified_creation_session_1 = require("./unified-creation-session");
|
|
21
|
+
const kubernetes_utils_1 = require("./kubernetes-utils");
|
|
22
|
+
// Note: validateVectorDBConnection and validateEmbeddingService are shared utilities
|
|
23
|
+
// that remain in the main organizational-data.ts file as they're used by multiple domains
|
|
24
|
+
/**
|
|
25
|
+
* Get initialized policy service
|
|
26
|
+
*/
|
|
27
|
+
async function getPolicyService() {
|
|
28
|
+
const policyService = new policy_vector_service_1.PolicyVectorService();
|
|
29
|
+
// Always ensure proper collection initialization
|
|
30
|
+
try {
|
|
31
|
+
await policyService.initialize();
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
// If initialization fails, try to provide helpful error context
|
|
35
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
36
|
+
throw new Error(`Vector DB collection initialization failed: ${errorMessage}. This may be due to dimension mismatch or collection configuration issues.`);
|
|
37
|
+
}
|
|
38
|
+
return policyService;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Find Kyverno policies by policy intent ID using label selector
|
|
42
|
+
*/
|
|
43
|
+
async function findKyvernoPoliciesByPolicyId(policyId, logger, requestId) {
|
|
44
|
+
try {
|
|
45
|
+
logger.info('Searching for Kyverno policies by policy ID', {
|
|
46
|
+
requestId,
|
|
47
|
+
policyId
|
|
48
|
+
});
|
|
49
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(['get', 'clusterpolicy', '-l', `policy-intent/id=${policyId}`, '-o', 'json'], {
|
|
50
|
+
kubeconfig: process.env.KUBECONFIG,
|
|
51
|
+
timeout: 15000
|
|
52
|
+
});
|
|
53
|
+
const parsedOutput = JSON.parse(output || '{"items": []}');
|
|
54
|
+
const policies = parsedOutput.items || [];
|
|
55
|
+
logger.info('Found Kyverno policies for policy intent', {
|
|
56
|
+
requestId,
|
|
57
|
+
policyId,
|
|
58
|
+
policyCount: policies.length,
|
|
59
|
+
policyNames: policies.map((p) => p.metadata?.name)
|
|
60
|
+
});
|
|
61
|
+
return policies.map((p) => ({
|
|
62
|
+
name: p.metadata?.name,
|
|
63
|
+
labels: p.metadata?.labels,
|
|
64
|
+
creationTimestamp: p.metadata?.creationTimestamp
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
logger.warn('Failed to query Kyverno policies (cluster may not have Kyverno or no policies found)', {
|
|
69
|
+
requestId,
|
|
70
|
+
policyId,
|
|
71
|
+
error: error instanceof Error ? error.message : String(error)
|
|
72
|
+
});
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Find all Kyverno policies that have policy-intent/id labels
|
|
78
|
+
*/
|
|
79
|
+
async function findAllKyvernoPoliciesForPolicyIntents(logger, requestId) {
|
|
80
|
+
try {
|
|
81
|
+
logger.info('Searching for all Kyverno policies with policy-intent labels', {
|
|
82
|
+
requestId
|
|
83
|
+
});
|
|
84
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(['get', 'clusterpolicy', '-l', 'policy-intent/id', '-o', 'json'], {
|
|
85
|
+
kubeconfig: process.env.KUBECONFIG,
|
|
86
|
+
timeout: 15000
|
|
87
|
+
});
|
|
88
|
+
const parsedOutput = JSON.parse(output || '{"items": []}');
|
|
89
|
+
const policies = parsedOutput.items || [];
|
|
90
|
+
logger.info('Found all Kyverno policies for policy intents', {
|
|
91
|
+
requestId,
|
|
92
|
+
policyCount: policies.length,
|
|
93
|
+
policyNames: policies.map((p) => p.metadata?.name)
|
|
94
|
+
});
|
|
95
|
+
return policies.map((p) => ({
|
|
96
|
+
name: p.metadata?.name,
|
|
97
|
+
policyId: p.metadata?.labels?.['policy-intent/id'],
|
|
98
|
+
labels: p.metadata?.labels,
|
|
99
|
+
creationTimestamp: p.metadata?.creationTimestamp
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
logger.warn('Failed to query all Kyverno policies (cluster may not have Kyverno or no policies found)', {
|
|
104
|
+
requestId,
|
|
105
|
+
error: error instanceof Error ? error.message : String(error)
|
|
106
|
+
});
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Delete Kyverno policies by policy intent ID using label selector
|
|
112
|
+
*/
|
|
113
|
+
async function deleteKyvernoPoliciesByPolicyId(policyId, logger, requestId) {
|
|
114
|
+
try {
|
|
115
|
+
logger.info('Deleting Kyverno policies by policy ID', {
|
|
116
|
+
requestId,
|
|
117
|
+
policyId
|
|
118
|
+
});
|
|
119
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(['delete', 'clusterpolicy', '-l', `policy-intent/id=${policyId}`], {
|
|
120
|
+
kubeconfig: process.env.KUBECONFIG,
|
|
121
|
+
timeout: 30000
|
|
122
|
+
});
|
|
123
|
+
logger.info('Kyverno policies deleted successfully', {
|
|
124
|
+
requestId,
|
|
125
|
+
policyId,
|
|
126
|
+
output
|
|
127
|
+
});
|
|
128
|
+
return {
|
|
129
|
+
successful: [{ policyId, deletedAt: new Date().toISOString() }],
|
|
130
|
+
failed: [],
|
|
131
|
+
total: 1
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
logger.error('Failed to delete Kyverno policies', error, {
|
|
136
|
+
requestId,
|
|
137
|
+
policyId,
|
|
138
|
+
error: error instanceof Error ? error.message : String(error)
|
|
139
|
+
});
|
|
140
|
+
return {
|
|
141
|
+
successful: [],
|
|
142
|
+
failed: [{ policyId, error: error instanceof Error ? error.message : String(error) }],
|
|
143
|
+
total: 1
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Delete all Kyverno policies that have policy-intent/id labels
|
|
149
|
+
*/
|
|
150
|
+
async function deleteAllKyvernoPoliciesForPolicyIntents(logger, requestId) {
|
|
151
|
+
try {
|
|
152
|
+
logger.info('Deleting all Kyverno policies with policy-intent labels', {
|
|
153
|
+
requestId
|
|
154
|
+
});
|
|
155
|
+
const output = await (0, kubernetes_utils_1.executeKubectl)(['delete', 'clusterpolicy', '-l', 'policy-intent/id'], {
|
|
156
|
+
kubeconfig: process.env.KUBECONFIG,
|
|
157
|
+
timeout: 30000
|
|
158
|
+
});
|
|
159
|
+
logger.info('All Kyverno policies deleted successfully', {
|
|
160
|
+
requestId,
|
|
161
|
+
output
|
|
162
|
+
});
|
|
163
|
+
return {
|
|
164
|
+
successful: [{ deletedAt: new Date().toISOString() }],
|
|
165
|
+
failed: [],
|
|
166
|
+
total: 1
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
logger.error('Failed to delete all Kyverno policies', error, {
|
|
171
|
+
requestId,
|
|
172
|
+
error: error instanceof Error ? error.message : String(error)
|
|
173
|
+
});
|
|
174
|
+
return {
|
|
175
|
+
successful: [],
|
|
176
|
+
failed: [{ error: error instanceof Error ? error.message : String(error) }],
|
|
177
|
+
total: 1
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Handle individual policy delete with Kyverno cleanup
|
|
183
|
+
*/
|
|
184
|
+
async function handlePolicyDelete(policyId, policyService, args, logger, requestId) {
|
|
185
|
+
try {
|
|
186
|
+
// Check if policy intent exists
|
|
187
|
+
const existingPolicyIntent = await policyService.getPolicyIntent(policyId);
|
|
188
|
+
if (!existingPolicyIntent) {
|
|
189
|
+
return {
|
|
190
|
+
success: false,
|
|
191
|
+
operation: 'delete',
|
|
192
|
+
dataType: 'policy',
|
|
193
|
+
message: `Policy intent not found: ${policyId}`,
|
|
194
|
+
error: 'Policy intent not found'
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
// Check if there are deployed Kyverno policies with this policy ID
|
|
198
|
+
const kyvernoPolicies = await findKyvernoPoliciesByPolicyId(policyId, logger, requestId);
|
|
199
|
+
if (kyvernoPolicies.length > 0 && !args.response) {
|
|
200
|
+
// Show confirmation prompt for Kyverno cleanup
|
|
201
|
+
return {
|
|
202
|
+
success: true,
|
|
203
|
+
operation: 'delete',
|
|
204
|
+
dataType: 'policy',
|
|
205
|
+
requiresConfirmation: true,
|
|
206
|
+
message: 'Policy intent has deployed Kyverno policies that need cleanup decision',
|
|
207
|
+
confirmation: {
|
|
208
|
+
question: `Policy intent "${existingPolicyIntent.description.substring(0, 60)}..." has ${kyvernoPolicies.length} deployed Kyverno policies in your cluster: ${kyvernoPolicies.map(p => p.name).join(', ')}\n\n**Choose what to do:**\n\n1. **Delete everything** - Remove policy intent AND delete Kyverno policies from cluster\n2. **Keep Kyverno policies** - Remove policy intent only, preserve cluster policies\n\n⚠️ **Warning**: Option 1 will remove active policy enforcement from your cluster.\n\n**What would you like to do?**`,
|
|
209
|
+
options: ['Delete everything', 'Keep Kyverno policies']
|
|
210
|
+
},
|
|
211
|
+
policyIntent: existingPolicyIntent,
|
|
212
|
+
kyvernoPolicies: kyvernoPolicies
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
// Process user's response or proceed with direct deletion
|
|
216
|
+
let kyvernoCleanupResults = null;
|
|
217
|
+
if (kyvernoPolicies.length > 0 && args.response) {
|
|
218
|
+
const response = args.response.trim();
|
|
219
|
+
if (response === '1' || response.toLowerCase().includes('delete everything')) {
|
|
220
|
+
// Delete Kyverno policies from cluster
|
|
221
|
+
kyvernoCleanupResults = await deleteKyvernoPoliciesByPolicyId(policyId, logger, requestId);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// Always delete the policy intent from Vector DB
|
|
225
|
+
await policyService.deletePolicyIntent(policyId);
|
|
226
|
+
const cleanupMessage = kyvernoCleanupResults
|
|
227
|
+
? `with Kyverno cleanup (${kyvernoCleanupResults.successful.length} deleted, ${kyvernoCleanupResults.failed.length} failed)`
|
|
228
|
+
: kyvernoPolicies.length > 0
|
|
229
|
+
? '(Kyverno policies preserved in cluster)'
|
|
230
|
+
: '(no Kyverno policies to cleanup)';
|
|
231
|
+
return {
|
|
232
|
+
success: true,
|
|
233
|
+
operation: 'delete',
|
|
234
|
+
dataType: 'policy',
|
|
235
|
+
message: `Policy intent deleted successfully ${cleanupMessage}`,
|
|
236
|
+
deletedPolicyIntent: existingPolicyIntent,
|
|
237
|
+
kyvernoCleanup: kyvernoCleanupResults || { preserved: true }
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
logger.error('Failed to delete policy intent', error, { requestId, policyId });
|
|
242
|
+
return {
|
|
243
|
+
success: false,
|
|
244
|
+
operation: 'delete',
|
|
245
|
+
dataType: 'policy',
|
|
246
|
+
message: 'Failed to delete policy intent',
|
|
247
|
+
error: error instanceof Error ? error.message : String(error)
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Handle deleteAll policies with batch Kyverno cleanup
|
|
253
|
+
*/
|
|
254
|
+
async function handlePolicyDeleteAll(policyService, args, logger, requestId) {
|
|
255
|
+
try {
|
|
256
|
+
// Get all policy intents
|
|
257
|
+
const allPolicyIntents = await policyService.getAllPolicyIntents();
|
|
258
|
+
if (!allPolicyIntents || allPolicyIntents.length === 0) {
|
|
259
|
+
return {
|
|
260
|
+
success: true,
|
|
261
|
+
operation: 'deleteAll',
|
|
262
|
+
dataType: 'policy',
|
|
263
|
+
message: 'No policy intents found to delete',
|
|
264
|
+
deletedCount: 0
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
// Find all deployed Kyverno policies for all policy intents
|
|
268
|
+
const allKyvernoPolicies = await findAllKyvernoPoliciesForPolicyIntents(logger, requestId);
|
|
269
|
+
if (allKyvernoPolicies.length > 0 && !args.response) {
|
|
270
|
+
// Show confirmation prompt for batch Kyverno cleanup
|
|
271
|
+
return {
|
|
272
|
+
success: true,
|
|
273
|
+
operation: 'deleteAll',
|
|
274
|
+
dataType: 'policy',
|
|
275
|
+
requiresConfirmation: true,
|
|
276
|
+
message: 'Found policy intents with deployed Kyverno policies that need cleanup decision',
|
|
277
|
+
confirmation: {
|
|
278
|
+
question: `Deleting ${allPolicyIntents.length} policy intents. Found ${allKyvernoPolicies.length} deployed Kyverno policies in your cluster: ${allKyvernoPolicies.map(p => p.name).join(', ')}\n\n**Choose what to do:**\n\n1. **Delete everything** - Remove all policy intents AND delete all Kyverno policies from cluster\n2. **Keep Kyverno policies** - Remove all policy intents only, preserve all cluster policies\n\n⚠️ **Warning**: Option 1 will remove ALL active policy enforcement from your cluster.\n\n**What would you like to do?**`,
|
|
279
|
+
options: ['Delete everything', 'Keep Kyverno policies']
|
|
280
|
+
},
|
|
281
|
+
policyIntents: allPolicyIntents,
|
|
282
|
+
kyvernoPolicies: allKyvernoPolicies
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
// Process user's response or proceed with direct deletion
|
|
286
|
+
let kyvernoCleanupResults = null;
|
|
287
|
+
if (allKyvernoPolicies.length > 0 && args.response) {
|
|
288
|
+
const response = args.response.trim();
|
|
289
|
+
if (response === '1' || response.toLowerCase().includes('delete everything')) {
|
|
290
|
+
// Delete all Kyverno policies from cluster
|
|
291
|
+
kyvernoCleanupResults = await deleteAllKyvernoPoliciesForPolicyIntents(logger, requestId);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
// Always delete all policy intents from Vector DB
|
|
295
|
+
for (const policyIntent of allPolicyIntents) {
|
|
296
|
+
await policyService.deletePolicyIntent(policyIntent.id);
|
|
297
|
+
}
|
|
298
|
+
const cleanupMessage = kyvernoCleanupResults
|
|
299
|
+
? `with Kyverno cleanup (${kyvernoCleanupResults.successful.length} deleted, ${kyvernoCleanupResults.failed.length} failed)`
|
|
300
|
+
: allKyvernoPolicies.length > 0
|
|
301
|
+
? '(Kyverno policies preserved in cluster)'
|
|
302
|
+
: '(no Kyverno policies to cleanup)';
|
|
303
|
+
return {
|
|
304
|
+
success: true,
|
|
305
|
+
operation: 'deleteAll',
|
|
306
|
+
dataType: 'policy',
|
|
307
|
+
message: `All ${allPolicyIntents.length} policy intents deleted successfully ${cleanupMessage}`,
|
|
308
|
+
deletedCount: allPolicyIntents.length,
|
|
309
|
+
deletedPolicyIntents: allPolicyIntents,
|
|
310
|
+
kyvernoCleanup: kyvernoCleanupResults || { preserved: true }
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
logger.error('Failed to delete all policy intents', error, { requestId });
|
|
315
|
+
return {
|
|
316
|
+
success: false,
|
|
317
|
+
operation: 'deleteAll',
|
|
318
|
+
dataType: 'policy',
|
|
319
|
+
message: 'Failed to delete all policy intents',
|
|
320
|
+
error: error instanceof Error ? error.message : String(error)
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Main policy operations handler - delegates to specific operation functions
|
|
326
|
+
* Requires shared validation utilities to be passed as parameters to avoid circular imports
|
|
327
|
+
*/
|
|
328
|
+
async function handlePolicyOperation(operation, args, logger, requestId, validateVectorDBConnection, validateEmbeddingService) {
|
|
329
|
+
// Get policy service and validate Vector DB connection
|
|
330
|
+
const policyService = await getPolicyService();
|
|
331
|
+
const connectionCheck = await validateVectorDBConnection(policyService, logger, requestId);
|
|
332
|
+
if (!connectionCheck.success) {
|
|
333
|
+
return {
|
|
334
|
+
success: false,
|
|
335
|
+
operation,
|
|
336
|
+
dataType: 'policy',
|
|
337
|
+
error: connectionCheck.error,
|
|
338
|
+
message: 'Vector DB connection required for policy management'
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
// Validate embedding service and fail if unavailable (except for delete operations)
|
|
342
|
+
const operationsRequiringEmbedding = ['create', 'search'];
|
|
343
|
+
if (operationsRequiringEmbedding.includes(operation)) {
|
|
344
|
+
const embeddingCheck = await validateEmbeddingService(logger, requestId);
|
|
345
|
+
if (!embeddingCheck.success) {
|
|
346
|
+
return {
|
|
347
|
+
success: false,
|
|
348
|
+
operation,
|
|
349
|
+
dataType: 'policy',
|
|
350
|
+
error: embeddingCheck.error,
|
|
351
|
+
message: 'OpenAI API key required for policy management'
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const sessionManager = new unified_creation_session_1.UnifiedCreationSessionManager('policy');
|
|
356
|
+
switch (operation) {
|
|
357
|
+
case 'create': {
|
|
358
|
+
let workflowStep;
|
|
359
|
+
if (args.sessionId) {
|
|
360
|
+
// Continue existing session
|
|
361
|
+
logger.info('Continuing policy creation workflow', {
|
|
362
|
+
requestId,
|
|
363
|
+
sessionId: args.sessionId
|
|
364
|
+
});
|
|
365
|
+
if (args.response) {
|
|
366
|
+
// Process user response and move to next step
|
|
367
|
+
const updatedSession = sessionManager.processResponse(args.sessionId, args.response, args);
|
|
368
|
+
workflowStep = await sessionManager.getNextWorkflowStep(updatedSession, args);
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
// Just get current step without processing response
|
|
372
|
+
const session = sessionManager.loadSession(args.sessionId, args);
|
|
373
|
+
if (!session) {
|
|
374
|
+
throw error_handling_1.ErrorHandler.createError(error_handling_1.ErrorCategory.VALIDATION, error_handling_1.ErrorSeverity.HIGH, `Session not found: ${args.sessionId}`, {
|
|
375
|
+
operation: 'policy_workflow_continue',
|
|
376
|
+
component: 'OrganizationalDataTool',
|
|
377
|
+
requestId,
|
|
378
|
+
input: { sessionId: args.sessionId }
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
workflowStep = await sessionManager.getNextWorkflowStep(session, args);
|
|
382
|
+
}
|
|
383
|
+
if (!workflowStep) {
|
|
384
|
+
throw error_handling_1.ErrorHandler.createError(error_handling_1.ErrorCategory.VALIDATION, error_handling_1.ErrorSeverity.HIGH, `Session not found or workflow failed`, {
|
|
385
|
+
operation: 'policy_workflow_continue',
|
|
386
|
+
component: 'OrganizationalDataTool',
|
|
387
|
+
requestId,
|
|
388
|
+
input: { sessionId: args.sessionId }
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
// Start new workflow session
|
|
394
|
+
logger.info('Starting new policy creation workflow', { requestId });
|
|
395
|
+
const session = sessionManager.createSession(args);
|
|
396
|
+
workflowStep = await sessionManager.getNextWorkflowStep(session, args);
|
|
397
|
+
if (!workflowStep) {
|
|
398
|
+
throw error_handling_1.ErrorHandler.createError(error_handling_1.ErrorCategory.OPERATION, error_handling_1.ErrorSeverity.HIGH, 'Failed to initialize policy creation workflow', {
|
|
399
|
+
operation: 'policy_workflow_start',
|
|
400
|
+
component: 'OrganizationalDataTool',
|
|
401
|
+
requestId
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
// Always check if workflow is complete and store policy in Vector DB
|
|
406
|
+
let storageInfo = {};
|
|
407
|
+
const isComplete = !('nextStep' in workflowStep) || !workflowStep.nextStep; // Complete when no next step
|
|
408
|
+
const hasPolicy = !!workflowStep.data?.policy;
|
|
409
|
+
logger.info('Checking workflow completion', {
|
|
410
|
+
requestId,
|
|
411
|
+
nextStep: ('nextStep' in workflowStep) ? workflowStep.nextStep : 'complete',
|
|
412
|
+
hasPolicy,
|
|
413
|
+
policyId: workflowStep.data?.policy?.id
|
|
414
|
+
});
|
|
415
|
+
if (isComplete && hasPolicy) {
|
|
416
|
+
try {
|
|
417
|
+
await policyService.storePolicyIntent(workflowStep.data.policy);
|
|
418
|
+
const vectorDBConfig = new vector_db_service_1.VectorDBService({ collectionName: 'policies' }).getConfig();
|
|
419
|
+
storageInfo = {
|
|
420
|
+
stored: true,
|
|
421
|
+
vectorDbUrl: vectorDBConfig.url,
|
|
422
|
+
collectionName: vectorDBConfig.collectionName,
|
|
423
|
+
policyId: workflowStep.data.policy.id
|
|
424
|
+
};
|
|
425
|
+
logger.info('Policy stored in Vector DB successfully', {
|
|
426
|
+
requestId,
|
|
427
|
+
policyId: workflowStep.data.policy.id,
|
|
428
|
+
description: workflowStep.data.policy.description.substring(0, 50) + (workflowStep.data.policy.description.length > 50 ? '...' : '')
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
433
|
+
storageInfo = {
|
|
434
|
+
stored: false,
|
|
435
|
+
error: errorMessage,
|
|
436
|
+
policyId: workflowStep.data.policy.id
|
|
437
|
+
};
|
|
438
|
+
logger.error('Failed to store policy in Vector DB', error instanceof Error ? error : new Error(String(error)), {
|
|
439
|
+
requestId,
|
|
440
|
+
policyId: workflowStep.data.policy.id
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
// For completed policies, storage failure means creation failure
|
|
445
|
+
const storageSucceeded = storageInfo.stored === true;
|
|
446
|
+
const operationSucceeded = !isComplete || storageSucceeded;
|
|
447
|
+
return {
|
|
448
|
+
success: operationSucceeded,
|
|
449
|
+
operation: 'create',
|
|
450
|
+
dataType: 'policy',
|
|
451
|
+
workflow: workflowStep,
|
|
452
|
+
storage: storageInfo,
|
|
453
|
+
message: isComplete ?
|
|
454
|
+
(storageSucceeded ? 'Policy created and stored successfully' : 'Policy creation failed - storage error') :
|
|
455
|
+
'Workflow step ready'
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
case 'list': {
|
|
459
|
+
const limit = args.limit || 10;
|
|
460
|
+
const policyIntents = await policyService.getAllPolicyIntents();
|
|
461
|
+
const totalCount = await policyService.getPolicyIntentsCount();
|
|
462
|
+
const limitedPolicyIntents = policyIntents.slice(0, limit);
|
|
463
|
+
return {
|
|
464
|
+
success: true,
|
|
465
|
+
operation,
|
|
466
|
+
dataType: 'policy',
|
|
467
|
+
message: `Found ${totalCount} policy intents (showing ${limitedPolicyIntents.length})`,
|
|
468
|
+
policyIntents: limitedPolicyIntents,
|
|
469
|
+
totalCount,
|
|
470
|
+
note: totalCount > limit ? `Showing first ${limit} of ${totalCount} policy intents. Use limit parameter to see more.` : undefined
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
case 'get': {
|
|
474
|
+
if (!args.id) {
|
|
475
|
+
return {
|
|
476
|
+
success: false,
|
|
477
|
+
operation,
|
|
478
|
+
dataType: 'policy',
|
|
479
|
+
message: 'Policy intent ID is required for get operation',
|
|
480
|
+
error: 'Missing required parameter: id'
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
const policyIntent = await policyService.getPolicyIntent(args.id);
|
|
484
|
+
if (!policyIntent) {
|
|
485
|
+
return {
|
|
486
|
+
success: false,
|
|
487
|
+
operation,
|
|
488
|
+
dataType: 'policy',
|
|
489
|
+
message: `Policy intent not found: ${args.id}`,
|
|
490
|
+
error: 'Policy intent not found'
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
return {
|
|
494
|
+
success: true,
|
|
495
|
+
operation,
|
|
496
|
+
dataType: 'policy',
|
|
497
|
+
message: 'Policy intent retrieved successfully',
|
|
498
|
+
policyIntent
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
case 'search': {
|
|
502
|
+
if (!args.id) { // For search, 'id' parameter contains the search query
|
|
503
|
+
return {
|
|
504
|
+
success: false,
|
|
505
|
+
operation,
|
|
506
|
+
dataType: 'policy',
|
|
507
|
+
message: 'Search query is required (use id parameter)',
|
|
508
|
+
error: 'Missing required parameter: id (search query)'
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
const limit = args.limit || 10;
|
|
512
|
+
const searchResults = await policyService.searchPolicyIntents(args.id, { limit });
|
|
513
|
+
return {
|
|
514
|
+
success: true,
|
|
515
|
+
operation,
|
|
516
|
+
dataType: 'policy',
|
|
517
|
+
message: `Found ${searchResults.length} policy intents matching "${args.id}"`,
|
|
518
|
+
policyIntents: searchResults.map(result => result.data),
|
|
519
|
+
searchResults: searchResults.map(result => ({
|
|
520
|
+
policyIntent: result.data,
|
|
521
|
+
score: result.score
|
|
522
|
+
}))
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
case 'delete': {
|
|
526
|
+
if (!args.id) {
|
|
527
|
+
return {
|
|
528
|
+
success: false,
|
|
529
|
+
operation,
|
|
530
|
+
dataType: 'policy',
|
|
531
|
+
message: 'Policy intent ID is required for delete operation',
|
|
532
|
+
error: 'Missing required parameter: id'
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
return await handlePolicyDelete(args.id, policyService, args, logger, requestId);
|
|
536
|
+
}
|
|
537
|
+
case 'deleteAll': {
|
|
538
|
+
return await handlePolicyDeleteAll(policyService, args, logger, requestId);
|
|
539
|
+
}
|
|
540
|
+
default:
|
|
541
|
+
return {
|
|
542
|
+
success: false,
|
|
543
|
+
operation,
|
|
544
|
+
dataType: 'policy',
|
|
545
|
+
message: `Unsupported operation: ${operation}. Supported operations: create, list, get, search, delete, deleteAll`,
|
|
546
|
+
error: 'Unsupported operation'
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
}
|
package/dist/core/schema.js
CHANGED
|
@@ -821,7 +821,7 @@ class ResourceRecommender {
|
|
|
821
821
|
if (this.policyService) {
|
|
822
822
|
try {
|
|
823
823
|
const resourceContext = solution.resources.map(r => `${r.kind} ${r.description}`).join(' ');
|
|
824
|
-
const policyResults = await this.policyService.searchPolicyIntents(`${intent} ${resourceContext}`, { limit:
|
|
824
|
+
const policyResults = await this.policyService.searchPolicyIntents(`${intent} ${resourceContext}`, { limit: 50 });
|
|
825
825
|
relevantPolicyResults = policyResults.map(result => ({
|
|
826
826
|
policy: result.data,
|
|
827
827
|
score: result.score,
|
|
@@ -839,7 +839,7 @@ Please try again or modify your policy description.`,
|
|
|
839
839
|
const capabilityService = new capability_vector_service_1.CapabilityVectorService();
|
|
840
840
|
// Use existing searchCapabilities function - no fallback, let it throw if it fails
|
|
841
841
|
const searchResults = await capabilityService.searchCapabilities(searchQuery, {
|
|
842
|
-
limit:
|
|
842
|
+
limit: 50 // Higher limit to get more relevant resources - aligns with recommendation tool
|
|
843
843
|
});
|
|
844
844
|
if (searchResults.length === 0) {
|
|
845
845
|
throw new Error(`No relevant capabilities found for policy description: "${policyDescription}"`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizational-data.d.ts","sourceRoot":"","sources":["../../src/tools/organizational-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"organizational-data.d.ts","sourceRoot":"","sources":["../../src/tools/organizational-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAchD,eAAO,MAAM,6BAA6B,kBAAkB,CAAC;AAC7D,eAAO,MAAM,oCAAoC,+jBAAyjB,CAAC;AAG3mB,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;;;CAwBjD,CAAC;AAsjBF;;GAEG;AACH,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,KAAK,GAAG,IAAI,EACpB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,GAAG,CAAC,CA0Hd"}
|