@juspay/neurolink 7.33.3 → 7.34.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.
Files changed (135) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +37 -0
  3. package/dist/cli/commands/config.d.ts +3 -4
  4. package/dist/cli/commands/config.js +2 -3
  5. package/dist/cli/errorHandler.d.ts +1 -0
  6. package/dist/cli/errorHandler.js +28 -0
  7. package/dist/cli/factories/commandFactory.d.ts +23 -0
  8. package/dist/cli/factories/commandFactory.js +375 -60
  9. package/dist/cli/factories/ollamaCommandFactory.js +7 -1
  10. package/dist/cli/index.d.ts +1 -1
  11. package/dist/cli/index.js +9 -164
  12. package/dist/cli/loop/optionsSchema.d.ts +15 -0
  13. package/dist/cli/loop/optionsSchema.js +59 -0
  14. package/dist/cli/loop/session.d.ts +15 -0
  15. package/dist/cli/loop/session.js +252 -0
  16. package/dist/cli/parser.d.ts +1 -0
  17. package/dist/cli/parser.js +158 -0
  18. package/dist/cli/utils/ollamaUtils.js +6 -0
  19. package/dist/config/{conversationMemoryConfig.d.ts → conversationMemory.d.ts} +1 -1
  20. package/dist/core/baseProvider.js +43 -4
  21. package/dist/core/constants.d.ts +12 -3
  22. package/dist/core/constants.js +22 -6
  23. package/dist/core/conversationMemoryFactory.d.ts +23 -0
  24. package/dist/core/conversationMemoryFactory.js +144 -0
  25. package/dist/core/conversationMemoryInitializer.d.ts +14 -0
  26. package/dist/core/conversationMemoryInitializer.js +127 -0
  27. package/dist/core/conversationMemoryManager.d.ts +3 -2
  28. package/dist/core/conversationMemoryManager.js +4 -3
  29. package/dist/core/factory.js +19 -0
  30. package/dist/core/redisConversationMemoryManager.d.ts +73 -0
  31. package/dist/core/redisConversationMemoryManager.js +483 -0
  32. package/dist/core/types.d.ts +1 -1
  33. package/dist/factories/providerRegistry.js +2 -0
  34. package/dist/lib/config/{conversationMemoryConfig.d.ts → conversationMemory.d.ts} +1 -1
  35. package/dist/lib/core/baseProvider.js +43 -4
  36. package/dist/lib/core/constants.d.ts +12 -3
  37. package/dist/lib/core/constants.js +22 -6
  38. package/dist/lib/core/conversationMemoryFactory.d.ts +23 -0
  39. package/dist/lib/core/conversationMemoryFactory.js +144 -0
  40. package/dist/lib/core/conversationMemoryInitializer.d.ts +14 -0
  41. package/dist/lib/core/conversationMemoryInitializer.js +127 -0
  42. package/dist/lib/core/conversationMemoryManager.d.ts +3 -2
  43. package/dist/lib/core/conversationMemoryManager.js +4 -3
  44. package/dist/lib/core/factory.js +19 -0
  45. package/dist/lib/core/redisConversationMemoryManager.d.ts +73 -0
  46. package/dist/lib/core/redisConversationMemoryManager.js +483 -0
  47. package/dist/lib/core/types.d.ts +1 -1
  48. package/dist/lib/factories/providerRegistry.js +2 -0
  49. package/dist/lib/mcp/servers/aiProviders/aiWorkflowTools.js +2 -2
  50. package/dist/lib/neurolink.d.ts +15 -9
  51. package/dist/lib/neurolink.js +218 -67
  52. package/dist/lib/providers/amazonBedrock.d.ts +4 -4
  53. package/dist/lib/providers/amazonBedrock.js +2 -2
  54. package/dist/lib/providers/anthropic.d.ts +4 -4
  55. package/dist/lib/providers/anthropic.js +3 -12
  56. package/dist/lib/providers/anthropicBaseProvider.js +1 -2
  57. package/dist/lib/providers/azureOpenai.d.ts +4 -4
  58. package/dist/lib/providers/azureOpenai.js +49 -8
  59. package/dist/lib/providers/googleAiStudio.d.ts +4 -4
  60. package/dist/lib/providers/googleAiStudio.js +2 -2
  61. package/dist/lib/providers/googleVertex.js +2 -2
  62. package/dist/lib/providers/huggingFace.d.ts +4 -4
  63. package/dist/lib/providers/huggingFace.js +1 -2
  64. package/dist/lib/providers/litellm.d.ts +1 -1
  65. package/dist/lib/providers/litellm.js +1 -2
  66. package/dist/lib/providers/mistral.d.ts +4 -4
  67. package/dist/lib/providers/mistral.js +4 -4
  68. package/dist/lib/providers/ollama.js +7 -8
  69. package/dist/lib/providers/openAI.d.ts +4 -4
  70. package/dist/lib/providers/openAI.js +2 -2
  71. package/dist/lib/providers/openaiCompatible.js +5 -2
  72. package/dist/lib/providers/sagemaker/language-model.d.ts +5 -0
  73. package/dist/lib/providers/sagemaker/language-model.js +9 -1
  74. package/dist/lib/session/globalSessionState.d.ts +27 -0
  75. package/dist/lib/session/globalSessionState.js +77 -0
  76. package/dist/lib/types/{conversationTypes.d.ts → conversation.d.ts} +32 -0
  77. package/dist/lib/types/generateTypes.d.ts +1 -1
  78. package/dist/lib/types/streamTypes.d.ts +1 -1
  79. package/dist/lib/utils/conversationMemory.d.ts +22 -0
  80. package/dist/lib/utils/conversationMemory.js +121 -0
  81. package/dist/lib/utils/conversationMemoryUtils.d.ts +1 -1
  82. package/dist/lib/utils/conversationMemoryUtils.js +2 -2
  83. package/dist/lib/utils/messageBuilder.d.ts +1 -1
  84. package/dist/lib/utils/messageBuilder.js +1 -1
  85. package/dist/lib/utils/providerHealth.js +7 -3
  86. package/dist/lib/utils/redis.d.ts +42 -0
  87. package/dist/lib/utils/redis.js +263 -0
  88. package/dist/lib/utils/tokenLimits.d.ts +2 -2
  89. package/dist/lib/utils/tokenLimits.js +10 -3
  90. package/dist/mcp/servers/aiProviders/aiWorkflowTools.js +2 -2
  91. package/dist/neurolink.d.ts +15 -9
  92. package/dist/neurolink.js +218 -67
  93. package/dist/providers/amazonBedrock.d.ts +4 -4
  94. package/dist/providers/amazonBedrock.js +2 -2
  95. package/dist/providers/anthropic.d.ts +4 -4
  96. package/dist/providers/anthropic.js +3 -12
  97. package/dist/providers/anthropicBaseProvider.js +1 -2
  98. package/dist/providers/azureOpenai.d.ts +4 -4
  99. package/dist/providers/azureOpenai.js +49 -8
  100. package/dist/providers/googleAiStudio.d.ts +4 -4
  101. package/dist/providers/googleAiStudio.js +2 -2
  102. package/dist/providers/googleVertex.js +2 -2
  103. package/dist/providers/huggingFace.d.ts +4 -4
  104. package/dist/providers/huggingFace.js +1 -2
  105. package/dist/providers/litellm.d.ts +1 -1
  106. package/dist/providers/litellm.js +1 -2
  107. package/dist/providers/mistral.d.ts +4 -4
  108. package/dist/providers/mistral.js +4 -4
  109. package/dist/providers/ollama.js +7 -8
  110. package/dist/providers/openAI.d.ts +4 -4
  111. package/dist/providers/openAI.js +2 -2
  112. package/dist/providers/openaiCompatible.js +5 -2
  113. package/dist/providers/sagemaker/language-model.d.ts +5 -0
  114. package/dist/providers/sagemaker/language-model.js +9 -1
  115. package/dist/session/globalSessionState.d.ts +27 -0
  116. package/dist/session/globalSessionState.js +77 -0
  117. package/dist/types/{conversationTypes.d.ts → conversation.d.ts} +32 -0
  118. package/dist/types/generateTypes.d.ts +1 -1
  119. package/dist/types/streamTypes.d.ts +1 -1
  120. package/dist/utils/conversationMemory.d.ts +22 -0
  121. package/dist/utils/conversationMemory.js +121 -0
  122. package/dist/utils/conversationMemoryUtils.d.ts +1 -1
  123. package/dist/utils/conversationMemoryUtils.js +2 -2
  124. package/dist/utils/messageBuilder.d.ts +1 -1
  125. package/dist/utils/messageBuilder.js +1 -1
  126. package/dist/utils/providerHealth.js +7 -3
  127. package/dist/utils/redis.d.ts +42 -0
  128. package/dist/utils/redis.js +263 -0
  129. package/dist/utils/tokenLimits.d.ts +2 -2
  130. package/dist/utils/tokenLimits.js +10 -3
  131. package/package.json +3 -1
  132. /package/dist/config/{conversationMemoryConfig.js → conversationMemory.js} +0 -0
  133. /package/dist/lib/config/{conversationMemoryConfig.js → conversationMemory.js} +0 -0
  134. /package/dist/lib/types/{conversationTypes.js → conversation.js} +0 -0
  135. /package/dist/types/{conversationTypes.js → conversation.js} +0 -0
@@ -1,7 +1,9 @@
1
- import { NeuroLink } from "../../lib/neurolink.js";
1
+ import { globalSession } from "../../lib/session/globalSessionState.js";
2
2
  import { configManager } from "../commands/config.js";
3
- import { handleError } from "../index.js";
3
+ import { handleError } from "../errorHandler.js";
4
4
  import { normalizeEvaluationData } from "../../lib/utils/evaluationUtils.js";
5
+ import { LoopSession } from "../loop/session.js";
6
+ import { initializeCliParser } from "../parser.js";
5
7
  // Use TokenUsage from standard types - no local interface needed
6
8
  import { ContextFactory, } from "../../lib/types/contextTypes.js";
7
9
  import { ModelsCommandFactory } from "../commands/models.js";
@@ -189,8 +191,7 @@ export class CLICommandFactory {
189
191
  const truncatedJson = contextStr.length > 100
190
192
  ? `${contextStr.slice(0, 100)}...`
191
193
  : contextStr;
192
- logger.error(`Invalid JSON in --context parameter: ${err.message}. Received: ${truncatedJson}`);
193
- process.exit(1);
194
+ handleError(new Error(`Invalid JSON in --context parameter: ${err.message}. Received: ${truncatedJson}`), "Context parsing");
194
195
  }
195
196
  }
196
197
  else {
@@ -494,6 +495,39 @@ export class CLICommandFactory {
494
495
  static createDiscoverCommand() {
495
496
  return MCPCommandFactory.createDiscoverCommand();
496
497
  }
498
+ /**
499
+ * Create memory commands
500
+ */
501
+ static createMemoryCommands() {
502
+ return {
503
+ command: "memory <subcommand>",
504
+ describe: "Manage conversation memory",
505
+ builder: (yargs) => {
506
+ return yargs
507
+ .command("stats", "Show conversation memory statistics", (y) => this.buildOptions(y)
508
+ .example("$0 memory stats", "Show memory usage statistics")
509
+ .example("$0 memory stats --format json", "Export stats as JSON"), async (argv) => await this.executeMemoryStats(argv))
510
+ .command("history <sessionId>", "Show conversation history for a session", (y) => this.buildOptions(y)
511
+ .positional("sessionId", {
512
+ type: "string",
513
+ description: "Session ID to retrieve history for",
514
+ demandOption: true,
515
+ })
516
+ .example("$0 memory history session-123", "Show conversation history")
517
+ .example("$0 memory history session-123 --format json", "Export history as JSON"), async (argv) => await this.executeMemoryHistory(argv))
518
+ .command("clear [sessionId]", "Clear conversation history", (y) => this.buildOptions(y)
519
+ .positional("sessionId", {
520
+ type: "string",
521
+ description: "Session ID to clear (omit to clear all sessions)",
522
+ demandOption: false,
523
+ })
524
+ .example("$0 memory clear", "Clear all conversation history")
525
+ .example("$0 memory clear session-123", "Clear specific session"), async (argv) => await this.executeMemoryClear(argv))
526
+ .demandCommand(1, "Please specify a memory subcommand");
527
+ },
528
+ handler: () => { }, // No-op handler as subcommands handle everything
529
+ };
530
+ }
497
531
  /**
498
532
  * Create config commands
499
533
  */
@@ -515,9 +549,8 @@ export class CLICommandFactory {
515
549
  logger.always(chalk.green("✅ Configuration is valid"));
516
550
  }
517
551
  else {
518
- logger.always(chalk.red(" Configuration has errors:"));
519
- result.errors.forEach((error) => logger.always(` • ${error}`));
520
- process.exit(1);
552
+ const errorMessages = result.errors.join("\n • ");
553
+ handleError(new Error(`Configuration has errors:\n • ${errorMessages}`), "Configuration validation");
521
554
  }
522
555
  })
523
556
  .command("reset", "Reset configuration to defaults", (y) => this.buildOptions(y), async (_argv) => {
@@ -543,9 +576,8 @@ export class CLICommandFactory {
543
576
  logger.always(chalk.green("✅ Configuration is valid"));
544
577
  }
545
578
  else {
546
- logger.always(chalk.red(" Configuration has errors:"));
547
- result.errors.forEach((error) => logger.always(` • ${error}`));
548
- throw new Error("Configuration is invalid. See errors above.");
579
+ const errorMessages = result.errors.join("\n • ");
580
+ handleError(new Error(`Configuration has errors:\n • ${errorMessages}`), "Configuration validation");
549
581
  }
550
582
  },
551
583
  };
@@ -576,6 +608,53 @@ export class CLICommandFactory {
576
608
  static createSageMakerCommands() {
577
609
  return SageMakerCommandFactory.createSageMakerCommands();
578
610
  }
611
+ /**
612
+ * Create completion command
613
+ */
614
+ /**
615
+ * Create loop command
616
+ */
617
+ static createLoopCommand() {
618
+ return {
619
+ command: "loop",
620
+ describe: "Start an interactive loop session",
621
+ builder: (yargs) => yargs
622
+ .option("enable-conversation-memory", {
623
+ type: "boolean",
624
+ description: "Enable conversation memory for the loop session",
625
+ default: false,
626
+ })
627
+ .option("max-sessions", {
628
+ type: "number",
629
+ description: "Maximum number of conversation sessions to keep",
630
+ default: 50,
631
+ })
632
+ .option("max-turns-per-session", {
633
+ type: "number",
634
+ description: "Maximum turns per conversation session",
635
+ default: 20,
636
+ })
637
+ .example("$0 loop", "Start interactive session")
638
+ .example("$0 loop --enable-conversation-memory", "Start loop with memory"),
639
+ handler: async (argv) => {
640
+ if (globalSession.getCurrentSessionId()) {
641
+ logger.error("A loop session is already active. Cannot start a new one.");
642
+ return;
643
+ }
644
+ let conversationMemoryConfig;
645
+ const { enableConversationMemory, maxSessions, maxTurnsPerSession } = argv;
646
+ if (enableConversationMemory) {
647
+ conversationMemoryConfig = {
648
+ enabled: true,
649
+ maxSessions: maxSessions,
650
+ maxTurnsPerSession: maxTurnsPerSession,
651
+ };
652
+ }
653
+ const session = new LoopSession(initializeCliParser, conversationMemoryConfig);
654
+ await session.start();
655
+ },
656
+ };
657
+ }
579
658
  /**
580
659
  * Create completion command
581
660
  */
@@ -601,6 +680,7 @@ export class CLICommandFactory {
601
680
  const spinner = argv.quiet
602
681
  ? null
603
682
  : ora("🔍 Checking AI provider status...\n").start();
683
+ const sdk = globalSession.getOrCreateNeuroLink();
604
684
  try {
605
685
  // Handle dry-run mode for provider status
606
686
  if (argv.dryRun) {
@@ -652,7 +732,6 @@ export class CLICommandFactory {
652
732
  return;
653
733
  }
654
734
  // Use SDK's provider diagnostic method instead of manual testing
655
- const sdk = new NeuroLink();
656
735
  const results = await sdk.getProviderStatus({ quiet: !!argv.quiet });
657
736
  if (spinner) {
658
737
  const working = results.filter((r) => r.status === "working").length;
@@ -682,8 +761,19 @@ export class CLICommandFactory {
682
761
  if (spinner) {
683
762
  spinner.fail("Provider status check failed");
684
763
  }
685
- logger.error(chalk.red("Error checking provider status:"), error);
686
- process.exit(1);
764
+ handleError(error, "Provider status check");
765
+ }
766
+ finally {
767
+ // Ensure all background processes are terminated
768
+ try {
769
+ await sdk.shutdownExternalMCPServers();
770
+ }
771
+ catch (shutdownError) {
772
+ logger.error("Error during SDK shutdown:", shutdownError);
773
+ }
774
+ if (!globalSession.getCurrentSessionId()) {
775
+ process.exit();
776
+ }
687
777
  }
688
778
  }
689
779
  /**
@@ -779,9 +869,17 @@ export class CLICommandFactory {
779
869
  logger.debug("Model:", mockResult.model);
780
870
  logger.debug("Mode: DRY-RUN (no actual API calls made)");
781
871
  }
782
- process.exit(0);
872
+ if (!globalSession.getCurrentSessionId()) {
873
+ process.exit(0);
874
+ }
783
875
  }
784
- const sdk = new NeuroLink();
876
+ const sdk = globalSession.getOrCreateNeuroLink();
877
+ const sessionVariables = globalSession.getSessionVariables();
878
+ const enhancedOptions = { ...options, ...sessionVariables };
879
+ const sessionId = globalSession.getCurrentSessionId();
880
+ const context = sessionId
881
+ ? { ...options.context, sessionId }
882
+ : options.context;
785
883
  if (options.debug) {
786
884
  logger.debug("CLI Tools configuration:", {
787
885
  disableTools: options.disableTools,
@@ -790,21 +888,21 @@ export class CLICommandFactory {
790
888
  }
791
889
  const result = await sdk.generate({
792
890
  input: { text: inputText },
793
- provider: options.provider,
794
- model: options.model,
795
- temperature: options.temperature,
796
- maxTokens: options.maxTokens,
797
- systemPrompt: options.systemPrompt,
798
- timeout: options.timeout,
799
- disableTools: options.disableTools,
800
- enableAnalytics: options.enableAnalytics,
801
- enableEvaluation: options.enableEvaluation,
802
- evaluationDomain: options.evaluationDomain,
803
- toolUsageContext: options.toolUsageContext,
804
- context: contextMetadata,
805
- factoryConfig: options.domain
891
+ provider: enhancedOptions.provider,
892
+ model: enhancedOptions.model,
893
+ temperature: enhancedOptions.temperature,
894
+ maxTokens: enhancedOptions.maxTokens,
895
+ systemPrompt: enhancedOptions.systemPrompt,
896
+ timeout: enhancedOptions.timeout,
897
+ disableTools: enhancedOptions.disableTools,
898
+ enableAnalytics: enhancedOptions.enableAnalytics,
899
+ enableEvaluation: enhancedOptions.enableEvaluation,
900
+ evaluationDomain: enhancedOptions.evaluationDomain,
901
+ toolUsageContext: enhancedOptions.toolUsageContext,
902
+ context: context,
903
+ factoryConfig: enhancedOptions.domain
806
904
  ? {
807
- domainType: options.domain,
905
+ domainType: enhancedOptions.domain,
808
906
  enhancementType: "domain-configuration",
809
907
  validateDomainData: true,
810
908
  }
@@ -813,6 +911,12 @@ export class CLICommandFactory {
813
911
  if (spinner) {
814
912
  spinner.succeed(chalk.green("✅ Text generated successfully!"));
815
913
  }
914
+ // Display provider and model info by default (unless quiet mode)
915
+ if (!options.quiet) {
916
+ const providerInfo = result.provider || "auto";
917
+ const modelInfo = result.model || "default";
918
+ logger.always(chalk.gray(`🔧 Provider: ${providerInfo} | Model: ${modelInfo}`));
919
+ }
816
920
  // Handle output with universal formatting
817
921
  this.handleOutput(result, options);
818
922
  if (options.debug) {
@@ -826,7 +930,9 @@ export class CLICommandFactory {
826
930
  logger.debug("Evaluation:", JSON.stringify(result.evaluation, null, 2));
827
931
  }
828
932
  }
829
- process.exit(0);
933
+ if (!globalSession.getCurrentSessionId()) {
934
+ process.exit(0);
935
+ }
830
936
  }
831
937
  catch (error) {
832
938
  if (spinner) {
@@ -981,24 +1087,34 @@ export class CLICommandFactory {
981
1087
  logger.debug("Model:", options.model || "test-model");
982
1088
  logger.debug("Mode: DRY-RUN (no actual API calls made)");
983
1089
  }
984
- process.exit(0);
1090
+ if (!globalSession.getCurrentSessionId()) {
1091
+ process.exit(0);
1092
+ }
985
1093
  }
986
- const sdk = new NeuroLink();
1094
+ const sdk = globalSession.getOrCreateNeuroLink();
1095
+ const sessionVariables = globalSession.getSessionVariables();
1096
+ const enhancedOptions = { ...options, ...sessionVariables };
1097
+ const sessionId = globalSession.getCurrentSessionId();
1098
+ const context = sessionId
1099
+ ? { ...contextMetadata, sessionId }
1100
+ : contextMetadata;
987
1101
  const stream = await sdk.stream({
988
1102
  input: { text: inputText },
989
- provider: options.provider,
990
- model: options.model,
991
- temperature: options.temperature,
992
- maxTokens: options.maxTokens,
993
- systemPrompt: options.systemPrompt,
994
- timeout: options.timeout,
995
- disableTools: options.disableTools,
996
- enableAnalytics: options.enableAnalytics,
997
- enableEvaluation: options.enableEvaluation,
998
- context: contextMetadata,
999
- factoryConfig: options.domain
1103
+ provider: enhancedOptions.provider,
1104
+ model: enhancedOptions.model,
1105
+ temperature: enhancedOptions.temperature,
1106
+ maxTokens: enhancedOptions.maxTokens,
1107
+ systemPrompt: enhancedOptions.systemPrompt,
1108
+ timeout: enhancedOptions.timeout,
1109
+ disableTools: enhancedOptions.disableTools,
1110
+ enableAnalytics: enhancedOptions.enableAnalytics,
1111
+ enableEvaluation: enhancedOptions.enableEvaluation,
1112
+ evaluationDomain: enhancedOptions.evaluationDomain,
1113
+ toolUsageContext: enhancedOptions.toolUsageContext,
1114
+ context: context,
1115
+ factoryConfig: enhancedOptions.domain
1000
1116
  ? {
1001
- domainType: options.domain,
1117
+ domainType: enhancedOptions.domain,
1002
1118
  enhancementType: "domain-configuration",
1003
1119
  validateDomainData: true,
1004
1120
  }
@@ -1123,7 +1239,9 @@ export class CLICommandFactory {
1123
1239
  if (options.debug) {
1124
1240
  await this.logStreamDebugInfo(stream);
1125
1241
  }
1126
- process.exit(0);
1242
+ if (!globalSession.getCurrentSessionId()) {
1243
+ process.exit(0);
1244
+ }
1127
1245
  }
1128
1246
  catch (error) {
1129
1247
  handleError(error, "Streaming");
@@ -1158,7 +1276,10 @@ export class CLICommandFactory {
1158
1276
  logger.always(chalk.blue(`📦 Processing ${prompts.length} prompts...\n`));
1159
1277
  }
1160
1278
  const results = [];
1161
- const sdk = new NeuroLink();
1279
+ const sdk = globalSession.getOrCreateNeuroLink();
1280
+ const sessionVariables = globalSession.getSessionVariables();
1281
+ const enhancedOptions = { ...options, ...sessionVariables };
1282
+ const sessionId = globalSession.getCurrentSessionId();
1162
1283
  for (let i = 0; i < prompts.length; i++) {
1163
1284
  if (spinner) {
1164
1285
  spinner.text = `Processing ${i + 1}/${prompts.length}: ${prompts[i].substring(0, 30)}...`;
@@ -1190,21 +1311,24 @@ export class CLICommandFactory {
1190
1311
  batchIndex: i,
1191
1312
  };
1192
1313
  }
1314
+ const context = sessionId
1315
+ ? { ...contextMetadata, sessionId }
1316
+ : contextMetadata;
1193
1317
  const result = await sdk.generate({
1194
1318
  input: { text: inputText },
1195
- provider: options.provider,
1196
- model: options.model,
1197
- temperature: options.temperature,
1198
- maxTokens: options.maxTokens,
1199
- systemPrompt: options.systemPrompt,
1200
- timeout: options.timeout,
1201
- disableTools: options.disableTools,
1202
- enableAnalytics: options.enableAnalytics,
1203
- enableEvaluation: options.enableEvaluation,
1204
- context: contextMetadata,
1205
- factoryConfig: options.domain
1319
+ provider: enhancedOptions.provider,
1320
+ model: enhancedOptions.model,
1321
+ temperature: enhancedOptions.temperature,
1322
+ maxTokens: enhancedOptions.maxTokens,
1323
+ systemPrompt: enhancedOptions.systemPrompt,
1324
+ timeout: enhancedOptions.timeout,
1325
+ disableTools: enhancedOptions.disableTools,
1326
+ evaluationDomain: enhancedOptions.evaluationDomain,
1327
+ toolUsageContext: enhancedOptions.toolUsageContext,
1328
+ context: context,
1329
+ factoryConfig: enhancedOptions.domain
1206
1330
  ? {
1207
- domainType: options.domain,
1331
+ domainType: enhancedOptions.domain,
1208
1332
  enhancementType: "domain-configuration",
1209
1333
  validateDomainData: true,
1210
1334
  }
@@ -1234,7 +1358,9 @@ export class CLICommandFactory {
1234
1358
  }
1235
1359
  // Handle output with universal formatting
1236
1360
  this.handleOutput(results, options);
1237
- process.exit(0);
1361
+ if (!globalSession.getCurrentSessionId()) {
1362
+ process.exit(0);
1363
+ }
1238
1364
  }
1239
1365
  catch (error) {
1240
1366
  if (spinner) {
@@ -1296,6 +1422,189 @@ export class CLICommandFactory {
1296
1422
  handleError(error, "Provider selection");
1297
1423
  }
1298
1424
  }
1425
+ /**
1426
+ * Execute memory stats command
1427
+ */
1428
+ static async executeMemoryStats(argv) {
1429
+ const options = this.processOptions(argv);
1430
+ const spinner = options.quiet
1431
+ ? null
1432
+ : ora("🧠 Getting memory stats...").start();
1433
+ try {
1434
+ const sdk = globalSession.getOrCreateNeuroLink();
1435
+ // Handle dry-run mode
1436
+ if (options.dryRun) {
1437
+ const mockStats = {
1438
+ totalSessions: 5,
1439
+ totalTurns: 47,
1440
+ memoryUsage: "Active",
1441
+ };
1442
+ if (spinner) {
1443
+ spinner.succeed(chalk.green("✅ Memory stats retrieved (dry-run)"));
1444
+ }
1445
+ this.handleOutput(mockStats, options);
1446
+ return;
1447
+ }
1448
+ const stats = await sdk.getConversationStats();
1449
+ if (spinner) {
1450
+ spinner.succeed(chalk.green("✅ Memory stats retrieved"));
1451
+ }
1452
+ if (options.format === "json") {
1453
+ this.handleOutput(stats, options);
1454
+ }
1455
+ else {
1456
+ logger.always(chalk.blue("📊 Conversation Memory Stats:"));
1457
+ logger.always(` Total Sessions: ${stats.totalSessions}`);
1458
+ logger.always(` Total Turns: ${stats.totalTurns}`);
1459
+ logger.always(` Memory Status: ${stats.totalSessions > 0 ? "Active" : "Empty"}`);
1460
+ }
1461
+ }
1462
+ catch (error) {
1463
+ if (spinner) {
1464
+ spinner.fail("Memory stats failed");
1465
+ }
1466
+ if (error.message.includes("not enabled")) {
1467
+ logger.always(chalk.yellow("⚠️ Conversation memory is not enabled"));
1468
+ logger.always("Enable it by using --enable-conversation-memory with loop mode");
1469
+ }
1470
+ else {
1471
+ handleError(error, "Memory stats");
1472
+ }
1473
+ }
1474
+ }
1475
+ /**
1476
+ * Execute memory history command
1477
+ */
1478
+ static async executeMemoryHistory(argv) {
1479
+ const options = this.processOptions(argv);
1480
+ const spinner = options.quiet
1481
+ ? null
1482
+ : ora(`🧠 Getting history for ${argv.sessionId}...`).start();
1483
+ try {
1484
+ const sdk = globalSession.getOrCreateNeuroLink();
1485
+ // Handle dry-run mode
1486
+ if (options.dryRun) {
1487
+ const mockHistory = [
1488
+ { role: "user", content: "Hello, how are you?" },
1489
+ {
1490
+ role: "assistant",
1491
+ content: "I'm doing well, thank you! How can I help you today?",
1492
+ },
1493
+ { role: "user", content: "Can you explain quantum computing?" },
1494
+ {
1495
+ role: "assistant",
1496
+ content: "Quantum computing is a revolutionary technology...",
1497
+ },
1498
+ ];
1499
+ if (spinner) {
1500
+ spinner.succeed(chalk.green(`✅ History retrieved for ${argv.sessionId} (dry-run)`));
1501
+ }
1502
+ this.handleOutput(mockHistory, options);
1503
+ return;
1504
+ }
1505
+ const history = await sdk.getConversationHistory(argv.sessionId);
1506
+ if (spinner) {
1507
+ spinner.succeed(chalk.green(`✅ History retrieved for ${argv.sessionId}`));
1508
+ }
1509
+ if (history.length === 0) {
1510
+ logger.always(chalk.yellow(`⚠️ No conversation history found for session: ${argv.sessionId}`));
1511
+ return;
1512
+ }
1513
+ if (options.format === "json") {
1514
+ this.handleOutput(history, options);
1515
+ }
1516
+ else {
1517
+ logger.always(chalk.blue(`💬 Conversation History (${argv.sessionId}):`));
1518
+ for (const message of history) {
1519
+ const roleColor = message.role === "user" ? chalk.cyan : chalk.green;
1520
+ const roleLabel = message.role === "user" ? "User" : "Assistant";
1521
+ logger.always(` [${roleColor(roleLabel)}]: ${message.content}`);
1522
+ }
1523
+ }
1524
+ }
1525
+ catch (error) {
1526
+ if (spinner) {
1527
+ spinner.fail("Memory history failed");
1528
+ }
1529
+ if (error.message.includes("not enabled")) {
1530
+ logger.always(chalk.yellow("⚠️ Conversation memory is not enabled"));
1531
+ logger.always("Enable it by using --enable-conversation-memory with loop mode");
1532
+ }
1533
+ else {
1534
+ handleError(error, "Memory history");
1535
+ }
1536
+ }
1537
+ }
1538
+ /**
1539
+ * Execute memory clear command
1540
+ */
1541
+ static async executeMemoryClear(argv) {
1542
+ const options = this.processOptions(argv);
1543
+ const isAllSessions = !argv.sessionId;
1544
+ const target = isAllSessions ? "all sessions" : `session ${argv.sessionId}`;
1545
+ const spinner = options.quiet
1546
+ ? null
1547
+ : ora(`🧠 Clearing ${target}...`).start();
1548
+ try {
1549
+ const sdk = globalSession.getOrCreateNeuroLink();
1550
+ // Handle dry-run mode
1551
+ if (options.dryRun) {
1552
+ if (spinner) {
1553
+ spinner.succeed(chalk.green(`✅ ${isAllSessions ? "All sessions" : "Session"} cleared (dry-run)`));
1554
+ }
1555
+ const result = {
1556
+ success: true,
1557
+ action: isAllSessions ? "clear_all" : "clear_session",
1558
+ sessionId: argv.sessionId || null,
1559
+ message: `${isAllSessions ? "All sessions" : "Session"} would be cleared`,
1560
+ };
1561
+ this.handleOutput(result, options);
1562
+ return;
1563
+ }
1564
+ let success;
1565
+ if (isAllSessions) {
1566
+ await sdk.clearAllConversations();
1567
+ success = true;
1568
+ }
1569
+ else {
1570
+ success = await sdk.clearConversationSession(argv.sessionId);
1571
+ }
1572
+ if (spinner) {
1573
+ if (success) {
1574
+ spinner.succeed(chalk.green(`✅ ${isAllSessions ? "All sessions" : "Session"} cleared successfully`));
1575
+ }
1576
+ else {
1577
+ spinner.warn(chalk.yellow(`⚠️ Session ${argv.sessionId} not found or already empty`));
1578
+ }
1579
+ }
1580
+ if (options.format === "json") {
1581
+ const result = {
1582
+ success,
1583
+ action: isAllSessions ? "clear_all" : "clear_session",
1584
+ sessionId: argv.sessionId || null,
1585
+ };
1586
+ this.handleOutput(result, options);
1587
+ }
1588
+ else if (!success && !isAllSessions) {
1589
+ logger.always(chalk.yellow(`⚠️ Session ${argv.sessionId} not found or already empty`));
1590
+ }
1591
+ else if (!options.quiet) {
1592
+ logger.always(chalk.green(`✅ ${isAllSessions ? "All conversation history" : `Session ${argv.sessionId}`} cleared`));
1593
+ }
1594
+ }
1595
+ catch (error) {
1596
+ if (spinner) {
1597
+ spinner.fail("Memory clear failed");
1598
+ }
1599
+ if (error.message.includes("not enabled")) {
1600
+ logger.always(chalk.yellow("⚠️ Conversation memory is not enabled"));
1601
+ logger.always("Enable it by using --enable-conversation-memory with loop mode");
1602
+ }
1603
+ else {
1604
+ handleError(error, "Memory clear");
1605
+ }
1606
+ }
1607
+ }
1299
1608
  /**
1300
1609
  * Execute completion command
1301
1610
  */
@@ -1317,7 +1626,7 @@ export class CLICommandFactory {
1317
1626
  ' prev="${COMP_WORDS[COMP_CWORD - 1]}"\n\n' +
1318
1627
  " # Main commands\n" +
1319
1628
  " if [[ ${COMP_CWORD} -eq 1 ]]; then\n" +
1320
- ' opts="generate gen stream batch provider status models mcp discover config get-best-provider completion"\n' +
1629
+ ' opts="generate gen stream batch provider status models mcp discover memory config get-best-provider completion"\n' +
1321
1630
  ' COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )\n' +
1322
1631
  " return 0\n" +
1323
1632
  " fi\n\n" +
@@ -1379,6 +1688,12 @@ export class CLICommandFactory {
1379
1688
  " return 0\n" +
1380
1689
  " fi\n" +
1381
1690
  " ;;\n" +
1691
+ " memory)\n" +
1692
+ " if [[ ${COMP_CWORD} -eq 2 ]]; then\n" +
1693
+ ' COMPREPLY=( $(compgen -W "stats history clear" -- ${cur}) )\n' +
1694
+ " return 0\n" +
1695
+ " fi\n" +
1696
+ " ;;\n" +
1382
1697
  " *)\n" +
1383
1698
  " # Global options for all commands\n" +
1384
1699
  ' opts="--help --version --debug --quiet --noColor --configFile"\n' +
@@ -196,7 +196,13 @@ export class OllamaCommandFactory {
196
196
  * Handler for starting Ollama service
197
197
  */
198
198
  static async startHandler() {
199
- await OllamaUtils.startOllamaService();
199
+ try {
200
+ await OllamaUtils.startOllamaService();
201
+ }
202
+ catch (error) {
203
+ logger.error("Failed to start Ollama service:", error);
204
+ throw error;
205
+ }
200
206
  }
201
207
  /**
202
208
  * Handler for stopping Ollama service
@@ -5,4 +5,4 @@
5
5
  * Professional CLI experience with minimal maintenance overhead.
6
6
  * Features: Spinners, colors, batch processing, provider testing, rich help
7
7
  */
8
- export declare function handleError(_error: Error, context: string): void;
8
+ export {};