@bedolla/enrivision 0.1.5 → 0.1.6
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/README.md +31 -6
- package/dist/client/EnriProxyClient.d.ts +289 -244
- package/dist/client/EnriProxyClient.d.ts.map +1 -1
- package/dist/client/EnriProxyClient.js +841 -115
- package/dist/client/EnriProxyClient.js.map +1 -1
- package/dist/client/EnriProxyClientContract.d.ts +425 -0
- package/dist/client/EnriProxyClientContract.d.ts.map +1 -0
- package/dist/client/EnriProxyClientContract.js +87 -0
- package/dist/client/EnriProxyClientContract.js.map +1 -0
- package/dist/index.js +23 -12
- package/dist/index.js.map +1 -1
- package/dist/package-info.d.ts +28 -0
- package/dist/package-info.d.ts.map +1 -1
- package/dist/package-info.js +28 -0
- package/dist/package-info.js.map +1 -1
- package/dist/server/EnriVisionServer.d.ts +186 -0
- package/dist/server/EnriVisionServer.d.ts.map +1 -1
- package/dist/server/EnriVisionServer.js +780 -93
- package/dist/server/EnriVisionServer.js.map +1 -1
- package/dist/shared/codepointTruncation.d.ts +61 -0
- package/dist/shared/codepointTruncation.d.ts.map +1 -0
- package/dist/shared/codepointTruncation.js +73 -0
- package/dist/shared/codepointTruncation.js.map +1 -0
- package/dist/shared/mediaUrlFetcher.d.ts +247 -9
- package/dist/shared/mediaUrlFetcher.d.ts.map +1 -1
- package/dist/shared/mediaUrlFetcher.js +712 -53
- package/dist/shared/mediaUrlFetcher.js.map +1 -1
- package/dist/shared/tar.d.ts +82 -2
- package/dist/shared/tar.d.ts.map +1 -1
- package/dist/shared/tar.js +106 -43
- package/dist/shared/tar.js.map +1 -1
- package/dist/shared/validation.d.ts +96 -2
- package/dist/shared/validation.d.ts.map +1 -1
- package/dist/shared/validation.js +169 -10
- package/dist/shared/validation.js.map +1 -1
- package/dist/tools/AnalyzeMediaContract.d.ts +457 -0
- package/dist/tools/AnalyzeMediaContract.d.ts.map +1 -0
- package/dist/tools/AnalyzeMediaContract.js +161 -0
- package/dist/tools/AnalyzeMediaContract.js.map +1 -0
- package/dist/tools/AnalyzeMediaExtractionSanitizer.d.ts +35 -0
- package/dist/tools/AnalyzeMediaExtractionSanitizer.d.ts.map +1 -0
- package/dist/tools/AnalyzeMediaExtractionSanitizer.js +214 -0
- package/dist/tools/AnalyzeMediaExtractionSanitizer.js.map +1 -0
- package/dist/tools/AnalyzeMediaInputResolver.d.ts +250 -0
- package/dist/tools/AnalyzeMediaInputResolver.d.ts.map +1 -0
- package/dist/tools/AnalyzeMediaInputResolver.js +430 -0
- package/dist/tools/AnalyzeMediaInputResolver.js.map +1 -0
- package/dist/tools/AnalyzeMediaParamParser.d.ts +299 -0
- package/dist/tools/AnalyzeMediaParamParser.d.ts.map +1 -0
- package/dist/tools/AnalyzeMediaParamParser.js +824 -0
- package/dist/tools/AnalyzeMediaParamParser.js.map +1 -0
- package/dist/tools/AnalyzeMediaResumableUploader.d.ts +244 -0
- package/dist/tools/AnalyzeMediaResumableUploader.d.ts.map +1 -0
- package/dist/tools/AnalyzeMediaResumableUploader.js +549 -0
- package/dist/tools/AnalyzeMediaResumableUploader.js.map +1 -0
- package/dist/tools/AnalyzeMediaTarPackager.d.ts +42 -0
- package/dist/tools/AnalyzeMediaTarPackager.d.ts.map +1 -0
- package/dist/tools/AnalyzeMediaTarPackager.js +245 -0
- package/dist/tools/AnalyzeMediaTarPackager.js.map +1 -0
- package/dist/tools/AnalyzeMediaTool.d.ts +155 -294
- package/dist/tools/AnalyzeMediaTool.d.ts.map +1 -1
- package/dist/tools/AnalyzeMediaTool.js +600 -457
- package/dist/tools/AnalyzeMediaTool.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ This is useful for media types that many MCP clients cannot read reliably (video
|
|
|
11
11
|
|
|
12
12
|
## Requirements
|
|
13
13
|
|
|
14
|
-
- Node.js `>=
|
|
14
|
+
- Node.js `>= 24`
|
|
15
15
|
- A reachable EnriProxy server with these endpoints enabled:
|
|
16
16
|
- `POST /v1/uploads`
|
|
17
17
|
- `HEAD /v1/uploads/:id`
|
|
@@ -85,7 +85,7 @@ Example: no install (always uses whatever npm currently tags as `latest`)
|
|
|
85
85
|
"EnriVision": {
|
|
86
86
|
"type": "stdio",
|
|
87
87
|
"command": "node",
|
|
88
|
-
"args": ["C
|
|
88
|
+
"args": ["C:\\Users\\Administrator\\Projects\\EnriVision\\dist\\index.js"],
|
|
89
89
|
"env": {
|
|
90
90
|
"ENRIPROXY_URL": "http://127.0.0.1:8787",
|
|
91
91
|
"ENRIPROXY_API_KEY": "YOUR_ENRIPROXY_API_KEY",
|
|
@@ -104,9 +104,34 @@ EnriVision is configured via environment variables:
|
|
|
104
104
|
- `ENRIPROXY_URL` (`string`, optional, default: `http://127.0.0.1:8787`)
|
|
105
105
|
- `ENRIPROXY_API_KEY` (`string`, required)
|
|
106
106
|
- `ENRIVISION_TIMEOUT_MS` (`string`, optional, default: `1800000`)
|
|
107
|
-
- Parsed as an integer (milliseconds). Uploads are performed in chunks;
|
|
107
|
+
- Parsed as an integer (milliseconds). This is the operator cap: the per-call analyze timeout is `min(operator, mode budget)` with `single` = 10 min (one pass, fast/cheap), `multipass`/`auto` = 20 min (per-segment/batch map + reduce; `auto` may escalate to multipass server-side). Uploads are performed in chunks; per-chunk timeouts honor `min(operator, derived 30s..300s)` floored at 30 s (an operator budget below 30 s never forces tighter single-chunk budgets).
|
|
108
108
|
- `ENRIVISION_DEFAULT_LANGUAGE` (`string`, optional)
|
|
109
109
|
- Default language to send when the tool call does not provide `language`.
|
|
110
|
+
- `ENRIVISION_DENY_SYMLINKS` (`string`, optional)
|
|
111
|
+
- Set to `1` to reject symlinked `path`/`paths` inputs. Strict mode opens with `O_NOFOLLOW` (POSIX) and compares the `dev:ino` handle identity from `fstat`. On Windows (`win32`) `O_NOFOLLOW` is `0` (advisory only), so strict mode there rests solely on the `lstat`-vs-`fstat` comparison with a small swap window: prefer POSIX hosts when symlink races are in scope.
|
|
112
|
+
- `ENRIVISION_MODEL` (`string`, optional)
|
|
113
|
+
- Model id for server-side dispatch affinity; omit for auto-dispatch.
|
|
114
|
+
- `ENRIVISION_QUIET` (`string`, optional)
|
|
115
|
+
- Set to `1` to silence upload/retry progress lines on stderr.
|
|
116
|
+
|
|
117
|
+
## Analysis budgets
|
|
118
|
+
|
|
119
|
+
The client analyze timeout is `min(ENRIVISION_TIMEOUT_MS, mode budget)`:
|
|
120
|
+
|
|
121
|
+
- `single` → 10 min (mirrors EnriCode and the EnriProxy single-pass stage budget).
|
|
122
|
+
- `multipass` → 20 min (mirrors EnriCode and the server multipass wall-clock budget).
|
|
123
|
+
- `auto` (default) → 20 min: the server picks the mode and may escalate to multipass, so the client cannot assume the short budget. If unsure, omit tuning (`auto`).
|
|
124
|
+
|
|
125
|
+
## Error shape
|
|
126
|
+
|
|
127
|
+
Tool failures return MCP `isError` with Spanish-first bilingual text (ES first, EN second) plus machine-readable `structuredContent: { code, retryable, httpStatus? }` reusing the EnriCode vocabulary:
|
|
128
|
+
|
|
129
|
+
- `ENRICODE_ERR_TOOL_INPUT_INVALID` — argument/tuning errors (including proxy 400/422). Never retry unchanged (`retryable: false`).
|
|
130
|
+
- `ENRICODE_ERR_TOOL_EXECUTION_FAILED` — server/transport failures. `retryable` is true for 408/429/5xx, false otherwise.
|
|
131
|
+
- `ENRICODE_ERR_TOOL_EXECUTION_TIMEOUT` — expired upload/analyze budgets (`retryable: true`; retry with a smaller scope).
|
|
132
|
+
- `ENRICODE_ERR_TOOL_EXECUTION_ABORTED` — caller-cancelled (`retryable: false`).
|
|
133
|
+
|
|
134
|
+
`httpStatus` is present only when the failure carries a proxy HTTP status.
|
|
110
135
|
|
|
111
136
|
## MCP tools
|
|
112
137
|
|
|
@@ -120,7 +145,7 @@ EnriVision exposes this MCP tool:
|
|
|
120
145
|
General notes:
|
|
121
146
|
|
|
122
147
|
- The tool accepts a single JSON object as its input (the MCP `arguments`).
|
|
123
|
-
-
|
|
148
|
+
- At least one of `path` or `paths` is required. When `paths` carries at least one valid entry, `path` is ignored (explicit ignore-path contract: sending both is allowed, `path` is silently ignored — prefer oneOf semantics and send only one).
|
|
124
149
|
- Paths must be absolute on the machine running the MCP server, or http(s) URLs. URLs are downloaded to a temporary directory on the MCP host (up to 64 MiB each; localhost and private-network destinations are blocked) and deleted after analysis.
|
|
125
150
|
- EnriVision does not accept per-call `server_url`/`api_key` overrides (these are configured via env vars).
|
|
126
151
|
|
|
@@ -135,7 +160,7 @@ Inputs:
|
|
|
135
160
|
- `language` (`string`, optional): preferred response language (ISO 639-1; e.g., `es`, `en`). If omitted, uses `ENRIVISION_DEFAULT_LANGUAGE` when set.
|
|
136
161
|
- `analysis_mode` (`string`, optional): `auto` | `single` | `multipass`.
|
|
137
162
|
- `max_frames` (`number`, optional): single-pass video frames (`1..20`).
|
|
138
|
-
- `transcribe` (`boolean`, optional): enable/disable transcription (videos).
|
|
163
|
+
- `transcribe` (`boolean`, optional): enable/disable transcription (videos). Has no effect on images/documents (declared in `warnings`, ignored).
|
|
139
164
|
- `transcription_language` (`string`, optional): whisper hint (`auto`, `es`, `en`, ...).
|
|
140
165
|
|
|
141
166
|
Video targeting:
|
|
@@ -169,7 +194,7 @@ Example `arguments` object:
|
|
|
169
194
|
|
|
170
195
|
```jsonc
|
|
171
196
|
{
|
|
172
|
-
"path": "C
|
|
197
|
+
"path": "C:\\path\\to\\video.mp4",
|
|
173
198
|
"question": "What are the key steps demonstrated?",
|
|
174
199
|
"analysis_mode": "auto",
|
|
175
200
|
"transcribe": true,
|
|
@@ -9,95 +9,35 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @module client/EnriProxyClient
|
|
11
11
|
*/
|
|
12
|
+
import { type AnalyzeVisionParams, type AnalyzeVisionResponse, type AppendUploadChunkParams, type CreateUploadSessionParams, type CreateUploadSessionResponse, type EnriProxyClientConfig, type FetchSegmentPageParams, type SegmentPageResponse } from "./EnriProxyClientContract.js";
|
|
13
|
+
export { EnriProxyHttpError } from "./EnriProxyClientContract.js";
|
|
14
|
+
export type { AnalyzeVisionElement, AnalyzeVisionParams, AnalyzeVisionResponse, AppendUploadChunkParams, CreateUploadSessionParams, CreateUploadSessionResponse, FetchSegmentPageParams, EnriProxyAudioTuning, EnriProxyClientConfig, EnriProxyDocumentTuning, EnriProxyHttpResult, EnriProxyImageRegion, EnriProxyImagesTuning, EnriProxyVideoTuning, SegmentPageResponse, } from "./EnriProxyClientContract.js";
|
|
12
15
|
/**
|
|
13
|
-
*
|
|
16
|
+
* Timeout for upload session creation (`POST /v1/uploads`, 60 s).
|
|
17
|
+
*
|
|
18
|
+
* @remarks
|
|
19
|
+
* Mirrors EnriCode `VisionAnalyzeMediaUploadCoordinator` (60 s create
|
|
20
|
+
* budget): session creation is a tiny metadata call, but it deserves more
|
|
21
|
+
* headroom than offset probes. Capped by the operator timeout via `Math.min`.
|
|
14
22
|
*/
|
|
15
|
-
export
|
|
16
|
-
/**
|
|
17
|
-
* EnriProxy base URL (e.g., https://proxy.example.com).
|
|
18
|
-
*/
|
|
19
|
-
readonly baseUrl: string;
|
|
20
|
-
/**
|
|
21
|
-
* EnriProxy API key (sent as Authorization: Bearer ...).
|
|
22
|
-
*/
|
|
23
|
-
readonly apiKey: string;
|
|
24
|
-
/**
|
|
25
|
-
* Default request timeout in milliseconds.
|
|
26
|
-
*/
|
|
27
|
-
readonly timeoutMs: number;
|
|
28
|
-
}
|
|
23
|
+
export declare const CREATE_CONTROL_TIMEOUT_MS: number;
|
|
29
24
|
/**
|
|
30
|
-
*
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*/
|
|
36
|
-
readonly upload_id: string;
|
|
37
|
-
/**
|
|
38
|
-
* Recommended chunk size in bytes.
|
|
39
|
-
*/
|
|
40
|
-
readonly chunk_size_bytes: number;
|
|
41
|
-
/**
|
|
42
|
-
* Expiration timestamp in ms since epoch.
|
|
43
|
-
*/
|
|
44
|
-
readonly expires_at: number;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Response from POST `/v1/vision/analyze`.
|
|
25
|
+
* Timeout for upload offset probes (`HEAD /v1/uploads/:id`, 15 s).
|
|
26
|
+
*
|
|
27
|
+
* @remarks
|
|
28
|
+
* Mirrors EnriCode (15 s probe budget): offset queries are single-header
|
|
29
|
+
* reads and must fail fast. Capped by the operator timeout via `Math.min`.
|
|
48
30
|
*/
|
|
49
|
-
export
|
|
50
|
-
/**
|
|
51
|
-
* Text analysis.
|
|
52
|
-
*/
|
|
53
|
-
readonly analysis: string;
|
|
54
|
-
/**
|
|
55
|
-
* Grounded element boxes for image analyses (original-relative [0,1]).
|
|
56
|
-
*/
|
|
57
|
-
readonly elements?: ReadonlyArray<{
|
|
58
|
-
readonly label: string;
|
|
59
|
-
readonly box: {
|
|
60
|
-
readonly x: number;
|
|
61
|
-
readonly y: number;
|
|
62
|
-
readonly width: number;
|
|
63
|
-
readonly height: number;
|
|
64
|
-
};
|
|
65
|
-
}>;
|
|
66
|
-
/**
|
|
67
|
-
* Detected media type.
|
|
68
|
-
*/
|
|
69
|
-
readonly media_type: string;
|
|
70
|
-
/**
|
|
71
|
-
* Extraction metadata.
|
|
72
|
-
*/
|
|
73
|
-
readonly extraction: Record<string, unknown>;
|
|
74
|
-
}
|
|
31
|
+
export declare const PROBE_CONTROL_TIMEOUT_MS: number;
|
|
75
32
|
/**
|
|
76
|
-
*
|
|
33
|
+
* Budget for the fail-open vision-capability probe (`GET /v1/account/models`, 15 s).
|
|
34
|
+
*
|
|
35
|
+
* @remarks
|
|
36
|
+
* Mirrors EnriCode `assertRemoteVisionCapable` and
|
|
37
|
+
* `ANALYZE_MEDIA_LIMITS.visionProbeTimeoutMs` (pinned equal by tests): the
|
|
38
|
+
* probe must never stall session creation.
|
|
77
39
|
*/
|
|
78
|
-
export declare
|
|
79
|
-
/**
|
|
80
|
-
* HTTP status code returned by the server.
|
|
81
|
-
*/
|
|
82
|
-
readonly status: number;
|
|
83
|
-
/**
|
|
84
|
-
* Response headers returned by the server.
|
|
85
|
-
*/
|
|
86
|
-
readonly headers: Record<string, string | string[] | undefined>;
|
|
87
|
-
/**
|
|
88
|
-
* Response body returned by the server (best-effort UTF-8).
|
|
89
|
-
*/
|
|
90
|
-
readonly body: string;
|
|
91
|
-
/**
|
|
92
|
-
* Creates a new {@link EnriProxyHttpError}.
|
|
93
|
-
*
|
|
94
|
-
* @param message - Error message
|
|
95
|
-
* @param status - HTTP status code
|
|
96
|
-
* @param headers - Response headers
|
|
97
|
-
* @param body - Response body
|
|
98
|
-
*/
|
|
99
|
-
constructor(message: string, status: number, headers: Record<string, string | string[] | undefined>, body: string);
|
|
100
|
-
}
|
|
40
|
+
export declare const ACCOUNT_MODELS_PROBE_TIMEOUT_MS: number;
|
|
101
41
|
/**
|
|
102
42
|
* Minimal client for EnriProxy HTTP endpoints.
|
|
103
43
|
*/
|
|
@@ -125,192 +65,295 @@ export declare class EnriProxyClient {
|
|
|
125
65
|
*
|
|
126
66
|
* @param params - Session parameters
|
|
127
67
|
* @returns Session response
|
|
68
|
+
* @throws Error with the parsed server detail when creation fails, or when the success body is not valid JSON.
|
|
128
69
|
*/
|
|
129
|
-
createUploadSession(params:
|
|
130
|
-
/**
|
|
131
|
-
* Original filename.
|
|
132
|
-
*/
|
|
133
|
-
readonly filename: string;
|
|
134
|
-
/**
|
|
135
|
-
* Total file size in bytes.
|
|
136
|
-
*/
|
|
137
|
-
readonly sizeBytes: number;
|
|
138
|
-
/**
|
|
139
|
-
* MIME type.
|
|
140
|
-
*/
|
|
141
|
-
readonly contentType: string;
|
|
142
|
-
/**
|
|
143
|
-
* Optional client trace id.
|
|
144
|
-
*/
|
|
145
|
-
readonly clientTraceId?: string;
|
|
146
|
-
}): Promise<CreateUploadSessionResponse>;
|
|
70
|
+
createUploadSession(params: CreateUploadSessionParams): Promise<CreateUploadSessionResponse>;
|
|
147
71
|
/**
|
|
148
72
|
* Queries the current upload offset for a session.
|
|
149
73
|
*
|
|
150
74
|
* @param uploadId - Upload id
|
|
75
|
+
* @param signal - Optional cancellation signal.
|
|
151
76
|
* @returns Offset in bytes
|
|
77
|
+
* @throws Error with the parsed server detail when the query fails.
|
|
152
78
|
*/
|
|
153
|
-
getUploadOffset(uploadId: string): Promise<number>;
|
|
79
|
+
getUploadOffset(uploadId: string, signal?: AbortSignal): Promise<number>;
|
|
80
|
+
/**
|
|
81
|
+
* Deletes an upload session and its stored bytes (best-effort orphan cleanup).
|
|
82
|
+
*
|
|
83
|
+
* @remarks
|
|
84
|
+
* Mirrors `DELETE /v1/uploads/:id` on EnriProxy. Callers must invoke this
|
|
85
|
+
* with an independent timeout signal (never the already-cancelled caller
|
|
86
|
+
* signal) and swallow failures: cleanup must never mask the original
|
|
87
|
+
* upload/analysis error.
|
|
88
|
+
*
|
|
89
|
+
* @param uploadId - Upload id to delete.
|
|
90
|
+
* @param signal - Optional cancellation signal (prefer an independent timeout).
|
|
91
|
+
* @throws Error with an Spanish-first bilingual message when the server rejects the deletion.
|
|
92
|
+
*/
|
|
93
|
+
deleteUploadSession(uploadId: string, signal?: AbortSignal): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Fetches the account model catalog for the fail-open vision probe.
|
|
96
|
+
*
|
|
97
|
+
* @remarks
|
|
98
|
+
* Thin `GET /v1/account/models` reader for `AnalyzeMediaTool` (mirrors
|
|
99
|
+
* EnriCode `assertRemoteVisionCapable`): callers treat every failure as
|
|
100
|
+
* fail-open (proceed with the upload) and only reject on an explicit
|
|
101
|
+
* `vision === false` match, so a stale discovery snapshot never blocks a
|
|
102
|
+
* valid upload. Non-2xx responses throw {@link EnriProxyHttpError} (the
|
|
103
|
+
* caller uses the status to invalidate cached verdicts on 401/404);
|
|
104
|
+
* non-JSON 2xx bodies throw an Spanish-first bilingual error.
|
|
105
|
+
*
|
|
106
|
+
* @param signal - Optional cancellation signal.
|
|
107
|
+
* @returns Parsed response body.
|
|
108
|
+
* @throws Error with an Spanish-first bilingual message when the probe request fails.
|
|
109
|
+
*/
|
|
110
|
+
getAccountModels(signal?: AbortSignal): Promise<unknown>;
|
|
154
111
|
/**
|
|
155
112
|
* Appends a chunk to an upload session.
|
|
156
113
|
*
|
|
157
114
|
* @param params - Chunk parameters
|
|
158
115
|
* @returns New upload offset in bytes
|
|
159
116
|
*/
|
|
160
|
-
appendUploadChunk(params:
|
|
161
|
-
/**
|
|
162
|
-
* Upload session id.
|
|
163
|
-
*/
|
|
164
|
-
readonly uploadId: string;
|
|
165
|
-
/**
|
|
166
|
-
* Expected offset in bytes.
|
|
167
|
-
*/
|
|
168
|
-
readonly offset: number;
|
|
169
|
-
/**
|
|
170
|
-
* Chunk bytes.
|
|
171
|
-
*/
|
|
172
|
-
readonly chunk: Buffer;
|
|
173
|
-
/**
|
|
174
|
-
* Optional timeout override in milliseconds.
|
|
175
|
-
*/
|
|
176
|
-
readonly timeoutMs?: number;
|
|
177
|
-
}): Promise<number>;
|
|
117
|
+
appendUploadChunk(params: AppendUploadChunkParams): Promise<number>;
|
|
178
118
|
/**
|
|
179
119
|
* Triggers server-side vision analysis for an uploaded file.
|
|
180
120
|
*
|
|
181
121
|
* @param params - Analysis parameters
|
|
182
122
|
* @returns Analysis response
|
|
123
|
+
* @throws Error with the parsed server detail when analysis fails, or when the success body is not valid JSON.
|
|
124
|
+
*/
|
|
125
|
+
analyze(params: AnalyzeVisionParams): Promise<AnalyzeVisionResponse>;
|
|
126
|
+
/**
|
|
127
|
+
* Reads one continuation window over a truncated media list.
|
|
128
|
+
*
|
|
129
|
+
* @param params - Cursor plus optional offset/limit.
|
|
130
|
+
* @returns Page entries with totals and continuation state.
|
|
131
|
+
* @throws Error with a Spanish-first bilingual message on invalid
|
|
132
|
+
* cursors, expired cursors, or malformed responses.
|
|
133
|
+
*/
|
|
134
|
+
fetchSegmentPage(params: FetchSegmentPageParams): Promise<SegmentPageResponse>;
|
|
135
|
+
/**
|
|
136
|
+
* Validates one continuation page body.
|
|
137
|
+
*
|
|
138
|
+
* @param raw - Parsed response body.
|
|
139
|
+
* @returns Validated page.
|
|
140
|
+
* @throws Error with a Spanish-first bilingual message when the body
|
|
141
|
+
* carries no usable page.
|
|
142
|
+
*/
|
|
143
|
+
private static requireValidSegmentPage;
|
|
144
|
+
/**
|
|
145
|
+
* Rejects oversized prompt text before any byte is uploaded.
|
|
146
|
+
*
|
|
147
|
+
* @remarks
|
|
148
|
+
* Mirrors the parser gate (2000 chars): the server 400s after upload cost.
|
|
149
|
+
*
|
|
150
|
+
* @param value - Optional prompt text.
|
|
151
|
+
* @param fieldName - `question` or `context`.
|
|
152
|
+
* @throws Error in Spanish naming the 2000-character cap.
|
|
153
|
+
*/
|
|
154
|
+
private static requireBoundedPromptText;
|
|
155
|
+
/**
|
|
156
|
+
* Rejects mistyped tuning before any upload cost on the direct-client path.
|
|
157
|
+
*
|
|
158
|
+
* @remarks
|
|
159
|
+
* Mirrors `AnalyzeMediaParamParser` (enum, language pattern, section
|
|
160
|
+
* key closure): direct callers bypass the tool parser, and a typo would
|
|
161
|
+
* otherwise analyze the whole file at full cost. Exposed for reuse and
|
|
162
|
+
* unit-pinned against the parser key sets.
|
|
163
|
+
*
|
|
164
|
+
* @param params - Analysis parameters about to travel.
|
|
165
|
+
* @throws Error with a Spanish-first bilingual message on the first defect.
|
|
166
|
+
*/
|
|
167
|
+
static requirePreUploadTuning(params: AnalyzeVisionParams): void;
|
|
168
|
+
/**
|
|
169
|
+
* Validates one language hint against the parser pattern.
|
|
170
|
+
*
|
|
171
|
+
* @param value - Candidate hint.
|
|
172
|
+
* @param fieldName - Dotted field name for error messages.
|
|
173
|
+
* @returns Nothing.
|
|
174
|
+
* @throws Error with a Spanish-first bilingual message on mismatch.
|
|
175
|
+
*/
|
|
176
|
+
private static requireLanguageHint;
|
|
177
|
+
/**
|
|
178
|
+
* Rejects unknown keys inside one tuning section.
|
|
179
|
+
*
|
|
180
|
+
* @param section - Candidate section object.
|
|
181
|
+
* @param knownKeys - Parser-owned accepted spellings.
|
|
182
|
+
* @param sectionName - Section name for error messages.
|
|
183
|
+
* @returns Nothing.
|
|
184
|
+
* @throws Error with a Spanish-first bilingual message on unknown keys.
|
|
185
|
+
*/
|
|
186
|
+
private static requireKnownSectionKeys;
|
|
187
|
+
/**
|
|
188
|
+
* Rejects per-batch sizes exceeding their totals on the direct-client path.
|
|
189
|
+
*
|
|
190
|
+
* @remarks
|
|
191
|
+
* The tool parser already guards this; direct callers bypass it, and the
|
|
192
|
+
* server would truncate after paid multipass work.
|
|
193
|
+
*
|
|
194
|
+
* @param perBatch - Per-batch value, or undefined when absent.
|
|
195
|
+
* @param total - Total value, or undefined when absent.
|
|
196
|
+
* @param family - `document` or `images`.
|
|
197
|
+
* @throws Error with an Spanish-first bilingual message when the batch exceeds the total.
|
|
198
|
+
*/
|
|
199
|
+
private static throwOnBatchExceedingTotal;
|
|
200
|
+
/**
|
|
201
|
+
* Coerces an optional integer tuning knob, failing loudly on garbage.
|
|
202
|
+
*
|
|
203
|
+
* @remarks
|
|
204
|
+
* Parity with `AnalyzeMediaParamParser` (`optionalInt` accepts `"60"`):
|
|
205
|
+
* integers and complete integer strings travel floored; any other present
|
|
206
|
+
* value throws bilingually instead of being silently dropped (a dropped
|
|
207
|
+
* knob would analyze the whole file at full cost with default tuning).
|
|
208
|
+
*
|
|
209
|
+
* @param raw - Raw knob value.
|
|
210
|
+
* @param fieldName - Dotted field name for error messages.
|
|
211
|
+
* @param min - Inclusive minimum (shares the parser range table so direct
|
|
212
|
+
* callers fail pre-upload like parser-gated calls).
|
|
213
|
+
* @param max - Inclusive maximum (shares the parser range table).
|
|
214
|
+
* @returns Floored integer, or undefined when absent.
|
|
215
|
+
* @throws Error with an Spanish-first bilingual message when present but not an integer within range.
|
|
216
|
+
*/
|
|
217
|
+
private static requireOptionalInt;
|
|
218
|
+
/**
|
|
219
|
+
* Coerces an optional float tuning knob, failing loudly on garbage.
|
|
220
|
+
*
|
|
221
|
+
* @remarks
|
|
222
|
+
* Parity with `AnalyzeMediaParamParser` (`optionalNumber` accepts
|
|
223
|
+
* `"12.5"`): numbers and complete numeric strings travel; any other
|
|
224
|
+
* present value throws bilingually instead of being silently dropped.
|
|
225
|
+
*
|
|
226
|
+
* @param raw - Raw knob value.
|
|
227
|
+
* @param fieldName - Dotted field name for error messages.
|
|
228
|
+
* @param min - Inclusive minimum (shares the parser range table).
|
|
229
|
+
* @param max - Inclusive maximum (shares the parser range table).
|
|
230
|
+
* @returns Finite number, or undefined when absent.
|
|
231
|
+
* @throws Error with an Spanish-first bilingual message when present but not a number within range.
|
|
232
|
+
*/
|
|
233
|
+
private static requireOptionalNumber;
|
|
234
|
+
/**
|
|
235
|
+
* Coerces an optional boolean tuning knob, failing loudly on garbage.
|
|
236
|
+
*
|
|
237
|
+
* @remarks
|
|
238
|
+
* Parity with `AnalyzeMediaParamParser` (`assertOptionalBoolean` accepts
|
|
239
|
+
* `"true"`/`"false"`): booleans and true/false strings travel; any
|
|
240
|
+
* other present value throws bilingually instead of being silently dropped.
|
|
241
|
+
*
|
|
242
|
+
* @param raw - Raw knob value.
|
|
243
|
+
* @param fieldName - Dotted field name for error messages.
|
|
244
|
+
* @returns Boolean, or undefined when absent.
|
|
245
|
+
* @throws Error with an Spanish-first bilingual message when present but not a boolean.
|
|
246
|
+
*/
|
|
247
|
+
private static requireOptionalBoolean;
|
|
248
|
+
/**
|
|
249
|
+
* Resolves the `transcribe` knob, defaulting to true like EnriCode.
|
|
250
|
+
*
|
|
251
|
+
* @remarks
|
|
252
|
+
* A `"false"` string must never collapse to the `true` default (that
|
|
253
|
+
* would pay a full transcription the caller explicitly disabled):
|
|
254
|
+
* true/false strings coerce, anything else present throws in Spanish.
|
|
255
|
+
*
|
|
256
|
+
* @param raw - Raw transcribe value.
|
|
257
|
+
* @returns Resolved transcribe flag.
|
|
258
|
+
* @throws Error with an Spanish-first bilingual message when present but not a boolean nor a true/false string.
|
|
183
259
|
*/
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
readonly video?: {
|
|
230
|
-
/**
|
|
231
|
-
* Clip start offset in seconds for targeted analysis.
|
|
232
|
-
*/
|
|
233
|
-
readonly clipStartSeconds?: number;
|
|
234
|
-
/**
|
|
235
|
-
* Clip duration in seconds for targeted analysis.
|
|
236
|
-
*/
|
|
237
|
-
readonly clipDurationSeconds?: number;
|
|
238
|
-
/**
|
|
239
|
-
* Segment duration in seconds.
|
|
240
|
-
*/
|
|
241
|
-
readonly segmentSeconds?: number;
|
|
242
|
-
/**
|
|
243
|
-
* Maximum number of segments to analyze.
|
|
244
|
-
*/
|
|
245
|
-
readonly maxSegments?: number;
|
|
246
|
-
/**
|
|
247
|
-
* Maximum frames per segment.
|
|
248
|
-
*/
|
|
249
|
-
readonly maxFramesPerSegment?: number;
|
|
250
|
-
};
|
|
251
|
-
/**
|
|
252
|
-
* Optional document multipass tuning (PDF).
|
|
253
|
-
*/
|
|
254
|
-
readonly document?: {
|
|
255
|
-
/**
|
|
256
|
-
* Maximum pages to analyze in total.
|
|
257
|
-
*/
|
|
258
|
-
readonly maxPagesTotal?: number;
|
|
259
|
-
/**
|
|
260
|
-
* Pages per batch.
|
|
261
|
-
*/
|
|
262
|
-
readonly pagesPerBatch?: number;
|
|
263
|
-
/**
|
|
264
|
-
* Maximum rendered pages per batch.
|
|
265
|
-
*/
|
|
266
|
-
readonly maxImagesPerBatch?: number;
|
|
267
|
-
/**
|
|
268
|
-
* Minimum extracted text length to treat a page as textual.
|
|
269
|
-
*/
|
|
270
|
-
readonly scannedTextThresholdChars?: number;
|
|
271
|
-
};
|
|
272
|
-
/**
|
|
273
|
-
* Optional audio multipass tuning.
|
|
274
|
-
*/
|
|
275
|
-
readonly audio?: {
|
|
276
|
-
/**
|
|
277
|
-
* Whether to include timestamped segments in the extracted transcript.
|
|
278
|
-
*/
|
|
279
|
-
readonly timestamps?: boolean;
|
|
280
|
-
/**
|
|
281
|
-
* Segment duration in seconds for audio multipass.
|
|
282
|
-
*/
|
|
283
|
-
readonly segmentSeconds?: number;
|
|
284
|
-
/**
|
|
285
|
-
* Maximum number of audio segments to analyze.
|
|
286
|
-
*/
|
|
287
|
-
readonly maxSegments?: number;
|
|
288
|
-
};
|
|
289
|
-
/**
|
|
290
|
-
* Optional image-set multipass tuning.
|
|
291
|
-
*/
|
|
292
|
-
readonly images?: {
|
|
293
|
-
/**
|
|
294
|
-
* Maximum number of images to analyze in total.
|
|
295
|
-
*/
|
|
296
|
-
readonly maxImagesTotal?: number;
|
|
297
|
-
/**
|
|
298
|
-
* Images per batch for multipass map calls.
|
|
299
|
-
*/
|
|
300
|
-
readonly imagesPerBatch?: number;
|
|
301
|
-
/**
|
|
302
|
-
* Maximum dimension for images (width/height).
|
|
303
|
-
*/
|
|
304
|
-
readonly maxDimension?: number;
|
|
305
|
-
};
|
|
306
|
-
}): Promise<AnalyzeVisionResponse>;
|
|
260
|
+
private static requireTranscribe;
|
|
261
|
+
/**
|
|
262
|
+
* Validates a `POST /v1/vision/analyze` response body for third-party callers.
|
|
263
|
+
*
|
|
264
|
+
* @remarks
|
|
265
|
+
* A malformed 200 body (`{}`, `analysis: 123`, missing `media_type`)
|
|
266
|
+
* must surface as a Spanish coaching error, never as an English
|
|
267
|
+
* `TypeError` from downstream formatters (model-facing text is always
|
|
268
|
+
* Spanish). Malformed `elements` entries are sanitized (dropped), not
|
|
269
|
+
* fatal: partial grounding still analyzes.
|
|
270
|
+
*
|
|
271
|
+
* @param raw - Parsed response body.
|
|
272
|
+
* @returns Validated analysis response.
|
|
273
|
+
* @throws Error with an Spanish-first bilingual message when the body shape is invalid.
|
|
274
|
+
*/
|
|
275
|
+
private static requireValidAnalyzeResponse;
|
|
276
|
+
/**
|
|
277
|
+
* Keeps only well-formed grounded element boxes.
|
|
278
|
+
*
|
|
279
|
+
* @remarks
|
|
280
|
+
* Malformed entries (non-string label, non-finite box coordinates) are
|
|
281
|
+
* dropped so one bad box never fails the whole analysis; downstream
|
|
282
|
+
* formatters can assume `{label, box: {x, y, width, height}}`.
|
|
283
|
+
*
|
|
284
|
+
* @param elements - Raw elements array from the server.
|
|
285
|
+
* @returns Sanitized element boxes.
|
|
286
|
+
*/
|
|
287
|
+
private static sanitizeAnalyzeElements;
|
|
288
|
+
/**
|
|
289
|
+
* Builds an {@link EnriProxyHttpError} embedding the parsed server detail.
|
|
290
|
+
*
|
|
291
|
+
* @param baseMessage - Base message naming the failed operation with its HTTP status.
|
|
292
|
+
* @param result - Raw HTTP result carrying headers and body.
|
|
293
|
+
* @returns HTTP error preserving status, headers, and body.
|
|
294
|
+
*/
|
|
295
|
+
private static buildHttpError;
|
|
296
|
+
/**
|
|
297
|
+
* Parses a 2xx JSON body with a bilingual guard for non-JSON payloads.
|
|
298
|
+
*
|
|
299
|
+
* @param body - Raw response body.
|
|
300
|
+
* @param status - HTTP status code (reported in the error).
|
|
301
|
+
* @returns Parsed body.
|
|
302
|
+
* @throws Error with an Spanish-first bilingual message when the body is not valid JSON.
|
|
303
|
+
*/
|
|
304
|
+
private static parseJsonBody;
|
|
307
305
|
/**
|
|
308
306
|
* Builds an absolute URL relative to the configured base URL.
|
|
309
307
|
*
|
|
310
|
-
* @
|
|
308
|
+
* @remarks
|
|
309
|
+
* The base subpath is preserved (`http://host/proxy` + `/v1/uploads` =
|
|
310
|
+
* `http://host/proxy/v1/uploads`): `new URL(path, base)` alone would
|
|
311
|
+
* discard it. A root base keeps working exactly as before.
|
|
312
|
+
*
|
|
313
|
+
* @param pathname - Pathname to append (must start with `/`).
|
|
311
314
|
* @returns URL instance
|
|
315
|
+
* @throws Error with an Spanish-first bilingual message when the configured base URL is malformed.
|
|
312
316
|
*/
|
|
313
317
|
private buildUrl;
|
|
318
|
+
/**
|
|
319
|
+
* Parses a strict `Upload-Offset` response header.
|
|
320
|
+
*
|
|
321
|
+
* @remarks
|
|
322
|
+
* Strict by design: only `^\d+$` (after trimming) is accepted, so
|
|
323
|
+
* `"12abc"` or `"1.5"` fail bilingually instead of being prefix-parsed
|
|
324
|
+
* (`parseInt("12abc") === 12`) and resuming at a wrong offset.
|
|
325
|
+
*
|
|
326
|
+
* @param headers - Response headers.
|
|
327
|
+
* @returns Offset in bytes.
|
|
328
|
+
* @throws Error with an Spanish-first bilingual message when the header is missing or malformed.
|
|
329
|
+
*/
|
|
330
|
+
private parseUploadOffsetHeader;
|
|
331
|
+
/**
|
|
332
|
+
* Validates a relative image region for native-resolution zoom.
|
|
333
|
+
*
|
|
334
|
+
* @remarks
|
|
335
|
+
* Mirrors the `AnalyzeMediaParamParser` region contract (`[0,1]` bounds,
|
|
336
|
+
* positive size, `x+width<=1`/`y+height<=1`, complete numeric strings
|
|
337
|
+
* coerced via `optionalFraction`) so direct client callers get the same
|
|
338
|
+
* Spanish coaching instead of a late server rejection.
|
|
339
|
+
*
|
|
340
|
+
* @param region - Raw region value.
|
|
341
|
+
* @returns Validated region payload.
|
|
342
|
+
* @throws Error with an Spanish-first bilingual message when the region is malformed or out of range.
|
|
343
|
+
*/
|
|
344
|
+
private static requireValidRegion;
|
|
345
|
+
/**
|
|
346
|
+
* Resolves the session-creation control timeout (60 s, mirrors EnriCode).
|
|
347
|
+
*
|
|
348
|
+
* @returns Control timeout in milliseconds (never above 60 s).
|
|
349
|
+
*/
|
|
350
|
+
private createControlTimeoutMs;
|
|
351
|
+
/**
|
|
352
|
+
* Resolves the offset-probe control timeout (15 s, mirrors EnriCode).
|
|
353
|
+
*
|
|
354
|
+
* @returns Control timeout in milliseconds (never above 15 s).
|
|
355
|
+
*/
|
|
356
|
+
private probeControlTimeoutMs;
|
|
314
357
|
/**
|
|
315
358
|
* Extracts a response header as a single string.
|
|
316
359
|
*
|
|
@@ -326,6 +369,7 @@ export declare class EnriProxyClient {
|
|
|
326
369
|
* @param url - Target URL
|
|
327
370
|
* @param jsonBody - JSON payload
|
|
328
371
|
* @param timeoutMs - Timeout in milliseconds
|
|
372
|
+
* @param signal - Optional cancellation signal.
|
|
329
373
|
* @returns HTTP result
|
|
330
374
|
*/
|
|
331
375
|
private requestJson;
|
|
@@ -337,6 +381,7 @@ export declare class EnriProxyClient {
|
|
|
337
381
|
* @param headers - Request headers
|
|
338
382
|
* @param body - Request body
|
|
339
383
|
* @param timeoutMs - Timeout in milliseconds
|
|
384
|
+
* @param signal - Optional cancellation signal; aborts with a Spanish error.
|
|
340
385
|
* @returns HTTP result
|
|
341
386
|
*/
|
|
342
387
|
private requestRaw;
|