@vfarcic/dot-ai
Version:
AI-powered development productivity platform that enhances software development workflows through intelligent automation and AI-driven assistance
190 lines (189 loc) • 7.27 kB
JavaScript
;
/**
* Capability Vector Service
*
* Vector-based storage and retrieval for resource capabilities
* Extends BaseVectorService to provide capability-specific operations
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.CapabilityVectorService = void 0;
const base_vector_service_1 = require("./base-vector-service");
const capabilities_1 = require("./capabilities");
/**
* Vector service for storing and searching resource capabilities
*/
class CapabilityVectorService extends base_vector_service_1.BaseVectorService {
constructor(collectionName = 'capabilities', embeddingService) {
super(collectionName, embeddingService);
}
/**
* Create searchable text from capability data for embedding generation
*/
createSearchText(capability) {
return [
capability.resourceName,
...capability.capabilities,
...capability.providers,
...capability.abstractions,
capability.description,
capability.useCase,
capability.complexity
].join(' ');
}
/**
* Extract unique ID from capability data
*/
extractId(capability) {
return capabilities_1.CapabilityInferenceEngine.generateCapabilityId(capability.resourceName);
}
/**
* Convert capability to storage payload format
*/
createPayload(capability) {
return {
resourceName: capability.resourceName,
apiVersion: capability.apiVersion,
version: capability.version,
group: capability.group,
capabilities: capability.capabilities,
providers: capability.providers,
abstractions: capability.abstractions,
complexity: capability.complexity,
description: capability.description,
useCase: capability.useCase,
printerColumns: capability.printerColumns,
confidence: capability.confidence,
analyzedAt: capability.analyzedAt
};
}
/**
* Convert storage payload back to capability object
*/
payloadToData(payload) {
return {
resourceName: payload.resourceName,
apiVersion: payload.apiVersion,
version: payload.version,
group: payload.group,
capabilities: payload.capabilities || [],
providers: payload.providers || [],
abstractions: payload.abstractions || [],
complexity: payload.complexity || 'medium',
description: payload.description || '',
useCase: payload.useCase || '',
printerColumns: payload.printerColumns,
confidence: payload.confidence || 0,
analyzedAt: payload.analyzedAt || new Date().toISOString()
};
}
/**
* Store a capability in the vector database
*/
async storeCapability(capability) {
await this.storeData(capability);
}
/**
* Search capabilities by user intent with optional filters
*/
async searchCapabilities(intent, options = {}) {
const results = await this.searchData(intent, options);
// Apply complexity filter if specified
if (options.complexityFilter) {
return results.filter((result) => result.data.complexity === options.complexityFilter);
}
// Apply provider filter if specified
if (options.providerFilter && options.providerFilter.length > 0) {
return results.filter((result) => result.data.providers.some((provider) => options.providerFilter.includes(provider)));
}
return results;
}
/**
* Get capability by ID
* Used by MCP operations with IDs from list/search results
*/
async getCapability(id) {
return await this.getData(id);
}
/**
* Get capability by kind and apiVersion
* Used for JSON format lookup from dashboard UI
*
* @param kind - Resource kind (e.g., "Deployment", "Cluster")
* @param apiVersion - Full apiVersion (e.g., "apps/v1", "postgresql.cnpg.io/v1")
* @returns Matching capability or null if not found
*/
async getCapabilityByKindApiVersion(kind, apiVersion) {
// Build Qdrant filter for exact apiVersion match
const filter = {
must: [
{ key: 'apiVersion', match: { value: apiVersion } }
]
};
const results = await this.queryWithFilter(filter, 100);
if (results.length === 0) {
return null;
}
// Find matching capability by kind
// For standard resources: resourceName === kind (case insensitive)
// For CRDs: resourceName matches Kind.group or plural.group pattern
const kindLower = kind.toLowerCase();
const match = results.find(cap => {
const resourceNameLower = cap.resourceName.toLowerCase();
// Exact match
if (resourceNameLower === kindLower)
return true;
// Pluralized exact match (e.g., "deployment" -> "deployments")
if (resourceNameLower === kindLower + 's' || resourceNameLower === kindLower + 'es')
return true;
// CRD format: Kind.group (e.g., "deployment" -> "deployment.apps")
// Must match kind followed by a dot to avoid false positives like "cluster" matching "clusterroles"
if (resourceNameLower.startsWith(kindLower + '.'))
return true;
// CRD format: plural.group (e.g., "cluster" -> "clusters.devopstoolkit.live")
if (resourceNameLower.startsWith(kindLower + 's.') || resourceNameLower.startsWith(kindLower + 'es.'))
return true;
// Handle -y -> -ies pluralization (e.g., "policy" -> "policies.group")
if (kindLower.endsWith('y')) {
const stem = kindLower.slice(0, -1);
if (resourceNameLower === stem + 'ies' || resourceNameLower.startsWith(stem + 'ies.'))
return true;
}
return false;
});
return match || null;
}
/**
* Delete capability by resource name
*/
async deleteCapability(resourceName) {
const capabilityId = capabilities_1.CapabilityInferenceEngine.generateCapabilityId(resourceName);
await this.deleteData(capabilityId);
}
/**
* Delete capability by ID (for MCP tool interface)
*/
async deleteCapabilityById(id) {
await this.deleteData(id);
}
/**
* Delete all capabilities efficiently by recreating collection
*/
async deleteAllCapabilities() {
await this.deleteAllData();
}
/**
* List all capabilities with optional pagination
*/
async getAllCapabilities(limit) {
return await this.getAllData(limit);
}
/**
* Get count of stored capabilities
*/
async getCapabilitiesCount() {
// Use getAllData to get count since base class doesn't expose getCount
const allCapabilities = await this.getAllData(); // Get all capabilities to count them
return allCapabilities.length;
}
}
exports.CapabilityVectorService = CapabilityVectorService;