@soulcraft/brainy 1.5.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +188 -0
- package/LICENSE +2 -2
- package/README.md +201 -596
- package/bin/brainy-interactive.js +564 -0
- package/bin/brainy-ts.js +18 -0
- package/bin/brainy.js +672 -81
- package/dist/augmentationPipeline.d.ts +48 -220
- package/dist/augmentationPipeline.js +60 -508
- package/dist/augmentationRegistry.d.ts +22 -31
- package/dist/augmentationRegistry.js +28 -79
- package/dist/augmentations/apiServerAugmentation.d.ts +108 -0
- package/dist/augmentations/apiServerAugmentation.js +502 -0
- package/dist/augmentations/batchProcessingAugmentation.d.ts +95 -0
- package/dist/augmentations/batchProcessingAugmentation.js +567 -0
- package/dist/augmentations/brainyAugmentation.d.ts +153 -0
- package/dist/augmentations/brainyAugmentation.js +145 -0
- package/dist/augmentations/cacheAugmentation.d.ts +105 -0
- package/dist/augmentations/cacheAugmentation.js +238 -0
- package/dist/augmentations/conduitAugmentations.d.ts +54 -156
- package/dist/augmentations/conduitAugmentations.js +156 -1082
- package/dist/augmentations/connectionPoolAugmentation.d.ts +62 -0
- package/dist/augmentations/connectionPoolAugmentation.js +316 -0
- package/dist/augmentations/defaultAugmentations.d.ts +53 -0
- package/dist/augmentations/defaultAugmentations.js +88 -0
- package/dist/augmentations/entityRegistryAugmentation.d.ts +126 -0
- package/dist/augmentations/entityRegistryAugmentation.js +386 -0
- package/dist/augmentations/indexAugmentation.d.ts +117 -0
- package/dist/augmentations/indexAugmentation.js +284 -0
- package/dist/augmentations/intelligentVerbScoringAugmentation.d.ts +152 -0
- package/dist/augmentations/intelligentVerbScoringAugmentation.js +554 -0
- package/dist/augmentations/metricsAugmentation.d.ts +202 -0
- package/dist/augmentations/metricsAugmentation.js +291 -0
- package/dist/augmentations/monitoringAugmentation.d.ts +94 -0
- package/dist/augmentations/monitoringAugmentation.js +227 -0
- package/dist/augmentations/neuralImport.d.ts +50 -117
- package/dist/augmentations/neuralImport.js +255 -629
- package/dist/augmentations/requestDeduplicatorAugmentation.d.ts +52 -0
- package/dist/augmentations/requestDeduplicatorAugmentation.js +162 -0
- package/dist/augmentations/serverSearchAugmentations.d.ts +43 -22
- package/dist/augmentations/serverSearchAugmentations.js +125 -72
- package/dist/augmentations/storageAugmentation.d.ts +54 -0
- package/dist/augmentations/storageAugmentation.js +93 -0
- package/dist/augmentations/storageAugmentations.d.ts +96 -0
- package/dist/augmentations/storageAugmentations.js +182 -0
- package/dist/augmentations/synapseAugmentation.d.ts +156 -0
- package/dist/augmentations/synapseAugmentation.js +312 -0
- package/dist/augmentations/walAugmentation.d.ts +108 -0
- package/dist/augmentations/walAugmentation.js +515 -0
- package/dist/brainyData.d.ts +404 -130
- package/dist/brainyData.js +1331 -853
- package/dist/chat/BrainyChat.d.ts +16 -8
- package/dist/chat/BrainyChat.js +60 -32
- package/dist/chat/ChatCLI.d.ts +1 -1
- package/dist/chat/ChatCLI.js +6 -6
- package/dist/cli/catalog.d.ts +3 -3
- package/dist/cli/catalog.js +116 -70
- package/dist/cli/commands/core.d.ts +61 -0
- package/dist/cli/commands/core.js +348 -0
- package/dist/cli/commands/neural.d.ts +25 -0
- package/dist/cli/commands/neural.js +508 -0
- package/dist/cli/commands/utility.d.ts +37 -0
- package/dist/cli/commands/utility.js +276 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.js +167 -0
- package/dist/cli/interactive.d.ts +164 -0
- package/dist/cli/interactive.js +542 -0
- package/dist/cortex/neuralImport.js +5 -5
- package/dist/critical/model-guardian.js +11 -4
- package/dist/embeddings/lightweight-embedder.d.ts +23 -0
- package/dist/embeddings/lightweight-embedder.js +136 -0
- package/dist/embeddings/universal-memory-manager.d.ts +38 -0
- package/dist/embeddings/universal-memory-manager.js +206 -0
- package/dist/embeddings/worker-embedding.d.ts +7 -0
- package/dist/embeddings/worker-embedding.js +77 -0
- package/dist/embeddings/worker-manager.d.ts +28 -0
- package/dist/embeddings/worker-manager.js +162 -0
- package/dist/examples/basicUsage.js +7 -7
- package/dist/graph/pathfinding.d.ts +78 -0
- package/dist/graph/pathfinding.js +393 -0
- package/dist/hnsw/hnswIndex.d.ts +13 -0
- package/dist/hnsw/hnswIndex.js +35 -0
- package/dist/hnsw/hnswIndexOptimized.d.ts +1 -0
- package/dist/hnsw/hnswIndexOptimized.js +3 -0
- package/dist/index.d.ts +9 -11
- package/dist/index.js +21 -11
- package/dist/indices/fieldIndex.d.ts +76 -0
- package/dist/indices/fieldIndex.js +357 -0
- package/dist/mcp/brainyMCPAdapter.js +3 -2
- package/dist/mcp/mcpAugmentationToolset.js +11 -17
- package/dist/neural/embeddedPatterns.d.ts +41 -0
- package/dist/neural/embeddedPatterns.js +4044 -0
- package/dist/neural/naturalLanguageProcessor.d.ts +94 -0
- package/dist/neural/naturalLanguageProcessor.js +317 -0
- package/dist/neural/naturalLanguageProcessorStatic.d.ts +64 -0
- package/dist/neural/naturalLanguageProcessorStatic.js +151 -0
- package/dist/neural/neuralAPI.d.ts +255 -0
- package/dist/neural/neuralAPI.js +612 -0
- package/dist/neural/patternLibrary.d.ts +101 -0
- package/dist/neural/patternLibrary.js +313 -0
- package/dist/neural/patterns.d.ts +27 -0
- package/dist/neural/patterns.js +68 -0
- package/dist/neural/staticPatternMatcher.d.ts +35 -0
- package/dist/neural/staticPatternMatcher.js +153 -0
- package/dist/scripts/precomputePatternEmbeddings.d.ts +19 -0
- package/dist/scripts/precomputePatternEmbeddings.js +100 -0
- package/dist/storage/adapters/fileSystemStorage.d.ts +5 -0
- package/dist/storage/adapters/fileSystemStorage.js +20 -0
- package/dist/storage/adapters/s3CompatibleStorage.d.ts +5 -0
- package/dist/storage/adapters/s3CompatibleStorage.js +16 -0
- package/dist/storage/enhancedClearOperations.d.ts +83 -0
- package/dist/storage/enhancedClearOperations.js +345 -0
- package/dist/storage/storageFactory.js +31 -27
- package/dist/triple/TripleIntelligence.d.ts +134 -0
- package/dist/triple/TripleIntelligence.js +548 -0
- package/dist/types/augmentations.d.ts +45 -344
- package/dist/types/augmentations.js +5 -2
- package/dist/types/brainyDataInterface.d.ts +20 -10
- package/dist/types/graphTypes.d.ts +46 -0
- package/dist/types/graphTypes.js +16 -2
- package/dist/utils/BoundedRegistry.d.ts +29 -0
- package/dist/utils/BoundedRegistry.js +54 -0
- package/dist/utils/embedding.js +20 -3
- package/dist/utils/hybridModelManager.js +10 -5
- package/dist/utils/metadataFilter.d.ts +33 -19
- package/dist/utils/metadataFilter.js +58 -23
- package/dist/utils/metadataIndex.d.ts +37 -6
- package/dist/utils/metadataIndex.js +427 -64
- package/dist/utils/requestDeduplicator.d.ts +10 -0
- package/dist/utils/requestDeduplicator.js +24 -0
- package/dist/utils/unifiedCache.d.ts +103 -0
- package/dist/utils/unifiedCache.js +311 -0
- package/package.json +43 -128
- package/scripts/ensure-models.js +108 -0
- package/scripts/prepare-models.js +387 -0
- package/OFFLINE_MODELS.md +0 -56
- package/dist/intelligence/neuralEngine.d.ts +0 -207
- package/dist/intelligence/neuralEngine.js +0 -706
- package/dist/utils/modelLoader.d.ts +0 -32
- package/dist/utils/modelLoader.js +0 -219
- package/dist/utils/modelManager.d.ts +0 -77
- package/dist/utils/modelManager.js +0 -219
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Professional Interactive CLI System
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent, delightful interactive prompts for all commands
|
|
5
|
+
* with smart defaults, validation, and helpful examples
|
|
6
|
+
*/
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import inquirer from 'inquirer';
|
|
9
|
+
import fuzzy from 'fuzzy';
|
|
10
|
+
import ora from 'ora';
|
|
11
|
+
// Professional color scheme
|
|
12
|
+
export const colors = {
|
|
13
|
+
primary: chalk.hex('#3A5F4A'), // Teal (from logo)
|
|
14
|
+
success: chalk.hex('#2D4A3A'), // Deep teal
|
|
15
|
+
info: chalk.hex('#4A6B5A'), // Medium teal
|
|
16
|
+
warning: chalk.hex('#D67441'), // Orange (from logo)
|
|
17
|
+
error: chalk.hex('#B85C35'), // Deep orange
|
|
18
|
+
brain: chalk.hex('#D67441'), // Brain orange
|
|
19
|
+
cream: chalk.hex('#F5E6A3'), // Cream background
|
|
20
|
+
dim: chalk.dim,
|
|
21
|
+
bold: chalk.bold,
|
|
22
|
+
cyan: chalk.cyan,
|
|
23
|
+
green: chalk.green,
|
|
24
|
+
yellow: chalk.yellow,
|
|
25
|
+
red: chalk.red
|
|
26
|
+
};
|
|
27
|
+
// Icons for consistent visual language
|
|
28
|
+
export const icons = {
|
|
29
|
+
brain: '🧠',
|
|
30
|
+
search: '🔍',
|
|
31
|
+
add: '➕',
|
|
32
|
+
delete: '🗑️',
|
|
33
|
+
update: '🔄',
|
|
34
|
+
import: '📥',
|
|
35
|
+
export: '📤',
|
|
36
|
+
connect: '🔗',
|
|
37
|
+
question: '❓',
|
|
38
|
+
success: '✅',
|
|
39
|
+
error: '❌',
|
|
40
|
+
warning: '⚠️',
|
|
41
|
+
info: 'ℹ️',
|
|
42
|
+
sparkle: '✨',
|
|
43
|
+
rocket: '🚀',
|
|
44
|
+
thinking: '🤔',
|
|
45
|
+
chat: '💬'
|
|
46
|
+
};
|
|
47
|
+
// Store recent inputs for smart suggestions
|
|
48
|
+
const recentInputs = {
|
|
49
|
+
searches: [],
|
|
50
|
+
ids: [],
|
|
51
|
+
types: [],
|
|
52
|
+
formats: []
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Professional prompt wrapper with consistent styling
|
|
56
|
+
*/
|
|
57
|
+
export async function prompt(config) {
|
|
58
|
+
// Add consistent styling
|
|
59
|
+
if (config.message) {
|
|
60
|
+
config.message = colors.cyan(config.message);
|
|
61
|
+
}
|
|
62
|
+
// Add prefix with appropriate icon
|
|
63
|
+
if (!config.prefix) {
|
|
64
|
+
config.prefix = colors.dim(' › ');
|
|
65
|
+
}
|
|
66
|
+
return inquirer.prompt([config]);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Interactive prompt for search query with smart features
|
|
70
|
+
*/
|
|
71
|
+
export async function promptSearchQuery(previousSearches) {
|
|
72
|
+
console.log(colors.primary(`\n${icons.search} Smart Search\n`));
|
|
73
|
+
console.log(colors.dim('Search your neural database with natural language'));
|
|
74
|
+
console.log(colors.dim('Examples: "meetings last week", "John from Google", "important documents"'));
|
|
75
|
+
const { query } = await prompt({
|
|
76
|
+
type: 'input',
|
|
77
|
+
name: 'query',
|
|
78
|
+
message: 'What would you like to search for?',
|
|
79
|
+
validate: (input) => {
|
|
80
|
+
if (!input.trim()) {
|
|
81
|
+
return 'Please enter a search query';
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
},
|
|
85
|
+
transformer: (input) => {
|
|
86
|
+
// Show live character count
|
|
87
|
+
const count = input.length;
|
|
88
|
+
if (count > 100) {
|
|
89
|
+
return colors.warning(input);
|
|
90
|
+
}
|
|
91
|
+
return colors.green(input);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
// Store for future suggestions
|
|
95
|
+
if (!recentInputs.searches.includes(query)) {
|
|
96
|
+
recentInputs.searches.unshift(query);
|
|
97
|
+
recentInputs.searches = recentInputs.searches.slice(0, 10);
|
|
98
|
+
}
|
|
99
|
+
return query;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Interactive prompt for item ID with fuzzy search
|
|
103
|
+
*/
|
|
104
|
+
export async function promptItemId(action, brain, allowMultiple = false) {
|
|
105
|
+
console.log(colors.primary(`\n${icons.thinking} Select item to ${action}\n`));
|
|
106
|
+
// If we have brain instance, show recent items
|
|
107
|
+
let choices = [];
|
|
108
|
+
if (brain) {
|
|
109
|
+
try {
|
|
110
|
+
const recent = await brain.search('*', 10, {
|
|
111
|
+
sortBy: 'timestamp',
|
|
112
|
+
descending: true
|
|
113
|
+
});
|
|
114
|
+
choices = recent.map(item => ({
|
|
115
|
+
name: `${item.id} - ${item.content?.substring(0, 50)}...`,
|
|
116
|
+
value: item.id,
|
|
117
|
+
short: item.id
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Fallback to manual input
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (choices.length > 0) {
|
|
125
|
+
choices.push(new inquirer.Separator());
|
|
126
|
+
choices.push({ name: 'Enter ID manually', value: '__manual__' });
|
|
127
|
+
const { selected } = await prompt({
|
|
128
|
+
type: allowMultiple ? 'checkbox' : 'list',
|
|
129
|
+
name: 'selected',
|
|
130
|
+
message: `Select item(s) to ${action}:`,
|
|
131
|
+
choices,
|
|
132
|
+
pageSize: 10
|
|
133
|
+
});
|
|
134
|
+
if (selected === '__manual__' || (Array.isArray(selected) && selected.includes('__manual__'))) {
|
|
135
|
+
return promptManualId(action, allowMultiple);
|
|
136
|
+
}
|
|
137
|
+
return selected;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
return promptManualId(action, allowMultiple);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Manual ID input with validation
|
|
145
|
+
*/
|
|
146
|
+
async function promptManualId(action, allowMultiple) {
|
|
147
|
+
const { id } = await prompt({
|
|
148
|
+
type: 'input',
|
|
149
|
+
name: 'id',
|
|
150
|
+
message: allowMultiple
|
|
151
|
+
? `Enter ID(s) to ${action} (comma-separated):`
|
|
152
|
+
: `Enter ID to ${action}:`,
|
|
153
|
+
validate: (input) => {
|
|
154
|
+
if (!input.trim()) {
|
|
155
|
+
return `Please enter at least one ID`;
|
|
156
|
+
}
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
if (allowMultiple) {
|
|
161
|
+
return id.split(',').map((i) => i.trim()).filter(Boolean);
|
|
162
|
+
}
|
|
163
|
+
return id.trim();
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Confirm destructive action with preview
|
|
167
|
+
*/
|
|
168
|
+
export async function confirmDestructiveAction(action, items, showPreview = true) {
|
|
169
|
+
console.log(colors.warning(`\n${icons.warning} Confirmation Required\n`));
|
|
170
|
+
if (showPreview && items.length > 0) {
|
|
171
|
+
console.log(colors.dim(`You are about to ${action}:`));
|
|
172
|
+
items.slice(0, 5).forEach(item => {
|
|
173
|
+
console.log(colors.dim(` • ${item.id || item}`));
|
|
174
|
+
});
|
|
175
|
+
if (items.length > 5) {
|
|
176
|
+
console.log(colors.dim(` ... and ${items.length - 5} more`));
|
|
177
|
+
}
|
|
178
|
+
console.log();
|
|
179
|
+
}
|
|
180
|
+
const { confirm } = await prompt({
|
|
181
|
+
type: 'confirm',
|
|
182
|
+
name: 'confirm',
|
|
183
|
+
message: colors.warning(`Are you sure you want to ${action}?`),
|
|
184
|
+
default: false
|
|
185
|
+
});
|
|
186
|
+
return confirm;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Interactive data input with multiline support
|
|
190
|
+
*/
|
|
191
|
+
export async function promptDataInput(action = 'add', currentValue) {
|
|
192
|
+
console.log(colors.primary(`\n${icons.add} ${action === 'add' ? 'Add Data' : 'Update Data'}\n`));
|
|
193
|
+
if (currentValue) {
|
|
194
|
+
console.log(colors.dim('Current value:'));
|
|
195
|
+
console.log(colors.info(` ${currentValue.substring(0, 100)}${currentValue.length > 100 ? '...' : ''}`));
|
|
196
|
+
console.log();
|
|
197
|
+
}
|
|
198
|
+
const { data } = await prompt({
|
|
199
|
+
type: 'editor',
|
|
200
|
+
name: 'data',
|
|
201
|
+
message: 'Enter your data:',
|
|
202
|
+
default: currentValue || '',
|
|
203
|
+
postfix: '.md',
|
|
204
|
+
validate: (input) => {
|
|
205
|
+
if (!input.trim() && action === 'add') {
|
|
206
|
+
return 'Please enter some data';
|
|
207
|
+
}
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
return data;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Interactive metadata input with JSON validation
|
|
215
|
+
*/
|
|
216
|
+
export async function promptMetadata(currentMetadata, suggestions) {
|
|
217
|
+
console.log(colors.dim('\nOptional: Add metadata (JSON format)'));
|
|
218
|
+
const { addMetadata } = await prompt({
|
|
219
|
+
type: 'confirm',
|
|
220
|
+
name: 'addMetadata',
|
|
221
|
+
message: 'Would you like to add metadata?',
|
|
222
|
+
default: false
|
|
223
|
+
});
|
|
224
|
+
if (!addMetadata) {
|
|
225
|
+
return {};
|
|
226
|
+
}
|
|
227
|
+
// Show field suggestions if available
|
|
228
|
+
if (suggestions && suggestions.length > 0) {
|
|
229
|
+
console.log(colors.dim('\nAvailable fields:'));
|
|
230
|
+
suggestions.forEach(field => {
|
|
231
|
+
console.log(colors.dim(` • ${field}`));
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
const { metadata } = await prompt({
|
|
235
|
+
type: 'editor',
|
|
236
|
+
name: 'metadata',
|
|
237
|
+
message: 'Enter metadata (JSON):',
|
|
238
|
+
default: currentMetadata ? JSON.stringify(currentMetadata, null, 2) : '{\n \n}',
|
|
239
|
+
postfix: '.json',
|
|
240
|
+
validate: (input) => {
|
|
241
|
+
try {
|
|
242
|
+
JSON.parse(input);
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
catch (e) {
|
|
246
|
+
return `Invalid JSON: ${e.message}`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
return JSON.parse(metadata);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Interactive format selector
|
|
254
|
+
*/
|
|
255
|
+
export async function promptFormat(availableFormats, defaultFormat) {
|
|
256
|
+
console.log(colors.primary(`\n${icons.export} Select Format\n`));
|
|
257
|
+
const { format } = await prompt({
|
|
258
|
+
type: 'list',
|
|
259
|
+
name: 'format',
|
|
260
|
+
message: 'Choose export format:',
|
|
261
|
+
choices: availableFormats.map(f => ({
|
|
262
|
+
name: getFormatDescription(f),
|
|
263
|
+
value: f,
|
|
264
|
+
short: f
|
|
265
|
+
})),
|
|
266
|
+
default: defaultFormat
|
|
267
|
+
});
|
|
268
|
+
return format;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Get friendly format descriptions
|
|
272
|
+
*/
|
|
273
|
+
function getFormatDescription(format) {
|
|
274
|
+
const descriptions = {
|
|
275
|
+
json: 'JSON - Universal data interchange',
|
|
276
|
+
jsonl: 'JSON Lines - Streaming format',
|
|
277
|
+
csv: 'CSV - Spreadsheet compatible',
|
|
278
|
+
graphml: 'GraphML - Graph visualization',
|
|
279
|
+
dot: 'DOT - Graphviz format',
|
|
280
|
+
d3: 'D3.js - Web visualization',
|
|
281
|
+
markdown: 'Markdown - Human readable',
|
|
282
|
+
yaml: 'YAML - Configuration format'
|
|
283
|
+
};
|
|
284
|
+
return `${format.toUpperCase()} - ${descriptions[format] || 'Custom format'}`;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Interactive file/URL input with validation
|
|
288
|
+
*/
|
|
289
|
+
export async function promptFileOrUrl(action = 'import') {
|
|
290
|
+
console.log(colors.primary(`\n${icons.import} ${action === 'import' ? 'Import Source' : 'Export Destination'}\n`));
|
|
291
|
+
const { sourceType } = await prompt({
|
|
292
|
+
type: 'list',
|
|
293
|
+
name: 'sourceType',
|
|
294
|
+
message: 'What type of source?',
|
|
295
|
+
choices: [
|
|
296
|
+
{ name: 'Local file', value: 'file' },
|
|
297
|
+
{ name: 'URL', value: 'url' },
|
|
298
|
+
{ name: 'Clipboard', value: 'clipboard' },
|
|
299
|
+
{ name: 'Direct input', value: 'input' }
|
|
300
|
+
]
|
|
301
|
+
});
|
|
302
|
+
switch (sourceType) {
|
|
303
|
+
case 'file':
|
|
304
|
+
return promptFilePath(action);
|
|
305
|
+
case 'url':
|
|
306
|
+
return promptUrl();
|
|
307
|
+
case 'clipboard':
|
|
308
|
+
// Would need clipboard integration
|
|
309
|
+
console.log(colors.warning('Clipboard support coming soon!'));
|
|
310
|
+
return promptFilePath(action);
|
|
311
|
+
case 'input':
|
|
312
|
+
const data = await promptDataInput('import');
|
|
313
|
+
// Save to temp file and return path
|
|
314
|
+
const tmpFile = `/tmp/brainy-import-${Date.now()}.json`;
|
|
315
|
+
const { writeFileSync } = await import('fs');
|
|
316
|
+
writeFileSync(tmpFile, data);
|
|
317
|
+
return tmpFile;
|
|
318
|
+
default:
|
|
319
|
+
return '';
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* File path input with autocomplete
|
|
324
|
+
*/
|
|
325
|
+
async function promptFilePath(action) {
|
|
326
|
+
const { path } = await prompt({
|
|
327
|
+
type: 'input',
|
|
328
|
+
name: 'path',
|
|
329
|
+
message: `Enter file path to ${action}:`,
|
|
330
|
+
validate: async (input) => {
|
|
331
|
+
if (!input.trim()) {
|
|
332
|
+
return 'Please enter a file path';
|
|
333
|
+
}
|
|
334
|
+
const { existsSync } = await import('fs');
|
|
335
|
+
if (action === 'import' && !existsSync(input)) {
|
|
336
|
+
return `File not found: ${input}`;
|
|
337
|
+
}
|
|
338
|
+
return true;
|
|
339
|
+
},
|
|
340
|
+
// Add file path autocomplete
|
|
341
|
+
transformer: (input) => {
|
|
342
|
+
if (input.startsWith('~/')) {
|
|
343
|
+
const home = process.env.HOME || '~';
|
|
344
|
+
return colors.green(input.replace('~', home));
|
|
345
|
+
}
|
|
346
|
+
return colors.green(input);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
return path;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* URL input with validation
|
|
353
|
+
*/
|
|
354
|
+
async function promptUrl() {
|
|
355
|
+
const { url } = await prompt({
|
|
356
|
+
type: 'input',
|
|
357
|
+
name: 'url',
|
|
358
|
+
message: 'Enter URL:',
|
|
359
|
+
validate: (input) => {
|
|
360
|
+
try {
|
|
361
|
+
new URL(input);
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
return 'Please enter a valid URL';
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
return url;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Interactive relationship builder
|
|
373
|
+
*/
|
|
374
|
+
export async function promptRelationship(brain) {
|
|
375
|
+
console.log(colors.primary(`\n${icons.connect} Create Relationship\n`));
|
|
376
|
+
console.log(colors.dim('Connect two items with a semantic relationship'));
|
|
377
|
+
// Get source
|
|
378
|
+
const source = await promptItemId('connect from', brain, false);
|
|
379
|
+
// Get verb/relationship type
|
|
380
|
+
const { verb } = await prompt({
|
|
381
|
+
type: 'list',
|
|
382
|
+
name: 'verb',
|
|
383
|
+
message: 'Relationship type:',
|
|
384
|
+
choices: [
|
|
385
|
+
{ name: 'Works For', value: 'WorksFor' },
|
|
386
|
+
{ name: 'Knows', value: 'Knows' },
|
|
387
|
+
{ name: 'Created By', value: 'CreatedBy' },
|
|
388
|
+
{ name: 'Belongs To', value: 'BelongsTo' },
|
|
389
|
+
{ name: 'Uses', value: 'Uses' },
|
|
390
|
+
{ name: 'Manages', value: 'Manages' },
|
|
391
|
+
{ name: 'Located In', value: 'LocatedIn' },
|
|
392
|
+
{ name: 'Related To', value: 'RelatedTo' },
|
|
393
|
+
new inquirer.Separator(),
|
|
394
|
+
{ name: 'Custom relationship...', value: '__custom__' }
|
|
395
|
+
]
|
|
396
|
+
});
|
|
397
|
+
let finalVerb = verb;
|
|
398
|
+
if (verb === '__custom__') {
|
|
399
|
+
const { customVerb } = await prompt({
|
|
400
|
+
type: 'input',
|
|
401
|
+
name: 'customVerb',
|
|
402
|
+
message: 'Enter custom relationship:',
|
|
403
|
+
validate: (input) => input.trim() ? true : 'Please enter a relationship'
|
|
404
|
+
});
|
|
405
|
+
finalVerb = customVerb;
|
|
406
|
+
}
|
|
407
|
+
// Get target
|
|
408
|
+
const target = await promptItemId('connect to', brain, false);
|
|
409
|
+
// Optional metadata
|
|
410
|
+
const metadata = await promptMetadata();
|
|
411
|
+
return {
|
|
412
|
+
source,
|
|
413
|
+
verb: finalVerb,
|
|
414
|
+
target,
|
|
415
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : undefined
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Smart command suggestions when user types wrong command
|
|
420
|
+
*/
|
|
421
|
+
export function suggestCommand(input, availableCommands) {
|
|
422
|
+
const results = fuzzy.filter(input, availableCommands);
|
|
423
|
+
return results.slice(0, 3).map(r => r.string);
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Beautiful error display with helpful context
|
|
427
|
+
*/
|
|
428
|
+
export function showError(error, context) {
|
|
429
|
+
console.log();
|
|
430
|
+
console.log(colors.error(`${icons.error} Error`));
|
|
431
|
+
if (context) {
|
|
432
|
+
console.log(colors.dim(context));
|
|
433
|
+
}
|
|
434
|
+
console.log(colors.red(error.message));
|
|
435
|
+
// Provide helpful suggestions based on error
|
|
436
|
+
if (error.message.includes('not found')) {
|
|
437
|
+
console.log(colors.dim('\nTip: Use "brainy search" to find items'));
|
|
438
|
+
}
|
|
439
|
+
else if (error.message.includes('network') || error.message.includes('fetch')) {
|
|
440
|
+
console.log(colors.dim('\nTip: Check your internet connection'));
|
|
441
|
+
}
|
|
442
|
+
else if (error.message.includes('permission')) {
|
|
443
|
+
console.log(colors.dim('\nTip: Check file permissions or run with appropriate access'));
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Progress indicator for long operations
|
|
448
|
+
*/
|
|
449
|
+
export class ProgressTracker {
|
|
450
|
+
constructor(message) {
|
|
451
|
+
this.spinner = ora({
|
|
452
|
+
text: message,
|
|
453
|
+
color: 'cyan',
|
|
454
|
+
spinner: 'dots'
|
|
455
|
+
}).start();
|
|
456
|
+
this.startTime = Date.now();
|
|
457
|
+
}
|
|
458
|
+
update(message, count, total) {
|
|
459
|
+
if (count && total) {
|
|
460
|
+
const percent = Math.round((count / total) * 100);
|
|
461
|
+
const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);
|
|
462
|
+
this.spinner.text = `${message} (${percent}% - ${elapsed}s)`;
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
this.spinner.text = message;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
succeed(message) {
|
|
469
|
+
const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);
|
|
470
|
+
this.spinner.succeed(message ? `${message} (${elapsed}s)` : `Done (${elapsed}s)`);
|
|
471
|
+
}
|
|
472
|
+
fail(message) {
|
|
473
|
+
this.spinner.fail(message || 'Failed');
|
|
474
|
+
}
|
|
475
|
+
stop() {
|
|
476
|
+
this.spinner.stop();
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Welcome message for interactive mode
|
|
481
|
+
*/
|
|
482
|
+
export function showWelcome() {
|
|
483
|
+
console.clear();
|
|
484
|
+
console.log(colors.primary(`
|
|
485
|
+
╔══════════════════════════════════════════════╗
|
|
486
|
+
║ ║
|
|
487
|
+
║ ${icons.brain} BRAINY - Neural Intelligence ║
|
|
488
|
+
║ Your AI-Powered Second Brain ║
|
|
489
|
+
║ ║
|
|
490
|
+
╚══════════════════════════════════════════════╝
|
|
491
|
+
`));
|
|
492
|
+
console.log(colors.dim('Version 1.5.0 • Type "help" for commands'));
|
|
493
|
+
console.log();
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Interactive command selector for beginners
|
|
497
|
+
*/
|
|
498
|
+
export async function promptCommand() {
|
|
499
|
+
const { command } = await prompt({
|
|
500
|
+
type: 'list',
|
|
501
|
+
name: 'command',
|
|
502
|
+
message: 'What would you like to do?',
|
|
503
|
+
choices: [
|
|
504
|
+
{ name: `${icons.add} Add data to your brain`, value: 'add' },
|
|
505
|
+
{ name: `${icons.search} Search your knowledge`, value: 'search' },
|
|
506
|
+
{ name: `${icons.chat} Chat with your data`, value: 'chat' },
|
|
507
|
+
{ name: `${icons.update} Update existing data`, value: 'update' },
|
|
508
|
+
{ name: `${icons.delete} Delete data`, value: 'delete' },
|
|
509
|
+
{ name: `${icons.connect} Create relationships`, value: 'relate' },
|
|
510
|
+
{ name: `${icons.import} Import from file`, value: 'import' },
|
|
511
|
+
{ name: `${icons.export} Export your brain`, value: 'export' },
|
|
512
|
+
new inquirer.Separator(),
|
|
513
|
+
{ name: `${icons.brain} Neural operations`, value: 'neural' },
|
|
514
|
+
{ name: `${icons.info} View statistics`, value: 'status' },
|
|
515
|
+
{ name: 'Exit', value: 'exit' }
|
|
516
|
+
],
|
|
517
|
+
pageSize: 15
|
|
518
|
+
});
|
|
519
|
+
return command;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Export all interactive components
|
|
523
|
+
*/
|
|
524
|
+
export default {
|
|
525
|
+
colors,
|
|
526
|
+
icons,
|
|
527
|
+
prompt,
|
|
528
|
+
promptSearchQuery,
|
|
529
|
+
promptItemId,
|
|
530
|
+
confirmDestructiveAction,
|
|
531
|
+
promptDataInput,
|
|
532
|
+
promptMetadata,
|
|
533
|
+
promptFormat,
|
|
534
|
+
promptFileOrUrl,
|
|
535
|
+
promptRelationship,
|
|
536
|
+
suggestCommand,
|
|
537
|
+
showError,
|
|
538
|
+
ProgressTracker,
|
|
539
|
+
showWelcome,
|
|
540
|
+
promptCommand
|
|
541
|
+
};
|
|
542
|
+
//# sourceMappingURL=interactive.js.map
|
|
@@ -188,7 +188,7 @@ export class NeuralImport {
|
|
|
188
188
|
*/
|
|
189
189
|
async calculateEntityTypeConfidence(text, data, nounType) {
|
|
190
190
|
// Base semantic similarity using search instead of similarity method
|
|
191
|
-
const searchResults = await this.brainy.search(text + ' ' + nounType, 1);
|
|
191
|
+
const searchResults = await this.brainy.search(text + ' ' + nounType, { limit: 1 });
|
|
192
192
|
const textSimilarity = searchResults.length > 0 ? searchResults[0].score : 0.5;
|
|
193
193
|
// Field-based confidence boost
|
|
194
194
|
const fieldBoost = this.calculateFieldBasedConfidence(data, nounType);
|
|
@@ -258,7 +258,7 @@ export class NeuralImport {
|
|
|
258
258
|
async generateEntityReasoning(text, data, nounType) {
|
|
259
259
|
const reasons = [];
|
|
260
260
|
// Semantic similarity reason using search
|
|
261
|
-
const searchResults = await this.brainy.search(text + ' ' + nounType, 1);
|
|
261
|
+
const searchResults = await this.brainy.search(text + ' ' + nounType, { limit: 1 });
|
|
262
262
|
const similarity = searchResults.length > 0 ? searchResults[0].score : 0.5;
|
|
263
263
|
if (similarity > 0.7) {
|
|
264
264
|
reasons.push(`High semantic similarity (${(similarity * 100).toFixed(1)}%)`);
|
|
@@ -319,10 +319,10 @@ export class NeuralImport {
|
|
|
319
319
|
async calculateRelationshipConfidence(source, target, verbType, context) {
|
|
320
320
|
// Semantic similarity between entities and verb type using search
|
|
321
321
|
const relationshipText = `${this.extractMainText(source.originalData)} ${verbType} ${this.extractMainText(target.originalData)}`;
|
|
322
|
-
const directResults = await this.brainy.search(relationshipText, 1);
|
|
322
|
+
const directResults = await this.brainy.search(relationshipText, { limit: 1 });
|
|
323
323
|
const directSimilarity = directResults.length > 0 ? directResults[0].score : 0.5;
|
|
324
324
|
// Context-based similarity using search
|
|
325
|
-
const contextResults = await this.brainy.search(context + ' ' + verbType, 1);
|
|
325
|
+
const contextResults = await this.brainy.search(context + ' ' + verbType, { limit: 1 });
|
|
326
326
|
const contextSimilarity = contextResults.length > 0 ? contextResults[0].score : 0.5;
|
|
327
327
|
// Entity type compatibility
|
|
328
328
|
const typeCompatibility = this.calculateTypeCompatibility(source.nounType, target.nounType, verbType);
|
|
@@ -576,7 +576,7 @@ export class NeuralImport {
|
|
|
576
576
|
try {
|
|
577
577
|
// Add entities to Brainy
|
|
578
578
|
for (const entity of result.detectedEntities) {
|
|
579
|
-
await this.brainy.
|
|
579
|
+
await this.brainy.addNoun(this.extractMainText(entity.originalData), {
|
|
580
580
|
...entity.originalData,
|
|
581
581
|
nounType: entity.nounType,
|
|
582
582
|
confidence: entity.confidence,
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { existsSync } from 'fs';
|
|
14
14
|
import { stat } from 'fs/promises';
|
|
15
|
-
import { join
|
|
15
|
+
import { join } from 'path';
|
|
16
16
|
import { env } from '@huggingface/transformers';
|
|
17
17
|
// CRITICAL: These values MUST NEVER CHANGE
|
|
18
18
|
const CRITICAL_MODEL_CONFIG = {
|
|
@@ -23,7 +23,7 @@ const CRITICAL_MODEL_CONFIG = {
|
|
|
23
23
|
'tokenizer.json': 'add_actual_hash_here'
|
|
24
24
|
},
|
|
25
25
|
modelSize: {
|
|
26
|
-
'onnx/model.onnx':
|
|
26
|
+
'onnx/model.onnx': 90387606, // Exact size in bytes (updated to match actual file)
|
|
27
27
|
'tokenizer.json': 711661
|
|
28
28
|
},
|
|
29
29
|
embeddingDimensions: 384,
|
|
@@ -65,7 +65,10 @@ export class ModelGuardian {
|
|
|
65
65
|
* This MUST be called before any embedding operations
|
|
66
66
|
*/
|
|
67
67
|
async ensureCriticalModel() {
|
|
68
|
+
console.log('DEBUG: ensureCriticalModel called');
|
|
68
69
|
console.log('🛡️ MODEL GUARDIAN: Verifying critical model availability...');
|
|
70
|
+
console.log(`🚀 Debug: Model path: ${this.modelPath}`);
|
|
71
|
+
console.log(`🚀 Debug: Already verified: ${this.isVerified}`);
|
|
69
72
|
// Check if already verified in this session
|
|
70
73
|
if (this.isVerified && this.lastVerification) {
|
|
71
74
|
const hoursSinceVerification = (Date.now() - this.lastVerification.getTime()) / (1000 * 60 * 60);
|
|
@@ -75,6 +78,7 @@ export class ModelGuardian {
|
|
|
75
78
|
}
|
|
76
79
|
}
|
|
77
80
|
// Step 1: Check if model exists locally
|
|
81
|
+
console.log('🔍 Debug: Calling verifyLocalModel()');
|
|
78
82
|
const modelExists = await this.verifyLocalModel();
|
|
79
83
|
if (modelExists) {
|
|
80
84
|
console.log('✅ Critical model verified locally');
|
|
@@ -121,6 +125,8 @@ export class ModelGuardian {
|
|
|
121
125
|
*/
|
|
122
126
|
async verifyLocalModel() {
|
|
123
127
|
const modelBasePath = join(this.modelPath, ...CRITICAL_MODEL_CONFIG.modelName.split('/'));
|
|
128
|
+
console.log(`🔍 Debug: Checking model at path: ${modelBasePath}`);
|
|
129
|
+
console.log(`🔍 Debug: Model path components: ${this.modelPath} + ${CRITICAL_MODEL_CONFIG.modelName.split('/')}`);
|
|
124
130
|
// Check critical files
|
|
125
131
|
const criticalFiles = [
|
|
126
132
|
'onnx/model.onnx',
|
|
@@ -129,8 +135,9 @@ export class ModelGuardian {
|
|
|
129
135
|
];
|
|
130
136
|
for (const file of criticalFiles) {
|
|
131
137
|
const filePath = join(modelBasePath, file);
|
|
138
|
+
console.log(`🔍 Debug: Checking file: ${filePath}`);
|
|
132
139
|
if (!existsSync(filePath)) {
|
|
133
|
-
console.log(`❌ Missing critical file: ${file}`);
|
|
140
|
+
console.log(`❌ Missing critical file: ${file} at ${filePath}`);
|
|
134
141
|
return false;
|
|
135
142
|
}
|
|
136
143
|
// Verify size for critical files
|
|
@@ -205,7 +212,7 @@ export class ModelGuardian {
|
|
|
205
212
|
if (path && existsSync(path)) {
|
|
206
213
|
const modelPath = join(path, ...CRITICAL_MODEL_CONFIG.modelName.split('/'));
|
|
207
214
|
if (existsSync(join(modelPath, 'onnx', 'model.onnx'))) {
|
|
208
|
-
return
|
|
215
|
+
return path; // Return the models directory, not its parent
|
|
209
216
|
}
|
|
210
217
|
}
|
|
211
218
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight Embedding Alternative
|
|
3
|
+
*
|
|
4
|
+
* Uses pre-computed embeddings for common terms
|
|
5
|
+
* Falls back to ONNX for unknown terms
|
|
6
|
+
*
|
|
7
|
+
* This reduces memory usage by 90% for typical queries
|
|
8
|
+
*/
|
|
9
|
+
import { Vector } from '../coreTypes.js';
|
|
10
|
+
export declare class LightweightEmbedder {
|
|
11
|
+
private onnxEmbedder;
|
|
12
|
+
private stats;
|
|
13
|
+
embed(text: string | string[]): Promise<Vector | Vector[]>;
|
|
14
|
+
private embedSingle;
|
|
15
|
+
getStats(): {
|
|
16
|
+
totalEmbeddings: number;
|
|
17
|
+
cacheHitRate: number;
|
|
18
|
+
precomputedHits: number;
|
|
19
|
+
simpleComputes: number;
|
|
20
|
+
onnxComputes: number;
|
|
21
|
+
};
|
|
22
|
+
loadPrecomputed(filePath?: string): Promise<void>;
|
|
23
|
+
}
|