@vfarcic/dot-ai 0.48.0 → 0.50.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 (47) hide show
  1. package/README.md +49 -2
  2. package/dist/core/base-vector-service.d.ts +86 -0
  3. package/dist/core/base-vector-service.d.ts.map +1 -0
  4. package/dist/core/base-vector-service.js +223 -0
  5. package/dist/core/capabilities.d.ts +71 -0
  6. package/dist/core/capabilities.d.ts.map +1 -0
  7. package/dist/core/capabilities.js +215 -0
  8. package/dist/core/capability-vector-service.d.ts +80 -0
  9. package/dist/core/capability-vector-service.d.ts.map +1 -0
  10. package/dist/core/capability-vector-service.js +142 -0
  11. package/dist/core/claude.d.ts +14 -1
  12. package/dist/core/claude.d.ts.map +1 -1
  13. package/dist/core/claude.js +109 -13
  14. package/dist/core/discovery.d.ts +6 -0
  15. package/dist/core/discovery.d.ts.map +1 -1
  16. package/dist/core/discovery.js +7 -1
  17. package/dist/core/embedding-service.d.ts +3 -3
  18. package/dist/core/embedding-service.d.ts.map +1 -1
  19. package/dist/core/embedding-service.js +6 -7
  20. package/dist/core/index.d.ts +2 -0
  21. package/dist/core/index.d.ts.map +1 -1
  22. package/dist/core/index.js +7 -4
  23. package/dist/core/pattern-vector-service.d.ts +11 -80
  24. package/dist/core/pattern-vector-service.d.ts.map +1 -1
  25. package/dist/core/pattern-vector-service.js +40 -277
  26. package/dist/core/schema.d.ts +11 -30
  27. package/dist/core/schema.d.ts.map +1 -1
  28. package/dist/core/schema.js +107 -126
  29. package/dist/core/vector-db-service.d.ts +6 -0
  30. package/dist/core/vector-db-service.d.ts.map +1 -1
  31. package/dist/core/vector-db-service.js +40 -10
  32. package/dist/tools/organizational-data.d.ts +18 -3
  33. package/dist/tools/organizational-data.d.ts.map +1 -1
  34. package/dist/tools/organizational-data.js +1750 -17
  35. package/dist/tools/recommend.d.ts.map +1 -1
  36. package/dist/tools/recommend.js +3 -7
  37. package/dist/tools/version.d.ts +9 -0
  38. package/dist/tools/version.d.ts.map +1 -1
  39. package/dist/tools/version.js +115 -5
  40. package/package.json +1 -1
  41. package/prompts/capability-inference.md +121 -0
  42. package/prompts/doc-testing-test-section.md +40 -2
  43. package/prompts/resource-selection.md +10 -3
  44. package/shared-prompts/prd-done.md +5 -4
  45. package/shared-prompts/prd-update-decisions.md +9 -0
  46. package/shared-prompts/prd-update-progress.md +33 -0
  47. package/prompts/concept-extraction.md +0 -95
package/README.md CHANGED
@@ -12,7 +12,7 @@ DevOps AI Toolkit is an AI-powered development productivity platform that enhanc
12
12
 
13
13
  ### Kubernetes Deployment
14
14
  - **Developers**: Deploy applications without needing deep Kubernetes expertise
15
- - **Platform Engineers**: Create organizational deployment patterns that enhance AI recommendations with institutional knowledge and best practices
15
+ - **Platform Engineers**: Create organizational deployment patterns that enhance AI recommendations with institutional knowledge and best practices, and scan cluster resources to enable semantic matching for dramatically improved recommendation accuracy
16
16
 
17
17
  ### Documentation Testing
18
18
  - **Documentation Maintainers**: Automatically validate documentation accuracy and catch outdated content
@@ -31,10 +31,34 @@ DevOps AI Toolkit is an AI-powered development productivity platform that enhanc
31
31
 
32
32
  ### Kubernetes Deployment Intelligence
33
33
  🔍 **Smart Discovery**: Automatically finds all available resources and operators in your cluster
34
- 🤖 **AI Recommendations**: Get deployment suggestions tailored to your specific cluster setup
34
+ 🧠 **Semantic Capability Management**: Discovers what each resource actually does for intelligent matching
35
+ 🤖 **AI Recommendations**: Get deployment suggestions tailored to your specific cluster setup with enhanced semantic understanding
35
36
  🔧 **Operator-Aware**: Leverages custom operators and CRDs when available
36
37
  🚀 **Complete Workflow**: From discovery to deployment with automated Kubernetes integration
37
38
 
39
+ #### Capability-Enhanced Recommendations
40
+ Transform how AI understands your cluster by discovering semantic capabilities of each resource:
41
+
42
+ **The Problem**: Traditional discovery sees `sqls.devopstoolkit.live` as a meaningless name among hundreds of resources.
43
+
44
+ **The Solution**: Capability management teaches the system that `sqls.devopstoolkit.live` handles PostgreSQL databases with multi-cloud support.
45
+
46
+ **Before Capability Management:**
47
+ ```
48
+ User: "I need a PostgreSQL database"
49
+ AI: Gets 400+ generic resource names → picks complex multi-resource solution
50
+ Result: Misses optimal single-resource solutions
51
+ ```
52
+
53
+ **After Capability Management:**
54
+ ```
55
+ User: "I need a PostgreSQL database"
56
+ AI: Gets pre-filtered relevant resources with rich context
57
+ Result: Finds sqls.devopstoolkit.live as perfect match ✨
58
+ ```
59
+
60
+ **Get Started**: See the [Capability Management Guide](./docs/mcp-capability-management-guide.md) for complete workflows including cluster scanning, capability search, and recommendation enhancement.
61
+
38
62
  ### Documentation Testing & Validation
39
63
  📖 **Automated Testing**: Validates documentation by executing commands and testing examples
40
64
  🔍 **Two-Phase Validation**: Tests both functionality (does it work?) and semantic accuracy (are descriptions truthful?)
@@ -164,6 +188,29 @@ Agent: Perfect! Generating manifests and deploying now...
164
188
  Agent: ✅ Successfully deployed! Your application is running.
165
189
  ```
166
190
 
191
+ **Example: Capability Management**
192
+ ```
193
+ User: I want to scan my cluster for resource capabilities to improve recommendations
194
+
195
+ Agent: I'll help you scan your cluster to discover semantic capabilities. This will dramatically improve recommendation accuracy.
196
+ [Uses manageOrgData with capabilities scanning]
197
+
198
+ Agent: Would you like to scan all cluster resources or specify a subset?
199
+ Options: 1) All resources 2) Specific subset
200
+
201
+ User: All resources in auto mode
202
+
203
+ Agent: Starting comprehensive cluster capability scan...
204
+ ✅ Capability scan completed! Processed cluster resources successfully.
205
+
206
+ User: Now I need a PostgreSQL database
207
+
208
+ Agent: Let me get enhanced recommendations using your capability data.
209
+ [Uses recommend tool with capability pre-filtering]
210
+
211
+ Agent: Perfect! I found sqls.devopstoolkit.live as the top match - it's a managed database solution supporting PostgreSQL with multi-cloud capabilities and low complexity. Much better than the generic StatefulSet approach I would have suggested before!
212
+ ```
213
+
167
214
  **Example: Documentation Testing**
168
215
  ```
169
216
  User: I want to test my README.md file to make sure all the examples work
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Base Vector Service
3
+ *
4
+ * Generic vector operations that can be extended for different data types
5
+ * (patterns, capabilities, dependencies, etc.)
6
+ */
7
+ import { VectorDBService } from './vector-db-service';
8
+ import { EmbeddingService } from './embedding-service';
9
+ export interface BaseSearchOptions {
10
+ limit?: number;
11
+ scoreThreshold?: number;
12
+ keywordWeight?: number;
13
+ }
14
+ export interface BaseSearchResult<T> {
15
+ data: T;
16
+ score: number;
17
+ matchType: 'keyword' | 'semantic' | 'hybrid';
18
+ }
19
+ export interface SearchMode {
20
+ semantic: boolean;
21
+ provider?: string;
22
+ reason?: string;
23
+ }
24
+ /**
25
+ * Abstract base class for vector-based data services
26
+ */
27
+ export declare abstract class BaseVectorService<T> {
28
+ protected vectorDB: VectorDBService;
29
+ protected embeddingService: EmbeddingService;
30
+ protected collectionName: string;
31
+ constructor(collectionName: string, vectorDB?: VectorDBService, embeddingService?: EmbeddingService);
32
+ /**
33
+ * Initialize the collection
34
+ */
35
+ initialize(): Promise<void>;
36
+ /**
37
+ * Health check for Vector DB connection
38
+ */
39
+ healthCheck(): Promise<boolean>;
40
+ /**
41
+ * Store data in Vector DB with optional semantic embedding
42
+ */
43
+ storeData(data: T): Promise<void>;
44
+ /**
45
+ * Search for data using hybrid semantic + keyword matching
46
+ */
47
+ searchData(query: string, options?: BaseSearchOptions): Promise<BaseSearchResult<T>[]>;
48
+ /**
49
+ * Get data by ID
50
+ */
51
+ getData(id: string): Promise<T | null>;
52
+ /**
53
+ * Delete data by ID
54
+ */
55
+ deleteData(id: string): Promise<void>;
56
+ /**
57
+ * Delete all data (recreate collection)
58
+ */
59
+ deleteAllData(): Promise<void>;
60
+ /**
61
+ * Get all data (limited)
62
+ */
63
+ getAllData(limit?: number): Promise<T[]>;
64
+ /**
65
+ * Get total count of data items
66
+ */
67
+ getDataCount(): Promise<number>;
68
+ /**
69
+ * Get current search mode (semantic vs keyword-only)
70
+ */
71
+ getSearchMode(): SearchMode;
72
+ protected abstract createSearchText(data: T): string;
73
+ protected abstract extractId(data: T): string;
74
+ protected abstract createPayload(data: T): Record<string, any>;
75
+ protected abstract payloadToData(payload: Record<string, any>): T;
76
+ protected extractKeywords(query: string): string[];
77
+ /**
78
+ * Hybrid search combining semantic and keyword matching
79
+ */
80
+ private hybridSearch;
81
+ /**
82
+ * Combine semantic and keyword results with hybrid ranking
83
+ */
84
+ private combineHybridResults;
85
+ }
86
+ //# sourceMappingURL=base-vector-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-vector-service.d.ts","sourceRoot":"","sources":["../../src/core/base-vector-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAkB,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;CAC9C;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,8BAAsB,iBAAiB,CAAC,CAAC;IACvC,SAAS,CAAC,QAAQ,EAAE,eAAe,CAAC;IACpC,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC7C,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC;gBAErB,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,eAAe,EAAE,gBAAgB,CAAC,EAAE,gBAAgB;IAMnG;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAIrC;;OAEG;IACG,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA+BvC;;OAEG;IACG,UAAU,CACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IAyBjC;;OAEG;IACG,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAW5C;;OAEG;IACG,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC;;OAEG;IACG,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAS9C;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAWrC;;OAEG;IACH,aAAa,IAAI,UAAU;IAU3B,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM;IACpD,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM;IAC7C,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC9D,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC;IAGjE,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAIlD;;OAEG;YACW,YAAY;IAkC1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;CA2C7B"}
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ /**
3
+ * Base Vector Service
4
+ *
5
+ * Generic vector operations that can be extended for different data types
6
+ * (patterns, capabilities, dependencies, etc.)
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.BaseVectorService = void 0;
10
+ const vector_db_service_1 = require("./vector-db-service");
11
+ const embedding_service_1 = require("./embedding-service");
12
+ /**
13
+ * Abstract base class for vector-based data services
14
+ */
15
+ class BaseVectorService {
16
+ vectorDB;
17
+ embeddingService;
18
+ collectionName;
19
+ constructor(collectionName, vectorDB, embeddingService) {
20
+ this.collectionName = collectionName;
21
+ this.vectorDB = vectorDB || new vector_db_service_1.VectorDBService({ collectionName });
22
+ this.embeddingService = embeddingService || new embedding_service_1.EmbeddingService();
23
+ }
24
+ /**
25
+ * Initialize the collection
26
+ */
27
+ async initialize() {
28
+ // Use embedding dimensions if available, otherwise default to 1536 (OpenAI default)
29
+ const dimensions = this.embeddingService.isAvailable() ?
30
+ this.embeddingService.getDimensions() :
31
+ 1536;
32
+ await this.vectorDB.initializeCollection(dimensions);
33
+ }
34
+ /**
35
+ * Health check for Vector DB connection
36
+ */
37
+ async healthCheck() {
38
+ return await this.vectorDB.healthCheck();
39
+ }
40
+ /**
41
+ * Store data in Vector DB with optional semantic embedding
42
+ */
43
+ async storeData(data) {
44
+ const searchText = this.createSearchText(data);
45
+ const id = this.extractId(data);
46
+ // Generate embedding - required for vector storage
47
+ let embedding;
48
+ if (this.embeddingService.isAvailable()) {
49
+ try {
50
+ embedding = await this.embeddingService.generateEmbedding(searchText);
51
+ }
52
+ catch (error) {
53
+ // Fail immediately with clear error about embedding generation
54
+ throw new Error(`Embedding generation failed: ${error instanceof Error ? error.message : String(error)}`);
55
+ }
56
+ }
57
+ else {
58
+ // Embedding service not available - fail with clear error
59
+ throw new Error('Embedding service not available - cannot store data in vector collection');
60
+ }
61
+ const document = {
62
+ id,
63
+ payload: {
64
+ ...this.createPayload(data),
65
+ searchText: searchText,
66
+ hasEmbedding: true
67
+ },
68
+ vector: embedding
69
+ };
70
+ await this.vectorDB.upsertDocument(document);
71
+ }
72
+ /**
73
+ * Search for data using hybrid semantic + keyword matching
74
+ */
75
+ async searchData(query, options = {}) {
76
+ // Fail immediately if embedding service not available - no graceful fallback
77
+ if (!this.embeddingService.isAvailable()) {
78
+ throw new Error('Embedding service not available - cannot perform semantic search');
79
+ }
80
+ // Extract keywords for keyword search
81
+ const queryKeywords = this.extractKeywords(query);
82
+ if (queryKeywords.length === 0) {
83
+ return [];
84
+ }
85
+ const limit = options.limit || 10;
86
+ const scoreThreshold = options.scoreThreshold || 0.01;
87
+ // Perform hybrid search (semantic + keyword)
88
+ try {
89
+ return await this.hybridSearch(query, queryKeywords, { limit, scoreThreshold });
90
+ }
91
+ catch (error) {
92
+ // Fail immediately - no fallback to keyword-only search
93
+ throw new Error(`Semantic search failed: ${error instanceof Error ? error.message : String(error)}`);
94
+ }
95
+ }
96
+ /**
97
+ * Get data by ID
98
+ */
99
+ async getData(id) {
100
+ const document = await this.vectorDB.getDocument(id);
101
+ if (!document) {
102
+ return null;
103
+ }
104
+ const data = this.payloadToData(document.payload);
105
+ // Set the ID from the document
106
+ data.id = document.id;
107
+ return data;
108
+ }
109
+ /**
110
+ * Delete data by ID
111
+ */
112
+ async deleteData(id) {
113
+ await this.vectorDB.deleteDocument(id);
114
+ }
115
+ /**
116
+ * Delete all data (recreate collection)
117
+ */
118
+ async deleteAllData() {
119
+ await this.vectorDB.deleteAllDocuments();
120
+ }
121
+ /**
122
+ * Get all data (limited)
123
+ */
124
+ async getAllData(limit) {
125
+ const documents = await this.vectorDB.getAllDocuments(limit);
126
+ return documents.map(doc => {
127
+ const data = this.payloadToData(doc.payload);
128
+ data.id = doc.id;
129
+ return data;
130
+ });
131
+ }
132
+ /**
133
+ * Get total count of data items
134
+ */
135
+ async getDataCount() {
136
+ try {
137
+ const info = await this.vectorDB.getCollectionInfo();
138
+ return info.points_count || 0;
139
+ }
140
+ catch (error) {
141
+ // Fallback: get all and count
142
+ const data = await this.getAllData();
143
+ return data.length;
144
+ }
145
+ }
146
+ /**
147
+ * Get current search mode (semantic vs keyword-only)
148
+ */
149
+ getSearchMode() {
150
+ const status = this.embeddingService.getStatus();
151
+ return {
152
+ semantic: status.available,
153
+ provider: status.provider || undefined,
154
+ reason: status.reason || (status.available ? 'Embedding service available' : undefined)
155
+ };
156
+ }
157
+ // Virtual methods that can be overridden by subclasses
158
+ extractKeywords(query) {
159
+ return query.toLowerCase().split(/\s+/).filter(word => word.length > 2);
160
+ }
161
+ /**
162
+ * Hybrid search combining semantic and keyword matching
163
+ */
164
+ async hybridSearch(query, queryKeywords, options) {
165
+ // Generate query embedding - required for semantic search
166
+ const queryEmbedding = await this.embeddingService.generateEmbedding(query);
167
+ if (!queryEmbedding) {
168
+ throw new Error('Failed to generate query embedding for semantic search');
169
+ }
170
+ // Semantic search using vector similarity
171
+ const semanticResults = await this.vectorDB.searchSimilar(queryEmbedding, {
172
+ limit: options.limit * 2, // Get more candidates for hybrid ranking
173
+ scoreThreshold: 0.1 // Very permissive threshold for single-word queries
174
+ });
175
+ // Keyword search
176
+ const keywordResults = await this.vectorDB.searchByKeywords(queryKeywords, {
177
+ limit: options.limit * 2,
178
+ scoreThreshold: 0.1
179
+ });
180
+ // Combine and rank results
181
+ return this.combineHybridResults(semanticResults, keywordResults, queryKeywords, options);
182
+ }
183
+ /**
184
+ * Combine semantic and keyword results with hybrid ranking
185
+ */
186
+ combineHybridResults(semanticResults, keywordResults, queryKeywords, options) {
187
+ const combinedResults = new Map();
188
+ // Add semantic results
189
+ for (const result of semanticResults) {
190
+ const data = this.payloadToData(result.payload);
191
+ data.id = result.id;
192
+ combinedResults.set(result.id, {
193
+ data,
194
+ score: result.score * 0.7, // Weight semantic similarity
195
+ matchType: 'semantic'
196
+ });
197
+ }
198
+ // Add or boost keyword results
199
+ for (const result of keywordResults) {
200
+ const existing = combinedResults.get(result.id);
201
+ if (existing) {
202
+ // Boost score for hybrid match
203
+ existing.score = Math.max(existing.score, result.score * 0.8);
204
+ existing.matchType = 'hybrid';
205
+ }
206
+ else {
207
+ const data = this.payloadToData(result.payload);
208
+ data.id = result.id;
209
+ combinedResults.set(result.id, {
210
+ data,
211
+ score: result.score * 0.6, // Weight keyword matching
212
+ matchType: 'keyword'
213
+ });
214
+ }
215
+ }
216
+ // Sort by score and apply limits
217
+ return Array.from(combinedResults.values())
218
+ .filter(result => result.score >= options.scoreThreshold)
219
+ .sort((a, b) => b.score - a.score)
220
+ .slice(0, options.limit);
221
+ }
222
+ }
223
+ exports.BaseVectorService = BaseVectorService;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Resource Capability Discovery & Inference Engine
3
+ *
4
+ * PRD #48: Resource Capabilities Discovery & Integration
5
+ *
6
+ * This module provides capability inference for Kubernetes resources through
7
+ * AI-powered analysis of schemas and metadata.
8
+ */
9
+ import { Logger } from './error-handling';
10
+ import { ClaudeIntegration } from './claude';
11
+ /**
12
+ * Complete resource capability data structure for Vector DB storage
13
+ */
14
+ export interface ResourceCapability {
15
+ resourceName: string;
16
+ capabilities: string[];
17
+ providers: string[];
18
+ abstractions: string[];
19
+ complexity: 'low' | 'medium' | 'high';
20
+ description: string;
21
+ useCase: string;
22
+ embedding?: number[];
23
+ analyzedAt: string;
24
+ confidence: number;
25
+ }
26
+ /**
27
+ * Generic Capability Inference Engine
28
+ *
29
+ * Analyzes any Kubernetes CRD using AI to extract semantic capabilities
30
+ * for improved AI recommendations and resource matching.
31
+ */
32
+ export declare class CapabilityInferenceEngine {
33
+ private logger;
34
+ private claudeIntegration;
35
+ constructor(claudeIntegration: ClaudeIntegration, logger: Logger);
36
+ /**
37
+ * Main entry point: analyze resource to infer complete capabilities
38
+ *
39
+ * @param resourceName - Full resource name (e.g., "resourcegroups.azure.upbound.io")
40
+ * @throws Error if capability inference fails for any reason
41
+ */
42
+ inferCapabilities(resourceName: string, schema?: string, metadata?: any): Promise<ResourceCapability>;
43
+ /**
44
+ * Use AI to infer capabilities from all available resource context
45
+ *
46
+ * @throws Error if AI inference fails
47
+ */
48
+ private inferWithAI;
49
+ /**
50
+ * Build AI inference prompt using standard prompt loading pattern
51
+ *
52
+ * @throws Error if prompt template cannot be loaded
53
+ */
54
+ private buildInferencePrompt;
55
+ /**
56
+ * Parse AI response into structured capability data
57
+ *
58
+ * @throws Error if AI response cannot be parsed or is invalid
59
+ */
60
+ private parseCapabilitiesFromAI;
61
+ /**
62
+ * Build final ResourceCapability from AI analysis result
63
+ */
64
+ private buildResourceCapability;
65
+ /**
66
+ * Generate Vector DB ID for capability storage
67
+ * Creates deterministic UUID from resource name for Qdrant compatibility
68
+ */
69
+ static generateCapabilityId(resourceName: string): string;
70
+ }
71
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/core/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAK7C;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAEjC,YAAY,EAAE,MAAM,CAAC;IAGrB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAGtC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAGhB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAGrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,iBAAiB,CAAoB;gBAEjC,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM;IAKhE;;;;;OAKG;IACG,iBAAiB,CACrB,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,GAAG,GACb,OAAO,CAAC,kBAAkB,CAAC;IA4B9B;;;;OAIG;YACW,WAAW;IA2BzB;;;;OAIG;YACW,oBAAoB;IAkClC;;;;OAIG;IACH,OAAO,CAAC,uBAAuB;IAwD/B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAyB/B;;;OAGG;IACH,MAAM,CAAC,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;CAQ1D"}
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ /**
3
+ * Resource Capability Discovery & Inference Engine
4
+ *
5
+ * PRD #48: Resource Capabilities Discovery & Integration
6
+ *
7
+ * This module provides capability inference for Kubernetes resources through
8
+ * AI-powered analysis of schemas and metadata.
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.CapabilityInferenceEngine = void 0;
45
+ const fs = __importStar(require("fs"));
46
+ const path = __importStar(require("path"));
47
+ /**
48
+ * Generic Capability Inference Engine
49
+ *
50
+ * Analyzes any Kubernetes CRD using AI to extract semantic capabilities
51
+ * for improved AI recommendations and resource matching.
52
+ */
53
+ class CapabilityInferenceEngine {
54
+ logger;
55
+ claudeIntegration;
56
+ constructor(claudeIntegration, logger) {
57
+ this.claudeIntegration = claudeIntegration;
58
+ this.logger = logger;
59
+ }
60
+ /**
61
+ * Main entry point: analyze resource to infer complete capabilities
62
+ *
63
+ * @param resourceName - Full resource name (e.g., "resourcegroups.azure.upbound.io")
64
+ * @throws Error if capability inference fails for any reason
65
+ */
66
+ async inferCapabilities(resourceName, schema, metadata) {
67
+ const requestId = `capability-inference-${Date.now()}`;
68
+ this.logger.info('Starting capability inference', {
69
+ requestId,
70
+ resource: resourceName,
71
+ hasSchema: !!schema,
72
+ hasMetadata: !!metadata
73
+ });
74
+ // Use AI to analyze all available information
75
+ const aiResult = await this.inferWithAI(resourceName, schema, metadata, requestId);
76
+ // Convert AI result to final capability structure
77
+ const finalCapability = this.buildResourceCapability(resourceName, aiResult);
78
+ this.logger.info('Capability inference completed', {
79
+ requestId,
80
+ resource: resourceName,
81
+ capabilitiesFound: finalCapability.capabilities.length,
82
+ providersFound: finalCapability.providers.length,
83
+ complexity: finalCapability.complexity,
84
+ confidence: finalCapability.confidence
85
+ });
86
+ return finalCapability;
87
+ }
88
+ /**
89
+ * Use AI to infer capabilities from all available resource context
90
+ *
91
+ * @throws Error if AI inference fails
92
+ */
93
+ async inferWithAI(resourceName, schema, metadata, requestId) {
94
+ try {
95
+ const prompt = await this.buildInferencePrompt(resourceName, schema, metadata);
96
+ const response = await this.claudeIntegration.sendMessage(prompt);
97
+ return this.parseCapabilitiesFromAI(response.content);
98
+ }
99
+ catch (error) {
100
+ this.logger.error('AI capability inference failed', error, {
101
+ requestId,
102
+ resource: resourceName
103
+ });
104
+ throw error; // Re-throw to maintain fail-fast behavior
105
+ }
106
+ }
107
+ /**
108
+ * Build AI inference prompt using standard prompt loading pattern
109
+ *
110
+ * @throws Error if prompt template cannot be loaded
111
+ */
112
+ async buildInferencePrompt(resourceName, schema, metadata) {
113
+ // Load prompt template using standard pattern from existing codebase
114
+ const promptPath = path.join(__dirname, '..', '..', 'prompts', 'capability-inference.md');
115
+ if (!fs.existsSync(promptPath)) {
116
+ throw new Error(`Capability inference prompt template not found: ${promptPath}`);
117
+ }
118
+ let template;
119
+ try {
120
+ template = fs.readFileSync(promptPath, 'utf8');
121
+ }
122
+ catch (error) {
123
+ throw new Error(`Failed to read capability inference prompt: ${error instanceof Error ? error.message : String(error)}`);
124
+ }
125
+ // Replace template variables using standard pattern
126
+ const analysisContext = schema && metadata ?
127
+ 'Schema and metadata available' :
128
+ schema ? 'Schema only' :
129
+ metadata ? 'Metadata only' : 'Limited context';
130
+ const finalPrompt = template
131
+ .replace(/\{resourceName\}/g, resourceName)
132
+ .replace(/\{analysisContext\}/g, analysisContext)
133
+ .replace(/\{schema\}/g, schema || 'No schema provided')
134
+ .replace(/\{metadata\}/g, metadata ? JSON.stringify(metadata, null, 2) : 'No metadata provided');
135
+ return finalPrompt;
136
+ }
137
+ /**
138
+ * Parse AI response into structured capability data
139
+ *
140
+ * @throws Error if AI response cannot be parsed or is invalid
141
+ */
142
+ parseCapabilitiesFromAI(response) {
143
+ // Look for JSON in the response using standard pattern
144
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
145
+ if (!jsonMatch) {
146
+ throw new Error(`No JSON found in AI response. Response: ${response.substring(0, 200)}...`);
147
+ }
148
+ let parsed;
149
+ try {
150
+ parsed = JSON.parse(jsonMatch[0]);
151
+ }
152
+ catch (parseError) {
153
+ throw new Error(`Invalid JSON in AI response: ${parseError instanceof Error ? parseError.message : String(parseError)}. JSON: ${jsonMatch[0].substring(0, 200)}...`);
154
+ }
155
+ // Validate required fields with detailed error messages
156
+ if (!Array.isArray(parsed.capabilities)) {
157
+ throw new Error(`AI response missing or invalid capabilities array. Got: ${typeof parsed.capabilities}`);
158
+ }
159
+ if (!Array.isArray(parsed.providers)) {
160
+ throw new Error(`AI response missing or invalid providers array. Got: ${typeof parsed.providers}`);
161
+ }
162
+ if (!Array.isArray(parsed.abstractions)) {
163
+ throw new Error(`AI response missing or invalid abstractions array. Got: ${typeof parsed.abstractions}`);
164
+ }
165
+ if (!['low', 'medium', 'high'].includes(parsed.complexity)) {
166
+ throw new Error(`AI response invalid complexity: ${parsed.complexity}. Must be low, medium, or high`);
167
+ }
168
+ if (typeof parsed.description !== 'string' || parsed.description.trim() === '') {
169
+ throw new Error(`AI response missing or invalid description. Got: ${typeof parsed.description}`);
170
+ }
171
+ if (typeof parsed.useCase !== 'string' || parsed.useCase.trim() === '') {
172
+ throw new Error(`AI response missing or invalid useCase. Got: ${typeof parsed.useCase}`);
173
+ }
174
+ if (typeof parsed.confidence !== 'number' || parsed.confidence < 0 || parsed.confidence > 1) {
175
+ throw new Error(`AI response invalid confidence score: ${parsed.confidence}. Must be number between 0-1`);
176
+ }
177
+ return {
178
+ capabilities: parsed.capabilities,
179
+ providers: parsed.providers,
180
+ abstractions: parsed.abstractions,
181
+ complexity: parsed.complexity,
182
+ description: parsed.description.trim(),
183
+ useCase: parsed.useCase.trim(),
184
+ confidence: parsed.confidence
185
+ };
186
+ }
187
+ /**
188
+ * Build final ResourceCapability from AI analysis result
189
+ */
190
+ buildResourceCapability(resourceName, aiResult) {
191
+ return {
192
+ resourceName,
193
+ capabilities: aiResult.capabilities,
194
+ providers: aiResult.providers,
195
+ abstractions: aiResult.abstractions,
196
+ complexity: aiResult.complexity,
197
+ description: aiResult.description,
198
+ useCase: aiResult.useCase,
199
+ confidence: aiResult.confidence,
200
+ analyzedAt: new Date().toISOString()
201
+ };
202
+ }
203
+ /**
204
+ * Generate Vector DB ID for capability storage
205
+ * Creates deterministic UUID from resource name for Qdrant compatibility
206
+ */
207
+ static generateCapabilityId(resourceName) {
208
+ // Create deterministic UUID from resource name hash
209
+ const crypto = require('crypto');
210
+ const hash = crypto.createHash('sha256').update(`capability-${resourceName}`).digest('hex');
211
+ // Convert to UUID format: 8-4-4-4-12
212
+ return `${hash.substring(0, 8)}-${hash.substring(8, 12)}-${hash.substring(12, 16)}-${hash.substring(16, 20)}-${hash.substring(20, 32)}`;
213
+ }
214
+ }
215
+ exports.CapabilityInferenceEngine = CapabilityInferenceEngine;