@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.
- package/CHANGELOG.md +19 -0
- package/README.md +215 -16
- package/dist/agent/directTools.d.ts +55 -0
- package/dist/agent/directTools.js +266 -0
- package/dist/cli/factories/commandFactory.d.ts +6 -0
- package/dist/cli/factories/commandFactory.js +149 -16
- package/dist/cli/index.js +13 -2
- package/dist/cli/loop/conversationSelector.d.ts +45 -0
- package/dist/cli/loop/conversationSelector.js +222 -0
- package/dist/cli/loop/optionsSchema.d.ts +1 -1
- package/dist/cli/loop/session.d.ts +36 -8
- package/dist/cli/loop/session.js +257 -61
- package/dist/core/baseProvider.d.ts +9 -0
- package/dist/core/baseProvider.js +45 -5
- package/dist/core/evaluation.js +5 -2
- package/dist/factories/providerRegistry.js +2 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +11 -10
- package/dist/lib/agent/directTools.d.ts +55 -0
- package/dist/lib/agent/directTools.js +266 -0
- package/dist/lib/core/baseProvider.d.ts +9 -0
- package/dist/lib/core/baseProvider.js +45 -5
- package/dist/lib/core/evaluation.js +5 -2
- package/dist/lib/factories/providerRegistry.js +2 -2
- package/dist/lib/index.d.ts +8 -2
- package/dist/lib/index.js +11 -10
- package/dist/lib/mcp/factory.d.ts +2 -157
- package/dist/lib/mcp/flexibleToolValidator.d.ts +1 -5
- package/dist/lib/mcp/index.d.ts +3 -2
- package/dist/lib/mcp/mcpCircuitBreaker.d.ts +1 -75
- package/dist/lib/mcp/mcpClientFactory.d.ts +1 -20
- package/dist/lib/mcp/mcpClientFactory.js +1 -0
- package/dist/lib/mcp/registry.d.ts +3 -10
- package/dist/lib/mcp/servers/agent/directToolsServer.d.ts +1 -1
- package/dist/lib/mcp/servers/aiProviders/aiCoreServer.d.ts +1 -1
- package/dist/lib/mcp/servers/utilities/utilityServer.d.ts +1 -1
- package/dist/lib/mcp/toolDiscoveryService.d.ts +3 -84
- package/dist/lib/mcp/toolRegistry.d.ts +2 -24
- package/dist/lib/middleware/builtin/guardrails.d.ts +5 -16
- package/dist/lib/middleware/builtin/guardrails.js +44 -39
- package/dist/lib/middleware/utils/guardrailsUtils.d.ts +64 -0
- package/dist/lib/middleware/utils/guardrailsUtils.js +387 -0
- package/dist/lib/neurolink.d.ts +36 -7
- package/dist/lib/neurolink.js +141 -0
- package/dist/lib/providers/anthropic.js +47 -3
- package/dist/lib/providers/azureOpenai.js +9 -2
- package/dist/lib/providers/googleAiStudio.js +9 -2
- package/dist/lib/providers/googleVertex.js +12 -2
- package/dist/lib/providers/huggingFace.js +1 -1
- package/dist/lib/providers/litellm.js +1 -1
- package/dist/lib/providers/mistral.js +1 -1
- package/dist/lib/providers/openAI.js +47 -3
- package/dist/lib/services/server/ai/observability/instrumentation.d.ts +57 -0
- package/dist/lib/services/server/ai/observability/instrumentation.js +170 -0
- package/dist/lib/session/globalSessionState.d.ts +26 -0
- package/dist/lib/session/globalSessionState.js +86 -1
- package/dist/lib/telemetry/index.d.ts +1 -0
- package/dist/lib/telemetry/telemetryService.d.ts +2 -0
- package/dist/lib/telemetry/telemetryService.js +7 -7
- package/dist/lib/types/cli.d.ts +28 -0
- package/dist/lib/types/content.d.ts +18 -5
- package/dist/lib/types/contextTypes.d.ts +1 -1
- package/dist/lib/types/conversation.d.ts +57 -4
- package/dist/lib/types/fileTypes.d.ts +65 -0
- package/dist/lib/types/fileTypes.js +4 -0
- package/dist/lib/types/generateTypes.d.ts +12 -0
- package/dist/lib/types/guardrails.d.ts +103 -0
- package/dist/lib/types/guardrails.js +1 -0
- package/dist/lib/types/index.d.ts +4 -2
- package/dist/lib/types/index.js +4 -0
- package/dist/lib/types/mcpTypes.d.ts +407 -14
- package/dist/lib/types/modelTypes.d.ts +6 -6
- package/dist/lib/types/observability.d.ts +49 -0
- package/dist/lib/types/observability.js +6 -0
- package/dist/lib/types/streamTypes.d.ts +7 -0
- package/dist/lib/types/tools.d.ts +132 -35
- package/dist/lib/utils/csvProcessor.d.ts +68 -0
- package/dist/lib/utils/csvProcessor.js +277 -0
- package/dist/lib/utils/fileDetector.d.ts +57 -0
- package/dist/lib/utils/fileDetector.js +457 -0
- package/dist/lib/utils/imageProcessor.d.ts +10 -0
- package/dist/lib/utils/imageProcessor.js +22 -0
- package/dist/lib/utils/loopUtils.d.ts +71 -0
- package/dist/lib/utils/loopUtils.js +262 -0
- package/dist/lib/utils/messageBuilder.d.ts +2 -1
- package/dist/lib/utils/messageBuilder.js +197 -2
- package/dist/lib/utils/optionsUtils.d.ts +1 -1
- package/dist/mcp/factory.d.ts +2 -157
- package/dist/mcp/flexibleToolValidator.d.ts +1 -5
- package/dist/mcp/index.d.ts +3 -2
- package/dist/mcp/mcpCircuitBreaker.d.ts +1 -75
- package/dist/mcp/mcpClientFactory.d.ts +1 -20
- package/dist/mcp/mcpClientFactory.js +1 -0
- package/dist/mcp/registry.d.ts +3 -10
- package/dist/mcp/servers/agent/directToolsServer.d.ts +1 -1
- package/dist/mcp/servers/aiProviders/aiCoreServer.d.ts +1 -1
- package/dist/mcp/servers/utilities/utilityServer.d.ts +1 -1
- package/dist/mcp/toolDiscoveryService.d.ts +3 -84
- package/dist/mcp/toolRegistry.d.ts +2 -24
- package/dist/middleware/builtin/guardrails.d.ts +5 -16
- package/dist/middleware/builtin/guardrails.js +44 -39
- package/dist/middleware/utils/guardrailsUtils.d.ts +64 -0
- package/dist/middleware/utils/guardrailsUtils.js +387 -0
- package/dist/neurolink.d.ts +36 -7
- package/dist/neurolink.js +141 -0
- package/dist/providers/anthropic.js +47 -3
- package/dist/providers/azureOpenai.js +9 -2
- package/dist/providers/googleAiStudio.js +9 -2
- package/dist/providers/googleVertex.js +12 -2
- package/dist/providers/huggingFace.js +1 -1
- package/dist/providers/litellm.js +1 -1
- package/dist/providers/mistral.js +1 -1
- package/dist/providers/openAI.js +47 -3
- package/dist/services/server/ai/observability/instrumentation.d.ts +57 -0
- package/dist/services/server/ai/observability/instrumentation.js +170 -0
- package/dist/session/globalSessionState.d.ts +26 -0
- package/dist/session/globalSessionState.js +86 -1
- package/dist/telemetry/index.d.ts +1 -0
- package/dist/telemetry/telemetryService.d.ts +2 -0
- package/dist/telemetry/telemetryService.js +7 -7
- package/dist/types/cli.d.ts +28 -0
- package/dist/types/content.d.ts +18 -5
- package/dist/types/contextTypes.d.ts +1 -1
- package/dist/types/conversation.d.ts +57 -4
- package/dist/types/fileTypes.d.ts +65 -0
- package/dist/types/fileTypes.js +4 -0
- package/dist/types/generateTypes.d.ts +12 -0
- package/dist/types/guardrails.d.ts +103 -0
- package/dist/types/guardrails.js +1 -0
- package/dist/types/index.d.ts +4 -2
- package/dist/types/index.js +4 -0
- package/dist/types/mcpTypes.d.ts +407 -14
- package/dist/types/modelTypes.d.ts +6 -6
- package/dist/types/observability.d.ts +49 -0
- package/dist/types/observability.js +6 -0
- package/dist/types/streamTypes.d.ts +7 -0
- package/dist/types/tools.d.ts +132 -35
- package/dist/utils/csvProcessor.d.ts +68 -0
- package/dist/utils/csvProcessor.js +277 -0
- package/dist/utils/fileDetector.d.ts +57 -0
- package/dist/utils/fileDetector.js +457 -0
- package/dist/utils/imageProcessor.d.ts +10 -0
- package/dist/utils/imageProcessor.js +22 -0
- package/dist/utils/loopUtils.d.ts +71 -0
- package/dist/utils/loopUtils.js +262 -0
- package/dist/utils/messageBuilder.d.ts +2 -1
- package/dist/utils/messageBuilder.js +197 -2
- package/dist/utils/optionsUtils.d.ts +1 -1
- package/package.json +18 -16
- package/dist/lib/mcp/contracts/mcpContract.d.ts +0 -106
- package/dist/lib/mcp/contracts/mcpContract.js +0 -5
- package/dist/mcp/contracts/mcpContract.d.ts +0 -106
- 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
|
-
|
|
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-${
|
|
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-${
|
|
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(
|
|
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 ||
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -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) -
|
|
102
|
+
// Optional Telemetry (Phase 2) - Telemetry service initialization
|
|
100
103
|
export async function initializeTelemetry() {
|
|
101
|
-
|
|
102
|
-
const { initializeTelemetry: init } = await import("./telemetry/index.js");
|
|
104
|
+
try {
|
|
103
105
|
const result = await init();
|
|
104
|
-
return !!result;
|
|
106
|
+
return !!result;
|
|
105
107
|
}
|
|
106
|
-
|
|
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
|
-
|
|
111
|
+
}
|
|
112
|
+
export async function getTelemetryStatus() {
|
|
113
|
+
return getStatus();
|
|
113
114
|
}
|
|
114
115
|
/**
|
|
115
116
|
* BACKWARD COMPATIBILITY: Legacy generateText function
|