@eddyskywalker/dsh-chatgpt-subscription 0.30.0 → 0.31.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 (55) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/lib/client.js +2905 -194
  3. package/lib/client.js.map +1 -1
  4. package/lib/index.js +3829 -553
  5. package/lib/types/client/index.d.ts.map +1 -1
  6. package/lib/types/client/minimax-code/MinimaxCodeSection.d.ts.map +1 -1
  7. package/lib/types/client/minimax-code/MinimaxVideoDocumentBody.d.ts +69 -0
  8. package/lib/types/client/minimax-code/MinimaxVideoDocumentBody.d.ts.map +1 -0
  9. package/lib/types/client/minimax-code/MinimaxVideoToolView.d.ts +83 -0
  10. package/lib/types/client/minimax-code/MinimaxVideoToolView.d.ts.map +1 -0
  11. package/lib/types/client/minimax-code/VideoFormDialog.d.ts +90 -0
  12. package/lib/types/client/minimax-code/VideoFormDialog.d.ts.map +1 -0
  13. package/lib/types/client/minimax-code/VideoSettingsSections.d.ts +73 -0
  14. package/lib/types/client/minimax-code/VideoSettingsSections.d.ts.map +1 -0
  15. package/lib/types/client/minimax-code/commands-contract.d.ts +35 -0
  16. package/lib/types/client/minimax-code/commands-contract.d.ts.map +1 -0
  17. package/lib/types/client/minimax-code/document-preview.d.ts +45 -0
  18. package/lib/types/client/minimax-code/document-preview.d.ts.map +1 -0
  19. package/lib/types/client/minimax-code/locales.d.ts +206 -2
  20. package/lib/types/client/minimax-code/locales.d.ts.map +1 -1
  21. package/lib/types/client/minimax-code/styles.d.ts.map +1 -1
  22. package/lib/types/client/minimax-code/video-command-host.d.ts +61 -0
  23. package/lib/types/client/minimax-code/video-command-host.d.ts.map +1 -0
  24. package/lib/types/client/minimax-code/video-command.d.ts +126 -0
  25. package/lib/types/client/minimax-code/video-command.d.ts.map +1 -0
  26. package/lib/types/client/minimax-code/video-contract.d.ts +172 -0
  27. package/lib/types/client/minimax-code/video-contract.d.ts.map +1 -0
  28. package/lib/types/client/minimax-code/video-defaults-store.d.ts +61 -0
  29. package/lib/types/client/minimax-code/video-defaults-store.d.ts.map +1 -0
  30. package/lib/types/client/minimax-code/video-form-rules.d.ts +288 -0
  31. package/lib/types/client/minimax-code/video-form-rules.d.ts.map +1 -0
  32. package/lib/types/client/minimax-code/video-media.d.ts +61 -0
  33. package/lib/types/client/minimax-code/video-media.d.ts.map +1 -0
  34. package/lib/types/client/minimax-code/video-slots.d.ts +87 -0
  35. package/lib/types/client/minimax-code/video-slots.d.ts.map +1 -0
  36. package/lib/types/host/minimax-code/client.d.ts.map +1 -1
  37. package/lib/types/host/minimax-code/iso-bmff-duration.d.ts +84 -0
  38. package/lib/types/host/minimax-code/iso-bmff-duration.d.ts.map +1 -0
  39. package/lib/types/host/minimax-code/matrix-client.d.ts +168 -0
  40. package/lib/types/host/minimax-code/matrix-client.d.ts.map +1 -0
  41. package/lib/types/host/minimax-code/media-store.d.ts +153 -0
  42. package/lib/types/host/minimax-code/media-store.d.ts.map +1 -0
  43. package/lib/types/host/minimax-code/routes.d.ts.map +1 -1
  44. package/lib/types/host/minimax-code/video-history.d.ts +240 -0
  45. package/lib/types/host/minimax-code/video-history.d.ts.map +1 -0
  46. package/lib/types/host/minimax-code/video-submit-rules.d.ts +40 -0
  47. package/lib/types/host/minimax-code/video-submit-rules.d.ts.map +1 -0
  48. package/lib/types/host/minimax-code/video-tool.d.ts +757 -0
  49. package/lib/types/host/minimax-code/video-tool.d.ts.map +1 -0
  50. package/lib/types/host/progress-updates/index.d.ts +6 -0
  51. package/lib/types/host/progress-updates/index.d.ts.map +1 -1
  52. package/lib/types/host/progress-updates/projection.d.ts +214 -0
  53. package/lib/types/host/progress-updates/projection.d.ts.map +1 -0
  54. package/lib/types/index.d.ts.map +1 -1
  55. package/package.json +13 -4
@@ -0,0 +1,757 @@
1
+ /**
2
+ * The MiniMax Code video tools: understanding and generation.
3
+ *
4
+ * Both ride the Matrix media gateway (./matrix-client.ts), which sits beside the
5
+ * Messages route on the same agent host. Neither of them sends video to the
6
+ * model as a content block: the Anthropic Messages wire this line speaks has no
7
+ * video part (./modalities.ts records the same conclusion for the prompt path),
8
+ * so understanding is a SERVER-SIDE call that answers with text, and generation
9
+ * is a two-step async task that produces a file.
10
+ *
11
+ * THE ROUTE GATE. Both tools refuse unless the session is routed to
12
+ * `minimax-code`. The reason is not a modality declaration - generation needs
13
+ * none - but the credential: the bearer both tools present is this line's
14
+ * subscription token read from this line's pool. A session served by another
15
+ * provider has no such credential, so the call would 401 in a way the user
16
+ * cannot act on. Refusing here, with the model to switch to, is the same
17
+ * contract `kimi_attach_video` states for its own route.
18
+ *
19
+ * @module dsh-chatgpt-subscription/minimax-code/video-tool
20
+ */
21
+ import type { Context } from '@deepseek-ai/cordis';
22
+ export declare const MINIMAX_UNDERSTAND_VIDEO_TOOL_NAME = "minimax_understand_video";
23
+ export declare const MINIMAX_GENERATE_VIDEO_TOOL_NAME = "minimax_generate_video";
24
+ /** Default prompt used when the caller asks no specific question. */
25
+ export declare const DEFAULT_UNDERSTAND_PROMPT = "\u63CF\u8FF0\u8FD9\u4E2A\u89C6\u9891\u7684\u5185\u5BB9";
26
+ /**
27
+ * Largest local file the INLINE (base64) understanding path will send.
28
+ *
29
+ * A MEASURED CONSTRAINT, not a taste. `videos_understand` reads a local clip
30
+ * only through `video_info[].data`, which is base64 (docs/
31
+ * minimax-video-generation-probe.md §3.2, U3: the only one of the three source
32
+ * forms that answered `results[0].success: true`). Base64 grows the bytes by
33
+ * 4/3 on the wire, and this line's request body is capped at
34
+ * {@link maxMessageBodyBytes} (./types.ts, 64 MB by default), so a 40 MB clip
35
+ * encodes to ~53 MB and still fits. A larger file would leave the caller with
36
+ * an opaque "body too large" from the transport instead of an answer, which is
37
+ * why it is refused here, before the bytes become a request.
38
+ */
39
+ export declare const MAX_INLINE_VIDEO_BYTES: number;
40
+ /**
41
+ * The effective inline ceiling for one deployment.
42
+ *
43
+ * Two limits apply at once: the fixed {@link MAX_INLINE_VIDEO_BYTES}, and the
44
+ * body budget `maxMessageBodyBytes()` — which a deployment can pin lower with
45
+ * `DSH_MINIMAX_CODE_MAX_BODY_BYTES`. The base64 form costs 4 bytes per 3 bytes
46
+ * of video, so the body budget converts to 3/4 of itself; a further 1/8 is
47
+ * reserved for the JSON envelope around the payload.
48
+ *
49
+ * @param bodyLimit - the request-body ceiling; defaults to this line's own.
50
+ * @returns the largest raw video size that can be sent inline.
51
+ */
52
+ export declare function inlineVideoByteBudget(bodyLimit?: number): number;
53
+ /**
54
+ * Largest local file the UPLOAD (presigned PUT) understanding path will send.
55
+ *
56
+ * 200 MiB, which is deliberately the SAME number as
57
+ * {@link MAX_GENERATED_VIDEO_BYTES} — the ceiling the download side puts on a
58
+ * generated clip. The two directions are held to one value on purpose: a file
59
+ * this route can push into the bucket is also a file it can pull back out, so
60
+ * neither limit can leave the other holding a video that moves one way and not
61
+ * the other.
62
+ *
63
+ * Upstream's own ceiling is `MATRIX_MAX_UPLOAD_BYTES` = 500 MiB
64
+ * (packages/agent-tools/src/desktop/matrix-media-client.ts:14), so the service
65
+ * is not what binds here — this process' memory is.
66
+ *
67
+ * WHY AN UPLOAD CAP AT ALL, given that these bytes never enter the request
68
+ * body: they still pass THROUGH this process. {@link uploadLocalVideo} is
69
+ * handed a `Uint8Array` of the entire file and `get_upload_url` is asked for
70
+ * a target sized from it, so with no cap a 2 GB clip would be read into RAM and
71
+ * PUT as one object. That is why the check lives in {@link readLocalVideo},
72
+ * against `stats.size`, before a single byte is read — see the note there.
73
+ */
74
+ export declare const MAX_UPLOAD_VIDEO_BYTES: number;
75
+ /**
76
+ * How a local file reaches the service.
77
+ *
78
+ * `inline` is the default because it needs no upload step at all. `upload`
79
+ * exists because base64 stops scaling at {@link MAX_INLINE_VIDEO_BYTES}; both
80
+ * its field names (§5) and its end-to-end read-back are measured — see
81
+ * {@link uploadLocalVideo} for what that does and does not cover.
82
+ */
83
+ export declare const MINIMAX_VIDEO_TRANSPORTS: readonly ["inline", "upload"];
84
+ export type MinimaxVideoTransport = (typeof MINIMAX_VIDEO_TRANSPORTS)[number];
85
+ /**
86
+ * Models the generation tool accepts, in the order the picker shows them.
87
+ *
88
+ * THREE, AND ALL THREE ARE MEASURED. `MiniMax-H3-Max` was missing from this
89
+ * list; it is not an inference, because the service named it in its own duration
90
+ * rule (docs/minimax-video-free-checks.md section 2.1, verbatim):
91
+ *
92
+ * > use 4-15 seconds for MiniMax-H3, 5-15 seconds for MiniMax-H3-Max, or 6/10
93
+ * > seconds for Hailuo 2.3
94
+ *
95
+ * That sentence is also what proves `MiniMax-Hailuo-2.3` is recognised: asked
96
+ * for a bad duration, the service answered with a rule about THAT model, so its
97
+ * id had already passed the model check (section 3).
98
+ */
99
+ export declare const MINIMAX_VIDEO_MODELS: readonly ["MiniMax-H3", "MiniMax-H3-Max", "MiniMax-Hailuo-2.3"];
100
+ export type MinimaxVideoModel = (typeof MINIMAX_VIDEO_MODELS)[number];
101
+ /** Model used when the caller names none. */
102
+ export declare const DEFAULT_MINIMAX_VIDEO_MODEL: MinimaxVideoModel;
103
+ /**
104
+ * Every resolution spelling ANY model accepts: a UNION, never a legal set.
105
+ *
106
+ * THIS LIST IS NOT ANY MODEL'S LEGAL RESOLUTION SET, AND MUST NOT BE USED AS
107
+ * ONE. MEASURED, and the measurement contradicts the intuitive reading
108
+ * (docs/minimax-video-model-rules.md section 5): the three models' sets are
109
+ * pairwise different and none of them is the union.
110
+ *
111
+ * | model | accepts | only this model has |
112
+ * | -------------------- | --------------------------- | ------------------- |
113
+ * | `MiniMax-H3` | `768P`, `2K` | `2K` |
114
+ * | `MiniMax-H3-Max` | `480P`, `768P` | `480P` |
115
+ * | `MiniMax-Hailuo-2.3` | `768P`, `1080P` | `1080P` |
116
+ *
117
+ * So every member of this list is illegal for at least one model: `2K` is
118
+ * refused by H3-Max and by Hailuo, `1080P` by H3 and by H3-Max, `480P` by H3
119
+ * and by Hailuo. The one place this list is legitimately used is the tool
120
+ * parameter schema, which can advertise only ONE `enum` for a field whose real
121
+ * rule is per model; the per-model enforcement that has to follow it lives in
122
+ * {@link assertVideoResolution}, driven by {@link MINIMAX_VIDEO_MODEL_RULES}.
123
+ */
124
+ export declare const MINIMAX_VIDEO_RESOLUTION_UNION: readonly ["480P", "768P", "1080P", "2K"];
125
+ export type MinimaxVideoResolution = (typeof MINIMAX_VIDEO_RESOLUTION_UNION)[number];
126
+ /**
127
+ * Shortest clip ANY model accepts, in seconds.
128
+ *
129
+ * The union of the per-model windows, for a caller that needs the widest answer.
130
+ * It is NOT what enforcement uses: a Hailuo clip of 7 s sits inside 4-15 and must
131
+ * still be refused, because that model accepts only 6 or 10.
132
+ */
133
+ export declare const MINIMAX_VIDEO_MIN_DURATION_SECONDS = 4;
134
+ /** Longest clip ANY model accepts, in seconds. See {@link MINIMAX_VIDEO_MIN_DURATION_SECONDS}. */
135
+ export declare const MINIMAX_VIDEO_MAX_DURATION_SECONDS = 15;
136
+ /** How one model bounds `duration`: an inclusive interval, or a closed set. */
137
+ export type MinimaxVideoDurationRule = {
138
+ readonly kind: 'range';
139
+ readonly min: number;
140
+ readonly max: number;
141
+ } | {
142
+ readonly kind: 'values';
143
+ readonly values: readonly number[];
144
+ };
145
+ /** One model's accepted `duration` and `resolution`, with where each came from. */
146
+ export interface MinimaxVideoModelRule {
147
+ readonly model: MinimaxVideoModel;
148
+ /** The `duration` window. MEASURED for all three (sections 2.1, 2.2 and 3). */
149
+ readonly duration: MinimaxVideoDurationRule;
150
+ /** The spellings this model accepts, exactly as they must be sent (case-sensitive). */
151
+ readonly resolutions: readonly MinimaxVideoResolution[];
152
+ /**
153
+ * Where {@link resolutions} came from.
154
+ *
155
+ * `measured` - the service's own refusal sentence named the values.
156
+ * `documented` - upstream documentation states them; no probe confirmed them.
157
+ * `inferred` - no evidence at all for THIS model; copied from the model the
158
+ * comment names, and it may be wrong.
159
+ */
160
+ readonly resolutionSource: 'measured' | 'documented' | 'inferred';
161
+ }
162
+ /**
163
+ * The per-model table, and the ONE place the service's real rules live.
164
+ *
165
+ * The old shape - one 4-15 window and one resolution list shared by every model
166
+ * - is wrong in three measured ways: H3-Max starts at 5, Hailuo accepts only 6
167
+ * or 10, and H3 refuses `1080P` outright.
168
+ */
169
+ export declare const MINIMAX_VIDEO_MODEL_RULES: readonly MinimaxVideoModelRule[];
170
+ /** The rule for one model id, or undefined when this build has none. */
171
+ export declare function videoModelRule(model: string): MinimaxVideoModelRule | undefined;
172
+ /**
173
+ * Narrow a caller-supplied model id to one this build knows.
174
+ *
175
+ * The parameter schema already lists exactly these three, so a value outside the
176
+ * set is a caller bypassing its own schema rather than a new upstream model. It
177
+ * is refused with the legal ids instead of being forwarded, because a model this
178
+ * build has no rule for cannot have its duration and resolution checked - and the
179
+ * service bills a submit before it refuses those.
180
+ *
181
+ * @param value - the caller's `model` argument, already trimmed.
182
+ * @returns the matching model id.
183
+ * @throws HarnessError `MINIMAX_VIDEO_MODEL_INVALID` listing the accepted ids.
184
+ */
185
+ export declare function assertVideoModel(value: string): MinimaxVideoModel;
186
+ /**
187
+ * The meta shape the client reads, field for field.
188
+ *
189
+ * docs/minimax-video-design-spec.md section 5 fixes these names: the client
190
+ * narrows `ToolResultNode.meta` to this interface, and a rename here is a
191
+ * silently blank card there. The `value` a tool returns is deliberately NOT
192
+ * persisted by the harness, so this is the only channel.
193
+ */
194
+ export interface MinimaxVideoPresentationMeta {
195
+ /** Workspace-relative path; the client resolves it against `cwd`. */
196
+ readonly videoPath: string;
197
+ readonly mediaType: string;
198
+ readonly bytes: number;
199
+ readonly model: string;
200
+ readonly durationSeconds?: number;
201
+ /** Upstream task id, for diagnosis and follow-up. */
202
+ readonly taskId: string;
203
+ }
204
+ /** Base backoff for a transient Matrix failure, matching the adapter's policy. */
205
+ export declare const DEFAULT_RETRY_BACKOFF_MS = 1500;
206
+ /** How often the generation task is polled. */
207
+ export declare const VIDEO_POLL_INTERVAL_MS = 4000;
208
+ /**
209
+ * Total wall-clock budget for one generation.
210
+ *
211
+ * Matches the upstream submit timeout (600 s). Past it the task is very likely
212
+ * stuck rather than slow, and the user is better served by an answer than by a
213
+ * request that outlives every other thing in the turn.
214
+ */
215
+ export declare const VIDEO_GENERATION_BUDGET_MS = 600000;
216
+ /** The slice of the account pool these tools use. */
217
+ export interface MinimaxVideoCredentialSource {
218
+ getFreshCredential(accountId?: string, fetchFn?: typeof fetch): Promise<{
219
+ accessToken: string;
220
+ region: 'cn' | 'global';
221
+ }>;
222
+ }
223
+ /** A partial Matrix credential, as the tools need it. */
224
+ export interface MinimaxVideoCredential {
225
+ readonly accessToken: string;
226
+ readonly region: 'cn' | 'global';
227
+ }
228
+ /** Options for both video tools. */
229
+ export interface MinimaxVideoToolOptions {
230
+ /** Injected fetch; tests supply a mock so no request ever leaves the process. */
231
+ readonly fetchFn?: typeof fetch;
232
+ /** Credential source (the line's account pool). */
233
+ readonly pool: MinimaxVideoCredentialSource;
234
+ /** Poll interval, injected so a test does not sleep for real. */
235
+ readonly pollIntervalMs?: number;
236
+ /** Generation budget, injected for the same reason. */
237
+ readonly generationBudgetMs?: number;
238
+ /**
239
+ * Base backoff between retries of a transient Matrix failure.
240
+ *
241
+ * Injected so a test does not spend the real 1.5 s the adapter's policy uses;
242
+ * production leaves it at {@link DEFAULT_RETRY_BACKOFF_MS}.
243
+ */
244
+ readonly retryBackoffMs?: number;
245
+ /** Clock, injected so a test can pin the generated file name. */
246
+ readonly now?: () => number;
247
+ }
248
+ type FetchLike = typeof fetch;
249
+ /**
250
+ * The provider this session is routed to, and the model on it.
251
+ *
252
+ * Read through the same two seams `kimi_attach_video` uses: the live session's
253
+ * request header first, the agent's own options second. Both are read
254
+ * defensively because a tool is also executed by tooling that composes no
255
+ * agent.
256
+ */
257
+ export declare function routedProvider(exec: {
258
+ readonly agent?: unknown;
259
+ }): {
260
+ provider?: string;
261
+ model?: string;
262
+ };
263
+ /**
264
+ * Refuse unless this session is served by the MiniMax Code line.
265
+ *
266
+ * @param exec - the tool execution.
267
+ * @param what - the operation being refused, for the message.
268
+ * @throws HarnessError naming the model to switch to.
269
+ */
270
+ export declare function assertMinimaxRoute(exec: {
271
+ readonly agent?: unknown;
272
+ }, what: string): void;
273
+ /**
274
+ * Prove the `durationSeconds` argument is legal FOR THE MODEL the caller picked.
275
+ *
276
+ * The window is not a property of the endpoint, it is a property of the model,
277
+ * and the service said so itself (docs/minimax-video-free-checks.md section 2.1,
278
+ * verbatim):
279
+ *
280
+ * > use 4-15 seconds for MiniMax-H3, 5-15 seconds for MiniMax-H3-Max, or 6/10
281
+ * > seconds for Hailuo 2.3
282
+ *
283
+ * So a single 4-15 check is wrong in both directions: it lets 7 s through to
284
+ * Hailuo (which accepts only 6 or 10) and it refuses 4 s on H3-Max (which
285
+ * accepts 5-15). Both are refusals the service makes AFTER billing the submit,
286
+ * which is why they are caught here for free instead.
287
+ *
288
+ * `0` IS NOT AN OUT-OF-RANGE VALUE. The service treats it as ABSENT - asked for
289
+ * `duration: 0` it answers "duration is required for MiniMax-H3" (section 2.2) -
290
+ * so it is reported as a missing argument rather than as a number outside the
291
+ * window, and the caller is told the model's legal values rather than a range
292
+ * that would not have applied anyway.
293
+ *
294
+ * @param value - the caller's argument, in seconds.
295
+ * @param model - the model id the submit names, which selects the rule.
296
+ * @returns the same value, proven legal for that model.
297
+ * @throws HarnessError naming THAT model's accepted values.
298
+ */
299
+ export declare function assertVideoDuration(value: unknown, model: MinimaxVideoModel): number;
300
+ /**
301
+ * Prove the `resolution` argument is one THIS MODEL accepts, spelled exactly.
302
+ *
303
+ * The service validates the value against the model, and its sentence names the
304
+ * model AND its own pair. All three are MEASURED, verbatim
305
+ * (docs/minimax-video-model-rules.md sections 1 and 2.1, plus
306
+ * docs/minimax-video-free-checks.md section 2.3 for H3):
307
+ *
308
+ * > model resolution for `MiniMax-H3` must be `768P` or `2K`
309
+ * > model resolution for `MiniMax-H3-Max` must be `480P` or `768P`
310
+ * > model resolution for `MiniMax-Hailuo-2.3` must be `768P` or `1080P`
311
+ *
312
+ * Three measured consequences:
313
+ *
314
+ * 1. `1080P` is a real resolution in general and ILLEGAL for H3, so the check
315
+ * cannot be "is it in the union" - it has to be "is it in THIS model's set".
316
+ * 2. The sets are PAIRWISE DIFFERENT and none of them is the union: `2K` is
317
+ * H3's alone, `480P` is H3-Max's alone, `1080P` is Hailuo's alone. Nothing
318
+ * in this function may fall back to {@link MINIMAX_VIDEO_RESOLUTION_UNION}
319
+ * for a model that has a row.
320
+ * 3. The match is CASE-SENSITIVE. `720p` and `4K` came back with the identical
321
+ * sentence, so a lowercase spelling is refused exactly like an invented one.
322
+ * The value is trimmed but NOT case-folded, and `'768p'` must stay refused.
323
+ *
324
+ * @param value - the caller's argument.
325
+ * @param model - the model id the submit names, which selects the set.
326
+ * @returns the matched member, exactly as it will be sent.
327
+ * @throws HarnessError listing THAT model's accepted spellings.
328
+ */
329
+ export declare function assertVideoResolution(value: unknown, model: MinimaxVideoModel): MinimaxVideoResolution;
330
+ /**
331
+ * Every `ratio` spelling the service accepts, in upstream's own order.
332
+ *
333
+ * COPIED FROM UPSTREAM'S SCHEMA (docs/minimax-video-extended-spec.md section 1),
334
+ * including `adaptive`. `adaptive` is listed even though a caller should rarely
335
+ * type it, because the LINKAGE below produces it: on the H3 family a keyframe
336
+ * submit OVERWRITES whatever ratio was given with `adaptive`, and a reference
337
+ * submit defaults to it.
338
+ */
339
+ export declare const MINIMAX_VIDEO_RATIOS: readonly ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16", "adaptive"];
340
+ export type MinimaxVideoRatio = (typeof MINIMAX_VIDEO_RATIOS)[number];
341
+ /** The ratio the H3 linkage sends for a text-only submit (upstream: `ratio ?? '16:9'`). */
342
+ export declare const MINIMAX_H3_TEXT_DEFAULT_RATIO: MinimaxVideoRatio;
343
+ /** The ratio the H3 linkage FORCES when a first and/or last frame is present. */
344
+ export declare const MINIMAX_KEYFRAME_RATIO: MinimaxVideoRatio;
345
+ /** The ratio the H3 linkage falls back to when reference media is present. */
346
+ export declare const MINIMAX_REFERENCE_DEFAULT_RATIO: MinimaxVideoRatio;
347
+ /**
348
+ * The resolution the H3 linkage sends when the caller names none.
349
+ *
350
+ * UPSTREAM'S DEFAULT (`input.resolution ?? '2K'`), applied only where it is a
351
+ * LEGAL value for that model - see {@link resolveVideoSubmissionResolution} for
352
+ * the one row where the literal rule and the measured table disagree.
353
+ */
354
+ export declare const MINIMAX_H3_DEFAULT_RESOLUTION: MinimaxVideoResolution;
355
+ /**
356
+ * Whether this model belongs to the H3 family, which is what the ratio and
357
+ * resolution linkage is written for.
358
+ *
359
+ * THE SAME PREDICATE UPSTREAM USES (`isH3VideoModel`), and the same one that
360
+ * decides reference-media support: H3 and H3-Max take the reference collections
361
+ * and the linkage defaults, Hailuo-2.3 takes neither.
362
+ *
363
+ * @param model - a model id.
364
+ * @returns true for `MiniMax-H3` and `MiniMax-H3-Max`.
365
+ */
366
+ export declare function isH3VideoModel(model: string): boolean;
367
+ /**
368
+ * Prove the `ratio` argument is one of the spellings the service knows.
369
+ *
370
+ * ONLY THE SPELLING IS CHECKED HERE. Which ratio is finally sent is decided by
371
+ * {@link resolveVideoSubmissionRatio}, because on the H3 family the caller's
372
+ * choice is often replaced (a keyframe submit is forced to `adaptive`) and on
373
+ * Hailuo it is passed through untouched. Refusing an invented spelling here means
374
+ * the linkage never has to reason about a value the service would reject anyway,
375
+ * and it costs no request.
376
+ *
377
+ * @param value - the caller's argument.
378
+ * @returns the matched spelling, exactly as the schema lists it.
379
+ * @throws HarnessError `MINIMAX_VIDEO_RATIO_INVALID` listing every spelling.
380
+ */
381
+ export declare function assertVideoRatio(value: unknown): MinimaxVideoRatio;
382
+ /** Everything the ratio rule branches on. */
383
+ export interface MinimaxVideoRatioDecision {
384
+ /** The model the submit names; only the H3 family gets a default. */
385
+ readonly model: MinimaxVideoModel;
386
+ /** The caller's ratio, already proven to be a known spelling. */
387
+ readonly ratio?: MinimaxVideoRatio;
388
+ /** True when `inputImagePath` and/or `lastFrameImagePath` is present. */
389
+ readonly hasKeyframes: boolean;
390
+ /** True when at least one reference image, video or audio is present. */
391
+ readonly hasReferences: boolean;
392
+ }
393
+ /**
394
+ * Decide the ratio that is actually SENT, or undefined when none is.
395
+ *
396
+ * COPIED FROM UPSTREAM (`submit-video-generation.ts:77-86`), branch for branch:
397
+ *
398
+ * ```ts
399
+ * const effectiveRatio = isH3VideoModel(model)
400
+ * ? hasKeyframes ? 'adaptive'
401
+ * : hasReferences ? (ratio ?? 'adaptive')
402
+ * : (ratio ?? '16:9')
403
+ * : ratio
404
+ * ```
405
+ *
406
+ * ONE REFUSAL IS ADDED ON TOP, and it comes from upstream's own description
407
+ * ("cannot use adaptive"): `adaptive` means "adapt to the input frame", so a
408
+ * TEXT-ONLY submit has nothing to adapt to. Sending it anyway would spend a
409
+ * billed request learning what upstream already states, so it is refused here,
410
+ * for every model - a text-only adaptive request is meaningless whichever model
411
+ * reads it. On the H3 family the refusal is also unavoidable rather than
412
+ * pedantic: the text-only branch would otherwise have replaced it with `16:9`
413
+ * silently, and a caller who asked for `adaptive` and got `16:9` was never told.
414
+ *
415
+ * @param input - the model, the caller's ratio, and what the call carries.
416
+ * @returns the ratio to send, or undefined to send no `ratio` field at all.
417
+ * @throws HarnessError `MINIMAX_VIDEO_RATIO_ADAPTIVE_UNSUPPORTED` for a
418
+ * text-only adaptive call.
419
+ */
420
+ export declare function resolveVideoSubmissionRatio(input: MinimaxVideoRatioDecision): MinimaxVideoRatio | undefined;
421
+ /**
422
+ * Decide the resolution that is actually SENT, or undefined when none is.
423
+ *
424
+ * TWO VALUES, AND THEY ARE NOT THE SAME VALUE - which is the whole point of the
425
+ * split with {@link assertVideoResolution}:
426
+ *
427
+ * - The CALLER's resolution is proven by `assertVideoResolution`, against the
428
+ * measured set for the model in {@link MINIMAX_VIDEO_MODEL_RULES}. That check runs
429
+ * first, outside this function, and is untouched by it.
430
+ * - The value SENT is what this function returns. For the H3 family it is
431
+ * `resolution ?? '2K'` (upstream's "defaults to 2K when omitted"); for Hailuo it
432
+ * is whatever the caller gave, with NO default, because upstream sets none for
433
+ * that model. THIS IS THE BEHAVIOUR CHANGE: an H3 submit that names no resolution
434
+ * used to send no `resolution` field at all, and now sends `2K`.
435
+ *
436
+ * THE ONE PLACE THIS DELIBERATELY DIVERGES FROM A LITERAL COPY, and the reason is
437
+ * MEASURED rather than stylistic: `MiniMax-H3-Max` is part of the H3 family, so
438
+ * the literal rule would make 2K its default - and 2K is exactly the spelling its
439
+ * measured set does NOT contain ("model resolution for MiniMax-H3-Max must be
440
+ * 480P or 768P", docs/minimax-video-model-rules.md section 2.1). Defaulting it to
441
+ * 2K would turn every H3-Max call that omits `resolution` into a billed submit
442
+ * the service always refuses. So the default is applied only where it is a legal
443
+ * member of THAT model's set; where it is not, no resolution is sent and the
444
+ * service keeps its own default - H3-Max's behaviour is unchanged on purpose.
445
+ *
446
+ * @param model - the model the submit names.
447
+ * @param resolution - the caller's value, already proven legal for that model.
448
+ * @returns the resolution to send, or undefined to send no `resolution` field.
449
+ */
450
+ export declare function resolveVideoSubmissionResolution(model: MinimaxVideoModel, resolution: MinimaxVideoResolution | undefined): MinimaxVideoResolution | undefined;
451
+ /**
452
+ * Prove one URL is a public destination before anything connects to it.
453
+ *
454
+ * The generation response's own video_url is upstream data, not a caller
455
+ * argument, and that is exactly why the gate matters: a service - or anything
456
+ * that has compromised its response - that answered with http://127.0.0.1/...
457
+ * would otherwise turn this tool into a reader of the user's own machine.
458
+ */
459
+ export declare function assertPublicUrl(url: URL, what: string): Promise<void>;
460
+ /** The one CDN host measured to work through the `url` key (upload probe section 4). */
461
+ export declare const MINIMAX_CDN_HOST = "cdn.hailuoai.com";
462
+ /**
463
+ * The agent hosts whose own addresses the service also accepts.
464
+ *
465
+ * MEASURED for the CDN host only (docs/minimax-video-upload-probe.md section 4:
466
+ * `get_upload_url` answered `cdn_url` on `cdn.hailuoai.com` and citing that
467
+ * address answered `success: true`). The `agent.minimax.` forms are accepted
468
+ * because they are MiniMax's own origin hosts - the same family this line already
469
+ * talks to - and refusing them would break a source the service would take. This
470
+ * half is NOT probe-confirmed; it is the service's own-family host, accepted on
471
+ * that basis alone.
472
+ */
473
+ export declare const MINIMAX_CDN_HOST_SUFFIXES: readonly string[];
474
+ /**
475
+ * Refuse a `url` source that is not a MiniMax-hosted address.
476
+ *
477
+ * THE MEASURED REASON. Two of three third-party URLs were confirmed fetchable
478
+ * from this machine - HTTP 206, `video/mp4`, `ftypmp42` - and the service still
479
+ * answered `results[0].success: false` with `video_info.url could not be used as
480
+ * a media source` for all three (docs/minimax-video-free-checks.md sections 5.2
481
+ * and 5.3). The key is syntactically legal; the service simply will not go and
482
+ * fetch a third party's address. Only its own CDN is measured to work.
483
+ *
484
+ * So a third-party address is refused locally, before the request, with the
485
+ * remedy (send the local file) instead of a remote refusal that reads like a
486
+ * transient problem.
487
+ *
488
+ * The exempt hosts are exactly the ones this route's own upload path produces,
489
+ * so `transport: "upload"` never trips this check.
490
+ *
491
+ * `what` NAMES THE ARGUMENT, and that is not decoration: the generation submit
492
+ * carries a whole set of media arguments (a first frame, a last frame, up to
493
+ * nine reference images, three reference videos, three reference audios), so a
494
+ * refusal that said only "the URL" would leave the caller hunting for which of
495
+ * thirteen arguments it was.
496
+ *
497
+ * @param url - the parsed caller URL.
498
+ * @param what - the argument being refused, named in the message.
499
+ * @throws HarnessError `MINIMAX_VIDEO_URL_NOT_MINIMAX_CDN` for anything else.
500
+ */
501
+ export declare function assertMinimaxCdnUrl(url: URL, what?: string): void;
502
+ /** How many leading bytes the container sniff reads. Enough for every magic below. */
503
+ export declare const VIDEO_CONTAINER_SNIFF_BYTES = 32;
504
+ /** The video container one file's first bytes declare. */
505
+ export type VideoContainerKind = 'iso-bmff' | 'matroska' | 'avi' | 'mpeg-ps';
506
+ /**
507
+ * Identify the video container from the first bytes of a file.
508
+ *
509
+ * WHY THIS EXISTS AT ALL. The service answers `results[0].success: true` for
510
+ * bytes no decoder could ever read: 1 MiB of `0x11` filler came back with a
511
+ * confident, invented description of a tabby cat, and a 5 MiB sample with a
512
+ * "purple onion rotating on white" (docs/minimax-video-free-checks.md section
513
+ * 4.4). So a file that is NOT a video does not fail loudly upstream - it comes
514
+ * back as a fabricated answer the user will believe was about their clip. The
515
+ * cheapest place to stop that is here, on this machine, before the bytes leave.
516
+ *
517
+ * The four magic numbers are the ones the extensions this route accepts map to:
518
+ *
519
+ * | container | leading bytes |
520
+ * | -------------------- | -------------------------------------------------- |
521
+ * | ISO BMFF (mp4/mov) | offset 4 is ASCII `ftyp` |
522
+ * | Matroska / WebM | `1A 45 DF A3` |
523
+ * | AVI (RIFF) | `RIFF` at 0 and `AVI ` at 8 |
524
+ * | MPEG program stream | `00 00 01 BA` (pack) or `00 00 01 B3` (video seq) |
525
+ *
526
+ * @param head - the first {@link VIDEO_CONTAINER_SNIFF_BYTES} bytes (or fewer).
527
+ * @returns the container, or undefined when the bytes are none of them.
528
+ */
529
+ export declare function sniffVideoContainer(head: Uint8Array): VideoContainerKind | undefined;
530
+ /**
531
+ * The `category` every upload body must carry, measured upstream.
532
+ *
533
+ * WHY IT IS A CONSTANT RATHER THAN A LITERAL AT THE CALL SITE. The value is
534
+ * part of upstream's own measured request body
535
+ * (`{ filename, mime_type, size_bytes, category: 'user_file_upload_tmp' }`,
536
+ * docs/minimax-video-extended-spec.md section 2.1). It names the TEMPORARY
537
+ * bucket the object lands in, and it is the same bucket for a video being
538
+ * understood and for a reference image being sent to the generation service -
539
+ * so both paths share the one spelling instead of each carrying its own copy
540
+ * that can drift.
541
+ */
542
+ export declare const MINIMAX_UPLOAD_CATEGORY = "user_file_upload_tmp";
543
+ /**
544
+ * The tool parameter each service field name belongs to, and where they differ.
545
+ *
546
+ * THIS TABLE IS THE POINT OF THIS SECTION, so it is stated once, here, in the
547
+ * service's own spelling:
548
+ *
549
+ * | tool parameter | sent as |
550
+ * | -------------------------- | ------------------ |
551
+ * | inputImagePath | input_image |
552
+ * | lastFrameImagePath | last_frame_image |
553
+ * | referenceImagePaths | reference_images |
554
+ * | referenceVideoPaths | reference_videos |
555
+ * | referenceAudioPaths | reference_audios |
556
+ *
557
+ * Four of the five differ from their parameter names, which is exactly the kind
558
+ * of mapping that survives right up until someone builds the body by
559
+ * destructuring the arguments. Nothing outside this section spells either
560
+ * column: prepareGenerationMedia returns an object whose keys ARE the right-hand
561
+ * column, so the submit merges it instead of re-deriving a name.
562
+ * (docs/minimax-video-extended-spec.md section 0.)
563
+ */
564
+ /** One prepared media argument: the shape the service reads. */
565
+ export interface MinimaxMediaPayload {
566
+ /** A cdn.hailuoai.com address - measured to be the only url shape read. */
567
+ readonly url: string;
568
+ readonly mime_type: string;
569
+ }
570
+ /** A prepared reference video: a media payload plus the length the service needs. */
571
+ export interface MinimaxVideoMediaPayload extends MinimaxMediaPayload {
572
+ /** Seconds, from the container or from the caller. */
573
+ readonly duration_seconds: number;
574
+ }
575
+ /**
576
+ * Largest total number of reference media items (images + videos + audios).
577
+ *
578
+ * COPIED FROM UPSTREAM'S MEASURED LIMITS (spec section 6): 1-9 images, 1-3
579
+ * videos, 1-3 audios, and never more than 12 in total. The per-set ceilings are
580
+ * enforced as well as the total, because the two refuse different mistakes -
581
+ * 9 images plus 3 videos is 12 items and passes both, while 13 images passes
582
+ * neither.
583
+ */
584
+ export declare const MAX_REFERENCE_MEDIA_TOTAL = 12;
585
+ /** Most reference images one submit may carry. */
586
+ export declare const MAX_REFERENCE_IMAGES = 9;
587
+ /** Most reference videos one submit may carry. */
588
+ export declare const MAX_REFERENCE_VIDEOS = 3;
589
+ /** Most reference audios one submit may carry. */
590
+ export declare const MAX_REFERENCE_AUDIOS = 3;
591
+ /**
592
+ * How far a caller's stated reference-video length may sit from the length this
593
+ * route reads out of the container before the two are treated as a contradiction.
594
+ *
595
+ * A SECOND of slack, because the container reports an exact rational and a
596
+ * caller writing 10 for a 10.033 s clip is not wrong. Beyond that the two
597
+ * describe different clips, and accepting either one silently would mean
598
+ * sending a length the user never saw.
599
+ */
600
+ export declare const MINIMAX_REFERENCE_DURATION_TOLERANCE_SECONDS = 1;
601
+ /**
602
+ * Everything one media preparation needs.
603
+ *
604
+ * sleepFn and backoffMs are here because the upload channel retries, and a test
605
+ * must not spend the real 1.5 s doing it - the same injection the understanding
606
+ * path already uses.
607
+ */
608
+ export interface MinimaxMediaPrepareContext {
609
+ readonly credential: MinimaxVideoCredential;
610
+ readonly fetchFn: FetchLike;
611
+ readonly sleepFn: (ms: number) => Promise<void>;
612
+ readonly backoffMs: number;
613
+ readonly signal?: AbortSignal;
614
+ /** The model the submit names, which can narrow the legal extension set. */
615
+ readonly model?: MinimaxVideoModel;
616
+ }
617
+ /** The media arguments one generation call may carry, as the caller typed them. */
618
+ export interface MinimaxGenerationMediaInput {
619
+ readonly inputImagePath?: string;
620
+ readonly lastFrameImagePath?: string;
621
+ readonly referenceImagePaths?: readonly string[];
622
+ readonly referenceVideoPaths?: readonly string[];
623
+ readonly referenceVideoDurationSeconds?: readonly number[];
624
+ readonly referenceAudioPaths?: readonly string[];
625
+ }
626
+ /**
627
+ * The prepared media, keyed by the SERVICE's field names.
628
+ *
629
+ * The two booleans beside them are what the submit's ratio rule branches on;
630
+ * they are reported rather than acted on here, because this layer decides what
631
+ * is sent as media, not what ratio defaults to.
632
+ */
633
+ export interface MinimaxGenerationMedia {
634
+ readonly input_image?: MinimaxMediaPayload;
635
+ readonly last_frame_image?: MinimaxMediaPayload;
636
+ readonly reference_images?: readonly MinimaxMediaPayload[];
637
+ readonly reference_videos?: readonly MinimaxVideoMediaPayload[];
638
+ readonly reference_audios?: readonly MinimaxMediaPayload[];
639
+ /** True when a first and/or last frame image was prepared. */
640
+ readonly hasKeyframes: boolean;
641
+ /** True when at least one reference image, video or audio was prepared. */
642
+ readonly hasReferences: boolean;
643
+ }
644
+ /**
645
+ * Whether this model accepts the reference collections at all.
646
+ *
647
+ * Hailuo-2.3 does not (spec section 7): upstream's own description limits it to
648
+ * first_frame and the legacy subject reference type, with no image/video/audio
649
+ * reference sets and no last frame. Both H3 models do.
650
+ *
651
+ * @param model - the model id the submit names.
652
+ * @returns true for the two H3 models.
653
+ */
654
+ export declare function minimaxModelSupportsReferenceMedia(model: string): boolean;
655
+ /** A length rounded the way seconds are reported, without float noise. */
656
+ export declare function normalizeDurationSeconds(seconds: number): number;
657
+ /**
658
+ * Prepare an image argument (a first frame, a last frame, or a reference).
659
+ *
660
+ * @param pathOrUrl - absolute local path, or a MiniMax CDN URL.
661
+ * @param fieldName - the tool argument, for every message this can raise.
662
+ * @param context - credential, fetch, retry policy and the model.
663
+ * @returns an object with url and mime_type.
664
+ */
665
+ export declare function prepareImageInput(pathOrUrl: string, fieldName: string, context: MinimaxMediaPrepareContext): Promise<MinimaxMediaPayload>;
666
+ /**
667
+ * Prepare an audio argument.
668
+ *
669
+ * @param pathOrUrl - absolute local path, or a MiniMax CDN URL.
670
+ * @param fieldName - the tool argument, for every message this can raise.
671
+ * @param context - credential, fetch, retry policy and the model.
672
+ * @returns an object with url and mime_type.
673
+ */
674
+ export declare function prepareAudioInput(pathOrUrl: string, fieldName: string, context: MinimaxMediaPrepareContext): Promise<MinimaxMediaPayload>;
675
+ /**
676
+ * Reconcile the caller's stated reference-video length with the one this route
677
+ * read out of the file.
678
+ *
679
+ * THE CALLER WINS, BUT NOT SILENTLY (spec section 4.4): a caller may deliberately
680
+ * trim a clip and state the trimmed length, so their number is the one sent -
681
+ * but if the container disagrees by more than
682
+ * MINIMAX_REFERENCE_DURATION_TOLERANCE_SECONDS the two are describing different
683
+ * things, and sending either one quietly would mean the user believes a 5 s
684
+ * reference was used while 12 s went out.
685
+ *
686
+ * @param fieldName - the tool argument, for the message.
687
+ * @param measured - seconds read from the container.
688
+ * @param given - the caller's value, when they supplied one.
689
+ * @returns the length to send.
690
+ * @throws HarnessError naming BOTH values when they contradict each other.
691
+ */
692
+ export declare function reconcileReferenceVideoDurationSeconds(fieldName: string, measured: number, given: number | undefined): number;
693
+ /**
694
+ * Prepare a reference video: the media payload PLUS the length it must carry.
695
+ *
696
+ * THE LENGTH COMES FROM TWO PLACES AND THEY ARE NOT INTERCHANGEABLE:
697
+ *
698
+ * - a LOCAL file is read here, out of the container's own moov/mvhd
699
+ * (readIsoBmffDurationSeconds), so the caller owes nothing;
700
+ * - a REMOTE URL cannot be read - this route does not download a reference to
701
+ * measure it, and the service does not either - so the caller MUST state it,
702
+ * and a missing value is refused rather than guessed (spec section 4.2).
703
+ *
704
+ * @param pathOrUrl - absolute local path, or a MiniMax CDN URL.
705
+ * @param fieldName - the tool argument, for every message this can raise.
706
+ * @param durationSeconds - the caller's stated length, when they gave one.
707
+ * @param context - credential, fetch, retry policy and the model.
708
+ * @returns an object with url, mime_type and duration_seconds.
709
+ */
710
+ export declare function prepareVideoInput(pathOrUrl: string, fieldName: string, durationSeconds: number | undefined, context: MinimaxMediaPrepareContext): Promise<MinimaxVideoMediaPayload>;
711
+ /**
712
+ * Prepare every media argument of one generation submit.
713
+ *
714
+ * The ORDER of the refusals is deliberate: the free ones come first. A model
715
+ * that does not accept reference media at all is refused before a single file is
716
+ * read, and the counts are checked before any upload, so an over-limit call
717
+ * costs no request instead of nine uploads and then a refusal.
718
+ *
719
+ * @param input - the media arguments as the caller typed them.
720
+ * @param model - the model the submit names, which constrains what is legal.
721
+ * @param context - credential, fetch, retry policy.
722
+ * @returns the media keyed by the SERVICE's field names, plus the two booleans
723
+ * the ratio rule branches on.
724
+ * @throws HarnessError for any refusal; nothing is uploaded before the last free
725
+ * check has passed.
726
+ */
727
+ export declare function prepareGenerationMedia(input: MinimaxGenerationMediaInput, model: MinimaxVideoModel, context: MinimaxMediaPrepareContext): Promise<MinimaxGenerationMedia>;
728
+ /**
729
+ * Extract the byte count from an `inline:<N>B` source, or undefined.
730
+ *
731
+ * Only the inline spelling carries a count; a URL source echoes the URL, and a
732
+ * body with no `source` at all carries nothing. Both are "no count", and the
733
+ * caller SKIPS the cross-check rather than failing it.
734
+ *
735
+ * @param source - the measured `results[0].source`.
736
+ * @returns the byte count, or undefined when the source is not `inline:<N>B`.
737
+ */
738
+ export declare function inlineSourceBytes(source: string): number | undefined;
739
+ /**
740
+ * Whether this text says the video was never seen.
741
+ *
742
+ * @param text - the description, the error, or both joined.
743
+ * @returns true when the text declares no video was received.
744
+ */
745
+ export declare function declaresNoVideoViewed(text: string): boolean;
746
+ /**
747
+ * Build the video-understanding tool.
748
+ *
749
+ * @param ctx - host context (the route gate needs no service, but the context
750
+ * is kept for symmetry with the generation tool and for later extensions).
751
+ * @param options - credential source, fetch and the injectable clocks.
752
+ * @returns a registry-ready tool definition.
753
+ */
754
+ export declare function createMinimaxUnderstandVideoTool(ctx: Context, options: MinimaxVideoToolOptions): import("@deepseek-ai/dsh-tools").ToolDefinition;
755
+ export declare function createMinimaxGenerateVideoTool(ctx: Context, options: MinimaxVideoToolOptions): import("@deepseek-ai/dsh-tools").ToolDefinition;
756
+ export {};
757
+ //# sourceMappingURL=video-tool.d.ts.map