@vfarcic/dot-ai 0.47.0 → 0.49.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,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
+ * Get all data (limited)
58
+ */
59
+ getAllData(limit?: number): Promise<T[]>;
60
+ /**
61
+ * Get total count of data items
62
+ */
63
+ getDataCount(): Promise<number>;
64
+ /**
65
+ * Get current search mode (semantic vs keyword-only)
66
+ */
67
+ getSearchMode(): SearchMode;
68
+ protected abstract createSearchText(data: T): string;
69
+ protected abstract extractId(data: T): string;
70
+ protected abstract createPayload(data: T): Record<string, any>;
71
+ protected abstract payloadToData(payload: Record<string, any>): T;
72
+ protected extractKeywords(query: string): string[];
73
+ /**
74
+ * Hybrid search combining semantic and keyword matching
75
+ */
76
+ private hybridSearch;
77
+ /**
78
+ * Keyword-only search (fallback when embeddings not available)
79
+ */
80
+ private keywordOnlySearch;
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;IA4BvC;;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,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;YACW,iBAAiB;IAsB/B;;OAEG;IACH,OAAO,CAAC,oBAAoB;CA2C7B"}
@@ -0,0 +1,231 @@
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
+ // Try to generate embedding if service is available
47
+ let embedding = null;
48
+ if (this.embeddingService.isAvailable()) {
49
+ try {
50
+ embedding = await this.embeddingService.generateEmbedding(searchText);
51
+ }
52
+ catch (error) {
53
+ // Log but don't fail - fall back to keyword-only storage
54
+ console.warn(`Failed to generate embedding for ${this.collectionName}, using keyword-only storage:`, error);
55
+ }
56
+ }
57
+ const document = {
58
+ id,
59
+ payload: {
60
+ ...this.createPayload(data),
61
+ searchText: searchText,
62
+ hasEmbedding: embedding !== null
63
+ },
64
+ vector: embedding || undefined
65
+ };
66
+ await this.vectorDB.upsertDocument(document);
67
+ }
68
+ /**
69
+ * Search for data using hybrid semantic + keyword matching
70
+ */
71
+ async searchData(query, options = {}) {
72
+ // Extract keywords for keyword search
73
+ const queryKeywords = this.extractKeywords(query);
74
+ if (queryKeywords.length === 0) {
75
+ return [];
76
+ }
77
+ const limit = options.limit || 10;
78
+ const scoreThreshold = options.scoreThreshold || 0.1;
79
+ // Try semantic search first if embeddings available
80
+ if (this.embeddingService.isAvailable()) {
81
+ try {
82
+ return await this.hybridSearch(query, queryKeywords, { limit, scoreThreshold });
83
+ }
84
+ catch (error) {
85
+ // Fall back to keyword-only search if semantic search fails
86
+ console.warn('Semantic search failed, falling back to keyword search:', error);
87
+ }
88
+ }
89
+ // Keyword-only search (fallback or when embeddings not available)
90
+ return await this.keywordOnlySearch(queryKeywords, { limit, scoreThreshold });
91
+ }
92
+ /**
93
+ * Get data by ID
94
+ */
95
+ async getData(id) {
96
+ const document = await this.vectorDB.getDocument(id);
97
+ if (!document) {
98
+ return null;
99
+ }
100
+ const data = this.payloadToData(document.payload);
101
+ // Set the ID from the document
102
+ data.id = document.id;
103
+ return data;
104
+ }
105
+ /**
106
+ * Delete data by ID
107
+ */
108
+ async deleteData(id) {
109
+ await this.vectorDB.deleteDocument(id);
110
+ }
111
+ /**
112
+ * Get all data (limited)
113
+ */
114
+ async getAllData(limit) {
115
+ const documents = await this.vectorDB.getAllDocuments(limit);
116
+ return documents.map(doc => {
117
+ const data = this.payloadToData(doc.payload);
118
+ data.id = doc.id;
119
+ return data;
120
+ });
121
+ }
122
+ /**
123
+ * Get total count of data items
124
+ */
125
+ async getDataCount() {
126
+ try {
127
+ const info = await this.vectorDB.getCollectionInfo();
128
+ return info.points_count || 0;
129
+ }
130
+ catch (error) {
131
+ // Fallback: get all and count
132
+ const data = await this.getAllData();
133
+ return data.length;
134
+ }
135
+ }
136
+ /**
137
+ * Get current search mode (semantic vs keyword-only)
138
+ */
139
+ getSearchMode() {
140
+ const status = this.embeddingService.getStatus();
141
+ return {
142
+ semantic: status.available,
143
+ provider: status.provider || undefined,
144
+ reason: status.reason || (status.available ? 'Embedding service available' : undefined)
145
+ };
146
+ }
147
+ // Virtual methods that can be overridden by subclasses
148
+ extractKeywords(query) {
149
+ return query.toLowerCase().split(/\s+/).filter(word => word.length > 2);
150
+ }
151
+ /**
152
+ * Hybrid search combining semantic and keyword matching
153
+ */
154
+ async hybridSearch(query, queryKeywords, options) {
155
+ // Generate query embedding
156
+ const queryEmbedding = await this.embeddingService.generateEmbedding(query);
157
+ if (!queryEmbedding) {
158
+ // Fall back to keyword search
159
+ return await this.keywordOnlySearch(queryKeywords, options);
160
+ }
161
+ // Semantic search using vector similarity
162
+ const semanticResults = await this.vectorDB.searchSimilar(queryEmbedding, {
163
+ limit: options.limit * 2, // Get more candidates for hybrid ranking
164
+ scoreThreshold: 0.5 // Lower threshold for semantic similarity
165
+ });
166
+ // Keyword search
167
+ const keywordResults = await this.vectorDB.searchByKeywords(queryKeywords, {
168
+ limit: options.limit * 2,
169
+ scoreThreshold: 0.1
170
+ });
171
+ // Combine and rank results
172
+ return this.combineHybridResults(semanticResults, keywordResults, queryKeywords, options);
173
+ }
174
+ /**
175
+ * Keyword-only search (fallback when embeddings not available)
176
+ */
177
+ async keywordOnlySearch(queryKeywords, options) {
178
+ const keywordResults = await this.vectorDB.searchByKeywords(queryKeywords, options);
179
+ return keywordResults
180
+ .map(result => {
181
+ const data = this.payloadToData(result.payload);
182
+ data.id = result.id;
183
+ return {
184
+ data,
185
+ score: result.score,
186
+ matchType: 'keyword'
187
+ };
188
+ })
189
+ .filter(result => result.score >= options.scoreThreshold); // Apply score filtering
190
+ }
191
+ /**
192
+ * Combine semantic and keyword results with hybrid ranking
193
+ */
194
+ combineHybridResults(semanticResults, keywordResults, queryKeywords, options) {
195
+ const combinedResults = new Map();
196
+ // Add semantic results
197
+ for (const result of semanticResults) {
198
+ const data = this.payloadToData(result.payload);
199
+ data.id = result.id;
200
+ combinedResults.set(result.id, {
201
+ data,
202
+ score: result.score * 0.7, // Weight semantic similarity
203
+ matchType: 'semantic'
204
+ });
205
+ }
206
+ // Add or boost keyword results
207
+ for (const result of keywordResults) {
208
+ const existing = combinedResults.get(result.id);
209
+ if (existing) {
210
+ // Boost score for hybrid match
211
+ existing.score = Math.max(existing.score, result.score * 0.8);
212
+ existing.matchType = 'hybrid';
213
+ }
214
+ else {
215
+ const data = this.payloadToData(result.payload);
216
+ data.id = result.id;
217
+ combinedResults.set(result.id, {
218
+ data,
219
+ score: result.score * 0.6, // Weight keyword matching
220
+ matchType: 'keyword'
221
+ });
222
+ }
223
+ }
224
+ // Sort by score and apply limits
225
+ return Array.from(combinedResults.values())
226
+ .filter(result => result.score >= options.scoreThreshold)
227
+ .sort((a, b) => b.score - a.score)
228
+ .slice(0, options.limit);
229
+ }
230
+ }
231
+ exports.BaseVectorService = BaseVectorService;
@@ -44,6 +44,7 @@ export { validatePattern, createPattern, serializePattern, deserializePattern }
44
44
  export { PatternCreationStep, PatternCreationSession, PatternWorkflowStep } from './pattern-creation-types';
45
45
  export { PatternCreationSessionManager } from './pattern-creation-session';
46
46
  export { VectorDBService, VectorDBConfig, VectorDocument, SearchResult } from './vector-db-service';
47
+ export { BaseVectorService, BaseSearchOptions, BaseSearchResult } from './base-vector-service';
47
48
  export { PatternVectorService, PatternSearchOptions, PatternSearchResult } from './pattern-vector-service';
48
49
  export { EmbeddingService, EmbeddingConfig, EmbeddingProvider, OpenAIEmbeddingProvider } from './embedding-service';
49
50
  export default DotAI;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEhF,MAAM,WAAW,UAAU;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,WAAW,CAAkB;IAErC,SAAgB,SAAS,EAAE,mBAAmB,CAAC;IAC/C,SAAgB,MAAM,EAAE,YAAY,CAAC;IACrC,SAAgB,QAAQ,EAAE,cAAc,CAAC;IACzC,SAAgB,MAAM,EAAE,iBAAiB,CAAC;IAC1C,SAAgB,MAAM,EAAE;QACtB,MAAM,EAAE,YAAY,CAAC;QACrB,SAAS,EAAE,iBAAiB,CAAC;QAC7B,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC;QACnC,aAAa,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;QACtD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;KACjD,CAAC;gBAEU,MAAM,GAAE,UAAe;IAoEnC,OAAO,CAAC,cAAc;IAMhB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;IAa/C,aAAa,IAAI,OAAO;IAIxB,UAAU,IAAI,MAAM;IAIpB,kBAAkB,IAAI,MAAM,GAAG,SAAS;CAGzC;AAGD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC5G,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC5G,OAAO,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC3G,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAGpH,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEhF,MAAM,WAAW,UAAU;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,WAAW,CAAkB;IAErC,SAAgB,SAAS,EAAE,mBAAmB,CAAC;IAC/C,SAAgB,MAAM,EAAE,YAAY,CAAC;IACrC,SAAgB,QAAQ,EAAE,cAAc,CAAC;IACzC,SAAgB,MAAM,EAAE,iBAAiB,CAAC;IAC1C,SAAgB,MAAM,EAAE;QACtB,MAAM,EAAE,YAAY,CAAC;QACrB,SAAS,EAAE,iBAAiB,CAAC;QAC7B,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC;QACnC,aAAa,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;QACtD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;KACjD,CAAC;gBAEU,MAAM,GAAE,UAAe;IAoEnC,OAAO,CAAC,cAAc;IAMhB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;IAa/C,aAAa,IAAI,OAAO;IAIxB,UAAU,IAAI,MAAM;IAIpB,kBAAkB,IAAI,MAAM,GAAG,SAAS;CAGzC;AAGD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC5G,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC5G,OAAO,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC3G,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAGpH,eAAe,KAAK,CAAC"}
@@ -5,7 +5,7 @@
5
5
  * Shared intelligence for both CLI and MCP interfaces
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.OpenAIEmbeddingProvider = exports.EmbeddingService = exports.PatternVectorService = exports.VectorDBService = exports.PatternCreationSessionManager = exports.deserializePattern = exports.serializePattern = exports.createPattern = exports.validatePattern = exports.ResourceRecommender = exports.ManifestValidator = exports.SchemaParser = exports.ClaudeIntegration = exports.WorkflowEngine = exports.MemorySystem = exports.KubernetesDiscovery = exports.DotAI = void 0;
8
+ exports.OpenAIEmbeddingProvider = exports.EmbeddingService = exports.PatternVectorService = exports.BaseVectorService = exports.VectorDBService = exports.PatternCreationSessionManager = exports.deserializePattern = exports.serializePattern = exports.createPattern = exports.validatePattern = exports.ResourceRecommender = exports.ManifestValidator = exports.SchemaParser = exports.ClaudeIntegration = exports.WorkflowEngine = exports.MemorySystem = exports.KubernetesDiscovery = exports.DotAI = void 0;
9
9
  const discovery_1 = require("./discovery");
10
10
  const memory_1 = require("./memory");
11
11
  const workflow_1 = require("./workflow");
@@ -140,6 +140,8 @@ var pattern_creation_session_1 = require("./pattern-creation-session");
140
140
  Object.defineProperty(exports, "PatternCreationSessionManager", { enumerable: true, get: function () { return pattern_creation_session_1.PatternCreationSessionManager; } });
141
141
  var vector_db_service_1 = require("./vector-db-service");
142
142
  Object.defineProperty(exports, "VectorDBService", { enumerable: true, get: function () { return vector_db_service_1.VectorDBService; } });
143
+ var base_vector_service_1 = require("./base-vector-service");
144
+ Object.defineProperty(exports, "BaseVectorService", { enumerable: true, get: function () { return base_vector_service_1.BaseVectorService; } });
143
145
  var pattern_vector_service_1 = require("./pattern-vector-service");
144
146
  Object.defineProperty(exports, "PatternVectorService", { enumerable: true, get: function () { return pattern_vector_service_1.PatternVectorService; } });
145
147
  var embedding_service_1 = require("./embedding-service");
@@ -1,97 +1,28 @@
1
1
  /**
2
2
  * Pattern Vector Service
3
3
  *
4
- * Handles pattern-specific Vector DB operations with keyword-based matching
4
+ * Handles pattern-specific Vector DB operations
5
+ * Extends BaseVectorService for organizational patterns
5
6
  */
6
7
  import { VectorDBService } from './vector-db-service';
7
8
  import { OrganizationalPattern } from './pattern-types';
8
9
  import { EmbeddingService } from './embedding-service';
9
- export interface PatternSearchOptions {
10
- limit?: number;
11
- scoreThreshold?: number;
12
- keywordWeight?: number;
10
+ import { BaseVectorService, BaseSearchOptions, BaseSearchResult } from './base-vector-service';
11
+ export interface PatternSearchOptions extends BaseSearchOptions {
13
12
  }
14
- export interface PatternSearchResult {
15
- pattern: OrganizationalPattern;
16
- score: number;
17
- matchType: 'keyword' | 'semantic' | 'hybrid';
13
+ export interface PatternSearchResult extends BaseSearchResult<OrganizationalPattern> {
18
14
  }
19
- export declare class PatternVectorService {
20
- private vectorDB;
21
- private embeddingService;
22
- private collectionName;
23
- constructor(vectorDB: VectorDBService, embeddingService?: EmbeddingService);
24
- /**
25
- * Initialize the patterns collection
26
- */
27
- initialize(): Promise<void>;
28
- /**
29
- * Store a pattern in Vector DB with optional semantic embedding
30
- */
15
+ export declare class PatternVectorService extends BaseVectorService<OrganizationalPattern> {
16
+ constructor(vectorDB?: VectorDBService, embeddingService?: EmbeddingService);
17
+ protected createSearchText(pattern: OrganizationalPattern): string;
18
+ protected extractId(pattern: OrganizationalPattern): string;
19
+ protected createPayload(pattern: OrganizationalPattern): Record<string, any>;
20
+ protected payloadToData(payload: Record<string, any>): OrganizationalPattern;
31
21
  storePattern(pattern: OrganizationalPattern): Promise<void>;
32
- /**
33
- * Search for patterns using hybrid semantic + keyword matching
34
- */
35
22
  searchPatterns(query: string, options?: PatternSearchOptions): Promise<PatternSearchResult[]>;
36
- /**
37
- * Hybrid search combining semantic and keyword matching
38
- */
39
- private hybridSearch;
40
- /**
41
- * Keyword-only search (fallback when embeddings not available)
42
- */
43
- private keywordOnlySearch;
44
- /**
45
- * Combine semantic and keyword search results with hybrid ranking
46
- */
47
- private combineHybridResults;
48
- /**
49
- * Get search mode information for debugging
50
- */
51
- getSearchMode(): {
52
- semantic: boolean;
53
- provider: string | null;
54
- reason?: string;
55
- };
56
- /**
57
- * Get pattern by ID
58
- */
59
23
  getPattern(id: string): Promise<OrganizationalPattern | null>;
60
- /**
61
- * Get all patterns
62
- */
63
24
  getAllPatterns(): Promise<OrganizationalPattern[]>;
64
- /**
65
- * Delete pattern by ID
66
- */
67
25
  deletePattern(id: string): Promise<void>;
68
- /**
69
- * Get patterns count
70
- */
71
26
  getPatternsCount(): Promise<number>;
72
- /**
73
- * Health check for pattern storage
74
- */
75
- healthCheck(): Promise<boolean>;
76
- /**
77
- * Extract keywords from query text
78
- */
79
- private extractKeywords;
80
- /**
81
- * Simple stop words list
82
- */
83
- private isStopWord;
84
- /**
85
- * Calculate keyword match score
86
- */
87
- private calculateKeywordScore;
88
- /**
89
- * Create searchable text from pattern
90
- */
91
- private createSearchText;
92
- /**
93
- * Convert Vector DB payload back to OrganizationalPattern
94
- */
95
- private payloadToPattern;
96
27
  }
97
28
  //# sourceMappingURL=pattern-vector-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pattern-vector-service.d.ts","sourceRoot":"","sources":["../../src/core/pattern-vector-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAkB,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;CAC9C;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,cAAc,CAAc;gBAExB,QAAQ,EAAE,eAAe,EAAE,gBAAgB,CAAC,EAAE,gBAAgB;IAK1E;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCjE;;OAEG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAyBjC;;OAEG;YACW,YAAY;IAkC1B;;OAEG;YACW,iBAAiB;IAqB/B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAmD5B;;OAEG;IACH,aAAa,IAAI;QACf,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IASD;;OAEG;IACG,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAQnE;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAKxD;;OAEG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9C;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IAWzC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAIrC;;OAEG;IACH,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACH,OAAO,CAAC,UAAU;IAYlB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAkC7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IASxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAWzB"}
1
+ {"version":3,"file":"pattern-vector-service.d.ts","sourceRoot":"","sources":["../../src/core/pattern-vector-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE/F,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;CAAG;AAClE,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB,CAAC,qBAAqB,CAAC;CAAG;AAEvF,qBAAa,oBAAqB,SAAQ,iBAAiB,CAAC,qBAAqB,CAAC;gBACpE,QAAQ,CAAC,EAAE,eAAe,EAAE,gBAAgB,CAAC,EAAE,gBAAgB;IAK3E,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM;IAOlE,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM;IAI3D,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAW5E,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,qBAAqB;IAatE,YAAY,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAIjG,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAI7D,cAAc,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAIlD,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;CAG1C"}
@@ -2,301 +2,64 @@
2
2
  /**
3
3
  * Pattern Vector Service
4
4
  *
5
- * Handles pattern-specific Vector DB operations with keyword-based matching
5
+ * Handles pattern-specific Vector DB operations
6
+ * Extends BaseVectorService for organizational patterns
6
7
  */
7
8
  Object.defineProperty(exports, "__esModule", { value: true });
8
9
  exports.PatternVectorService = void 0;
9
- const embedding_service_1 = require("./embedding-service");
10
- class PatternVectorService {
11
- vectorDB;
12
- embeddingService;
13
- collectionName = 'patterns';
10
+ const base_vector_service_1 = require("./base-vector-service");
11
+ class PatternVectorService extends base_vector_service_1.BaseVectorService {
14
12
  constructor(vectorDB, embeddingService) {
15
- this.vectorDB = vectorDB;
16
- this.embeddingService = embeddingService || new embedding_service_1.EmbeddingService();
13
+ super('patterns', vectorDB, embeddingService);
17
14
  }
18
- /**
19
- * Initialize the patterns collection
20
- */
21
- async initialize() {
22
- // Use embedding dimensions if available, otherwise default to 1536 (OpenAI default)
23
- const dimensions = this.embeddingService.isAvailable() ?
24
- this.embeddingService.getDimensions() :
25
- 1536;
26
- await this.vectorDB.initializeCollection(dimensions);
27
- }
28
- /**
29
- * Store a pattern in Vector DB with optional semantic embedding
30
- */
31
- async storePattern(pattern) {
32
- const searchText = this.createSearchText(pattern);
33
- // Try to generate embedding if service is available
34
- let embedding = null;
35
- if (this.embeddingService.isAvailable()) {
36
- try {
37
- embedding = await this.embeddingService.generateEmbedding(searchText);
38
- }
39
- catch (error) {
40
- // Log but don't fail - fall back to keyword-only storage
41
- console.warn('Failed to generate embedding for pattern, using keyword-only storage:', error);
42
- }
43
- }
44
- const document = {
45
- id: pattern.id,
46
- payload: {
47
- description: pattern.description,
48
- triggers: pattern.triggers.map(t => t.toLowerCase()), // Store lowercase for matching
49
- suggestedResources: pattern.suggestedResources,
50
- rationale: pattern.rationale,
51
- createdAt: pattern.createdAt,
52
- createdBy: pattern.createdBy,
53
- searchText: searchText,
54
- // Store embedding status for debugging
55
- hasEmbedding: embedding !== null
56
- },
57
- vector: embedding || undefined // Use real embedding or let VectorDB use zero vector
58
- };
59
- await this.vectorDB.upsertDocument(document);
60
- }
61
- /**
62
- * Search for patterns using hybrid semantic + keyword matching
63
- */
64
- async searchPatterns(query, options = {}) {
65
- // Extract keywords for keyword search
66
- const queryKeywords = this.extractKeywords(query);
67
- if (queryKeywords.length === 0) {
68
- return [];
69
- }
70
- const limit = options.limit || 10;
71
- const scoreThreshold = options.scoreThreshold || 0.1;
72
- // Try semantic search first if embeddings available
73
- if (this.embeddingService.isAvailable()) {
74
- try {
75
- return await this.hybridSearch(query, queryKeywords, { limit, scoreThreshold });
76
- }
77
- catch (error) {
78
- // Fall back to keyword-only search if semantic search fails
79
- console.warn('Semantic search failed, falling back to keyword search:', error);
80
- }
81
- }
82
- // Keyword-only search (fallback or when embeddings not available)
83
- return await this.keywordOnlySearch(queryKeywords, { limit, scoreThreshold });
84
- }
85
- /**
86
- * Hybrid search combining semantic and keyword matching
87
- */
88
- async hybridSearch(query, queryKeywords, options) {
89
- // Generate query embedding
90
- const queryEmbedding = await this.embeddingService.generateEmbedding(query);
91
- if (!queryEmbedding) {
92
- // Fall back to keyword search
93
- return await this.keywordOnlySearch(queryKeywords, options);
94
- }
95
- // Semantic search using vector similarity
96
- const semanticResults = await this.vectorDB.searchSimilar(queryEmbedding, {
97
- limit: options.limit * 2, // Get more candidates for hybrid ranking
98
- scoreThreshold: 0.5 // Lower threshold for semantic similarity
99
- });
100
- // Keyword search
101
- const keywordResults = await this.vectorDB.searchByKeywords(queryKeywords, {
102
- limit: options.limit * 2,
103
- scoreThreshold: 0.1
104
- });
105
- // Combine and rank results
106
- return this.combineHybridResults(semanticResults, keywordResults, queryKeywords, options);
15
+ // Implement abstract methods from BaseVectorService
16
+ createSearchText(pattern) {
17
+ const triggerText = pattern.triggers.join(' ');
18
+ const resourceText = pattern.suggestedResources.join(' ');
19
+ return `${pattern.description} ${triggerText} ${resourceText} ${pattern.rationale}`.toLowerCase();
107
20
  }
108
- /**
109
- * Keyword-only search (fallback when embeddings not available)
110
- */
111
- async keywordOnlySearch(queryKeywords, options) {
112
- const keywordResults = await this.vectorDB.searchByKeywords(queryKeywords, {
113
- limit: options.limit,
114
- scoreThreshold: options.scoreThreshold
115
- });
116
- return keywordResults.map(result => ({
117
- pattern: this.payloadToPattern(result.payload, result.id),
118
- score: this.calculateKeywordScore(queryKeywords, result.payload.triggers || []),
119
- matchType: 'keyword'
120
- }))
121
- .filter(result => result.score > options.scoreThreshold)
122
- .sort((a, b) => b.score - a.score);
21
+ extractId(pattern) {
22
+ return pattern.id;
123
23
  }
124
- /**
125
- * Combine semantic and keyword search results with hybrid ranking
126
- */
127
- combineHybridResults(semanticResults, keywordResults, queryKeywords, options) {
128
- // Create map to avoid duplicates and combine scores
129
- const resultMap = new Map();
130
- // Process semantic results
131
- semanticResults.forEach(result => {
132
- const pattern = this.payloadToPattern(result.payload, result.id);
133
- const semanticScore = result.score; // Cosine similarity from Vector DB
134
- resultMap.set(result.id, {
135
- pattern,
136
- score: semanticScore * 0.7, // Weight semantic score at 70%
137
- matchType: 'semantic'
138
- });
139
- });
140
- // Process keyword results and combine with semantic
141
- keywordResults.forEach(result => {
142
- const pattern = this.payloadToPattern(result.payload, result.id);
143
- const keywordScore = this.calculateKeywordScore(queryKeywords, result.payload.triggers || []);
144
- if (resultMap.has(result.id)) {
145
- // Combine scores for hybrid result
146
- const existing = resultMap.get(result.id);
147
- resultMap.set(result.id, {
148
- pattern,
149
- score: existing.score + (keywordScore * 0.3), // Add 30% keyword weight
150
- matchType: 'hybrid'
151
- });
152
- }
153
- else {
154
- // Keyword-only result - give fair weight, don't penalize
155
- resultMap.set(result.id, {
156
- pattern,
157
- score: keywordScore, // Use full keyword score for keyword-only results
158
- matchType: 'keyword'
159
- });
160
- }
161
- });
162
- // Convert to array, filter, and sort
163
- return Array.from(resultMap.values())
164
- .filter(result => result.score > options.scoreThreshold)
165
- .sort((a, b) => b.score - a.score)
166
- .slice(0, options.limit);
24
+ createPayload(pattern) {
25
+ return {
26
+ description: pattern.description,
27
+ triggers: pattern.triggers.map(t => t.toLowerCase()),
28
+ suggestedResources: pattern.suggestedResources,
29
+ rationale: pattern.rationale,
30
+ createdAt: pattern.createdAt,
31
+ createdBy: pattern.createdBy
32
+ };
167
33
  }
168
- /**
169
- * Get search mode information for debugging
170
- */
171
- getSearchMode() {
172
- const status = this.embeddingService.getStatus();
34
+ payloadToData(payload) {
173
35
  return {
174
- semantic: status.available,
175
- provider: status.provider,
176
- reason: status.reason
36
+ id: '', // Will be set from document ID in base class
37
+ description: payload.description,
38
+ triggers: payload.triggers,
39
+ suggestedResources: payload.suggestedResources,
40
+ rationale: payload.rationale,
41
+ createdAt: payload.createdAt,
42
+ createdBy: payload.createdBy
177
43
  };
178
44
  }
179
- /**
180
- * Get pattern by ID
181
- */
45
+ // Public API methods - delegate to base class with appropriate names
46
+ async storePattern(pattern) {
47
+ await this.storeData(pattern);
48
+ }
49
+ async searchPatterns(query, options = {}) {
50
+ return await this.searchData(query, options);
51
+ }
182
52
  async getPattern(id) {
183
- const document = await this.vectorDB.getDocument(id);
184
- if (!document) {
185
- return null;
186
- }
187
- return this.payloadToPattern(document.payload, document.id);
53
+ return await this.getData(id);
188
54
  }
189
- /**
190
- * Get all patterns
191
- */
192
55
  async getAllPatterns() {
193
- const documents = await this.vectorDB.getAllDocuments();
194
- return documents.map(doc => this.payloadToPattern(doc.payload, doc.id));
56
+ return await this.getAllData();
195
57
  }
196
- /**
197
- * Delete pattern by ID
198
- */
199
58
  async deletePattern(id) {
200
- await this.vectorDB.deleteDocument(id);
59
+ await this.deleteData(id);
201
60
  }
202
- /**
203
- * Get patterns count
204
- */
205
61
  async getPatternsCount() {
206
- try {
207
- const info = await this.vectorDB.getCollectionInfo();
208
- return info.points_count || 0;
209
- }
210
- catch (error) {
211
- // Fallback: get all and count
212
- const patterns = await this.getAllPatterns();
213
- return patterns.length;
214
- }
215
- }
216
- /**
217
- * Health check for pattern storage
218
- */
219
- async healthCheck() {
220
- return await this.vectorDB.healthCheck();
221
- }
222
- /**
223
- * Extract keywords from query text
224
- */
225
- extractKeywords(query) {
226
- // Simple keyword extraction - split on whitespace and punctuation
227
- return query
228
- .toLowerCase()
229
- .replace(/[^\w\s]/g, ' ') // Replace punctuation with spaces
230
- .split(/\s+/)
231
- .filter(word => word.length > 2) // Filter out very short words
232
- .filter(word => !this.isStopWord(word)); // Filter out stop words
233
- }
234
- /**
235
- * Simple stop words list
236
- */
237
- isStopWord(word) {
238
- const stopWords = new Set([
239
- 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with',
240
- 'by', 'is', 'are', 'was', 'were', 'be', 'been', 'have', 'has', 'had',
241
- 'do', 'does', 'did', 'will', 'would', 'could', 'should', 'may', 'might',
242
- 'can', 'this', 'that', 'these', 'those', 'i', 'you', 'he', 'she', 'it',
243
- 'we', 'they', 'me', 'him', 'her', 'us', 'them', 'my', 'your', 'his',
244
- 'our', 'their', 'a', 'an'
245
- ]);
246
- return stopWords.has(word);
247
- }
248
- /**
249
- * Calculate keyword match score
250
- */
251
- calculateKeywordScore(queryKeywords, patternTriggers) {
252
- if (queryKeywords.length === 0 || patternTriggers.length === 0) {
253
- return 0;
254
- }
255
- const lowerTriggers = patternTriggers.map(t => t.toLowerCase());
256
- let matchCount = 0;
257
- let exactMatches = 0;
258
- for (const keyword of queryKeywords) {
259
- // Check for exact matches
260
- if (lowerTriggers.includes(keyword)) {
261
- exactMatches++;
262
- matchCount++;
263
- continue;
264
- }
265
- // Check for partial matches (keyword contains trigger or vice versa)
266
- const hasPartialMatch = lowerTriggers.some(trigger => keyword.includes(trigger) || trigger.includes(keyword));
267
- if (hasPartialMatch) {
268
- matchCount++;
269
- }
270
- }
271
- // Calculate score: exact matches worth more than partial matches
272
- const exactScore = (exactMatches / queryKeywords.length) * 1.0;
273
- const partialScore = ((matchCount - exactMatches) / queryKeywords.length) * 0.5;
274
- return Math.min(exactScore + partialScore, 1.0);
275
- }
276
- /**
277
- * Create searchable text from pattern
278
- */
279
- createSearchText(pattern) {
280
- return [
281
- pattern.description,
282
- ...pattern.triggers,
283
- ...pattern.suggestedResources,
284
- pattern.rationale
285
- ].join(' ').toLowerCase();
286
- }
287
- /**
288
- * Convert Vector DB payload back to OrganizationalPattern
289
- */
290
- payloadToPattern(payload, id) {
291
- return {
292
- id: id || payload.id || '',
293
- description: payload.description || '',
294
- triggers: payload.triggers || [],
295
- suggestedResources: payload.suggestedResources || [],
296
- rationale: payload.rationale || '',
297
- createdAt: payload.createdAt || new Date().toISOString(),
298
- createdBy: payload.createdBy || 'unknown'
299
- };
62
+ return await this.getDataCount();
300
63
  }
301
64
  }
302
65
  exports.PatternVectorService = PatternVectorService;
@@ -315,7 +315,7 @@ class ResourceRecommender {
315
315
  if (concepts.length === 0) {
316
316
  console.warn('⚠️ No concepts extracted, falling back to simple pattern search');
317
317
  const fallbackResults = await this.patternService.searchPatterns(intent, { limit: 5 });
318
- return fallbackResults.map(result => result.pattern);
318
+ return fallbackResults.map(result => result.data);
319
319
  }
320
320
  // Step 2: Find patterns for each concept
321
321
  const allPatternMatches = [];
@@ -326,7 +326,7 @@ class ResourceRecommender {
326
326
  const searchResults = await this.patternService.searchPatterns(conceptKeywords, { limit: 10 });
327
327
  // Convert to PatternMatch with concept context
328
328
  const matches = searchResults.map(result => ({
329
- pattern: result.pattern,
329
+ pattern: result.data,
330
330
  score: result.score * this.getConceptImportanceWeight(concept.importance),
331
331
  matchedConcept: concept,
332
332
  matchType: result.matchType
@@ -11,14 +11,27 @@ import { z } from 'zod';
11
11
  import { DotAI } from '../core/index';
12
12
  import { Logger } from '../core/error-handling';
13
13
  export declare const ORGANIZATIONAL_DATA_TOOL_NAME = "manageOrgData";
14
- export declare const ORGANIZATIONAL_DATA_TOOL_DESCRIPTION = "Manage organizational deployment patterns, templates, standards, and best practices for AI recommendations. Use this tool when user wants to save, create, add, or manage deployment patterns, templates, resource configurations, organizational standards, best practices, or reusable deployment guidelines. This tool uses a step-by-step workflow for creation. IMPORTANT: When user wants to create something, call this tool with operation=create (no other parameters). The tool will return a workflow step with a \"prompt\" field - you must execute that prompt immediately and wait for user response before calling again.";
14
+ export declare const ORGANIZATIONAL_DATA_TOOL_DESCRIPTION = "Unified tool for managing cluster data: organizational patterns (available now), resource capabilities (PRD #48), and resource dependencies (PRD #49). For patterns: supports step-by-step creation workflow. For capabilities/dependencies: returns implementation status. Use dataType parameter to specify what to manage: \"pattern\" for organizational patterns, \"capabilities\" for resource capabilities, \"dependencies\" for resource dependencies.";
15
15
  export declare const ORGANIZATIONAL_DATA_TOOL_INPUT_SCHEMA: {
16
- dataType: z.ZodEnum<["pattern"]>;
17
- operation: z.ZodEnum<["create", "list", "get", "delete"]>;
16
+ dataType: z.ZodEnum<["pattern", "capabilities", "dependencies"]>;
17
+ operation: z.ZodEnum<["create", "list", "get", "delete", "scan", "analyze"]>;
18
18
  sessionId: z.ZodOptional<z.ZodString>;
19
19
  response: z.ZodOptional<z.ZodString>;
20
20
  id: z.ZodOptional<z.ZodString>;
21
21
  limit: z.ZodOptional<z.ZodNumber>;
22
+ resource: z.ZodOptional<z.ZodObject<{
23
+ kind: z.ZodString;
24
+ group: z.ZodString;
25
+ apiVersion: z.ZodString;
26
+ }, "strip", z.ZodTypeAny, {
27
+ kind: string;
28
+ group: string;
29
+ apiVersion: string;
30
+ }, {
31
+ kind: string;
32
+ group: string;
33
+ apiVersion: string;
34
+ }>>;
22
35
  };
23
36
  /**
24
37
  * Main tool handler - routes to appropriate data type handler
@@ -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;AAShD,eAAO,MAAM,6BAA6B,kBAAkB,CAAC;AAC7D,eAAO,MAAM,oCAAoC,8mBAA4mB,CAAC;AAG9pB,eAAO,MAAM,qCAAqC;;;;;;;CAajD,CAAC;AA0XF;;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;AAShD,eAAO,MAAM,6BAA6B,kBAAkB,CAAC;AAC7D,eAAO,MAAM,oCAAoC,mcAA6b,CAAC;AAG/e,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;CAoBjD,CAAC;AA6fF;;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"}
@@ -54,18 +54,24 @@ const fs = __importStar(require("fs"));
54
54
  const path = __importStar(require("path"));
55
55
  // Tool metadata for MCP registration
56
56
  exports.ORGANIZATIONAL_DATA_TOOL_NAME = 'manageOrgData';
57
- exports.ORGANIZATIONAL_DATA_TOOL_DESCRIPTION = 'Manage organizational deployment patterns, templates, standards, and best practices for AI recommendations. Use this tool when user wants to save, create, add, or manage deployment patterns, templates, resource configurations, organizational standards, best practices, or reusable deployment guidelines. This tool uses a step-by-step workflow for creation. IMPORTANT: When user wants to create something, call this tool with operation=create (no other parameters). The tool will return a workflow step with a "prompt" field - you must execute that prompt immediately and wait for user response before calling again.';
58
- // Extensible schema - ready for future data types
57
+ exports.ORGANIZATIONAL_DATA_TOOL_DESCRIPTION = 'Unified tool for managing cluster data: organizational patterns (available now), resource capabilities (PRD #48), and resource dependencies (PRD #49). For patterns: supports step-by-step creation workflow. For capabilities/dependencies: returns implementation status. Use dataType parameter to specify what to manage: "pattern" for organizational patterns, "capabilities" for resource capabilities, "dependencies" for resource dependencies.';
58
+ // Extensible schema - supports patterns, capabilities, and dependencies
59
59
  exports.ORGANIZATIONAL_DATA_TOOL_INPUT_SCHEMA = {
60
- dataType: zod_1.z.enum(['pattern']).describe('Type of organizational data to manage (currently only "pattern" supported)'),
61
- operation: zod_1.z.enum(['create', 'list', 'get', 'delete']).describe('Operation to perform on the organizational data'),
60
+ dataType: zod_1.z.enum(['pattern', 'capabilities', 'dependencies']).describe('Type of cluster data to manage: pattern (organizational patterns), capabilities (resource capabilities), dependencies (resource dependencies)'),
61
+ operation: zod_1.z.enum(['create', 'list', 'get', 'delete', 'scan', 'analyze']).describe('Operation to perform on the cluster data'),
62
62
  // Workflow fields for step-by-step pattern creation
63
63
  sessionId: zod_1.z.string().optional().describe('Pattern creation session ID (for continuing multi-step workflow)'),
64
64
  response: zod_1.z.string().optional().describe('User response to previous workflow step question'),
65
65
  // Generic fields for get/delete operations
66
66
  id: zod_1.z.string().optional().describe('Data item ID (required for get/delete operations)'),
67
67
  // Generic fields for list operations
68
- limit: zod_1.z.number().optional().describe('Maximum number of items to return (default: 10)')
68
+ limit: zod_1.z.number().optional().describe('Maximum number of items to return (default: 10)'),
69
+ // Resource-specific fields (for capabilities and dependencies)
70
+ resource: zod_1.z.object({
71
+ kind: zod_1.z.string(),
72
+ group: zod_1.z.string(),
73
+ apiVersion: zod_1.z.string()
74
+ }).optional().describe('Kubernetes resource reference (for capabilities/dependencies operations)')
69
75
  };
70
76
  /**
71
77
  * Get Vector DB-based pattern service with optional embedding support
@@ -120,6 +126,48 @@ async function validateVectorDBConnection(patternService, logger, requestId) {
120
126
  }
121
127
  return { success: true };
122
128
  }
129
+ /**
130
+ * Validate embedding service configuration and fail if unavailable
131
+ */
132
+ async function validateEmbeddingService(logger, requestId) {
133
+ const { EmbeddingService } = await Promise.resolve().then(() => __importStar(require('../core/embedding-service')));
134
+ const embeddingService = new EmbeddingService();
135
+ const status = embeddingService.getStatus();
136
+ if (!status.available) {
137
+ logger.warn('Embedding service required but not available', {
138
+ requestId,
139
+ reason: status.reason
140
+ });
141
+ return {
142
+ success: false,
143
+ error: {
144
+ message: 'OpenAI API key required for pattern management',
145
+ details: 'Pattern management requires OpenAI embeddings for semantic search and storage. The system cannot proceed without proper configuration.',
146
+ reason: status.reason,
147
+ setup: {
148
+ required: 'export OPENAI_API_KEY=your-openai-api-key',
149
+ optional: [
150
+ 'export OPENAI_MODEL=text-embedding-3-small (default)',
151
+ 'export OPENAI_DIMENSIONS=1536 (default)'
152
+ ],
153
+ docs: 'Get API key from https://platform.openai.com/api-keys'
154
+ },
155
+ currentConfig: {
156
+ OPENAI_API_KEY: process.env.OPENAI_API_KEY ? 'set' : 'not set',
157
+ QDRANT_URL: process.env.QDRANT_URL || 'http://localhost:6333',
158
+ status: 'embedding service unavailable'
159
+ }
160
+ }
161
+ };
162
+ }
163
+ logger.info('Embedding service available', {
164
+ requestId,
165
+ provider: status.provider,
166
+ model: status.model,
167
+ dimensions: status.dimensions
168
+ });
169
+ return { success: true };
170
+ }
123
171
  /**
124
172
  * Handle pattern operations with workflow support
125
173
  */
@@ -136,6 +184,17 @@ async function handlePatternOperation(operation, args, logger, requestId) {
136
184
  message: 'Vector DB connection required for pattern management'
137
185
  };
138
186
  }
187
+ // Validate embedding service and fail if unavailable
188
+ const embeddingCheck = await validateEmbeddingService(logger, requestId);
189
+ if (!embeddingCheck.success) {
190
+ return {
191
+ success: false,
192
+ operation,
193
+ dataType: 'pattern',
194
+ error: embeddingCheck.error,
195
+ message: 'OpenAI API key required for pattern management'
196
+ };
197
+ }
139
198
  const sessionManager = new pattern_creation_session_1.PatternCreationSessionManager();
140
199
  switch (operation) {
141
200
  case 'create': {
@@ -366,6 +425,60 @@ async function handlePatternOperation(operation, args, logger, requestId) {
366
425
  });
367
426
  }
368
427
  }
428
+ /**
429
+ * Handle capabilities operations (placeholder for PRD #48)
430
+ */
431
+ async function handleCapabilitiesOperation(operation, args, logger, requestId) {
432
+ logger.info('Capabilities operation requested', { requestId, operation });
433
+ return {
434
+ success: false,
435
+ operation,
436
+ dataType: 'capabilities',
437
+ error: {
438
+ message: 'Resource capabilities management not yet implemented',
439
+ details: 'This feature is planned for PRD #48 - Resource Capabilities Discovery & Integration',
440
+ status: 'coming-soon',
441
+ implementationPlan: {
442
+ prd: 'PRD #48',
443
+ description: 'Kubernetes resource capability discovery and semantic matching',
444
+ expectedFeatures: [
445
+ 'Cluster resource scanning',
446
+ 'Capability inference from schemas',
447
+ 'Semantic resource matching',
448
+ 'Vector DB storage and search'
449
+ ]
450
+ }
451
+ },
452
+ message: 'Capabilities management will be available after PRD #48 implementation'
453
+ };
454
+ }
455
+ /**
456
+ * Handle dependencies operations (placeholder for PRD #49)
457
+ */
458
+ async function handleDependenciesOperation(operation, args, logger, requestId) {
459
+ logger.info('Dependencies operation requested', { requestId, operation });
460
+ return {
461
+ success: false,
462
+ operation,
463
+ dataType: 'dependencies',
464
+ error: {
465
+ message: 'Resource dependencies management not yet implemented',
466
+ details: 'This feature is planned for PRD #49 - Resource Dependencies Discovery & Integration',
467
+ status: 'coming-soon',
468
+ implementationPlan: {
469
+ prd: 'PRD #49',
470
+ description: 'Resource dependency discovery and complete solution assembly',
471
+ expectedFeatures: [
472
+ 'Dependency relationship discovery',
473
+ 'Complete solution assembly',
474
+ 'Deployment order optimization',
475
+ 'Vector DB storage and search'
476
+ ]
477
+ }
478
+ },
479
+ message: 'Dependencies management will be available after PRD #49 implementation'
480
+ };
481
+ }
369
482
  /**
370
483
  * Main tool handler - routes to appropriate data type handler
371
484
  */
@@ -399,19 +512,18 @@ async function handleOrganizationalDataTool(args, _dotAI, logger, requestId) {
399
512
  case 'pattern':
400
513
  result = await handlePatternOperation(args.operation, args, logger, requestId);
401
514
  break;
402
- // Future data types will be added here:
403
- // case 'policy':
404
- // result = await handlePolicyOperation(args.operation, args, logger, requestId);
405
- // break;
406
- // case 'memory':
407
- // result = await handleMemoryOperation(args.operation, args, logger, requestId);
408
- // break;
515
+ case 'capabilities':
516
+ result = await handleCapabilitiesOperation(args.operation, args, logger, requestId);
517
+ break;
518
+ case 'dependencies':
519
+ result = await handleDependenciesOperation(args.operation, args, logger, requestId);
520
+ break;
409
521
  default:
410
- throw error_handling_1.ErrorHandler.createError(error_handling_1.ErrorCategory.VALIDATION, error_handling_1.ErrorSeverity.HIGH, `Unsupported data type: ${args.dataType}. Currently supported: pattern`, {
522
+ throw error_handling_1.ErrorHandler.createError(error_handling_1.ErrorCategory.VALIDATION, error_handling_1.ErrorSeverity.HIGH, `Unsupported data type: ${args.dataType}. Currently supported: pattern, capabilities, dependencies`, {
411
523
  operation: 'data_type_validation',
412
524
  component: 'OrganizationalDataTool',
413
525
  requestId,
414
- input: { dataType: args.dataType, supportedTypes: ['pattern'] }
526
+ input: { dataType: args.dataType, supportedTypes: ['pattern', 'capabilities', 'dependencies'] }
415
527
  });
416
528
  }
417
529
  logger.info('Organizational-data tool request completed successfully', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vfarcic/dot-ai",
3
- "version": "0.47.0",
3
+ "version": "0.49.0",
4
4
  "description": "Universal Kubernetes application deployment agent with CLI and MCP interfaces",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -30,10 +30,11 @@ Complete the PRD implementation workflow including branch management, pull reque
30
30
  - [ ] **Request reviews**: Assign appropriate team members for code review
31
31
 
32
32
  ### 4. Review and Merge Process
33
- - [ ] **Check PR status**: Use `gh pr view [pr-number]` to check for any ongoing reviews or processes
34
- - [ ] **Wait for completion**: Do NOT merge if PR comments indicate reviews, checks, or processes are still in progress
35
- - [ ] **Address review feedback**: Make any required changes from code review
36
- - [ ] **Verify all checks pass**: Ensure all CI/CD, tests, and automated processes are complete and passing
33
+ - [ ] **Check ongoing processes**: Use `gh pr checks [pr-number]` to check for any ongoing CI/CD, security analysis, or automated reviews (CodeRabbit, CodeQL, etc.)
34
+ - [ ] **Check PR details**: Use `gh pr view [pr-number]` to check for human review comments and PR metadata
35
+ - [ ] **Wait for completion**: Do NOT merge if checks show pending processes or PR comments indicate reviews still in progress
36
+ - [ ] **Address review feedback**: Make any required changes from code review (both automated and human)
37
+ - [ ] **Verify all checks pass**: Ensure all CI/CD, tests, security analysis, and automated processes are complete and passing
37
38
  - [ ] **Merge to main**: Complete the pull request merge only after all feedback addressed and processes complete
38
39
  - [ ] **Verify deployment**: Ensure feature works in production environment
39
40
  - [ ] **Monitor for issues**: Watch for any post-deployment problems