@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.
Files changed (82) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/auth/AuthProviderFactory.d.ts +3 -3
  3. package/dist/auth/providers/BaseAuthProvider.d.ts +2 -2
  4. package/dist/auth/providers/BaseAuthProvider.js +1 -1
  5. package/dist/auth/serverBridge.d.ts +2 -2
  6. package/dist/browser/neurolink.min.js +306 -306
  7. package/dist/cli/factories/commandFactory.js +32 -8
  8. package/dist/cli/loop/optionsSchema.js +4 -0
  9. package/dist/cli/parser.js +3 -3
  10. package/dist/dynamic/dynamicResolver.d.ts +282 -0
  11. package/dist/dynamic/dynamicResolver.js +633 -0
  12. package/dist/dynamic/index.d.ts +10 -0
  13. package/dist/dynamic/index.js +12 -0
  14. package/dist/dynamic/resolution.d.ts +17 -0
  15. package/dist/dynamic/resolution.js +21 -0
  16. package/dist/evaluation/index.js +1 -1
  17. package/dist/files/fileReferenceRegistry.js +25 -10
  18. package/dist/index.js +19 -2
  19. package/dist/lib/auth/AuthProviderFactory.d.ts +3 -3
  20. package/dist/lib/auth/providers/BaseAuthProvider.d.ts +2 -2
  21. package/dist/lib/auth/providers/BaseAuthProvider.js +1 -1
  22. package/dist/lib/auth/serverBridge.d.ts +2 -2
  23. package/dist/lib/dynamic/dynamicResolver.d.ts +282 -0
  24. package/dist/lib/dynamic/dynamicResolver.js +634 -0
  25. package/dist/lib/dynamic/index.d.ts +10 -0
  26. package/dist/lib/dynamic/index.js +13 -0
  27. package/dist/lib/dynamic/resolution.d.ts +17 -0
  28. package/dist/lib/dynamic/resolution.js +22 -0
  29. package/dist/lib/evaluation/index.js +1 -1
  30. package/dist/lib/files/fileReferenceRegistry.js +25 -10
  31. package/dist/lib/index.js +19 -2
  32. package/dist/lib/mcp/mcpServerBase.d.ts +1 -1
  33. package/dist/lib/mcp/mcpServerBase.js +1 -1
  34. package/dist/lib/neurolink.d.ts +12 -4
  35. package/dist/lib/neurolink.js +79 -6
  36. package/dist/lib/observability/exporters/baseExporter.d.ts +1 -1
  37. package/dist/lib/observability/exporters/baseExporter.js +1 -1
  38. package/dist/lib/types/auth.d.ts +6 -6
  39. package/dist/lib/types/config.d.ts +4 -4
  40. package/dist/lib/types/dynamic.d.ts +98 -0
  41. package/dist/lib/types/dynamic.js +10 -0
  42. package/dist/lib/types/file.d.ts +10 -0
  43. package/dist/lib/types/fileReference.d.ts +9 -0
  44. package/dist/lib/types/generate.d.ts +29 -0
  45. package/dist/lib/types/index.d.ts +1 -0
  46. package/dist/lib/types/index.js +2 -0
  47. package/dist/lib/types/scorer.d.ts +1 -1
  48. package/dist/lib/types/scorer.js +1 -1
  49. package/dist/lib/types/span.d.ts +1 -1
  50. package/dist/lib/types/span.js +1 -1
  51. package/dist/lib/types/stream.d.ts +6 -0
  52. package/dist/lib/utils/fileDetector.d.ts +7 -0
  53. package/dist/lib/utils/fileDetector.js +47 -0
  54. package/dist/lib/utils/messageBuilder.js +15 -1
  55. package/dist/lib/utils/mimeTypeHints.d.ts +40 -0
  56. package/dist/lib/utils/mimeTypeHints.js +122 -0
  57. package/dist/mcp/mcpServerBase.d.ts +1 -1
  58. package/dist/mcp/mcpServerBase.js +1 -1
  59. package/dist/neurolink.d.ts +12 -4
  60. package/dist/neurolink.js +79 -6
  61. package/dist/observability/exporters/baseExporter.d.ts +1 -1
  62. package/dist/observability/exporters/baseExporter.js +1 -1
  63. package/dist/types/auth.d.ts +6 -6
  64. package/dist/types/config.d.ts +4 -4
  65. package/dist/types/dynamic.d.ts +98 -0
  66. package/dist/types/dynamic.js +9 -0
  67. package/dist/types/file.d.ts +10 -0
  68. package/dist/types/fileReference.d.ts +9 -0
  69. package/dist/types/generate.d.ts +29 -0
  70. package/dist/types/index.d.ts +1 -0
  71. package/dist/types/index.js +2 -0
  72. package/dist/types/scorer.d.ts +1 -1
  73. package/dist/types/scorer.js +1 -1
  74. package/dist/types/span.d.ts +1 -1
  75. package/dist/types/span.js +1 -1
  76. package/dist/types/stream.d.ts +6 -0
  77. package/dist/utils/fileDetector.d.ts +7 -0
  78. package/dist/utils/fileDetector.js +47 -0
  79. package/dist/utils/messageBuilder.js +15 -1
  80. package/dist/utils/mimeTypeHints.d.ts +40 -0
  81. package/dist/utils/mimeTypeHints.js +121 -0
  82. package/package.json +1 -1
@@ -7,7 +7,7 @@ import type { TaskManagerConfig } from "./task.js";
7
7
  import type { HITLConfig } from "../types/hitl.js";
8
8
  import type { ConversationMemoryConfig } from "./conversation.js";
9
9
  import type { ObservabilityConfig } from "./observability.js";
10
- import type { MastraAuthProvider, AuthProviderType, AuthProviderConfig, Auth0Config, ClerkConfig, FirebaseConfig, SupabaseConfig, WorkOSConfig, BetterAuthConfig, JWTConfig, OAuth2Config, CognitoConfig, KeycloakConfig, AuthenticatedContext } from "./auth.js";
10
+ import type { AuthProvider, AuthProviderType, AuthProviderConfig, Auth0Config, ClerkConfig, FirebaseConfig, SupabaseConfig, WorkOSConfig, BetterAuthConfig, JWTConfig, OAuth2Config, CognitoConfig, KeycloakConfig, AuthenticatedContext } from "./auth.js";
11
11
  import type { NeurolinkCredentials } from "./providers.js";
12
12
  /**
13
13
  * Main NeuroLink configuration type
@@ -130,8 +130,8 @@ export type MCPEnhancementsConfig = {
130
130
  /**
131
131
  * Authentication configuration for NeuroLink SDK
132
132
  */
133
- export type NeuroLinkAuthConfig = MastraAuthProvider | {
134
- provider: MastraAuthProvider;
133
+ export type NeuroLinkAuthConfig = AuthProvider | {
134
+ provider: AuthProvider;
135
135
  } | {
136
136
  type: "auth0";
137
137
  config: Auth0Config;
@@ -169,7 +169,7 @@ export type NeuroLinkAuthConfig = MastraAuthProvider | {
169
169
  /**
170
170
  * Re-export auth types for convenience
171
171
  */
172
- export type { MastraAuthProvider, AuthProviderType, AuthProviderConfig, AuthenticatedContext, };
172
+ export type { AuthProvider, AuthProviderType, AuthProviderConfig, AuthenticatedContext, };
173
173
  /**
174
174
  * Provider-specific configuration
175
175
  */
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Dynamic Arguments Type Definitions
3
+ *
4
+ * Pass functions instead of static values to generate() and stream().
5
+ * Functions are resolved at runtime before provider dispatch.
6
+ *
7
+ * @module types/dynamic
8
+ */
9
+ import type { AIProviderName } from "../constants/enums.js";
10
+ /**
11
+ * Context passed to context-aware dynamic argument functions.
12
+ * `requestContext` is whatever the consumer passed as `dynamicContext` —
13
+ * NeuroLink does not prescribe its shape.
14
+ */
15
+ export type DynamicResolutionContext = {
16
+ /** Consumer-provided context (any shape) */
17
+ requestContext: Record<string, unknown>;
18
+ /** Abort signal for cancellation */
19
+ signal?: AbortSignal;
20
+ };
21
+ /**
22
+ * A value that can be static, a function, or a context-aware function.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // Static
27
+ * model: "gpt-4o"
28
+ *
29
+ * // Function
30
+ * model: () => process.env.MODEL || "gpt-4o"
31
+ *
32
+ * // Context-aware
33
+ * model: (ctx) => ctx.requestContext.plan === "enterprise" ? "gpt-4o" : "gpt-4o-mini"
34
+ * ```
35
+ */
36
+ export type DynamicArgument<T> = T | (() => T) | (() => Promise<T>) | ((context: DynamicResolutionContext) => T) | ((context: DynamicResolutionContext) => Promise<T>);
37
+ /**
38
+ * Dynamic options for generate() and stream() — pass functions
39
+ * instead of static values for context-aware resolution.
40
+ */
41
+ export type DynamicOptions = {
42
+ model?: DynamicArgument<string>;
43
+ provider?: DynamicArgument<AIProviderName | string>;
44
+ temperature?: DynamicArgument<number>;
45
+ maxTokens?: DynamicArgument<number>;
46
+ systemPrompt?: DynamicArgument<string>;
47
+ /**
48
+ * Resolves to a `string[]` of tool names to enable.
49
+ * The resolved array is merged into `enabledToolNames` (and from there
50
+ * into `toolFilter`) — it does NOT replace `GenerateOptions.tools`,
51
+ * which is a `Record<string, Tool>` map of tool definitions.
52
+ */
53
+ tools?: DynamicArgument<string[]>;
54
+ timeout?: DynamicArgument<number>;
55
+ thinkingLevel?: DynamicArgument<"minimal" | "low" | "medium" | "high">;
56
+ disableTools?: DynamicArgument<boolean>;
57
+ enableAnalytics?: DynamicArgument<boolean>;
58
+ enableEvaluation?: DynamicArgument<boolean>;
59
+ input: {
60
+ text: string;
61
+ images?: Array<Buffer | string>;
62
+ files?: Array<Buffer | string>;
63
+ };
64
+ /**
65
+ * Context passed to dynamic resolver functions — any shape you want.
66
+ *
67
+ * This is intentionally separate from `GenerateOptions.context` (which is
68
+ * for telemetry/tracing metadata). If your resolvers need values from
69
+ * telemetry context (sessionId, userId, etc.), pass them here as well.
70
+ */
71
+ dynamicContext?: Record<string, unknown>;
72
+ };
73
+ export type ResolutionOptions = {
74
+ timeout?: number;
75
+ cache?: boolean;
76
+ cacheKey?: string;
77
+ cacheTtl?: number;
78
+ defaultValue?: unknown;
79
+ throwOnError?: boolean;
80
+ };
81
+ export type ResolutionResult<T> = {
82
+ value: T;
83
+ fromCache: boolean;
84
+ resolutionTime: number;
85
+ resolutionType: "static" | "sync-function" | "async-function" | "context-aware";
86
+ };
87
+ export type DynamicConfig<T> = {
88
+ [K in keyof T]: DynamicArgument<T[K]>;
89
+ };
90
+ export type ResolvedConfig<T> = {
91
+ [K in keyof T]: T[K] extends DynamicArgument<infer U> ? U : T[K];
92
+ };
93
+ export type DynamicCacheEntry<T> = {
94
+ value: T;
95
+ resolvedAt: number;
96
+ expiresAt: number;
97
+ key: string;
98
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Dynamic Arguments Type Definitions
3
+ *
4
+ * Pass functions instead of static values to generate() and stream().
5
+ * Functions are resolved at runtime before provider dispatch.
6
+ *
7
+ * @module types/dynamic
8
+ */
9
+ export {};
@@ -307,6 +307,16 @@ export type FileDetectorOptions = {
307
307
  maxRetries?: number;
308
308
  /** Initial retry delay in milliseconds with exponential backoff (default: 1000) */
309
309
  retryDelay?: number;
310
+ /**
311
+ * Caller-provided MIME type hint (e.g. "text/plain", "application/json").
312
+ * Used when the filename has no extension and magic-byte detection cannot
313
+ * identify the content — the common Slack/Curator extension-less-buffer
314
+ * case. When set to a trustworthy mimetype (not "application/octet-stream"),
315
+ * it short-circuits the detection strategy loop with a high-confidence
316
+ * result so small files on the eager file-processing path still honor the
317
+ * hint (the lazy FileReferenceRegistry path has its own hint-handling).
318
+ */
319
+ mimetypeHint?: string;
310
320
  };
311
321
  /**
312
322
  * Google AI Studio Files API types
@@ -96,6 +96,15 @@ export type FileRegistrationOptions = {
96
96
  filename?: string;
97
97
  /** Override file type detection */
98
98
  fileType?: FileType;
99
+ /**
100
+ * Caller-provided MIME type hint (e.g. "text/plain", "application/json").
101
+ * Used when the filename has no extension and magic-byte detection cannot
102
+ * identify the content (common for Slack/Curator-style buffers where the
103
+ * original extension was stripped). Honored during type detection, mimeType
104
+ * assignment, and filename-extension synthesis. An explicit `fileType`
105
+ * override still wins over this hint.
106
+ */
107
+ mimetype?: string;
99
108
  /** Maximum preview length in characters */
100
109
  maxPreviewChars?: number;
101
110
  /** Skip persisting buffer to temp directory */
@@ -230,6 +230,20 @@ export type GenerateOptions = {
230
230
  */
231
231
  schema?: ValidationSchema;
232
232
  tools?: Record<string, Tool>;
233
+ /**
234
+ * Filter available tools by name.
235
+ * Only tools with names in this array will be made available.
236
+ * Used by dynamic arguments to dynamically select which tools to enable.
237
+ *
238
+ * @example
239
+ * ```typescript
240
+ * await neurolink.generate({
241
+ * input: { text: "Search for information" },
242
+ * enabledToolNames: ["websearchGrounding", "readFile"]
243
+ * });
244
+ * ```
245
+ */
246
+ enabledToolNames?: string[];
233
247
  timeout?: number | string;
234
248
  /** AbortSignal for external cancellation of the AI call */
235
249
  abortSignal?: AbortSignal;
@@ -738,6 +752,21 @@ export type TextGenerationOptions = {
738
752
  director?: DirectorModeOptions;
739
753
  };
740
754
  tools?: Record<string, Tool>;
755
+ /**
756
+ * Filter available tools by name.
757
+ * Only tools with names in this array will be made available.
758
+ * Used by dynamic arguments to dynamically select which tools to enable.
759
+ * Merged into `toolFilter` before tool filtering runs.
760
+ *
761
+ * @example
762
+ * ```typescript
763
+ * await neurolink.generate({
764
+ * input: { text: "Search for information" },
765
+ * enabledToolNames: ["websearchGrounding", "readFile"]
766
+ * });
767
+ * ```
768
+ */
769
+ enabledToolNames?: string[];
741
770
  timeout?: number | string;
742
771
  /** AbortSignal for external cancellation of the AI call */
743
772
  abortSignal?: AbortSignal;
@@ -56,3 +56,4 @@ export * from "./exporter.js";
56
56
  export * from "./span.js";
57
57
  export * from "./imageGen.js";
58
58
  export * from "./elicitation.js";
59
+ export * from "./dynamic.js";
@@ -58,3 +58,5 @@ export * from "./exporter.js";
58
58
  export * from "./span.js";
59
59
  export * from "./imageGen.js";
60
60
  export * from "./elicitation.js";
61
+ // Dynamic Arguments types
62
+ export * from "./dynamic.js";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @file Scorer type definitions for NeuroLink evaluation system
3
- * Mastra-style modular scorer interfaces and types
3
+ * Modular scorer interfaces and types
4
4
  */
5
5
  import type { JsonObject } from "./common.js";
6
6
  import type { EnhancedEvaluationContext } from "./evaluation.js";
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * @file Scorer type definitions for NeuroLink evaluation system
3
- * Mastra-style modular scorer interfaces and types
3
+ * Modular scorer interfaces and types
4
4
  */
5
5
  export {};
@@ -4,7 +4,7 @@
4
4
  */
5
5
  /**
6
6
  * Span types for AI operations
7
- * Following Mastra's span categorization and OTel GenAI conventions
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) */
@@ -4,7 +4,7 @@
4
4
  */
5
5
  /**
6
6
  * Span types for AI operations
7
- * Following Mastra's span categorization and OTel GenAI conventions
7
+ * Following OTel GenAI conventions for span categorization
8
8
  */
9
9
  export var SpanType;
10
10
  (function (SpanType) {
@@ -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
- await registry.register(buffer, getFileSource(file), { filename });
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,121 @@
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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "9.56.1",
3
+ "version": "9.57.0",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 13 providers: OpenAI, Anthropic, Google AI, AWS Bedrock, Azure, Hugging Face, Ollama, and Mistral AI.",
6
6
  "author": {