Merge remote-tracking branch 'origin/main'

This commit is contained in:
David Snelling 2025-07-23 12:39:19 -07:00
commit b8f10ba39a
6 changed files with 399 additions and 313 deletions

View file

@ -61,7 +61,8 @@ GitHub Pages that showcases Brainy's main features.
npm install @soulcraft/brainy npm install @soulcraft/brainy
``` ```
TensorFlow.js packages are included as bundled dependencies and will be automatically installed without any additional configuration. TensorFlow.js packages are included as bundled dependencies and will be automatically installed without any additional
configuration.
### Additional Packages ### Additional Packages
@ -122,7 +123,9 @@ import { BrainyData } from '@soulcraft/brainy'
import {BrainyData} from '@soulcraft/brainy/min' import {BrainyData} from '@soulcraft/brainy/min'
``` ```
> **Note**: The CLI functionality is available as a separate package `@soulcraft/brainy-cli` to reduce the bundle size of the main package. Install it globally with `npm install -g @soulcraft/brainy-cli` to use the command-line interface. > **Note**: The CLI functionality is available as a separate package `@soulcraft/brainy-cli` to reduce the bundle size
> of the main package. Install it globally with `npm install -g @soulcraft/brainy-cli` to use the command-line
> interface.
### Browser Usage ### Browser Usage
@ -423,7 +426,8 @@ brainy visualize --root <id> --depth 3
### Using the CLI in Your Code ### Using the CLI in Your Code
The CLI functionality is available as a separate package `@soulcraft/brainy-cli`. If you need CLI functionality in your application, install the CLI package: The CLI functionality is available as a separate package `@soulcraft/brainy-cli`. If you need CLI functionality in your
application, install the CLI package:
```bash ```bash
npm install @soulcraft/brainy-cli npm install @soulcraft/brainy-cli
@ -539,6 +543,19 @@ await db.addVerb(sourceId, targetId, {
// other metadata... // other metadata...
}) })
// Add a relationship with auto-creation of missing nouns
// This is useful when the target noun might not exist yet
await db.addVerb(sourceId, targetId, {
verb: VerbType.RelatedTo,
// Enable auto-creation of missing nouns
autoCreateMissingNouns: true,
// Optional metadata for auto-created nouns
missingNounMetadata: {
noun: NounType.Concept,
description: 'Auto-created noun'
}
})
// Get all relationships // Get all relationships
const verbs = await db.getAllVerbs() const verbs = await db.getAllVerbs()
@ -924,7 +941,8 @@ The simplified augmentation system provides:
#### WebSocket Augmentation Types #### WebSocket Augmentation Types
Brainy exports several WebSocket augmentation types that can be used by augmentation creators to add WebSocket capabilities to their augmentations: Brainy exports several WebSocket augmentation types that can be used by augmentation creators to add WebSocket
capabilities to their augmentations:
```typescript ```typescript
import { import {
@ -985,7 +1003,8 @@ await mySenseAug.processRawData('data', 'text')
await mySenseAug.connectWebSocket('wss://example.com') await mySenseAug.connectWebSocket('wss://example.com')
``` ```
These WebSocket augmentation types combine the base augmentation interfaces with the `IWebSocketSupport` interface, providing type safety and autocompletion for augmentations with WebSocket capabilities. These WebSocket augmentation types combine the base augmentation interfaces with the `IWebSocketSupport` interface,
providing type safety and autocompletion for augmentations with WebSocket capabilities.
### Model Control Protocol (MCP) ### Model Control Protocol (MCP)
@ -1049,7 +1068,6 @@ Works in all modern browsers:
For browsers without OPFS support, falls back to in-memory storage. For browsers without OPFS support, falls back to in-memory storage.
## Related Projects ## Related Projects
- **[Cartographer](https://github.com/sodal-project/cartographer)** - A companion project that provides standardized - **[Cartographer](https://github.com/sodal-project/cartographer)** - A companion project that provides standardized

View file

@ -1,16 +1,16 @@
{ {
"name": "@soulcraft/brainy-cli", "name": "@soulcraft/brainy-cli",
"version": "0.17.0", "version": "0.18.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@soulcraft/brainy-cli", "name": "@soulcraft/brainy-cli",
"version": "0.17.0", "version": "0.18.0",
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@soulcraft/brainy": "0.12.0", "@soulcraft/brainy": "^0.17.0",
"commander": "^14.0.0", "commander": "^14.0.0",
"omelette": "^0.4.17" "omelette": "^0.4.17"
}, },
@ -2087,10 +2087,9 @@
} }
}, },
"node_modules/@soulcraft/brainy": { "node_modules/@soulcraft/brainy": {
"version": "0.12.0", "version": "0.17.0",
"resolved": "https://registry.npmjs.org/@soulcraft/brainy/-/brainy-0.12.0.tgz", "resolved": "https://registry.npmjs.org/@soulcraft/brainy/-/brainy-0.17.0.tgz",
"integrity": "sha512-Wka8OAw0TQTYZqSSFD+t8cRDOr5l6OblPuZspW54theHn9HwohUtpoHzqwcvYfs5qCF6u0zC7YHhBQtlbrdkIg==", "integrity": "sha512-QoTiNnyK7fBuNRDsGOcP89UrFfwxoqkS6lRh6VpIXAWVTtxUBy256PWxQAqtZgpslOZRAA58GlXIQf3IYHiM5g==",
"hasInstallScript": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@aws-sdk/client-s3": "^3.540.0", "@aws-sdk/client-s3": "^3.540.0",

View file

@ -1,6 +1,6 @@
{ {
"name": "@soulcraft/brainy-cli", "name": "@soulcraft/brainy-cli",
"version": "0.17.0", "version": "0.18.0",
"description": "Command-line interface for the Brainy vector graph database", "description": "Command-line interface for the Brainy vector graph database",
"type": "module", "type": "module",
"bin": { "bin": {
@ -46,7 +46,7 @@
"url": "git+https://github.com/soulcraft-research/brainy.git" "url": "git+https://github.com/soulcraft-research/brainy.git"
}, },
"dependencies": { "dependencies": {
"@soulcraft/brainy": "^0.15.0", "@soulcraft/brainy": "^0.17.0",
"commander": "^14.0.0", "commander": "^14.0.0",
"omelette": "^0.4.17" "omelette": "^0.4.17"
}, },

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{ {
"name": "@soulcraft/brainy", "name": "@soulcraft/brainy",
"version": "0.16.0", "version": "0.17.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@soulcraft/brainy", "name": "@soulcraft/brainy",
"version": "0.16.0", "version": "0.17.0",
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View file

@ -1,6 +1,6 @@
{ {
"name": "@soulcraft/brainy", "name": "@soulcraft/brainy",
"version": "0.16.0", "version": "0.17.0",
"description": "A vector graph database using HNSW indexing with Origin Private File System storage", "description": "A vector graph database using HNSW indexing with Origin Private File System storage",
"main": "dist/unified.js", "main": "dist/unified.js",
"module": "dist/unified.js", "module": "dist/unified.js",

View file

@ -1253,6 +1253,22 @@ export class BrainyData<T = any> implements BrainyDataInterface<T> {
/** /**
* Add a verb between two nouns * Add a verb between two nouns
* If metadata is provided and vector is not, the metadata will be vectorized using the embedding function * If metadata is provided and vector is not, the metadata will be vectorized using the embedding function
*
* @param sourceId ID of the source noun
* @param targetId ID of the target noun
* @param vector Optional vector for the verb
* @param options Additional options:
* - type: Type of the verb
* - weight: Weight of the verb
* - metadata: Metadata for the verb
* - forceEmbed: Force using the embedding function for metadata even if vector is provided
* - id: Optional ID to use instead of generating a new one
* - autoCreateMissingNouns: Automatically create missing nouns if they don't exist
* - missingNounMetadata: Metadata to use when auto-creating missing nouns
*
* @returns The ID of the added verb
*
* @throws Error if source or target nouns don't exist and autoCreateMissingNouns is false or auto-creation fails
*/ */
public async addVerb( public async addVerb(
sourceId: string, sourceId: string,
@ -1264,6 +1280,8 @@ export class BrainyData<T = any> implements BrainyDataInterface<T> {
metadata?: any metadata?: any
forceEmbed?: boolean // Force using the embedding function for metadata even if vector is provided forceEmbed?: boolean // Force using the embedding function for metadata even if vector is provided
id?: string // Optional ID to use instead of generating a new one id?: string // Optional ID to use instead of generating a new one
autoCreateMissingNouns?: boolean // Automatically create missing nouns
missingNounMetadata?: any // Metadata to use when auto-creating missing nouns
} = {} } = {}
): Promise<string> { ): Promise<string> {
await this.ensureInitialized() await this.ensureInitialized()
@ -1273,8 +1291,59 @@ export class BrainyData<T = any> implements BrainyDataInterface<T> {
try { try {
// Check if source and target nouns exist // Check if source and target nouns exist
const sourceNoun = this.index.getNouns().get(sourceId) let sourceNoun = this.index.getNouns().get(sourceId)
const targetNoun = this.index.getNouns().get(targetId) let targetNoun = this.index.getNouns().get(targetId)
// Auto-create missing nouns if option is enabled
if (!sourceNoun && options.autoCreateMissingNouns) {
try {
// Create a placeholder vector for the missing noun
const placeholderVector = new Array(this._dimensions).fill(0)
// Add metadata if provided
const metadata = options.missingNounMetadata || {
autoCreated: true,
createdAt: new Date().toISOString(),
noun: NounType.Concept
}
// Add the missing noun
await this.add(placeholderVector, metadata, {id: sourceId})
// Get the newly created noun
sourceNoun = this.index.getNouns().get(sourceId)
console.warn(`Auto-created missing source noun with ID ${sourceId}`)
} catch (createError) {
console.error(`Failed to auto-create source noun with ID ${sourceId}:`, createError)
throw new Error(`Failed to auto-create source noun with ID ${sourceId}: ${createError}`)
}
}
if (!targetNoun && options.autoCreateMissingNouns) {
try {
// Create a placeholder vector for the missing noun
const placeholderVector = new Array(this._dimensions).fill(0)
// Add metadata if provided
const metadata = options.missingNounMetadata || {
autoCreated: true,
createdAt: new Date().toISOString(),
noun: NounType.Concept
}
// Add the missing noun
await this.add(placeholderVector, metadata, {id: targetId})
// Get the newly created noun
targetNoun = this.index.getNouns().get(targetId)
console.warn(`Auto-created missing target noun with ID ${targetId}`)
} catch (createError) {
console.error(`Failed to auto-create target noun with ID ${targetId}:`, createError)
throw new Error(`Failed to auto-create target noun with ID ${targetId}: ${createError}`)
}
}
if (!sourceNoun) { if (!sourceNoun) {
throw new Error(`Source noun with ID ${sourceId} not found`) throw new Error(`Source noun with ID ${sourceId} not found`)