@vfarcic/dot-ai 0.172.0 → 0.174.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/core/base-vector-service.d.ts +6 -0
- package/dist/core/base-vector-service.d.ts.map +1 -1
- package/dist/core/base-vector-service.js +13 -0
- package/dist/core/capability-tools.d.ts +38 -0
- package/dist/core/capability-tools.d.ts.map +1 -0
- package/dist/core/capability-tools.js +202 -0
- package/dist/core/resource-tools.d.ts +38 -0
- package/dist/core/resource-tools.d.ts.map +1 -0
- package/dist/core/resource-tools.js +216 -0
- package/dist/core/resource-vector-service.d.ts +12 -0
- package/dist/core/resource-vector-service.d.ts.map +1 -1
- package/dist/core/resource-vector-service.js +16 -5
- package/dist/core/tracing/qdrant-tracing.d.ts +1 -1
- package/dist/core/tracing/qdrant-tracing.d.ts.map +1 -1
- package/dist/core/vector-db-service.d.ts +6 -0
- package/dist/core/vector-db-service.d.ts.map +1 -1
- package/dist/core/vector-db-service.js +32 -0
- package/dist/interfaces/mcp.d.ts.map +1 -1
- package/dist/interfaces/mcp.js +10 -2
- package/dist/interfaces/resource-sync-handler.d.ts.map +1 -1
- package/dist/interfaces/resource-sync-handler.js +4 -1
- package/dist/interfaces/rest-api.d.ts.map +1 -1
- package/dist/interfaces/rest-api.js +3 -2
- package/dist/tools/query.d.ts +34 -0
- package/dist/tools/query.d.ts.map +1 -0
- package/dist/tools/query.js +209 -0
- package/package.json +1 -1
- package/prompts/query-system.md +15 -0
- package/scripts/crossplane.nu +8 -58
- package/scripts/dot-ai.nu +23 -9
- package/shared-prompts/prd-create.md +6 -2
package/README.md
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
DevOps AI Toolkit brings AI-powered intelligence to platform engineering, Kubernetes operations, and development workflows. Built on the Model Context Protocol (MCP), it integrates seamlessly with Claude Code, Cursor, and VS Code.
|
|
34
34
|
|
|
35
35
|
**Key capabilities:**
|
|
36
|
+
- Natural language cluster querying and exploration
|
|
36
37
|
- Intelligent Kubernetes deployment recommendations
|
|
37
38
|
- AI-powered issue remediation and root cause analysis
|
|
38
39
|
- Organizational pattern and policy management
|
|
@@ -57,6 +57,12 @@ export declare abstract class BaseVectorService<T> {
|
|
|
57
57
|
* Delete all data (recreate collection)
|
|
58
58
|
*/
|
|
59
59
|
deleteAllData(): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Query data with Qdrant filter (no semantic search)
|
|
62
|
+
* @param filter - Qdrant filter object constructed by AI
|
|
63
|
+
* @param limit - Maximum results to return
|
|
64
|
+
*/
|
|
65
|
+
queryWithFilter(filter: any, limit?: number): Promise<T[]>;
|
|
60
66
|
/**
|
|
61
67
|
* Get all data (limited)
|
|
62
68
|
*/
|
|
@@ -1 +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"}
|
|
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;;;;OAIG;IACG,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,GAAE,MAAY,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IASrE;;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"}
|
|
@@ -118,6 +118,19 @@ class BaseVectorService {
|
|
|
118
118
|
async deleteAllData() {
|
|
119
119
|
await this.vectorDB.deleteAllDocuments();
|
|
120
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Query data with Qdrant filter (no semantic search)
|
|
123
|
+
* @param filter - Qdrant filter object constructed by AI
|
|
124
|
+
* @param limit - Maximum results to return
|
|
125
|
+
*/
|
|
126
|
+
async queryWithFilter(filter, limit = 100) {
|
|
127
|
+
const documents = await this.vectorDB.scrollWithFilter(filter, limit);
|
|
128
|
+
return documents.map(doc => {
|
|
129
|
+
const data = this.payloadToData(doc.payload);
|
|
130
|
+
data.id = doc.id;
|
|
131
|
+
return data;
|
|
132
|
+
});
|
|
133
|
+
}
|
|
121
134
|
/**
|
|
122
135
|
* Get all data (limited)
|
|
123
136
|
*/
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability Tools for AI-Powered Cluster Intelligence
|
|
3
|
+
*
|
|
4
|
+
* Shared tool definitions and executor for capability vector DB operations.
|
|
5
|
+
* Used by query, recommend, and other cluster intelligence workflows.
|
|
6
|
+
*
|
|
7
|
+
* PRD #291: Cluster Query Tool - Natural Language Cluster Intelligence
|
|
8
|
+
*/
|
|
9
|
+
import { AITool } from './ai-provider.interface';
|
|
10
|
+
/**
|
|
11
|
+
* Tool: search_capabilities
|
|
12
|
+
* Semantic search for cluster capabilities by intent/concept
|
|
13
|
+
*/
|
|
14
|
+
export declare const SEARCH_CAPABILITIES_TOOL: AITool;
|
|
15
|
+
/**
|
|
16
|
+
* Tool: query_capabilities
|
|
17
|
+
* Filter-based query for capabilities using Qdrant filter syntax
|
|
18
|
+
*/
|
|
19
|
+
export declare const QUERY_CAPABILITIES_TOOL: AITool;
|
|
20
|
+
/**
|
|
21
|
+
* All capability tools for cluster intelligence
|
|
22
|
+
* Convenient array for passing to toolLoop()
|
|
23
|
+
*/
|
|
24
|
+
export declare const CAPABILITY_TOOLS: AITool[];
|
|
25
|
+
/**
|
|
26
|
+
* Tool executor for capability-based tools
|
|
27
|
+
* Handles execution and error handling for all capability tool calls
|
|
28
|
+
*
|
|
29
|
+
* @param toolName - Name of the tool to execute
|
|
30
|
+
* @param input - Tool input parameters
|
|
31
|
+
* @returns Tool execution result
|
|
32
|
+
*/
|
|
33
|
+
export declare function executeCapabilityTools(toolName: string, input: any): Promise<any>;
|
|
34
|
+
/**
|
|
35
|
+
* Reset the capability service (useful for testing)
|
|
36
|
+
*/
|
|
37
|
+
export declare function resetCapabilityService(): void;
|
|
38
|
+
//# sourceMappingURL=capability-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-tools.d.ts","sourceRoot":"","sources":["../../src/core/capability-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGjD;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAwBtC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAkCrC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,EAGpC,CAAC;AAsBF;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAwFvF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Capability Tools for AI-Powered Cluster Intelligence
|
|
4
|
+
*
|
|
5
|
+
* Shared tool definitions and executor for capability vector DB operations.
|
|
6
|
+
* Used by query, recommend, and other cluster intelligence workflows.
|
|
7
|
+
*
|
|
8
|
+
* PRD #291: Cluster Query Tool - Natural Language Cluster Intelligence
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.CAPABILITY_TOOLS = exports.QUERY_CAPABILITIES_TOOL = exports.SEARCH_CAPABILITIES_TOOL = void 0;
|
|
12
|
+
exports.executeCapabilityTools = executeCapabilityTools;
|
|
13
|
+
exports.resetCapabilityService = resetCapabilityService;
|
|
14
|
+
const capability_vector_service_1 = require("./capability-vector-service");
|
|
15
|
+
/**
|
|
16
|
+
* Tool: search_capabilities
|
|
17
|
+
* Semantic search for cluster capabilities by intent/concept
|
|
18
|
+
*/
|
|
19
|
+
exports.SEARCH_CAPABILITIES_TOOL = {
|
|
20
|
+
name: 'search_capabilities',
|
|
21
|
+
description: `Semantic search for cluster capabilities. Use this to find what KINDS of resources relate to a concept (e.g., "database" returns StatefulSet, CNPG Cluster, Crossplane RDS). Returns capability definitions with semantic meaning, not actual resource instances.
|
|
22
|
+
|
|
23
|
+
This tool is essential for the "semantic bridge" pattern:
|
|
24
|
+
1. User asks about a concept (e.g., "databases", "message queues", "web servers")
|
|
25
|
+
2. This tool finds which resource KINDS relate to that concept
|
|
26
|
+
3. Then use query_resources or kubectl_get to find actual instances of those kinds
|
|
27
|
+
|
|
28
|
+
Example: "database" might return capabilities for StatefulSet, clusters.postgresql.cnpg.io, compositions.apiextensions.crossplane.io (RDS), etc.`,
|
|
29
|
+
inputSchema: {
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: {
|
|
32
|
+
query: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
description: 'Semantic search query (e.g., "database", "message queue", "web server", "monitoring", "ingress controller")'
|
|
35
|
+
},
|
|
36
|
+
limit: {
|
|
37
|
+
type: 'number',
|
|
38
|
+
description: 'Maximum results to return (default: 10)'
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
required: ['query']
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Tool: query_capabilities
|
|
46
|
+
* Filter-based query for capabilities using Qdrant filter syntax
|
|
47
|
+
*/
|
|
48
|
+
exports.QUERY_CAPABILITIES_TOOL = {
|
|
49
|
+
name: 'query_capabilities',
|
|
50
|
+
description: `Query capabilities using Qdrant filter syntax. Use this when you need to filter by specific fields like provider, complexity, or group - NOT for semantic/conceptual searches.
|
|
51
|
+
|
|
52
|
+
Available payload fields for filtering:
|
|
53
|
+
- resourceName: string (e.g., "Deployment", "StatefulSet", "Cluster")
|
|
54
|
+
- group: string (e.g., "apps", "postgresql.cnpg.io", "apiextensions.crossplane.io")
|
|
55
|
+
- apiVersion: string (e.g., "apps/v1", "postgresql.cnpg.io/v1")
|
|
56
|
+
- providers: string[] (e.g., ["kubernetes", "crossplane", "cnpg"])
|
|
57
|
+
- complexity: string ("low", "medium", "high")
|
|
58
|
+
- capabilities: string[] (e.g., ["stateless-workload", "database", "networking"])
|
|
59
|
+
- abstractions: string[] (e.g., ["container", "pod", "service"])
|
|
60
|
+
- description: string (human-readable description)
|
|
61
|
+
- useCase: string (recommended use cases)
|
|
62
|
+
|
|
63
|
+
Qdrant filter syntax examples:
|
|
64
|
+
- Filter by complexity: { "must": [{ "key": "complexity", "match": { "value": "low" } }] }
|
|
65
|
+
- Filter by provider: { "must": [{ "key": "providers", "match": { "any": ["crossplane"] } }] }
|
|
66
|
+
- Filter by group: { "must": [{ "key": "group", "match": { "value": "postgresql.cnpg.io" } }] }
|
|
67
|
+
- Combined filter: { "must": [{ "key": "complexity", "match": { "value": "low" } }, { "key": "providers", "match": { "any": ["kubernetes"] } }] }`,
|
|
68
|
+
inputSchema: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: {
|
|
71
|
+
filter: {
|
|
72
|
+
type: 'object',
|
|
73
|
+
description: 'Qdrant filter object with must/should/must_not conditions'
|
|
74
|
+
},
|
|
75
|
+
limit: {
|
|
76
|
+
type: 'number',
|
|
77
|
+
description: 'Maximum results to return (default: 100)'
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
required: ['filter']
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* All capability tools for cluster intelligence
|
|
85
|
+
* Convenient array for passing to toolLoop()
|
|
86
|
+
*/
|
|
87
|
+
exports.CAPABILITY_TOOLS = [
|
|
88
|
+
exports.SEARCH_CAPABILITIES_TOOL,
|
|
89
|
+
exports.QUERY_CAPABILITIES_TOOL
|
|
90
|
+
];
|
|
91
|
+
/**
|
|
92
|
+
* Shared CapabilityVectorService instance for tool execution
|
|
93
|
+
* Initialized lazily on first use
|
|
94
|
+
*/
|
|
95
|
+
let capabilityService = null;
|
|
96
|
+
/**
|
|
97
|
+
* Get or create the capability vector service
|
|
98
|
+
* Uses lazy initialization to avoid startup errors when Qdrant isn't ready
|
|
99
|
+
* Respects QDRANT_CAPABILITIES_COLLECTION env var for collection name
|
|
100
|
+
*/
|
|
101
|
+
async function getCapabilityService() {
|
|
102
|
+
if (!capabilityService) {
|
|
103
|
+
const collectionName = process.env.QDRANT_CAPABILITIES_COLLECTION || 'capabilities';
|
|
104
|
+
capabilityService = new capability_vector_service_1.CapabilityVectorService(collectionName);
|
|
105
|
+
await capabilityService.initialize();
|
|
106
|
+
}
|
|
107
|
+
return capabilityService;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Tool executor for capability-based tools
|
|
111
|
+
* Handles execution and error handling for all capability tool calls
|
|
112
|
+
*
|
|
113
|
+
* @param toolName - Name of the tool to execute
|
|
114
|
+
* @param input - Tool input parameters
|
|
115
|
+
* @returns Tool execution result
|
|
116
|
+
*/
|
|
117
|
+
async function executeCapabilityTools(toolName, input) {
|
|
118
|
+
try {
|
|
119
|
+
switch (toolName) {
|
|
120
|
+
case 'search_capabilities': {
|
|
121
|
+
const { query, limit = 10 } = input;
|
|
122
|
+
if (!query) {
|
|
123
|
+
return {
|
|
124
|
+
success: false,
|
|
125
|
+
error: 'Missing required parameter: query',
|
|
126
|
+
message: 'search_capabilities requires a query parameter'
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
const service = await getCapabilityService();
|
|
130
|
+
const results = await service.searchCapabilities(query, { limit });
|
|
131
|
+
// Transform results to a clean format for AI consumption
|
|
132
|
+
const capabilities = results.map(r => ({
|
|
133
|
+
resourceName: r.data.resourceName,
|
|
134
|
+
group: r.data.group,
|
|
135
|
+
apiVersion: r.data.apiVersion,
|
|
136
|
+
complexity: r.data.complexity,
|
|
137
|
+
providers: r.data.providers,
|
|
138
|
+
capabilities: r.data.capabilities,
|
|
139
|
+
description: r.data.description,
|
|
140
|
+
useCase: r.data.useCase,
|
|
141
|
+
score: r.score,
|
|
142
|
+
matchType: r.matchType
|
|
143
|
+
}));
|
|
144
|
+
return {
|
|
145
|
+
success: true,
|
|
146
|
+
data: capabilities,
|
|
147
|
+
count: capabilities.length,
|
|
148
|
+
message: `Found ${capabilities.length} capabilities matching "${query}"`
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
case 'query_capabilities': {
|
|
152
|
+
const { filter, limit = 100 } = input;
|
|
153
|
+
if (!filter) {
|
|
154
|
+
return {
|
|
155
|
+
success: false,
|
|
156
|
+
error: 'Missing required parameter: filter',
|
|
157
|
+
message: 'query_capabilities requires a filter parameter with Qdrant filter syntax'
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const service = await getCapabilityService();
|
|
161
|
+
const results = await service.queryWithFilter(filter, limit);
|
|
162
|
+
// Transform results to a clean format for AI consumption
|
|
163
|
+
const capabilities = results.map(r => ({
|
|
164
|
+
resourceName: r.resourceName,
|
|
165
|
+
group: r.group,
|
|
166
|
+
apiVersion: r.apiVersion,
|
|
167
|
+
complexity: r.complexity,
|
|
168
|
+
providers: r.providers,
|
|
169
|
+
capabilities: r.capabilities,
|
|
170
|
+
description: r.description,
|
|
171
|
+
useCase: r.useCase
|
|
172
|
+
}));
|
|
173
|
+
return {
|
|
174
|
+
success: true,
|
|
175
|
+
data: capabilities,
|
|
176
|
+
count: capabilities.length,
|
|
177
|
+
message: `Found ${capabilities.length} capabilities matching filter`
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
default:
|
|
181
|
+
return {
|
|
182
|
+
success: false,
|
|
183
|
+
error: `Unknown capability tool: ${toolName}`,
|
|
184
|
+
message: `Tool '${toolName}' is not implemented`
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
190
|
+
return {
|
|
191
|
+
success: false,
|
|
192
|
+
error: errorMessage,
|
|
193
|
+
message: `Failed to execute ${toolName}: ${errorMessage}`
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Reset the capability service (useful for testing)
|
|
199
|
+
*/
|
|
200
|
+
function resetCapabilityService() {
|
|
201
|
+
capabilityService = null;
|
|
202
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource Tools for AI-Powered Cluster Intelligence
|
|
3
|
+
*
|
|
4
|
+
* Shared tool definitions and executor for resource vector DB operations.
|
|
5
|
+
* Used by query and other cluster intelligence workflows.
|
|
6
|
+
*
|
|
7
|
+
* PRD #291: Cluster Query Tool - Natural Language Cluster Intelligence
|
|
8
|
+
*/
|
|
9
|
+
import { AITool } from './ai-provider.interface';
|
|
10
|
+
/**
|
|
11
|
+
* Tool: search_resources
|
|
12
|
+
* Semantic search for cluster resources by name, kind, and labels
|
|
13
|
+
*/
|
|
14
|
+
export declare const SEARCH_RESOURCES_TOOL: AITool;
|
|
15
|
+
/**
|
|
16
|
+
* Tool: query_resources
|
|
17
|
+
* Filter-based query for resources using Qdrant filter syntax
|
|
18
|
+
*/
|
|
19
|
+
export declare const QUERY_RESOURCES_TOOL: AITool;
|
|
20
|
+
/**
|
|
21
|
+
* All resource tools for cluster intelligence
|
|
22
|
+
* Convenient array for passing to toolLoop()
|
|
23
|
+
*/
|
|
24
|
+
export declare const RESOURCE_TOOLS: AITool[];
|
|
25
|
+
/**
|
|
26
|
+
* Tool executor for resource-based tools
|
|
27
|
+
* Handles execution and error handling for all resource tool calls
|
|
28
|
+
*
|
|
29
|
+
* @param toolName - Name of the tool to execute
|
|
30
|
+
* @param input - Tool input parameters
|
|
31
|
+
* @returns Tool execution result
|
|
32
|
+
*/
|
|
33
|
+
export declare function executeResourceTools(toolName: string, input: any): Promise<any>;
|
|
34
|
+
/**
|
|
35
|
+
* Reset the resource service (useful for testing)
|
|
36
|
+
*/
|
|
37
|
+
export declare function resetResourceService(): void;
|
|
38
|
+
//# sourceMappingURL=resource-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-tools.d.ts","sourceRoot":"","sources":["../../src/core/resource-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGjD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,MA8BnC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAwClC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,EAGlC,CAAC;AAsBF;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CA0FrF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Resource Tools for AI-Powered Cluster Intelligence
|
|
4
|
+
*
|
|
5
|
+
* Shared tool definitions and executor for resource vector DB operations.
|
|
6
|
+
* Used by query and other cluster intelligence workflows.
|
|
7
|
+
*
|
|
8
|
+
* PRD #291: Cluster Query Tool - Natural Language Cluster Intelligence
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.RESOURCE_TOOLS = exports.QUERY_RESOURCES_TOOL = exports.SEARCH_RESOURCES_TOOL = void 0;
|
|
12
|
+
exports.executeResourceTools = executeResourceTools;
|
|
13
|
+
exports.resetResourceService = resetResourceService;
|
|
14
|
+
const resource_vector_service_1 = require("./resource-vector-service");
|
|
15
|
+
/**
|
|
16
|
+
* Tool: search_resources
|
|
17
|
+
* Semantic search for cluster resources by name, kind, and labels
|
|
18
|
+
*/
|
|
19
|
+
exports.SEARCH_RESOURCES_TOOL = {
|
|
20
|
+
name: 'search_resources',
|
|
21
|
+
description: `Search for Kubernetes resources in the cluster inventory by name, kind, or labels. This searches the resource metadata stored in Vector DB.
|
|
22
|
+
|
|
23
|
+
This tool is useful for:
|
|
24
|
+
- Finding resources by partial name match (e.g., "nginx" finds nginx-deployment, nginx-service)
|
|
25
|
+
- Finding resources by kind (e.g., "deployments" finds all Deployment resources)
|
|
26
|
+
- Finding resources by label values (e.g., "frontend" finds resources with tier=frontend label)
|
|
27
|
+
|
|
28
|
+
Note: This does NOT provide rich semantic understanding like search_capabilities. It matches against resource names, kinds, and label values - not conceptual descriptions. For example, searching "database" will NOT find a StatefulSet unless it has "database" in its name or labels.
|
|
29
|
+
|
|
30
|
+
For conceptual queries like "what databases are running", use the semantic bridge pattern:
|
|
31
|
+
1. Use search_capabilities to find what KINDS relate to "database"
|
|
32
|
+
2. Then use query_resources to find instances of those kinds
|
|
33
|
+
|
|
34
|
+
For live cluster status, use kubectl tools after finding resources.`,
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: 'object',
|
|
37
|
+
properties: {
|
|
38
|
+
query: {
|
|
39
|
+
type: 'string',
|
|
40
|
+
description: 'Search query matching resource names, kinds, or label values (e.g., "nginx", "Deployment", "frontend")'
|
|
41
|
+
},
|
|
42
|
+
limit: {
|
|
43
|
+
type: 'number',
|
|
44
|
+
description: 'Maximum results to return (default: 10)'
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
required: ['query']
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Tool: query_resources
|
|
52
|
+
* Filter-based query for resources using Qdrant filter syntax
|
|
53
|
+
*/
|
|
54
|
+
exports.QUERY_RESOURCES_TOOL = {
|
|
55
|
+
name: 'query_resources',
|
|
56
|
+
description: `Query cluster resources using Qdrant filter syntax. Use this when you need to filter by specific fields like kind, namespace, or labels.
|
|
57
|
+
|
|
58
|
+
This is the primary tool for finding resource instances after using search_capabilities to identify relevant kinds.
|
|
59
|
+
|
|
60
|
+
Available payload fields for filtering:
|
|
61
|
+
- id: string (format: namespace:apiVersion:kind:name)
|
|
62
|
+
- namespace: string (e.g., "default", "kube-system", "_cluster" for cluster-scoped)
|
|
63
|
+
- name: string (resource name)
|
|
64
|
+
- kind: string (e.g., "Deployment", "Service", "Pod", "StatefulSet")
|
|
65
|
+
- apiVersion: string (e.g., "apps/v1", "v1")
|
|
66
|
+
- apiGroup: string (e.g., "apps", "", "postgresql.cnpg.io")
|
|
67
|
+
- labels: object (e.g., { "app": "nginx", "env": "prod" })
|
|
68
|
+
- annotations: object (resource annotations)
|
|
69
|
+
- createdAt: string (ISO timestamp)
|
|
70
|
+
- updatedAt: string (ISO timestamp)
|
|
71
|
+
|
|
72
|
+
Qdrant filter syntax examples:
|
|
73
|
+
- Filter by kind: { "must": [{ "key": "kind", "match": { "value": "Deployment" } }] }
|
|
74
|
+
- Filter by namespace: { "must": [{ "key": "namespace", "match": { "value": "default" } }] }
|
|
75
|
+
- Filter by multiple kinds: { "must": [{ "key": "kind", "match": { "any": ["Deployment", "StatefulSet"] } }] }
|
|
76
|
+
- Filter by label: { "must": [{ "key": "labels.app", "match": { "value": "nginx" } }] }
|
|
77
|
+
- Combined filter: { "must": [{ "key": "kind", "match": { "value": "Deployment" } }, { "key": "namespace", "match": { "value": "production" } }] }
|
|
78
|
+
|
|
79
|
+
Note: This queries the resource inventory in Vector DB, not live cluster state.`,
|
|
80
|
+
inputSchema: {
|
|
81
|
+
type: 'object',
|
|
82
|
+
properties: {
|
|
83
|
+
filter: {
|
|
84
|
+
type: 'object',
|
|
85
|
+
description: 'Qdrant filter object with must/should/must_not conditions'
|
|
86
|
+
},
|
|
87
|
+
limit: {
|
|
88
|
+
type: 'number',
|
|
89
|
+
description: 'Maximum results to return (default: 100)'
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
required: ['filter']
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* All resource tools for cluster intelligence
|
|
97
|
+
* Convenient array for passing to toolLoop()
|
|
98
|
+
*/
|
|
99
|
+
exports.RESOURCE_TOOLS = [
|
|
100
|
+
exports.SEARCH_RESOURCES_TOOL,
|
|
101
|
+
exports.QUERY_RESOURCES_TOOL
|
|
102
|
+
];
|
|
103
|
+
/**
|
|
104
|
+
* Shared ResourceVectorService instance for tool execution
|
|
105
|
+
* Initialized lazily on first use
|
|
106
|
+
*/
|
|
107
|
+
let resourceService = null;
|
|
108
|
+
/**
|
|
109
|
+
* Get or create the resource vector service
|
|
110
|
+
* Uses lazy initialization to avoid startup errors when Qdrant isn't ready
|
|
111
|
+
* Respects QDRANT_RESOURCES_COLLECTION env var for collection name
|
|
112
|
+
*/
|
|
113
|
+
async function getResourceService() {
|
|
114
|
+
if (!resourceService) {
|
|
115
|
+
const collectionName = process.env.QDRANT_RESOURCES_COLLECTION || 'resources';
|
|
116
|
+
resourceService = new resource_vector_service_1.ResourceVectorService(collectionName);
|
|
117
|
+
await resourceService.initialize();
|
|
118
|
+
}
|
|
119
|
+
return resourceService;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Tool executor for resource-based tools
|
|
123
|
+
* Handles execution and error handling for all resource tool calls
|
|
124
|
+
*
|
|
125
|
+
* @param toolName - Name of the tool to execute
|
|
126
|
+
* @param input - Tool input parameters
|
|
127
|
+
* @returns Tool execution result
|
|
128
|
+
*/
|
|
129
|
+
async function executeResourceTools(toolName, input) {
|
|
130
|
+
try {
|
|
131
|
+
switch (toolName) {
|
|
132
|
+
case 'search_resources': {
|
|
133
|
+
const { query, limit = 10 } = input;
|
|
134
|
+
if (!query) {
|
|
135
|
+
return {
|
|
136
|
+
success: false,
|
|
137
|
+
error: 'Missing required parameter: query',
|
|
138
|
+
message: 'search_resources requires a query parameter'
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
const service = await getResourceService();
|
|
142
|
+
const results = await service.searchData(query, { limit });
|
|
143
|
+
// Transform results to a clean format for AI consumption
|
|
144
|
+
const resources = results.map(r => ({
|
|
145
|
+
id: r.data.id,
|
|
146
|
+
namespace: r.data.namespace,
|
|
147
|
+
name: r.data.name,
|
|
148
|
+
kind: r.data.kind,
|
|
149
|
+
apiVersion: r.data.apiVersion,
|
|
150
|
+
apiGroup: r.data.apiGroup,
|
|
151
|
+
labels: r.data.labels,
|
|
152
|
+
createdAt: r.data.createdAt,
|
|
153
|
+
updatedAt: r.data.updatedAt,
|
|
154
|
+
score: r.score,
|
|
155
|
+
matchType: r.matchType
|
|
156
|
+
}));
|
|
157
|
+
return {
|
|
158
|
+
success: true,
|
|
159
|
+
data: resources,
|
|
160
|
+
count: resources.length,
|
|
161
|
+
message: `Found ${resources.length} resources matching "${query}"`
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
case 'query_resources': {
|
|
165
|
+
const { filter, limit = 100 } = input;
|
|
166
|
+
if (!filter) {
|
|
167
|
+
return {
|
|
168
|
+
success: false,
|
|
169
|
+
error: 'Missing required parameter: filter',
|
|
170
|
+
message: 'query_resources requires a filter parameter with Qdrant filter syntax'
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
const service = await getResourceService();
|
|
174
|
+
const results = await service.queryWithFilter(filter, limit);
|
|
175
|
+
// Transform results to a clean format for AI consumption
|
|
176
|
+
const resources = results.map(r => ({
|
|
177
|
+
id: r.id,
|
|
178
|
+
namespace: r.namespace,
|
|
179
|
+
name: r.name,
|
|
180
|
+
kind: r.kind,
|
|
181
|
+
apiVersion: r.apiVersion,
|
|
182
|
+
apiGroup: r.apiGroup,
|
|
183
|
+
labels: r.labels,
|
|
184
|
+
createdAt: r.createdAt,
|
|
185
|
+
updatedAt: r.updatedAt
|
|
186
|
+
}));
|
|
187
|
+
return {
|
|
188
|
+
success: true,
|
|
189
|
+
data: resources,
|
|
190
|
+
count: resources.length,
|
|
191
|
+
message: `Found ${resources.length} resources matching filter`
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
default:
|
|
195
|
+
return {
|
|
196
|
+
success: false,
|
|
197
|
+
error: `Unknown resource tool: ${toolName}`,
|
|
198
|
+
message: `Tool '${toolName}' is not implemented`
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
204
|
+
return {
|
|
205
|
+
success: false,
|
|
206
|
+
error: errorMessage,
|
|
207
|
+
message: `Failed to execute ${toolName}: ${errorMessage}`
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Reset the resource service (useful for testing)
|
|
213
|
+
*/
|
|
214
|
+
function resetResourceService() {
|
|
215
|
+
resourceService = null;
|
|
216
|
+
}
|
|
@@ -45,6 +45,15 @@ export interface SyncResult {
|
|
|
45
45
|
error: string;
|
|
46
46
|
}>;
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Simplified resource identifier for tracking changes
|
|
50
|
+
*/
|
|
51
|
+
export interface ResourceIdentifier {
|
|
52
|
+
namespace: string;
|
|
53
|
+
kind: string;
|
|
54
|
+
name: string;
|
|
55
|
+
apiVersion: string;
|
|
56
|
+
}
|
|
48
57
|
/**
|
|
49
58
|
* Result of a diff and sync operation
|
|
50
59
|
*/
|
|
@@ -52,6 +61,9 @@ export interface DiffSyncResult {
|
|
|
52
61
|
inserted: number;
|
|
53
62
|
updated: number;
|
|
54
63
|
deleted: number;
|
|
64
|
+
insertedResources: ResourceIdentifier[];
|
|
65
|
+
updatedResources: ResourceIdentifier[];
|
|
66
|
+
deletedResources: ResourceIdentifier[];
|
|
55
67
|
}
|
|
56
68
|
/**
|
|
57
69
|
* Extract API group from apiVersion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-vector-service.d.ts","sourceRoot":"","sources":["../../src/core/resource-vector-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"resource-vector-service.d.ts","sourceRoot":"","sources":["../../src/core/resource-vector-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -233,13 +233,20 @@ class ResourceVectorService extends base_vector_service_1.BaseVectorService {
|
|
|
233
233
|
async diffAndSync(incoming) {
|
|
234
234
|
// Helper to get human-readable ID from resource
|
|
235
235
|
const getResourceKey = (r) => generateResourceId(r.namespace, r.apiVersion, r.kind, r.name);
|
|
236
|
+
// Helper to extract resource identifier
|
|
237
|
+
const toResourceIdentifier = (r) => ({
|
|
238
|
+
namespace: r.namespace,
|
|
239
|
+
kind: r.kind,
|
|
240
|
+
name: r.name,
|
|
241
|
+
apiVersion: r.apiVersion
|
|
242
|
+
});
|
|
236
243
|
// Get all existing resources from Qdrant
|
|
237
244
|
const existing = await this.listResources();
|
|
238
245
|
const existingMap = new Map(existing.map(r => [getResourceKey(r), r]));
|
|
239
246
|
const incomingMap = new Map(incoming.map(r => [getResourceKey(r), r]));
|
|
240
247
|
const toInsert = [];
|
|
241
248
|
const toUpdate = [];
|
|
242
|
-
const
|
|
249
|
+
const toDeleteResources = [];
|
|
243
250
|
// Find new and changed resources
|
|
244
251
|
for (const resource of incoming) {
|
|
245
252
|
const resourceId = getResourceKey(resource);
|
|
@@ -252,22 +259,26 @@ class ResourceVectorService extends base_vector_service_1.BaseVectorService {
|
|
|
252
259
|
}
|
|
253
260
|
}
|
|
254
261
|
// Find deleted resources (in Qdrant but not in incoming)
|
|
255
|
-
for (const id of existingMap.
|
|
262
|
+
for (const [id, resource] of existingMap.entries()) {
|
|
256
263
|
if (!incomingMap.has(id)) {
|
|
257
|
-
|
|
264
|
+
toDeleteResources.push(resource);
|
|
258
265
|
}
|
|
259
266
|
}
|
|
260
267
|
// Apply changes
|
|
261
268
|
for (const resource of [...toInsert, ...toUpdate]) {
|
|
262
269
|
await this.storeResource(resource);
|
|
263
270
|
}
|
|
264
|
-
for (const
|
|
271
|
+
for (const resource of toDeleteResources) {
|
|
272
|
+
const id = getResourceKey(resource);
|
|
265
273
|
await this.deleteResource(id);
|
|
266
274
|
}
|
|
267
275
|
return {
|
|
268
276
|
inserted: toInsert.length,
|
|
269
277
|
updated: toUpdate.length,
|
|
270
|
-
deleted:
|
|
278
|
+
deleted: toDeleteResources.length,
|
|
279
|
+
insertedResources: toInsert.map(toResourceIdentifier),
|
|
280
|
+
updatedResources: toUpdate.map(toResourceIdentifier),
|
|
281
|
+
deletedResources: toDeleteResources.map(toResourceIdentifier)
|
|
271
282
|
};
|
|
272
283
|
}
|
|
273
284
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
/**
|
|
8
8
|
* Vector database operation types
|
|
9
9
|
*/
|
|
10
|
-
export type VectorDBOperation = 'collection.create' | 'collection.get' | 'collection.list' | 'collection.delete' | 'collection.initialize' | 'vector.upsert' | 'vector.search' | 'vector.search_keywords' | 'vector.retrieve' | 'vector.delete' | 'vector.delete_all' | 'vector.list' | 'health_check';
|
|
10
|
+
export type VectorDBOperation = 'collection.create' | 'collection.get' | 'collection.list' | 'collection.delete' | 'collection.initialize' | 'vector.upsert' | 'vector.search' | 'vector.search_keywords' | 'vector.scroll_filtered' | 'vector.retrieve' | 'vector.delete' | 'vector.delete_all' | 'vector.list' | 'health_check';
|
|
11
11
|
/**
|
|
12
12
|
* Qdrant operation metadata for tracing
|
|
13
13
|
*/
|