@bedolla/enrivision 0.1.5 → 0.1.7

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 (64) hide show
  1. package/README.md +43 -9
  2. package/dist/client/EnriProxyClient.d.ts +296 -248
  3. package/dist/client/EnriProxyClient.d.ts.map +1 -1
  4. package/dist/client/EnriProxyClient.js +849 -119
  5. package/dist/client/EnriProxyClient.js.map +1 -1
  6. package/dist/client/EnriProxyClientContract.d.ts +478 -0
  7. package/dist/client/EnriProxyClientContract.d.ts.map +1 -0
  8. package/dist/client/EnriProxyClientContract.js +136 -0
  9. package/dist/client/EnriProxyClientContract.js.map +1 -0
  10. package/dist/index.js +23 -12
  11. package/dist/index.js.map +1 -1
  12. package/dist/package-info.d.ts +28 -0
  13. package/dist/package-info.d.ts.map +1 -1
  14. package/dist/package-info.js +28 -0
  15. package/dist/package-info.js.map +1 -1
  16. package/dist/server/EnriVisionServer.d.ts +186 -0
  17. package/dist/server/EnriVisionServer.d.ts.map +1 -1
  18. package/dist/server/EnriVisionServer.js +804 -94
  19. package/dist/server/EnriVisionServer.js.map +1 -1
  20. package/dist/shared/codepointTruncation.d.ts +61 -0
  21. package/dist/shared/codepointTruncation.d.ts.map +1 -0
  22. package/dist/shared/codepointTruncation.js +73 -0
  23. package/dist/shared/codepointTruncation.js.map +1 -0
  24. package/dist/shared/mediaUrlFetcher.d.ts +247 -9
  25. package/dist/shared/mediaUrlFetcher.d.ts.map +1 -1
  26. package/dist/shared/mediaUrlFetcher.js +712 -53
  27. package/dist/shared/mediaUrlFetcher.js.map +1 -1
  28. package/dist/shared/tar.d.ts +82 -2
  29. package/dist/shared/tar.d.ts.map +1 -1
  30. package/dist/shared/tar.js +106 -43
  31. package/dist/shared/tar.js.map +1 -1
  32. package/dist/shared/validation.d.ts +96 -2
  33. package/dist/shared/validation.d.ts.map +1 -1
  34. package/dist/shared/validation.js +169 -10
  35. package/dist/shared/validation.js.map +1 -1
  36. package/dist/tools/AnalyzeMediaContract.d.ts +462 -0
  37. package/dist/tools/AnalyzeMediaContract.d.ts.map +1 -0
  38. package/dist/tools/AnalyzeMediaContract.js +161 -0
  39. package/dist/tools/AnalyzeMediaContract.js.map +1 -0
  40. package/dist/tools/AnalyzeMediaExtractionSanitizer.d.ts +35 -0
  41. package/dist/tools/AnalyzeMediaExtractionSanitizer.d.ts.map +1 -0
  42. package/dist/tools/AnalyzeMediaExtractionSanitizer.js +214 -0
  43. package/dist/tools/AnalyzeMediaExtractionSanitizer.js.map +1 -0
  44. package/dist/tools/AnalyzeMediaInputResolver.d.ts +250 -0
  45. package/dist/tools/AnalyzeMediaInputResolver.d.ts.map +1 -0
  46. package/dist/tools/AnalyzeMediaInputResolver.js +430 -0
  47. package/dist/tools/AnalyzeMediaInputResolver.js.map +1 -0
  48. package/dist/tools/AnalyzeMediaParamParser.d.ts +307 -0
  49. package/dist/tools/AnalyzeMediaParamParser.d.ts.map +1 -0
  50. package/dist/tools/AnalyzeMediaParamParser.js +843 -0
  51. package/dist/tools/AnalyzeMediaParamParser.js.map +1 -0
  52. package/dist/tools/AnalyzeMediaResumableUploader.d.ts +244 -0
  53. package/dist/tools/AnalyzeMediaResumableUploader.d.ts.map +1 -0
  54. package/dist/tools/AnalyzeMediaResumableUploader.js +549 -0
  55. package/dist/tools/AnalyzeMediaResumableUploader.js.map +1 -0
  56. package/dist/tools/AnalyzeMediaTarPackager.d.ts +42 -0
  57. package/dist/tools/AnalyzeMediaTarPackager.d.ts.map +1 -0
  58. package/dist/tools/AnalyzeMediaTarPackager.js +245 -0
  59. package/dist/tools/AnalyzeMediaTarPackager.js.map +1 -0
  60. package/dist/tools/AnalyzeMediaTool.d.ts +156 -294
  61. package/dist/tools/AnalyzeMediaTool.d.ts.map +1 -1
  62. package/dist/tools/AnalyzeMediaTool.js +611 -457
  63. package/dist/tools/AnalyzeMediaTool.js.map +1 -1
  64. package/package.json +2 -1
@@ -0,0 +1,462 @@
1
+ /**
2
+ * ANALYZE MEDIA CONTRACT
3
+ *
4
+ * Public parameter, result, and dependency contracts for the
5
+ * `analyze_media` MCP tool. The facade (`AnalyzeMediaTool`) re-exports
6
+ * these types so external import sites keep working.
7
+ *
8
+ * @module tools/AnalyzeMediaContract
9
+ */
10
+ import type { EnriProxyClient } from "../client/EnriProxyClient.js";
11
+ /**
12
+ * Shared upload and batching limits for the `analyze_media` MCP tool.
13
+ *
14
+ * @remarks
15
+ * Parity note vs EnriCode `vision.analyze_media` (single-file tool):
16
+ * - EnriCode-only (no MCP equivalent, by design): `attachmentIndex`,
17
+ * `attachmentId`, and the required-`question` rule. EnriVision accepts
18
+ * `path`/`paths` only and `question` stays optional.
19
+ * - EnriVision extras (intentional, not bugs): `paths[]` multi-image sets
20
+ * packed as one `application/vnd.enrivision.media-set+tar` archive for
21
+ * server-side batching + reduce, `images.*` tuning, and the
22
+ * `document.pages_per_batch/max_images_per_batch/scanned_text_threshold_chars`
23
+ * multipass knobs beyond EnriCode.
24
+ * - EnriVision validates strictly with Spanish-first bilingual errors (ES first,
25
+ * EN second) and fails (EnriCode coerces
26
+ * and clamps silently); flat aliases (camelCase plus snake_case) are
27
+ * accepted with flat-over-nested precedence, mirroring EnriCode. Flat
28
+ * `segmentSeconds`/`maxSegments` win over nested `video`/`audio` values;
29
+ * differing nested `video` vs `audio` values without a flat fail locally.
30
+ * Nested `document.documentMaxPages` and `audio.audioTimestamps` (plus
31
+ * `audio_timestamps`) are accepted like EnriCode; exponents (`"1e3"`)
32
+ * are rejected on all three surfaces.
33
+ */
34
+ export declare const ANALYZE_MEDIA_LIMITS: {
35
+ /**
36
+ * Maximum accepted upload size in bytes (4 GiB, mirrors EnriProxy).
37
+ */
38
+ readonly maxUploadBytes: number;
39
+ /**
40
+ * Maximum chunk size in bytes per upload request (server value capped).
41
+ *
42
+ * @remarks
43
+ * 16 MiB mirrors EnriProxy (`UploadSessionService` default) and EnriCode
44
+ * `MAX_CHUNK_SIZE_BYTES`: 4 GiB needs ~256 PATCH instead of ~512.
45
+ */
46
+ readonly maxChunkBytes: number;
47
+ /**
48
+ * Maximum entries accepted in `paths[]` before materializing downloads.
49
+ */
50
+ readonly maxPathsCount: 100;
51
+ /**
52
+ * Maximum prompt characters accepted for `question`/`context` (mirrors
53
+ * EnriProxy `VISION_MAX_QUESTION_CHARS`/`VISION_MAX_CONTEXT_CHARS`):
54
+ * oversized prompts fail fast here, before any byte is uploaded.
55
+ */
56
+ readonly maxPromptChars: 2000;
57
+ /**
58
+ * Maximum clip-window bound in seconds (0-86400, 24 h).
59
+ */
60
+ readonly maxClipSeconds: 86400;
61
+ /**
62
+ * Maximum characters of server analysis text forwarded to the model.
63
+ */
64
+ readonly maxAnalysisTextChars: 30000;
65
+ /**
66
+ * Maximum characters of analysis text kept inside `structuredContent`.
67
+ *
68
+ * @remarks
69
+ * MCP delivers the whole result in one JSON frame, so the full payload is
70
+ * truncated here too (with `analysis_truncated` + `analysis_total_chars`):
71
+ * small clients pay parse/memory cost regardless of text truncation.
72
+ * Budgeted in code points (not UTF-8 bytes) on purpose: MCP hosts parse
73
+ * JSON into UTF-16 strings, and seam-safe slicing must never split
74
+ * surrogate pairs. This diverges knowingly from EnriCode's 256 KiB byte
75
+ * envelope: astral-heavy analyses ship more wire bytes here, but never
76
+ * more characters, and `analysis_total_chars` keeps the cut honest.
77
+ */
78
+ readonly maxStructuredContentAnalysisChars: 262144;
79
+ /**
80
+ * Code points of the structured analysis budget kept at the start.
81
+ *
82
+ * @remarks
83
+ * The remainder (`maxStructuredContentAnalysisChars` minus this head)
84
+ * is kept at the end: conclusions live at the tail of long analyses,
85
+ * so head-only truncation would drop exactly what small models need.
86
+ */
87
+ readonly maxStructuredContentAnalysisHeadChars: 200000;
88
+ /**
89
+ * Maximum serialized characters of `extraction` kept inside
90
+ * `structuredContent` (512 KiB).
91
+ *
92
+ * @remarks
93
+ * Multipass timelines can grow without bound; past this cap long strings
94
+ * are head+tail cut (shape preserved) instead of shipping megabytes of
95
+ * metadata to small MCP clients. Code points, like the analysis budget
96
+ * above; the 32768 per-string cap stays wider than EnriCode's 16 KiB
97
+ * field cap because MCP has no separate byte envelope to absorb the
98
+ * remainder (the shape-preserving cut is the only bound).
99
+ */
100
+ readonly maxStructuredContentExtractionChars: 524288;
101
+ /**
102
+ * Maximum characters kept per string when bounding `extraction`.
103
+ */
104
+ readonly maxBoundExtractionStringChars: 32768;
105
+ /**
106
+ * Unary analyze timeout for `analysis_mode: "single"` (10 min, mirrors
107
+ * EnriCode `ANALYZE_TIMEOUT_MS` and the EnriProxy single-pass stage budget).
108
+ *
109
+ * @remarks
110
+ * The operator `ENRIVISION_TIMEOUT_MS` still caps it via `Math.min`.
111
+ */
112
+ readonly singleAnalyzeTimeoutMs: number;
113
+ /**
114
+ * Unary analyze timeout for `analysis_mode: "multipass"` and `"auto"`
115
+ * (20 min, mirrors EnriCode `MULTIPASS_ANALYZE_TIMEOUT_MS` and the server
116
+ * multipass wall-clock budget).
117
+ *
118
+ * @remarks
119
+ * `auto` shares the multipass budget because the server may escalate to
120
+ * multipass (long videos, scanned PDFs over the page threshold) and the
121
+ * client cannot know upfront. The operator `ENRIVISION_TIMEOUT_MS` still
122
+ * caps it via `Math.min`.
123
+ */
124
+ readonly multipassAnalyzeTimeoutMs: number;
125
+ /**
126
+ * Budget for the fail-open vision-capability probe (`GET
127
+ * `/v1/account/models`, 15 s, mirrors EnriCode).
128
+ */
129
+ readonly visionProbeTimeoutMs: 15000;
130
+ /**
131
+ * Time-to-live for cached vision-capability verdicts (5 min, mirrors EnriCode
132
+ * `PROBE_CACHE_TTL_MS`).
133
+ */
134
+ readonly visionProbeCacheTtlMs: number;
135
+ };
136
+ /**
137
+ * Machine-readable error codes surfaced in `structuredContent` on MCP tool errors.
138
+ *
139
+ * @remarks
140
+ * Reuses the EnriCode `VisionAnalyzeMediaErrorMapper` vocabulary so OpenAI-compatible
141
+ * third-party clients can branch programmatically (retryable 429/5xx and timeouts vs
142
+ * terminal input/auth errors vs aborts) instead of parsing human text.
143
+ */
144
+ export declare const ANALYZE_MEDIA_ERROR_CODES: {
145
+ /**
146
+ * Caller-side argument or tuning error (400/422 from the proxy included): never retry unchanged.
147
+ */
148
+ readonly inputInvalid: "ENRICODE_ERR_TOOL_INPUT_INVALID";
149
+ /**
150
+ * Server-side or transport execution failure: retry only when `retryable` is true.
151
+ */
152
+ readonly executionFailed: "ENRICODE_ERR_TOOL_EXECUTION_FAILED";
153
+ /**
154
+ * Analysis or upload deadline exceeded: retry with a smaller scope once.
155
+ */
156
+ readonly executionTimeout: "ENRICODE_ERR_TOOL_EXECUTION_TIMEOUT";
157
+ /**
158
+ * Caller-cancelled request: do not retry automatically.
159
+ */
160
+ readonly executionAborted: "ENRICODE_ERR_TOOL_EXECUTION_ABORTED";
161
+ };
162
+ /**
163
+ * One machine-readable MCP error code (see {@link ANALYZE_MEDIA_ERROR_CODES}).
164
+ */
165
+ export type AnalyzeMediaErrorCode = (typeof ANALYZE_MEDIA_ERROR_CODES)[keyof typeof ANALYZE_MEDIA_ERROR_CODES];
166
+ /**
167
+ * Relative image region for native-resolution zoom (images only).
168
+ */
169
+ export interface ImageRegion {
170
+ /**
171
+ * Relative horizontal coordinate of the top-left corner (0 = left edge).
172
+ */
173
+ readonly x: number;
174
+ /**
175
+ * Relative vertical coordinate of the top-left corner (0 = top edge).
176
+ */
177
+ readonly y: number;
178
+ /**
179
+ * Relative width (1 = full width).
180
+ */
181
+ readonly width: number;
182
+ /**
183
+ * Relative height (1 = full height).
184
+ */
185
+ readonly height: number;
186
+ }
187
+ /**
188
+ * Tool parameters for `analyze_media`.
189
+ */
190
+ export interface AnalyzeMediaToolParams {
191
+ /**
192
+ * Absolute local filesystem path on the MCP host, or one http(s) URL to
193
+ * download (bounded, temporary) and analyze.
194
+ *
195
+ * @remarks
196
+ * Use `paths` to analyze multiple images in a single call. When `paths`
197
+ * carries at least one valid entry, `path` is ignored.
198
+ */
199
+ readonly path?: string;
200
+ /**
201
+ * Absolute local filesystem paths or http(s) URLs on the MCP host.
202
+ *
203
+ * @remarks
204
+ * When provided, EnriVision uploads the files as a single media-set archive
205
+ * (resumable, up to 4GB) and triggers server-side batching + reduce.
206
+ *
207
+ * This is intended for many UI screenshots / photo sets. Blank entries are
208
+ * discarded; when at least one valid entry remains, `path` is ignored.
209
+ */
210
+ readonly paths?: ReadonlyArray<string>;
211
+ /**
212
+ * Optional analysis hint (ui, diagram, chart, error, code, meeting, tutorial, photo).
213
+ */
214
+ readonly context?: string;
215
+ /**
216
+ * Optional explicit user question.
217
+ */
218
+ readonly question?: string;
219
+ /**
220
+ * Preferred response language code (e.g., "es", "en").
221
+ */
222
+ readonly language?: string;
223
+ /**
224
+ * Optional max frames override for videos (integer 1-20, default 20).
225
+ */
226
+ readonly maxFrames?: number;
227
+ /**
228
+ * Optional override for transcription on videos.
229
+ */
230
+ readonly transcribe?: boolean;
231
+ /**
232
+ * Optional transcription language hint for Whisper.
233
+ */
234
+ readonly transcriptionLanguage?: string;
235
+ /**
236
+ * Optional analysis mode selector (auto|single|multipass).
237
+ */
238
+ readonly analysisMode?: "auto" | "single" | "multipass";
239
+ /**
240
+ * Optional video multipass tuning.
241
+ */
242
+ readonly video?: {
243
+ /**
244
+ * Optional clip start offset in seconds for targeted video analysis.
245
+ *
246
+ * @remarks
247
+ * Use this when the question references a specific timestamp to avoid
248
+ * scanning the full timeline.
249
+ */
250
+ readonly clipStartSeconds?: number;
251
+ /**
252
+ * Optional clip duration in seconds for targeted video analysis.
253
+ *
254
+ * @remarks
255
+ * Use together with {@link clipStartSeconds} to analyze only a time window.
256
+ */
257
+ readonly clipDurationSeconds?: number;
258
+ /**
259
+ * Segment duration in seconds (5-600, default 60).
260
+ */
261
+ readonly segmentSeconds?: number;
262
+ /**
263
+ * Maximum number of segments to analyze (integer 1-60, mirrors EnriProxy).
264
+ */
265
+ readonly maxSegments?: number;
266
+ /**
267
+ * Maximum frames per segment (integer 1-20, default 8).
268
+ */
269
+ readonly maxFramesPerSegment?: number;
270
+ };
271
+ /**
272
+ * Optional document multipass tuning (PDF).
273
+ */
274
+ readonly document?: {
275
+ /**
276
+ * Maximum pages to analyze in total (integer 1-200, default 20, mirrors EnriProxy).
277
+ */
278
+ readonly maxPagesTotal?: number;
279
+ /**
280
+ * Pages per batch (integer 1-200, mirrors EnriProxy).
281
+ */
282
+ readonly pagesPerBatch?: number;
283
+ /**
284
+ * Maximum rendered pages per batch (integer 0-20, 0 = no render, mirrors EnriProxy).
285
+ */
286
+ readonly maxImagesPerBatch?: number;
287
+ /**
288
+ * Minimum extracted text length to treat a page as textual (integer 0-5000, mirrors EnriProxy).
289
+ */
290
+ readonly scannedTextThresholdChars?: number;
291
+ };
292
+ /**
293
+ * Optional audio multipass tuning.
294
+ */
295
+ readonly audio?: {
296
+ /**
297
+ * Whether to include timestamped segments in audio extraction.
298
+ */
299
+ readonly timestamps?: boolean;
300
+ /**
301
+ * Segment duration in seconds for audio multipass (5-600, default 60).
302
+ */
303
+ readonly segmentSeconds?: number;
304
+ /**
305
+ * Maximum number of audio segments to analyze (integer 1-60, mirrors EnriProxy).
306
+ */
307
+ readonly maxSegments?: number;
308
+ };
309
+ /**
310
+ * Optional image-set multipass tuning.
311
+ *
312
+ * @remarks
313
+ * Used only when analyzing multiple images via `paths`.
314
+ */
315
+ readonly images?: {
316
+ /**
317
+ * Maximum number of images to analyze in total (integer 1-500, mirrors EnriProxy).
318
+ */
319
+ readonly maxImagesTotal?: number;
320
+ /**
321
+ * Images per batch for multipass map calls (integer 1-20, mirrors EnriProxy).
322
+ */
323
+ readonly imagesPerBatch?: number;
324
+ /**
325
+ * Maximum dimension for images (width/height, integer 256-4096, mirrors EnriProxy).
326
+ */
327
+ readonly maxDimension?: number;
328
+ };
329
+ /**
330
+ * Optional requested model id for server-side dispatch affinity.
331
+ *
332
+ * @remarks
333
+ * Mirrors EnriCode `requestedModelId`: EnriProxy preserves the active
334
+ * model before fallbacks (including the Muse Spark image-count reroute).
335
+ * Omitted (or `ENRIVISION_MODEL`) means auto-dispatch. Unknown keys
336
+ * inside tuning objects are rejected, never ignored.
337
+ */
338
+ readonly model?: string;
339
+ /**
340
+ * Optional relative region of the analyzed image for native-resolution zoom.
341
+ *
342
+ * @remarks
343
+ * Normalized [0,1] coordinates over the original image (0,0 = top-left
344
+ * corner). Use the boxes returned in `elements` of a previous analysis of
345
+ * the same image; never invent coordinates.
346
+ */
347
+ readonly region?: ImageRegion;
348
+ /**
349
+ * Opaque continuation cursor from a truncated response
350
+ * (`segment_summaries_cursor` or `transcription_segments_cursor`).
351
+ *
352
+ * @remarks
353
+ * Continuation mode: no file is uploaded or analyzed; the call only
354
+ * reads the next window of a previously truncated list. `path`/`paths`
355
+ * are ignored while `cursor` is present.
356
+ */
357
+ readonly cursor?: string;
358
+ /**
359
+ * Start index for a continuation read (defaults to the response
360
+ * `next_offset`).
361
+ */
362
+ readonly offset?: number;
363
+ /**
364
+ * Maximum entries to read in one continuation window (1-100; defaults to
365
+ * the server window size).
366
+ */
367
+ readonly continuationLimit?: number;
368
+ /**
369
+ * Parser-generated honesty notes (Spanish-first bilingual, e.g., a clamped clip window).
370
+ *
371
+ * @remarks
372
+ * Present only when parsing adjusted a requested value: `execute` copies
373
+ * these into the result so the model always sees what changed instead of
374
+ * analyzing a silently different window.
375
+ */
376
+ readonly warnings?: ReadonlyArray<string>;
377
+ }
378
+ /**
379
+ * One grounded element box returned by an image analysis.
380
+ */
381
+ export interface AnalyzeMediaElementBox {
382
+ /**
383
+ * Short label naming the grounded element.
384
+ */
385
+ readonly label: string;
386
+ /**
387
+ * Original-relative [0,1] box that can be echoed back as `region`.
388
+ */
389
+ readonly box: ImageRegion;
390
+ }
391
+ /**
392
+ * Structured result for `analyze_media`.
393
+ */
394
+ export interface AnalyzeMediaToolResult extends Record<string, unknown> {
395
+ /**
396
+ * Text analysis produced by EnriProxy.
397
+ */
398
+ readonly analysis: string;
399
+ /**
400
+ * Grounded element boxes for image analyses (original-relative [0,1]).
401
+ */
402
+ readonly elements?: ReadonlyArray<AnalyzeMediaElementBox>;
403
+ /**
404
+ * Detected media type.
405
+ */
406
+ readonly media_type: string;
407
+ /**
408
+ * Parser-generated honesty notes (Spanish-first bilingual, e.g., a clamped clip window).
409
+ *
410
+ * @remarks
411
+ * Copied from the validated params by `execute`: adjustments made before
412
+ * any upload stay visible to the model in both the text output and the
413
+ * structured content.
414
+ */
415
+ readonly warnings?: ReadonlyArray<string>;
416
+ /**
417
+ * Extraction metadata returned by the server.
418
+ *
419
+ * @remarks
420
+ * This metadata is intended for debugging and transparency (e.g., duration,
421
+ * selected frames, warnings). Internal identifiers like upload ids are
422
+ * stripped to avoid leaking implementation details into the model context.
423
+ */
424
+ readonly extraction: Record<string, unknown>;
425
+ }
426
+ /**
427
+ * Execution options for {@link AnalyzeMediaTool.execute}.
428
+ */
429
+ export interface AnalyzeMediaExecutionOptions {
430
+ /**
431
+ * Cancellation signal (e.g., the MCP request `extra.signal`); aborts URL
432
+ * downloads, uploads, and the analysis request with a Spanish error.
433
+ */
434
+ readonly signal?: AbortSignal;
435
+ }
436
+ /**
437
+ * Dependencies for {@link AnalyzeMediaTool}.
438
+ */
439
+ export interface AnalyzeMediaToolDeps {
440
+ /**
441
+ * Creates an EnriProxy client with a base URL, API key, and timeout.
442
+ *
443
+ * @param serverUrl - EnriProxy URL.
444
+ * @param apiKey - EnriProxy API key.
445
+ * @param timeoutMs - Timeout in milliseconds.
446
+ * @returns Client instance.
447
+ */
448
+ readonly createClient: (serverUrl: string, apiKey: string, timeoutMs: number) => EnriProxyClient;
449
+ /**
450
+ * Default EnriProxy server URL.
451
+ */
452
+ readonly defaultServerUrl: string;
453
+ /**
454
+ * Default EnriProxy API key.
455
+ */
456
+ readonly defaultApiKey: string;
457
+ /**
458
+ * Default timeout in milliseconds.
459
+ */
460
+ readonly defaultTimeoutMs: number;
461
+ }
462
+ //# sourceMappingURL=AnalyzeMediaContract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyzeMediaContract.d.ts","sourceRoot":"","sources":["../../src/tools/AnalyzeMediaContract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,161 @@
1
+ /**
2
+ * ANALYZE MEDIA CONTRACT
3
+ *
4
+ * Public parameter, result, and dependency contracts for the
5
+ * `analyze_media` MCP tool. The facade (`AnalyzeMediaTool`) re-exports
6
+ * these types so external import sites keep working.
7
+ *
8
+ * @module tools/AnalyzeMediaContract
9
+ */
10
+ /**
11
+ * Shared upload and batching limits for the `analyze_media` MCP tool.
12
+ *
13
+ * @remarks
14
+ * Parity note vs EnriCode `vision.analyze_media` (single-file tool):
15
+ * - EnriCode-only (no MCP equivalent, by design): `attachmentIndex`,
16
+ * `attachmentId`, and the required-`question` rule. EnriVision accepts
17
+ * `path`/`paths` only and `question` stays optional.
18
+ * - EnriVision extras (intentional, not bugs): `paths[]` multi-image sets
19
+ * packed as one `application/vnd.enrivision.media-set+tar` archive for
20
+ * server-side batching + reduce, `images.*` tuning, and the
21
+ * `document.pages_per_batch/max_images_per_batch/scanned_text_threshold_chars`
22
+ * multipass knobs beyond EnriCode.
23
+ * - EnriVision validates strictly with Spanish-first bilingual errors (ES first,
24
+ * EN second) and fails (EnriCode coerces
25
+ * and clamps silently); flat aliases (camelCase plus snake_case) are
26
+ * accepted with flat-over-nested precedence, mirroring EnriCode. Flat
27
+ * `segmentSeconds`/`maxSegments` win over nested `video`/`audio` values;
28
+ * differing nested `video` vs `audio` values without a flat fail locally.
29
+ * Nested `document.documentMaxPages` and `audio.audioTimestamps` (plus
30
+ * `audio_timestamps`) are accepted like EnriCode; exponents (`"1e3"`)
31
+ * are rejected on all three surfaces.
32
+ */
33
+ export const ANALYZE_MEDIA_LIMITS = {
34
+ /**
35
+ * Maximum accepted upload size in bytes (4 GiB, mirrors EnriProxy).
36
+ */
37
+ maxUploadBytes: 4 * 1024 * 1024 * 1024,
38
+ /**
39
+ * Maximum chunk size in bytes per upload request (server value capped).
40
+ *
41
+ * @remarks
42
+ * 16 MiB mirrors EnriProxy (`UploadSessionService` default) and EnriCode
43
+ * `MAX_CHUNK_SIZE_BYTES`: 4 GiB needs ~256 PATCH instead of ~512.
44
+ */
45
+ maxChunkBytes: 16 * 1024 * 1024,
46
+ /**
47
+ * Maximum entries accepted in `paths[]` before materializing downloads.
48
+ */
49
+ maxPathsCount: 100,
50
+ /**
51
+ * Maximum prompt characters accepted for `question`/`context` (mirrors
52
+ * EnriProxy `VISION_MAX_QUESTION_CHARS`/`VISION_MAX_CONTEXT_CHARS`):
53
+ * oversized prompts fail fast here, before any byte is uploaded.
54
+ */
55
+ maxPromptChars: 2000,
56
+ /**
57
+ * Maximum clip-window bound in seconds (0-86400, 24 h).
58
+ */
59
+ maxClipSeconds: 86400,
60
+ /**
61
+ * Maximum characters of server analysis text forwarded to the model.
62
+ */
63
+ maxAnalysisTextChars: 30000,
64
+ /**
65
+ * Maximum characters of analysis text kept inside `structuredContent`.
66
+ *
67
+ * @remarks
68
+ * MCP delivers the whole result in one JSON frame, so the full payload is
69
+ * truncated here too (with `analysis_truncated` + `analysis_total_chars`):
70
+ * small clients pay parse/memory cost regardless of text truncation.
71
+ * Budgeted in code points (not UTF-8 bytes) on purpose: MCP hosts parse
72
+ * JSON into UTF-16 strings, and seam-safe slicing must never split
73
+ * surrogate pairs. This diverges knowingly from EnriCode's 256 KiB byte
74
+ * envelope: astral-heavy analyses ship more wire bytes here, but never
75
+ * more characters, and `analysis_total_chars` keeps the cut honest.
76
+ */
77
+ maxStructuredContentAnalysisChars: 262144,
78
+ /**
79
+ * Code points of the structured analysis budget kept at the start.
80
+ *
81
+ * @remarks
82
+ * The remainder (`maxStructuredContentAnalysisChars` minus this head)
83
+ * is kept at the end: conclusions live at the tail of long analyses,
84
+ * so head-only truncation would drop exactly what small models need.
85
+ */
86
+ maxStructuredContentAnalysisHeadChars: 200000,
87
+ /**
88
+ * Maximum serialized characters of `extraction` kept inside
89
+ * `structuredContent` (512 KiB).
90
+ *
91
+ * @remarks
92
+ * Multipass timelines can grow without bound; past this cap long strings
93
+ * are head+tail cut (shape preserved) instead of shipping megabytes of
94
+ * metadata to small MCP clients. Code points, like the analysis budget
95
+ * above; the 32768 per-string cap stays wider than EnriCode's 16 KiB
96
+ * field cap because MCP has no separate byte envelope to absorb the
97
+ * remainder (the shape-preserving cut is the only bound).
98
+ */
99
+ maxStructuredContentExtractionChars: 524288,
100
+ /**
101
+ * Maximum characters kept per string when bounding `extraction`.
102
+ */
103
+ maxBoundExtractionStringChars: 32768,
104
+ /**
105
+ * Unary analyze timeout for `analysis_mode: "single"` (10 min, mirrors
106
+ * EnriCode `ANALYZE_TIMEOUT_MS` and the EnriProxy single-pass stage budget).
107
+ *
108
+ * @remarks
109
+ * The operator `ENRIVISION_TIMEOUT_MS` still caps it via `Math.min`.
110
+ */
111
+ singleAnalyzeTimeoutMs: 10 * 60 * 1000,
112
+ /**
113
+ * Unary analyze timeout for `analysis_mode: "multipass"` and `"auto"`
114
+ * (20 min, mirrors EnriCode `MULTIPASS_ANALYZE_TIMEOUT_MS` and the server
115
+ * multipass wall-clock budget).
116
+ *
117
+ * @remarks
118
+ * `auto` shares the multipass budget because the server may escalate to
119
+ * multipass (long videos, scanned PDFs over the page threshold) and the
120
+ * client cannot know upfront. The operator `ENRIVISION_TIMEOUT_MS` still
121
+ * caps it via `Math.min`.
122
+ */
123
+ multipassAnalyzeTimeoutMs: 20 * 60 * 1000,
124
+ /**
125
+ * Budget for the fail-open vision-capability probe (`GET
126
+ * `/v1/account/models`, 15 s, mirrors EnriCode).
127
+ */
128
+ visionProbeTimeoutMs: 15_000,
129
+ /**
130
+ * Time-to-live for cached vision-capability verdicts (5 min, mirrors EnriCode
131
+ * `PROBE_CACHE_TTL_MS`).
132
+ */
133
+ visionProbeCacheTtlMs: 5 * 60 * 1000,
134
+ };
135
+ /**
136
+ * Machine-readable error codes surfaced in `structuredContent` on MCP tool errors.
137
+ *
138
+ * @remarks
139
+ * Reuses the EnriCode `VisionAnalyzeMediaErrorMapper` vocabulary so OpenAI-compatible
140
+ * third-party clients can branch programmatically (retryable 429/5xx and timeouts vs
141
+ * terminal input/auth errors vs aborts) instead of parsing human text.
142
+ */
143
+ export const ANALYZE_MEDIA_ERROR_CODES = {
144
+ /**
145
+ * Caller-side argument or tuning error (400/422 from the proxy included): never retry unchanged.
146
+ */
147
+ inputInvalid: "ENRICODE_ERR_TOOL_INPUT_INVALID",
148
+ /**
149
+ * Server-side or transport execution failure: retry only when `retryable` is true.
150
+ */
151
+ executionFailed: "ENRICODE_ERR_TOOL_EXECUTION_FAILED",
152
+ /**
153
+ * Analysis or upload deadline exceeded: retry with a smaller scope once.
154
+ */
155
+ executionTimeout: "ENRICODE_ERR_TOOL_EXECUTION_TIMEOUT",
156
+ /**
157
+ * Caller-cancelled request: do not retry automatically.
158
+ */
159
+ executionAborted: "ENRICODE_ERR_TOOL_EXECUTION_ABORTED",
160
+ };
161
+ //# sourceMappingURL=AnalyzeMediaContract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyzeMediaContract.js","sourceRoot":"","sources":["../../src/tools/AnalyzeMediaContract.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC;;OAEG;IACH,cAAc,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI;IACtC;;;;;;OAMG;IACH,aAAa,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;IAC/B;;OAEG;IACH,aAAa,EAAE,GAAG;IAClB;;;;OAIG;IACH,cAAc,EAAE,IAAI;IACpB;;OAEG;IACH,cAAc,EAAE,KAAK;IACrB;;OAEG;IACH,oBAAoB,EAAE,KAAK;IAC3B;;;;;;;;;;;;OAYG;IACH,iCAAiC,EAAE,MAAM;IACzC;;;;;;;OAOG;IACH,qCAAqC,EAAE,MAAM;IAC7C;;;;;;;;;;;OAWG;IACH,mCAAmC,EAAE,MAAM;IAC3C;;OAEG;IACH,6BAA6B,EAAE,KAAK;IACpC;;;;;;OAMG;IACH,sBAAsB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IACtC;;;;;;;;;;OAUG;IACH,yBAAyB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;IACzC;;;OAGG;IACH,oBAAoB,EAAE,MAAM;IAC5B;;;OAGG;IACH,qBAAqB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;CAC5B,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC;;OAEG;IACH,YAAY,EAAE,iCAAiC;IAC/C;;OAEG;IACH,eAAe,EAAE,oCAAoC;IACrD;;OAEG;IACH,gBAAgB,EAAE,qCAAqC;IACvD;;OAEG;IACH,gBAAgB,EAAE,qCAAqC;CAC/C,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * ANALYZE MEDIA EXTRACTION SANITIZER
3
+ *
4
+ * Strips routing-only internals from the EnriProxy extraction payload before
5
+ * it reaches the model. Only upload identifiers, provider-routing identities,
6
+ * and secret-bearing keys are removed: coverage metadata that EnriProxy
7
+ * intentionally returns (`detected_media_type`, `analysis_mode_*`,
8
+ * `multipass`, `models`, `strategy`, `warnings`, `frame_count`, `timeline`)
9
+ * is preserved so the model can report honest coverage (missing frames).
10
+ *
11
+ * Key matching is separator-insensitive (`-`, `_`, `.` stripped): hyphenated
12
+ * spellings such as `api-key` or `access-token` match like `api_key`.
13
+ *
14
+ * @module tools/AnalyzeMediaExtractionSanitizer
15
+ */
16
+ /**
17
+ * Sanitizes EnriProxy extraction payloads for model consumption.
18
+ */
19
+ export declare class AnalyzeMediaExtractionSanitizer {
20
+ /**
21
+ * Removes internal identifiers from the extraction payload.
22
+ *
23
+ * @param extraction - Raw extraction object returned by EnriProxy.
24
+ * @returns Sanitized plain extraction object.
25
+ */
26
+ sanitize(extraction: Record<string, unknown>): Record<string, unknown>;
27
+ /**
28
+ * Recursively strips internal fields from an unknown value.
29
+ *
30
+ * @param value - Unknown value to sanitize.
31
+ * @returns Sanitized value.
32
+ */
33
+ private stripInternalFields;
34
+ }
35
+ //# sourceMappingURL=AnalyzeMediaExtractionSanitizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyzeMediaExtractionSanitizer.d.ts","sourceRoot":"","sources":["../../src/tools/AnalyzeMediaExtractionSanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAoIH;;GAEG;AACH,qBAAa,+BAA+B;IAC1C;;;;;OAKG;IACI,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAQ7E;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;CA0D5B"}