@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.
@@ -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
+ }
@@ -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: 25 });
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: 25 // Higher limit to get more relevant resources
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;AAehD,eAAO,MAAM,6BAA6B,kBAAkB,CAAC;AAC7D,eAAO,MAAM,oCAAoC,+jBAAyjB,CAAC;AAG3mB,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;;;CAwBjD,CAAC;AA6uFF;;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"}
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"}