@juspay/neurolink 9.56.1 → 9.57.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 +12 -0
- package/dist/auth/AuthProviderFactory.d.ts +3 -3
- package/dist/auth/providers/BaseAuthProvider.d.ts +2 -2
- package/dist/auth/providers/BaseAuthProvider.js +1 -1
- package/dist/auth/serverBridge.d.ts +2 -2
- package/dist/browser/neurolink.min.js +306 -306
- package/dist/cli/factories/commandFactory.js +32 -8
- package/dist/cli/loop/optionsSchema.js +4 -0
- package/dist/cli/parser.js +3 -3
- package/dist/dynamic/dynamicResolver.d.ts +282 -0
- package/dist/dynamic/dynamicResolver.js +633 -0
- package/dist/dynamic/index.d.ts +10 -0
- package/dist/dynamic/index.js +12 -0
- package/dist/dynamic/resolution.d.ts +17 -0
- package/dist/dynamic/resolution.js +21 -0
- package/dist/evaluation/index.js +1 -1
- package/dist/files/fileReferenceRegistry.js +25 -10
- package/dist/index.js +19 -2
- package/dist/lib/auth/AuthProviderFactory.d.ts +3 -3
- package/dist/lib/auth/providers/BaseAuthProvider.d.ts +2 -2
- package/dist/lib/auth/providers/BaseAuthProvider.js +1 -1
- package/dist/lib/auth/serverBridge.d.ts +2 -2
- package/dist/lib/dynamic/dynamicResolver.d.ts +282 -0
- package/dist/lib/dynamic/dynamicResolver.js +634 -0
- package/dist/lib/dynamic/index.d.ts +10 -0
- package/dist/lib/dynamic/index.js +13 -0
- package/dist/lib/dynamic/resolution.d.ts +17 -0
- package/dist/lib/dynamic/resolution.js +22 -0
- package/dist/lib/evaluation/index.js +1 -1
- package/dist/lib/files/fileReferenceRegistry.js +25 -10
- package/dist/lib/index.js +19 -2
- package/dist/lib/mcp/mcpServerBase.d.ts +1 -1
- package/dist/lib/mcp/mcpServerBase.js +1 -1
- package/dist/lib/neurolink.d.ts +12 -4
- package/dist/lib/neurolink.js +79 -6
- package/dist/lib/observability/exporters/baseExporter.d.ts +1 -1
- package/dist/lib/observability/exporters/baseExporter.js +1 -1
- package/dist/lib/types/auth.d.ts +6 -6
- package/dist/lib/types/config.d.ts +4 -4
- package/dist/lib/types/dynamic.d.ts +98 -0
- package/dist/lib/types/dynamic.js +10 -0
- package/dist/lib/types/file.d.ts +10 -0
- package/dist/lib/types/fileReference.d.ts +9 -0
- package/dist/lib/types/generate.d.ts +29 -0
- package/dist/lib/types/index.d.ts +1 -0
- package/dist/lib/types/index.js +2 -0
- package/dist/lib/types/scorer.d.ts +1 -1
- package/dist/lib/types/scorer.js +1 -1
- package/dist/lib/types/span.d.ts +1 -1
- package/dist/lib/types/span.js +1 -1
- package/dist/lib/types/stream.d.ts +6 -0
- package/dist/lib/utils/fileDetector.d.ts +7 -0
- package/dist/lib/utils/fileDetector.js +47 -0
- package/dist/lib/utils/messageBuilder.js +15 -1
- package/dist/lib/utils/mimeTypeHints.d.ts +40 -0
- package/dist/lib/utils/mimeTypeHints.js +122 -0
- package/dist/mcp/mcpServerBase.d.ts +1 -1
- package/dist/mcp/mcpServerBase.js +1 -1
- package/dist/neurolink.d.ts +12 -4
- package/dist/neurolink.js +79 -6
- package/dist/observability/exporters/baseExporter.d.ts +1 -1
- package/dist/observability/exporters/baseExporter.js +1 -1
- package/dist/types/auth.d.ts +6 -6
- package/dist/types/config.d.ts +4 -4
- package/dist/types/dynamic.d.ts +98 -0
- package/dist/types/dynamic.js +9 -0
- package/dist/types/file.d.ts +10 -0
- package/dist/types/fileReference.d.ts +9 -0
- package/dist/types/generate.d.ts +29 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/scorer.d.ts +1 -1
- package/dist/types/scorer.js +1 -1
- package/dist/types/span.d.ts +1 -1
- package/dist/types/span.js +1 -1
- package/dist/types/stream.d.ts +6 -0
- package/dist/utils/fileDetector.d.ts +7 -0
- package/dist/utils/fileDetector.js +47 -0
- package/dist/utils/messageBuilder.js +15 -1
- package/dist/utils/mimeTypeHints.d.ts +40 -0
- package/dist/utils/mimeTypeHints.js +121 -0
- package/package.json +1 -1
package/dist/lib/types/scorer.js
CHANGED
package/dist/lib/types/span.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
6
|
* Span types for AI operations
|
|
7
|
-
* Following
|
|
7
|
+
* Following OTel GenAI conventions for span categorization
|
|
8
8
|
*/
|
|
9
9
|
export declare enum SpanType {
|
|
10
10
|
/** Agent execution run (reserved for future multi-agent support) */
|
package/dist/lib/types/span.js
CHANGED
|
@@ -330,6 +330,12 @@ export type StreamOptions = {
|
|
|
330
330
|
} | undefined>;
|
|
331
331
|
/** Include only these tools by name (whitelist). If set, only matching tools are available. */
|
|
332
332
|
toolFilter?: string[];
|
|
333
|
+
/**
|
|
334
|
+
* Filter available tools by name.
|
|
335
|
+
* Used by dynamic arguments to dynamically select which tools to enable.
|
|
336
|
+
* Merged into `toolFilter` before tool filtering runs.
|
|
337
|
+
*/
|
|
338
|
+
enabledToolNames?: string[];
|
|
333
339
|
/** Exclude these tools by name (blacklist). Applied after toolFilter. */
|
|
334
340
|
excludeTools?: string[];
|
|
335
341
|
/** Disable tool result caching for this request (overrides global mcp.cache.enabled) */
|
|
@@ -43,6 +43,13 @@ export declare class FileDetector {
|
|
|
43
43
|
* Derive byte size from FileInput for tracing.
|
|
44
44
|
*/
|
|
45
45
|
private static deriveInputSize;
|
|
46
|
+
/**
|
|
47
|
+
* Classify a FileInput into the FileSource enum used by downstream
|
|
48
|
+
* loaders. Keeps the mimetype-hint short-circuit in detect() able to
|
|
49
|
+
* produce a valid FileDetectionResult without re-implementing the
|
|
50
|
+
* source-inference rules scattered across loadContent().
|
|
51
|
+
*/
|
|
52
|
+
private static deriveInputSource;
|
|
46
53
|
/**
|
|
47
54
|
* Try fallback parsing for a specific file type
|
|
48
55
|
* Used when file detection returns "unknown" but we want to try parsing anyway
|
|
@@ -23,6 +23,7 @@ import { tracers, ATTR, withSpan } from "../telemetry/index.js";
|
|
|
23
23
|
import { CSVProcessor } from "./csvProcessor.js";
|
|
24
24
|
import { ImageProcessor } from "./imageProcessor.js";
|
|
25
25
|
import { logger } from "./logger.js";
|
|
26
|
+
import { mimeHintToExtension, mimeHintToFileType, normalizeMimeHint, } from "./mimeTypeHints.js";
|
|
26
27
|
import { PDFProcessor } from "./pdfProcessor.js";
|
|
27
28
|
/**
|
|
28
29
|
* Default retry configuration constants
|
|
@@ -320,6 +321,27 @@ export class FileDetector {
|
|
|
320
321
|
}
|
|
321
322
|
return 0;
|
|
322
323
|
}
|
|
324
|
+
/**
|
|
325
|
+
* Classify a FileInput into the FileSource enum used by downstream
|
|
326
|
+
* loaders. Keeps the mimetype-hint short-circuit in detect() able to
|
|
327
|
+
* produce a valid FileDetectionResult without re-implementing the
|
|
328
|
+
* source-inference rules scattered across loadContent().
|
|
329
|
+
*/
|
|
330
|
+
static deriveInputSource(input) {
|
|
331
|
+
if (Buffer.isBuffer(input)) {
|
|
332
|
+
return "buffer";
|
|
333
|
+
}
|
|
334
|
+
if (typeof input === "string") {
|
|
335
|
+
if (input.startsWith("data:")) {
|
|
336
|
+
return "datauri";
|
|
337
|
+
}
|
|
338
|
+
if (input.startsWith("http://") || input.startsWith("https://")) {
|
|
339
|
+
return "url";
|
|
340
|
+
}
|
|
341
|
+
return "path";
|
|
342
|
+
}
|
|
343
|
+
return "buffer";
|
|
344
|
+
}
|
|
323
345
|
/**
|
|
324
346
|
* Try fallback parsing for a specific file type
|
|
325
347
|
* Used when file detection returns "unknown" but we want to try parsing anyway
|
|
@@ -520,6 +542,31 @@ export class FileDetector {
|
|
|
520
542
|
* Stops at first strategy with confidence >= threshold (default: 80%)
|
|
521
543
|
*/
|
|
522
544
|
static async detect(input, options) {
|
|
545
|
+
// Short-circuit on a trustworthy caller-provided mimetype hint. This is
|
|
546
|
+
// the eager-path counterpart to FileReferenceRegistry.register()'s hint
|
|
547
|
+
// handling — necessary for tiny files (<= TINY_MAX) that skip the lazy
|
|
548
|
+
// registry path. normalizeMimeHint drops "application/octet-stream" so a
|
|
549
|
+
// caller cannot hide real content behind the opaque sentinel.
|
|
550
|
+
const hintMime = normalizeMimeHint(options?.mimetypeHint);
|
|
551
|
+
if (hintMime) {
|
|
552
|
+
const type = mimeHintToFileType(hintMime);
|
|
553
|
+
if (type) {
|
|
554
|
+
const ext = mimeHintToExtension(hintMime);
|
|
555
|
+
const result = {
|
|
556
|
+
type,
|
|
557
|
+
mimeType: hintMime,
|
|
558
|
+
extension: ext || null,
|
|
559
|
+
source: FileDetector.deriveInputSource(input),
|
|
560
|
+
metadata: {
|
|
561
|
+
confidence: 95,
|
|
562
|
+
filename: FileDetector.deriveInputFilename(input),
|
|
563
|
+
size: FileDetector.deriveInputSize(input),
|
|
564
|
+
},
|
|
565
|
+
};
|
|
566
|
+
logger.info(`[FileDetector] Type: ${type} (95%, from mimetype hint: ${hintMime})`);
|
|
567
|
+
return result;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
523
570
|
const confidenceThreshold = options?.confidenceThreshold ?? 80;
|
|
524
571
|
const strategies = [
|
|
525
572
|
new MagicBytesStrategy(),
|
|
@@ -554,6 +554,7 @@ export async function buildMessagesArray(options) {
|
|
|
554
554
|
maxSize: 50 * 1024 * 1024,
|
|
555
555
|
allowedTypes: ["csv"],
|
|
556
556
|
csvOptions: csvOptions,
|
|
557
|
+
mimetypeHint: isFileWithMetadata(file) ? file.mimetype : undefined,
|
|
557
558
|
});
|
|
558
559
|
if (result.type === "csv") {
|
|
559
560
|
let csvSection = `\n\n## CSV Data from "${filename}":\n`;
|
|
@@ -806,6 +807,12 @@ async function processUnifiedFilesArray(options, maxSize, provider) {
|
|
|
806
807
|
// ─── Full processing path (current behavior) ──────────────────
|
|
807
808
|
const genericFileMaxSize = Math.max(maxSize, 100 * 1024 * 1024);
|
|
808
809
|
const rawFileInput = isFileWithMetadata(file) ? file.buffer : file;
|
|
810
|
+
// Forward the caller's mimetype hint (Slack/Curator-style
|
|
811
|
+
// extension-less buffers) so the eager path classifies correctly
|
|
812
|
+
// for tiny files — the lazy registry path has its own hint wiring.
|
|
813
|
+
const fileMimetypeHint = isFileWithMetadata(file)
|
|
814
|
+
? file.mimetype
|
|
815
|
+
: undefined;
|
|
809
816
|
const result = await FileDetector.detectAndProcess(rawFileInput, {
|
|
810
817
|
maxSize: genericFileMaxSize,
|
|
811
818
|
allowedTypes: [
|
|
@@ -824,6 +831,7 @@ async function processUnifiedFilesArray(options, maxSize, provider) {
|
|
|
824
831
|
],
|
|
825
832
|
csvOptions: options.csvOptions,
|
|
826
833
|
provider: provider,
|
|
834
|
+
mimetypeHint: fileMimetypeHint,
|
|
827
835
|
});
|
|
828
836
|
appendDetectedFileResult(result, file, options);
|
|
829
837
|
includedCount++;
|
|
@@ -1658,7 +1666,13 @@ async function tryRegisterFileReference(file, fileSize, registry, index = 0) {
|
|
|
1658
1666
|
return false;
|
|
1659
1667
|
}
|
|
1660
1668
|
const filename = extractFilename(file, index);
|
|
1661
|
-
|
|
1669
|
+
const mimetype = typeof file === "object" && !Buffer.isBuffer(file)
|
|
1670
|
+
? file.mimetype
|
|
1671
|
+
: undefined;
|
|
1672
|
+
await registry.register(buffer, getFileSource(file), {
|
|
1673
|
+
filename,
|
|
1674
|
+
mimetype,
|
|
1675
|
+
});
|
|
1662
1676
|
logger.info(`[FileDetector] Registered "${filename}" (${(fileSize / 1024).toFixed(0)} KB) ` +
|
|
1663
1677
|
`as lazy reference — skipping upfront processing`);
|
|
1664
1678
|
return true;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for caller-provided MIME type hints.
|
|
3
|
+
*
|
|
4
|
+
* A "MIME hint" is a mimetype string the SDK receives alongside a raw Buffer
|
|
5
|
+
* whose original filename is missing (e.g. Slack/Curator file-uploads that
|
|
6
|
+
* arrive as { buffer, filename: "Untitled", mimetype: "text/plain" }). When
|
|
7
|
+
* the filename has no extension and magic-byte detection cannot identify the
|
|
8
|
+
* content, the hint is the only signal we have.
|
|
9
|
+
*
|
|
10
|
+
* Both FileReferenceRegistry.register() and FileDetector.detect() consume
|
|
11
|
+
* these helpers so the trust/normalization rules stay in one place:
|
|
12
|
+
*
|
|
13
|
+
* - `application/octet-stream` is never trusted — it is the opaque
|
|
14
|
+
* "I don't know" sentinel and would let a caller hide real content
|
|
15
|
+
* behind a generic label (a PNG hinted as octet-stream would otherwise
|
|
16
|
+
* record mimeType="application/octet-stream" instead of "image/png").
|
|
17
|
+
* - Empty/undefined hints pass through as `undefined`.
|
|
18
|
+
* - A hint that cannot be classified maps to `null` so the caller falls
|
|
19
|
+
* back to magic-byte / extension detection instead of synthesising a
|
|
20
|
+
* wrong type.
|
|
21
|
+
*/
|
|
22
|
+
import type { FileType } from "../types/index.js";
|
|
23
|
+
/**
|
|
24
|
+
* Normalize a caller-provided mimetype hint: strip any `;charset=...`
|
|
25
|
+
* parameter, lowercase, trim. Returns undefined for empty strings or for
|
|
26
|
+
* the opaque `application/octet-stream` sentinel so downstream code can
|
|
27
|
+
* treat the hint as absent instead of trusting it verbatim.
|
|
28
|
+
*/
|
|
29
|
+
export declare function normalizeMimeHint(raw?: string): string | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Map a normalized mimetype hint to a NeuroLink FileType. Returns null when
|
|
32
|
+
* the mimetype is unknown or too generic to classify confidently.
|
|
33
|
+
*/
|
|
34
|
+
export declare function mimeHintToFileType(mimetype: string): FileType | null;
|
|
35
|
+
/**
|
|
36
|
+
* Map a normalized mimetype hint to the canonical file extension (without
|
|
37
|
+
* leading dot). Returns "" when the mimetype is unknown — caller should
|
|
38
|
+
* then fall back to magic-byte detection.
|
|
39
|
+
*/
|
|
40
|
+
export declare function mimeHintToExtension(mimetype: string): string;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
const OPAQUE_MIMETYPE = "application/octet-stream";
|
|
2
|
+
/**
|
|
3
|
+
* Normalize a caller-provided mimetype hint: strip any `;charset=...`
|
|
4
|
+
* parameter, lowercase, trim. Returns undefined for empty strings or for
|
|
5
|
+
* the opaque `application/octet-stream` sentinel so downstream code can
|
|
6
|
+
* treat the hint as absent instead of trusting it verbatim.
|
|
7
|
+
*/
|
|
8
|
+
export function normalizeMimeHint(raw) {
|
|
9
|
+
if (!raw) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
const cleaned = raw.split(";")[0].trim().toLowerCase();
|
|
13
|
+
if (!cleaned || cleaned === OPAQUE_MIMETYPE) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
return cleaned;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Map a normalized mimetype hint to a NeuroLink FileType. Returns null when
|
|
20
|
+
* the mimetype is unknown or too generic to classify confidently.
|
|
21
|
+
*/
|
|
22
|
+
export function mimeHintToFileType(mimetype) {
|
|
23
|
+
const exact = {
|
|
24
|
+
"text/csv": "csv",
|
|
25
|
+
"application/csv": "csv",
|
|
26
|
+
"image/svg+xml": "svg",
|
|
27
|
+
"application/pdf": "pdf",
|
|
28
|
+
"application/json": "text",
|
|
29
|
+
"application/xml": "text",
|
|
30
|
+
"text/xml": "text",
|
|
31
|
+
"application/yaml": "text",
|
|
32
|
+
"application/x-yaml": "text",
|
|
33
|
+
"text/yaml": "text",
|
|
34
|
+
"application/javascript": "text",
|
|
35
|
+
"application/typescript": "text",
|
|
36
|
+
"application/zip": "archive",
|
|
37
|
+
"application/x-tar": "archive",
|
|
38
|
+
"application/gzip": "archive",
|
|
39
|
+
"application/x-gzip": "archive",
|
|
40
|
+
"application/x-7z-compressed": "archive",
|
|
41
|
+
"application/vnd.rar": "archive",
|
|
42
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
|
|
43
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx",
|
|
44
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
|
|
45
|
+
};
|
|
46
|
+
if (exact[mimetype]) {
|
|
47
|
+
return exact[mimetype];
|
|
48
|
+
}
|
|
49
|
+
if (mimetype.startsWith("text/")) {
|
|
50
|
+
return "text";
|
|
51
|
+
}
|
|
52
|
+
if (mimetype.startsWith("image/")) {
|
|
53
|
+
return "image";
|
|
54
|
+
}
|
|
55
|
+
if (mimetype.startsWith("audio/")) {
|
|
56
|
+
return "audio";
|
|
57
|
+
}
|
|
58
|
+
if (mimetype.startsWith("video/")) {
|
|
59
|
+
return "video";
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Map a normalized mimetype hint to the canonical file extension (without
|
|
65
|
+
* leading dot). Returns "" when the mimetype is unknown — caller should
|
|
66
|
+
* then fall back to magic-byte detection.
|
|
67
|
+
*/
|
|
68
|
+
export function mimeHintToExtension(mimetype) {
|
|
69
|
+
const table = {
|
|
70
|
+
// Text
|
|
71
|
+
"text/plain": "txt",
|
|
72
|
+
"text/html": "html",
|
|
73
|
+
"text/css": "css",
|
|
74
|
+
"text/javascript": "js",
|
|
75
|
+
"application/javascript": "js",
|
|
76
|
+
"application/typescript": "ts",
|
|
77
|
+
"text/markdown": "md",
|
|
78
|
+
"text/csv": "csv",
|
|
79
|
+
"application/csv": "csv",
|
|
80
|
+
"application/json": "json",
|
|
81
|
+
"application/xml": "xml",
|
|
82
|
+
"text/xml": "xml",
|
|
83
|
+
"application/yaml": "yaml",
|
|
84
|
+
"application/x-yaml": "yaml",
|
|
85
|
+
"text/yaml": "yaml",
|
|
86
|
+
// Documents
|
|
87
|
+
"application/pdf": "pdf",
|
|
88
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
|
|
89
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx",
|
|
90
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
|
|
91
|
+
// Images
|
|
92
|
+
"image/png": "png",
|
|
93
|
+
"image/jpeg": "jpg",
|
|
94
|
+
"image/gif": "gif",
|
|
95
|
+
"image/webp": "webp",
|
|
96
|
+
"image/bmp": "bmp",
|
|
97
|
+
"image/tiff": "tiff",
|
|
98
|
+
"image/svg+xml": "svg",
|
|
99
|
+
// Video
|
|
100
|
+
"video/mp4": "mp4",
|
|
101
|
+
"video/webm": "webm",
|
|
102
|
+
"video/quicktime": "mov",
|
|
103
|
+
"video/x-matroska": "mkv",
|
|
104
|
+
"video/x-msvideo": "avi",
|
|
105
|
+
// Audio
|
|
106
|
+
"audio/mpeg": "mp3",
|
|
107
|
+
"audio/wav": "wav",
|
|
108
|
+
"audio/ogg": "ogg",
|
|
109
|
+
"audio/flac": "flac",
|
|
110
|
+
"audio/mp4": "m4a",
|
|
111
|
+
"audio/aac": "aac",
|
|
112
|
+
// Archives
|
|
113
|
+
"application/zip": "zip",
|
|
114
|
+
"application/x-tar": "tar",
|
|
115
|
+
"application/gzip": "gz",
|
|
116
|
+
"application/x-gzip": "gz",
|
|
117
|
+
"application/x-7z-compressed": "7z",
|
|
118
|
+
"application/vnd.rar": "rar",
|
|
119
|
+
};
|
|
120
|
+
return table[mimetype] || "";
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=mimeTypeHints.js.map
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Abstract base class for creating custom MCP servers with consistent patterns
|
|
5
5
|
* for tool registration, execution, and lifecycle management.
|
|
6
6
|
*
|
|
7
|
-
* Implements
|
|
7
|
+
* Implements MCPServerBase features including:
|
|
8
8
|
* - Tool annotation support (readOnlyHint, destructiveHint, idempotentHint)
|
|
9
9
|
* - Lifecycle hooks (onInit, onStart, onStop)
|
|
10
10
|
* - Event emission for tool operations
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Abstract base class for creating custom MCP servers with consistent patterns
|
|
5
5
|
* for tool registration, execution, and lifecycle management.
|
|
6
6
|
*
|
|
7
|
-
* Implements
|
|
7
|
+
* Implements MCPServerBase features including:
|
|
8
8
|
* - Tool annotation support (readOnlyHint, destructiveHint, idempotentHint)
|
|
9
9
|
* - Lifecycle hooks (onInit, onStart, onStop)
|
|
10
10
|
* - Event emission for tool operations
|
package/dist/neurolink.d.ts
CHANGED
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
* Enhanced AI provider system with natural MCP tool access.
|
|
6
6
|
* Uses real MCP infrastructure for tool discovery and execution.
|
|
7
7
|
*/
|
|
8
|
-
import type { CompactionConfig, CompactionResult, SpanData, ObservabilityConfig, MetricsSummary, MCPToolAnnotations, TraceView, AuthenticatedContext,
|
|
8
|
+
import type { CompactionConfig, CompactionResult, SpanData, ObservabilityConfig, MetricsSummary, MCPToolAnnotations, TraceView, AuthenticatedContext, AuthProvider, JsonObject, NeuroLinkEvents, TypedEventEmitter, MCPEnhancementsConfig, NeuroLinkAuthConfig, NeurolinkConstructorConfig, ChatMessage, ExternalMCPOperationResult, ExternalMCPServerInstance, ExternalMCPToolInfo, GenerateOptions, GenerateResult, ProviderStatus, TextGenerationOptions, TextGenerationResult, MCPExecutableTool, MCPServerInfo, MCPStatus, StreamOptions, StreamResult, ToolExecutionContext, ToolExecutionSummary, ToolInfo, ToolRegistrationOptions, BatchOperationResult } from "./types/index.js";
|
|
9
9
|
import { ConversationMemoryManager } from "./core/conversationMemoryManager.js";
|
|
10
10
|
import type { RedisConversationMemoryManager } from "./core/redisConversationMemoryManager.js";
|
|
11
11
|
import { ExternalServerManager } from "./mcp/externalServerManager.js";
|
|
12
12
|
import { MCPToolRegistry } from "./mcp/toolRegistry.js";
|
|
13
|
+
import type { DynamicOptions } from "./types/index.js";
|
|
13
14
|
import { TaskManager } from "./tasks/taskManager.js";
|
|
14
15
|
export declare class NeuroLink {
|
|
15
16
|
private mcpInitialized;
|
|
@@ -539,7 +540,7 @@ export declare class NeuroLink {
|
|
|
539
540
|
* @see {@link stream} for streaming generation
|
|
540
541
|
* @since 1.0.0
|
|
541
542
|
*/
|
|
542
|
-
generate(optionsOrPrompt: GenerateOptions | string): Promise<GenerateResult>;
|
|
543
|
+
generate(optionsOrPrompt: GenerateOptions | DynamicOptions | string): Promise<GenerateResult>;
|
|
543
544
|
private executeGenerateWithMetricsContext;
|
|
544
545
|
private executeGenerateRequest;
|
|
545
546
|
private prepareGenerateRequest;
|
|
@@ -695,7 +696,7 @@ export declare class NeuroLink {
|
|
|
695
696
|
* @throws {Error} When all providers fail to generate content
|
|
696
697
|
* @throws {Error} When conversation memory operations fail (if enabled)
|
|
697
698
|
*/
|
|
698
|
-
stream(options: StreamOptions): Promise<StreamResult>;
|
|
699
|
+
stream(options: StreamOptions | DynamicOptions): Promise<StreamResult>;
|
|
699
700
|
private executeStreamRequest;
|
|
700
701
|
private validateStreamRequestOptions;
|
|
701
702
|
private maybeHandleWorkflowStreamRequest;
|
|
@@ -1959,7 +1960,7 @@ export declare class NeuroLink {
|
|
|
1959
1960
|
/**
|
|
1960
1961
|
* Get the currently configured authentication provider
|
|
1961
1962
|
*/
|
|
1962
|
-
getAuthProvider():
|
|
1963
|
+
getAuthProvider(): AuthProvider | undefined;
|
|
1963
1964
|
/**
|
|
1964
1965
|
* Lazily initialize the auth provider from pendingAuthConfig.
|
|
1965
1966
|
* Called on first use (generate/stream with auth token) to avoid
|
|
@@ -1993,6 +1994,13 @@ export declare class NeuroLink {
|
|
|
1993
1994
|
* @returns The ExternalServerManager instance
|
|
1994
1995
|
*/
|
|
1995
1996
|
getExternalServerManager(): ExternalServerManager;
|
|
1997
|
+
private buildResolutionContext;
|
|
1998
|
+
/**
|
|
1999
|
+
* Resolve dynamic arguments in GenerateOptions, mutating the options in place.
|
|
2000
|
+
* Only resolves fields that are functions; static values pass through unchanged.
|
|
2001
|
+
*/
|
|
2002
|
+
private resolveDynamicOptions;
|
|
2003
|
+
private resolveDynamicFields;
|
|
1996
2004
|
}
|
|
1997
2005
|
export declare const neurolink: NeuroLink;
|
|
1998
2006
|
export default neurolink;
|
package/dist/neurolink.js
CHANGED
|
@@ -47,6 +47,8 @@ import { ToolRouter } from "./mcp/routing/index.js";
|
|
|
47
47
|
import { directToolsServer } from "./mcp/servers/agent/directToolsServer.js";
|
|
48
48
|
import { inferAnnotations, isSafeToRetry } from "./mcp/toolAnnotations.js";
|
|
49
49
|
import { MCPToolRegistry } from "./mcp/toolRegistry.js";
|
|
50
|
+
// Dynamic argument resolution imports
|
|
51
|
+
import { resolveDynamicArgument } from "./dynamic/dynamicResolver.js";
|
|
50
52
|
import { initializeHippocampus } from "./memory/hippocampusInitializer.js";
|
|
51
53
|
import { createMemoryRetrievalTools } from "./memory/memoryRetrievalTools.js";
|
|
52
54
|
import { getMetricsAggregator, MetricsAggregator, } from "./observability/metricsAggregator.js";
|
|
@@ -2658,8 +2660,10 @@ Current user's request: ${currentInput}`;
|
|
|
2658
2660
|
return metricsTraceContextStorage.run(this.createMetricsTraceContext(), () => this.executeGenerateRequest(optionsOrPrompt, generateSpan));
|
|
2659
2661
|
}
|
|
2660
2662
|
async executeGenerateRequest(optionsOrPrompt, generateSpan) {
|
|
2663
|
+
let resolvedOptions;
|
|
2661
2664
|
try {
|
|
2662
2665
|
const { options, originalPrompt } = await this.prepareGenerateRequest(optionsOrPrompt, generateSpan);
|
|
2666
|
+
resolvedOptions = options;
|
|
2663
2667
|
const earlyResult = await this.maybeHandleEarlyGenerateResult(options, generateSpan);
|
|
2664
2668
|
if (earlyResult) {
|
|
2665
2669
|
generateSpan.setStatus({ code: SpanStatusCode.OK });
|
|
@@ -2680,7 +2684,7 @@ Current user's request: ${currentInput}`;
|
|
|
2680
2684
|
generateSpan.setAttribute("neurolink.context.estimated_tokens", error.estimatedTokens);
|
|
2681
2685
|
generateSpan.setAttribute("neurolink.context.available_tokens", error.availableTokens);
|
|
2682
2686
|
}
|
|
2683
|
-
this.emitGenerateErrorEvent(optionsOrPrompt, error);
|
|
2687
|
+
this.emitGenerateErrorEvent((resolvedOptions ?? optionsOrPrompt), error);
|
|
2684
2688
|
throw error;
|
|
2685
2689
|
}
|
|
2686
2690
|
finally {
|
|
@@ -2693,6 +2697,8 @@ Current user's request: ${currentInput}`;
|
|
|
2693
2697
|
const options = typeof optionsOrPrompt === "string"
|
|
2694
2698
|
? { input: { text: optionsOrPrompt } }
|
|
2695
2699
|
: { ...optionsOrPrompt };
|
|
2700
|
+
// Dynamic argument resolution — resolve any function-valued options before downstream use
|
|
2701
|
+
await this.resolveDynamicOptions(options);
|
|
2696
2702
|
options.model = resolveModel(options.model, this.modelAliasConfig);
|
|
2697
2703
|
this._disableToolCacheForCurrentRequest = !!options.disableToolCache;
|
|
2698
2704
|
generateSpan.setAttribute("neurolink.provider", options.provider || "default");
|
|
@@ -2839,6 +2845,7 @@ Current user's request: ${currentInput}`;
|
|
|
2839
2845
|
maxSteps: options.maxSteps,
|
|
2840
2846
|
toolChoice: options.toolChoice,
|
|
2841
2847
|
prepareStep: options.prepareStep,
|
|
2848
|
+
enabledToolNames: options.enabledToolNames,
|
|
2842
2849
|
enableAnalytics: options.enableAnalytics,
|
|
2843
2850
|
enableEvaluation: options.enableEvaluation,
|
|
2844
2851
|
context: options.context,
|
|
@@ -4331,13 +4338,18 @@ Current user's request: ${currentInput}`;
|
|
|
4331
4338
|
* Used to filter the tool list before building the system prompt.
|
|
4332
4339
|
*/
|
|
4333
4340
|
applyToolInfoFiltering(tools, options) {
|
|
4334
|
-
|
|
4341
|
+
// enabledToolNames is an additional whitelist — merged into toolFilter
|
|
4342
|
+
const whitelist = [
|
|
4343
|
+
...(options.toolFilter ?? []),
|
|
4344
|
+
...(options.enabledToolNames ?? []),
|
|
4345
|
+
];
|
|
4346
|
+
if (whitelist.length === 0 &&
|
|
4335
4347
|
(!options.excludeTools || options.excludeTools.length === 0)) {
|
|
4336
4348
|
return tools;
|
|
4337
4349
|
}
|
|
4338
4350
|
let filtered = tools;
|
|
4339
|
-
if (
|
|
4340
|
-
const allowSet = new Set(
|
|
4351
|
+
if (whitelist.length > 0) {
|
|
4352
|
+
const allowSet = new Set(whitelist);
|
|
4341
4353
|
filtered = filtered.filter((t) => allowSet.has(t.name));
|
|
4342
4354
|
}
|
|
4343
4355
|
if (options.excludeTools && options.excludeTools.length > 0) {
|
|
@@ -4493,12 +4505,16 @@ Current user's request: ${currentInput}`;
|
|
|
4493
4505
|
disableTools: options.disableTools,
|
|
4494
4506
|
enableAnalytics: options.enableAnalytics,
|
|
4495
4507
|
enableEvaluation: options.enableEvaluation,
|
|
4496
|
-
contextKeys: options.context
|
|
4508
|
+
contextKeys: options.context
|
|
4509
|
+
? Object.keys(options.context ?? {})
|
|
4510
|
+
: [],
|
|
4497
4511
|
optionKeys: Object.keys(options),
|
|
4498
4512
|
});
|
|
4499
4513
|
return metricsTraceContextStorage.run(this.createMetricsTraceContext(), () => this.executeStreamRequest({ ...options }));
|
|
4500
4514
|
}
|
|
4501
4515
|
async executeStreamRequest(options) {
|
|
4516
|
+
// Dynamic argument resolution — resolve any function-valued options before downstream use
|
|
4517
|
+
await this.resolveDynamicOptions(options);
|
|
4502
4518
|
const streamSpan = tracers.sdk.startSpan("neurolink.stream", {
|
|
4503
4519
|
kind: SpanKind.INTERNAL,
|
|
4504
4520
|
attributes: {
|
|
@@ -8974,7 +8990,7 @@ Current user's request: ${currentInput}`;
|
|
|
8974
8990
|
async initializeAuthProviderFromConfig(config) {
|
|
8975
8991
|
let provider;
|
|
8976
8992
|
let providerType;
|
|
8977
|
-
// Duck-type check: direct
|
|
8993
|
+
// Duck-type check: direct AuthProvider instance
|
|
8978
8994
|
if ("authenticateToken" in config &&
|
|
8979
8995
|
typeof config.authenticateToken === "function") {
|
|
8980
8996
|
provider = config;
|
|
@@ -9075,6 +9091,63 @@ Current user's request: ${currentInput}`;
|
|
|
9075
9091
|
getExternalServerManager() {
|
|
9076
9092
|
return this.externalServerManager;
|
|
9077
9093
|
}
|
|
9094
|
+
// ==========================================================================
|
|
9095
|
+
// Dynamic Argument Resolution
|
|
9096
|
+
// ==========================================================================
|
|
9097
|
+
buildResolutionContext(signal, inlineContext) {
|
|
9098
|
+
return {
|
|
9099
|
+
requestContext: inlineContext || {},
|
|
9100
|
+
signal,
|
|
9101
|
+
};
|
|
9102
|
+
}
|
|
9103
|
+
/**
|
|
9104
|
+
* Resolve dynamic arguments in GenerateOptions, mutating the options in place.
|
|
9105
|
+
* Only resolves fields that are functions; static values pass through unchanged.
|
|
9106
|
+
*/
|
|
9107
|
+
async resolveDynamicOptions(options) {
|
|
9108
|
+
const dynamicFields = [
|
|
9109
|
+
"model",
|
|
9110
|
+
"provider",
|
|
9111
|
+
"temperature",
|
|
9112
|
+
"maxTokens",
|
|
9113
|
+
"systemPrompt",
|
|
9114
|
+
"timeout",
|
|
9115
|
+
"thinkingLevel",
|
|
9116
|
+
"disableTools",
|
|
9117
|
+
"enableAnalytics",
|
|
9118
|
+
"enableEvaluation",
|
|
9119
|
+
];
|
|
9120
|
+
const hasDynamic = dynamicFields.some((f) => typeof options[f] === "function") ||
|
|
9121
|
+
typeof options.tools === "function";
|
|
9122
|
+
if (!hasDynamic) {
|
|
9123
|
+
return;
|
|
9124
|
+
}
|
|
9125
|
+
const inlineCtx = options.dynamicContext;
|
|
9126
|
+
await this.resolveDynamicFields(options, dynamicFields, inlineCtx);
|
|
9127
|
+
}
|
|
9128
|
+
async resolveDynamicFields(options, dynamicFields, inlineContext) {
|
|
9129
|
+
const resolutionContext = this.buildResolutionContext(options.abortSignal, inlineContext);
|
|
9130
|
+
logger.debug("[NeuroLink] Resolving dynamic arguments");
|
|
9131
|
+
await Promise.all(dynamicFields.map(async (field) => {
|
|
9132
|
+
if (typeof options[field] === "function") {
|
|
9133
|
+
const result = await resolveDynamicArgument(options[field], resolutionContext);
|
|
9134
|
+
options[field] = result.value;
|
|
9135
|
+
logger.debug(`[NeuroLink] Resolved dynamic ${field}: ${result.resolutionType}`);
|
|
9136
|
+
}
|
|
9137
|
+
}));
|
|
9138
|
+
// Handle dynamic tools → enabledToolNames mapping.
|
|
9139
|
+
// Per DynamicOptions.tools: DynamicArgument<string[]>, the resolver
|
|
9140
|
+
// must return an array of tool names. Anything else is a contract
|
|
9141
|
+
// violation — fail fast rather than silently disabling tooling.
|
|
9142
|
+
if (typeof options.tools === "function") {
|
|
9143
|
+
const result = await resolveDynamicArgument(options.tools, resolutionContext);
|
|
9144
|
+
if (!Array.isArray(result.value)) {
|
|
9145
|
+
throw new TypeError(`Dynamic tools resolver must return string[] (tool names), got ${typeof result.value === "object" ? "object" : typeof result.value}`);
|
|
9146
|
+
}
|
|
9147
|
+
options.enabledToolNames = result.value;
|
|
9148
|
+
delete options.tools;
|
|
9149
|
+
}
|
|
9150
|
+
}
|
|
9078
9151
|
}
|
|
9079
9152
|
// Create default instance
|
|
9080
9153
|
export const neurolink = new NeuroLink();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Abstract base class for all observability exporters
|
|
3
|
-
* Follows NeuroLink's factory pattern
|
|
3
|
+
* Follows NeuroLink's factory pattern with a unified exporter interface
|
|
4
4
|
*/
|
|
5
5
|
import type { ExporterConfig, ExporterHealthStatus, ExportResult, SpanData } from "../../types/index.js";
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Abstract base class for all observability exporters
|
|
3
|
-
* Follows NeuroLink's factory pattern
|
|
3
|
+
* Follows NeuroLink's factory pattern with a unified exporter interface
|
|
4
4
|
*/
|
|
5
5
|
import { logger } from "../../utils/logger.js";
|
|
6
6
|
/**
|
package/dist/types/auth.d.ts
CHANGED
|
@@ -490,7 +490,7 @@ export type PermissionDefinition = {
|
|
|
490
490
|
*/
|
|
491
491
|
export type AuthMiddlewareOptions = {
|
|
492
492
|
/** Auth provider instance */
|
|
493
|
-
provider:
|
|
493
|
+
provider: AuthProvider;
|
|
494
494
|
/** Routes to exclude from authentication */
|
|
495
495
|
excludePaths?: string[];
|
|
496
496
|
/** Whether auth is optional (continue if no token) */
|
|
@@ -729,7 +729,7 @@ export type CustomAuthConfig = {
|
|
|
729
729
|
createSession?: (user: AuthUser, context?: AuthRequestContext) => Promise<AuthSession>;
|
|
730
730
|
};
|
|
731
731
|
/**
|
|
732
|
-
* Configuration for
|
|
732
|
+
* Configuration for AuthProvider.
|
|
733
733
|
*
|
|
734
734
|
* Discriminated union of base + each provider-specific config so that
|
|
735
735
|
* provider factories receive the properly typed config without requiring
|
|
@@ -819,7 +819,7 @@ export type AuthEventHandler = (event: AuthEventData) => void | Promise<void>;
|
|
|
819
819
|
/**
|
|
820
820
|
* Auth provider factory function type
|
|
821
821
|
*/
|
|
822
|
-
export type AuthProviderFactoryFn = (config: AuthProviderConfig) => Promise<
|
|
822
|
+
export type AuthProviderFactoryFn = (config: AuthProviderConfig) => Promise<AuthProvider>;
|
|
823
823
|
/**
|
|
824
824
|
* Auth health check result
|
|
825
825
|
*/
|
|
@@ -973,7 +973,7 @@ export type AuthLifecycle = {
|
|
|
973
973
|
* Composed from focused sub-types so consumers can depend on only the
|
|
974
974
|
* slice they need (e.g. `AuthTokenValidator` for token-only middleware).
|
|
975
975
|
*
|
|
976
|
-
*
|
|
976
|
+
* Unified auth provider interface covering:
|
|
977
977
|
* - Token validation (AuthTokenValidator)
|
|
978
978
|
* - User authorization (AuthUserAuthorizer)
|
|
979
979
|
* - Session management (AuthSessionManager)
|
|
@@ -981,7 +981,7 @@ export type AuthLifecycle = {
|
|
|
981
981
|
* - User management (AuthUserManager)
|
|
982
982
|
* - Lifecycle (AuthLifecycle)
|
|
983
983
|
*/
|
|
984
|
-
export type
|
|
984
|
+
export type AuthProvider = AuthTokenValidator & AuthUserAuthorizer & AuthSessionManager & AuthRequestHandler & AuthUserManager & AuthLifecycle & {
|
|
985
985
|
/** Provider type identifier */
|
|
986
986
|
readonly type: AuthProviderType;
|
|
987
987
|
/** Provider configuration */
|
|
@@ -1019,7 +1019,7 @@ export type AuthJWKSCacheEntry = {
|
|
|
1019
1019
|
expiresAt: number;
|
|
1020
1020
|
};
|
|
1021
1021
|
/** Async constructor for an auth provider given its config. */
|
|
1022
|
-
export type AuthProviderConstructor = (config: AuthProviderConfig) => Promise<
|
|
1022
|
+
export type AuthProviderConstructor = (config: AuthProviderConfig) => Promise<AuthProvider>;
|
|
1023
1023
|
/** Registration row for an auth provider in AuthProviderFactory. */
|
|
1024
1024
|
export type AuthProviderRegistration = {
|
|
1025
1025
|
factory: AuthProviderConstructor;
|