@juspay/neurolink 7.14.2 → 7.14.4

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 (99) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cli/commands/config.d.ts +66 -66
  3. package/dist/core/baseProvider.d.ts +12 -7
  4. package/dist/core/baseProvider.js +118 -125
  5. package/dist/core/constants.d.ts +5 -0
  6. package/dist/core/constants.js +6 -0
  7. package/dist/core/dynamicModels.d.ts +4 -4
  8. package/dist/core/factory.d.ts +2 -4
  9. package/dist/core/types.d.ts +8 -22
  10. package/dist/index.d.ts +1 -4
  11. package/dist/lib/core/baseProvider.d.ts +12 -7
  12. package/dist/lib/core/baseProvider.js +118 -125
  13. package/dist/lib/core/constants.d.ts +5 -0
  14. package/dist/lib/core/constants.js +6 -0
  15. package/dist/lib/core/dynamicModels.d.ts +8 -8
  16. package/dist/lib/core/factory.d.ts +2 -4
  17. package/dist/lib/core/types.d.ts +8 -22
  18. package/dist/lib/index.d.ts +1 -4
  19. package/dist/lib/mcp/contracts/mcpContract.d.ts +6 -19
  20. package/dist/lib/mcp/externalServerManager.d.ts +2 -4
  21. package/dist/lib/mcp/externalServerManager.js +7 -8
  22. package/dist/lib/mcp/factory.d.ts +61 -7
  23. package/dist/lib/mcp/factory.js +36 -23
  24. package/dist/lib/mcp/mcpClientFactory.d.ts +2 -1
  25. package/dist/lib/mcp/mcpClientFactory.js +73 -26
  26. package/dist/lib/mcp/registry.d.ts +1 -1
  27. package/dist/lib/mcp/toolDiscoveryService.d.ts +1 -1
  28. package/dist/lib/mcp/toolDiscoveryService.js +50 -19
  29. package/dist/lib/mcp/toolRegistry.d.ts +23 -1
  30. package/dist/lib/mcp/toolRegistry.js +108 -17
  31. package/dist/lib/models/modelResolver.js +2 -1
  32. package/dist/lib/neurolink.d.ts +12 -8
  33. package/dist/lib/neurolink.js +130 -134
  34. package/dist/lib/providers/amazonBedrock.d.ts +2 -2
  35. package/dist/lib/providers/anthropic.d.ts +3 -3
  36. package/dist/lib/providers/googleAiStudio.d.ts +2 -2
  37. package/dist/lib/providers/mistral.d.ts +3 -3
  38. package/dist/lib/providers/ollama.d.ts +2 -2
  39. package/dist/lib/providers/openAI.d.ts +3 -3
  40. package/dist/lib/providers/openaiCompatible.d.ts +2 -2
  41. package/dist/lib/providers/sagemaker/client.d.ts +2 -5
  42. package/dist/lib/providers/sagemaker/language-model.d.ts +4 -6
  43. package/dist/lib/providers/sagemaker/parsers.js +5 -4
  44. package/dist/lib/sdk/toolRegistration.d.ts +6 -6
  45. package/dist/lib/sdk/toolRegistration.js +17 -56
  46. package/dist/lib/types/generateTypes.d.ts +9 -9
  47. package/dist/lib/types/streamTypes.d.ts +4 -4
  48. package/dist/lib/types/tools.d.ts +15 -7
  49. package/dist/lib/types/typeAliases.d.ts +412 -0
  50. package/dist/lib/types/typeAliases.js +48 -0
  51. package/dist/lib/utils/factoryProcessing.d.ts +2 -1
  52. package/dist/lib/utils/factoryProcessing.js +4 -3
  53. package/dist/lib/utils/parameterValidation.d.ts +97 -0
  54. package/dist/lib/utils/parameterValidation.js +452 -0
  55. package/dist/lib/utils/transformationUtils.d.ts +204 -0
  56. package/dist/lib/utils/transformationUtils.js +334 -0
  57. package/dist/lib/utils/typeUtils.d.ts +77 -0
  58. package/dist/lib/utils/typeUtils.js +97 -0
  59. package/dist/mcp/contracts/mcpContract.d.ts +6 -19
  60. package/dist/mcp/externalServerManager.d.ts +2 -4
  61. package/dist/mcp/externalServerManager.js +7 -8
  62. package/dist/mcp/factory.d.ts +61 -7
  63. package/dist/mcp/factory.js +36 -23
  64. package/dist/mcp/mcpClientFactory.d.ts +2 -1
  65. package/dist/mcp/mcpClientFactory.js +73 -26
  66. package/dist/mcp/registry.d.ts +1 -1
  67. package/dist/mcp/toolDiscoveryService.d.ts +1 -1
  68. package/dist/mcp/toolDiscoveryService.js +50 -19
  69. package/dist/mcp/toolRegistry.d.ts +23 -1
  70. package/dist/mcp/toolRegistry.js +108 -17
  71. package/dist/models/modelResolver.js +2 -1
  72. package/dist/neurolink.d.ts +12 -8
  73. package/dist/neurolink.js +130 -134
  74. package/dist/providers/amazonBedrock.d.ts +2 -2
  75. package/dist/providers/anthropic.d.ts +3 -3
  76. package/dist/providers/googleAiStudio.d.ts +2 -2
  77. package/dist/providers/mistral.d.ts +3 -3
  78. package/dist/providers/ollama.d.ts +2 -2
  79. package/dist/providers/openAI.d.ts +3 -3
  80. package/dist/providers/openaiCompatible.d.ts +2 -2
  81. package/dist/providers/sagemaker/client.d.ts +2 -5
  82. package/dist/providers/sagemaker/language-model.d.ts +4 -6
  83. package/dist/providers/sagemaker/parsers.js +5 -4
  84. package/dist/sdk/toolRegistration.d.ts +6 -6
  85. package/dist/sdk/toolRegistration.js +17 -56
  86. package/dist/types/generateTypes.d.ts +9 -9
  87. package/dist/types/streamTypes.d.ts +4 -4
  88. package/dist/types/tools.d.ts +15 -7
  89. package/dist/types/typeAliases.d.ts +412 -0
  90. package/dist/types/typeAliases.js +48 -0
  91. package/dist/utils/factoryProcessing.d.ts +2 -1
  92. package/dist/utils/factoryProcessing.js +4 -3
  93. package/dist/utils/parameterValidation.d.ts +97 -0
  94. package/dist/utils/parameterValidation.js +452 -0
  95. package/dist/utils/transformationUtils.d.ts +204 -0
  96. package/dist/utils/transformationUtils.js +334 -0
  97. package/dist/utils/typeUtils.d.ts +77 -0
  98. package/dist/utils/typeUtils.js +97 -0
  99. package/package.json +1 -1
@@ -1,11 +1,13 @@
1
1
  import { z } from "zod";
2
2
  import { logger } from "../utils/logger.js";
3
- import { SYSTEM_LIMITS, DEFAULT_MAX_STEPS } from "../core/constants.js";
3
+ import { DEFAULT_MAX_STEPS, STEP_LIMITS } from "../core/constants.js";
4
4
  import { directAgentTools } from "../agent/directTools.js";
5
5
  import { getSafeMaxTokens } from "../utils/tokenLimits.js";
6
6
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
7
7
  import { shouldDisableBuiltinTools } from "../utils/toolUtils.js";
8
8
  import { buildMessagesArray } from "../utils/messageBuilder.js";
9
+ import { getKeysAsString, getKeyCount } from "../utils/transformationUtils.js";
10
+ import { validateStreamOptions as validateStreamOpts, validateTextGenerationOptions, ValidationError, createValidationSummary, } from "../utils/parameterValidation.js";
9
11
  /**
10
12
  * Abstract base class for all AI providers
11
13
  * Tools are integrated as first-class citizens - always available by default
@@ -141,8 +143,10 @@ export class BaseProvider {
141
143
  * Text generation method - implements AIProvider interface
142
144
  * Tools are always available unless explicitly disabled
143
145
  */
144
- async generate(optionsOrPrompt, analysisSchema) {
146
+ async generate(optionsOrPrompt, _analysisSchema) {
145
147
  const options = this.normalizeTextOptions(optionsOrPrompt);
148
+ // Validate options before proceeding
149
+ this.validateOptions(options);
146
150
  const startTime = Date.now();
147
151
  try {
148
152
  // Import generateText dynamically to avoid circular dependencies
@@ -157,9 +161,12 @@ export class BaseProvider {
157
161
  }
158
162
  : {};
159
163
  logger.debug(`[BaseProvider.generate] Tools for ${this.providerName}:`, {
160
- directTools: Object.keys(baseTools),
161
- externalTools: Object.keys(options.tools || {}),
162
- totalTools: Object.keys(tools),
164
+ directTools: getKeyCount(baseTools),
165
+ directToolNames: getKeysAsString(baseTools),
166
+ externalTools: getKeyCount(options.tools || {}),
167
+ externalToolNames: getKeysAsString(options.tools || {}),
168
+ totalTools: getKeyCount(tools),
169
+ totalToolNames: getKeysAsString(tools),
163
170
  });
164
171
  // EVERY provider uses Vercel AI SDK - no exceptions
165
172
  const model = await this.getAISDKModel(); // This method is now REQUIRED
@@ -292,12 +299,15 @@ export class BaseProvider {
292
299
  toolResults: result.toolResults,
293
300
  toolsUsed: uniqueToolsUsed,
294
301
  toolExecutions, // ✅ Add extracted tool executions
295
- availableTools: Object.keys(tools).map((name) => ({
296
- name,
297
- description: tools[name].description || "No description available",
298
- parameters: tools[name].parameters || {},
299
- server: tools[name].serverId || "direct",
300
- })),
302
+ availableTools: Object.keys(tools).map((name) => {
303
+ const tool = tools[name];
304
+ return {
305
+ name,
306
+ description: tool.description || "No description available",
307
+ parameters: tool.parameters || {},
308
+ server: tool.serverId || "direct",
309
+ };
310
+ }),
301
311
  };
302
312
  // Enhanced result with analytics and evaluation
303
313
  return await this.enhanceResult(enhancedResult, options, startTime);
@@ -313,6 +323,40 @@ export class BaseProvider {
313
323
  async gen(optionsOrPrompt, analysisSchema) {
314
324
  return this.generate(optionsOrPrompt, analysisSchema);
315
325
  }
326
+ /**
327
+ * BACKWARD COMPATIBILITY: Legacy generateText method
328
+ * Converts EnhancedGenerateResult to TextGenerationResult format
329
+ * Ensures existing scripts using createAIProvider().generateText() continue to work
330
+ */
331
+ async generateText(options) {
332
+ // Validate required parameters for backward compatibility
333
+ if (!options.prompt ||
334
+ typeof options.prompt !== "string" ||
335
+ options.prompt.trim() === "") {
336
+ throw new Error("GenerateText options must include prompt as a non-empty string");
337
+ }
338
+ // Call the main generate method
339
+ const result = await this.generate(options);
340
+ if (!result) {
341
+ throw new Error("Generation failed: No result returned");
342
+ }
343
+ // Convert EnhancedGenerateResult to TextGenerationResult format
344
+ return {
345
+ content: result.content || "",
346
+ provider: result.provider || this.providerName,
347
+ model: result.model || this.modelName,
348
+ usage: result.usage || {
349
+ promptTokens: 0,
350
+ completionTokens: 0,
351
+ totalTokens: 0,
352
+ },
353
+ responseTime: 0, // BaseProvider doesn't track response time directly
354
+ toolsUsed: result.toolsUsed || [],
355
+ enhancedWithTools: !!(result.toolsUsed && result.toolsUsed.length > 0),
356
+ analytics: result.analytics,
357
+ evaluation: result.evaluation,
358
+ };
359
+ }
316
360
  // ===================
317
361
  // TOOL MANAGEMENT
318
362
  // ===================
@@ -327,9 +371,9 @@ export class BaseProvider {
327
371
  logger.debug(`[BaseProvider] getAllTools called for ${this.providerName}`, {
328
372
  neurolinkAvailable: !!this.neurolink,
329
373
  neurolinkType: typeof this.neurolink,
330
- directToolsCount: Object.keys(this.directTools).length,
374
+ directToolsCount: getKeyCount(this.directTools),
331
375
  });
332
- logger.debug(`[BaseProvider] Direct tools: ${Object.keys(this.directTools).join(", ")}`);
376
+ logger.debug(`[BaseProvider] Direct tools: ${getKeysAsString(this.directTools)}`);
333
377
  // Add custom tools from setupToolExecutor if available
334
378
  if (this.customTools && this.customTools.size > 0) {
335
379
  logger.debug(`[BaseProvider] Loading ${this.customTools.size} custom tools from setupToolExecutor`);
@@ -349,14 +393,14 @@ export class BaseProvider {
349
393
  tools[toolName] = createAISDKTool({
350
394
  description: typedToolDef.description || `Custom tool ${toolName}`,
351
395
  parameters: z.object({}), // Use empty schema for custom tools
352
- execute: async (args) => {
353
- logger.debug(`[BaseProvider] Executing custom tool: ${toolName}`, { args });
396
+ execute: async (params) => {
397
+ logger.debug(`[BaseProvider] Executing custom tool: ${toolName}`, { params });
354
398
  // Use the tool executor if available (from setupToolExecutor)
355
399
  if (this.toolExecutor) {
356
- return await this.toolExecutor(toolName, args);
400
+ return await this.toolExecutor(toolName, params);
357
401
  }
358
402
  else {
359
- return await typedToolDef.execute(args);
403
+ return await typedToolDef.execute(params);
360
404
  }
361
405
  },
362
406
  });
@@ -388,7 +432,7 @@ export class BaseProvider {
388
432
  logger.debug(`[BaseProvider] Loading custom tools from SDK, found ${inMemoryServers.size} servers`);
389
433
  if (inMemoryServers && inMemoryServers.size > 0) {
390
434
  // Convert in-memory server tools to AI SDK format
391
- for (const [serverId, serverConfig] of inMemoryServers) {
435
+ for (const [_serverId, serverConfig] of inMemoryServers) {
392
436
  if (serverConfig && serverConfig.tools) {
393
437
  // Handle tools array from MCPServerInfo
394
438
  const toolEntries = serverConfig.tools.map((tool) => [
@@ -401,13 +445,18 @@ export class BaseProvider {
401
445
  try {
402
446
  // Convert to AI SDK tool format
403
447
  const { tool: createAISDKTool } = await import("ai");
448
+ // Validate optional schemas if present (accept Zod or plain JSON schema objects)
449
+ const isZodSchema = (s) => typeof s === "object" &&
450
+ s !== null &&
451
+ // Most Zod schemas have an internal _def and a parse method
452
+ typeof s.parse === "function";
404
453
  tools[toolName] = createAISDKTool({
405
454
  description: toolInfo.description || `Tool ${toolName}`,
406
- parameters: toolInfo.parameters instanceof z.ZodType
455
+ parameters: isZodSchema(toolInfo.parameters)
407
456
  ? toolInfo.parameters
408
457
  : z.object({}),
409
- execute: async (args) => {
410
- const result = await toolInfo.execute(args);
458
+ execute: async (params) => {
459
+ const result = await toolInfo.execute(params);
411
460
  // Handle MCP-style results
412
461
  if (result &&
413
462
  typeof result === "object" &&
@@ -454,12 +503,12 @@ export class BaseProvider {
454
503
  tools[tool.name] = createAISDKTool({
455
504
  description: tool.description || `External MCP tool ${tool.name}`,
456
505
  parameters: await this.convertMCPSchemaToZod(tool.inputSchema),
457
- execute: async (args) => {
458
- logger.debug(`[BaseProvider] Executing external MCP tool: ${tool.name}`, { args });
506
+ execute: async (params) => {
507
+ logger.debug(`[BaseProvider] Executing external MCP tool: ${tool.name}`, { params });
459
508
  // Execute via NeuroLink's direct tool execution
460
509
  if (this.neurolink &&
461
510
  typeof this.neurolink.executeExternalMCPTool === "function") {
462
- return await this.neurolink.executeExternalMCPTool(tool.serverId || "unknown", tool.name, args);
511
+ return await this.neurolink.executeExternalMCPTool(tool.serverId || "unknown", tool.name, params);
463
512
  }
464
513
  else {
465
514
  throw new Error(`Cannot execute external MCP tool: NeuroLink executeExternalMCPTool not available`);
@@ -497,7 +546,7 @@ export class BaseProvider {
497
546
  if (this.mcpTools) {
498
547
  Object.assign(tools, this.mcpTools);
499
548
  }
500
- logger.debug(`[BaseProvider] getAllTools returning tools: ${Object.keys(tools).join(", ")}`);
549
+ logger.debug(`[BaseProvider] getAllTools returning tools: ${getKeysAsString(tools)}`);
501
550
  return tools;
502
551
  }
503
552
  /**
@@ -522,39 +571,39 @@ export class BaseProvider {
522
571
  switch (prop.type) {
523
572
  case "string":
524
573
  zodType = z.string();
525
- if (prop.description) {
574
+ if (prop.description && typeof prop.description === "string") {
526
575
  zodType = zodType.describe(prop.description);
527
576
  }
528
577
  break;
529
578
  case "number":
530
579
  case "integer":
531
580
  zodType = z.number();
532
- if (prop.description) {
581
+ if (prop.description && typeof prop.description === "string") {
533
582
  zodType = zodType.describe(prop.description);
534
583
  }
535
584
  break;
536
585
  case "boolean":
537
586
  zodType = z.boolean();
538
- if (prop.description) {
587
+ if (prop.description && typeof prop.description === "string") {
539
588
  zodType = zodType.describe(prop.description);
540
589
  }
541
590
  break;
542
591
  case "array":
543
592
  zodType = z.array(z.unknown());
544
- if (prop.description) {
593
+ if (prop.description && typeof prop.description === "string") {
545
594
  zodType = zodType.describe(prop.description);
546
595
  }
547
596
  break;
548
597
  case "object":
549
598
  zodType = z.object({});
550
- if (prop.description) {
599
+ if (prop.description && typeof prop.description === "string") {
551
600
  zodType = zodType.describe(prop.description);
552
601
  }
553
602
  break;
554
603
  default:
555
604
  // Unknown type, use string as fallback
556
605
  zodType = z.string();
557
- if (prop.description) {
606
+ if (prop.description && typeof prop.description === "string") {
558
607
  zodType = zodType.describe(prop.description);
559
608
  }
560
609
  }
@@ -565,9 +614,7 @@ export class BaseProvider {
565
614
  zodFields[propName] = zodType;
566
615
  }
567
616
  }
568
- return Object.keys(zodFields).length > 0
569
- ? z.object(zodFields)
570
- : z.object({});
617
+ return getKeyCount(zodFields) > 0 ? z.object(zodFields) : z.object({});
571
618
  }
572
619
  catch (error) {
573
620
  logger.warn(`Failed to convert MCP schema to Zod, using empty schema:`, error);
@@ -615,17 +662,22 @@ export class BaseProvider {
615
662
  * Validate stream options - consolidates validation from 7/10 providers
616
663
  */
617
664
  validateStreamOptions(options) {
618
- if (!options.input?.text || options.input.text.trim().length === 0) {
619
- throw new Error("Input text is required and cannot be empty");
620
- }
621
- if (options.temperature !== undefined) {
622
- if (options.temperature < 0 || options.temperature > 2) {
623
- throw new Error("temperature must be between 0 and 2");
624
- }
625
- }
626
- if (options.maxTokens !== undefined) {
627
- if (options.maxTokens < 1) {
628
- throw new Error("maxTokens must be at least 1");
665
+ const validation = validateStreamOpts(options);
666
+ if (!validation.isValid) {
667
+ const summary = createValidationSummary(validation);
668
+ throw new ValidationError(`Stream options validation failed: ${summary}`, "options", "VALIDATION_FAILED", validation.suggestions);
669
+ }
670
+ // Log warnings if any
671
+ if (validation.warnings.length > 0) {
672
+ logger.warn("Stream options validation warnings:", validation.warnings);
673
+ }
674
+ // Additional BaseProvider-specific validation
675
+ if (options.maxSteps !== undefined) {
676
+ if (options.maxSteps < STEP_LIMITS.min ||
677
+ options.maxSteps > STEP_LIMITS.max) {
678
+ throw new ValidationError(`maxSteps must be between ${STEP_LIMITS.min} and ${STEP_LIMITS.max}`, "maxSteps", "OUT_OF_RANGE", [
679
+ `Use a value between ${STEP_LIMITS.min} and ${STEP_LIMITS.max} for optimal performance`,
680
+ ]);
629
681
  }
630
682
  }
631
683
  }
@@ -656,7 +708,7 @@ export class BaseProvider {
656
708
  async createStreamAnalytics(result, startTime, options) {
657
709
  try {
658
710
  const { createAnalytics } = await import("./analytics.js");
659
- const analytics = await createAnalytics(this.providerName, this.modelName, result, Date.now() - startTime, {
711
+ const analytics = createAnalytics(this.providerName, this.modelName, result, Date.now() - startTime, {
660
712
  requestId: `${this.providerName}-stream-${Date.now()}`,
661
713
  streamingMode: true,
662
714
  ...options.context,
@@ -698,57 +750,17 @@ export class BaseProvider {
698
750
  * @param functionTag - Function name for logging
699
751
  */
700
752
  setupToolExecutor(sdk, functionTag) {
701
- // Type guard to check for setToolExecutor method
702
- function hasSetToolExecutor(obj) {
703
- return (typeof obj === "object" &&
704
- obj !== null &&
705
- typeof obj.setToolExecutor ===
706
- "function");
707
- }
708
- if (!hasSetToolExecutor(this)) {
709
- logger.warn(`[${functionTag}] Provider does not support setToolExecutor - tools will not be executed`, {
710
- hasProvider: true,
711
- providerType: this.constructor.name,
712
- availableCustomTools: sdk.customTools.size,
713
- });
714
- return;
715
- }
716
753
  // Store custom tools for use in getAllTools()
717
754
  this.customTools = sdk.customTools;
718
755
  this.toolExecutor = sdk.executeTool;
719
756
  logger.debug(`[${functionTag}] Setting up tool executor for provider`, {
720
757
  providerType: this.constructor.name,
721
758
  availableCustomTools: sdk.customTools.size,
759
+ customToolsStored: !!this.customTools,
760
+ toolExecutorStored: !!this.toolExecutor,
722
761
  });
723
- // Set up tool executor to handle actual tool calls
724
- this.setToolExecutor(async (toolName, params) => {
725
- logger.debug(`[${functionTag}] AI provider requesting tool execution: ${toolName}`, {
726
- toolName,
727
- params,
728
- availableCustomTools: sdk.customTools.size,
729
- hasRequestedTool: sdk.customTools.has(toolName),
730
- });
731
- try {
732
- // Execute the tool using NeuroLink's executeTool method
733
- const result = await sdk.executeTool(toolName, params);
734
- logger.debug(`[${functionTag}] Tool execution successful: ${toolName}`, {
735
- toolName,
736
- result: typeof result === "object"
737
- ? JSON.stringify(result).substring(0, 200)
738
- : result,
739
- resultType: typeof result,
740
- });
741
- return result;
742
- }
743
- catch (error) {
744
- logger.error(`[${functionTag}] Tool execution failed: ${toolName}`, {
745
- toolName,
746
- error: error instanceof Error ? error.message : String(error),
747
- params,
748
- });
749
- throw error;
750
- }
751
- });
762
+ // Note: Tool execution will be handled through getAllTools() -> AI SDK tools
763
+ // The custom tools are converted to AI SDK format in getAllTools() method
752
764
  }
753
765
  // ===================
754
766
  // TEMPLATE METHODS - COMMON FUNCTIONALITY
@@ -833,43 +845,24 @@ export class BaseProvider {
833
845
  return evaluation;
834
846
  }
835
847
  validateOptions(options) {
836
- // 🔧 EDGE CASE: Basic prompt validation
837
- if (!options.prompt || options.prompt.trim().length === 0) {
838
- throw new Error("Prompt is required and cannot be empty");
839
- }
840
- // 🔧 EDGE CASE: Handle very large prompts (>1M characters)
841
- if (options.prompt.length > SYSTEM_LIMITS.MAX_PROMPT_LENGTH) {
842
- throw new Error(`Prompt too large: ${options.prompt.length} characters (max: ${SYSTEM_LIMITS.MAX_PROMPT_LENGTH}). Consider breaking into smaller chunks. Use BaseProvider.chunkPrompt(prompt, maxSize, overlap) static method for chunking.`);
843
- }
844
- // 🔧 EDGE CASE: Validate token limits
845
- if (options.maxTokens && options.maxTokens > 200000) {
846
- throw new Error(`Max tokens too high: ${options.maxTokens} (recommended max: 200,000). This may cause timeouts or API errors.`);
847
- }
848
- if (options.maxTokens && options.maxTokens < 1) {
849
- throw new Error("Max tokens must be at least 1");
850
- }
851
- // 🔧 EDGE CASE: Validate temperature range
852
- if (options.temperature !== undefined) {
853
- if (options.temperature < 0 || options.temperature > 2) {
854
- throw new Error(`Temperature must be between 0 and 2, got: ${options.temperature}`);
855
- }
856
- }
857
- // 🔧 EDGE CASE: Validate timeout values
858
- if (options.timeout !== undefined) {
859
- const timeoutMs = typeof options.timeout === "string"
860
- ? parseInt(options.timeout, 10)
861
- : options.timeout;
862
- if (isNaN(timeoutMs) || timeoutMs < 1000) {
863
- throw new Error(`Timeout must be at least 1000ms (1 second), got: ${options.timeout}`);
864
- }
865
- if (timeoutMs > SYSTEM_LIMITS.LONG_TIMEOUT_WARNING) {
866
- logger.warn(`⚠️ Very long timeout: ${timeoutMs}ms. This may cause the CLI to hang.`);
848
+ const validation = validateTextGenerationOptions(options);
849
+ if (!validation.isValid) {
850
+ const summary = createValidationSummary(validation);
851
+ throw new ValidationError(`Text generation options validation failed: ${summary}`, "options", "VALIDATION_FAILED", validation.suggestions);
852
+ }
853
+ // Log warnings if any
854
+ if (validation.warnings.length > 0) {
855
+ logger.warn("Text generation options validation warnings:", validation.warnings);
856
+ }
857
+ // Additional BaseProvider-specific validation
858
+ if (options.maxSteps !== undefined) {
859
+ if (options.maxSteps < STEP_LIMITS.min ||
860
+ options.maxSteps > STEP_LIMITS.max) {
861
+ throw new ValidationError(`maxSteps must be between ${STEP_LIMITS.min} and ${STEP_LIMITS.max}`, "maxSteps", "OUT_OF_RANGE", [
862
+ `Use a value between ${STEP_LIMITS.min} and ${STEP_LIMITS.max} for optimal performance`,
863
+ ]);
867
864
  }
868
865
  }
869
- // 🔧 EDGE CASE: Validate maxSteps for tool execution
870
- if (options.maxSteps !== undefined && options.maxSteps > 20) {
871
- throw new Error(`Max steps too high: ${options.maxSteps} (recommended max: 20). This may cause long execution times.`);
872
- }
873
866
  }
874
867
  getProviderInfo() {
875
868
  return {
@@ -6,6 +6,11 @@ export declare const DEFAULT_MAX_TOKENS = 8192;
6
6
  export declare const DEFAULT_TEMPERATURE = 0.7;
7
7
  export declare const DEFAULT_TIMEOUT = 30000;
8
8
  export declare const DEFAULT_MAX_STEPS = 5;
9
+ export declare const STEP_LIMITS: {
10
+ min: number;
11
+ max: number;
12
+ default: number;
13
+ };
9
14
  export declare const DEFAULT_EVALUATION_MAX_TOKENS = 500;
10
15
  export declare const DEFAULT_ANALYSIS_MAX_TOKENS = 800;
11
16
  export declare const DEFAULT_DOCUMENTATION_MAX_TOKENS = 12000;
@@ -7,6 +7,12 @@ export const DEFAULT_MAX_TOKENS = 8192; // Changed from 10000 to fix Anthropic e
7
7
  export const DEFAULT_TEMPERATURE = 0.7;
8
8
  export const DEFAULT_TIMEOUT = 30000;
9
9
  export const DEFAULT_MAX_STEPS = 5; // Default multi-turn tool execution steps
10
+ // Step execution limits
11
+ export const STEP_LIMITS = {
12
+ min: 1,
13
+ max: 20,
14
+ default: DEFAULT_MAX_STEPS,
15
+ };
10
16
  // Specialized Use Case Defaults
11
17
  export const DEFAULT_EVALUATION_MAX_TOKENS = 500; // Keep evaluation fast
12
18
  export const DEFAULT_ANALYSIS_MAX_TOKENS = 800; // For analysis tools
@@ -88,8 +88,6 @@ declare const ModelRegistrySchema: z.ZodObject<{
88
88
  aliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
89
89
  defaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
90
90
  }, "strip", z.ZodTypeAny, {
91
- version: string;
92
- lastUpdated: string;
93
91
  models: Record<string, Record<string, {
94
92
  capabilities: string[];
95
93
  id: string;
@@ -102,11 +100,11 @@ declare const ModelRegistrySchema: z.ZodObject<{
102
100
  contextWindow: number;
103
101
  releaseDate: string;
104
102
  }>>;
103
+ version: string;
104
+ lastUpdated: string;
105
105
  defaults?: Record<string, string> | undefined;
106
106
  aliases?: Record<string, string> | undefined;
107
107
  }, {
108
- version: string;
109
- lastUpdated: string;
110
108
  models: Record<string, Record<string, {
111
109
  capabilities: string[];
112
110
  id: string;
@@ -119,6 +117,8 @@ declare const ModelRegistrySchema: z.ZodObject<{
119
117
  contextWindow: number;
120
118
  releaseDate: string;
121
119
  }>>;
120
+ version: string;
121
+ lastUpdated: string;
122
122
  defaults?: Record<string, string> | undefined;
123
123
  aliases?: Record<string, string> | undefined;
124
124
  }>;
@@ -1,5 +1,6 @@
1
1
  import type { AIProvider, AIProviderName, SupportedModelName } from "./types.js";
2
2
  import type { UnknownRecord } from "../types/common.js";
3
+ import type { ProviderPairResult } from "../types/typeAliases.js";
3
4
  declare const componentIdentifier = "aiProviderFactory";
4
5
  /**
5
6
  * Factory for creating AI provider instances with centralized configuration
@@ -45,9 +46,6 @@ export declare class AIProviderFactory {
45
46
  * @param enableMCP - Optional flag to enable MCP integration (default: true)
46
47
  * @returns Object with primary and fallback providers
47
48
  */
48
- static createProviderWithFallback(primaryProvider: string, fallbackProvider: string, modelName?: string | null, enableMCP?: boolean): Promise<{
49
- primary: AIProvider;
50
- fallback: AIProvider;
51
- }>;
49
+ static createProviderWithFallback(primaryProvider: string, fallbackProvider: string, modelName?: string | null, enableMCP?: boolean): Promise<ProviderPairResult<AIProvider>>;
52
50
  }
53
51
  export { componentIdentifier };
@@ -1,9 +1,10 @@
1
- import type { ZodType, ZodTypeDef } from "zod";
2
- import type { Schema, Tool } from "ai";
1
+ import type { Tool, Schema } from "ai";
2
+ import type { ZodUnknownSchema, ValidationSchema } from "../types/typeAliases.js";
3
3
  import type { GenerateResult } from "../types/generateTypes.js";
4
4
  import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
5
5
  import type { JsonValue } from "../types/common.js";
6
6
  import type { ChatMessage } from "../types/conversationTypes.js";
7
+ import type { AnalyticsData } from "./analytics.js";
7
8
  export interface TextGenerationResult {
8
9
  content: string;
9
10
  provider?: string;
@@ -137,7 +138,7 @@ export interface TextGenerationOptions {
137
138
  temperature?: number;
138
139
  maxTokens?: number;
139
140
  systemPrompt?: string;
140
- schema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>;
141
+ schema?: ZodUnknownSchema | Schema<unknown>;
141
142
  tools?: Record<string, Tool>;
142
143
  timeout?: number | string;
143
144
  disableTools?: boolean;
@@ -153,22 +154,7 @@ export interface TextGenerationOptions {
153
154
  }>;
154
155
  conversationMessages?: ChatMessage[];
155
156
  }
156
- /**
157
- * Analytics data for usage tracking
158
- */
159
- export interface AnalyticsData {
160
- provider: string;
161
- model: string;
162
- tokens: {
163
- input: number;
164
- output: number;
165
- total: number;
166
- };
167
- cost?: number;
168
- responseTime: number;
169
- timestamp: string;
170
- context?: Record<string, JsonValue>;
171
- }
157
+ export type { AnalyticsData };
172
158
  /**
173
159
  * Response quality evaluation scores
174
160
  * Comprehensive evaluation interface for response quality assessment
@@ -299,9 +285,9 @@ export type ProgressCallback = (progress: StreamingProgressData) => void;
299
285
  * AI Provider interface with flexible parameter support
300
286
  */
301
287
  export interface AIProvider {
302
- stream(optionsOrPrompt: StreamOptions | string, analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<StreamResult>;
303
- generate(optionsOrPrompt: TextGenerationOptions | string, analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<EnhancedGenerateResult | null>;
304
- gen(optionsOrPrompt: TextGenerationOptions | string, analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<EnhancedGenerateResult | null>;
288
+ stream(optionsOrPrompt: StreamOptions | string, analysisSchema?: ValidationSchema): Promise<StreamResult>;
289
+ generate(optionsOrPrompt: TextGenerationOptions | string, analysisSchema?: ValidationSchema): Promise<EnhancedGenerateResult | null>;
290
+ gen(optionsOrPrompt: TextGenerationOptions | string, analysisSchema?: ValidationSchema): Promise<EnhancedGenerateResult | null>;
305
291
  setupToolExecutor(sdk: {
306
292
  customTools: Map<string, unknown>;
307
293
  executeTool: (toolName: string, params: unknown) => Promise<unknown>;
package/dist/index.d.ts CHANGED
@@ -41,10 +41,7 @@ export declare function createAIProvider(providerName?: string, modelName?: stri
41
41
  * const { primary, fallback } = await createAIProviderWithFallback('bedrock', 'vertex');
42
42
  * ```
43
43
  */
44
- export declare function createAIProviderWithFallback(primaryProvider?: string, fallbackProvider?: string, modelName?: string): Promise<{
45
- primary: import("./core/types.js").AIProvider;
46
- fallback: import("./core/types.js").AIProvider;
47
- }>;
44
+ export declare function createAIProviderWithFallback(primaryProvider?: string, fallbackProvider?: string, modelName?: string): Promise<import("./types/typeAliases.js").ProviderPairResult<import("./core/types.js").AIProvider>>;
48
45
  /**
49
46
  * Create the best available provider based on configuration
50
47
  *
@@ -1,7 +1,6 @@
1
- import type { ZodType, ZodTypeDef } from "zod";
2
- import type { Schema } from "ai";
1
+ import type { ValidationSchema } from "../types/typeAliases.js";
3
2
  import type { Tool, LanguageModelV1 } from "ai";
4
- import type { AIProvider, TextGenerationOptions, EnhancedGenerateResult, AnalyticsData, AIProviderName, EvaluationData } from "../core/types.js";
3
+ import type { AIProvider, TextGenerationOptions, TextGenerationResult, EnhancedGenerateResult, AnalyticsData, AIProviderName, EvaluationData } from "../core/types.js";
5
4
  import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
6
5
  import type { UnknownRecord } from "../types/common.js";
7
6
  import type { NeuroLink } from "../neurolink.js";
@@ -31,20 +30,26 @@ export declare abstract class BaseProvider implements AIProvider {
31
30
  * Primary streaming method - implements AIProvider interface
32
31
  * When tools are involved, falls back to generate() with synthetic streaming
33
32
  */
34
- stream(optionsOrPrompt: StreamOptions | string, analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<StreamResult>;
33
+ stream(optionsOrPrompt: StreamOptions | string, analysisSchema?: ValidationSchema): Promise<StreamResult>;
35
34
  /**
36
35
  * Text generation method - implements AIProvider interface
37
36
  * Tools are always available unless explicitly disabled
38
37
  */
39
- generate(optionsOrPrompt: TextGenerationOptions | string, analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<EnhancedGenerateResult | null>;
38
+ generate(optionsOrPrompt: TextGenerationOptions | string, _analysisSchema?: ValidationSchema): Promise<EnhancedGenerateResult | null>;
40
39
  /**
41
40
  * Alias for generate method - implements AIProvider interface
42
41
  */
43
- gen(optionsOrPrompt: TextGenerationOptions | string, analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<EnhancedGenerateResult | null>;
42
+ gen(optionsOrPrompt: TextGenerationOptions | string, analysisSchema?: ValidationSchema): Promise<EnhancedGenerateResult | null>;
43
+ /**
44
+ * BACKWARD COMPATIBILITY: Legacy generateText method
45
+ * Converts EnhancedGenerateResult to TextGenerationResult format
46
+ * Ensures existing scripts using createAIProvider().generateText() continue to work
47
+ */
48
+ generateText(options: TextGenerationOptions): Promise<TextGenerationResult>;
44
49
  /**
45
50
  * Provider-specific streaming implementation (only used when tools are disabled)
46
51
  */
47
- protected abstract executeStream(options: StreamOptions, analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<StreamResult>;
52
+ protected abstract executeStream(options: StreamOptions, analysisSchema?: ValidationSchema): Promise<StreamResult>;
48
53
  /**
49
54
  * Get the provider name
50
55
  */