@juspay/neurolink 7.33.3 → 7.33.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 (50) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cli/commands/config.d.ts +3 -4
  3. package/dist/cli/commands/config.js +2 -3
  4. package/dist/core/baseProvider.js +26 -1
  5. package/dist/core/constants.d.ts +12 -3
  6. package/dist/core/constants.js +22 -6
  7. package/dist/core/factory.js +19 -0
  8. package/dist/factories/providerRegistry.js +2 -0
  9. package/dist/lib/core/baseProvider.js +26 -1
  10. package/dist/lib/core/constants.d.ts +12 -3
  11. package/dist/lib/core/constants.js +22 -6
  12. package/dist/lib/core/factory.js +19 -0
  13. package/dist/lib/factories/providerRegistry.js +2 -0
  14. package/dist/lib/mcp/servers/aiProviders/aiWorkflowTools.js +2 -2
  15. package/dist/lib/providers/amazonBedrock.js +2 -2
  16. package/dist/lib/providers/anthropic.js +3 -12
  17. package/dist/lib/providers/anthropicBaseProvider.js +1 -2
  18. package/dist/lib/providers/azureOpenai.js +49 -8
  19. package/dist/lib/providers/googleAiStudio.js +3 -3
  20. package/dist/lib/providers/googleVertex.js +2 -2
  21. package/dist/lib/providers/huggingFace.js +1 -2
  22. package/dist/lib/providers/litellm.js +1 -2
  23. package/dist/lib/providers/mistral.js +2 -2
  24. package/dist/lib/providers/ollama.js +7 -8
  25. package/dist/lib/providers/openAI.js +2 -2
  26. package/dist/lib/providers/openaiCompatible.js +5 -2
  27. package/dist/lib/providers/sagemaker/language-model.d.ts +5 -0
  28. package/dist/lib/providers/sagemaker/language-model.js +9 -1
  29. package/dist/lib/utils/providerHealth.js +7 -3
  30. package/dist/lib/utils/tokenLimits.d.ts +2 -2
  31. package/dist/lib/utils/tokenLimits.js +10 -3
  32. package/dist/mcp/servers/aiProviders/aiWorkflowTools.js +2 -2
  33. package/dist/providers/amazonBedrock.js +2 -2
  34. package/dist/providers/anthropic.js +3 -12
  35. package/dist/providers/anthropicBaseProvider.js +1 -2
  36. package/dist/providers/azureOpenai.js +49 -8
  37. package/dist/providers/googleAiStudio.js +3 -3
  38. package/dist/providers/googleVertex.js +2 -2
  39. package/dist/providers/huggingFace.js +1 -2
  40. package/dist/providers/litellm.js +1 -2
  41. package/dist/providers/mistral.js +2 -2
  42. package/dist/providers/ollama.js +7 -8
  43. package/dist/providers/openAI.js +2 -2
  44. package/dist/providers/openaiCompatible.js +5 -2
  45. package/dist/providers/sagemaker/language-model.d.ts +5 -0
  46. package/dist/providers/sagemaker/language-model.js +9 -1
  47. package/dist/utils/providerHealth.js +7 -3
  48. package/dist/utils/tokenLimits.d.ts +2 -2
  49. package/dist/utils/tokenLimits.js +10 -3
  50. package/package.json +1 -1
@@ -4,7 +4,7 @@ import { streamText, Output, } from "ai";
4
4
  import { BaseProvider } from "../core/baseProvider.js";
5
5
  import { logger } from "../utils/logger.js";
6
6
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
7
- import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
7
+ import { DEFAULT_MAX_STEPS } from "../core/constants.js";
8
8
  import { ModelConfigurationManager } from "../core/modelConfiguration.js";
9
9
  import { validateApiKey, createVertexProjectConfig, createGoogleAuthConfig, } from "../utils/providerConfig.js";
10
10
  import fs from "fs";
@@ -945,7 +945,7 @@ export class GoogleVertexProvider extends BaseProvider {
945
945
  // This avoids hardcoded model-specific logic and repeated config lookups
946
946
  const shouldSetMaxTokens = this.shouldSetMaxTokensCached(modelName);
947
947
  const maxTokens = shouldSetMaxTokens
948
- ? options.maxTokens || DEFAULT_MAX_TOKENS
948
+ ? options.maxTokens // No default limit
949
949
  : undefined;
950
950
  // Build complete stream options with proper typing
951
951
  let streamOptions = {
@@ -3,7 +3,6 @@ import { streamText, } from "ai";
3
3
  import { BaseProvider } from "../core/baseProvider.js";
4
4
  import { logger } from "../utils/logger.js";
5
5
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
6
- import { DEFAULT_MAX_TOKENS } from "../core/constants.js";
7
6
  import { validateApiKey, createHuggingFaceConfig, getProviderModel, } from "../utils/providerConfig.js";
8
7
  import { buildMessagesArray } from "../utils/messageBuilder.js";
9
8
  import { createProxyFetch } from "../proxy/proxyFetch.js";
@@ -120,7 +119,7 @@ export class HuggingFaceProvider extends BaseProvider {
120
119
  model: this.model,
121
120
  messages: messages,
122
121
  temperature: options.temperature,
123
- maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
122
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
124
123
  tools: streamOptions.tools, // Tools format conversion handled by prepareStreamOptions
125
124
  toolChoice: streamOptions.toolChoice, // Tool choice handled by prepareStreamOptions
126
125
  abortSignal: timeoutController?.controller.signal,
@@ -3,7 +3,6 @@ import { streamText } from "ai";
3
3
  import { BaseProvider } from "../core/baseProvider.js";
4
4
  import { logger } from "../utils/logger.js";
5
5
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
6
- import { DEFAULT_MAX_TOKENS } from "../core/constants.js";
7
6
  import { getProviderModel } from "../utils/providerConfig.js";
8
7
  import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
9
8
  import { buildMessagesArray } from "../utils/messageBuilder.js";
@@ -127,7 +126,7 @@ export class LiteLLMProvider extends BaseProvider {
127
126
  model: this.model,
128
127
  messages: messages,
129
128
  temperature: options.temperature,
130
- maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
129
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
131
130
  tools: options.tools,
132
131
  toolChoice: "auto",
133
132
  abortSignal: timeoutController?.controller.signal,
@@ -3,7 +3,7 @@ import { streamText } from "ai";
3
3
  import { BaseProvider } from "../core/baseProvider.js";
4
4
  import { logger } from "../utils/logger.js";
5
5
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
6
- import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
6
+ import { DEFAULT_MAX_STEPS } from "../core/constants.js";
7
7
  import { validateApiKey, createMistralConfig, getProviderModel, } from "../utils/providerConfig.js";
8
8
  import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
9
9
  import { buildMessagesArray } from "../utils/messageBuilder.js";
@@ -54,7 +54,7 @@ export class MistralProvider extends BaseProvider {
54
54
  model: this.model,
55
55
  messages: messages,
56
56
  temperature: options.temperature,
57
- maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
57
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
58
58
  tools,
59
59
  maxSteps: options.maxSteps || DEFAULT_MAX_STEPS,
60
60
  toolChoice: shouldUseTools ? "auto" : "none",
@@ -1,6 +1,5 @@
1
1
  import { BaseProvider } from "../core/baseProvider.js";
2
2
  import { logger } from "../utils/logger.js";
3
- import { DEFAULT_MAX_TOKENS } from "../core/constants.js";
4
3
  import { modelConfig } from "../core/modelConfiguration.js";
5
4
  import { createProxyFetch } from "../proxy/proxyFetch.js";
6
5
  import { TimeoutError } from "../utils/timeout.js";
@@ -88,10 +87,10 @@ class OllamaLanguageModel {
88
87
  return {
89
88
  text: data.response,
90
89
  usage: {
91
- promptTokens: data.prompt_eval_count || this.estimateTokens(prompt),
92
- completionTokens: data.eval_count || this.estimateTokens(data.response),
93
- totalTokens: (data.prompt_eval_count || this.estimateTokens(prompt)) +
94
- (data.eval_count || this.estimateTokens(data.response)),
90
+ promptTokens: data.prompt_eval_count ?? this.estimateTokens(prompt),
91
+ completionTokens: data.eval_count ?? this.estimateTokens(String(data.response ?? "")),
92
+ totalTokens: (data.prompt_eval_count ?? this.estimateTokens(prompt)) +
93
+ (data.eval_count ?? this.estimateTokens(String(data.response ?? ""))),
95
94
  },
96
95
  finishReason: "stop",
97
96
  rawCall: {
@@ -271,7 +270,7 @@ export class OllamaProvider extends BaseProvider {
271
270
  * @returns true for supported models, false for unsupported models
272
271
  */
273
272
  supportsTools() {
274
- const modelName = this.modelName.toLowerCase();
273
+ const modelName = (this.modelName ?? getDefaultOllamaModel()).toLowerCase();
275
274
  // Get tool-capable models from configuration
276
275
  const ollamaConfig = modelConfig.getProviderConfiguration("ollama");
277
276
  const toolCapableModels = ollamaConfig?.modelBehavior?.toolCapableModels || [];
@@ -340,7 +339,7 @@ export class OllamaProvider extends BaseProvider {
340
339
  tool_choice: "auto",
341
340
  stream: true,
342
341
  temperature: options.temperature,
343
- max_tokens: options.maxTokens || DEFAULT_MAX_TOKENS,
342
+ max_tokens: options.maxTokens,
344
343
  }),
345
344
  signal: createAbortSignalWithTimeout(this.timeout),
346
345
  });
@@ -381,7 +380,7 @@ export class OllamaProvider extends BaseProvider {
381
380
  stream: true,
382
381
  options: {
383
382
  temperature: options.temperature,
384
- num_predict: options.maxTokens || DEFAULT_MAX_TOKENS,
383
+ num_predict: options.maxTokens,
385
384
  },
386
385
  }),
387
386
  signal: createAbortSignalWithTimeout(this.timeout),
@@ -5,7 +5,7 @@ import { BaseProvider } from "../core/baseProvider.js";
5
5
  import { logger } from "../utils/logger.js";
6
6
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
7
7
  import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
8
- import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
8
+ import { DEFAULT_MAX_STEPS } from "../core/constants.js";
9
9
  import { validateApiKey, createOpenAIConfig, getProviderModel, } from "../utils/providerConfig.js";
10
10
  import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
11
11
  import { buildMessagesArray } from "../utils/messageBuilder.js";
@@ -97,7 +97,7 @@ export class OpenAIProvider extends BaseProvider {
97
97
  model: this.model,
98
98
  messages: messages,
99
99
  temperature: options.temperature,
100
- maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
100
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
101
101
  tools,
102
102
  maxSteps: options.maxSteps || DEFAULT_MAX_STEPS,
103
103
  toolChoice: shouldUseTools ? "auto" : "none",
@@ -3,7 +3,6 @@ import { streamText } from "ai";
3
3
  import { BaseProvider } from "../core/baseProvider.js";
4
4
  import { logger } from "../utils/logger.js";
5
5
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
6
- import { DEFAULT_MAX_TOKENS } from "../core/constants.js";
7
6
  import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
8
7
  import { createProxyFetch } from "../proxy/proxyFetch.js";
9
8
  // Constants
@@ -163,7 +162,7 @@ export class OpenAICompatibleProvider extends BaseProvider {
163
162
  prompt: options.input.text,
164
163
  system: options.systemPrompt,
165
164
  temperature: options.temperature,
166
- maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
165
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
167
166
  tools: options.tools,
168
167
  toolChoice: "auto",
169
168
  abortSignal: timeoutController?.controller.signal,
@@ -207,12 +206,16 @@ export class OpenAICompatibleProvider extends BaseProvider {
207
206
  const modelsUrl = new URL("/v1/models", this.config.baseURL).toString();
208
207
  logger.debug(`Fetching available models from: ${modelsUrl}`);
209
208
  const proxyFetch = createProxyFetch();
209
+ const controller = new AbortController();
210
+ const t = setTimeout(() => controller.abort(), 5000);
210
211
  const response = await proxyFetch(modelsUrl, {
211
212
  headers: {
212
213
  Authorization: `Bearer ${this.config.apiKey}`,
213
214
  "Content-Type": "application/json",
214
215
  },
216
+ signal: controller.signal,
215
217
  });
218
+ clearTimeout(t);
216
219
  if (!response.ok) {
217
220
  logger.warn(`Models endpoint returned ${response.status}: ${response.statusText}`);
218
221
  return this.getFallbackModels();
@@ -9,6 +9,11 @@ import type { SageMakerConfig, SageMakerModelConfig } from "./types.js";
9
9
  import type { ConnectivityResult } from "../../types/typeAliases.js";
10
10
  /**
11
11
  * SageMaker Language Model implementing LanguageModelV1 interface
12
+ *
13
+ * Token Limit Behavior:
14
+ * - When maxTokens is undefined, SageMaker uses the model's default token limits
15
+ * - When maxTokens is specified, it sets max_new_tokens parameter explicitly
16
+ * - This aligns with the unlimited-by-default token policy across all providers
12
17
  */
13
18
  export declare class SageMakerLanguageModel implements LanguageModelV1 {
14
19
  readonly specificationVersion = "v1";
@@ -75,6 +75,11 @@ const DEFAULT_MAX_CONCURRENCY = 10;
75
75
  const DEFAULT_MIN_CONCURRENCY = 1;
76
76
  /**
77
77
  * SageMaker Language Model implementing LanguageModelV1 interface
78
+ *
79
+ * Token Limit Behavior:
80
+ * - When maxTokens is undefined, SageMaker uses the model's default token limits
81
+ * - When maxTokens is specified, it sets max_new_tokens parameter explicitly
82
+ * - This aligns with the unlimited-by-default token policy across all providers
78
83
  */
79
84
  export class SageMakerLanguageModel {
80
85
  specificationVersion = "v1";
@@ -345,7 +350,10 @@ export class SageMakerLanguageModel {
345
350
  const request = {
346
351
  inputs: promptText,
347
352
  parameters: {
348
- max_new_tokens: options.maxTokens || 512,
353
+ // Only include max_new_tokens if explicitly specified; let SageMaker use model defaults otherwise
354
+ ...(options.maxTokens !== undefined
355
+ ? { max_new_tokens: options.maxTokens }
356
+ : {}),
349
357
  temperature: options.temperature || 0.7,
350
358
  top_p: options.topP || 0.9,
351
359
  stop: options.stopSequences || [],
@@ -639,9 +639,13 @@ export class ProviderHealthChecker {
639
639
  healthStatus.configurationIssues.push("Invalid AZURE_OPENAI_ENDPOINT format");
640
640
  healthStatus.recommendations.push("Set AZURE_OPENAI_ENDPOINT to a valid URL (e.g., https://your-resource.openai.azure.com/)");
641
641
  }
642
- if (!process.env.AZURE_OPENAI_DEPLOYMENT_NAME) {
643
- healthStatus.configurationIssues.push("AZURE_OPENAI_DEPLOYMENT_NAME not set");
644
- healthStatus.recommendations.push("Set AZURE_OPENAI_DEPLOYMENT_NAME to your deployment name");
642
+ // Check for deployment name using the SAME logic as the Azure provider
643
+ const deploymentName = process.env.AZURE_OPENAI_MODEL ||
644
+ process.env.AZURE_OPENAI_DEPLOYMENT ||
645
+ process.env.AZURE_OPENAI_DEPLOYMENT_ID;
646
+ if (!deploymentName) {
647
+ healthStatus.configurationIssues.push("No Azure deployment specified");
648
+ healthStatus.recommendations.push("Set one of: AZURE_OPENAI_MODEL, AZURE_OPENAI_DEPLOYMENT, or AZURE_OPENAI_DEPLOYMENT_ID");
645
649
  }
646
650
  }
647
651
  /**
@@ -6,13 +6,13 @@ import { PROVIDER_MAX_TOKENS } from "../core/constants.js";
6
6
  /**
7
7
  * Get the safe maximum tokens for a provider and model
8
8
  */
9
- export declare function getSafeMaxTokens(provider: keyof typeof PROVIDER_MAX_TOKENS | string, model?: string, requestedMaxTokens?: number): number;
9
+ export declare function getSafeMaxTokens(provider: keyof typeof PROVIDER_MAX_TOKENS | string, model?: string, requestedMaxTokens?: number): number | undefined;
10
10
  /**
11
11
  * Validate if maxTokens is safe for a provider/model combination
12
12
  */
13
13
  export declare function validateMaxTokens(provider: keyof typeof PROVIDER_MAX_TOKENS | string, model?: string, maxTokens?: number): {
14
14
  isValid: boolean;
15
- recommendedMaxTokens: number;
15
+ recommendedMaxTokens?: number;
16
16
  warning?: string;
17
17
  };
18
18
  /**
@@ -2,7 +2,7 @@
2
2
  * Provider-specific token limit utilities
3
3
  * Provides safe maxTokens values based on provider and model capabilities
4
4
  */
5
- import { PROVIDER_MAX_TOKENS, DEFAULT_MAX_TOKENS } from "../core/constants.js";
5
+ import { PROVIDER_MAX_TOKENS } from "../core/constants.js";
6
6
  import { logger } from "./logger.js";
7
7
  /**
8
8
  * Get the safe maximum tokens for a provider and model
@@ -11,8 +11,8 @@ export function getSafeMaxTokens(provider, model, requestedMaxTokens) {
11
11
  // Get provider-specific limits
12
12
  const providerLimits = PROVIDER_MAX_TOKENS[provider];
13
13
  if (!providerLimits) {
14
- logger.warn(`Unknown provider ${provider}, using default maxTokens limit`);
15
- return Math.min(requestedMaxTokens || DEFAULT_MAX_TOKENS, PROVIDER_MAX_TOKENS.default);
14
+ logger.warn(`Unknown provider ${provider}, no token limits enforced`);
15
+ return requestedMaxTokens || undefined; // No default limit for unknown providers
16
16
  }
17
17
  // Get model-specific limit or provider default
18
18
  let maxLimit;
@@ -54,6 +54,13 @@ export function validateMaxTokens(provider, model, maxTokens) {
54
54
  recommendedMaxTokens: safeMaxTokens,
55
55
  };
56
56
  }
57
+ // If no limits are defined, validation always passes
58
+ if (safeMaxTokens === undefined) {
59
+ return {
60
+ isValid: true,
61
+ recommendedMaxTokens: maxTokens,
62
+ };
63
+ }
57
64
  const isValid = maxTokens <= safeMaxTokens;
58
65
  return {
59
66
  isValid,
@@ -146,7 +146,7 @@ Return ONLY a valid JSON object with this exact structure:
146
146
  Generate 3-5 comprehensive test cases covering the requested types.`;
147
147
  const result = await provider.generate({
148
148
  prompt: prompt,
149
- maxTokens: Math.floor(DEFAULT_MAX_TOKENS * 1.2),
149
+ maxTokens: 10000, // High limit for complex analysis
150
150
  temperature: 0.3, // Lower temperature for more consistent structured output
151
151
  });
152
152
  if (!result || !result.content) {
@@ -360,7 +360,7 @@ Return ONLY a valid JSON object with this exact structure:
360
360
  Focus on creating accurate, useful documentation that explains the code's purpose, parameters, return values, and usage patterns.`;
361
361
  const result = await provider.generate({
362
362
  prompt: prompt,
363
- maxTokens: Math.floor(DEFAULT_MAX_TOKENS * 1.2),
363
+ maxTokens: 10000, // High limit for complex analysis
364
364
  temperature: 0.3, // Moderate temperature for creative but structured documentation
365
365
  });
366
366
  if (!result || !result.content) {
@@ -157,7 +157,7 @@ export class AmazonBedrockProvider extends BaseProvider {
157
157
  },
158
158
  ],
159
159
  inferenceConfig: {
160
- maxTokens: options.maxTokens || 4096,
160
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
161
161
  temperature: options.temperature || 0.7,
162
162
  },
163
163
  };
@@ -718,7 +718,7 @@ export class AmazonBedrockProvider extends BaseProvider {
718
718
  },
719
719
  ],
720
720
  inferenceConfig: {
721
- maxTokens: options.maxTokens || 4096,
721
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
722
722
  temperature: options.temperature || 0.7,
723
723
  },
724
724
  };
@@ -5,7 +5,7 @@ import { BaseProvider } from "../core/baseProvider.js";
5
5
  import { logger } from "../utils/logger.js";
6
6
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
7
7
  import { AuthenticationError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
8
- import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
8
+ import { DEFAULT_MAX_STEPS } from "../core/constants.js";
9
9
  import { validateApiKey, createAnthropicConfig, getProviderModel, } from "../utils/providerConfig.js";
10
10
  import { buildMessagesArray } from "../utils/messageBuilder.js";
11
11
  import { createProxyFetch } from "../proxy/proxyFetch.js";
@@ -98,7 +98,7 @@ export class AnthropicProvider extends BaseProvider {
98
98
  model: this.model,
99
99
  messages: messages,
100
100
  temperature: options.temperature,
101
- maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
101
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
102
102
  tools,
103
103
  maxSteps: options.maxSteps || DEFAULT_MAX_STEPS,
104
104
  toolChoice: shouldUseTools ? "auto" : "none",
@@ -111,22 +111,13 @@ export class AnthropicProvider extends BaseProvider {
111
111
  // Full tool support is now available with real streaming
112
112
  const toolCalls = [];
113
113
  const toolResults = [];
114
- const usage = await result.usage;
115
- const finishReason = await result.finishReason;
116
114
  return {
117
115
  stream: transformedStream,
118
116
  provider: this.providerName,
119
117
  model: this.modelName,
120
118
  toolCalls, // ✅ Include tool calls in stream result
121
119
  toolResults, // ✅ Include tool results in stream result
122
- usage: usage
123
- ? {
124
- input: usage.promptTokens || 0,
125
- output: usage.completionTokens || 0,
126
- total: usage.totalTokens || 0,
127
- }
128
- : undefined,
129
- finishReason: finishReason || undefined,
120
+ // Note: omit usage/finishReason to avoid blocking streaming; compute asynchronously if needed.
130
121
  };
131
122
  }
132
123
  catch (error) {
@@ -4,7 +4,6 @@ import { AnthropicModels } from "../types/index.js";
4
4
  import { BaseProvider } from "../core/baseProvider.js";
5
5
  import { logger } from "../utils/logger.js";
6
6
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
7
- import { DEFAULT_MAX_TOKENS } from "../core/constants.js";
8
7
  import { validateApiKey, createAnthropicBaseConfig, } from "../utils/providerConfig.js";
9
8
  /**
10
9
  * Anthropic provider implementation using BaseProvider pattern
@@ -70,7 +69,7 @@ export class AnthropicProviderV2 extends BaseProvider {
70
69
  prompt: options.input.text,
71
70
  system: options.systemPrompt,
72
71
  temperature: options.temperature,
73
- maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
72
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
74
73
  tools: options.tools,
75
74
  toolChoice: "auto",
76
75
  abortSignal: timeoutController?.controller.signal,
@@ -6,6 +6,7 @@ import { validateApiKey, createAzureAPIKeyConfig, createAzureEndpointConfig, } f
6
6
  import { logger } from "../utils/logger.js";
7
7
  import { buildMessagesArray } from "../utils/messageBuilder.js";
8
8
  import { createProxyFetch } from "../proxy/proxyFetch.js";
9
+ import { DEFAULT_MAX_STEPS } from "../core/constants.js";
9
10
  export class AzureOpenAIProvider extends BaseProvider {
10
11
  apiKey;
11
12
  resourceName;
@@ -19,9 +20,11 @@ export class AzureOpenAIProvider extends BaseProvider {
19
20
  this.resourceName = endpoint
20
21
  .replace("https://", "")
21
22
  .replace(/\/+$/, "") // Remove trailing slashes
22
- .replace(".openai.azure.com", "");
23
+ .replace(".openai.azure.com", "")
24
+ .replace(".cognitiveservices.azure.com", "");
23
25
  this.deployment =
24
26
  modelName ||
27
+ process.env.AZURE_OPENAI_MODEL ||
25
28
  process.env.AZURE_OPENAI_DEPLOYMENT ||
26
29
  process.env.AZURE_OPENAI_DEPLOYMENT_ID ||
27
30
  "gpt-4o";
@@ -34,6 +37,7 @@ export class AzureOpenAIProvider extends BaseProvider {
34
37
  validateApiKey(createAzureEndpointConfig());
35
38
  }
36
39
  // Create the Azure provider instance with proxy support
40
+ // Let the Azure SDK handle all URL construction automatically
37
41
  this.azureProvider = createAzure({
38
42
  resourceName: this.resourceName,
39
43
  apiKey: this.apiKey,
@@ -73,20 +77,57 @@ export class AzureOpenAIProvider extends BaseProvider {
73
77
  // executeGenerate removed - BaseProvider handles all generation with tools
74
78
  async executeStream(options, _analysisSchema) {
75
79
  try {
80
+ // Get ALL available tools (direct + MCP + external from options) - EXACTLY like BaseProvider
81
+ const shouldUseTools = !options.disableTools && this.supportsTools();
82
+ const baseTools = shouldUseTools ? await this.getAllTools() : {};
83
+ const tools = shouldUseTools
84
+ ? {
85
+ ...baseTools,
86
+ ...(options.tools || {}), // Include external tools passed from NeuroLink
87
+ }
88
+ : undefined;
89
+ // DEBUG: Log detailed tool information
90
+ logger.debug("Azure Stream - Tool Loading Debug", {
91
+ shouldUseTools,
92
+ baseToolsProvided: !!baseTools,
93
+ baseToolCount: baseTools ? Object.keys(baseTools).length : 0,
94
+ finalToolCount: tools ? Object.keys(tools).length : 0,
95
+ toolNames: tools ? Object.keys(tools).slice(0, 10) : [],
96
+ disableTools: options.disableTools,
97
+ supportsTools: this.supportsTools(),
98
+ externalToolsCount: options.tools
99
+ ? Object.keys(options.tools).length
100
+ : 0,
101
+ });
102
+ if (tools && Object.keys(tools).length > 0) {
103
+ logger.debug("Azure Stream - First 5 Tools Detail", {
104
+ tools: Object.keys(tools)
105
+ .slice(0, 5)
106
+ .map((name) => ({
107
+ name,
108
+ description: tools[name]?.description?.substring(0, 100),
109
+ })),
110
+ });
111
+ }
76
112
  // Build message array from options
77
113
  const messages = buildMessagesArray(options);
78
114
  const stream = await streamText({
79
115
  model: this.azureProvider(this.deployment),
80
116
  messages: messages,
81
- maxTokens: options.maxTokens || 1000,
82
- temperature: options.temperature || 0.7,
117
+ ...(options.maxTokens !== null && options.maxTokens !== undefined
118
+ ? { maxTokens: options.maxTokens }
119
+ : {}),
120
+ ...(options.temperature !== null && options.temperature !== undefined
121
+ ? { temperature: options.temperature }
122
+ : {}),
123
+ tools,
124
+ toolChoice: shouldUseTools ? "auto" : "none",
125
+ maxSteps: options.maxSteps || DEFAULT_MAX_STEPS,
83
126
  });
127
+ // Transform string stream to content object stream using BaseProvider method
128
+ const transformedStream = this.createTextStream(stream);
84
129
  return {
85
- stream: (async function* () {
86
- for await (const chunk of stream.textStream) {
87
- yield { content: chunk };
88
- }
89
- })(),
130
+ stream: transformedStream,
90
131
  provider: "azure",
91
132
  model: this.deployment,
92
133
  metadata: {
@@ -5,12 +5,12 @@ import { BaseProvider } from "../core/baseProvider.js";
5
5
  import { logger } from "../utils/logger.js";
6
6
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
7
7
  import { AuthenticationError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
8
- import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
8
+ import { DEFAULT_MAX_STEPS } from "../core/constants.js";
9
9
  import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
10
10
  import { buildMessagesArray } from "../utils/messageBuilder.js";
11
11
  // Create Google GenAI client
12
12
  async function createGoogleGenAIClient(apiKey) {
13
- const mod = await import("@google/genai");
13
+ const mod = await import("@google/generative-ai");
14
14
  const ctor = mod.GoogleGenAI;
15
15
  if (!ctor) {
16
16
  throw new Error("@google/genai does not export GoogleGenAI");
@@ -96,7 +96,7 @@ export class GoogleAIStudioProvider extends BaseProvider {
96
96
  model,
97
97
  messages: messages,
98
98
  temperature: options.temperature,
99
- maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
99
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
100
100
  tools,
101
101
  maxSteps: options.maxSteps || DEFAULT_MAX_STEPS,
102
102
  toolChoice: shouldUseTools ? "auto" : "none",
@@ -4,7 +4,7 @@ import { streamText, Output, } from "ai";
4
4
  import { BaseProvider } from "../core/baseProvider.js";
5
5
  import { logger } from "../utils/logger.js";
6
6
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
7
- import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
7
+ import { DEFAULT_MAX_STEPS } from "../core/constants.js";
8
8
  import { ModelConfigurationManager } from "../core/modelConfiguration.js";
9
9
  import { validateApiKey, createVertexProjectConfig, createGoogleAuthConfig, } from "../utils/providerConfig.js";
10
10
  import fs from "fs";
@@ -945,7 +945,7 @@ export class GoogleVertexProvider extends BaseProvider {
945
945
  // This avoids hardcoded model-specific logic and repeated config lookups
946
946
  const shouldSetMaxTokens = this.shouldSetMaxTokensCached(modelName);
947
947
  const maxTokens = shouldSetMaxTokens
948
- ? options.maxTokens || DEFAULT_MAX_TOKENS
948
+ ? options.maxTokens // No default limit
949
949
  : undefined;
950
950
  // Build complete stream options with proper typing
951
951
  let streamOptions = {
@@ -3,7 +3,6 @@ import { streamText, } from "ai";
3
3
  import { BaseProvider } from "../core/baseProvider.js";
4
4
  import { logger } from "../utils/logger.js";
5
5
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
6
- import { DEFAULT_MAX_TOKENS } from "../core/constants.js";
7
6
  import { validateApiKey, createHuggingFaceConfig, getProviderModel, } from "../utils/providerConfig.js";
8
7
  import { buildMessagesArray } from "../utils/messageBuilder.js";
9
8
  import { createProxyFetch } from "../proxy/proxyFetch.js";
@@ -120,7 +119,7 @@ export class HuggingFaceProvider extends BaseProvider {
120
119
  model: this.model,
121
120
  messages: messages,
122
121
  temperature: options.temperature,
123
- maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
122
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
124
123
  tools: streamOptions.tools, // Tools format conversion handled by prepareStreamOptions
125
124
  toolChoice: streamOptions.toolChoice, // Tool choice handled by prepareStreamOptions
126
125
  abortSignal: timeoutController?.controller.signal,
@@ -3,7 +3,6 @@ import { streamText } from "ai";
3
3
  import { BaseProvider } from "../core/baseProvider.js";
4
4
  import { logger } from "../utils/logger.js";
5
5
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
6
- import { DEFAULT_MAX_TOKENS } from "../core/constants.js";
7
6
  import { getProviderModel } from "../utils/providerConfig.js";
8
7
  import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
9
8
  import { buildMessagesArray } from "../utils/messageBuilder.js";
@@ -127,7 +126,7 @@ export class LiteLLMProvider extends BaseProvider {
127
126
  model: this.model,
128
127
  messages: messages,
129
128
  temperature: options.temperature,
130
- maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
129
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
131
130
  tools: options.tools,
132
131
  toolChoice: "auto",
133
132
  abortSignal: timeoutController?.controller.signal,
@@ -3,7 +3,7 @@ import { streamText } from "ai";
3
3
  import { BaseProvider } from "../core/baseProvider.js";
4
4
  import { logger } from "../utils/logger.js";
5
5
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
6
- import { DEFAULT_MAX_TOKENS, DEFAULT_MAX_STEPS } from "../core/constants.js";
6
+ import { DEFAULT_MAX_STEPS } from "../core/constants.js";
7
7
  import { validateApiKey, createMistralConfig, getProviderModel, } from "../utils/providerConfig.js";
8
8
  import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
9
9
  import { buildMessagesArray } from "../utils/messageBuilder.js";
@@ -54,7 +54,7 @@ export class MistralProvider extends BaseProvider {
54
54
  model: this.model,
55
55
  messages: messages,
56
56
  temperature: options.temperature,
57
- maxTokens: options.maxTokens || DEFAULT_MAX_TOKENS,
57
+ maxTokens: options.maxTokens, // No default limit - unlimited unless specified
58
58
  tools,
59
59
  maxSteps: options.maxSteps || DEFAULT_MAX_STEPS,
60
60
  toolChoice: shouldUseTools ? "auto" : "none",
@@ -1,6 +1,5 @@
1
1
  import { BaseProvider } from "../core/baseProvider.js";
2
2
  import { logger } from "../utils/logger.js";
3
- import { DEFAULT_MAX_TOKENS } from "../core/constants.js";
4
3
  import { modelConfig } from "../core/modelConfiguration.js";
5
4
  import { createProxyFetch } from "../proxy/proxyFetch.js";
6
5
  import { TimeoutError } from "../utils/timeout.js";
@@ -88,10 +87,10 @@ class OllamaLanguageModel {
88
87
  return {
89
88
  text: data.response,
90
89
  usage: {
91
- promptTokens: data.prompt_eval_count || this.estimateTokens(prompt),
92
- completionTokens: data.eval_count || this.estimateTokens(data.response),
93
- totalTokens: (data.prompt_eval_count || this.estimateTokens(prompt)) +
94
- (data.eval_count || this.estimateTokens(data.response)),
90
+ promptTokens: data.prompt_eval_count ?? this.estimateTokens(prompt),
91
+ completionTokens: data.eval_count ?? this.estimateTokens(String(data.response ?? "")),
92
+ totalTokens: (data.prompt_eval_count ?? this.estimateTokens(prompt)) +
93
+ (data.eval_count ?? this.estimateTokens(String(data.response ?? ""))),
95
94
  },
96
95
  finishReason: "stop",
97
96
  rawCall: {
@@ -271,7 +270,7 @@ export class OllamaProvider extends BaseProvider {
271
270
  * @returns true for supported models, false for unsupported models
272
271
  */
273
272
  supportsTools() {
274
- const modelName = this.modelName.toLowerCase();
273
+ const modelName = (this.modelName ?? getDefaultOllamaModel()).toLowerCase();
275
274
  // Get tool-capable models from configuration
276
275
  const ollamaConfig = modelConfig.getProviderConfiguration("ollama");
277
276
  const toolCapableModels = ollamaConfig?.modelBehavior?.toolCapableModels || [];
@@ -340,7 +339,7 @@ export class OllamaProvider extends BaseProvider {
340
339
  tool_choice: "auto",
341
340
  stream: true,
342
341
  temperature: options.temperature,
343
- max_tokens: options.maxTokens || DEFAULT_MAX_TOKENS,
342
+ max_tokens: options.maxTokens,
344
343
  }),
345
344
  signal: createAbortSignalWithTimeout(this.timeout),
346
345
  });
@@ -381,7 +380,7 @@ export class OllamaProvider extends BaseProvider {
381
380
  stream: true,
382
381
  options: {
383
382
  temperature: options.temperature,
384
- num_predict: options.maxTokens || DEFAULT_MAX_TOKENS,
383
+ num_predict: options.maxTokens,
385
384
  },
386
385
  }),
387
386
  signal: createAbortSignalWithTimeout(this.timeout),