@vfarcic/dot-ai 1.23.1 → 1.24.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 (63) hide show
  1. package/dist/core/index.d.ts +0 -5
  2. package/dist/core/index.d.ts.map +1 -1
  3. package/dist/core/index.js +2 -11
  4. package/dist/core/knowledge-migration.d.ts +30 -0
  5. package/dist/core/knowledge-migration.d.ts.map +1 -0
  6. package/dist/core/knowledge-migration.js +289 -0
  7. package/dist/core/knowledge-service.d.ts +46 -0
  8. package/dist/core/knowledge-service.d.ts.map +1 -0
  9. package/dist/core/knowledge-service.js +185 -0
  10. package/dist/core/knowledge-types.d.ts +14 -0
  11. package/dist/core/knowledge-types.d.ts.map +1 -1
  12. package/dist/core/schema.d.ts +13 -12
  13. package/dist/core/schema.d.ts.map +1 -1
  14. package/dist/core/schema.js +105 -170
  15. package/dist/core/user-prompts-loader.d.ts.map +1 -1
  16. package/dist/core/user-prompts-loader.js +13 -6
  17. package/dist/interfaces/rest-api.d.ts.map +1 -1
  18. package/dist/interfaces/rest-api.js +7 -6
  19. package/dist/mcp/server.js +12 -0
  20. package/dist/tools/manage-knowledge.d.ts +0 -22
  21. package/dist/tools/manage-knowledge.d.ts.map +1 -1
  22. package/dist/tools/manage-knowledge.js +71 -131
  23. package/dist/tools/operate-analysis.d.ts.map +1 -1
  24. package/dist/tools/operate-analysis.js +7 -6
  25. package/dist/tools/operate.d.ts +23 -11
  26. package/dist/tools/operate.d.ts.map +1 -1
  27. package/dist/tools/operate.js +40 -58
  28. package/dist/tools/organizational-data.d.ts +5 -8
  29. package/dist/tools/organizational-data.d.ts.map +1 -1
  30. package/dist/tools/organizational-data.js +19 -74
  31. package/dist/tools/query.d.ts +17 -0
  32. package/dist/tools/query.d.ts.map +1 -1
  33. package/dist/tools/query.js +36 -1
  34. package/dist/tools/version.d.ts +1 -12
  35. package/dist/tools/version.d.ts.map +1 -1
  36. package/dist/tools/version.js +10 -19
  37. package/package.json +2 -2
  38. package/prompts/knowledge-classification.md +24 -0
  39. package/prompts/operate-user.md +7 -8
  40. package/dist/core/organizational-types.d.ts +0 -43
  41. package/dist/core/organizational-types.d.ts.map +0 -1
  42. package/dist/core/organizational-types.js +0 -8
  43. package/dist/core/pattern-operations.d.ts +0 -50
  44. package/dist/core/pattern-operations.d.ts.map +0 -1
  45. package/dist/core/pattern-operations.js +0 -445
  46. package/dist/core/pattern-types.d.ts +0 -8
  47. package/dist/core/pattern-types.d.ts.map +0 -1
  48. package/dist/core/pattern-types.js +0 -8
  49. package/dist/core/pattern-vector-service.d.ts +0 -27
  50. package/dist/core/pattern-vector-service.d.ts.map +0 -1
  51. package/dist/core/pattern-vector-service.js +0 -65
  52. package/dist/core/policy-operations.d.ts +0 -136
  53. package/dist/core/policy-operations.d.ts.map +0 -1
  54. package/dist/core/policy-operations.js +0 -623
  55. package/dist/core/policy-vector-service.d.ts +0 -27
  56. package/dist/core/policy-vector-service.d.ts.map +0 -1
  57. package/dist/core/policy-vector-service.js +0 -64
  58. package/dist/core/unified-creation-session.d.ts +0 -88
  59. package/dist/core/unified-creation-session.d.ts.map +0 -1
  60. package/dist/core/unified-creation-session.js +0 -948
  61. package/dist/core/unified-creation-types.d.ts +0 -68
  62. package/dist/core/unified-creation-types.d.ts.map +0 -1
  63. package/dist/core/unified-creation-types.js +0 -61
@@ -48,6 +48,7 @@ const index_js_1 = require("../core/index.js");
48
48
  const index_js_2 = require("../core/tracing/index.js");
49
49
  const index_js_3 = require("../core/telemetry/index.js");
50
50
  const plugin_registry_js_1 = require("../core/plugin-registry.js");
51
+ const knowledge_migration_js_1 = require("../core/knowledge-migration.js");
51
52
  const mcp_client_registry_js_1 = require("../core/mcp-client-registry.js");
52
53
  const mcp_client_manager_js_1 = require("../core/mcp-client-manager.js");
53
54
  const fs_1 = require("fs");
@@ -156,6 +157,11 @@ async function main() {
156
157
  process.stderr.write(`Background discovery: Plugin '${plugin.name}' now available with ${plugin.tools.length} tool(s)\n`);
157
158
  // Note: Tools are automatically registered via pluginManager's internal maps
158
159
  // The version tool will reflect the updated plugin status
160
+ if (plugin.tools.some((tool) => tool.name === 'vector_store')) {
161
+ (0, knowledge_migration_js_1.runKnowledgeMigration)(new error_handling_js_1.ConsoleLogger('KnowledgeMigration')).catch((err) => {
162
+ process.stderr.write(`Knowledge migration (post-discovery) error: ${err instanceof Error ? err.message : String(err)}\n`);
163
+ });
164
+ }
159
165
  });
160
166
  pluginManager.startBackgroundDiscovery();
161
167
  }
@@ -168,6 +174,12 @@ async function main() {
168
174
  if (pluginConfigs.length > 0) {
169
175
  (0, plugin_registry_js_1.initializePluginRegistry)(pluginManager);
170
176
  }
177
+ // PRD #375: Auto-migrate legacy patterns/policies into unified knowledge-base
178
+ if (pluginConfigs.length > 0) {
179
+ const migrationLogger = new error_handling_js_1.ConsoleLogger('KnowledgeMigration');
180
+ process.stderr.write('Checking for legacy knowledge collections to migrate...\n');
181
+ await (0, knowledge_migration_js_1.runKnowledgeMigration)(migrationLogger);
182
+ }
171
183
  // PRD #358: Initialize MCP client for connecting to external MCP servers
172
184
  const mcpClientLogger = new error_handling_js_1.ConsoleLogger('McpClientManager');
173
185
  const mcpClientManager = new mcp_client_manager_js_1.McpClientManager(mcpClientLogger);
@@ -9,7 +9,6 @@
9
9
  import { z } from 'zod';
10
10
  import { Logger } from '../core/error-handling';
11
11
  import { DotAI } from '../core/index';
12
- import { KnowledgeSearchResultItem } from '../core/knowledge-types';
13
12
  export declare const MANAGE_KNOWLEDGE_TOOL_NAME = "manageKnowledge";
14
13
  export declare const MANAGE_KNOWLEDGE_TOOL_DESCRIPTION: string;
15
14
  export declare const MANAGE_KNOWLEDGE_TOOL_INPUT_SCHEMA: {
@@ -39,27 +38,6 @@ export interface ManageKnowledgeInput {
39
38
  uriFilter?: string;
40
39
  interaction_id?: string;
41
40
  }
42
- /**
43
- * Result type for the reusable search function
44
- */
45
- export interface SearchKnowledgeBaseResult {
46
- success: boolean;
47
- chunks: KnowledgeSearchResultItem[];
48
- totalMatches: number;
49
- error?: string;
50
- }
51
- /**
52
- * Reusable knowledge base search function.
53
- * Can be called from MCP tool handler or HTTP endpoints.
54
- *
55
- * @param params Search parameters
56
- * @returns Search results with chunks or error
57
- */
58
- export declare function searchKnowledgeBase(params: {
59
- query: string;
60
- limit?: number;
61
- uriFilter?: string;
62
- }): Promise<SearchKnowledgeBaseResult>;
63
41
  /**
64
42
  * MCP response format with content array
65
43
  */
@@ -1 +1 @@
1
- {"version":3,"file":"manage-knowledge.d.ts","sourceRoot":"","sources":["../../src/tools/manage-knowledge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAGtC,OAAO,EAIL,yBAAyB,EAE1B,MAAM,yBAAyB,CAAC;AAUjC,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAC5D,eAAO,MAAM,iCAAiC,QAKgB,CAAC;AAG/D,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;CAkC9C,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,aAAa,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAiPD;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,yBAAyB,EAAE,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CA4HrC;AA2ND;;GAEG;AACH,UAAU,eAAe;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAgBD;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,oBAAoB,EAC1B,MAAM,EAAE,KAAK,GAAG,IAAI,EACpB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAiD1B"}
1
+ {"version":3,"file":"manage-knowledge.d.ts","sourceRoot":"","sources":["../../src/tools/manage-knowledge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAuFtC,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAC5D,eAAO,MAAM,iCAAiC,QAKgB,CAAC;AAG/D,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;CAkC9C,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,aAAa,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAwcD;;GAEG;AACH,UAAU,eAAe;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAgBD;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,oBAAoB,EAC1B,MAAM,EAAE,KAAK,GAAG,IAAI,EACpB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAiD1B"}
@@ -9,17 +9,67 @@
9
9
  */
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
11
  exports.MANAGE_KNOWLEDGE_TOOL_INPUT_SCHEMA = exports.MANAGE_KNOWLEDGE_TOOL_DESCRIPTION = exports.MANAGE_KNOWLEDGE_TOOL_NAME = void 0;
12
- exports.searchKnowledgeBase = searchKnowledgeBase;
13
12
  exports.handleManageKnowledgeTool = handleManageKnowledgeTool;
14
13
  const zod_1 = require("zod");
15
14
  const plugin_registry_1 = require("../core/plugin-registry");
16
15
  const embedding_service_1 = require("../core/embedding-service");
17
16
  const request_context_1 = require("../interfaces/request-context");
18
17
  const rbac_1 = require("../core/rbac");
18
+ const ai_provider_factory_1 = require("../core/ai-provider-factory");
19
+ const shared_prompt_loader_1 = require("../core/shared-prompt-loader");
20
+ const knowledge_service_1 = require("../core/knowledge-service");
19
21
  /**
20
- * Collection name for knowledge base chunks in Qdrant
22
+ * Valid classification tags for document content
23
+ * PRD #375: Unified Knowledge Base
21
24
  */
22
- const KNOWLEDGE_COLLECTION = 'knowledge-base';
25
+ const VALID_CLASSIFICATION_TAGS = ['policy', 'pattern'];
26
+ /**
27
+ * Classify a document using AI to determine its content type.
28
+ * Returns a list of applicable tags (["policy"], ["pattern"], ["policy","pattern"], or []).
29
+ *
30
+ * Classification is done on the full document before chunking for better context.
31
+ * The same tags are applied to all chunks from the same document.
32
+ *
33
+ * Fails gracefully: if AI is unavailable or returns unexpected format, returns [].
34
+ *
35
+ * PRD #375: Milestone 2 - AI Classification During Ingestion
36
+ */
37
+ async function classifyDocument(content) {
38
+ // Skip classification for empty content
39
+ if (!content || content.trim().length === 0) {
40
+ return [];
41
+ }
42
+ try {
43
+ const aiProvider = (0, ai_provider_factory_1.createAIProvider)();
44
+ if (!aiProvider.isInitialized()) {
45
+ // AI not configured - gracefully skip classification
46
+ return [];
47
+ }
48
+ const prompt = (0, shared_prompt_loader_1.loadPrompt)('knowledge-classification', {
49
+ documentContent: content,
50
+ });
51
+ const response = await aiProvider.sendMessage(prompt, 'knowledge-classification');
52
+ // Parse the JSON array from AI response
53
+ // AI should return only a JSON array like [] or ["policy"] or ["policy","pattern"]
54
+ const rawContent = response.content.trim();
55
+ // Extract JSON array (handle potential extra text)
56
+ const jsonMatch = rawContent.match(/\[.*?\]/s);
57
+ if (!jsonMatch) {
58
+ return [];
59
+ }
60
+ const parsed = JSON.parse(jsonMatch[0]);
61
+ if (!Array.isArray(parsed)) {
62
+ return [];
63
+ }
64
+ // Filter to only valid classification tags
65
+ const validTags = parsed.filter((tag) => typeof tag === 'string' && VALID_CLASSIFICATION_TAGS.includes(tag));
66
+ return validTags;
67
+ }
68
+ catch {
69
+ // Classification failure is non-blocking — return empty tags
70
+ return [];
71
+ }
72
+ }
23
73
  // Tool metadata for MCP registration
24
74
  exports.MANAGE_KNOWLEDGE_TOOL_NAME = 'manageKnowledge';
25
75
  exports.MANAGE_KNOWLEDGE_TOOL_DESCRIPTION = 'Manage the knowledge base: ingest documents, search with natural language, or delete chunks. ' +
@@ -59,10 +109,6 @@ exports.MANAGE_KNOWLEDGE_TOOL_INPUT_SCHEMA = {
59
109
  .describe('Optional URL prefix to filter search results (e.g., "https://github.com/org/repo/").'),
60
110
  interaction_id: zod_1.z.string().optional().describe('INTERNAL ONLY - Do not populate.'),
61
111
  };
62
- /**
63
- * Plugin name for agentic-tools
64
- */
65
- const PLUGIN_NAME = 'agentic-tools';
66
112
  /**
67
113
  * Create error response matching other tool patterns
68
114
  */
@@ -123,9 +169,15 @@ async function handleIngestOperation(args, logger, requestId) {
123
169
  chunksDeleted: deletedCount,
124
170
  });
125
171
  }
172
+ // Step 1b: AI Classification — classify the full document before chunking
173
+ // Same tags are applied to all chunks from this document (document-level classification)
174
+ // PRD #375: Milestone 2 - AI Classification During Ingestion
175
+ logger.debug('Classifying document with AI', { requestId, uri });
176
+ const documentTags = await classifyDocument(content);
177
+ logger.info('Document classified', { requestId, uri, tags: documentTags });
126
178
  // Step 2: Chunk the document
127
179
  logger.debug('Calling knowledge_chunk plugin tool', { requestId, uri });
128
- const chunkResponse = await (0, plugin_registry_1.invokePluginTool)(PLUGIN_NAME, 'knowledge_chunk', {
180
+ const chunkResponse = await (0, plugin_registry_1.invokePluginTool)(knowledge_service_1.PLUGIN_NAME, 'knowledge_chunk', {
129
181
  content,
130
182
  uri,
131
183
  });
@@ -163,8 +215,8 @@ async function handleIngestOperation(args, logger, requestId) {
163
215
  // Step 3: Initialize collection via plugin
164
216
  const vectorSize = embeddingService.getDimensions();
165
217
  logger.debug('Initializing knowledge collection via plugin', { requestId, vectorSize });
166
- const initResponse = await (0, plugin_registry_1.invokePluginTool)(PLUGIN_NAME, 'collection_initialize', {
167
- collection: KNOWLEDGE_COLLECTION,
218
+ const initResponse = await (0, plugin_registry_1.invokePluginTool)(knowledge_service_1.PLUGIN_NAME, 'collection_initialize', {
219
+ collection: knowledge_service_1.KNOWLEDGE_COLLECTION,
168
220
  vectorSize,
169
221
  createTextIndex: true,
170
222
  });
@@ -197,6 +249,7 @@ async function handleIngestOperation(args, logger, requestId) {
197
249
  ingestedAt,
198
250
  chunkIndex: chunk.chunkIndex,
199
251
  totalChunks: chunk.totalChunks,
252
+ tags: documentTags, // PRD #375: Document-level AI classification tags (same for all chunks)
200
253
  extractedPolicyIds: [],
201
254
  };
202
255
  logger.debug('Storing chunk via plugin', {
@@ -206,8 +259,8 @@ async function handleIngestOperation(args, logger, requestId) {
206
259
  totalChunks: chunk.totalChunks,
207
260
  });
208
261
  // Store via plugin
209
- const storeResponse = await (0, plugin_registry_1.invokePluginTool)(PLUGIN_NAME, 'vector_store', {
210
- collection: KNOWLEDGE_COLLECTION,
262
+ const storeResponse = await (0, plugin_registry_1.invokePluginTool)(knowledge_service_1.PLUGIN_NAME, 'vector_store', {
263
+ collection: knowledge_service_1.KNOWLEDGE_COLLECTION,
211
264
  id: chunk.id,
212
265
  embedding,
213
266
  payload,
@@ -251,124 +304,11 @@ async function handleIngestOperation(args, logger, requestId) {
251
304
  });
252
305
  }
253
306
  }
254
- /**
255
- * Default limit for search results
256
- */
257
- const DEFAULT_SEARCH_LIMIT = 20;
258
- /**
259
- * Reusable knowledge base search function.
260
- * Can be called from MCP tool handler or HTTP endpoints.
261
- *
262
- * @param params Search parameters
263
- * @returns Search results with chunks or error
264
- */
265
- async function searchKnowledgeBase(params) {
266
- const { query, limit = DEFAULT_SEARCH_LIMIT, uriFilter } = params;
267
- // Check plugin availability
268
- if (!(0, plugin_registry_1.isPluginInitialized)()) {
269
- return {
270
- success: false,
271
- chunks: [],
272
- totalMatches: 0,
273
- error: 'Plugin system not available',
274
- };
275
- }
276
- // Check embedding service availability
277
- const embeddingService = new embedding_service_1.EmbeddingService();
278
- if (!embeddingService.isAvailable()) {
279
- const status = embeddingService.getStatus();
280
- return {
281
- success: false,
282
- chunks: [],
283
- totalMatches: 0,
284
- error: `Embedding service not available: ${status.reason}`,
285
- };
286
- }
287
- // Generate embedding for the search query
288
- const queryEmbedding = await embeddingService.generateEmbedding(query);
289
- // Build filter if uriFilter is provided
290
- let filter;
291
- if (uriFilter) {
292
- filter = {
293
- must: [
294
- {
295
- key: 'uri',
296
- match: {
297
- value: uriFilter,
298
- },
299
- },
300
- ],
301
- };
302
- }
303
- // Call vector_search plugin tool
304
- const searchResponse = await (0, plugin_registry_1.invokePluginTool)(PLUGIN_NAME, 'vector_search', {
305
- collection: KNOWLEDGE_COLLECTION,
306
- embedding: queryEmbedding,
307
- limit,
308
- filter,
309
- scoreThreshold: 0, // Return all results up to limit, let consumer filter by score
310
- });
311
- if (!searchResponse.success) {
312
- const error = searchResponse.error;
313
- const errorMessage = error?.message || error?.error || 'Search failed';
314
- // If collection doesn't exist (Not Found), return empty result (not error)
315
- if (errorMessage.includes('Not Found') || errorMessage.includes('not found')) {
316
- return {
317
- success: true,
318
- chunks: [],
319
- totalMatches: 0,
320
- };
321
- }
322
- return {
323
- success: false,
324
- chunks: [],
325
- totalMatches: 0,
326
- error: errorMessage,
327
- };
328
- }
329
- // Extract results from plugin response
330
- const searchResult = searchResponse.result;
331
- if (!searchResult.success) {
332
- const errorMessage = searchResult.error || searchResult.message;
333
- // If collection doesn't exist, return empty result (not error)
334
- if (errorMessage.includes('Not Found') || errorMessage.includes('not found')) {
335
- return {
336
- success: true,
337
- chunks: [],
338
- totalMatches: 0,
339
- };
340
- }
341
- return {
342
- success: false,
343
- chunks: [],
344
- totalMatches: 0,
345
- error: errorMessage,
346
- };
347
- }
348
- // Transform results to KnowledgeSearchResultItem format
349
- const results = searchResult.data || [];
350
- const chunks = results.map((result) => ({
351
- id: result.id,
352
- content: result.payload.content,
353
- score: result.score,
354
- matchType: 'semantic', // Dense vector search only (BM25 deferred)
355
- uri: result.payload.uri,
356
- metadata: result.payload.metadata || {},
357
- chunkIndex: result.payload.chunkIndex,
358
- totalChunks: result.payload.totalChunks,
359
- extractedPolicies: undefined, // Populated by PRD #357
360
- }));
361
- return {
362
- success: true,
363
- chunks,
364
- totalMatches: chunks.length,
365
- };
366
- }
367
307
  /**
368
308
  * Handle the search operation (MCP tool handler)
369
309
  */
370
310
  async function handleSearchOperation(args, logger, requestId) {
371
- const { query, limit = DEFAULT_SEARCH_LIMIT, uriFilter } = args;
311
+ const { query, limit = knowledge_service_1.DEFAULT_SEARCH_LIMIT, uriFilter } = args;
372
312
  // Validate required parameters
373
313
  if (!query) {
374
314
  return createErrorResponse('Missing required parameter: query', {
@@ -384,7 +324,7 @@ async function handleSearchOperation(args, logger, requestId) {
384
324
  });
385
325
  try {
386
326
  // Use the reusable search function
387
- const searchResult = await searchKnowledgeBase({ query, limit, uriFilter });
327
+ const searchResult = await (0, knowledge_service_1.searchKnowledgeBase)({ query, limit, uriFilter });
388
328
  if (!searchResult.success) {
389
329
  logger.error('Knowledge base search failed', new Error(searchResult.error), { requestId });
390
330
  return createErrorResponse('Search failed', {
@@ -433,8 +373,8 @@ async function handleSearchOperation(args, logger, requestId) {
433
373
  */
434
374
  async function deleteChunksByUri(uri, logger, requestId) {
435
375
  // Query all chunks matching the URI
436
- const queryResponse = await (0, plugin_registry_1.invokePluginTool)(PLUGIN_NAME, 'vector_query', {
437
- collection: KNOWLEDGE_COLLECTION,
376
+ const queryResponse = await (0, plugin_registry_1.invokePluginTool)(knowledge_service_1.PLUGIN_NAME, 'vector_query', {
377
+ collection: knowledge_service_1.KNOWLEDGE_COLLECTION,
438
378
  filter: {
439
379
  must: [{ key: 'uri', match: { value: uri } }],
440
380
  },
@@ -471,8 +411,8 @@ async function deleteChunksByUri(uri, logger, requestId) {
471
411
  let deletedCount = 0;
472
412
  for (const chunk of chunksToDelete) {
473
413
  logger.debug('Deleting chunk', { requestId, chunkId: chunk.id });
474
- const deleteResponse = await (0, plugin_registry_1.invokePluginTool)(PLUGIN_NAME, 'vector_delete', {
475
- collection: KNOWLEDGE_COLLECTION,
414
+ const deleteResponse = await (0, plugin_registry_1.invokePluginTool)(knowledge_service_1.PLUGIN_NAME, 'vector_delete', {
415
+ collection: knowledge_service_1.KNOWLEDGE_COLLECTION,
476
416
  id: chunk.id,
477
417
  });
478
418
  if (!deleteResponse.success) {
@@ -1 +1 @@
1
- {"version":3,"file":"operate-analysis.d.ts","sourceRoot":"","sources":["../../src/tools/operate-analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGvD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAIhD,OAAO,EAEL,kBAAkB,EAElB,eAAe,EAKhB,MAAM,WAAW,CAAC;AAwBnB;;GAEG;AACH,UAAU,qBAAqB;IAC7B,MAAM,EAAE,wBAAwB,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,eAAe,CAAC;QACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,gBAAgB,EAAE;YAChB,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;YAC7B,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC3B,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,KAAK,EAAE;YACL,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;YACjC,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,qBAAqB,CAAC,kBAAkB,CAAC,EACzD,aAAa,EAAE,aAAa,EAC5B,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,qBAAqB,CAAC,CA2DhC"}
1
+ {"version":3,"file":"operate-analysis.d.ts","sourceRoot":"","sources":["../../src/tools/operate-analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGvD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAIhD,OAAO,EAEL,kBAAkB,EAElB,eAAe,EAIhB,MAAM,WAAW,CAAC;AAwBnB;;GAEG;AACH,UAAU,qBAAqB;IAC7B,MAAM,EAAE,wBAAwB,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,eAAe,CAAC;QACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,gBAAgB,EAAE;YAChB,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;YAC7B,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC3B,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,KAAK,EAAE;YACL,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;YACjC,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,qBAAqB,CAAC,kBAAkB,CAAC,EACzD,aAAa,EAAE,aAAa,EAC5B,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,qBAAqB,CAAC,CA2DhC"}
@@ -65,19 +65,20 @@ function loadSystemPrompt() {
65
65
  return (0, shared_prompt_loader_1.loadPrompt)('operate-system');
66
66
  }
67
67
  /**
68
- * Builds dynamic user message with intent and embedded context
69
- * Uses template from prompts/operate-user.md and formatting functions from operate.ts
68
+ * Builds dynamic user message with intent and embedded context.
69
+ * Uses template from prompts/operate-user.md and formatting functions from operate.ts.
70
+ *
71
+ * PRD #375: Unified Knowledge Base — uses single knowledgeContext instead of
72
+ * separate patterns/policies sections.
70
73
  */
71
74
  function buildUserMessage(intent, context) {
72
75
  // Format context sections using shared formatting functions
73
- const patternsText = (0, operate_1.formatPatterns)(context.patterns);
74
- const policiesText = (0, operate_1.formatPolicies)(context.policies);
76
+ const knowledgeContextText = (0, operate_1.formatKnowledgeContext)(context.knowledgeChunks);
75
77
  const capabilitiesText = (0, operate_1.formatCapabilities)(context.capabilities);
76
78
  // Use loadPrompt with Handlebars template variables
77
79
  return (0, shared_prompt_loader_1.loadPrompt)('operate-user', {
78
80
  intent,
79
- patterns: patternsText,
80
- policies: policiesText,
81
+ knowledgeContext: knowledgeContextText,
81
82
  capabilities: capabilitiesText,
82
83
  });
83
84
  }
@@ -4,7 +4,7 @@
4
4
  import { z } from 'zod';
5
5
  import { Logger } from '../core/error-handling';
6
6
  import { PluginManager } from '../core/plugin-manager';
7
- import { OrganizationalPattern, PolicyIntent } from '../core/organizational-types';
7
+ import { KnowledgeSearchResultItem } from '../core/knowledge-types';
8
8
  import { ResourceCapability } from '../core/capabilities';
9
9
  import { BaseVisualizationData } from '../core/visualization';
10
10
  export declare const OPERATE_TOOL_NAME = "operate";
@@ -51,9 +51,15 @@ export type OperateSession = {
51
51
  updatedAt: string;
52
52
  data: OperateSessionData;
53
53
  };
54
+ /**
55
+ * Embedded context for operate analysis.
56
+ * PRD #375: Unified Knowledge Base — patterns and policies are now unified
57
+ * in the knowledge-base collection. knowledgeChunks replaces separate
58
+ * patterns[] and policies[] fields. Chunks include tags for type identification.
59
+ */
54
60
  export interface EmbeddedContext {
55
- patterns: OrganizationalPattern[];
56
- policies: PolicyIntent[];
61
+ /** Knowledge chunks from unified knowledge base (includes policy, pattern, and general content) */
62
+ knowledgeChunks: KnowledgeSearchResultItem[];
57
63
  capabilities: ResourceCapability[];
58
64
  }
59
65
  export interface ProposedChanges {
@@ -106,20 +112,26 @@ export interface OperateOutput {
106
112
  agentInstructions?: string;
107
113
  }
108
114
  /**
109
- * Embed context (patterns, policies, capabilities) for AI analysis
115
+ * Embed context (knowledge, capabilities) for AI analysis.
116
+ *
117
+ * PRD #375: Unified Knowledge Base — searches single knowledge-base collection
118
+ * instead of separate pattern/policy collections. Results include tags so the
119
+ * AI can distinguish policy, pattern, and general knowledge content.
120
+ *
110
121
  * @param intent User's operational intent
111
- * @returns Embedded context with patterns, policies, and capabilities
122
+ * @param logger Logger instance
123
+ * @returns Embedded context with knowledge chunks and capabilities
112
124
  * @throws Error if capabilities are not available (mandatory)
113
125
  */
114
126
  export declare function embedContext(intent: string, logger: Logger): Promise<EmbeddedContext>;
115
127
  /**
116
- * Format patterns for template placeholder
117
- */
118
- export declare function formatPatterns(patterns: OrganizationalPattern[]): string;
119
- /**
120
- * Format policies for template placeholder
128
+ * Format knowledge chunks for template placeholder.
129
+ *
130
+ * PRD #375: Unified Knowledge Base — replaces separate formatPatterns/formatPolicies.
131
+ * Chunks include tags so the AI can interpret what type each result represents.
132
+ * Tags: "policy" = enforcement rule, "pattern" = reusable architecture, [] = general content.
121
133
  */
122
- export declare function formatPolicies(policies: PolicyIntent[]): string;
134
+ export declare function formatKnowledgeContext(chunks: KnowledgeSearchResultItem[]): string;
123
135
  /**
124
136
  * Format capabilities for template placeholder
125
137
  * Capabilities are already ordered by relevance from vector search
@@ -1 +1 @@
1
- {"version":3,"file":"operate.d.ts","sourceRoot":"","sources":["../../src/tools/operate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"operate.d.ts","sourceRoot":"","sources":["../../src/tools/operate.ts"],"names":[],"mappings":"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"}
@@ -38,8 +38,7 @@ var __importStar = (this && this.__importStar) || (function () {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.OPERATE_TOOL_INPUT_SCHEMA = exports.OPERATE_TOOL_DESCRIPTION = exports.OPERATE_TOOL_NAME = void 0;
40
40
  exports.embedContext = embedContext;
41
- exports.formatPatterns = formatPatterns;
42
- exports.formatPolicies = formatPolicies;
41
+ exports.formatKnowledgeContext = formatKnowledgeContext;
43
42
  exports.formatCapabilities = formatCapabilities;
44
43
  exports.operate = operate;
45
44
  exports.handleOperateTool = handleOperateTool;
@@ -48,9 +47,8 @@ const error_handling_1 = require("../core/error-handling");
48
47
  const generic_session_manager_1 = require("../core/generic-session-manager");
49
48
  const request_context_1 = require("../interfaces/request-context");
50
49
  const rbac_1 = require("../core/rbac");
51
- const pattern_vector_service_1 = require("../core/pattern-vector-service");
52
- const policy_vector_service_1 = require("../core/policy-vector-service");
53
50
  const capability_vector_service_1 = require("../core/capability-vector-service");
51
+ const knowledge_service_1 = require("../core/knowledge-service");
54
52
  const index_1 = require("../core/index");
55
53
  // Tool metadata for direct MCP registration
56
54
  exports.OPERATE_TOOL_NAME = 'operate';
@@ -89,43 +87,41 @@ const sessionManager = new generic_session_manager_1.GenericSessionManager('opr'
89
87
  // Initialize logger
90
88
  const logger = new error_handling_1.ConsoleLogger('OperateTool');
91
89
  /**
92
- * Embed context (patterns, policies, capabilities) for AI analysis
90
+ * Embed context (knowledge, capabilities) for AI analysis.
91
+ *
92
+ * PRD #375: Unified Knowledge Base — searches single knowledge-base collection
93
+ * instead of separate pattern/policy collections. Results include tags so the
94
+ * AI can distinguish policy, pattern, and general knowledge content.
95
+ *
93
96
  * @param intent User's operational intent
94
- * @returns Embedded context with patterns, policies, and capabilities
97
+ * @param logger Logger instance
98
+ * @returns Embedded context with knowledge chunks and capabilities
95
99
  * @throws Error if capabilities are not available (mandatory)
96
100
  */
97
101
  async function embedContext(intent, logger) {
98
102
  const context = {
99
- patterns: [],
100
- policies: [],
103
+ knowledgeChunks: [],
101
104
  capabilities: [],
102
105
  };
103
- // Search for relevant patterns (optional - non-blocking)
106
+ // Search unified knowledge base (optional - non-blocking)
107
+ // Results include tags so AI can see which are policies, patterns, or general content
104
108
  try {
105
- const patternService = new pattern_vector_service_1.PatternVectorService();
106
- const patternResults = await patternService.searchPatterns(intent, {
107
- limit: 5,
108
- });
109
- context.patterns = patternResults.map(result => result.data);
110
- logger.info(`Found ${context.patterns.length} relevant organizational patterns`);
109
+ const knowledgeResult = await (0, knowledge_service_1.searchKnowledgeBase)({ query: intent, limit: 20 });
110
+ if (knowledgeResult.success) {
111
+ context.knowledgeChunks = knowledgeResult.chunks;
112
+ logger.info(`Found ${context.knowledgeChunks.length} relevant knowledge chunks (unified knowledge base)`);
113
+ }
114
+ else {
115
+ logger.warn('Knowledge base search failed, continuing without organizational context', {
116
+ error: knowledgeResult.error,
117
+ });
118
+ }
111
119
  }
112
120
  catch (error) {
113
- logger.warn('Pattern search failed, continuing without patterns', {
121
+ logger.warn('Knowledge base search failed, continuing without organizational context', {
114
122
  error,
115
123
  });
116
124
  }
117
- // Search for relevant policies (optional - non-blocking)
118
- try {
119
- const policyService = new policy_vector_service_1.PolicyVectorService();
120
- const policyResults = await policyService.searchPolicyIntents(intent, {
121
- limit: 5,
122
- });
123
- context.policies = policyResults.map(result => result.data);
124
- logger.info(`Found ${context.policies.length} relevant organizational policies`);
125
- }
126
- catch (error) {
127
- logger.warn('Policy search failed, continuing without policies', { error });
128
- }
129
125
  // Search for relevant cluster capabilities (MANDATORY)
130
126
  try {
131
127
  // Use QDRANT_CAPABILITIES_COLLECTION env var for collection name
@@ -157,39 +153,25 @@ async function embedContext(intent, logger) {
157
153
  return context;
158
154
  }
159
155
  /**
160
- * Format patterns for template placeholder
161
- */
162
- function formatPatterns(patterns) {
163
- if (patterns.length === 0) {
164
- return 'No organizational patterns found matching this intent.';
165
- }
166
- let formatted = '';
167
- patterns.forEach((pattern, index) => {
168
- formatted += `### Pattern ${index + 1}: ${pattern.description}\n\n`;
169
- formatted += `**Triggers:** ${pattern.triggers.join(', ')}\n\n`;
170
- formatted += `**Suggested Resources:** ${pattern.suggestedResources.join(', ')}\n\n`;
171
- formatted += `**Rationale:** ${pattern.rationale}\n\n`;
172
- if (index < patterns.length - 1) {
173
- formatted += '---\n\n';
174
- }
175
- });
176
- return formatted;
177
- }
178
- /**
179
- * Format policies for template placeholder
156
+ * Format knowledge chunks for template placeholder.
157
+ *
158
+ * PRD #375: Unified Knowledge Base — replaces separate formatPatterns/formatPolicies.
159
+ * Chunks include tags so the AI can interpret what type each result represents.
160
+ * Tags: "policy" = enforcement rule, "pattern" = reusable architecture, [] = general content.
180
161
  */
181
- function formatPolicies(policies) {
182
- if (policies.length === 0) {
183
- return 'No organizational policies found matching this intent.';
162
+ function formatKnowledgeContext(chunks) {
163
+ if (chunks.length === 0) {
164
+ return 'No relevant organizational knowledge found matching this intent.';
184
165
  }
185
166
  let formatted = '';
186
- policies.forEach((policy, index) => {
187
- formatted += `### Policy ${index + 1}: ${policy.description}\n\n`;
188
- if (policy.triggers && policy.triggers.length > 0) {
189
- formatted += `**Applies to:** ${policy.triggers.join(', ')}\n\n`;
190
- }
191
- formatted += `**Rationale:** ${policy.rationale}\n\n`;
192
- if (index < policies.length - 1) {
167
+ chunks.forEach((chunk, index) => {
168
+ const typeLabel = chunk.tags.length > 0
169
+ ? chunk.tags.map(t => t.charAt(0).toUpperCase() + t.slice(1)).join(' + ')
170
+ : 'General';
171
+ formatted += `### Knowledge ${index + 1} [${typeLabel}]\n\n`;
172
+ formatted += `**Source:** ${chunk.uri}\n\n`;
173
+ formatted += (chunk.content.length > 300 ? chunk.content.substring(0, 300) + '...' : chunk.content) + '\n\n';
174
+ if (index < chunks.length - 1) {
193
175
  formatted += '---\n\n';
194
176
  }
195
177
  });