docs: update README.md and suppress TensorFlow.js warnings
Enhanced the installation section with guidance on resolving TensorFlow.js dependency conflicts using `--legacy-peer-deps`. Added CLI autocomplete setup instructions to improve user experience. Suppressed specific TensorFlow.js Node.js backend warnings in the embedding utils. Updated dependencies to the latest versions.
This commit is contained in:
parent
bdb0b98b74
commit
be67c1b753
5 changed files with 345 additions and 193 deletions
68
README.md
68
README.md
|
|
@ -30,14 +30,14 @@ Brainy combines three key technologies:
|
|||
Brainy uses a graph-based data model with two primary concepts:
|
||||
|
||||
1. **Nouns**: The main entities in your data (nodes in the graph)
|
||||
- Each noun has a unique ID, vector representation, and metadata
|
||||
- Nouns can be categorized by type (Person, Place, Thing, Event, Concept, etc.)
|
||||
- Nouns are automatically vectorized for similarity search
|
||||
- Each noun has a unique ID, vector representation, and metadata
|
||||
- Nouns can be categorized by type (Person, Place, Thing, Event, Concept, etc.)
|
||||
- Nouns are automatically vectorized for similarity search
|
||||
|
||||
2. **Verbs**: Relationships between nouns (edges in the graph)
|
||||
- Each verb connects a source noun to a target noun
|
||||
- Verbs have types that define the relationship (RelatedTo, Controls, Contains, etc.)
|
||||
- Verbs can have their own metadata to describe the relationship
|
||||
- Each verb connects a source noun to a target noun
|
||||
- Verbs have types that define the relationship (RelatedTo, Controls, Contains, etc.)
|
||||
- Verbs can have their own metadata to describe the relationship
|
||||
|
||||
## What Can You Use It For?
|
||||
|
||||
|
|
@ -49,13 +49,27 @@ Brainy uses a graph-based data model with two primary concepts:
|
|||
|
||||
## Installation
|
||||
|
||||
Due to a dependency conflict between TensorFlow.js packages, you need to use the `--legacy-peer-deps` flag when
|
||||
installing:
|
||||
|
||||
```bash
|
||||
npm install @soulcraft/brainy
|
||||
npm install @soulcraft/brainy --legacy-peer-deps
|
||||
```
|
||||
|
||||
If you encounter an error like this:
|
||||
|
||||
```
|
||||
npm error ERESOLVE unable to resolve dependency tree
|
||||
npm error Found: @tensorflow/tfjs-core@4.22.0
|
||||
npm error Could not resolve dependency: peer @tensorflow/tfjs-core@"3.21.0" from @tensorflow/tfjs-converter@3.21.0
|
||||
```
|
||||
|
||||
Use the `--legacy-peer-deps` flag as shown above to resolve it.
|
||||
|
||||
## Command Line Interface
|
||||
|
||||
Brainy includes a command-line interface (CLI) that allows you to experiment with the API and data directly from the terminal.
|
||||
Brainy includes a command-line interface (CLI) that allows you to experiment with the API and data directly from the
|
||||
terminal.
|
||||
|
||||
### Using the CLI during development
|
||||
|
||||
|
|
@ -83,8 +97,8 @@ npm run cli status
|
|||
### Installing the CLI globally
|
||||
|
||||
```bash
|
||||
# Install the package globally
|
||||
npm install -g @soulcraft/brainy
|
||||
# Install the package globally (with --legacy-peer-deps to resolve TensorFlow.js dependency conflicts)
|
||||
npm install -g @soulcraft/brainy --legacy-peer-deps
|
||||
|
||||
# Now you can use the 'brainy' command directly
|
||||
brainy help
|
||||
|
|
@ -102,6 +116,28 @@ brainy add "Some text" '{"noun":"Thing"}'
|
|||
- `addVerb <sourceId> <targetId> <verbType> [metadata]` - Add a relationship between nouns
|
||||
- `getVerbs <id>` - Get all relationships for a noun
|
||||
- `status` - Show database status
|
||||
- `completion-setup` - Setup shell autocomplete for the Brainy CLI
|
||||
|
||||
### Autocomplete
|
||||
|
||||
The CLI supports autocomplete for commands, noun types, and verb types. To enable autocomplete:
|
||||
|
||||
```bash
|
||||
# Set up autocomplete for your shell
|
||||
brainy completion-setup
|
||||
|
||||
# Restart your shell or source your shell configuration file
|
||||
# For bash:
|
||||
source ~/.bashrc
|
||||
|
||||
# For zsh:
|
||||
source ~/.zshrc
|
||||
```
|
||||
|
||||
Once enabled, you can use tab completion for:
|
||||
- Commands (e.g., `brainy a<tab>` completes to `brainy add`)
|
||||
- Noun types in metadata (e.g., when adding nouns)
|
||||
- Verb types (e.g., when adding relationships)
|
||||
|
||||
## Basic Usage
|
||||
|
||||
|
|
@ -237,8 +273,8 @@ const status = await db.status();
|
|||
```typescript
|
||||
// Add a noun (automatically vectorized)
|
||||
const id = await db.add(textOrVector, {
|
||||
noun: NounType.Thing,
|
||||
// other metadata...
|
||||
noun: NounType.Thing,
|
||||
// other metadata...
|
||||
});
|
||||
|
||||
// Retrieve a noun
|
||||
|
|
@ -246,8 +282,8 @@ const noun = await db.get(id);
|
|||
|
||||
// Update noun metadata
|
||||
await db.updateMetadata(id, {
|
||||
noun: NounType.Thing,
|
||||
// updated metadata...
|
||||
noun: NounType.Thing,
|
||||
// updated metadata...
|
||||
});
|
||||
|
||||
// Delete a noun
|
||||
|
|
@ -266,8 +302,8 @@ const thingNouns = await db.searchByNounTypes([NounType.Thing], numResults);
|
|||
```typescript
|
||||
// Add a relationship between nouns
|
||||
await db.addVerb(sourceId, targetId, {
|
||||
verb: VerbType.RelatedTo,
|
||||
// other metadata...
|
||||
verb: VerbType.RelatedTo,
|
||||
// other metadata...
|
||||
});
|
||||
|
||||
// Get all relationships
|
||||
|
|
|
|||
151
package-lock.json
generated
151
package-lock.json
generated
|
|
@ -7,6 +7,7 @@
|
|||
"": {
|
||||
"name": "@soulcraft/brainy",
|
||||
"version": "0.7.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.427.0",
|
||||
|
|
@ -16,6 +17,7 @@
|
|||
"@tensorflow/tfjs-core": "^4.22.0",
|
||||
"@tensorflow/tfjs-layers": "^4.22.0",
|
||||
"commander": "^14.0.0",
|
||||
"omelette": "^0.4.17",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -24,6 +26,7 @@
|
|||
"devDependencies": {
|
||||
"@types/jest": "^29.5.3",
|
||||
"@types/node": "^20.4.5",
|
||||
"@types/omelette": "^0.4.5",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
|
|
@ -253,9 +256,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/client-s3": {
|
||||
"version": "3.823.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.823.0.tgz",
|
||||
"integrity": "sha512-cTp1Lkyv5NuHr6aUin5FCARY02o2jiOcRKnWnAahEQrlvgzOAe4SrjjOVVTH67wHdcB9zGeNDNCK/132+zaRow==",
|
||||
"version": "3.824.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.824.0.tgz",
|
||||
"integrity": "sha512-7neTQIdSVP/F4RTWG5T87LDpB955iQD6lxg9nJ00fdkIPczDcRtAEXow44NjF4fEdpQ1A9jokUtBSVE+GMXZ/A==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-crypto/sha1-browser": "5.2.0",
|
||||
|
|
@ -274,7 +277,7 @@
|
|||
"@aws-sdk/middleware-ssec": "3.821.0",
|
||||
"@aws-sdk/middleware-user-agent": "3.823.0",
|
||||
"@aws-sdk/region-config-resolver": "3.821.0",
|
||||
"@aws-sdk/signature-v4-multi-region": "3.823.0",
|
||||
"@aws-sdk/signature-v4-multi-region": "3.824.0",
|
||||
"@aws-sdk/types": "3.821.0",
|
||||
"@aws-sdk/util-endpoints": "3.821.0",
|
||||
"@aws-sdk/util-user-agent-browser": "3.821.0",
|
||||
|
|
@ -770,9 +773,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@aws-sdk/signature-v4-multi-region": {
|
||||
"version": "3.823.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.823.0.tgz",
|
||||
"integrity": "sha512-FAvtmR7G0ppNLa4O2yN8koFYUmUmPuL60UBIFrVb3BBeZvBIFLln69lB8EGtTBpAvVbxknudRZCzYtnOhE4QXg==",
|
||||
"version": "3.824.0",
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.824.0.tgz",
|
||||
"integrity": "sha512-HBjuWeN6Z1pvJjUvGXdMNLwEypKKB4km6zXj9jsbOOwP8NTL6J5rY+JmlX/mfBTmvzmI0kMu2bxlQ4ME2CIRbA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/middleware-sdk-s3": "3.823.0",
|
||||
|
|
@ -921,9 +924,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/compat-data": {
|
||||
"version": "7.27.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.3.tgz",
|
||||
"integrity": "sha512-V42wFfx1ymFte+ecf6iXghnnP8kWTO+ZLXIyZq+1LAXHHvTZdVxicn4yiVYdYMGaCO3tmqub11AorKkv+iodqw==",
|
||||
"version": "7.27.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.5.tgz",
|
||||
"integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
|
|
@ -972,13 +975,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/generator": {
|
||||
"version": "7.27.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.3.tgz",
|
||||
"integrity": "sha512-xnlJYj5zepml8NXtjkG0WquFUv8RskFqyFcVgTBp5k+NaA/8uw/K+OSVf8AMGw5e9HKP2ETd5xpK5MLZQD6b4Q==",
|
||||
"version": "7.27.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz",
|
||||
"integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.27.3",
|
||||
"@babel/parser": "^7.27.5",
|
||||
"@babel/types": "^7.27.3",
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.25",
|
||||
|
|
@ -1088,23 +1091,23 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/helpers": {
|
||||
"version": "7.27.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.4.tgz",
|
||||
"integrity": "sha512-Y+bO6U+I7ZKaM5G5rDUZiYfUvQPUibYmAFe7EnKdnKBbVXDZxvp+MWOH5gYciY0EPk4EScsuFMQBbEfpdRKSCQ==",
|
||||
"version": "7.27.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz",
|
||||
"integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/types": "^7.27.3"
|
||||
"@babel/types": "^7.27.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.27.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.4.tgz",
|
||||
"integrity": "sha512-BRmLHGwpUqLFR2jzx9orBuX/ABDkj2jLKOXrHDTN2aOKL+jFDDKaRNo9nyYsIl9h/UE/7lMKdDjKQQyxKKDZ7g==",
|
||||
"version": "7.27.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz",
|
||||
"integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
@ -1401,9 +1404,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.27.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.3.tgz",
|
||||
"integrity": "sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==",
|
||||
"version": "7.27.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz",
|
||||
"integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
@ -2142,9 +2145,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@smithy/core": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.5.1.tgz",
|
||||
"integrity": "sha512-xSw7bZEFKwOKrm/iv8e2BLt2ur98YZdrRD6nII8ditQeUsY2Q1JmIQ0rpILOhaLKYxxG2ivnoOpokzr9qLyDWA==",
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.5.3.tgz",
|
||||
"integrity": "sha512-xa5byV9fEguZNofCclv6v9ra0FYh5FATQW/da7FQUVTic94DfrN/NvmKZjrMyzbpqfot9ZjBaO8U1UeTbmSLuA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/middleware-serde": "^4.0.8",
|
||||
|
|
@ -2361,12 +2364,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@smithy/middleware-endpoint": {
|
||||
"version": "4.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.9.tgz",
|
||||
"integrity": "sha512-AjDgX4UjORLltD/LZCBQTwjQqEfyrx/GeDTHcYLzIgf87pIT70tMWnN87NQpJru1K4ITirY2htSOxNECZJCBOg==",
|
||||
"version": "4.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.11.tgz",
|
||||
"integrity": "sha512-zDogwtRLzKl58lVS8wPcARevFZNBOOqnmzWWxVe9XiaXU2CADFjvJ9XfNibgkOWs08sxLuSr81NrpY4mgp9OwQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/core": "^3.5.1",
|
||||
"@smithy/core": "^3.5.3",
|
||||
"@smithy/middleware-serde": "^4.0.8",
|
||||
"@smithy/node-config-provider": "^4.1.3",
|
||||
"@smithy/shared-ini-file-loader": "^4.0.4",
|
||||
|
|
@ -2380,15 +2383,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@smithy/middleware-retry": {
|
||||
"version": "4.1.10",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.10.tgz",
|
||||
"integrity": "sha512-RyhcA3sZIIvAo6r48b2Nx2qfg0OnyohlaV0fw415xrQyx5HQ2bvHl9vs/WBiDXIP49mCfws5wX4308c9Pi/isw==",
|
||||
"version": "4.1.12",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.12.tgz",
|
||||
"integrity": "sha512-wvIH70c4e91NtRxdaLZF+mbLZ/HcC6yg7ySKUiufL6ESp6zJUSnJucZ309AvG9nqCFHSRB5I6T3Ez1Q9wCh0Ww==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/node-config-provider": "^4.1.3",
|
||||
"@smithy/protocol-http": "^5.1.2",
|
||||
"@smithy/service-error-classification": "^4.0.5",
|
||||
"@smithy/smithy-client": "^4.4.1",
|
||||
"@smithy/smithy-client": "^4.4.3",
|
||||
"@smithy/types": "^4.3.1",
|
||||
"@smithy/util-middleware": "^4.0.4",
|
||||
"@smithy/util-retry": "^4.0.5",
|
||||
|
|
@ -2555,13 +2558,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@smithy/smithy-client": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.1.tgz",
|
||||
"integrity": "sha512-XPbcHRfd0iwx8dY5XCBCGyI7uweMW0oezYezxXcG8ANgvZ5YPuC6Ylh+n0bTHpdU3SCMZOnhzgVklYz+p3fIhw==",
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.3.tgz",
|
||||
"integrity": "sha512-xxzNYgA0HD6ETCe5QJubsxP0hQH3QK3kbpJz3QrosBCuIWyEXLR/CO5hFb2OeawEKUxMNhz3a1nuJNN2np2RMA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/core": "^3.5.1",
|
||||
"@smithy/middleware-endpoint": "^4.1.9",
|
||||
"@smithy/core": "^3.5.3",
|
||||
"@smithy/middleware-endpoint": "^4.1.11",
|
||||
"@smithy/middleware-stack": "^4.0.4",
|
||||
"@smithy/protocol-http": "^5.1.2",
|
||||
"@smithy/types": "^4.3.1",
|
||||
|
|
@ -2662,13 +2665,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@smithy/util-defaults-mode-browser": {
|
||||
"version": "4.0.17",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.17.tgz",
|
||||
"integrity": "sha512-HXq5181qnXmIwB7VrwqwP8rsJybHMoYuJnNoXy4PROs2pfSI4sWDMASF2i+7Lo+u64Y6xowhegcdxczowgJtZg==",
|
||||
"version": "4.0.19",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.19.tgz",
|
||||
"integrity": "sha512-mvLMh87xSmQrV5XqnUYEPoiFFeEGYeAKIDDKdhE2ahqitm8OHM3aSvhqL6rrK6wm1brIk90JhxDf5lf2hbrLbQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/property-provider": "^4.0.4",
|
||||
"@smithy/smithy-client": "^4.4.1",
|
||||
"@smithy/smithy-client": "^4.4.3",
|
||||
"@smithy/types": "^4.3.1",
|
||||
"bowser": "^2.11.0",
|
||||
"tslib": "^2.6.2"
|
||||
|
|
@ -2678,16 +2681,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@smithy/util-defaults-mode-node": {
|
||||
"version": "4.0.17",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.17.tgz",
|
||||
"integrity": "sha512-RfU2A5LjFhEHw4Nwl1GZNitK4AUWu5jGtigAUDoQtfDUvYHpQxcuLw2QGAdKDtKRflIiHSZ8wXBDR36H9R2Ang==",
|
||||
"version": "4.0.19",
|
||||
"resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.19.tgz",
|
||||
"integrity": "sha512-8tYnx+LUfj6m+zkUUIrIQJxPM1xVxfRBvoGHua7R/i6qAxOMjqR6CpEpDwKoIs1o0+hOjGvkKE23CafKL0vJ9w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/config-resolver": "^4.1.4",
|
||||
"@smithy/credential-provider-imds": "^4.0.6",
|
||||
"@smithy/node-config-provider": "^4.1.3",
|
||||
"@smithy/property-provider": "^4.0.4",
|
||||
"@smithy/smithy-client": "^4.4.1",
|
||||
"@smithy/smithy-client": "^4.4.3",
|
||||
"@smithy/types": "^4.3.1",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
|
|
@ -2872,6 +2875,15 @@
|
|||
"@tensorflow/tfjs-core": "4.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tensorflow/tfjs-converter": {
|
||||
"version": "4.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.22.0.tgz",
|
||||
"integrity": "sha512-PT43MGlnzIo+YfbsjM79Lxk9lOq6uUwZuCc8rrp0hfpLjF6Jv8jS84u2jFb+WpUeuF4K33ZDNx8CjiYrGQ2trQ==",
|
||||
"license": "Apache-2.0",
|
||||
"peerDependencies": {
|
||||
"@tensorflow/tfjs-core": "4.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tensorflow/tfjs-core": {
|
||||
"version": "4.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.22.0.tgz",
|
||||
|
|
@ -2920,15 +2932,6 @@
|
|||
"@tensorflow/tfjs-core": "4.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tensorflow/tfjs/node_modules/@tensorflow/tfjs-converter": {
|
||||
"version": "4.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.22.0.tgz",
|
||||
"integrity": "sha512-PT43MGlnzIo+YfbsjM79Lxk9lOq6uUwZuCc8rrp0hfpLjF6Jv8jS84u2jFb+WpUeuF4K33ZDNx8CjiYrGQ2trQ==",
|
||||
"license": "Apache-2.0",
|
||||
"peerDependencies": {
|
||||
"@tensorflow/tfjs-core": "4.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||
|
|
@ -3060,6 +3063,13 @@
|
|||
"integrity": "sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/omelette": {
|
||||
"version": "0.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/omelette/-/omelette-0.4.5.tgz",
|
||||
"integrity": "sha512-zUCJpVRwfMcZfkxSCGp73mgd3/xesvPz5tQJIORlfP/zkYEyp9KUfF7IP3RRjyZR3DwxkPs96/IFf70GmYZYHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/seedrandom": {
|
||||
"version": "2.4.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.34.tgz",
|
||||
|
|
@ -3713,9 +3723,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001720",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001720.tgz",
|
||||
"integrity": "sha512-Ec/2yV2nNPwb4DnTANEV99ZWwm3ZWfdlfkQbWSDDt+PsXEVYwlhPH8tdMaPunYTKKmz7AnHi2oNEi1GcmKCD8g==",
|
||||
"version": "1.0.30001721",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz",
|
||||
"integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -4048,9 +4058,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.162",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.162.tgz",
|
||||
"integrity": "sha512-hQA+Zb5QQwoSaXJWEAGEw1zhk//O7qDzib05Z4qTqZfNju/FAkrm5ZInp0JbTp4Z18A6bilopdZWEYrFSsfllA==",
|
||||
"version": "1.5.165",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.165.tgz",
|
||||
"integrity": "sha512-naiMx1Z6Nb2TxPU6fiFrUrDTjyPMLdTtaOd2oLmG8zVSg2hCWGkhPyxwk+qRmZ1ytwVqUv0u7ZcDA5+ALhaUtw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
|
|
@ -4571,14 +4581,15 @@
|
|||
"license": "ISC"
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
|
||||
"integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
|
||||
"integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
|
|
@ -6163,6 +6174,14 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/omelette": {
|
||||
"version": "0.4.17",
|
||||
"resolved": "https://registry.npmjs.org/omelette/-/omelette-0.4.17.tgz",
|
||||
"integrity": "sha512-UlU69G6Bhu0XFjw3tjFZ0qyiMUjAOR+rdzblA1nLQ8xiqFtxOVlkhM39BlgTpLFx9fxkm6rnxNNRsS5GxE/yww==",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@
|
|||
"version:patch": "npm version patch",
|
||||
"version:minor": "npm version minor",
|
||||
"version:major": "npm version major",
|
||||
"deploy": "npm run build && npm publish"
|
||||
"deploy": "npm run build && npm publish",
|
||||
"postinstall": "echo 'Note: If you encounter dependency conflicts with TensorFlow.js packages, please use: npm install --legacy-peer-deps'"
|
||||
},
|
||||
"bin": {
|
||||
"brainy": "dist/cli.js"
|
||||
|
|
@ -55,6 +56,7 @@
|
|||
"devDependencies": {
|
||||
"@types/jest": "^29.5.3",
|
||||
"@types/node": "^20.4.5",
|
||||
"@types/omelette": "^0.4.5",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
|
|
@ -71,6 +73,7 @@
|
|||
"@tensorflow/tfjs-core": "^4.22.0",
|
||||
"@tensorflow/tfjs-layers": "^4.22.0",
|
||||
"commander": "^14.0.0",
|
||||
"omelette": "^0.4.17",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"prettier": {
|
||||
|
|
|
|||
299
src/cli.ts
299
src/cli.ts
|
|
@ -5,86 +5,87 @@
|
|||
* A command-line interface for interacting with the Brainy vector database
|
||||
*/
|
||||
|
||||
import { BrainyData, NounType, VerbType, FileSystemStorage } from './index.js';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname, join } from 'path';
|
||||
import fs from 'fs';
|
||||
import { Command } from 'commander';
|
||||
import { BrainyData, NounType, VerbType, FileSystemStorage } from './index.js'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { dirname, join } from 'path'
|
||||
import fs from 'fs'
|
||||
import { Command } from 'commander'
|
||||
import omelette from 'omelette'
|
||||
|
||||
// Get the directory of the current module
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const __dirname = dirname(__filename)
|
||||
|
||||
// Import package.json for version info
|
||||
const packageJson = {
|
||||
name: '@soulcraft/brainy',
|
||||
version: '0.6.0',
|
||||
description: 'A vector database using HNSW indexing with Origin Private File System storage'
|
||||
};
|
||||
}
|
||||
|
||||
// Helper function to parse JSON safely
|
||||
function parseJSON(str: string): any {
|
||||
try {
|
||||
return JSON.parse(str);
|
||||
return JSON.parse(str)
|
||||
} catch (e) {
|
||||
console.error('Error parsing JSON:', (e as Error).message);
|
||||
return {};
|
||||
console.error('Error parsing JSON:', (e as Error).message)
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to resolve noun type
|
||||
function resolveNounType(type: string | number | undefined): NounType {
|
||||
if (!type) return NounType.Thing;
|
||||
if (!type) return NounType.Thing
|
||||
|
||||
// If it's a string, try to match it to a NounType
|
||||
if (typeof type === 'string') {
|
||||
const nounTypeKey = Object.keys(NounType).find(
|
||||
key => key.toLowerCase() === type.toLowerCase()
|
||||
);
|
||||
return nounTypeKey ? NounType[nounTypeKey as keyof typeof NounType] : NounType.Thing;
|
||||
)
|
||||
return nounTypeKey ? NounType[nounTypeKey as keyof typeof NounType] : NounType.Thing
|
||||
}
|
||||
|
||||
// Convert number to string type for safety
|
||||
return Object.values(NounType)[type as number] || NounType.Thing;
|
||||
return Object.values(NounType)[type as number] || NounType.Thing
|
||||
}
|
||||
|
||||
// Helper function to resolve verb type
|
||||
function resolveVerbType(type: string | number | undefined): VerbType {
|
||||
if (!type) return VerbType.RelatedTo;
|
||||
if (!type) return VerbType.RelatedTo
|
||||
|
||||
// If it's a string, try to match it to a VerbType
|
||||
if (typeof type === 'string') {
|
||||
const verbTypeKey = Object.keys(VerbType).find(
|
||||
key => key.toLowerCase() === type.toLowerCase()
|
||||
);
|
||||
return verbTypeKey ? VerbType[verbTypeKey as keyof typeof VerbType] : VerbType.RelatedTo;
|
||||
)
|
||||
return verbTypeKey ? VerbType[verbTypeKey as keyof typeof VerbType] : VerbType.RelatedTo
|
||||
}
|
||||
|
||||
// Convert number to string type for safety
|
||||
return Object.values(VerbType)[type as number] || VerbType.RelatedTo;
|
||||
return Object.values(VerbType)[type as number] || VerbType.RelatedTo
|
||||
}
|
||||
|
||||
// Create a new Command instance
|
||||
const program = new Command();
|
||||
const program = new Command()
|
||||
|
||||
// Configure the program
|
||||
program
|
||||
.name(packageJson.name)
|
||||
.description(packageJson.description)
|
||||
.version(packageJson.version);
|
||||
.version(packageJson.version)
|
||||
|
||||
// Create data directory if it doesn't exist
|
||||
const dataDir = join(__dirname, '..', 'data');
|
||||
const dataDir = join(__dirname, '..', 'data')
|
||||
if (!fs.existsSync(dataDir)) {
|
||||
fs.mkdirSync(dataDir, { recursive: true });
|
||||
fs.mkdirSync(dataDir, { recursive: true })
|
||||
}
|
||||
|
||||
// Create a database instance with file system storage
|
||||
const createDb = () => {
|
||||
return new BrainyData({
|
||||
storageAdapter: new FileSystemStorage(dataDir)
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
// Define commands
|
||||
program
|
||||
|
|
@ -92,14 +93,14 @@ program
|
|||
.description('Initialize a new database')
|
||||
.action(async () => {
|
||||
try {
|
||||
const db = createDb();
|
||||
await db.init();
|
||||
console.log('Database initialized successfully');
|
||||
const db = createDb()
|
||||
await db.init()
|
||||
console.log('Database initialized successfully')
|
||||
} catch (error) {
|
||||
console.error('Error:', (error as Error).message);
|
||||
process.exit(1);
|
||||
console.error('Error:', (error as Error).message)
|
||||
process.exit(1)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
program
|
||||
.command('add')
|
||||
|
|
@ -108,23 +109,23 @@ program
|
|||
.argument('[metadata]', 'Optional metadata as JSON string')
|
||||
.action(async (text, metadataStr) => {
|
||||
try {
|
||||
const db = createDb();
|
||||
await db.init();
|
||||
const db = createDb()
|
||||
await db.init()
|
||||
|
||||
const metadata = metadataStr ? parseJSON(metadataStr) : {};
|
||||
const metadata = metadataStr ? parseJSON(metadataStr) : {}
|
||||
|
||||
// Process metadata to handle noun type
|
||||
if (metadata.noun) {
|
||||
metadata.noun = resolveNounType(metadata.noun);
|
||||
metadata.noun = resolveNounType(metadata.noun)
|
||||
}
|
||||
|
||||
const id = await db.add(text, metadata);
|
||||
console.log(`Added noun with ID: ${id}`);
|
||||
const id = await db.add(text, metadata)
|
||||
console.log(`Added noun with ID: ${id}`)
|
||||
} catch (error) {
|
||||
console.error('Error:', (error as Error).message);
|
||||
process.exit(1);
|
||||
console.error('Error:', (error as Error).message)
|
||||
process.exit(1)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
program
|
||||
.command('search')
|
||||
|
|
@ -133,25 +134,25 @@ program
|
|||
.option('-l, --limit <number>', 'Maximum number of results to return', '5')
|
||||
.action(async (query, options) => {
|
||||
try {
|
||||
const db = createDb();
|
||||
await db.init();
|
||||
const db = createDb()
|
||||
await db.init()
|
||||
|
||||
const limit = parseInt(options.limit, 10);
|
||||
const results = await db.searchText(query, limit);
|
||||
const limit = parseInt(options.limit, 10)
|
||||
const results = await db.searchText(query, limit)
|
||||
|
||||
console.log(`Search results for "${query}":`);
|
||||
console.log(`Search results for "${query}":`)
|
||||
results.forEach((result, index) => {
|
||||
console.log(`${index + 1}. ID: ${result.id}`);
|
||||
console.log(` Score: ${result.score.toFixed(4)}`);
|
||||
console.log(` Metadata: ${JSON.stringify(result.metadata)}`);
|
||||
console.log(` Vector: [${result.vector.slice(0, 3).map(v => v.toFixed(2)).join(', ')}...]`);
|
||||
console.log();
|
||||
});
|
||||
console.log(`${index + 1}. ID: ${result.id}`)
|
||||
console.log(` Score: ${result.score.toFixed(4)}`)
|
||||
console.log(` Metadata: ${JSON.stringify(result.metadata)}`)
|
||||
console.log(` Vector: [${result.vector.slice(0, 3).map(v => v.toFixed(2)).join(', ')}...]`)
|
||||
console.log()
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error:', (error as Error).message);
|
||||
process.exit(1);
|
||||
console.error('Error:', (error as Error).message)
|
||||
process.exit(1)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
program
|
||||
.command('get')
|
||||
|
|
@ -159,22 +160,22 @@ program
|
|||
.argument('<id>', 'ID of the noun to get')
|
||||
.action(async (id) => {
|
||||
try {
|
||||
const db = createDb();
|
||||
await db.init();
|
||||
const db = createDb()
|
||||
await db.init()
|
||||
|
||||
const noun = await db.get(id);
|
||||
const noun = await db.get(id)
|
||||
if (noun) {
|
||||
console.log(`Noun ID: ${noun.id}`);
|
||||
console.log(`Metadata: ${JSON.stringify(noun.metadata)}`);
|
||||
console.log(`Vector: [${noun.vector.slice(0, 5).map(v => v.toFixed(2)).join(', ')}...]`);
|
||||
console.log(`Noun ID: ${noun.id}`)
|
||||
console.log(`Metadata: ${JSON.stringify(noun.metadata)}`)
|
||||
console.log(`Vector: [${noun.vector.slice(0, 5).map(v => v.toFixed(2)).join(', ')}...]`)
|
||||
} else {
|
||||
console.log(`No noun found with ID: ${id}`);
|
||||
console.log(`No noun found with ID: ${id}`)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', (error as Error).message);
|
||||
process.exit(1);
|
||||
console.error('Error:', (error as Error).message)
|
||||
process.exit(1)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
program
|
||||
.command('delete')
|
||||
|
|
@ -182,16 +183,16 @@ program
|
|||
.argument('<id>', 'ID of the noun to delete')
|
||||
.action(async (id) => {
|
||||
try {
|
||||
const db = createDb();
|
||||
await db.init();
|
||||
const db = createDb()
|
||||
await db.init()
|
||||
|
||||
await db.delete(id);
|
||||
console.log(`Deleted noun with ID: ${id}`);
|
||||
await db.delete(id)
|
||||
console.log(`Deleted noun with ID: ${id}`)
|
||||
} catch (error) {
|
||||
console.error('Error:', (error as Error).message);
|
||||
process.exit(1);
|
||||
console.error('Error:', (error as Error).message)
|
||||
process.exit(1)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
program
|
||||
.command('addVerb')
|
||||
|
|
@ -202,22 +203,25 @@ program
|
|||
.argument('[metadata]', 'Optional metadata as JSON string')
|
||||
.action(async (sourceId, targetId, verbTypeStr, metadataStr) => {
|
||||
try {
|
||||
const db = createDb();
|
||||
await db.init();
|
||||
const db = createDb()
|
||||
await db.init()
|
||||
|
||||
const verbType = resolveVerbType(verbTypeStr);
|
||||
const verbMetadata = metadataStr ? parseJSON(metadataStr) : {};
|
||||
const verbType = resolveVerbType(verbTypeStr)
|
||||
const verbMetadata = metadataStr ? parseJSON(metadataStr) : {}
|
||||
|
||||
// Add verb type to metadata
|
||||
verbMetadata.verb = verbType;
|
||||
verbMetadata.verb = verbType
|
||||
|
||||
const verbId = await db.addVerb(sourceId, targetId, verbMetadata);
|
||||
console.log(`Added verb with ID: ${verbId}`);
|
||||
const verbId = await db.addVerb(sourceId, targetId, undefined, {
|
||||
type: verbType,
|
||||
metadata: verbMetadata
|
||||
})
|
||||
console.log(`Added verb with ID: ${verbId}`)
|
||||
} catch (error) {
|
||||
console.error('Error:', (error as Error).message);
|
||||
process.exit(1);
|
||||
console.error('Error:', (error as Error).message)
|
||||
process.exit(1)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
program
|
||||
.command('getVerbs')
|
||||
|
|
@ -225,55 +229,55 @@ program
|
|||
.argument('<id>', 'ID of the noun to get relationships for')
|
||||
.action(async (id) => {
|
||||
try {
|
||||
const db = createDb();
|
||||
await db.init();
|
||||
const db = createDb()
|
||||
await db.init()
|
||||
|
||||
const verbs = await db.getVerbsBySource(id);
|
||||
const verbs = await db.getVerbsBySource(id)
|
||||
|
||||
console.log(`Relationships for noun ${id}:`);
|
||||
console.log(`Relationships for noun ${id}:`)
|
||||
if (verbs.length === 0) {
|
||||
console.log('No relationships found');
|
||||
console.log('No relationships found')
|
||||
} else {
|
||||
verbs.forEach((verb, index) => {
|
||||
console.log(`${index + 1}. ID: ${verb.id}`);
|
||||
console.log(` Type: ${Object.keys(VerbType).find(key => VerbType[key as keyof typeof VerbType] === verb.metadata.verb) || verb.metadata.verb}`);
|
||||
console.log(` Target: ${verb.targetId}`);
|
||||
console.log(` Metadata: ${JSON.stringify(verb.metadata)}`);
|
||||
console.log();
|
||||
});
|
||||
console.log(`${index + 1}. ID: ${verb.id}`)
|
||||
console.log(` Type: ${Object.keys(VerbType).find(key => VerbType[key as keyof typeof VerbType] === verb.metadata.verb) || verb.metadata.verb}`)
|
||||
console.log(` Target: ${verb.targetId}`)
|
||||
console.log(` Metadata: ${JSON.stringify(verb.metadata)}`)
|
||||
console.log()
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', (error as Error).message);
|
||||
process.exit(1);
|
||||
console.error('Error:', (error as Error).message)
|
||||
process.exit(1)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
program
|
||||
.command('status')
|
||||
.description('Show database status')
|
||||
.action(async () => {
|
||||
try {
|
||||
const db = createDb();
|
||||
await db.init();
|
||||
const db = createDb()
|
||||
await db.init()
|
||||
|
||||
const status = await db.status();
|
||||
console.log('Database Status:');
|
||||
console.log(`Storage type: ${status.type}`);
|
||||
console.log(`Storage used: ${status.used} bytes`);
|
||||
console.log(`Storage quota: ${status.quota !== null ? `${status.quota} bytes` : 'unlimited'}`);
|
||||
const status = await db.status()
|
||||
console.log('Database Status:')
|
||||
console.log(`Storage type: ${status.type}`)
|
||||
console.log(`Storage used: ${status.used} bytes`)
|
||||
console.log(`Storage quota: ${status.quota !== null ? `${status.quota} bytes` : 'unlimited'}`)
|
||||
|
||||
// Display additional details if available
|
||||
if (status.details) {
|
||||
console.log('Additional details:');
|
||||
console.log('Additional details:')
|
||||
Object.entries(status.details).forEach(([key, value]) => {
|
||||
console.log(` ${key}: ${JSON.stringify(value)}`);
|
||||
});
|
||||
console.log(` ${key}: ${JSON.stringify(value)}`)
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error:', (error as Error).message);
|
||||
process.exit(1);
|
||||
console.error('Error:', (error as Error).message)
|
||||
process.exit(1)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// Add examples to help text
|
||||
program.addHelpText('after', `
|
||||
|
|
@ -282,7 +286,82 @@ Examples:
|
|||
$ brainy add "Cats are independent pets" '{"noun":"Thing","category":"animal"}'
|
||||
$ brainy search "feline pets" --limit 5
|
||||
$ brainy addVerb id1 id2 RelatedTo '{"description":"Both are pets"}'
|
||||
`);
|
||||
`)
|
||||
|
||||
// Setup autocomplete
|
||||
const completion = omelette('brainy')
|
||||
|
||||
// Helper function to get all noun types
|
||||
const getNounTypes = () => Object.keys(NounType)
|
||||
|
||||
// Helper function to get all verb types
|
||||
const getVerbTypes = () => Object.keys(VerbType)
|
||||
|
||||
// Define autocomplete handlers
|
||||
completion.tree({
|
||||
// First level commands - suggest all available commands
|
||||
_: () => [
|
||||
'add',
|
||||
'addVerb',
|
||||
'search',
|
||||
'get',
|
||||
'delete',
|
||||
'getVerbs',
|
||||
'status',
|
||||
'completion-setup',
|
||||
'init',
|
||||
'help'
|
||||
],
|
||||
// Command-specific completions
|
||||
add: {
|
||||
// For the second argument of 'add' command (metadata)
|
||||
_: () => {
|
||||
// Generate templates for each noun type
|
||||
return getNounTypes().map(type =>
|
||||
`{"noun":"${type}","category":"example"}`
|
||||
)
|
||||
}
|
||||
},
|
||||
addVerb: {
|
||||
// First two arguments are IDs, third is verb type
|
||||
'<sourceId>': {
|
||||
'<targetId>': {
|
||||
_: () => {
|
||||
// Suggest all available verb types
|
||||
return getVerbTypes()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// Add autocomplete for other commands
|
||||
search: {},
|
||||
get: {},
|
||||
delete: {},
|
||||
getVerbs: {},
|
||||
status: {},
|
||||
'completion-setup': {},
|
||||
init: {},
|
||||
help: {}
|
||||
})
|
||||
|
||||
// Initialize autocomplete
|
||||
completion.init()
|
||||
|
||||
// If this script is run with --completion-setup flag, set up the autocomplete
|
||||
if (process.argv.includes('--completion-setup')) {
|
||||
completion.setupShellInitFile()
|
||||
console.log('Autocomplete setup complete. Please restart your shell.')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
// Add a command for setting up autocomplete
|
||||
program
|
||||
.command('completion-setup')
|
||||
.description('Setup shell autocomplete for the Brainy CLI')
|
||||
.action(() => {
|
||||
completion.setupShellInitFile()
|
||||
console.log('Autocomplete setup complete. Please restart your shell.')
|
||||
})
|
||||
|
||||
// Parse command line arguments
|
||||
program.parse();
|
||||
program.parse()
|
||||
|
|
|
|||
|
|
@ -89,6 +89,18 @@ export class UniversalSentenceEncoder implements EmbeddingModel {
|
|||
*/
|
||||
public async init(): Promise<void> {
|
||||
try {
|
||||
// Save original console.warn
|
||||
const originalWarn = console.warn
|
||||
|
||||
// Override console.warn to suppress TensorFlow.js Node.js backend message
|
||||
console.warn = function(message?: any, ...optionalParams: any[]) {
|
||||
if (message && typeof message === 'string' &&
|
||||
message.includes('Hi, looks like you are running TensorFlow.js in Node.js')) {
|
||||
return // Suppress the specific warning
|
||||
}
|
||||
originalWarn(message, ...optionalParams)
|
||||
}
|
||||
|
||||
// Dynamically import TensorFlow.js and Universal Sentence Encoder
|
||||
// Use type assertions to tell TypeScript these modules exist
|
||||
this.tf = await import('@tensorflow/tfjs')
|
||||
|
|
@ -97,6 +109,9 @@ export class UniversalSentenceEncoder implements EmbeddingModel {
|
|||
// Load the model
|
||||
this.model = await this.use.load()
|
||||
this.initialized = true
|
||||
|
||||
// Restore original console.warn
|
||||
console.warn = originalWarn
|
||||
} catch (error) {
|
||||
console.error('Failed to initialize Universal Sentence Encoder:', error)
|
||||
throw new Error(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue