@soulcraft/brainy 3.19.0 โ 3.20.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 +2 -0
- package/bin/brainy-minimal.js +82 -0
- package/bin/brainy.js +9 -2335
- package/dist/api/DataAPI.d.ts +1 -1
- package/dist/augmentations/cacheAugmentation.d.ts +1 -1
- package/dist/augmentations/metricsAugmentation.d.ts +20 -20
- package/dist/brainy.d.ts +1 -1
- package/dist/brainyData.js +1 -2
- package/dist/cli/catalog.js +8 -12
- package/dist/cli/commands/conversation.d.ts +22 -0
- package/dist/cli/commands/conversation.js +528 -0
- package/dist/cli/commands/core.d.ts +14 -2
- package/dist/cli/commands/core.js +195 -35
- package/dist/cli/commands/data.d.ts +29 -0
- package/dist/cli/commands/data.js +139 -0
- package/dist/cli/commands/neural.d.ts +14 -0
- package/dist/cli/commands/neural.js +18 -8
- package/dist/cli/commands/types.d.ts +30 -0
- package/dist/cli/commands/types.js +194 -0
- package/dist/cli/commands/utility.js +39 -98
- package/dist/cli/commands/vfs.d.ts +73 -0
- package/dist/cli/commands/vfs.js +372 -0
- package/dist/cli/index.js +244 -7
- package/dist/cli/interactive.d.ts +8 -3
- package/dist/cli/interactive.js +35 -11
- package/dist/hnsw/hnswIndexOptimized.d.ts +1 -1
- package/dist/mcp/brainyMCPBroadcast.d.ts +2 -2
- package/dist/mcp/brainyMCPBroadcast.js +1 -1
- package/dist/mcp/brainyMCPClient.js +8 -4
- package/dist/neural/types.d.ts +2 -2
- package/dist/streaming/pipeline.d.ts +1 -1
- package/dist/universal/fs.d.ts +24 -66
- package/package.json +5 -2
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ๐ฌ Conversation CLI Commands
|
|
3
|
+
*
|
|
4
|
+
* CLI interface for infinite agent memory and conversation management
|
|
5
|
+
*/
|
|
6
|
+
import inquirer from 'inquirer';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import * as fs from '../../universal/fs.js';
|
|
10
|
+
import * as path from '../../universal/path.js';
|
|
11
|
+
import { Brainy } from '../../brainy.js';
|
|
12
|
+
export const conversationCommand = {
|
|
13
|
+
command: 'conversation [action]',
|
|
14
|
+
describe: '๐ฌ Conversation and context management',
|
|
15
|
+
builder: (yargs) => {
|
|
16
|
+
return yargs
|
|
17
|
+
.positional('action', {
|
|
18
|
+
describe: 'Conversation operation to perform',
|
|
19
|
+
type: 'string',
|
|
20
|
+
choices: ['setup', 'remove', 'search', 'context', 'thread', 'stats', 'export', 'import']
|
|
21
|
+
})
|
|
22
|
+
.option('conversation-id', {
|
|
23
|
+
describe: 'Conversation ID',
|
|
24
|
+
type: 'string',
|
|
25
|
+
alias: 'c'
|
|
26
|
+
})
|
|
27
|
+
.option('query', {
|
|
28
|
+
describe: 'Search query or context query',
|
|
29
|
+
type: 'string',
|
|
30
|
+
alias: 'q'
|
|
31
|
+
})
|
|
32
|
+
.option('role', {
|
|
33
|
+
describe: 'Filter by message role',
|
|
34
|
+
type: 'string',
|
|
35
|
+
choices: ['user', 'assistant', 'system', 'tool'],
|
|
36
|
+
alias: 'r'
|
|
37
|
+
})
|
|
38
|
+
.option('limit', {
|
|
39
|
+
describe: 'Maximum results',
|
|
40
|
+
type: 'number',
|
|
41
|
+
default: 10,
|
|
42
|
+
alias: 'l'
|
|
43
|
+
})
|
|
44
|
+
.option('format', {
|
|
45
|
+
describe: 'Output format',
|
|
46
|
+
type: 'string',
|
|
47
|
+
choices: ['json', 'table', 'text'],
|
|
48
|
+
default: 'table',
|
|
49
|
+
alias: 'f'
|
|
50
|
+
})
|
|
51
|
+
.option('output', {
|
|
52
|
+
describe: 'Output file path',
|
|
53
|
+
type: 'string',
|
|
54
|
+
alias: 'o'
|
|
55
|
+
})
|
|
56
|
+
.example('$0 conversation setup', 'Set up MCP server for Claude Code')
|
|
57
|
+
.example('$0 conversation search -q "authentication" -l 5', 'Search messages')
|
|
58
|
+
.example('$0 conversation context -q "how to implement JWT"', 'Get relevant context')
|
|
59
|
+
.example('$0 conversation thread -c conv_123', 'Get conversation thread')
|
|
60
|
+
.example('$0 conversation stats', 'Show conversation statistics');
|
|
61
|
+
},
|
|
62
|
+
handler: async (argv) => {
|
|
63
|
+
const action = argv.action || 'setup';
|
|
64
|
+
try {
|
|
65
|
+
switch (action) {
|
|
66
|
+
case 'setup':
|
|
67
|
+
await handleSetup(argv);
|
|
68
|
+
break;
|
|
69
|
+
case 'remove':
|
|
70
|
+
await handleRemove(argv);
|
|
71
|
+
break;
|
|
72
|
+
case 'search':
|
|
73
|
+
await handleSearch(argv);
|
|
74
|
+
break;
|
|
75
|
+
case 'context':
|
|
76
|
+
await handleContext(argv);
|
|
77
|
+
break;
|
|
78
|
+
case 'thread':
|
|
79
|
+
await handleThread(argv);
|
|
80
|
+
break;
|
|
81
|
+
case 'stats':
|
|
82
|
+
await handleStats(argv);
|
|
83
|
+
break;
|
|
84
|
+
case 'export':
|
|
85
|
+
await handleExport(argv);
|
|
86
|
+
break;
|
|
87
|
+
case 'import':
|
|
88
|
+
await handleImport(argv);
|
|
89
|
+
break;
|
|
90
|
+
default:
|
|
91
|
+
console.log(chalk.yellow(`Unknown action: ${action}`));
|
|
92
|
+
console.log('Run "brainy conversation --help" for usage information');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Handle setup command - Set up MCP server for Claude Code
|
|
103
|
+
*/
|
|
104
|
+
async function handleSetup(argv) {
|
|
105
|
+
console.log(chalk.bold.cyan('\n๐ง Brainy Infinite Memory Setup\n'));
|
|
106
|
+
// Check for existing setup
|
|
107
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '~';
|
|
108
|
+
const brainyDir = path.join(homeDir, '.brainy-memory');
|
|
109
|
+
const dataDir = path.join(brainyDir, 'data');
|
|
110
|
+
const serverPath = path.join(brainyDir, 'mcp-server.js');
|
|
111
|
+
const configPath = path.join(homeDir, '.config', 'claude-code', 'mcp-servers.json');
|
|
112
|
+
// Check if already set up
|
|
113
|
+
if (await fs.exists(brainyDir)) {
|
|
114
|
+
const { overwrite } = await inquirer.prompt([
|
|
115
|
+
{
|
|
116
|
+
type: 'confirm',
|
|
117
|
+
name: 'overwrite',
|
|
118
|
+
message: 'Brainy memory setup already exists. Overwrite?',
|
|
119
|
+
default: false
|
|
120
|
+
}
|
|
121
|
+
]);
|
|
122
|
+
if (!overwrite) {
|
|
123
|
+
console.log(chalk.yellow('Setup cancelled'));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const spinner = ora('Creating Brainy memory directory...').start();
|
|
128
|
+
try {
|
|
129
|
+
// Create directories
|
|
130
|
+
await fs.mkdir(brainyDir, { recursive: true });
|
|
131
|
+
await fs.mkdir(dataDir, { recursive: true });
|
|
132
|
+
spinner.succeed('Created Brainy memory directory');
|
|
133
|
+
// Create MCP server script
|
|
134
|
+
spinner.start('Creating MCP server script...');
|
|
135
|
+
const serverScript = `#!/usr/bin/env node
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Brainy Infinite Memory MCP Server
|
|
139
|
+
*
|
|
140
|
+
* This server provides conversation and context management
|
|
141
|
+
* for Claude Code through the Model Control Protocol (MCP).
|
|
142
|
+
*/
|
|
143
|
+
|
|
144
|
+
import { Brainy } from '@soulcraft/brainy'
|
|
145
|
+
import { BrainyMCPService } from '@soulcraft/brainy'
|
|
146
|
+
import { MCPConversationToolset } from '@soulcraft/brainy'
|
|
147
|
+
|
|
148
|
+
async function main() {
|
|
149
|
+
try {
|
|
150
|
+
// Initialize Brainy with filesystem storage
|
|
151
|
+
const brain = new Brainy({
|
|
152
|
+
storage: {
|
|
153
|
+
type: 'filesystem',
|
|
154
|
+
path: '${dataDir.replace(/\\/g, '/')}'
|
|
155
|
+
},
|
|
156
|
+
silent: true // Suppress console output
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
await brain.init()
|
|
160
|
+
|
|
161
|
+
// Create MCP service
|
|
162
|
+
const mcpService = new BrainyMCPService(brain, {
|
|
163
|
+
enableAuth: false // Local usage, no auth needed
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
// Create conversation toolset
|
|
167
|
+
const conversationTools = new MCPConversationToolset(brain)
|
|
168
|
+
await conversationTools.init()
|
|
169
|
+
|
|
170
|
+
// Register conversation tools
|
|
171
|
+
const tools = await conversationTools.getAvailableTools()
|
|
172
|
+
|
|
173
|
+
console.error('๐ง Brainy Memory Server started')
|
|
174
|
+
console.error(\`๐ \${tools.length} conversation tools available\`)
|
|
175
|
+
console.error('โ
Ready for Claude Code integration')
|
|
176
|
+
|
|
177
|
+
// Handle MCP requests via stdio
|
|
178
|
+
process.stdin.on('data', async (data) => {
|
|
179
|
+
try {
|
|
180
|
+
const request = JSON.parse(data.toString())
|
|
181
|
+
|
|
182
|
+
// Route conversation tool requests
|
|
183
|
+
let response
|
|
184
|
+
if (request.toolName && request.toolName.startsWith('conversation_')) {
|
|
185
|
+
response = await conversationTools.handleRequest(request)
|
|
186
|
+
} else {
|
|
187
|
+
response = await mcpService.handleRequest(request)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Write response to stdout
|
|
191
|
+
process.stdout.write(JSON.stringify(response) + '\\n')
|
|
192
|
+
} catch (error) {
|
|
193
|
+
console.error('Error handling request:', error)
|
|
194
|
+
}
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
// Handle shutdown gracefully
|
|
198
|
+
process.on('SIGINT', () => {
|
|
199
|
+
console.error('\\n๐ Shutting down Brainy Memory Server')
|
|
200
|
+
process.exit(0)
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
} catch (error) {
|
|
204
|
+
console.error('Failed to start Brainy Memory Server:', error)
|
|
205
|
+
process.exit(1)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
main()
|
|
210
|
+
`;
|
|
211
|
+
await fs.writeFile(serverPath, serverScript, 'utf8');
|
|
212
|
+
// Make executable on Unix systems
|
|
213
|
+
try {
|
|
214
|
+
await import('fs').then(fsModule => {
|
|
215
|
+
fsModule.promises.chmod(serverPath, 0o755).catch(() => { });
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
// Windows doesn't need chmod
|
|
220
|
+
}
|
|
221
|
+
spinner.succeed('Created MCP server script');
|
|
222
|
+
// Create Claude Code config
|
|
223
|
+
spinner.start('Configuring Claude Code...');
|
|
224
|
+
const configDir = path.dirname(configPath);
|
|
225
|
+
await fs.mkdir(configDir, { recursive: true });
|
|
226
|
+
let mcpConfig = {};
|
|
227
|
+
if (await fs.exists(configPath)) {
|
|
228
|
+
const existingConfig = await fs.readFile(configPath, 'utf8');
|
|
229
|
+
mcpConfig = JSON.parse(existingConfig);
|
|
230
|
+
}
|
|
231
|
+
mcpConfig['brainy-memory'] = {
|
|
232
|
+
command: 'node',
|
|
233
|
+
args: [serverPath],
|
|
234
|
+
env: {
|
|
235
|
+
NODE_ENV: 'production'
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
await fs.writeFile(configPath, JSON.stringify(mcpConfig, null, 2), 'utf8');
|
|
239
|
+
spinner.succeed('Configured Claude Code');
|
|
240
|
+
// Initialize Brainy database
|
|
241
|
+
spinner.start('Initializing Brainy database...');
|
|
242
|
+
const brain = new Brainy({
|
|
243
|
+
storage: {
|
|
244
|
+
type: 'filesystem',
|
|
245
|
+
options: {
|
|
246
|
+
path: dataDir
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
silent: true
|
|
250
|
+
});
|
|
251
|
+
await brain.init();
|
|
252
|
+
spinner.succeed('Initialized Brainy database');
|
|
253
|
+
// Success!
|
|
254
|
+
console.log(chalk.bold.green('\nโ
Setup complete!\n'));
|
|
255
|
+
console.log(chalk.cyan('๐ Memory storage:'), brainyDir);
|
|
256
|
+
console.log(chalk.cyan('๐ง MCP server:'), serverPath);
|
|
257
|
+
console.log(chalk.cyan('โ๏ธ Claude Code config:'), configPath);
|
|
258
|
+
console.log();
|
|
259
|
+
console.log(chalk.bold('๐ Next steps:'));
|
|
260
|
+
console.log(' 1. Restart Claude Code to load the MCP server');
|
|
261
|
+
console.log(' 2. Start a new conversation - your history will be saved automatically!');
|
|
262
|
+
console.log(' 3. Claude will use past context to help you work faster');
|
|
263
|
+
console.log();
|
|
264
|
+
console.log(chalk.dim('Run "brainy conversation stats" to see your conversation statistics'));
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
spinner.fail('Setup failed');
|
|
268
|
+
throw error;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Handle remove command - Remove MCP server and optionally data
|
|
273
|
+
*/
|
|
274
|
+
async function handleRemove(argv) {
|
|
275
|
+
console.log(chalk.bold.cyan('\n๐๏ธ Brainy Infinite Memory Removal\n'));
|
|
276
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '~';
|
|
277
|
+
const brainyDir = path.join(homeDir, '.brainy-memory');
|
|
278
|
+
const configPath = path.join(homeDir, '.config', 'claude-code', 'mcp-servers.json');
|
|
279
|
+
// Check if setup exists
|
|
280
|
+
const brainyExists = await fs.exists(brainyDir);
|
|
281
|
+
const configExists = await fs.exists(configPath);
|
|
282
|
+
if (!brainyExists && !configExists) {
|
|
283
|
+
console.log(chalk.yellow('No Brainy memory setup found. Nothing to remove.'));
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
// Show what will be removed
|
|
287
|
+
console.log(chalk.white('The following will be removed:'));
|
|
288
|
+
if (brainyExists) {
|
|
289
|
+
console.log(chalk.dim(` โข ${brainyDir} (memory data and MCP server)`));
|
|
290
|
+
}
|
|
291
|
+
if (configExists) {
|
|
292
|
+
console.log(chalk.dim(` โข MCP config entry in ${configPath}`));
|
|
293
|
+
}
|
|
294
|
+
console.log();
|
|
295
|
+
// Confirm removal
|
|
296
|
+
const { confirm } = await inquirer.prompt([
|
|
297
|
+
{
|
|
298
|
+
type: 'confirm',
|
|
299
|
+
name: 'confirm',
|
|
300
|
+
message: 'Are you sure you want to remove Brainy infinite memory?',
|
|
301
|
+
default: false
|
|
302
|
+
}
|
|
303
|
+
]);
|
|
304
|
+
if (!confirm) {
|
|
305
|
+
console.log(chalk.yellow('Removal cancelled'));
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
const spinner = ora('Removing Brainy memory setup...').start();
|
|
309
|
+
try {
|
|
310
|
+
// Remove Brainy directory
|
|
311
|
+
if (brainyExists) {
|
|
312
|
+
// Use Node.js fs for rm operation as universal fs doesn't have it
|
|
313
|
+
const nodefs = await import('fs');
|
|
314
|
+
await nodefs.promises.rm(brainyDir, { recursive: true, force: true });
|
|
315
|
+
spinner.text = 'Removed memory directory...';
|
|
316
|
+
}
|
|
317
|
+
// Remove MCP config entry
|
|
318
|
+
if (configExists) {
|
|
319
|
+
try {
|
|
320
|
+
const configContent = await fs.readFile(configPath, 'utf8');
|
|
321
|
+
const mcpConfig = JSON.parse(configContent);
|
|
322
|
+
if (mcpConfig['brainy-memory']) {
|
|
323
|
+
delete mcpConfig['brainy-memory'];
|
|
324
|
+
await fs.writeFile(configPath, JSON.stringify(mcpConfig, null, 2), 'utf8');
|
|
325
|
+
spinner.text = 'Removed MCP configuration...';
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
// If config file is corrupted or empty, skip
|
|
330
|
+
spinner.warn('Could not update MCP config file');
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
spinner.succeed('Successfully removed Brainy infinite memory');
|
|
334
|
+
console.log();
|
|
335
|
+
console.log(chalk.bold('โ
Cleanup complete'));
|
|
336
|
+
console.log();
|
|
337
|
+
console.log(chalk.white('All conversation data and MCP configuration have been removed.'));
|
|
338
|
+
console.log(chalk.dim('Run "brainy conversation setup" to set up again.'));
|
|
339
|
+
console.log();
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
spinner.fail('Removal failed');
|
|
343
|
+
console.error(chalk.red('Error:'), error.message);
|
|
344
|
+
throw error;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Handle search command - Search messages
|
|
349
|
+
*/
|
|
350
|
+
async function handleSearch(argv) {
|
|
351
|
+
if (!argv.query) {
|
|
352
|
+
console.log(chalk.yellow('Query required. Use -q or --query'));
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const spinner = ora('Searching conversations...').start();
|
|
356
|
+
const brain = new Brainy();
|
|
357
|
+
await brain.init();
|
|
358
|
+
const conv = brain.conversation();
|
|
359
|
+
await conv.init();
|
|
360
|
+
const results = await conv.searchMessages({
|
|
361
|
+
query: argv.query,
|
|
362
|
+
limit: argv.limit || 10,
|
|
363
|
+
role: argv.role,
|
|
364
|
+
includeContent: true,
|
|
365
|
+
includeMetadata: true
|
|
366
|
+
});
|
|
367
|
+
spinner.succeed(`Found ${results.length} messages`);
|
|
368
|
+
if (results.length === 0) {
|
|
369
|
+
console.log(chalk.yellow('No messages found'));
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
// Display results
|
|
373
|
+
console.log();
|
|
374
|
+
for (const result of results) {
|
|
375
|
+
console.log(chalk.bold.cyan(`${result.message.role}:`), result.snippet);
|
|
376
|
+
console.log(chalk.dim(` Score: ${result.score.toFixed(3)} | Conv: ${result.conversationId}`));
|
|
377
|
+
console.log();
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Handle context command - Get relevant context
|
|
382
|
+
*/
|
|
383
|
+
async function handleContext(argv) {
|
|
384
|
+
if (!argv.query) {
|
|
385
|
+
console.log(chalk.yellow('Query required. Use -q or --query'));
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
const spinner = ora('Retrieving relevant context...').start();
|
|
389
|
+
const brain = new Brainy();
|
|
390
|
+
await brain.init();
|
|
391
|
+
const conv = brain.conversation();
|
|
392
|
+
await conv.init();
|
|
393
|
+
const context = await conv.getRelevantContext(argv.query, {
|
|
394
|
+
limit: argv.limit || 10,
|
|
395
|
+
includeArtifacts: true,
|
|
396
|
+
includeSimilarConversations: true
|
|
397
|
+
});
|
|
398
|
+
spinner.succeed(`Retrieved ${context.messages.length} relevant messages`);
|
|
399
|
+
if (context.messages.length === 0) {
|
|
400
|
+
console.log(chalk.yellow('No relevant context found'));
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
// Display context
|
|
404
|
+
console.log();
|
|
405
|
+
console.log(chalk.bold('๐ Context Statistics:'));
|
|
406
|
+
console.log(chalk.dim(` Messages: ${context.messages.length}`));
|
|
407
|
+
console.log(chalk.dim(` Tokens: ${context.totalTokens}`));
|
|
408
|
+
console.log(chalk.dim(` Query time: ${context.metadata.queryTime}ms`));
|
|
409
|
+
console.log();
|
|
410
|
+
console.log(chalk.bold('๐ฌ Relevant Messages:'));
|
|
411
|
+
for (const msg of context.messages) {
|
|
412
|
+
console.log();
|
|
413
|
+
console.log(chalk.cyan(`${msg.role} (score: ${msg.relevanceScore.toFixed(3)}):`));
|
|
414
|
+
console.log(msg.content.substring(0, 200) + (msg.content.length > 200 ? '...' : ''));
|
|
415
|
+
}
|
|
416
|
+
if (context.similarConversations && context.similarConversations.length > 0) {
|
|
417
|
+
console.log();
|
|
418
|
+
console.log(chalk.bold('๐ Similar Conversations:'));
|
|
419
|
+
for (const conv of context.similarConversations) {
|
|
420
|
+
console.log(chalk.dim(` - ${conv.title || conv.id} (${conv.relevance.toFixed(2)})`));
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Handle thread command - Get conversation thread
|
|
426
|
+
*/
|
|
427
|
+
async function handleThread(argv) {
|
|
428
|
+
if (!argv.conversationId) {
|
|
429
|
+
console.log(chalk.yellow('Conversation ID required. Use -c or --conversation-id'));
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
const spinner = ora('Loading conversation thread...').start();
|
|
433
|
+
const brain = new Brainy();
|
|
434
|
+
await brain.init();
|
|
435
|
+
const conv = brain.conversation();
|
|
436
|
+
await conv.init();
|
|
437
|
+
const thread = await conv.getConversationThread(argv.conversationId, {
|
|
438
|
+
includeArtifacts: true
|
|
439
|
+
});
|
|
440
|
+
spinner.succeed(`Loaded ${thread.messages.length} messages`);
|
|
441
|
+
// Display thread
|
|
442
|
+
console.log();
|
|
443
|
+
console.log(chalk.bold('๐ Thread Information:'));
|
|
444
|
+
console.log(chalk.dim(` Conversation: ${thread.id}`));
|
|
445
|
+
console.log(chalk.dim(` Messages: ${thread.metadata.messageCount}`));
|
|
446
|
+
console.log(chalk.dim(` Tokens: ${thread.metadata.totalTokens}`));
|
|
447
|
+
console.log(chalk.dim(` Started: ${new Date(thread.metadata.startTime).toLocaleString()}`));
|
|
448
|
+
console.log();
|
|
449
|
+
console.log(chalk.bold('๐ฌ Messages:'));
|
|
450
|
+
for (const msg of thread.messages) {
|
|
451
|
+
console.log();
|
|
452
|
+
console.log(chalk.cyan(`${msg.role}:`), msg.content);
|
|
453
|
+
console.log(chalk.dim(` ${new Date(msg.createdAt).toLocaleString()}`));
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Handle stats command - Show statistics
|
|
458
|
+
*/
|
|
459
|
+
async function handleStats(argv) {
|
|
460
|
+
const spinner = ora('Calculating statistics...').start();
|
|
461
|
+
const brain = new Brainy();
|
|
462
|
+
await brain.init();
|
|
463
|
+
const conv = brain.conversation();
|
|
464
|
+
await conv.init();
|
|
465
|
+
const stats = await conv.getConversationStats();
|
|
466
|
+
spinner.succeed('Statistics calculated');
|
|
467
|
+
// Display stats
|
|
468
|
+
console.log();
|
|
469
|
+
console.log(chalk.bold.cyan('๐ Conversation Statistics\n'));
|
|
470
|
+
console.log(chalk.bold('Overall:'));
|
|
471
|
+
console.log(chalk.dim(` Conversations: ${stats.totalConversations}`));
|
|
472
|
+
console.log(chalk.dim(` Messages: ${stats.totalMessages}`));
|
|
473
|
+
console.log(chalk.dim(` Total Tokens: ${stats.totalTokens.toLocaleString()}`));
|
|
474
|
+
console.log(chalk.dim(` Avg Messages/Conversation: ${stats.averageMessagesPerConversation.toFixed(1)}`));
|
|
475
|
+
console.log(chalk.dim(` Avg Tokens/Message: ${stats.averageTokensPerMessage.toFixed(1)}`));
|
|
476
|
+
console.log();
|
|
477
|
+
if (Object.keys(stats.roles).length > 0) {
|
|
478
|
+
console.log(chalk.bold('By Role:'));
|
|
479
|
+
for (const [role, count] of Object.entries(stats.roles)) {
|
|
480
|
+
console.log(chalk.dim(` ${role}: ${count}`));
|
|
481
|
+
}
|
|
482
|
+
console.log();
|
|
483
|
+
}
|
|
484
|
+
if (Object.keys(stats.phases).length > 0) {
|
|
485
|
+
console.log(chalk.bold('By Phase:'));
|
|
486
|
+
for (const [phase, count] of Object.entries(stats.phases)) {
|
|
487
|
+
console.log(chalk.dim(` ${phase}: ${count}`));
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Handle export command - Export conversation
|
|
493
|
+
*/
|
|
494
|
+
async function handleExport(argv) {
|
|
495
|
+
if (!argv.conversationId) {
|
|
496
|
+
console.log(chalk.yellow('Conversation ID required. Use -c or --conversation-id'));
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
const spinner = ora('Exporting conversation...').start();
|
|
500
|
+
const brain = new Brainy();
|
|
501
|
+
await brain.init();
|
|
502
|
+
const conv = brain.conversation();
|
|
503
|
+
await conv.init();
|
|
504
|
+
const exported = await conv.exportConversation(argv.conversationId);
|
|
505
|
+
const output = argv.output || `conversation_${argv.conversationId}.json`;
|
|
506
|
+
await fs.writeFile(output, JSON.stringify(exported, null, 2), 'utf8');
|
|
507
|
+
spinner.succeed(`Exported to ${output}`);
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Handle import command - Import conversation
|
|
511
|
+
*/
|
|
512
|
+
async function handleImport(argv) {
|
|
513
|
+
const inputFile = argv.output;
|
|
514
|
+
if (!inputFile) {
|
|
515
|
+
console.log(chalk.yellow('Input file required. Use -o or --output'));
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
const spinner = ora('Importing conversation...').start();
|
|
519
|
+
const brain = new Brainy();
|
|
520
|
+
await brain.init();
|
|
521
|
+
const conv = brain.conversation();
|
|
522
|
+
await conv.init();
|
|
523
|
+
const data = JSON.parse(await fs.readFile(inputFile, 'utf8'));
|
|
524
|
+
const conversationId = await conv.importConversation(data);
|
|
525
|
+
spinner.succeed(`Imported as conversation ${conversationId}`);
|
|
526
|
+
}
|
|
527
|
+
export default conversationCommand;
|
|
528
|
+
//# sourceMappingURL=conversation.js.map
|
|
@@ -15,8 +15,20 @@ interface AddOptions extends CoreOptions {
|
|
|
15
15
|
}
|
|
16
16
|
interface SearchOptions extends CoreOptions {
|
|
17
17
|
limit?: string;
|
|
18
|
+
offset?: string;
|
|
18
19
|
threshold?: string;
|
|
19
|
-
|
|
20
|
+
type?: string;
|
|
21
|
+
where?: string;
|
|
22
|
+
near?: string;
|
|
23
|
+
connectedTo?: string;
|
|
24
|
+
connectedFrom?: string;
|
|
25
|
+
via?: string;
|
|
26
|
+
explain?: boolean;
|
|
27
|
+
includeRelations?: boolean;
|
|
28
|
+
fusion?: string;
|
|
29
|
+
vectorWeight?: string;
|
|
30
|
+
graphWeight?: string;
|
|
31
|
+
fieldWeight?: string;
|
|
20
32
|
}
|
|
21
33
|
interface GetOptions extends CoreOptions {
|
|
22
34
|
withConnections?: boolean;
|
|
@@ -38,7 +50,7 @@ export declare const coreCommands: {
|
|
|
38
50
|
*/
|
|
39
51
|
add(text: string, options: AddOptions): Promise<void>;
|
|
40
52
|
/**
|
|
41
|
-
* Search the neural database
|
|
53
|
+
* Search the neural database with Triple Intelligenceโข
|
|
42
54
|
*/
|
|
43
55
|
search(query: string, options: SearchOptions): Promise<void>;
|
|
44
56
|
/**
|