@toothfairyai/cli 1.0.8 ā 1.0.10
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/bin/toothfairy.js +107 -48
- package/package.json +1 -1
- package/src/api.js +6 -2
package/bin/toothfairy.js
CHANGED
|
@@ -321,7 +321,7 @@ program
|
|
|
321
321
|
let currentSpinner = null;
|
|
322
322
|
|
|
323
323
|
// Function to update display with status filtering
|
|
324
|
-
const updateDisplay = (text, agentStatus, type = 'response') => {
|
|
324
|
+
const updateDisplay = (text, agentStatus, messageId, type = 'response') => {
|
|
325
325
|
if (currentSpinner) {
|
|
326
326
|
currentSpinner.stop();
|
|
327
327
|
currentSpinner = null;
|
|
@@ -329,12 +329,13 @@ program
|
|
|
329
329
|
|
|
330
330
|
// Only show text when agent is actually replying
|
|
331
331
|
if (text && type === 'response' && agentStatus === 'replying') {
|
|
332
|
-
|
|
333
|
-
if
|
|
332
|
+
const trimmedText = text.trim();
|
|
333
|
+
// Check if text is actually new/different and longer than before
|
|
334
|
+
if (trimmedText !== currentText && trimmedText.length > currentText.length) {
|
|
334
335
|
// For real-time streaming, we overwrite the current line
|
|
335
336
|
process.stdout.write('\r\x1b[K'); // Clear current line
|
|
336
|
-
process.stdout.write(chalk.green('š§ Response: ') +
|
|
337
|
-
currentText =
|
|
337
|
+
process.stdout.write(chalk.green('š§ Response: ') + trimmedText);
|
|
338
|
+
currentText = trimmedText;
|
|
338
339
|
}
|
|
339
340
|
}
|
|
340
341
|
};
|
|
@@ -361,25 +362,39 @@ program
|
|
|
361
362
|
);
|
|
362
363
|
}
|
|
363
364
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
365
|
+
// Handle connection status events
|
|
366
|
+
if (eventData.status === 'connected') {
|
|
367
|
+
if (options.showProgress) {
|
|
368
|
+
console.log(chalk.green('š Connected to streaming server'));
|
|
369
|
+
}
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (eventData.status === 'complete') {
|
|
374
|
+
if (options.showProgress) {
|
|
375
|
+
console.log(chalk.green('\nš Stream completed successfully!'));
|
|
376
|
+
}
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Handle message events
|
|
381
|
+
if (eventData.type === 'message') {
|
|
382
|
+
let metadata = {};
|
|
383
|
+
let agentStatus = null;
|
|
384
|
+
|
|
385
|
+
// Parse metadata if available
|
|
386
|
+
if (eventData.metadata) {
|
|
387
|
+
try {
|
|
388
|
+
metadata = JSON.parse(eventData.metadata);
|
|
389
|
+
agentStatus = metadata.agent_processing_status;
|
|
390
|
+
} catch (e) {
|
|
391
|
+
// Metadata parsing failed, continue without it
|
|
376
392
|
}
|
|
377
393
|
}
|
|
378
|
-
|
|
379
|
-
//
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
processingStatus = newStatus;
|
|
394
|
+
|
|
395
|
+
// Handle status changes
|
|
396
|
+
if (agentStatus && agentStatus !== processingStatus) {
|
|
397
|
+
processingStatus = agentStatus;
|
|
383
398
|
if (options.showProgress) {
|
|
384
399
|
const statusMsg = mapStateWithLabel(processingStatus);
|
|
385
400
|
if (currentSpinner) {
|
|
@@ -388,24 +403,49 @@ program
|
|
|
388
403
|
currentSpinner = ora(chalk.yellow(statusMsg)).start();
|
|
389
404
|
}
|
|
390
405
|
}
|
|
391
|
-
|
|
392
|
-
//
|
|
393
|
-
if (eventData.text) {
|
|
394
|
-
updateDisplay(
|
|
406
|
+
|
|
407
|
+
// Handle progressive text streaming
|
|
408
|
+
if (eventData.text && agentStatus === 'replying') {
|
|
409
|
+
updateDisplay(
|
|
410
|
+
eventData.text,
|
|
411
|
+
agentStatus,
|
|
412
|
+
eventData.message_id,
|
|
413
|
+
'response'
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Handle fulfilled status (final response)
|
|
418
|
+
if (eventData.status === 'fulfilled') {
|
|
419
|
+
finalResponse = eventData;
|
|
420
|
+
if (currentText) {
|
|
421
|
+
// Clean final display with magic wand emoji
|
|
422
|
+
if (currentSpinner) {
|
|
423
|
+
currentSpinner.stop();
|
|
424
|
+
currentSpinner = null;
|
|
425
|
+
}
|
|
426
|
+
process.stdout.write('\r\x1b[K'); // Clear current line
|
|
427
|
+
process.stdout.write(chalk.blue('šŖ ') + currentText.trim());
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Handle additional metadata events (images, files, callback metadata)
|
|
432
|
+
if (eventData.images !== undefined || eventData.files !== undefined) {
|
|
433
|
+
// These are attachment events - could show notification if needed
|
|
434
|
+
if (options.verbose) {
|
|
435
|
+
console.log(chalk.dim('\nš Attachments processed'));
|
|
436
|
+
}
|
|
395
437
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
if (currentSpinner) {
|
|
402
|
-
currentSpinner.stop();
|
|
403
|
-
currentSpinner = null;
|
|
438
|
+
|
|
439
|
+
if (eventData.callbackMetadata) {
|
|
440
|
+
// Function execution metadata
|
|
441
|
+
if (options.verbose) {
|
|
442
|
+
console.log(chalk.dim('\nāļø Function execution metadata received'));
|
|
404
443
|
}
|
|
405
|
-
process.stdout.write('\r\x1b[K'); // Clear current line
|
|
406
|
-
process.stdout.write(chalk.blue('šŖ ') + currentText.trim());
|
|
407
444
|
}
|
|
408
|
-
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Handle errors
|
|
448
|
+
if (eventType === 'error') {
|
|
409
449
|
const errorMsg = eventData.message || 'Unknown streaming error';
|
|
410
450
|
if (currentSpinner) {
|
|
411
451
|
currentSpinner.stop();
|
|
@@ -425,19 +465,38 @@ program
|
|
|
425
465
|
|
|
426
466
|
if (options.verbose && finalResponse) {
|
|
427
467
|
// Show final response metadata in verbose mode
|
|
428
|
-
console.log(chalk.cyan.bold('š Final Response Metadata'));
|
|
429
|
-
console.log('ā'.repeat(
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
468
|
+
console.log(chalk.cyan.bold('\nš Final Response Metadata'));
|
|
469
|
+
console.log('ā'.repeat(50));
|
|
470
|
+
|
|
471
|
+
// Parse and display metadata from the final response
|
|
472
|
+
if (finalResponse.metadata) {
|
|
473
|
+
try {
|
|
474
|
+
const metadata = JSON.parse(finalResponse.metadata);
|
|
475
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
476
|
+
if (key === 'agent_processing_status') {
|
|
477
|
+
console.log(chalk.cyan(`${key}:`), chalk.green(value));
|
|
478
|
+
} else if (key === 'duration') {
|
|
479
|
+
console.log(chalk.cyan(`${key}:`), chalk.yellow(`${value}s`));
|
|
480
|
+
} else if (key === 'sources' && Array.isArray(value)) {
|
|
481
|
+
console.log(chalk.cyan(`${key}:`), value.length > 0 ? value.join(', ') : 'None');
|
|
482
|
+
} else {
|
|
483
|
+
console.log(chalk.cyan(`${key}:`), String(value));
|
|
484
|
+
}
|
|
437
485
|
}
|
|
486
|
+
} catch (e) {
|
|
487
|
+
console.log(chalk.red('Could not parse metadata'));
|
|
438
488
|
}
|
|
439
489
|
}
|
|
440
|
-
|
|
490
|
+
|
|
491
|
+
// Show additional response fields
|
|
492
|
+
if (finalResponse.message_id) {
|
|
493
|
+
console.log(chalk.cyan('message_id:'), finalResponse.message_id);
|
|
494
|
+
}
|
|
495
|
+
if (finalResponse.t_text_summary) {
|
|
496
|
+
console.log(chalk.cyan('summary:'), finalResponse.t_text_summary);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
console.log('ā'.repeat(50));
|
|
441
500
|
}
|
|
442
501
|
|
|
443
502
|
if (!currentText) {
|
|
@@ -719,7 +778,7 @@ program
|
|
|
719
778
|
program
|
|
720
779
|
.command('config-show')
|
|
721
780
|
.description('Show current configuration')
|
|
722
|
-
.action(async (
|
|
781
|
+
.action(async (command) => {
|
|
723
782
|
try {
|
|
724
783
|
const globalOptions = command.parent.opts();
|
|
725
784
|
const config = loadConfig(globalOptions.config);
|
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -318,7 +318,9 @@ class ToothFairyAPI {
|
|
|
318
318
|
};
|
|
319
319
|
|
|
320
320
|
const createdChat = await this.createChat(chatData);
|
|
321
|
-
|
|
321
|
+
if (this.verbose) {
|
|
322
|
+
console.debug(`Chat created: ${createdChat.id}`);
|
|
323
|
+
}
|
|
322
324
|
|
|
323
325
|
// Create message
|
|
324
326
|
const messageData = {
|
|
@@ -328,7 +330,9 @@ class ToothFairyAPI {
|
|
|
328
330
|
userID: 'CLI',
|
|
329
331
|
};
|
|
330
332
|
const createdMessage = await this.createMessage(messageData);
|
|
331
|
-
|
|
333
|
+
if (this.verbose) {
|
|
334
|
+
console.debug(`Message created: ${createdMessage.id}`);
|
|
335
|
+
}
|
|
332
336
|
|
|
333
337
|
// Prepare agent data for streaming
|
|
334
338
|
const agentData = {
|