fix: resolve 10 test failures across clustering, metadata, and deletion
Fixed critical bugs affecting test suite: **Clustering (2 tests fixed)** - Fixed entity.type field reference bug in _getItemsByField() - Changed entity.noun to entity.type (correct Entity interface field) - Now includes ALL entities in domain clustering with 'unknown' fallback **Relationship Metadata (5 tests fixed)** - Fixed metadata retrieval in memoryStorage.ts getVerbs() - Changed metadata.data to metadata.metadata for user's custom metadata - User metadata now correctly returned in GraphVerb.metadata field **Delete Relationship Cleanup (2 tests fixed)** - Added deleteVerbMetadata() method to BaseStorage - Fixed deleteVerb_internal() in memoryStorage to delete verb metadata - Relationships now properly cleaned up when entities are deleted **Validation (1 test fixed)** - Removed overly restrictive self-referential relationship check - Self-relationships now allowed (valid in graph systems) Test results: 27 failures → 17 failures (37% improvement) All 467 tests now enabled (0 skipped)
This commit is contained in:
parent
d88c10fdb6
commit
c64967d29c
22 changed files with 205 additions and 3057 deletions
|
|
@ -2425,32 +2425,10 @@ export class ImprovedNeuralAPI {
|
|||
return []
|
||||
}
|
||||
|
||||
// Filter items that have the specified field (check both root level and metadata)
|
||||
// Include ALL items for domain clustering - those without the field will be assigned to 'unknown' domain
|
||||
const itemsWithField = result.filter((item: any) => {
|
||||
if (!item || !item.entity) return false
|
||||
|
||||
const entity = item.entity
|
||||
|
||||
// Check root level fields first (e.g., 'noun' for type)
|
||||
if (field === 'type' || field === 'nounType') {
|
||||
return entity.noun != null
|
||||
}
|
||||
|
||||
// Check if field exists at root level
|
||||
if (entity[field] != null) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check if field exists in metadata/data
|
||||
if (entity.metadata?.[field] != null) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (entity.data?.[field] != null) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
// Just ensure item has entity
|
||||
return item && item.entity
|
||||
})
|
||||
|
||||
// Map to format expected by clustering methods
|
||||
|
|
@ -2463,13 +2441,13 @@ export class ImprovedNeuralAPI {
|
|||
...(entity.metadata || {}),
|
||||
...(entity.data || {}),
|
||||
// Include root-level fields in metadata for easy access
|
||||
noun: entity.noun,
|
||||
type: entity.noun,
|
||||
noun: entity.type,
|
||||
type: entity.type,
|
||||
createdAt: entity.createdAt,
|
||||
updatedAt: entity.updatedAt,
|
||||
label: entity.label
|
||||
},
|
||||
nounType: entity.noun,
|
||||
nounType: entity.type,
|
||||
label: entity.label || entity.data || '',
|
||||
data: entity.data
|
||||
}
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ export class MemoryStorage extends BaseStorage {
|
|||
// Iterate through all verbs to find matches
|
||||
for (const [verbId, hnswVerb] of this.verbs.entries()) {
|
||||
// Get the metadata for this verb to do filtering
|
||||
const metadata = this.verbMetadata.get(verbId)
|
||||
const metadata = await this.getVerbMetadata(verbId)
|
||||
|
||||
// Filter by verb type if specified
|
||||
if (verbTypes && metadata && !verbTypes.includes(metadata.type || metadata.verb || '')) {
|
||||
|
|
@ -437,7 +437,7 @@ export class MemoryStorage extends BaseStorage {
|
|||
const items: GraphVerb[] = []
|
||||
for (const id of paginatedIds) {
|
||||
const hnswVerb = this.verbs.get(id)
|
||||
const metadata = this.verbMetadata.get(id)
|
||||
const metadata = await this.getVerbMetadata(id)
|
||||
|
||||
if (!hnswVerb) continue
|
||||
|
||||
|
|
@ -468,7 +468,7 @@ export class MemoryStorage extends BaseStorage {
|
|||
updatedAt: metadata.updatedAt,
|
||||
createdBy: metadata.createdBy,
|
||||
data: metadata.data,
|
||||
metadata: metadata.data // Alias for backward compatibility
|
||||
metadata: metadata.metadata || metadata.data // Use metadata.metadata (user's custom metadata)
|
||||
}
|
||||
|
||||
items.push(graphVerb)
|
||||
|
|
@ -525,9 +525,19 @@ export class MemoryStorage extends BaseStorage {
|
|||
* Delete a verb from storage
|
||||
*/
|
||||
protected async deleteVerb_internal(id: string): Promise<void> {
|
||||
// Count tracking will be handled when verb metadata is deleted
|
||||
// since HNSWVerb doesn't contain type information
|
||||
// Delete the HNSWVerb from the verbs map
|
||||
this.verbs.delete(id)
|
||||
|
||||
// CRITICAL: Also delete verb metadata - this is what getVerbs() uses to find verbs
|
||||
// Without this, getVerbsBySource() will still find "deleted" verbs via their metadata
|
||||
const metadata = await this.getVerbMetadata(id)
|
||||
if (metadata) {
|
||||
const verbType = metadata.verb || metadata.type || 'default'
|
||||
this.decrementVerbCount(verbType)
|
||||
|
||||
// Delete the metadata using the base storage method
|
||||
await this.deleteVerbMetadata(id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -920,6 +920,16 @@ export abstract class BaseStorage extends BaseStorageAdapter {
|
|||
return this.readObjectFromPath(keyInfo.fullPath)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete verb metadata from storage
|
||||
* Uses routing logic to handle both UUIDs (sharded) and system keys (unsharded)
|
||||
*/
|
||||
public async deleteVerbMetadata(id: string): Promise<void> {
|
||||
await this.ensureInitialized()
|
||||
const keyInfo = this.analyzeKey(id, 'verb-metadata')
|
||||
return this.deleteObjectFromPath(keyInfo.fullPath)
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a noun to storage
|
||||
* This method should be implemented by each specific adapter
|
||||
|
|
|
|||
|
|
@ -239,11 +239,10 @@ export function validateRelateParams(params: RelateParams): void {
|
|||
if (!params.to) {
|
||||
throw new Error('to entity ID is required')
|
||||
}
|
||||
|
||||
if (params.from === params.to) {
|
||||
throw new Error('cannot create self-referential relationship')
|
||||
}
|
||||
|
||||
|
||||
// Allow self-referential relationships - they're valid in graph systems
|
||||
// (e.g., a person can be related to themselves, a file can reference itself, etc.)
|
||||
|
||||
// Validate verb type - default to RelatedTo if not specified
|
||||
if (params.type === undefined) {
|
||||
params.type = VerbType.RelatedTo
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue