@juspay/neurolink 7.48.1 → 7.50.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 (153) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +215 -16
  3. package/dist/agent/directTools.d.ts +55 -0
  4. package/dist/agent/directTools.js +266 -0
  5. package/dist/cli/factories/commandFactory.d.ts +6 -0
  6. package/dist/cli/factories/commandFactory.js +149 -16
  7. package/dist/cli/index.js +13 -2
  8. package/dist/cli/loop/conversationSelector.d.ts +45 -0
  9. package/dist/cli/loop/conversationSelector.js +222 -0
  10. package/dist/cli/loop/optionsSchema.d.ts +1 -1
  11. package/dist/cli/loop/session.d.ts +36 -8
  12. package/dist/cli/loop/session.js +257 -61
  13. package/dist/core/baseProvider.d.ts +9 -0
  14. package/dist/core/baseProvider.js +45 -5
  15. package/dist/core/evaluation.js +5 -2
  16. package/dist/factories/providerRegistry.js +2 -2
  17. package/dist/index.d.ts +8 -2
  18. package/dist/index.js +11 -10
  19. package/dist/lib/agent/directTools.d.ts +55 -0
  20. package/dist/lib/agent/directTools.js +266 -0
  21. package/dist/lib/core/baseProvider.d.ts +9 -0
  22. package/dist/lib/core/baseProvider.js +45 -5
  23. package/dist/lib/core/evaluation.js +5 -2
  24. package/dist/lib/factories/providerRegistry.js +2 -2
  25. package/dist/lib/index.d.ts +8 -2
  26. package/dist/lib/index.js +11 -10
  27. package/dist/lib/mcp/factory.d.ts +2 -157
  28. package/dist/lib/mcp/flexibleToolValidator.d.ts +1 -5
  29. package/dist/lib/mcp/index.d.ts +3 -2
  30. package/dist/lib/mcp/mcpCircuitBreaker.d.ts +1 -75
  31. package/dist/lib/mcp/mcpClientFactory.d.ts +1 -20
  32. package/dist/lib/mcp/mcpClientFactory.js +1 -0
  33. package/dist/lib/mcp/registry.d.ts +3 -10
  34. package/dist/lib/mcp/servers/agent/directToolsServer.d.ts +1 -1
  35. package/dist/lib/mcp/servers/aiProviders/aiCoreServer.d.ts +1 -1
  36. package/dist/lib/mcp/servers/utilities/utilityServer.d.ts +1 -1
  37. package/dist/lib/mcp/toolDiscoveryService.d.ts +3 -84
  38. package/dist/lib/mcp/toolRegistry.d.ts +2 -24
  39. package/dist/lib/middleware/builtin/guardrails.d.ts +5 -16
  40. package/dist/lib/middleware/builtin/guardrails.js +44 -39
  41. package/dist/lib/middleware/utils/guardrailsUtils.d.ts +64 -0
  42. package/dist/lib/middleware/utils/guardrailsUtils.js +387 -0
  43. package/dist/lib/neurolink.d.ts +36 -7
  44. package/dist/lib/neurolink.js +141 -0
  45. package/dist/lib/providers/anthropic.js +47 -3
  46. package/dist/lib/providers/azureOpenai.js +9 -2
  47. package/dist/lib/providers/googleAiStudio.js +9 -2
  48. package/dist/lib/providers/googleVertex.js +12 -2
  49. package/dist/lib/providers/huggingFace.js +1 -1
  50. package/dist/lib/providers/litellm.js +1 -1
  51. package/dist/lib/providers/mistral.js +1 -1
  52. package/dist/lib/providers/openAI.js +47 -3
  53. package/dist/lib/services/server/ai/observability/instrumentation.d.ts +57 -0
  54. package/dist/lib/services/server/ai/observability/instrumentation.js +170 -0
  55. package/dist/lib/session/globalSessionState.d.ts +26 -0
  56. package/dist/lib/session/globalSessionState.js +86 -1
  57. package/dist/lib/telemetry/index.d.ts +1 -0
  58. package/dist/lib/telemetry/telemetryService.d.ts +2 -0
  59. package/dist/lib/telemetry/telemetryService.js +7 -7
  60. package/dist/lib/types/cli.d.ts +28 -0
  61. package/dist/lib/types/content.d.ts +18 -5
  62. package/dist/lib/types/contextTypes.d.ts +1 -1
  63. package/dist/lib/types/conversation.d.ts +57 -4
  64. package/dist/lib/types/fileTypes.d.ts +65 -0
  65. package/dist/lib/types/fileTypes.js +4 -0
  66. package/dist/lib/types/generateTypes.d.ts +12 -0
  67. package/dist/lib/types/guardrails.d.ts +103 -0
  68. package/dist/lib/types/guardrails.js +1 -0
  69. package/dist/lib/types/index.d.ts +4 -2
  70. package/dist/lib/types/index.js +4 -0
  71. package/dist/lib/types/mcpTypes.d.ts +407 -14
  72. package/dist/lib/types/modelTypes.d.ts +6 -6
  73. package/dist/lib/types/observability.d.ts +49 -0
  74. package/dist/lib/types/observability.js +6 -0
  75. package/dist/lib/types/streamTypes.d.ts +7 -0
  76. package/dist/lib/types/tools.d.ts +132 -35
  77. package/dist/lib/utils/csvProcessor.d.ts +68 -0
  78. package/dist/lib/utils/csvProcessor.js +277 -0
  79. package/dist/lib/utils/fileDetector.d.ts +57 -0
  80. package/dist/lib/utils/fileDetector.js +457 -0
  81. package/dist/lib/utils/imageProcessor.d.ts +10 -0
  82. package/dist/lib/utils/imageProcessor.js +22 -0
  83. package/dist/lib/utils/loopUtils.d.ts +71 -0
  84. package/dist/lib/utils/loopUtils.js +262 -0
  85. package/dist/lib/utils/messageBuilder.d.ts +2 -1
  86. package/dist/lib/utils/messageBuilder.js +197 -2
  87. package/dist/lib/utils/optionsUtils.d.ts +1 -1
  88. package/dist/mcp/factory.d.ts +2 -157
  89. package/dist/mcp/flexibleToolValidator.d.ts +1 -5
  90. package/dist/mcp/index.d.ts +3 -2
  91. package/dist/mcp/mcpCircuitBreaker.d.ts +1 -75
  92. package/dist/mcp/mcpClientFactory.d.ts +1 -20
  93. package/dist/mcp/mcpClientFactory.js +1 -0
  94. package/dist/mcp/registry.d.ts +3 -10
  95. package/dist/mcp/servers/agent/directToolsServer.d.ts +1 -1
  96. package/dist/mcp/servers/aiProviders/aiCoreServer.d.ts +1 -1
  97. package/dist/mcp/servers/utilities/utilityServer.d.ts +1 -1
  98. package/dist/mcp/toolDiscoveryService.d.ts +3 -84
  99. package/dist/mcp/toolRegistry.d.ts +2 -24
  100. package/dist/middleware/builtin/guardrails.d.ts +5 -16
  101. package/dist/middleware/builtin/guardrails.js +44 -39
  102. package/dist/middleware/utils/guardrailsUtils.d.ts +64 -0
  103. package/dist/middleware/utils/guardrailsUtils.js +387 -0
  104. package/dist/neurolink.d.ts +36 -7
  105. package/dist/neurolink.js +141 -0
  106. package/dist/providers/anthropic.js +47 -3
  107. package/dist/providers/azureOpenai.js +9 -2
  108. package/dist/providers/googleAiStudio.js +9 -2
  109. package/dist/providers/googleVertex.js +12 -2
  110. package/dist/providers/huggingFace.js +1 -1
  111. package/dist/providers/litellm.js +1 -1
  112. package/dist/providers/mistral.js +1 -1
  113. package/dist/providers/openAI.js +47 -3
  114. package/dist/services/server/ai/observability/instrumentation.d.ts +57 -0
  115. package/dist/services/server/ai/observability/instrumentation.js +170 -0
  116. package/dist/session/globalSessionState.d.ts +26 -0
  117. package/dist/session/globalSessionState.js +86 -1
  118. package/dist/telemetry/index.d.ts +1 -0
  119. package/dist/telemetry/telemetryService.d.ts +2 -0
  120. package/dist/telemetry/telemetryService.js +7 -7
  121. package/dist/types/cli.d.ts +28 -0
  122. package/dist/types/content.d.ts +18 -5
  123. package/dist/types/contextTypes.d.ts +1 -1
  124. package/dist/types/conversation.d.ts +57 -4
  125. package/dist/types/fileTypes.d.ts +65 -0
  126. package/dist/types/fileTypes.js +4 -0
  127. package/dist/types/generateTypes.d.ts +12 -0
  128. package/dist/types/guardrails.d.ts +103 -0
  129. package/dist/types/guardrails.js +1 -0
  130. package/dist/types/index.d.ts +4 -2
  131. package/dist/types/index.js +4 -0
  132. package/dist/types/mcpTypes.d.ts +407 -14
  133. package/dist/types/modelTypes.d.ts +6 -6
  134. package/dist/types/observability.d.ts +49 -0
  135. package/dist/types/observability.js +6 -0
  136. package/dist/types/streamTypes.d.ts +7 -0
  137. package/dist/types/tools.d.ts +132 -35
  138. package/dist/utils/csvProcessor.d.ts +68 -0
  139. package/dist/utils/csvProcessor.js +277 -0
  140. package/dist/utils/fileDetector.d.ts +57 -0
  141. package/dist/utils/fileDetector.js +457 -0
  142. package/dist/utils/imageProcessor.d.ts +10 -0
  143. package/dist/utils/imageProcessor.js +22 -0
  144. package/dist/utils/loopUtils.d.ts +71 -0
  145. package/dist/utils/loopUtils.js +262 -0
  146. package/dist/utils/messageBuilder.d.ts +2 -1
  147. package/dist/utils/messageBuilder.js +197 -2
  148. package/dist/utils/optionsUtils.d.ts +1 -1
  149. package/package.json +18 -16
  150. package/dist/lib/mcp/contracts/mcpContract.d.ts +0 -106
  151. package/dist/lib/mcp/contracts/mcpContract.js +0 -5
  152. package/dist/mcp/contracts/mcpContract.d.ts +0 -106
  153. package/dist/mcp/contracts/mcpContract.js +0 -5
@@ -346,6 +346,61 @@ export declare const directAgentTools: {
346
346
  count?: undefined;
347
347
  }>;
348
348
  };
349
+ analyzeCSV: import("ai").Tool<z.ZodObject<{
350
+ filePath: z.ZodEffects<z.ZodString, string, string>;
351
+ operation: z.ZodEnum<["count_by_column", "sum_by_column", "average_by_column", "min_max_by_column", "describe"]>;
352
+ column: z.ZodOptional<z.ZodString>;
353
+ maxRows: z.ZodOptional<z.ZodNumber>;
354
+ }, "strip", z.ZodTypeAny, {
355
+ filePath: string;
356
+ operation: "count_by_column" | "sum_by_column" | "average_by_column" | "min_max_by_column" | "describe";
357
+ maxRows?: number | undefined;
358
+ column?: string | undefined;
359
+ }, {
360
+ filePath: string;
361
+ operation: "count_by_column" | "sum_by_column" | "average_by_column" | "min_max_by_column" | "describe";
362
+ maxRows?: number | undefined;
363
+ column?: string | undefined;
364
+ }>, {
365
+ success: boolean;
366
+ operation: "count_by_column" | "sum_by_column" | "average_by_column" | "min_max_by_column" | "describe";
367
+ column: string | undefined;
368
+ result: string;
369
+ rowCount: number;
370
+ } | {
371
+ success: boolean;
372
+ error: string;
373
+ operation?: undefined;
374
+ column?: undefined;
375
+ } | {
376
+ success: boolean;
377
+ error: string;
378
+ operation: "count_by_column" | "sum_by_column" | "average_by_column" | "min_max_by_column" | "describe";
379
+ column: string | undefined;
380
+ }> & {
381
+ execute: (args: {
382
+ filePath: string;
383
+ operation: "count_by_column" | "sum_by_column" | "average_by_column" | "min_max_by_column" | "describe";
384
+ maxRows?: number | undefined;
385
+ column?: string | undefined;
386
+ }, options: import("ai").ToolExecutionOptions) => PromiseLike<{
387
+ success: boolean;
388
+ operation: "count_by_column" | "sum_by_column" | "average_by_column" | "min_max_by_column" | "describe";
389
+ column: string | undefined;
390
+ result: string;
391
+ rowCount: number;
392
+ } | {
393
+ success: boolean;
394
+ error: string;
395
+ operation?: undefined;
396
+ column?: undefined;
397
+ } | {
398
+ success: boolean;
399
+ error: string;
400
+ operation: "count_by_column" | "sum_by_column" | "average_by_column" | "min_max_by_column" | "describe";
401
+ column: string | undefined;
402
+ }>;
403
+ };
349
404
  websearchGrounding: import("ai").Tool<z.ZodObject<{
350
405
  query: z.ZodString;
351
406
  maxResults: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
@@ -8,6 +8,7 @@ import * as fs from "fs";
8
8
  import * as path from "path";
9
9
  import { logger } from "../utils/logger.js";
10
10
  import { VertexAI } from "@google-cloud/vertexai";
11
+ import { CSVProcessor } from "../utils/csvProcessor.js";
11
12
  // Runtime Google Search tool creation - bypasses TypeScript strict typing
12
13
  function createGoogleSearchTools() {
13
14
  const searchTool = {};
@@ -336,6 +337,271 @@ export const directAgentTools = {
336
337
  }
337
338
  },
338
339
  }),
340
+ analyzeCSV: tool({
341
+ description: "Analyze CSV file for accurate counting, aggregation, and statistical analysis. Use this for precise data operations like counting rows by column, calculating sums/averages, finding min/max values, etc. The tool reads the file directly - do NOT pass CSV content.",
342
+ parameters: z.object({
343
+ filePath: z
344
+ .string()
345
+ .refine((inputPath) => {
346
+ const resolvedPath = path.resolve(inputPath);
347
+ const normalizedPath = resolvedPath
348
+ .toLowerCase()
349
+ .replace(/\\/g, "/");
350
+ const sensitivePatterns = [
351
+ "/etc/",
352
+ "/sys/",
353
+ "/proc/",
354
+ "/dev/",
355
+ "/root/",
356
+ "/.ssh/",
357
+ "/private/etc/",
358
+ "/private/var/",
359
+ "c:/windows/",
360
+ "c:/program files/",
361
+ "c:/programdata/",
362
+ ];
363
+ return !sensitivePatterns.some((pattern) => normalizedPath.startsWith(pattern));
364
+ }, {
365
+ message: "Invalid file path: access to system directories is not allowed",
366
+ })
367
+ .describe("Path to the CSV file to analyze (e.g., 'test/data.csv' or '/absolute/path/file.csv')"),
368
+ operation: z
369
+ .enum([
370
+ "count_by_column",
371
+ "sum_by_column",
372
+ "average_by_column",
373
+ "min_max_by_column",
374
+ "describe",
375
+ ])
376
+ .describe("Type of analysis to perform"),
377
+ column: z
378
+ .string()
379
+ .optional()
380
+ .describe("Column name for the operation (required for most operations)"),
381
+ maxRows: z
382
+ .number()
383
+ .optional()
384
+ .describe("Maximum rows to process (default: 1000)"),
385
+ }),
386
+ execute: async ({ filePath, operation, column, maxRows = 1000 }) => {
387
+ const startTime = Date.now();
388
+ logger.info(`[analyzeCSV] 🚀 START: file=${filePath}, operation=${operation}, column=${column}, maxRows=${maxRows}`);
389
+ try {
390
+ // Resolve file path
391
+ logger.debug(`[analyzeCSV] Resolving file: ${filePath}`);
392
+ const path = await import("path");
393
+ // Resolve path (support both relative and absolute)
394
+ const resolvedPath = path.isAbsolute(filePath)
395
+ ? filePath
396
+ : path.resolve(process.cwd(), filePath);
397
+ logger.debug(`[analyzeCSV] Resolved path: ${resolvedPath}`);
398
+ // Parse CSV using streaming from disk (memory efficient)
399
+ logger.info(`[analyzeCSV] Starting CSV parsing (max ${maxRows} rows)...`);
400
+ const rows = (await CSVProcessor.parseCSVFile(resolvedPath, maxRows));
401
+ logger.info(`[analyzeCSV] ✅ CSV parsing complete: ${rows.length} rows`);
402
+ if (rows.length === 0) {
403
+ logger.warn(`[analyzeCSV] No data rows found`);
404
+ return {
405
+ success: false,
406
+ error: "No data rows found in CSV",
407
+ };
408
+ }
409
+ // Log column names
410
+ const columnNames = rows.length > 0 ? Object.keys(rows[0]) : [];
411
+ logger.info(`[analyzeCSV] Found ${rows.length} rows with columns:`, columnNames);
412
+ logger.info(`[analyzeCSV] Executing operation: ${operation}`);
413
+ let result;
414
+ switch (operation) {
415
+ case "count_by_column": {
416
+ logger.info(`[analyzeCSV] count_by_column: column=${column}`);
417
+ if (!column) {
418
+ return {
419
+ success: false,
420
+ error: "Column name required for count_by_column operation",
421
+ };
422
+ }
423
+ // Count occurrences of each value in the column
424
+ const counts = {};
425
+ logger.debug(`[analyzeCSV] Counting rows...`);
426
+ for (const row of rows) {
427
+ const value = row[column];
428
+ if (value !== undefined) {
429
+ counts[value] = (counts[value] || 0) + 1;
430
+ }
431
+ }
432
+ logger.debug(`[analyzeCSV] Found ${Object.keys(counts).length} unique values`);
433
+ // Sort by count descending
434
+ logger.debug(`[analyzeCSV] Sorting results...`);
435
+ result = Object.fromEntries(Object.entries(counts).sort(([, a], [, b]) => b - a));
436
+ logger.info(`[analyzeCSV] ✅ count_by_column complete. Result:`, result);
437
+ break;
438
+ }
439
+ case "sum_by_column": {
440
+ logger.info(`[analyzeCSV] sum_by_column: column=${column}`);
441
+ if (!column) {
442
+ return {
443
+ success: false,
444
+ error: "Column name required for sum_by_column operation",
445
+ };
446
+ }
447
+ // Sum numeric values from the target column itself for each group
448
+ const groups = {};
449
+ logger.debug(`[analyzeCSV] Grouping and summing ${rows.length} rows...`);
450
+ let processedRows = 0;
451
+ let totalNumericValuesFound = 0;
452
+ for (const row of rows) {
453
+ const key = row[column];
454
+ if (!key) {
455
+ continue;
456
+ }
457
+ // Parse numeric value from the target column
458
+ const value = row[column];
459
+ if (value === undefined || value === null || value === "") {
460
+ continue;
461
+ }
462
+ const num = parseFloat(value);
463
+ if (isNaN(num)) {
464
+ continue;
465
+ }
466
+ if (!groups[key]) {
467
+ groups[key] = 0;
468
+ }
469
+ groups[key] += num;
470
+ totalNumericValuesFound++;
471
+ processedRows++;
472
+ if (processedRows % 10 === 0) {
473
+ logger.debug(`[analyzeCSV] Processed ${processedRows}/${rows.length} rows`);
474
+ }
475
+ }
476
+ // Fail fast if no numeric data found in the requested column
477
+ if (totalNumericValuesFound === 0) {
478
+ return {
479
+ success: false,
480
+ error: `No numeric data found in column "${column}" for sum_by_column operation`,
481
+ };
482
+ }
483
+ logger.debug(`[analyzeCSV] Calculated sums for ${Object.keys(groups).length} groups (${totalNumericValuesFound} numeric values)`);
484
+ result = groups;
485
+ logger.info(`[analyzeCSV] ✅ sum_by_column complete`);
486
+ break;
487
+ }
488
+ case "average_by_column": {
489
+ logger.info(`[analyzeCSV] average_by_column: column=${column}`);
490
+ if (!column) {
491
+ return {
492
+ success: false,
493
+ error: "Column name required for average_by_column operation",
494
+ };
495
+ }
496
+ // Average numeric values from the target column itself for each group
497
+ const groups = {};
498
+ logger.debug(`[analyzeCSV] Grouping and averaging ${rows.length} rows...`);
499
+ let processedRows = 0;
500
+ let totalNumericValuesFound = 0;
501
+ for (const row of rows) {
502
+ const key = row[column];
503
+ if (!key) {
504
+ continue;
505
+ }
506
+ // Parse numeric value from the target column
507
+ const value = row[column];
508
+ if (value === undefined || value === null || value === "") {
509
+ continue;
510
+ }
511
+ const num = parseFloat(value);
512
+ if (isNaN(num)) {
513
+ continue;
514
+ }
515
+ if (!groups[key]) {
516
+ groups[key] = { sum: 0, count: 0 };
517
+ }
518
+ groups[key].sum += num;
519
+ groups[key].count++;
520
+ totalNumericValuesFound++;
521
+ processedRows++;
522
+ if (processedRows % 10 === 0) {
523
+ logger.debug(`[analyzeCSV] Processed ${processedRows}/${rows.length} rows`);
524
+ }
525
+ }
526
+ // Fail fast if no numeric data found in the requested column
527
+ if (totalNumericValuesFound === 0) {
528
+ return {
529
+ success: false,
530
+ error: `No numeric data found in column "${column}" for average_by_column operation`,
531
+ };
532
+ }
533
+ logger.debug(`[analyzeCSV] Calculated averages for ${Object.keys(groups).length} groups (${totalNumericValuesFound} numeric values)`);
534
+ result = Object.fromEntries(Object.entries(groups).map(([k, v]) => [
535
+ k,
536
+ v.count > 0 ? v.sum / v.count : 0,
537
+ ]));
538
+ logger.info(`[analyzeCSV] ✅ average_by_column complete`);
539
+ break;
540
+ }
541
+ case "min_max_by_column": {
542
+ if (!column) {
543
+ return {
544
+ success: false,
545
+ error: "Column name required for min_max_by_column operation",
546
+ };
547
+ }
548
+ const values = rows
549
+ .map((row) => row[column])
550
+ .filter((v) => v !== undefined && v !== "");
551
+ const numericValues = values
552
+ .map((v) => parseFloat(v))
553
+ .filter((n) => !isNaN(n));
554
+ if (numericValues.length === 0) {
555
+ return {
556
+ success: false,
557
+ error: `No numeric data found in column "${column}" for min_max_by_column operation`,
558
+ };
559
+ }
560
+ result = {
561
+ min: Math.min(...numericValues),
562
+ max: Math.max(...numericValues),
563
+ numericCount: numericValues.length,
564
+ totalCount: values.length,
565
+ };
566
+ break;
567
+ }
568
+ case "describe": {
569
+ const columnNames = rows.length > 0 ? Object.keys(rows[0]) : [];
570
+ result = {
571
+ total_rows: rows.length,
572
+ columns: columnNames,
573
+ column_count: columnNames.length,
574
+ };
575
+ break;
576
+ }
577
+ default:
578
+ return {
579
+ success: false,
580
+ error: `Unknown operation: ${operation}`,
581
+ };
582
+ }
583
+ const duration = Date.now() - startTime;
584
+ logger.info(`[analyzeCSV] 🏁 COMPLETE: ${operation} took ${duration}ms`);
585
+ const response = {
586
+ success: true,
587
+ operation,
588
+ column,
589
+ result: JSON.stringify(result, null, 2),
590
+ rowCount: rows.length,
591
+ };
592
+ logger.debug(`[analyzeCSV] 📤 RETURNING TO LLM:`, JSON.stringify(response, null, 2));
593
+ return response;
594
+ }
595
+ catch (error) {
596
+ return {
597
+ success: false,
598
+ error: error instanceof Error ? error.message : String(error),
599
+ operation,
600
+ column,
601
+ };
602
+ }
603
+ },
604
+ }),
339
605
  websearchGrounding: tool({
340
606
  description: "Search the web for current information using Google Search grounding. Returns raw search data for AI processing.",
341
607
  parameters: z.object({
@@ -236,4 +236,13 @@ export declare abstract class BaseProvider implements AIProvider {
236
236
  * @returns Array of prompt chunks
237
237
  */
238
238
  static chunkPrompt(prompt: string, maxChunkSize?: number, overlap?: number): string[];
239
+ /**
240
+ * Create telemetry configuration for Vercel AI SDK experimental_telemetry
241
+ * This enables automatic OpenTelemetry tracing when telemetry is enabled
242
+ */
243
+ protected getStreamTelemetryConfig(options: StreamOptions | TextGenerationOptions, operationType?: "stream" | "generate"): {
244
+ isEnabled: boolean;
245
+ functionId?: string;
246
+ metadata?: Record<string, string | number | boolean>;
247
+ } | undefined;
239
248
  }
@@ -6,6 +6,8 @@ import { DEFAULT_MAX_STEPS, STEP_LIMITS } from "../core/constants.js";
6
6
  import { directAgentTools } from "../agent/directTools.js";
7
7
  import { getSafeMaxTokens } from "../utils/tokenLimits.js";
8
8
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
9
+ import { nanoid } from "nanoid";
10
+ import { createAnalytics } from "./analytics.js";
9
11
  import { shouldDisableBuiltinTools } from "../utils/toolUtils.js";
10
12
  import { buildMessagesArray, buildMultimodalMessagesArray, } from "../utils/messageBuilder.js";
11
13
  import { getKeysAsString, getKeyCount } from "../utils/transformationUtils.js";
@@ -98,6 +100,7 @@ export class BaseProvider {
98
100
  // Convert stream options to text generation options
99
101
  const textOptions = {
100
102
  prompt: options.input?.text || "",
103
+ input: options.input,
101
104
  systemPrompt: options.systemPrompt,
102
105
  temperature: options.temperature,
103
106
  maxTokens: options.maxTokens,
@@ -111,6 +114,7 @@ export class BaseProvider {
111
114
  evaluationDomain: options.evaluationDomain,
112
115
  toolUsageContext: options.toolUsageContext,
113
116
  context: options.context,
117
+ csvOptions: options.csvOptions,
114
118
  };
115
119
  logger.debug(`Calling generate for fake streaming`, {
116
120
  provider: this.providerName,
@@ -229,7 +233,9 @@ export class BaseProvider {
229
233
  const input = opts.input;
230
234
  const hasImages = !!input?.images?.length;
231
235
  const hasContent = !!input?.content?.length;
232
- return hasImages || hasContent;
236
+ const hasCSVFiles = !!input?.csvFiles?.length;
237
+ const hasFiles = !!input?.files?.length;
238
+ return hasImages || hasContent || hasCSVFiles || hasFiles;
233
239
  };
234
240
  let messages;
235
241
  if (hasMultimodalInput(options)) {
@@ -242,7 +248,10 @@ export class BaseProvider {
242
248
  text: options.prompt || options.input?.text || "",
243
249
  images: input?.images,
244
250
  content: input?.content,
251
+ csvFiles: input?.csvFiles,
252
+ files: input?.files,
245
253
  },
254
+ csvOptions: options.csvOptions,
246
255
  provider: options.provider,
247
256
  model: options.model,
248
257
  temperature: options.temperature,
@@ -258,7 +267,7 @@ export class BaseProvider {
258
267
  if (process.env.NEUROLINK_DEBUG === "true") {
259
268
  logger.debug("No multimodal input detected, using standard message builder");
260
269
  }
261
- messages = buildMessagesArray(options);
270
+ messages = await buildMessagesArray(options);
262
271
  }
263
272
  // Convert messages to Vercel AI SDK format
264
273
  return messages.map((msg) => {
@@ -297,6 +306,7 @@ export class BaseProvider {
297
306
  toolChoice: shouldUseTools ? "auto" : "none",
298
307
  temperature: options.temperature,
299
308
  maxTokens: options.maxTokens,
309
+ experimental_telemetry: this.getStreamTelemetryConfig(options, "generate"),
300
310
  onStepFinish: ({ toolCalls, toolResults }) => {
301
311
  logger.info("Tool execution completed", { toolResults, toolCalls });
302
312
  // Handle tool execution storage
@@ -1276,9 +1286,8 @@ export class BaseProvider {
1276
1286
  */
1277
1287
  async createStreamAnalytics(result, startTime, options) {
1278
1288
  try {
1279
- const { createAnalytics } = await import("./analytics.js");
1280
1289
  const analytics = createAnalytics(this.providerName, this.modelName, result, Date.now() - startTime, {
1281
- requestId: `${this.providerName}-stream-${Date.now()}`,
1290
+ requestId: `${this.providerName}-stream-${nanoid()}`,
1282
1291
  streamingMode: true,
1283
1292
  ...options.context,
1284
1293
  });
@@ -1511,7 +1520,7 @@ export class BaseProvider {
1511
1520
  }
1512
1521
  const sessionId = options.context?.sessionId ||
1513
1522
  options.sessionId ||
1514
- `session-${Date.now()}`;
1523
+ `session-${nanoid()}`;
1515
1524
  const userId = options.context?.userId ||
1516
1525
  options.userId;
1517
1526
  try {
@@ -1558,4 +1567,35 @@ export class BaseProvider {
1558
1567
  }
1559
1568
  return chunks;
1560
1569
  }
1570
+ /**
1571
+ * Create telemetry configuration for Vercel AI SDK experimental_telemetry
1572
+ * This enables automatic OpenTelemetry tracing when telemetry is enabled
1573
+ */
1574
+ getStreamTelemetryConfig(options, operationType = "stream") {
1575
+ // Check if telemetry is enabled via NeuroLink observability config
1576
+ if (!this.neurolink?.isTelemetryEnabled()) {
1577
+ return undefined;
1578
+ }
1579
+ const functionId = `${this.providerName}-${operationType}-${nanoid()}`;
1580
+ const metadata = {
1581
+ provider: this.providerName,
1582
+ model: this.modelName,
1583
+ toolsEnabled: !options.disableTools,
1584
+ neurolink: true,
1585
+ };
1586
+ // Add sessionId if available
1587
+ if ("sessionId" in options && options.sessionId) {
1588
+ const sessionId = options.sessionId;
1589
+ if (typeof sessionId === "string" ||
1590
+ typeof sessionId === "number" ||
1591
+ typeof sessionId === "boolean") {
1592
+ metadata.sessionId = sessionId;
1593
+ }
1594
+ }
1595
+ return {
1596
+ isEnabled: true,
1597
+ functionId,
1598
+ metadata,
1599
+ };
1600
+ }
1561
1601
  }
@@ -225,8 +225,11 @@ Completeness: [score]
225
225
  Overall: [score]
226
226
  Reasoning: [Provide a detailed explanation of your evaluation, explaining why you gave these scores. Include specific observations about the response's strengths and all possible areas for improvement.]
227
227
  `;
228
- // Generate evaluation
229
- const result = await provider.generate(prompt);
228
+ // Generate evaluation (simple text prompt only - no file processing)
229
+ const result = await provider.generate({
230
+ input: { text: prompt },
231
+ disableTools: true, // Evaluation doesn't need tools
232
+ });
230
233
  if (!result) {
231
234
  logger.debug(`[${functionTag}] No response from provider`);
232
235
  return getDefaultEvaluation("no-response", Date.now() - startTime, context);
@@ -45,9 +45,9 @@ export class ProviderRegistry {
45
45
  }, undefined, // Let provider read BEDROCK_MODEL from .env
46
46
  ["bedrock", "aws"]);
47
47
  // Register Azure OpenAI provider
48
- ProviderFactory.registerProvider(AIProviderName.AZURE, async (modelName) => {
48
+ ProviderFactory.registerProvider(AIProviderName.AZURE, async (modelName, _providerName, sdk) => {
49
49
  const { AzureOpenAIProvider } = await import("../providers/azureOpenai.js");
50
- return new AzureOpenAIProvider(modelName);
50
+ return new AzureOpenAIProvider(modelName, sdk);
51
51
  }, process.env.AZURE_MODEL ||
52
52
  process.env.AZURE_OPENAI_MODEL ||
53
53
  process.env.AZURE_OPENAI_DEPLOYMENT ||
@@ -21,6 +21,9 @@ import { NeuroLink } from "./neurolink.js";
21
21
  export { NeuroLink };
22
22
  export type { ProviderStatus, MCPStatus } from "./neurolink.js";
23
23
  export type { MCPServerInfo } from "./types/mcpTypes.js";
24
+ export type { ObservabilityConfig, LangfuseConfig, OpenTelemetryConfig, } from "./types/observability.js";
25
+ import { initializeOpenTelemetry, shutdownOpenTelemetry, flushOpenTelemetry, getLangfuseHealthStatus } from "./services/server/ai/observability/instrumentation.js";
26
+ export { initializeOpenTelemetry, shutdownOpenTelemetry, flushOpenTelemetry, getLangfuseHealthStatus, };
24
27
  export type { NeuroLinkMiddleware, MiddlewareContext, MiddlewareFactoryOptions, MiddlewarePreset, MiddlewareConfig, } from "./types/middlewareTypes.js";
25
28
  export { MiddlewareFactory } from "./middleware/factory.js";
26
29
  export declare const VERSION = "1.0.0";
@@ -82,10 +85,13 @@ export declare function createBestAIProvider(requestedProvider?: string, modelNa
82
85
  export { initializeMCPEcosystem, listMCPs, executeMCP, getMCPStats, mcpLogger, } from "./mcp/index.js";
83
86
  export type { McpMetadata, ExecutionContext, DiscoveredMcp, ToolInfo, ToolExecutionResult, LogLevel, } from "./mcp/index.js";
84
87
  export declare function initializeTelemetry(): Promise<boolean>;
85
- export declare function getTelemetryStatus(): {
88
+ export declare function getTelemetryStatus(): Promise<{
86
89
  enabled: boolean;
87
90
  initialized: boolean;
88
- };
91
+ endpoint?: string;
92
+ service?: string;
93
+ version?: string;
94
+ }>;
89
95
  export type { TextGenerationOptions, TextGenerationResult, AnalyticsData, EvaluationData, } from "./types/index.js";
90
96
  /**
91
97
  * BACKWARD COMPATIBILITY: Legacy generateText function
package/dist/lib/index.js CHANGED
@@ -19,6 +19,9 @@ export { dynamicModelProvider } from "./core/dynamicModels.js";
19
19
  // Main NeuroLink wrapper class and diagnostic types
20
20
  import { NeuroLink } from "./neurolink.js";
21
21
  export { NeuroLink };
22
+ import { initializeOpenTelemetry, shutdownOpenTelemetry, flushOpenTelemetry, getLangfuseHealthStatus, } from "./services/server/ai/observability/instrumentation.js";
23
+ import { initializeTelemetry as init, getTelemetryStatus as getStatus, } from "./telemetry/index.js";
24
+ export { initializeOpenTelemetry, shutdownOpenTelemetry, flushOpenTelemetry, getLangfuseHealthStatus, };
22
25
  export { MiddlewareFactory } from "./middleware/factory.js";
23
26
  // Version
24
27
  export const VERSION = "1.0.0";
@@ -96,20 +99,18 @@ initializeMCPEcosystem, listMCPs, executeMCP, getMCPStats, mcpLogger, } from "./
96
99
  // Real-time Services (Phase 1) - Basic SSE functionality only
97
100
  // export { createEnhancedChatService } from './chat/index.js';
98
101
  // export type * from './services/types.js';
99
- // Optional Telemetry (Phase 2) - Conditional export based on feature flag
102
+ // Optional Telemetry (Phase 2) - Telemetry service initialization
100
103
  export async function initializeTelemetry() {
101
- if (process.env.NEUROLINK_TELEMETRY_ENABLED === "true") {
102
- const { initializeTelemetry: init } = await import("./telemetry/index.js");
104
+ try {
103
105
  const result = await init();
104
- return !!result; // Convert TelemetryService to boolean
106
+ return !!result;
105
107
  }
106
- return Promise.resolve(false);
107
- }
108
- export function getTelemetryStatus() {
109
- if (process.env.NEUROLINK_TELEMETRY_ENABLED === "true") {
110
- return { enabled: true, initialized: false };
108
+ catch {
109
+ return false;
111
110
  }
112
- return { enabled: false, initialized: false };
111
+ }
112
+ export async function getTelemetryStatus() {
113
+ return getStatus();
113
114
  }
114
115
  /**
115
116
  * BACKWARD COMPATIBILITY: Legacy generateText function