@memograph/cli 0.1.8 → 1.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/README.md +21 -364
- package/dist/cli.js +55 -8
- package/dist/cli.js.map +1 -1
- package/dist/core/hosted/analyze-client.d.ts +4 -0
- package/dist/core/hosted/analyze-client.d.ts.map +1 -0
- package/dist/core/hosted/analyze-client.js +116 -0
- package/dist/core/hosted/analyze-client.js.map +1 -0
- package/dist/core/hosted/types.d.ts +31 -0
- package/dist/core/hosted/types.d.ts.map +1 -0
- package/dist/core/hosted/types.js +3 -0
- package/dist/core/hosted/types.js.map +1 -0
- package/dist/core/inspect.d.ts.map +1 -1
- package/dist/core/inspect.js +26 -0
- package/dist/core/inspect.js.map +1 -1
- package/dist/core/progress.d.ts +14 -0
- package/dist/core/progress.d.ts.map +1 -0
- package/dist/core/progress.js +83 -0
- package/dist/core/progress.js.map +1 -0
- package/dist/core/types.d.ts +8 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/interactive/index.d.ts +6 -0
- package/dist/interactive/index.d.ts.map +1 -1
- package/dist/interactive/index.js +338 -149
- package/dist/interactive/index.js.map +1 -1
- package/dist/interactive/settings.d.ts +11 -0
- package/dist/interactive/settings.d.ts.map +1 -1
- package/dist/interactive/settings.js +67 -7
- package/dist/interactive/settings.js.map +1 -1
- package/package.json +1 -1
|
@@ -53,6 +53,7 @@ exports.runInteractiveMode = runInteractiveMode;
|
|
|
53
53
|
const readline = __importStar(require("readline"));
|
|
54
54
|
const inspect_js_1 = require("../core/inspect.js");
|
|
55
55
|
const load_js_1 = require("../core/load.js");
|
|
56
|
+
const progress_js_1 = require("../core/progress.js");
|
|
56
57
|
const render_js_1 = require("../core/render.js");
|
|
57
58
|
const providers_js_1 = require("../core/llm/providers.js");
|
|
58
59
|
const wizard_js_1 = require("./wizard.js");
|
|
@@ -503,17 +504,45 @@ function showBanner() {
|
|
|
503
504
|
renderBanner(true);
|
|
504
505
|
}
|
|
505
506
|
/**
|
|
506
|
-
*
|
|
507
|
+
* Resolve analyze mode from settings + env
|
|
508
|
+
*/
|
|
509
|
+
function resolveAnalyzeMode(settings) {
|
|
510
|
+
if (process.env.MEMOGRAPH_ANALYZE_MODE === 'llm') {
|
|
511
|
+
return 'llm';
|
|
512
|
+
}
|
|
513
|
+
return settings.analyzeMode || 'hosted';
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Check configuration and prompt for required setup if needed
|
|
507
517
|
*/
|
|
508
518
|
async function checkAndPromptWizard(settings) {
|
|
509
|
-
|
|
519
|
+
settings.analyzeMode = resolveAnalyzeMode(settings);
|
|
520
|
+
const status = (0, settings_js_1.getAnalyzeConfigStatus)(settings);
|
|
510
521
|
if (status.configured) {
|
|
511
522
|
return true;
|
|
512
523
|
}
|
|
513
524
|
console.log(`\n❌ ${status.message}`);
|
|
514
|
-
|
|
525
|
+
const mode = resolveAnalyzeMode(settings);
|
|
526
|
+
console.log(`\n${mode === 'hosted' ? 'Analyze API' : 'AI model'} is not configured yet.`);
|
|
515
527
|
// Ensure stdin is active and in the correct mode
|
|
516
528
|
await ensureStdinReady();
|
|
529
|
+
if (mode === 'hosted') {
|
|
530
|
+
const rl = createRL();
|
|
531
|
+
const response = await ask(rl, 'Set Analyze API URL now? (Y/n): ');
|
|
532
|
+
rl.close();
|
|
533
|
+
if (response.toLowerCase() === 'y' || response === '') {
|
|
534
|
+
await ensureStdinReady();
|
|
535
|
+
const rl2 = createRL();
|
|
536
|
+
const apiUrl = await ask(rl2, `Enter Analyze API URL (default: ${settings.api.url || 'https://ap-south-1-test.memograph.click/v1/analyze'}): `);
|
|
537
|
+
rl2.close();
|
|
538
|
+
if (apiUrl.trim()) {
|
|
539
|
+
settings.api.url = apiUrl.trim();
|
|
540
|
+
}
|
|
541
|
+
(0, settings_js_1.saveSettings)(settings);
|
|
542
|
+
return (0, settings_js_1.isAnalyzeConfigured)(settings);
|
|
543
|
+
}
|
|
544
|
+
return false;
|
|
545
|
+
}
|
|
517
546
|
const rl = createRL();
|
|
518
547
|
const response = await ask(rl, 'Run Setup Wizard now? (Y/n): ');
|
|
519
548
|
rl.close();
|
|
@@ -521,9 +550,9 @@ async function checkAndPromptWizard(settings) {
|
|
|
521
550
|
console.clear();
|
|
522
551
|
const newSettings = await (0, wizard_js_1.runSetupWizard)(settings);
|
|
523
552
|
Object.assign(settings, newSettings);
|
|
553
|
+
settings.analyzeMode = 'llm';
|
|
524
554
|
(0, settings_js_1.saveSettings)(settings);
|
|
525
|
-
|
|
526
|
-
return (0, settings_js_1.isLLMConfigured)(settings);
|
|
555
|
+
return (0, settings_js_1.isAnalyzeConfigured)(settings);
|
|
527
556
|
}
|
|
528
557
|
return false;
|
|
529
558
|
}
|
|
@@ -531,17 +560,24 @@ async function checkAndPromptWizard(settings) {
|
|
|
531
560
|
* Display current settings
|
|
532
561
|
*/
|
|
533
562
|
function displaySettings(settings) {
|
|
563
|
+
const mode = resolveAnalyzeMode(settings);
|
|
534
564
|
const maskedKey = settings.llm.apiKey
|
|
535
565
|
? settings.llm.apiKey.substring(0, 8) + '••••••••••••'
|
|
536
566
|
: '(not set)';
|
|
537
567
|
console.log('\n╭─ Current Settings ─────────────────────────────────────╮');
|
|
538
568
|
console.log('│ │');
|
|
539
|
-
console.log(`│ ◆
|
|
540
|
-
console.log(`│ ◆
|
|
541
|
-
console.log(`│ ◆
|
|
542
|
-
console.log(`│ ◆
|
|
543
|
-
|
|
544
|
-
|
|
569
|
+
console.log(`│ ◆ Analyze Mode: ${mode.padEnd(20)}│`);
|
|
570
|
+
console.log(`│ ◆ API URL: ${(settings.api.url || '(not set)').padEnd(20)}│`);
|
|
571
|
+
console.log(`│ ◆ API Timeout: ${String(settings.api.timeoutMs).padEnd(20)}│`);
|
|
572
|
+
console.log(`│ ◆ API Retries: ${String(settings.api.retries).padEnd(20)}│`);
|
|
573
|
+
if (mode === 'llm') {
|
|
574
|
+
console.log(`│ ◆ LLM Provider: ${settings.llm.provider.padEnd(20)}│`);
|
|
575
|
+
console.log(`│ ◆ LLM Model: ${settings.llm.model.padEnd(20)}│`);
|
|
576
|
+
console.log(`│ ◆ Temperature: ${String(settings.llm.temperature).padEnd(20)}│`);
|
|
577
|
+
console.log(`│ ◆ Max Tokens: ${String(settings.llm.maxTokens).padEnd(20)}│`);
|
|
578
|
+
console.log(`│ ◆ LLM Base URL: ${(settings.llm.baseUrl || '(default)').padEnd(20)}│`);
|
|
579
|
+
console.log(`│ ◆ LLM API Key: ${maskedKey.padEnd(20)}│`);
|
|
580
|
+
}
|
|
545
581
|
console.log('│ │');
|
|
546
582
|
console.log('╰──────────────────────────────────────────────────────╯\n');
|
|
547
583
|
}
|
|
@@ -549,160 +585,286 @@ function displaySettings(settings) {
|
|
|
549
585
|
* Settings menu
|
|
550
586
|
*/
|
|
551
587
|
async function settingsMenu(settings) {
|
|
552
|
-
const options = [
|
|
553
|
-
'Quick Setup (Wizard)',
|
|
554
|
-
'Change LLM Provider',
|
|
555
|
-
'Change LLM Model',
|
|
556
|
-
'Change Temperature',
|
|
557
|
-
'Change Max Tokens',
|
|
558
|
-
'Change Base URL',
|
|
559
|
-
'Set/Update API Key',
|
|
560
|
-
'Show raw config',
|
|
561
|
-
'Back to main menu',
|
|
562
|
-
];
|
|
563
588
|
while (true) {
|
|
589
|
+
const mode = resolveAnalyzeMode(settings);
|
|
590
|
+
settings.analyzeMode = mode;
|
|
591
|
+
const options = mode === 'hosted'
|
|
592
|
+
? [
|
|
593
|
+
'Change Analyze Mode',
|
|
594
|
+
'Change API URL',
|
|
595
|
+
'Change API Timeout',
|
|
596
|
+
'Change API Retries',
|
|
597
|
+
'Advanced: LLM Setup (Legacy)',
|
|
598
|
+
'Show raw config',
|
|
599
|
+
'Back to main menu',
|
|
600
|
+
]
|
|
601
|
+
: [
|
|
602
|
+
'Change Analyze Mode',
|
|
603
|
+
'Quick Setup (Wizard)',
|
|
604
|
+
'Change LLM Provider',
|
|
605
|
+
'Change LLM Model',
|
|
606
|
+
'Change Temperature',
|
|
607
|
+
'Change Max Tokens',
|
|
608
|
+
'Change Base URL',
|
|
609
|
+
'Set/Update API Key',
|
|
610
|
+
'Show raw config',
|
|
611
|
+
'Back to main menu',
|
|
612
|
+
];
|
|
564
613
|
const choice = await selectMenu('Settings', options);
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
}
|
|
577
|
-
break;
|
|
578
|
-
case 1: // Change provider
|
|
579
|
-
{
|
|
580
|
-
const selectedProvider = await selectProvider();
|
|
581
|
-
settings.llm.provider = selectedProvider;
|
|
582
|
-
const providerInfo = (0, providers_js_1.getProviderInfo)(selectedProvider);
|
|
583
|
-
if (providerInfo?.defaultBaseUrl) {
|
|
584
|
-
settings.llm.baseUrl = providerInfo.defaultBaseUrl;
|
|
585
|
-
}
|
|
586
|
-
(0, settings_js_1.saveSettings)(settings);
|
|
587
|
-
console.log('\n✓ Provider updated to', settings.llm.provider);
|
|
588
|
-
await ensureStdinReady();
|
|
589
|
-
await ask(createRL(), '\nPress Enter to continue...');
|
|
590
|
-
}
|
|
591
|
-
break;
|
|
592
|
-
case 2: // Change model
|
|
593
|
-
{
|
|
594
|
-
const models = settings.llm.provider === 'openai'
|
|
595
|
-
? ['gpt-4o-mini (recommended)', 'gpt-4o', 'gpt-3.5-turbo', 'Custom...']
|
|
596
|
-
: ['claude-3-5-sonnet-20241022 (recommended)', 'claude-3-5-haiku-20241022', 'Custom...'];
|
|
597
|
-
const modelChoice = await selectMenu('Select LLM Model', models);
|
|
598
|
-
const selected = models[modelChoice];
|
|
599
|
-
if (selected === 'Custom...') {
|
|
614
|
+
if (mode === 'hosted') {
|
|
615
|
+
switch (choice) {
|
|
616
|
+
case 0: // Change mode
|
|
617
|
+
{
|
|
618
|
+
const modeChoice = await selectMenu('Select Analyze Mode', [
|
|
619
|
+
'hosted (default)',
|
|
620
|
+
'llm (legacy fallback)',
|
|
621
|
+
]);
|
|
622
|
+
settings.analyzeMode = modeChoice === 0 ? 'hosted' : 'llm';
|
|
623
|
+
(0, settings_js_1.saveSettings)(settings);
|
|
624
|
+
console.log('\n✓ Analyze mode updated to', settings.analyzeMode);
|
|
600
625
|
await ensureStdinReady();
|
|
601
|
-
|
|
602
|
-
settings.llm.model = customModel;
|
|
626
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
603
627
|
}
|
|
604
|
-
|
|
605
|
-
|
|
628
|
+
break;
|
|
629
|
+
case 1: // API URL
|
|
630
|
+
{
|
|
631
|
+
await ensureStdinReady();
|
|
632
|
+
const apiUrl = await ask(createRL(), `Enter Analyze API URL (current: ${settings.api.url}): `);
|
|
633
|
+
if (apiUrl.trim()) {
|
|
634
|
+
settings.api.url = apiUrl.trim();
|
|
635
|
+
(0, settings_js_1.saveSettings)(settings);
|
|
636
|
+
console.log('\n✓ API URL updated');
|
|
637
|
+
}
|
|
638
|
+
await ensureStdinReady();
|
|
639
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
606
640
|
}
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
await ensureStdinReady();
|
|
616
|
-
const temp = await ask(createRL(), 'Enter temperature (0.0-1.0, default 0.3): ');
|
|
617
|
-
if (temp) {
|
|
618
|
-
const tempVal = parseFloat(temp);
|
|
619
|
-
if (!isNaN(tempVal) && tempVal >= 0 && tempVal <= 1) {
|
|
620
|
-
settings.llm.temperature = tempVal;
|
|
641
|
+
break;
|
|
642
|
+
case 2: // API timeout
|
|
643
|
+
{
|
|
644
|
+
await ensureStdinReady();
|
|
645
|
+
const timeout = await ask(createRL(), `Enter API timeout in ms (current: ${settings.api.timeoutMs}): `);
|
|
646
|
+
const timeoutVal = parseInt(timeout, 10);
|
|
647
|
+
if (!isNaN(timeoutVal) && timeoutVal > 0) {
|
|
648
|
+
settings.api.timeoutMs = timeoutVal;
|
|
621
649
|
(0, settings_js_1.saveSettings)(settings);
|
|
622
|
-
console.log('\n✓
|
|
650
|
+
console.log('\n✓ API timeout updated');
|
|
623
651
|
}
|
|
624
|
-
else {
|
|
625
|
-
console.log('\n❌ Invalid
|
|
652
|
+
else if (timeout.trim()) {
|
|
653
|
+
console.log('\n❌ Invalid timeout value');
|
|
626
654
|
}
|
|
655
|
+
await ensureStdinReady();
|
|
656
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
627
657
|
}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
if (maxTokens) {
|
|
637
|
-
const tokensVal = parseInt(maxTokens, 10);
|
|
638
|
-
if (!isNaN(tokensVal) && tokensVal > 0) {
|
|
639
|
-
settings.llm.maxTokens = tokensVal;
|
|
658
|
+
break;
|
|
659
|
+
case 3: // API retries
|
|
660
|
+
{
|
|
661
|
+
await ensureStdinReady();
|
|
662
|
+
const retries = await ask(createRL(), `Enter API retries (current: ${settings.api.retries}): `);
|
|
663
|
+
const retriesVal = parseInt(retries, 10);
|
|
664
|
+
if (!isNaN(retriesVal) && retriesVal >= 0) {
|
|
665
|
+
settings.api.retries = retriesVal;
|
|
640
666
|
(0, settings_js_1.saveSettings)(settings);
|
|
641
|
-
console.log('\n✓
|
|
667
|
+
console.log('\n✓ API retries updated');
|
|
642
668
|
}
|
|
643
|
-
else {
|
|
644
|
-
console.log('\n❌ Invalid value
|
|
669
|
+
else if (retries.trim()) {
|
|
670
|
+
console.log('\n❌ Invalid retries value');
|
|
645
671
|
}
|
|
672
|
+
await ensureStdinReady();
|
|
673
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
646
674
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
settings
|
|
675
|
+
break;
|
|
676
|
+
case 4: // Legacy wizard
|
|
677
|
+
{
|
|
678
|
+
console.clear();
|
|
679
|
+
const newSettings = await (0, wizard_js_1.runSetupWizard)(settings);
|
|
680
|
+
Object.assign(settings, newSettings);
|
|
681
|
+
settings.analyzeMode = 'llm';
|
|
682
|
+
(0, settings_js_1.saveSettings)(settings);
|
|
683
|
+
console.clear();
|
|
684
|
+
displaySettings(settings);
|
|
685
|
+
await ensureStdinReady();
|
|
686
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
657
687
|
}
|
|
658
|
-
|
|
659
|
-
|
|
688
|
+
break;
|
|
689
|
+
case 5: // Show raw config
|
|
690
|
+
{
|
|
691
|
+
const displayConfig = {
|
|
692
|
+
...settings,
|
|
693
|
+
llm: {
|
|
694
|
+
...settings.llm,
|
|
695
|
+
apiKey: settings.llm.apiKey
|
|
696
|
+
? settings.llm.apiKey.substring(0, 8) + '••••••••••'
|
|
697
|
+
: '',
|
|
698
|
+
},
|
|
699
|
+
};
|
|
700
|
+
console.log('\nRaw configuration:');
|
|
701
|
+
console.log(JSON.stringify(displayConfig, null, 2));
|
|
702
|
+
await ensureStdinReady();
|
|
703
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
660
704
|
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
705
|
+
break;
|
|
706
|
+
case 6: // Back
|
|
707
|
+
console.clear();
|
|
708
|
+
return true;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
else {
|
|
712
|
+
switch (choice) {
|
|
713
|
+
case 0: // Change mode
|
|
714
|
+
{
|
|
715
|
+
const modeChoice = await selectMenu('Select Analyze Mode', [
|
|
716
|
+
'hosted (default)',
|
|
717
|
+
'llm (legacy fallback)',
|
|
718
|
+
]);
|
|
719
|
+
settings.analyzeMode = modeChoice === 0 ? 'hosted' : 'llm';
|
|
720
|
+
(0, settings_js_1.saveSettings)(settings);
|
|
721
|
+
console.log('\n✓ Analyze mode updated to', settings.analyzeMode);
|
|
722
|
+
await ensureStdinReady();
|
|
723
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
724
|
+
}
|
|
725
|
+
break;
|
|
726
|
+
case 1: // Quick setup wizard
|
|
727
|
+
{
|
|
728
|
+
console.clear();
|
|
729
|
+
const newSettings = await (0, wizard_js_1.runSetupWizard)(settings);
|
|
730
|
+
Object.assign(settings, newSettings);
|
|
731
|
+
settings.analyzeMode = 'llm';
|
|
732
|
+
(0, settings_js_1.saveSettings)(settings);
|
|
733
|
+
console.clear();
|
|
734
|
+
displaySettings(settings);
|
|
672
735
|
await ensureStdinReady();
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
736
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
737
|
+
}
|
|
738
|
+
break;
|
|
739
|
+
case 2: // Change provider
|
|
740
|
+
{
|
|
741
|
+
const selectedProvider = await selectProvider();
|
|
742
|
+
settings.llm.provider = selectedProvider;
|
|
743
|
+
const providerInfo = (0, providers_js_1.getProviderInfo)(selectedProvider);
|
|
744
|
+
if (providerInfo?.defaultBaseUrl) {
|
|
745
|
+
settings.llm.baseUrl = providerInfo.defaultBaseUrl;
|
|
678
746
|
}
|
|
747
|
+
(0, settings_js_1.saveSettings)(settings);
|
|
748
|
+
console.log('\n✓ Provider updated to', settings.llm.provider);
|
|
749
|
+
await ensureStdinReady();
|
|
750
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
679
751
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
settings.llm.
|
|
752
|
+
break;
|
|
753
|
+
case 3: // Change model
|
|
754
|
+
{
|
|
755
|
+
const models = settings.llm.provider === 'openai'
|
|
756
|
+
? ['gpt-4o-mini (recommended)', 'gpt-4o', 'gpt-3.5-turbo', 'Custom...']
|
|
757
|
+
: ['claude-3-5-sonnet-20241022 (recommended)', 'claude-3-5-haiku-20241022', 'Custom...'];
|
|
758
|
+
const modelChoice = await selectMenu('Select LLM Model', models);
|
|
759
|
+
const selected = models[modelChoice];
|
|
760
|
+
if (selected === 'Custom...') {
|
|
761
|
+
await ensureStdinReady();
|
|
762
|
+
const customModel = await ask(createRL(), 'Enter custom model name: ');
|
|
763
|
+
settings.llm.model = customModel;
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
settings.llm.model = selected.split(' ')[0];
|
|
767
|
+
}
|
|
684
768
|
(0, settings_js_1.saveSettings)(settings);
|
|
685
|
-
console.log('\n✓
|
|
769
|
+
console.log('\n✓ Model updated to', settings.llm.model);
|
|
770
|
+
await ensureStdinReady();
|
|
771
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
686
772
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
773
|
+
break;
|
|
774
|
+
case 4: // Change temperature
|
|
775
|
+
{
|
|
776
|
+
await ensureStdinReady();
|
|
777
|
+
const temp = await ask(createRL(), 'Enter temperature (0.0-1.0, default 0.3): ');
|
|
778
|
+
if (temp) {
|
|
779
|
+
const tempVal = parseFloat(temp);
|
|
780
|
+
if (!isNaN(tempVal) && tempVal >= 0 && tempVal <= 1) {
|
|
781
|
+
settings.llm.temperature = tempVal;
|
|
782
|
+
(0, settings_js_1.saveSettings)(settings);
|
|
783
|
+
console.log('\n✓ Temperature updated to', tempVal);
|
|
784
|
+
}
|
|
785
|
+
else {
|
|
786
|
+
console.log('\n❌ Invalid temperature. Must be between 0.0 and 1.0');
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
await ensureStdinReady();
|
|
790
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
696
791
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
792
|
+
break;
|
|
793
|
+
case 5: // Change max tokens
|
|
794
|
+
{
|
|
795
|
+
await ensureStdinReady();
|
|
796
|
+
const maxTokens = await ask(createRL(), 'Enter max tokens (default 4096): ');
|
|
797
|
+
if (maxTokens) {
|
|
798
|
+
const tokensVal = parseInt(maxTokens, 10);
|
|
799
|
+
if (!isNaN(tokensVal) && tokensVal > 0) {
|
|
800
|
+
settings.llm.maxTokens = tokensVal;
|
|
801
|
+
(0, settings_js_1.saveSettings)(settings);
|
|
802
|
+
console.log('\n✓ Max tokens updated to', tokensVal);
|
|
803
|
+
}
|
|
804
|
+
else {
|
|
805
|
+
console.log('\n❌ Invalid value. Must be a positive number');
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
await ensureStdinReady();
|
|
809
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
810
|
+
}
|
|
811
|
+
break;
|
|
812
|
+
case 6: // Change base URL
|
|
813
|
+
{
|
|
814
|
+
await ensureStdinReady();
|
|
815
|
+
const baseUrl = await ask(createRL(), 'Enter base URL (or press Enter to clear): ');
|
|
816
|
+
if (baseUrl) {
|
|
817
|
+
settings.llm.baseUrl = baseUrl;
|
|
818
|
+
}
|
|
819
|
+
else {
|
|
820
|
+
settings.llm.baseUrl = undefined;
|
|
821
|
+
}
|
|
822
|
+
(0, settings_js_1.saveSettings)(settings);
|
|
823
|
+
console.log('\n✓ Base URL updated');
|
|
824
|
+
await ensureStdinReady();
|
|
825
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
826
|
+
}
|
|
827
|
+
break;
|
|
828
|
+
case 7: // Set API key
|
|
829
|
+
{
|
|
830
|
+
const currentKey = settings.llm.apiKey;
|
|
831
|
+
if (currentKey) {
|
|
832
|
+
console.log('\nCurrent API key:', currentKey.substring(0, 8) + '••••••••••');
|
|
833
|
+
await ensureStdinReady();
|
|
834
|
+
const confirm = await ask(createRL(), 'Update API key? (y/N): ');
|
|
835
|
+
if (confirm.toLowerCase() !== 'y') {
|
|
836
|
+
console.clear();
|
|
837
|
+
displaySettings(settings);
|
|
838
|
+
break;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
await ensureStdinReady();
|
|
842
|
+
const apiKey = await askMasked(`Enter ${settings.llm.provider.toUpperCase()} API key: `);
|
|
843
|
+
if (apiKey) {
|
|
844
|
+
settings.llm.apiKey = apiKey;
|
|
845
|
+
(0, settings_js_1.saveSettings)(settings);
|
|
846
|
+
console.log('\n✓ API key updated');
|
|
847
|
+
}
|
|
848
|
+
await ensureStdinReady();
|
|
849
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
850
|
+
}
|
|
851
|
+
break;
|
|
852
|
+
case 8: // Show raw config
|
|
853
|
+
{
|
|
854
|
+
const displayConfig = { ...settings };
|
|
855
|
+
if (displayConfig.llm.apiKey) {
|
|
856
|
+
displayConfig.llm.apiKey = displayConfig.llm.apiKey.substring(0, 8) + '••••••••••';
|
|
857
|
+
}
|
|
858
|
+
console.log('\nRaw configuration:');
|
|
859
|
+
console.log(JSON.stringify(displayConfig, null, 2));
|
|
860
|
+
await ensureStdinReady();
|
|
861
|
+
await ask(createRL(), '\nPress Enter to continue...');
|
|
862
|
+
}
|
|
863
|
+
break;
|
|
864
|
+
case 9: // Back
|
|
865
|
+
console.clear();
|
|
866
|
+
return true;
|
|
867
|
+
}
|
|
706
868
|
}
|
|
707
869
|
console.clear();
|
|
708
870
|
displaySettings(settings);
|
|
@@ -748,15 +910,39 @@ async function inspectTranscriptInteractive(settings) {
|
|
|
748
910
|
// Get output format
|
|
749
911
|
const formatChoice = await selectMenu('Output Format', ['Text (human-readable)', 'JSON (machine-readable)']);
|
|
750
912
|
const asJson = formatChoice === 1;
|
|
751
|
-
console.log('\n✓ Loading transcript...');
|
|
752
913
|
console.log(`✓ Loaded transcript with ${transcript.messages.length} messages`);
|
|
753
|
-
|
|
914
|
+
const mode = resolveAnalyzeMode(settings);
|
|
754
915
|
const config = {
|
|
916
|
+
analyzeMode: mode,
|
|
755
917
|
max_messages: 2000,
|
|
756
|
-
|
|
918
|
+
apiUrl: settings.api.url,
|
|
919
|
+
apiTimeoutMs: settings.api.timeoutMs,
|
|
920
|
+
apiRetries: settings.api.retries,
|
|
921
|
+
...(mode === 'llm' ? { llm: settings.llm } : {}),
|
|
757
922
|
};
|
|
758
|
-
const
|
|
759
|
-
|
|
923
|
+
const progress = (0, progress_js_1.createProgressIndicator)(mode === 'hosted' ? 'Sending transcript to hosted Analyze API' : 'Extracting facts using LLM', {
|
|
924
|
+
messages: mode === 'hosted'
|
|
925
|
+
? [
|
|
926
|
+
'Sending transcript to hosted Analyze API',
|
|
927
|
+
'Waiting for hosted analysis',
|
|
928
|
+
'Preparing drift report',
|
|
929
|
+
]
|
|
930
|
+
: [
|
|
931
|
+
'Extracting facts using LLM',
|
|
932
|
+
'Detecting drift patterns',
|
|
933
|
+
'Scoring conversation quality',
|
|
934
|
+
],
|
|
935
|
+
});
|
|
936
|
+
let result;
|
|
937
|
+
try {
|
|
938
|
+
result = await (0, inspect_js_1.inspectTranscript)(transcript, config);
|
|
939
|
+
progress.succeed('Analysis complete');
|
|
940
|
+
}
|
|
941
|
+
catch (error) {
|
|
942
|
+
progress.fail('Analysis failed');
|
|
943
|
+
throw error;
|
|
944
|
+
}
|
|
945
|
+
console.log('');
|
|
760
946
|
const output = asJson ? (0, render_js_1.renderJsonReport)(result) : (0, render_js_1.renderTextReport)(result);
|
|
761
947
|
// Use direct write with proper async handling instead of console.log
|
|
762
948
|
await new Promise((resolve) => {
|
|
@@ -779,6 +965,9 @@ async function inspectTranscriptInteractive(settings) {
|
|
|
779
965
|
await ensureStdinReady();
|
|
780
966
|
}
|
|
781
967
|
catch (error) {
|
|
968
|
+
if (process.stdout.isTTY) {
|
|
969
|
+
process.stdout.write('\n');
|
|
970
|
+
}
|
|
782
971
|
const errorMsg = '\n❌ Error: ' + (error instanceof Error ? error.message : 'Unknown error');
|
|
783
972
|
// Use direct write with proper async handling
|
|
784
973
|
await new Promise((resolve) => {
|