@juspay/neurolink 8.26.0 → 8.27.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 (101) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +47 -25
  3. package/dist/adapters/providerImageAdapter.js +11 -0
  4. package/dist/cli/commands/config.js +16 -23
  5. package/dist/cli/commands/setup-anthropic.js +3 -26
  6. package/dist/cli/commands/setup-azure.js +3 -22
  7. package/dist/cli/commands/setup-bedrock.js +3 -26
  8. package/dist/cli/commands/setup-google-ai.js +3 -22
  9. package/dist/cli/commands/setup-mistral.js +3 -31
  10. package/dist/cli/commands/setup-openai.js +3 -22
  11. package/dist/cli/factories/commandFactory.js +32 -0
  12. package/dist/cli/factories/ollamaCommandFactory.js +5 -17
  13. package/dist/cli/loop/optionsSchema.d.ts +1 -1
  14. package/dist/cli/loop/optionsSchema.js +13 -0
  15. package/dist/config/modelSpecificPrompts.d.ts +9 -0
  16. package/dist/config/modelSpecificPrompts.js +38 -0
  17. package/dist/constants/enums.d.ts +8 -0
  18. package/dist/constants/enums.js +8 -0
  19. package/dist/constants/tokens.d.ts +25 -0
  20. package/dist/constants/tokens.js +18 -0
  21. package/dist/core/analytics.js +7 -28
  22. package/dist/core/baseProvider.js +1 -0
  23. package/dist/core/constants.d.ts +1 -0
  24. package/dist/core/constants.js +1 -0
  25. package/dist/core/modules/GenerationHandler.js +43 -5
  26. package/dist/core/streamAnalytics.d.ts +1 -0
  27. package/dist/core/streamAnalytics.js +8 -16
  28. package/dist/lib/adapters/providerImageAdapter.js +11 -0
  29. package/dist/lib/config/modelSpecificPrompts.d.ts +9 -0
  30. package/dist/lib/config/modelSpecificPrompts.js +39 -0
  31. package/dist/lib/constants/enums.d.ts +8 -0
  32. package/dist/lib/constants/enums.js +8 -0
  33. package/dist/lib/constants/tokens.d.ts +25 -0
  34. package/dist/lib/constants/tokens.js +18 -0
  35. package/dist/lib/core/analytics.js +7 -28
  36. package/dist/lib/core/baseProvider.js +1 -0
  37. package/dist/lib/core/constants.d.ts +1 -0
  38. package/dist/lib/core/constants.js +1 -0
  39. package/dist/lib/core/modules/GenerationHandler.js +43 -5
  40. package/dist/lib/core/streamAnalytics.d.ts +1 -0
  41. package/dist/lib/core/streamAnalytics.js +8 -16
  42. package/dist/lib/providers/googleAiStudio.d.ts +15 -0
  43. package/dist/lib/providers/googleAiStudio.js +659 -3
  44. package/dist/lib/providers/googleVertex.d.ts +25 -0
  45. package/dist/lib/providers/googleVertex.js +978 -3
  46. package/dist/lib/providers/sagemaker/language-model.d.ts +2 -2
  47. package/dist/lib/types/analytics.d.ts +4 -0
  48. package/dist/lib/types/cli.d.ts +16 -0
  49. package/dist/lib/types/conversation.d.ts +72 -4
  50. package/dist/lib/types/conversation.js +30 -0
  51. package/dist/lib/types/generateTypes.d.ts +135 -0
  52. package/dist/lib/types/groundingTypes.d.ts +231 -0
  53. package/dist/lib/types/groundingTypes.js +12 -0
  54. package/dist/lib/types/providers.d.ts +29 -0
  55. package/dist/lib/types/streamTypes.d.ts +54 -0
  56. package/dist/lib/utils/analyticsUtils.js +22 -2
  57. package/dist/lib/utils/errorHandling.d.ts +65 -0
  58. package/dist/lib/utils/errorHandling.js +268 -0
  59. package/dist/lib/utils/modelChoices.d.ts +82 -0
  60. package/dist/lib/utils/modelChoices.js +402 -0
  61. package/dist/lib/utils/modelDetection.d.ts +9 -0
  62. package/dist/lib/utils/modelDetection.js +81 -0
  63. package/dist/lib/utils/parameterValidation.d.ts +59 -1
  64. package/dist/lib/utils/parameterValidation.js +196 -0
  65. package/dist/lib/utils/schemaConversion.d.ts +12 -0
  66. package/dist/lib/utils/schemaConversion.js +90 -0
  67. package/dist/lib/utils/thinkingConfig.d.ts +108 -0
  68. package/dist/lib/utils/thinkingConfig.js +105 -0
  69. package/dist/lib/utils/tokenUtils.d.ts +124 -0
  70. package/dist/lib/utils/tokenUtils.js +240 -0
  71. package/dist/lib/utils/transformationUtils.js +15 -26
  72. package/dist/providers/googleAiStudio.d.ts +15 -0
  73. package/dist/providers/googleAiStudio.js +659 -3
  74. package/dist/providers/googleVertex.d.ts +25 -0
  75. package/dist/providers/googleVertex.js +978 -3
  76. package/dist/types/analytics.d.ts +4 -0
  77. package/dist/types/cli.d.ts +16 -0
  78. package/dist/types/conversation.d.ts +72 -4
  79. package/dist/types/conversation.js +30 -0
  80. package/dist/types/generateTypes.d.ts +135 -0
  81. package/dist/types/groundingTypes.d.ts +231 -0
  82. package/dist/types/groundingTypes.js +11 -0
  83. package/dist/types/providers.d.ts +29 -0
  84. package/dist/types/streamTypes.d.ts +54 -0
  85. package/dist/utils/analyticsUtils.js +22 -2
  86. package/dist/utils/errorHandling.d.ts +65 -0
  87. package/dist/utils/errorHandling.js +268 -0
  88. package/dist/utils/modelChoices.d.ts +82 -0
  89. package/dist/utils/modelChoices.js +401 -0
  90. package/dist/utils/modelDetection.d.ts +9 -0
  91. package/dist/utils/modelDetection.js +80 -0
  92. package/dist/utils/parameterValidation.d.ts +59 -1
  93. package/dist/utils/parameterValidation.js +196 -0
  94. package/dist/utils/schemaConversion.d.ts +12 -0
  95. package/dist/utils/schemaConversion.js +90 -0
  96. package/dist/utils/thinkingConfig.d.ts +108 -0
  97. package/dist/utils/thinkingConfig.js +104 -0
  98. package/dist/utils/tokenUtils.d.ts +124 -0
  99. package/dist/utils/tokenUtils.js +239 -0
  100. package/dist/utils/transformationUtils.js +15 -26
  101. package/package.json +4 -3
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Centralized token usage extraction utilities
3
+ * Handles multiple provider formats and optional fields
4
+ *
5
+ * Consolidates token extraction logic from:
6
+ * - GenerationHandler.ts
7
+ * - analytics.ts
8
+ * - streamAnalytics.ts
9
+ */
10
+ /**
11
+ * Extract input token count from various provider formats
12
+ * Priority: input > inputTokens > promptTokens
13
+ */
14
+ export function extractInputTokens(usage) {
15
+ if (typeof usage.input === "number") {
16
+ return usage.input;
17
+ }
18
+ if (typeof usage.inputTokens === "number") {
19
+ return usage.inputTokens;
20
+ }
21
+ if (typeof usage.promptTokens === "number") {
22
+ return usage.promptTokens;
23
+ }
24
+ return 0;
25
+ }
26
+ /**
27
+ * Extract output token count from various provider formats
28
+ * Priority: output > outputTokens > completionTokens
29
+ */
30
+ export function extractOutputTokens(usage) {
31
+ if (typeof usage.output === "number") {
32
+ return usage.output;
33
+ }
34
+ if (typeof usage.outputTokens === "number") {
35
+ return usage.outputTokens;
36
+ }
37
+ if (typeof usage.completionTokens === "number") {
38
+ return usage.completionTokens;
39
+ }
40
+ return 0;
41
+ }
42
+ /**
43
+ * Extract total token count from various provider formats
44
+ * Falls back to input + output if total is not provided
45
+ */
46
+ export function extractTotalTokens(usage, input, output) {
47
+ if (typeof usage.total === "number") {
48
+ return usage.total;
49
+ }
50
+ if (typeof usage.totalTokens === "number") {
51
+ return usage.totalTokens;
52
+ }
53
+ return input + output;
54
+ }
55
+ /**
56
+ * Extract reasoning/thinking token count from various provider formats
57
+ * Supports: reasoningTokens, thinkingTokens, reasoning_tokens, reasoning
58
+ */
59
+ export function extractReasoningTokens(usage) {
60
+ if (typeof usage.reasoningTokens === "number" && usage.reasoningTokens > 0) {
61
+ return usage.reasoningTokens;
62
+ }
63
+ if (typeof usage.thinkingTokens === "number" && usage.thinkingTokens > 0) {
64
+ return usage.thinkingTokens;
65
+ }
66
+ if (typeof usage.reasoning_tokens === "number" &&
67
+ usage.reasoning_tokens > 0) {
68
+ return usage.reasoning_tokens;
69
+ }
70
+ if (typeof usage.reasoning === "number" && usage.reasoning > 0) {
71
+ return usage.reasoning;
72
+ }
73
+ return undefined;
74
+ }
75
+ /**
76
+ * Extract cache creation token count from various provider formats
77
+ * Supports: cacheCreationInputTokens, cacheCreationTokens
78
+ */
79
+ export function extractCacheCreationTokens(usage) {
80
+ if (typeof usage.cacheCreationInputTokens === "number" &&
81
+ usage.cacheCreationInputTokens > 0) {
82
+ return usage.cacheCreationInputTokens;
83
+ }
84
+ if (typeof usage.cacheCreationTokens === "number" &&
85
+ usage.cacheCreationTokens > 0) {
86
+ return usage.cacheCreationTokens;
87
+ }
88
+ return undefined;
89
+ }
90
+ /**
91
+ * Extract cache read token count from various provider formats
92
+ * Supports: cacheReadInputTokens, cacheReadTokens
93
+ */
94
+ export function extractCacheReadTokens(usage) {
95
+ if (typeof usage.cacheReadInputTokens === "number" &&
96
+ usage.cacheReadInputTokens > 0) {
97
+ return usage.cacheReadInputTokens;
98
+ }
99
+ if (typeof usage.cacheReadTokens === "number" && usage.cacheReadTokens > 0) {
100
+ return usage.cacheReadTokens;
101
+ }
102
+ return undefined;
103
+ }
104
+ /**
105
+ * Calculate cache savings percentage
106
+ *
107
+ * This represents the percentage of input tokens served from cache.
108
+ * For Anthropic, cache read tokens cost 0.1x, so actual cost savings = cacheSavingsPercent * 0.9
109
+ * For other providers, cost savings may vary based on their cache pricing.
110
+ *
111
+ * @param cacheReadTokens Number of tokens read from cache
112
+ * @param inputTokens Number of non-cached input tokens
113
+ * @returns Percentage of tokens served from cache (0-100), or undefined if no cache usage
114
+ */
115
+ export function calculateCacheSavingsPercent(cacheReadTokens, inputTokens) {
116
+ if (cacheReadTokens === undefined || cacheReadTokens <= 0) {
117
+ return undefined;
118
+ }
119
+ const totalInputWithCache = inputTokens + cacheReadTokens;
120
+ if (totalInputWithCache <= 0) {
121
+ return undefined;
122
+ }
123
+ return Math.round((cacheReadTokens / totalInputWithCache) * 100);
124
+ }
125
+ /**
126
+ * Extract token usage from various provider response formats
127
+ *
128
+ * Handles multiple input formats:
129
+ * - BaseProvider normalized format (input/output/total)
130
+ * - AI SDK format (inputTokens/outputTokens/totalTokens)
131
+ * - OpenAI/Mistral format (promptTokens/completionTokens)
132
+ * - Nested usage objects
133
+ *
134
+ * Also extracts optional fields:
135
+ * - Cache creation and read tokens (Anthropic-style)
136
+ * - Reasoning/thinking tokens (OpenAI o1, Anthropic, Google)
137
+ * - Cache savings percentage
138
+ *
139
+ * @param result Raw usage object from provider response
140
+ * @param options Extraction options
141
+ * @returns Normalized TokenUsage object
142
+ */
143
+ export function extractTokenUsage(result, options = {}) {
144
+ const { calculateCacheSavings = true, missingOptionalBehavior = "undefined", } = options;
145
+ // Handle null/undefined input
146
+ if (!result) {
147
+ return { input: 0, output: 0, total: 0 };
148
+ }
149
+ // Handle nested usage object (some providers wrap usage in a usage property)
150
+ const usage = result.usage && typeof result.usage === "object" ? result.usage : result;
151
+ // Extract base token counts
152
+ const input = extractInputTokens(usage);
153
+ const output = extractOutputTokens(usage);
154
+ const total = extractTotalTokens(usage, input, output);
155
+ // Extract optional token fields
156
+ const reasoning = extractReasoningTokens(usage);
157
+ const cacheCreationTokens = extractCacheCreationTokens(usage);
158
+ const cacheReadTokens = extractCacheReadTokens(usage);
159
+ // Calculate cache savings if enabled
160
+ const cacheSavingsPercent = calculateCacheSavings
161
+ ? calculateCacheSavingsPercent(cacheReadTokens, input)
162
+ : undefined;
163
+ // Build result object
164
+ const tokenUsage = {
165
+ input,
166
+ output,
167
+ total,
168
+ };
169
+ // Add optional fields based on behavior setting
170
+ if (missingOptionalBehavior === "zero") {
171
+ tokenUsage.cacheCreationTokens = cacheCreationTokens ?? 0;
172
+ tokenUsage.cacheReadTokens = cacheReadTokens ?? 0;
173
+ tokenUsage.reasoning = reasoning ?? 0;
174
+ tokenUsage.cacheSavingsPercent = cacheSavingsPercent ?? 0;
175
+ }
176
+ else {
177
+ // Only include optional fields if they have values
178
+ if (cacheCreationTokens !== undefined) {
179
+ tokenUsage.cacheCreationTokens = cacheCreationTokens;
180
+ }
181
+ if (cacheReadTokens !== undefined) {
182
+ tokenUsage.cacheReadTokens = cacheReadTokens;
183
+ }
184
+ if (reasoning !== undefined) {
185
+ tokenUsage.reasoning = reasoning;
186
+ }
187
+ if (cacheSavingsPercent !== undefined) {
188
+ tokenUsage.cacheSavingsPercent = cacheSavingsPercent;
189
+ }
190
+ }
191
+ return tokenUsage;
192
+ }
193
+ /**
194
+ * Create a default/empty TokenUsage object
195
+ * Useful for error handling and fallback scenarios
196
+ */
197
+ export function createEmptyTokenUsage() {
198
+ return {
199
+ input: 0,
200
+ output: 0,
201
+ total: 0,
202
+ };
203
+ }
204
+ /**
205
+ * Check if a TokenUsage object has any non-zero values
206
+ */
207
+ export function hasTokenUsage(usage) {
208
+ return usage.input > 0 || usage.output > 0 || usage.total > 0;
209
+ }
210
+ /**
211
+ * Merge two TokenUsage objects by summing their values
212
+ * Useful for aggregating usage across multiple calls
213
+ */
214
+ export function mergeTokenUsage(a, b) {
215
+ const merged = {
216
+ input: a.input + b.input,
217
+ output: a.output + b.output,
218
+ total: a.total + b.total,
219
+ };
220
+ // Merge optional fields if present in either
221
+ const cacheCreationTokens = (a.cacheCreationTokens ?? 0) + (b.cacheCreationTokens ?? 0);
222
+ const cacheReadTokens = (a.cacheReadTokens ?? 0) + (b.cacheReadTokens ?? 0);
223
+ const reasoning = (a.reasoning ?? 0) + (b.reasoning ?? 0);
224
+ if (cacheCreationTokens > 0) {
225
+ merged.cacheCreationTokens = cacheCreationTokens;
226
+ }
227
+ if (cacheReadTokens > 0) {
228
+ merged.cacheReadTokens = cacheReadTokens;
229
+ }
230
+ if (reasoning > 0) {
231
+ merged.reasoning = reasoning;
232
+ }
233
+ // Recalculate cache savings for merged usage
234
+ const cacheSavingsPercent = calculateCacheSavingsPercent(merged.cacheReadTokens, merged.input);
235
+ if (cacheSavingsPercent !== undefined) {
236
+ merged.cacheSavingsPercent = cacheSavingsPercent;
237
+ }
238
+ return merged;
239
+ }
240
+ //# sourceMappingURL=tokenUtils.js.map
@@ -3,6 +3,7 @@
3
3
  * Centralizes repeated object transformation patterns to improve code reuse and maintainability
4
4
  */
5
5
  import { logger } from "./logger.js";
6
+ import { inlineJsonSchema } from "./schemaConversion.js";
6
7
  // ============================================================================
7
8
  // TOOL EXECUTION TRANSFORMATIONS
8
9
  // ============================================================================
@@ -262,42 +263,30 @@ export function transformAvailableTools(availableTools) {
262
263
  const directParameters = toolRecord.parameters;
263
264
  const fallbackSchema = toolRecord.schema;
264
265
  if (inputSchema && typeof inputSchema === "object") {
265
- if (inputSchema.$ref && inputSchema.definitions) {
266
- const definitions = inputSchema.definitions;
267
- const refValue = inputSchema.$ref;
268
- if (typeof refValue === "string") {
269
- const refKey = refValue.replace("#/definitions/", "");
270
- if (definitions[refKey] && typeof definitions[refKey] === "object") {
271
- const resolvedSchema = definitions[refKey];
272
- extractedParameters = {
273
- type: resolvedSchema.type || "object",
274
- properties: resolvedSchema.properties || {},
275
- required: resolvedSchema.required || [],
276
- ...resolvedSchema, // Include all schema metadata
277
- };
278
- }
279
- }
280
- }
281
- else if (inputSchema.properties) {
266
+ // Use shared inlineJsonSchema for recursive $ref resolution
267
+ const inlinedSchema = inlineJsonSchema(inputSchema);
268
+ if (inlinedSchema.properties) {
282
269
  extractedParameters = {
283
- type: inputSchema.type || "object",
284
- properties: inputSchema.properties,
285
- required: inputSchema.required || [],
286
- ...inputSchema,
270
+ type: inlinedSchema.type || "object",
271
+ properties: inlinedSchema.properties,
272
+ required: inlinedSchema.required || [],
273
+ ...inlinedSchema,
287
274
  };
288
275
  }
289
- else if (inputSchema.type === "object") {
290
- extractedParameters = inputSchema;
276
+ else if (inlinedSchema.type === "object") {
277
+ extractedParameters = inlinedSchema;
291
278
  }
292
279
  else {
293
- extractedParameters = inputSchema;
280
+ extractedParameters = inlinedSchema;
294
281
  }
295
282
  }
296
283
  else if (directParameters && typeof directParameters === "object") {
297
- extractedParameters = directParameters;
284
+ // Also inline $ref for direct parameters if present
285
+ extractedParameters = inlineJsonSchema(directParameters);
298
286
  }
299
287
  else if (fallbackSchema && typeof fallbackSchema === "object") {
300
- extractedParameters = fallbackSchema;
288
+ // Also inline $ref for fallback schema if present
289
+ extractedParameters = inlineJsonSchema(fallbackSchema);
301
290
  }
302
291
  if (!extractedParameters || typeof extractedParameters !== "object") {
303
292
  extractedParameters = {};
@@ -2,6 +2,7 @@ import { type Schema, type LanguageModelV1 } from "ai";
2
2
  import type { ZodUnknownSchema } from "../types/typeAliases.js";
3
3
  import { AIProviderName } from "../constants/enums.js";
4
4
  import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
5
+ import type { TextGenerationOptions, EnhancedGenerateResult } from "../types/generateTypes.js";
5
6
  import { BaseProvider } from "../core/baseProvider.js";
6
7
  /**
7
8
  * Google AI Studio provider implementation using BaseProvider
@@ -44,6 +45,20 @@ export declare class GoogleAIStudioProvider extends BaseProvider {
44
45
  getAISDKModel(): LanguageModelV1;
45
46
  handleProviderError(error: unknown): Error;
46
47
  protected executeStream(options: StreamOptions, _analysisSchema?: ZodUnknownSchema | Schema<unknown>): Promise<StreamResult>;
48
+ /**
49
+ * Execute stream using native @google/genai SDK for Gemini 3 models
50
+ * This bypasses @ai-sdk/google to properly handle thought_signature
51
+ */
52
+ private executeNativeGemini3Stream;
53
+ /**
54
+ * Execute generate using native @google/genai SDK for Gemini 3 models
55
+ * This bypasses @ai-sdk/google to properly handle thought_signature
56
+ */
57
+ private executeNativeGemini3Generate;
58
+ /**
59
+ * Override generate to route Gemini 3 models with tools to native SDK
60
+ */
61
+ generate(optionsOrPrompt: TextGenerationOptions | string): Promise<EnhancedGenerateResult | null>;
47
62
  private executeAudioStreamViaGeminiLive;
48
63
  private getApiKey;
49
64
  }