@juspay/neurolink 10.10.12 → 10.11.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 (49) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/adapters/imageFormatSupport.d.ts +75 -0
  3. package/dist/adapters/imageFormatSupport.js +283 -0
  4. package/dist/adapters/video/ffmpegAdapter.d.ts +6 -0
  5. package/dist/adapters/video/ffmpegAdapter.js +1 -1
  6. package/dist/browser/neurolink.min.js +399 -398
  7. package/dist/lib/adapters/imageFormatSupport.d.ts +75 -0
  8. package/dist/lib/adapters/imageFormatSupport.js +284 -0
  9. package/dist/lib/adapters/video/ffmpegAdapter.d.ts +6 -0
  10. package/dist/lib/adapters/video/ffmpegAdapter.js +1 -1
  11. package/dist/lib/processors/config/fileExtensions.d.ts +32 -15
  12. package/dist/lib/processors/config/fileExtensions.js +27 -66
  13. package/dist/lib/processors/config/fileTypeRegistry.d.ts +106 -0
  14. package/dist/lib/processors/config/fileTypeRegistry.js +702 -0
  15. package/dist/lib/processors/config/index.d.ts +2 -1
  16. package/dist/lib/processors/config/index.js +5 -1
  17. package/dist/lib/processors/config/mimeConstants.d.ts +22 -7
  18. package/dist/lib/processors/config/mimeConstants.js +45 -66
  19. package/dist/lib/processors/media/AudioProcessor.js +16 -38
  20. package/dist/lib/processors/media/VideoProcessor.js +11 -32
  21. package/dist/lib/providers/googleAiStudio/client.js +12 -1
  22. package/dist/lib/providers/googleVertex/client.js +123 -66
  23. package/dist/lib/types/file.d.ts +41 -0
  24. package/dist/lib/utils/fileDetector.js +367 -251
  25. package/dist/lib/utils/imageProcessor.js +14 -17
  26. package/dist/lib/utils/markupSniff.d.ts +37 -0
  27. package/dist/lib/utils/markupSniff.js +125 -0
  28. package/dist/lib/utils/messageBuilder.d.ts +14 -0
  29. package/dist/lib/utils/messageBuilder.js +172 -92
  30. package/dist/processors/config/fileExtensions.d.ts +32 -15
  31. package/dist/processors/config/fileExtensions.js +27 -66
  32. package/dist/processors/config/fileTypeRegistry.d.ts +106 -0
  33. package/dist/processors/config/fileTypeRegistry.js +701 -0
  34. package/dist/processors/config/index.d.ts +2 -1
  35. package/dist/processors/config/index.js +5 -1
  36. package/dist/processors/config/mimeConstants.d.ts +22 -7
  37. package/dist/processors/config/mimeConstants.js +45 -66
  38. package/dist/processors/media/AudioProcessor.js +16 -38
  39. package/dist/processors/media/VideoProcessor.js +11 -32
  40. package/dist/providers/googleAiStudio/client.js +12 -1
  41. package/dist/providers/googleVertex/client.js +123 -66
  42. package/dist/types/file.d.ts +41 -0
  43. package/dist/utils/fileDetector.js +367 -251
  44. package/dist/utils/imageProcessor.js +14 -17
  45. package/dist/utils/markupSniff.d.ts +37 -0
  46. package/dist/utils/markupSniff.js +124 -0
  47. package/dist/utils/messageBuilder.d.ts +14 -0
  48. package/dist/utils/messageBuilder.js +172 -92
  49. package/package.json +3 -2
@@ -26,7 +26,8 @@
26
26
  * const maxSize = SIZE_LIMITS.IMAGE_MAX_MB; // 10
27
27
  * ```
28
28
  */
29
- export { ARCHIVE_MIME_TYPES, AUDIO_MIME_TYPES, DATA_MIME_TYPES, DOCUMENT_MIME_TYPES, EXTENSION_MIME_MAP, getMimeTypeForExtension, IMAGE_MIME_TYPES, MIME_TYPES, SOURCE_CODE_MIME_TYPES, TEXT_MIME_TYPES, VIDEO_MIME_TYPES, } from "./mimeConstants.js";
29
+ export { ARCHIVE_MIME_TYPES, AUDIO_MIME_TYPES, DATA_MIME_TYPES, DOCUMENT_MIME_TYPES, EXTENSION_MIME_MAP, getMimeTypeForExtension, IMAGE_MIME_TYPES, MIME_TYPES, SOURCE_CODE_MIME_TYPES, TEXT_EXTENSION_MIME_MAP, TEXT_MIME_TYPES, VIDEO_MIME_TYPES, } from "./mimeConstants.js";
30
+ export { extensionForMimeType, extensionsForModality, FILE_TYPE_REGISTRY, fileTypeForExtension, isModalityExtension, lookupByExtension, lookupByMimeType, mimeTypeForExtension, mimeTypesForModality, normalizeExtension, } from "./fileTypeRegistry.js";
30
31
  export { ADA_EXTENSIONS, AI_VISION_EXTENSIONS, ARCHIVE_EXTENSIONS, ASSEMBLY_EXTENSIONS, AUDIO_EXTENSIONS, C_EXTENSIONS, CLOJURE_EXTENSIONS, COBOL_EXTENSIONS, CONFIG_EXTENSIONS, CPP_EXTENSIONS, CRYSTAL_EXTENSIONS, CSHARP_EXTENSIONS, CSS_EXTENSIONS, CSV_EXTENSIONS, D_EXTENSIONS, DART_EXTENSIONS, DATA_EXTENSIONS, DATABASE_EXTENSIONS, DESIGN_EXTENSIONS, DOCKERFILE_EXTENSIONS, DOCUMENT_EXTENSIONS, EJS_EXTENSIONS, ELIXIR_EXTENSIONS, ERLANG_EXTENSIONS, EXCEL_EXTENSIONS, EXECUTABLE_EXTENSIONS, FILE_EXTENSIONS, FORTRAN_EXTENSIONS, FSHARP_EXTENSIONS, GO_EXTENSIONS, GROOVY_EXTENSIONS, HANDLEBARS_EXTENSIONS, HASKELL_EXTENSIONS, HTML_EXTENSIONS, IMAGE_EXTENSIONS, JAVA_EXTENSIONS, JAVASCRIPT_EXTENSIONS, JSON_EXTENSIONS, JULIA_EXTENSIONS, KOTLIN_EXTENSIONS, LESS_EXTENSIONS, LISP_EXTENSIONS, LUA_EXTENSIONS, MAKEFILE_EXTENSIONS, MARKDOWN_EXTENSIONS, NIM_EXTENSIONS, OBJECTIVE_C_EXTENSIONS, OCAML_EXTENSIONS, OPENDOCUMENT_EXTENSIONS, PASCAL_EXTENSIONS, PDF_EXTENSIONS, PERL_EXTENSIONS, PHP_EXTENSIONS, POWERPOINT_EXTENSIONS, POWERSHELL_EXTENSIONS, PUG_EXTENSIONS, PYTHON_EXTENSIONS, R_EXTENSIONS, RTF_EXTENSIONS, RUBY_EXTENSIONS, RUST_EXTENSIONS, SCALA_EXTENSIONS, SCHEME_EXTENSIONS, SCSS_EXTENSIONS, SHELL_EXTENSIONS, SOURCE_CODE_EXTENSIONS, SQL_EXTENSIONS, STYLUS_EXTENSIONS, SVELTE_EXTENSIONS, SWIFT_EXTENSIONS, TEXT_EXTENSIONS, TYPESCRIPT_EXTENSIONS, V_EXTENSIONS, VIDEO_EXTENSIONS, VUE_EXTENSIONS, WORD_EXTENSIONS, XML_EXTENSIONS, YAML_EXTENSIONS, ZIG_EXTENSIONS, } from "./fileExtensions.js";
31
32
  export { detectLanguageFromFilename, EXACT_FILENAME_MAP, getLanguageIdentifier, getSupportedExtensions, getSupportedFilenames, isSourceCodeFile, LANGUAGE_MAP, } from "./languageMap.js";
32
33
  export { ARCHIVE_LIMITS, bytesToMB, formatBytes, getSizeLimitForType, isWithinSizeLimit, mbToBytes, PROCESSING_LIMITS, SIZE_LIMITS, SIZE_LIMITS_BYTES, SIZE_LIMITS_MB, validateFileSize, YAML_LIMITS, } from "./sizeLimits.js";
@@ -36,7 +36,11 @@ EXTENSION_MIME_MAP, getMimeTypeForExtension,
36
36
  IMAGE_MIME_TYPES,
37
37
  // Types
38
38
  // Combined MIME types
39
- MIME_TYPES, SOURCE_CODE_MIME_TYPES, TEXT_MIME_TYPES, VIDEO_MIME_TYPES, } from "./mimeConstants.js";
39
+ MIME_TYPES, SOURCE_CODE_MIME_TYPES, TEXT_EXTENSION_MIME_MAP, TEXT_MIME_TYPES, VIDEO_MIME_TYPES, } from "./mimeConstants.js";
40
+ // =============================================================================
41
+ // CANONICAL FILE-TYPE REGISTRY
42
+ // =============================================================================
43
+ export { extensionForMimeType, extensionsForModality, FILE_TYPE_REGISTRY, fileTypeForExtension, isModalityExtension, lookupByExtension, lookupByMimeType, mimeTypeForExtension, mimeTypesForModality, normalizeExtension, } from "./fileTypeRegistry.js";
40
44
  // =============================================================================
41
45
  // FILE EXTENSIONS
42
46
  // =============================================================================
@@ -337,22 +337,37 @@ export declare const MIME_TYPES: {
337
337
  /** Microsoft ICO format */
338
338
  readonly ICO_MS: "image/vnd.microsoft.icon";
339
339
  };
340
+ /**
341
+ * Extension → MIME for text, markup, source-code and config files.
342
+ *
343
+ * These are the formats that carry no modality of their own — they are inlined
344
+ * into the prompt as text. Binary and structured formats (image, audio, video,
345
+ * document, data, archive) are NOT listed here; they come from
346
+ * {@link FILE_TYPE_REGISTRY}, which is the single source of truth for
347
+ * everything multimodal. See `fileTypeRegistry.ts` for why.
348
+ */
349
+ export declare const TEXT_EXTENSION_MIME_MAP: Record<string, string>;
340
350
  /**
341
351
  * Centralized mapping of file extensions (with leading dot) to MIME types.
342
352
  *
343
- * This is the single source of truth for extension-to-MIME lookups.
344
- * Derived from the category-specific MIME type constants above so that
345
- * consumers (e.g. CLI helpers, file detectors) do not need to maintain
346
- * their own duplicate mappings.
353
+ * Assembled from two sources so there is exactly one place to edit per kind of
354
+ * format: every image / audio / video / document / data / archive entry is
355
+ * derived from {@link FILE_TYPE_REGISTRY}, and the text, markup, source-code
356
+ * and config entries come from {@link TEXT_EXTENSION_MIME_MAP}.
347
357
  *
348
- * If you add a new MIME type constant above, also add its extension mapping
349
- * here to keep everything in sync.
358
+ * Registry entries are spread last so that a format which appears in both wins
359
+ * from the registry the registry is the authority for anything with a
360
+ * modality.
350
361
  */
351
362
  export declare const EXTENSION_MIME_MAP: Record<string, string>;
352
363
  /**
353
364
  * Get MIME type from file extension using the centralized map.
354
365
  *
355
- * @param ext - File extension (with leading dot, e.g. ".pdf")
366
+ * Accepts a bare extension (`"pdf"`), a dotted extension (`".pdf"`), a filename
367
+ * or a full path — `normalizeExtension` handles all four, including compound
368
+ * suffixes like `.tar.gz`.
369
+ *
370
+ * @param ext - File extension, filename or path
356
371
  * @returns MIME type string, or "application/octet-stream" if unknown
357
372
  */
358
373
  export declare function getMimeTypeForExtension(ext: string): string;
@@ -4,6 +4,7 @@
4
4
  *
5
5
  * @module processors/config/mimeTypes
6
6
  */
7
+ import { EXTENSION_MIME_OVERRIDES, FILE_TYPE_REGISTRY, normalizeExtension, } from "./fileTypeRegistry.js";
7
8
  // =============================================================================
8
9
  // IMAGE MIME TYPES
9
10
  // =============================================================================
@@ -237,54 +238,33 @@ export const MIME_TYPES = {
237
238
  // EXTENSION TO MIME TYPE MAP
238
239
  // =============================================================================
239
240
  /**
240
- * Centralized mapping of file extensions (with leading dot) to MIME types.
241
- *
242
- * This is the single source of truth for extension-to-MIME lookups.
243
- * Derived from the category-specific MIME type constants above so that
244
- * consumers (e.g. CLI helpers, file detectors) do not need to maintain
245
- * their own duplicate mappings.
241
+ * Extension MIME for text, markup, source-code and config files.
246
242
  *
247
- * If you add a new MIME type constant above, also add its extension mapping
248
- * here to keep everything in sync.
243
+ * These are the formats that carry no modality of their own they are inlined
244
+ * into the prompt as text. Binary and structured formats (image, audio, video,
245
+ * document, data, archive) are NOT listed here; they come from
246
+ * {@link FILE_TYPE_REGISTRY}, which is the single source of truth for
247
+ * everything multimodal. See `fileTypeRegistry.ts` for why.
249
248
  */
250
- export const EXTENSION_MIME_MAP = {
251
- // Documents
252
- ".pdf": DOCUMENT_MIME_TYPES.PDF,
253
- ".docx": DOCUMENT_MIME_TYPES.DOCX,
254
- ".doc": DOCUMENT_MIME_TYPES.DOC,
255
- ".xlsx": DOCUMENT_MIME_TYPES.XLSX,
256
- ".xls": DOCUMENT_MIME_TYPES.XLS,
257
- ".odt": DOCUMENT_MIME_TYPES.ODT,
258
- ".ods": DOCUMENT_MIME_TYPES.ODS,
259
- ".odp": DOCUMENT_MIME_TYPES.ODP,
260
- ".rtf": DOCUMENT_MIME_TYPES.RTF,
261
- ".pptx": DOCUMENT_MIME_TYPES.PPTX,
262
- ".ppt": DOCUMENT_MIME_TYPES.PPT,
263
- // Data formats
264
- ".json": DATA_MIME_TYPES.JSON,
265
- ".xml": DATA_MIME_TYPES.XML,
266
- ".yaml": DATA_MIME_TYPES.YAML_APP,
267
- ".yml": DATA_MIME_TYPES.YAML_APP,
268
- ".csv": DATA_MIME_TYPES.CSV,
269
- ".tsv": "text/tab-separated-values",
249
+ export const TEXT_EXTENSION_MIME_MAP = {
270
250
  // Text and Markup
271
251
  ".txt": TEXT_MIME_TYPES.PLAIN,
272
252
  ".md": TEXT_MIME_TYPES.MARKDOWN,
273
253
  ".markdown": TEXT_MIME_TYPES.MARKDOWN,
274
254
  ".html": TEXT_MIME_TYPES.HTML,
275
255
  ".htm": TEXT_MIME_TYPES.HTML,
276
- ".svg": IMAGE_MIME_TYPES.SVG,
256
+ ".xhtml": TEXT_MIME_TYPES.XHTML,
277
257
  ".log": TEXT_MIME_TYPES.PLAIN,
278
- // Images
279
- ".png": IMAGE_MIME_TYPES.PNG,
280
- ".jpg": IMAGE_MIME_TYPES.JPEG,
281
- ".jpeg": IMAGE_MIME_TYPES.JPEG,
282
- ".gif": IMAGE_MIME_TYPES.GIF,
283
- ".webp": IMAGE_MIME_TYPES.WEBP,
284
- ".bmp": IMAGE_MIME_TYPES.BMP,
285
- ".ico": IMAGE_MIME_TYPES.ICO,
286
- ".heic": IMAGE_MIME_TYPES.HEIC,
287
- ".heif": IMAGE_MIME_TYPES.HEIF,
258
+ ".css": TEXT_MIME_TYPES.CSS,
259
+ // Structured text.
260
+ // YAML uses the IANA-registered `application/yaml` (RFC 9512) rather than the
261
+ // legacy `application/x-yaml`. This is also what the content heuristic already
262
+ // reports for YAML bytes, so the extension path and the content path no longer
263
+ // disagree about the same file.
264
+ ".json": DATA_MIME_TYPES.JSON,
265
+ ".xml": DATA_MIME_TYPES.XML,
266
+ ".yaml": "application/yaml",
267
+ ".yml": "application/yaml",
288
268
  // Source code
289
269
  ".js": TEXT_MIME_TYPES.JAVASCRIPT,
290
270
  ".mjs": TEXT_MIME_TYPES.JAVASCRIPT,
@@ -315,31 +295,6 @@ export const EXTENSION_MIME_MAP = {
315
295
  ".lua": "text/x-lua",
316
296
  ".perl": "text/x-perl",
317
297
  ".pl": "text/x-perl",
318
- // Video
319
- ".mp4": VIDEO_MIME_TYPES.MP4,
320
- ".m4v": VIDEO_MIME_TYPES.MP4,
321
- ".mkv": VIDEO_MIME_TYPES.MKV,
322
- ".mov": VIDEO_MIME_TYPES.MOV,
323
- ".avi": VIDEO_MIME_TYPES.AVI,
324
- ".webm": VIDEO_MIME_TYPES.WEBM,
325
- ".wmv": VIDEO_MIME_TYPES.WMV,
326
- ".flv": VIDEO_MIME_TYPES.FLV,
327
- // Audio
328
- ".mp3": AUDIO_MIME_TYPES.MP3,
329
- ".wav": AUDIO_MIME_TYPES.WAV,
330
- ".ogg": AUDIO_MIME_TYPES.OGG,
331
- ".flac": AUDIO_MIME_TYPES.FLAC,
332
- ".m4a": AUDIO_MIME_TYPES.M4A,
333
- ".aac": AUDIO_MIME_TYPES.AAC,
334
- ".wma": AUDIO_MIME_TYPES.WMA,
335
- // Archives
336
- ".zip": ARCHIVE_MIME_TYPES.ZIP,
337
- ".tar": ARCHIVE_MIME_TYPES.TAR,
338
- ".gz": ARCHIVE_MIME_TYPES.GZIP,
339
- ".tgz": ARCHIVE_MIME_TYPES.GZIP,
340
- ".rar": ARCHIVE_MIME_TYPES.RAR,
341
- ".7z": ARCHIVE_MIME_TYPES.SEVEN_ZIP,
342
- ".jar": "application/java-archive",
343
298
  // Config files
344
299
  ".env": TEXT_MIME_TYPES.PLAIN,
345
300
  ".ini": TEXT_MIME_TYPES.PLAIN,
@@ -354,14 +309,38 @@ export const EXTENSION_MIME_MAP = {
354
309
  ".eslintrc": DATA_MIME_TYPES.JSON,
355
310
  ".babelrc": DATA_MIME_TYPES.JSON,
356
311
  };
312
+ /**
313
+ * Centralized mapping of file extensions (with leading dot) to MIME types.
314
+ *
315
+ * Assembled from two sources so there is exactly one place to edit per kind of
316
+ * format: every image / audio / video / document / data / archive entry is
317
+ * derived from {@link FILE_TYPE_REGISTRY}, and the text, markup, source-code
318
+ * and config entries come from {@link TEXT_EXTENSION_MIME_MAP}.
319
+ *
320
+ * Registry entries are spread last so that a format which appears in both wins
321
+ * from the registry — the registry is the authority for anything with a
322
+ * modality.
323
+ */
324
+ export const EXTENSION_MIME_MAP = {
325
+ ...TEXT_EXTENSION_MIME_MAP,
326
+ ...Object.fromEntries(FILE_TYPE_REGISTRY.flatMap((entry) => entry.extensions.map((ext) => [ext, entry.mimeTypes[0]]))),
327
+ // Applied last: an ambiguous extension (.ts) must report the MIME type of the
328
+ // format its routing was overridden to, or this map and the registry's
329
+ // mimeTypeForExtension() describe the same file differently.
330
+ ...EXTENSION_MIME_OVERRIDES,
331
+ };
357
332
  /**
358
333
  * Get MIME type from file extension using the centralized map.
359
334
  *
360
- * @param ext - File extension (with leading dot, e.g. ".pdf")
335
+ * Accepts a bare extension (`"pdf"`), a dotted extension (`".pdf"`), a filename
336
+ * or a full path — `normalizeExtension` handles all four, including compound
337
+ * suffixes like `.tar.gz`.
338
+ *
339
+ * @param ext - File extension, filename or path
361
340
  * @returns MIME type string, or "application/octet-stream" if unknown
362
341
  */
363
342
  export function getMimeTypeForExtension(ext) {
364
- return EXTENSION_MIME_MAP[ext.toLowerCase()] || "application/octet-stream";
343
+ return (EXTENSION_MIME_MAP[normalizeExtension(ext)] || "application/octet-stream");
365
344
  }
366
345
  // =============================================================================
367
346
  // TYPE EXPORTS
@@ -38,6 +38,7 @@
38
38
  */
39
39
  import { BaseFileProcessor } from "../base/BaseFileProcessor.js";
40
40
  import { SIZE_LIMITS_MB } from "../config/index.js";
41
+ import { extensionsForModality, mimeTypesForModality, } from "../config/fileTypeRegistry.js";
41
42
  import { FileErrorCode } from "../errors/index.js";
42
43
  import { withTimeout } from "../../utils/timeout.js";
43
44
  import { formatMediaDuration } from "../../utils/mediaDuration.js";
@@ -84,51 +85,28 @@ const AUDIO_CONFIG = {
84
85
  };
85
86
  /**
86
87
  * Supported MIME types for audio files.
87
- * Covers all major audio formats including common variants and aliases.
88
+ *
89
+ * Derived from the canonical registry so this processor cannot claim a format
90
+ * the detector standing in front of it does not recognise. It previously did:
91
+ * .aiff, .amr, .ape, .wv and .oga were all declared here and all resolved to
92
+ * "unknown" during detection, so a file in one of those formats never reached
93
+ * this processor at all.
94
+ *
95
+ * `audio/webm` is appended because WebM is registered as a video container and
96
+ * an audio-only .webm is legitimate input. Only the MIME type is accepted, not
97
+ * the extension: `isFileSupported` matches on extension OR mimetype, so
98
+ * claiming `.webm` here made `isAudioFile("video/webm", "clip.webm")` accept a
99
+ * video-only WebM as audio on its filename alone.
88
100
  */
89
101
  const SUPPORTED_AUDIO_MIME_TYPES = [
90
- "audio/mpeg",
91
- "audio/mp3",
92
- "audio/wav",
93
- "audio/x-wav",
94
- "audio/wave",
95
- "audio/ogg",
96
- "audio/vorbis",
97
- "audio/opus",
98
- "audio/flac",
99
- "audio/x-flac",
100
- "audio/mp4",
101
- "audio/x-m4a",
102
- "audio/aac",
103
- "audio/x-ms-wma",
102
+ ...mimeTypesForModality("audio"),
104
103
  "audio/webm",
105
- "audio/aiff",
106
- "audio/x-aiff",
107
- "audio/amr",
108
- "audio/3gpp",
109
104
  ];
110
105
  /**
111
106
  * Supported file extensions for audio files.
112
- * Includes common audio container formats and lossless variants.
107
+ * Derived from the canonical registry see the note above.
113
108
  */
114
- const SUPPORTED_AUDIO_EXTENSIONS = [
115
- ".mp3",
116
- ".wav",
117
- ".ogg",
118
- ".oga",
119
- ".opus",
120
- ".flac",
121
- ".m4a",
122
- ".aac",
123
- ".wma",
124
- ".webm",
125
- ".aiff",
126
- ".aif",
127
- ".amr",
128
- ".3gp",
129
- ".ape",
130
- ".wv",
131
- ];
109
+ const SUPPORTED_AUDIO_EXTENSIONS = extensionsForModality("audio");
132
110
  // =============================================================================
133
111
  // AUDIO PROCESSOR CLASS
134
112
  // =============================================================================
@@ -52,6 +52,7 @@ import { pipeline } from "stream/promises";
52
52
  import { BaseFileProcessor } from "../base/BaseFileProcessor.js";
53
53
  import { formatMediaDuration } from "../../utils/mediaDuration.js";
54
54
  import { SIZE_LIMITS_MB } from "../config/index.js";
55
+ import { extensionsForModality, mimeTypesForModality, } from "../config/fileTypeRegistry.js";
55
56
  import { FileErrorCode } from "../errors/index.js";
56
57
  import { tracers, ATTR, withSpan } from "../../telemetry/index.js";
57
58
  import { logger } from "../../utils/logger.js";
@@ -174,38 +175,16 @@ const VIDEO_CONFIG = {
174
175
  /** Timeout for ffprobe metadata extraction in milliseconds */
175
176
  FFPROBE_TIMEOUT_MS: 10_000,
176
177
  };
177
- /** Supported video MIME types */
178
- const SUPPORTED_VIDEO_MIME_TYPES = [
179
- "video/mp4",
180
- "video/x-matroska",
181
- "video/quicktime",
182
- "video/webm",
183
- "video/x-msvideo",
184
- "video/x-ms-wmv",
185
- "video/x-flv",
186
- "video/3gpp",
187
- "video/3gpp2",
188
- "video/MP2T",
189
- "video/ogg",
190
- ];
191
- /** Supported video file extensions */
192
- const SUPPORTED_VIDEO_EXTENSIONS = [
193
- ".mp4",
194
- ".m4v",
195
- ".mkv",
196
- ".mov",
197
- ".avi",
198
- ".wmv",
199
- ".flv",
200
- ".webm",
201
- ".3gp",
202
- ".3g2",
203
- ".ts",
204
- ".mts",
205
- ".m2ts",
206
- ".ogv",
207
- ".vob",
208
- ];
178
+ /**
179
+ * Supported video MIME types — derived from the canonical registry so this
180
+ * processor and the detector in front of it cannot disagree about what "video"
181
+ * means. Before the registry they did: .m2ts, .mts, .vob, .3g2 and .ogv were
182
+ * declared supported here and detected as "unknown", and .mpg/.mpeg were
183
+ * detected as CSV.
184
+ */
185
+ const SUPPORTED_VIDEO_MIME_TYPES = mimeTypesForModality("video");
186
+ /** Supported video file extensions — derived from the canonical registry. */
187
+ const SUPPORTED_VIDEO_EXTENSIONS = extensionsForModality("video");
209
188
  /**
210
189
  * Maximum video file size in MB.
211
190
  * Uses VIDEO_MAX_MB (500 MB) to support long meeting recordings and screen captures.
@@ -1,7 +1,7 @@
1
1
  import { ErrorCategory, ErrorSeverity, GoogleAIModels, } from "../../constants/enums.js";
2
2
  import { BaseProvider } from "../../core/baseProvider.js";
3
3
  import { IMAGE_GENERATION_MODELS, TOOL_STORAGE_TIMEOUT_MS, } from "../../core/constants.js";
4
- import { processUnifiedFilesArray } from "../../utils/messageBuilder.js";
4
+ import { normalizeVisionImageFormats, processUnifiedFilesArray, } from "../../utils/messageBuilder.js";
5
5
  import { ATTR, tracers, withClientSpan, withClientStreamSpan, withSpan, } from "../../telemetry/index.js";
6
6
  import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../../types/index.js";
7
7
  import { ERROR_CODES, NeuroLinkError } from "../../utils/errorHandling.js";
@@ -237,6 +237,13 @@ export class GoogleAIStudioProvider extends BaseProvider {
237
237
  * @returns A promise that resolves to the generation result, including the image data.
238
238
  */
239
239
  async executeImageGeneration(options) {
240
+ // Image-to-image generation takes reference images through the same
241
+ // `input.images` array, and generate() routes here BEFORE reaching its own
242
+ // normalization call — so a reference photo in HEIC/BMP/AVIF would arrive
243
+ // at the API untranscoded. Normalizing at the top of this method covers
244
+ // every route in, rather than relying on each caller to remember.
245
+ // Idempotent, so a request that was already normalized pays nothing.
246
+ await normalizeVisionImageFormats(options.input);
240
247
  const prompt = options.prompt || options.input?.text || "";
241
248
  const imageModelName = options.model || this.modelName;
242
249
  const startTime = Date.now();
@@ -1178,6 +1185,10 @@ export class GoogleAIStudioProvider extends BaseProvider {
1178
1185
  logger.warn(`[GoogleAIStudio] processUnifiedFilesArray threw, continuing without file content: ${fileError instanceof Error ? fileError.message : String(fileError)}`);
1179
1186
  }
1180
1187
  }
1188
+ // Runs even without input.files: a caller can populate input.images
1189
+ // directly, and this native path never reaches the shared multimodal
1190
+ // builder that would otherwise normalize the formats.
1191
+ await normalizeVisionImageFormats(options.input);
1181
1192
  // Merge registered (built-in / MCP) tools with caller-supplied tools.
1182
1193
  // AI Studio's generate() bypasses BaseProvider.generate(), so the
1183
1194
  // ToolsManager-driven merge that normally injects sdk.registerTool()