fix: combine vector and metadata in getNoun/getVerb internal methods

Fixed critical bug in 2-file architecture where getNoun_internal() and
getVerb_internal() only returned vector data without metadata, causing
brain.get() to return null despite data being correctly saved.

Changes:
- Updated all 5 storage adapters (GCS, S3, FileSystem, Memory, OPFS)
- Fixed getNoun_internal() to fetch and combine vector + metadata
- Fixed getVerb_internal() to fetch and combine vector + metadata
- Added metadata field to HNSWVerb interface for consistency

The 2-file architecture now works correctly for both read and write operations.
This commit is contained in:
David Snelling 2025-10-10 16:51:59 -07:00
parent 30063d440a
commit cb1e37c0e8
6 changed files with 140 additions and 30 deletions

View file

@ -78,7 +78,8 @@ export class MemoryStorage extends BaseStorage {
}
/**
* Get a noun from storage
* Get a noun from storage (internal implementation)
* Combines vector data from nouns map with metadata from getNounMetadata()
*/
protected async getNoun_internal(id: string): Promise<HNSWNoun | null> {
// Get the noun directly from the nouns map
@ -90,14 +91,11 @@ export class MemoryStorage extends BaseStorage {
}
// Return a deep copy to avoid reference issues
// CRITICAL: Only return lightweight vector data (no metadata)
// Metadata is retrieved separately via getNounMetadata() (2-file system)
const nounCopy: HNSWNoun = {
id: noun.id,
vector: [...noun.vector],
connections: new Map(),
level: noun.level || 0
// NO metadata field - retrieved separately for scalability
}
// Copy connections
@ -105,7 +103,14 @@ export class MemoryStorage extends BaseStorage {
nounCopy.connections.set(level, new Set(connections))
}
return nounCopy
// Get metadata (entity data in 2-file system)
const metadata = await this.getNounMetadata(id)
// Combine into complete noun object
return {
...nounCopy,
metadata: metadata || {}
}
}
/**
@ -303,7 +308,8 @@ export class MemoryStorage extends BaseStorage {
}
/**
* Get a verb from storage
* Get a verb from storage (internal implementation)
* Combines vector data from verbs map with metadata from getVerbMetadata()
*/
protected async getVerb_internal(id: string): Promise<HNSWVerb | null> {
// Get the verb directly from the verbs map
@ -314,18 +320,6 @@ export class MemoryStorage extends BaseStorage {
return null
}
// Create default timestamp if not present
const defaultTimestamp = {
seconds: Math.floor(Date.now() / 1000),
nanoseconds: (Date.now() % 1000) * 1000000
}
// Create default createdBy if not present
const defaultCreatedBy = {
augmentation: 'unknown',
version: '1.0'
}
// Return a deep copy of the HNSWVerb
const verbCopy: HNSWVerb = {
id: verb.id,
@ -338,7 +332,14 @@ export class MemoryStorage extends BaseStorage {
verbCopy.connections.set(level, new Set(connections))
}
return verbCopy
// Get metadata (relationship data in 2-file system)
const metadata = await this.getVerbMetadata(id)
// Combine into complete verb object
return {
...verbCopy,
metadata: metadata || {}
}
}
/**