@fungi.computer/darkroom 0.0.1 → 0.2.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.
@@ -3,8 +3,13 @@ import { defineIdFamily } from "@fungi.computer/cairn/id";
3
3
  import { mediaGenerationSettingsSchema, validateMediaGenerationSettings, } from "./index.js";
4
4
  import { z } from "zod";
5
5
  import { reportCatchFailure } from "./failure.js";
6
- import { MediaSafetyFilterRefusal } from "./execution-error.js";
7
- const providerRefusalSchema = z.literal("safety_filter_refused");
6
+ import { MediaExecutionError, MediaSafetyFilterRefusal, mediaFailureStageSchema, } from "./execution-error.js";
7
+ import { mediaProviderDiagnosticWireSchema, } from "@fungi.computer/agar/errors";
8
+ const providerFailureSchema = z.strictObject({
9
+ stage: mediaFailureStageSchema.extract(["provider", "normalization"]),
10
+ safetyRefused: z.boolean(),
11
+ provider: mediaProviderDiagnosticWireSchema.optional(),
12
+ });
8
13
  const ids = defineIdFamily({
9
14
  family: "hub-media-operation",
10
15
  version: 1,
@@ -12,21 +17,21 @@ const ids = defineIdFamily({
12
17
  });
13
18
  const text = z.string().min(1).max(256);
14
19
  const path = z.string().min(1).max(1_024);
15
- const referenceMetadataSchema = z.object({
20
+ const referenceMetadataSchema = z.lazy(() => z.object({
16
21
  format: z.enum(["png", "jpeg", "gif", "webp"]),
17
22
  width: z.coerce.number().int().positive(),
18
23
  height: z.coerce.number().int().positive(),
19
- });
24
+ }));
20
25
  const referenceKey = (operationId, index) => `media-reference/v1/${operationId}/${String(index)}`;
21
26
  /** Fixed generation destination captured before provider dispatch. */
22
- export const mediaOperationDestinationSchema = z.strictObject({
27
+ export const mediaOperationDestinationSchema = z.lazy(() => z.strictObject({
23
28
  /** Host-admitted destination or reference identity. */
24
29
  computerId: text,
25
30
  /** Fixed relative path in the admitted destination. */
26
31
  path,
27
32
  /** Optional verified image encoding pin. */
28
33
  outputFormat: mediaRequestedImageFormatSchema.optional(),
29
- });
34
+ }));
30
35
  /** Decode host namespace and owner identity. */
31
36
  export const mediaOperationCoordinatesSchema = z.strictObject({
32
37
  /** Host isolation namespace. */
@@ -54,13 +59,13 @@ export const mediaOperationStateSchema = z.enum({
54
59
  interrupted: "interrupted",
55
60
  });
56
61
  /** Decode retained or saved output size and encoding. */
57
- export const mediaImageSchema = z.strictObject({
62
+ export const mediaImageSchema = z.lazy(() => z.strictObject({
58
63
  /** Output byte length. */
59
64
  bytes: z.number().int().positive(),
60
65
  /** Actual output encoding. */
61
66
  format: text,
62
- });
63
- const retainedFormatSchema = z
67
+ }));
68
+ const retainedFormatSchema = z.lazy(() => z
64
69
  .enum(["image/png", "image/jpeg", "image/gif", "image/webp", "video/mp4"])
65
70
  .transform((mime) => ({
66
71
  "image/png": "png",
@@ -68,15 +73,15 @@ const retainedFormatSchema = z
68
73
  "image/gif": "gif",
69
74
  "image/webp": "webp",
70
75
  "video/mp4": "mp4",
71
- })[mime]);
72
- const outputSchema = z.strictObject({
76
+ })[mime]));
77
+ const outputSchema = z.lazy(() => z.strictObject({
73
78
  key: text,
74
79
  version: text,
75
80
  bytes: z.number().int().positive(),
76
81
  format: text,
77
- });
82
+ }));
78
83
  /** Decode the settled receipt, including the host-admitted customer price. */
79
- export const mediaOperationResultSchema = z.strictObject({
84
+ export const mediaOperationResultSchema = z.lazy(() => z.strictObject({
80
85
  /** Durable operation identifier. */
81
86
  generationId: text,
82
87
  /** Output byte length. */
@@ -85,7 +90,7 @@ export const mediaOperationResultSchema = z.strictObject({
85
90
  format: text,
86
91
  /** Admitted price in milliunits, where 1 cent is 1,000 milliunits. */
87
92
  costMilliunits: z.number().int().nonnegative(),
88
- });
93
+ }));
89
94
  class MediaOperationError extends Error {
90
95
  code;
91
96
  constructor(
@@ -98,7 +103,7 @@ class MediaOperationError extends Error {
98
103
  }
99
104
  /** Stored media type for an output format. */
100
105
  const outputMime = (format) => format === "mp4" ? "video/mp4" : `image/${format}`;
101
- const operationRowSchema = z.object({
106
+ const operationRowSchema = z.lazy(() => z.object({
102
107
  operation_id: z.string(),
103
108
  request_id: z.string(),
104
109
  actor_user_id: z.string(),
@@ -118,7 +123,7 @@ const operationRowSchema = z.object({
118
123
  updated_at: z.number(),
119
124
  background: z.number(),
120
125
  dispatched_at: z.number().nullable(),
121
- });
126
+ }));
122
127
  const schemaStatements = [
123
128
  `CREATE TABLE hub_media_operation (
124
129
  singleton INTEGER PRIMARY KEY CHECK(singleton=1),
@@ -143,12 +148,12 @@ const schemaStatements = [
143
148
  dispatched_at INTEGER
144
149
  ) STRICT`,
145
150
  "CREATE TABLE hub_media_spent_failure (singleton INTEGER PRIMARY KEY CHECK(singleton=1),code TEXT NOT NULL CHECK(code='output_format_mismatch')) STRICT",
146
- "CREATE TABLE hub_media_provider_refusal (singleton INTEGER PRIMARY KEY CHECK(singleton=1),code TEXT NOT NULL CHECK(code='safety_filter_refused')) STRICT",
151
+ "CREATE TABLE hub_media_provider_failure (singleton INTEGER PRIMARY KEY CHECK(singleton=1),failure_json TEXT NOT NULL) STRICT",
147
152
  ];
148
153
  function fingerprint(input) {
149
154
  return JSON.stringify(input);
150
155
  }
151
- const objectSchema = z.record(z.string(), z.unknown());
156
+ const objectSchema = z.lazy(() => z.record(z.string(), z.unknown()));
152
157
  function decodeStoredRequest(serialized) {
153
158
  let raw;
154
159
  try {
@@ -235,8 +240,8 @@ export class MediaOperationOwner {
235
240
  }
236
241
  else {
237
242
  // Pre-launch stores use the current fresh schema or get reset by the host.
238
- // Missing refusal facts are not healed or incrementally migrated here.
239
- this.ctx.storage.sql.exec("SELECT code FROM hub_media_provider_refusal LIMIT 0");
243
+ // Missing failure facts are not healed or incrementally migrated here.
244
+ this.ctx.storage.sql.exec("SELECT failure_json FROM hub_media_provider_failure LIMIT 0");
240
245
  }
241
246
  this.initialized = true;
242
247
  }
@@ -301,12 +306,14 @@ export class MediaOperationOwner {
301
306
  code: z.literal("output_format_mismatch"),
302
307
  })
303
308
  .parse(failure).code;
304
- const refusal = this.ctx.storage.sql
305
- .exec("SELECT code FROM hub_media_provider_refusal WHERE singleton=1")
309
+ const failureRow = this.ctx.storage.sql
310
+ .exec("SELECT failure_json FROM hub_media_provider_failure WHERE singleton=1")
306
311
  .toArray()[0];
307
- const providerRefusal = refusal === undefined
312
+ const providerFailure = failureRow === undefined
308
313
  ? null
309
- : z.strictObject({ code: providerRefusalSchema }).parse(refusal).code;
314
+ : this.decodeJson(z
315
+ .strictObject({ failure_json: z.string().max(1024) })
316
+ .parse(failureRow).failure_json, providerFailureSchema);
310
317
  return Object.freeze({
311
318
  operationId: record.operationId,
312
319
  requestId: record.requestId,
@@ -314,7 +321,7 @@ export class MediaOperationOwner {
314
321
  owner: record.owner,
315
322
  state: record.state,
316
323
  spentFailure,
317
- providerRefusal,
324
+ providerFailure,
318
325
  estimatedCostMilliunits: record.estimatedCostMilliunits,
319
326
  image: record.image,
320
327
  result: record.result,
@@ -684,8 +691,13 @@ export class MediaOperationOwner {
684
691
  // Nothing was delivered; the next retry sees interrupted and releases
685
692
  // the billing hold at zero units.
686
693
  try {
687
- this.interruptGeneration(leaseId, cause instanceof MediaSafetyFilterRefusal
688
- ? "safety_filter_refused"
694
+ this.interruptGeneration(leaseId, cause instanceof MediaExecutionError &&
695
+ (cause.stage === "provider" || cause.stage === "normalization")
696
+ ? {
697
+ stage: cause.stage,
698
+ safetyRefused: cause instanceof MediaSafetyFilterRefusal,
699
+ provider: cause.provider,
700
+ }
689
701
  : undefined);
690
702
  }
691
703
  catch (cause) {
@@ -702,8 +714,8 @@ export class MediaOperationOwner {
702
714
  this.ctx.storage.sql.exec("UPDATE hub_media_operation SET lease_id=NULL, lease_expires_at=NULL WHERE singleton=1 AND state='writing' AND lease_id=?", leaseId);
703
715
  }
704
716
  /** An aborted in-flight provider call is terminal for this request ID. */
705
- interruptGeneration(leaseId, refusalInput) {
706
- const refusal = providerRefusalSchema.optional().parse(refusalInput);
717
+ interruptGeneration(leaseId, failureInput) {
718
+ const failure = providerFailureSchema.optional().parse(failureInput);
707
719
  const record = this.requireRecord();
708
720
  if (record.state !== "generating" || record.leaseId !== leaseId)
709
721
  throw new MediaOperationError("lease_lost");
@@ -720,8 +732,8 @@ export class MediaOperationOwner {
720
732
  writeReceipt: null,
721
733
  result: null,
722
734
  });
723
- if (refusal !== undefined)
724
- this.ctx.storage.sql.exec("INSERT INTO hub_media_provider_refusal(singleton,code) VALUES(1,?)", refusal);
735
+ if (failure !== undefined)
736
+ this.ctx.storage.sql.exec("INSERT INTO hub_media_provider_failure(singleton,failure_json) VALUES(1,?)", JSON.stringify(failure));
725
737
  return this.project(interrupted);
726
738
  });
727
739
  }
@@ -72,8 +72,13 @@ export function executeMediaOperation(input) {
72
72
  }
73
73
  if (claim.kind === "interrupted") {
74
74
  yield* settleNothing();
75
- if (claim.operation.providerRefusal === "safety_filter_refused")
76
- return yield* Effect.fail(new MediaSafetyFilterRefusal());
75
+ const failure = claim.operation.providerFailure;
76
+ if (failure !== null)
77
+ return yield* Effect.fail(failure.safetyRefused
78
+ ? new MediaSafetyFilterRefusal({ provider: failure.provider })
79
+ : new MediaExecutionError(failure.stage, {
80
+ provider: failure.provider,
81
+ }));
77
82
  }
78
83
  if (claim.kind !== "claimed" || claim.leaseId === undefined)
79
84
  return {
@@ -149,11 +154,16 @@ export function executeMediaOperation(input) {
149
154
  }, "provider").pipe(
150
155
  // A provider failure delivered nothing and wrote no output: end the
151
156
  // request now and release its hold rather than leave it unresolved.
152
- Effect.tapError((error) => error.stage === "provider"
153
- ? call(() => input.operation.interruptGeneration(leaseId, error instanceof MediaSafetyFilterRefusal
154
- ? "safety_filter_refused"
155
- : undefined), "operation").pipe(Effect.andThen(settleNothing()), Effect.ignore)
156
- : Effect.void));
157
+ Effect.tapError((error) => {
158
+ const stage = error.stage;
159
+ return stage === "provider" || stage === "normalization"
160
+ ? call(() => input.operation.interruptGeneration(leaseId, {
161
+ stage,
162
+ safetyRefused: error instanceof MediaSafetyFilterRefusal,
163
+ provider: error.provider,
164
+ }), "operation").pipe(Effect.andThen(settleNothing()), Effect.ignore)
165
+ : Effect.void;
166
+ }));
157
167
  if (generation.kind === "interrupted") {
158
168
  yield* settleNothing();
159
169
  return { kind: "interrupted" };
@@ -26,7 +26,7 @@ export declare const mediaModelTierSchema: z.ZodEnum<{
26
26
  /** A model selection tier, independent of billing price. */
27
27
  export type MediaModelTier = z.output<typeof mediaModelTierSchema>;
28
28
  /** Media's provider catalog: Workers AI images plus gateway image and video models. */
29
- export declare const mediaModelInputSchema: z.ZodReadonly<z.ZodObject<{
29
+ export declare const mediaModelInputSchema: z.ZodLazy<z.ZodReadonly<z.ZodObject<{
30
30
  transport: z.ZodEnum<{
31
31
  /** JSON provider input. */
32
32
  readonly json: "json";
@@ -54,7 +54,7 @@ export declare const mediaModelInputSchema: z.ZodReadonly<z.ZodObject<{
54
54
  defaultSteps: z.ZodNullable<z.ZodNumber>;
55
55
  referenceField: z.ZodNullable<z.ZodString>;
56
56
  maxReferences: z.ZodNumber;
57
- }, z.core.$strict>>;
57
+ }, z.core.$strict>>>;
58
58
  /** Verified Unified AI video identifiers; no inferred family aliases. */
59
59
  export declare const mediaVideoModelIdSchema: z.ZodEnum<{
60
60
  /** Seedance 2.0. */
@@ -118,7 +118,7 @@ export declare const mediaVideoReferenceRoleSchema: z.ZodEnum<{
118
118
  /** The role of a selected reference image in a video request. */
119
119
  export type MediaVideoReferenceRole = z.output<typeof mediaVideoReferenceRoleSchema>;
120
120
  /** One nominal size used to select provider resolution and aspect. */
121
- export declare const mediaVideoFormatSchema: z.ZodReadonly<z.ZodObject<{
121
+ export declare const mediaVideoFormatSchema: z.ZodLazy<z.ZodReadonly<z.ZodObject<{
122
122
  resolution: z.ZodEnum<{
123
123
  /** 480p. */
124
124
  readonly p480: "480p";
@@ -149,11 +149,11 @@ export declare const mediaVideoFormatSchema: z.ZodReadonly<z.ZodObject<{
149
149
  }>;
150
150
  width: z.ZodNumber;
151
151
  height: z.ZodNumber;
152
- }, z.core.$strict>>;
152
+ }, z.core.$strict>>>;
153
153
  /** One immutable nominal video format. */
154
154
  export type MediaVideoFormat = z.output<typeof mediaVideoFormatSchema>;
155
155
  /** Verified video parameters and provider costs, checked 2026-10-11. */
156
- export declare const mediaVideoSchema: z.ZodReadonly<z.ZodObject<{
156
+ export declare const mediaVideoSchema: z.ZodLazy<z.ZodReadonly<z.ZodObject<{
157
157
  minSeconds: z.ZodNumber;
158
158
  maxSeconds: z.ZodNumber;
159
159
  defaultSeconds: z.ZodNumber;
@@ -166,7 +166,7 @@ export declare const mediaVideoSchema: z.ZodReadonly<z.ZodObject<{
166
166
  /** MiniMax multimodal `content[]` array and uppercase resolution. */
167
167
  readonly minimax: "minimax";
168
168
  }>;
169
- formats: z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
169
+ formats: z.ZodReadonly<z.ZodArray<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
170
170
  resolution: z.ZodEnum<{
171
171
  /** 480p. */
172
172
  readonly p480: "480p";
@@ -197,7 +197,7 @@ export declare const mediaVideoSchema: z.ZodReadonly<z.ZodObject<{
197
197
  }>;
198
198
  width: z.ZodNumber;
199
199
  height: z.ZodNumber;
200
- }, z.core.$strict>>>>;
200
+ }, z.core.$strict>>>>>;
201
201
  defaultResolution: z.ZodEnum<{
202
202
  /** 480p. */
203
203
  readonly p480: "480p";
@@ -265,7 +265,7 @@ export declare const mediaVideoSchema: z.ZodReadonly<z.ZodObject<{
265
265
  silentMilliunitsPerSecond: z.ZodNumber;
266
266
  audioMilliunitsPerSecond: z.ZodNumber;
267
267
  }, z.core.$strict>>>>;
268
- }, z.core.$strict>>;
268
+ }, z.core.$strict>>>;
269
269
  /** Immutable video capability and price metadata. */
270
270
  export type MediaVideoModel = z.output<typeof mediaVideoSchema>;
271
271
  /** Public wire grammar for a catalog entry returned by the Media owner. */
@@ -296,7 +296,7 @@ export declare const mediaModelSchema: z.ZodReadonly<z.ZodObject<{
296
296
  /** WebP image encoding. */
297
297
  readonly webp: "webp";
298
298
  }>>>;
299
- input: z.ZodReadonly<z.ZodObject<{
299
+ input: z.ZodLazy<z.ZodReadonly<z.ZodObject<{
300
300
  transport: z.ZodEnum<{
301
301
  /** JSON provider input. */
302
302
  readonly json: "json";
@@ -324,9 +324,9 @@ export declare const mediaModelSchema: z.ZodReadonly<z.ZodObject<{
324
324
  defaultSteps: z.ZodNullable<z.ZodNumber>;
325
325
  referenceField: z.ZodNullable<z.ZodString>;
326
326
  maxReferences: z.ZodNumber;
327
- }, z.core.$strict>>;
327
+ }, z.core.$strict>>>;
328
328
  sizes: z.ZodNullable<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
329
- video: z.ZodNullable<z.ZodReadonly<z.ZodObject<{
329
+ video: z.ZodNullable<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
330
330
  minSeconds: z.ZodNumber;
331
331
  maxSeconds: z.ZodNumber;
332
332
  defaultSeconds: z.ZodNumber;
@@ -339,7 +339,7 @@ export declare const mediaModelSchema: z.ZodReadonly<z.ZodObject<{
339
339
  /** MiniMax multimodal `content[]` array and uppercase resolution. */
340
340
  readonly minimax: "minimax";
341
341
  }>;
342
- formats: z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
342
+ formats: z.ZodReadonly<z.ZodArray<z.ZodLazy<z.ZodReadonly<z.ZodObject<{
343
343
  resolution: z.ZodEnum<{
344
344
  /** 480p. */
345
345
  readonly p480: "480p";
@@ -370,7 +370,7 @@ export declare const mediaModelSchema: z.ZodReadonly<z.ZodObject<{
370
370
  }>;
371
371
  width: z.ZodNumber;
372
372
  height: z.ZodNumber;
373
- }, z.core.$strict>>>>;
373
+ }, z.core.$strict>>>>>;
374
374
  defaultResolution: z.ZodEnum<{
375
375
  /** 480p. */
376
376
  readonly p480: "480p";
@@ -438,7 +438,7 @@ export declare const mediaModelSchema: z.ZodReadonly<z.ZodObject<{
438
438
  silentMilliunitsPerSecond: z.ZodNumber;
439
439
  audioMilliunitsPerSecond: z.ZodNumber;
440
440
  }, z.core.$strict>>>>;
441
- }, z.core.$strict>>>;
441
+ }, z.core.$strict>>>>;
442
442
  }, z.core.$strict>>;
443
443
  /** Model-specific dimensions, steps, transport and reference limits. */
444
444
  export type MediaModelInput = z.output<typeof mediaModelInputSchema>;
@@ -24,7 +24,7 @@ export const mediaModelTierSchema = z.enum({
24
24
  max: "max",
25
25
  });
26
26
  /** Media's provider catalog: Workers AI images plus gateway image and video models. */
27
- export const mediaModelInputSchema = z
27
+ export const mediaModelInputSchema = z.lazy(() => z
28
28
  .strictObject({
29
29
  /** Provider input transport. */
30
30
  transport: z.enum({
@@ -64,7 +64,7 @@ export const mediaModelInputSchema = z
64
64
  /** Maximum references accepted by this model. */
65
65
  maxReferences: z.number().int().nonnegative(),
66
66
  })
67
- .readonly();
67
+ .readonly());
68
68
  /** Verified Unified AI video identifiers; no inferred family aliases. */
69
69
  export const mediaVideoModelIdSchema = z.enum({
70
70
  /** Seedance 2.0. */
@@ -120,7 +120,7 @@ export const mediaVideoReferenceRoleSchema = z.enum({
120
120
  reference: "reference",
121
121
  });
122
122
  /** One nominal size used to select provider resolution and aspect. */
123
- export const mediaVideoFormatSchema = z
123
+ export const mediaVideoFormatSchema = z.lazy(() => z
124
124
  .strictObject({
125
125
  /** Provider resolution. */
126
126
  resolution: mediaVideoResolutionSchema,
@@ -131,9 +131,9 @@ export const mediaVideoFormatSchema = z
131
131
  /** Nominal height; actual MP4 dimensions are not decoded. */
132
132
  height: z.number().int().positive(),
133
133
  })
134
- .readonly();
134
+ .readonly());
135
135
  /** Verified video parameters and provider costs, checked 2026-10-11. */
136
- export const mediaVideoSchema = z
136
+ export const mediaVideoSchema = z.lazy(() => z
137
137
  .strictObject({
138
138
  /** Minimum duration, for callers displaying bounds. */
139
139
  minSeconds: z.number().int().positive(),
@@ -182,7 +182,7 @@ export const mediaVideoSchema = z
182
182
  .readonly())
183
183
  .readonly(),
184
184
  })
185
- .readonly();
185
+ .readonly());
186
186
  /** Public wire grammar for a catalog entry returned by the Media owner. */
187
187
  export const mediaModelSchema = z
188
188
  .strictObject({
package/dist/server.d.ts CHANGED
@@ -4,7 +4,7 @@ import { z } from "zod";
4
4
  import { validateMediaGenerationSettings, type MediaProvider, type MediaReference, type MediaReferenceBytes } from "./index.js";
5
5
  import { type MediaExecution, type MediaMetering } from "./media-operation-contract.js";
6
6
  import { MediaExecutionError, type MediaBillingRefusalCode } from "./execution-error.js";
7
- export { MediaBillingRefusal, MediaExecutionError, type MediaBillingRefusalCode, type MediaFailureStage, } from "./execution-error.js";
7
+ export { MediaBillingRefusal, MediaExecutionError, type MediaBillingRefusalCode, type MediaFailureStage, type MediaExecutionErrorOptions, } from "./execution-error.js";
8
8
  export { mediaUnits, type MediaUnits } from "./gateway-models.js";
9
9
  export type { MediaMetering, MediaOperation, } from "./media-operation-contract.js";
10
10
  export { MediaOperationOwner, mediaOperationDestinationSchema, mediaOperationCoordinatesSchema, mediaOperationStateSchema, mediaImageSchema, mediaOperationResultSchema, } from "./media-operation-owner.js";
package/dist/server.js CHANGED
@@ -11,7 +11,7 @@ import { MediaOutputFormatMismatch, MediaBillingRefusal, MediaExecutionError, Me
11
11
  export { MediaBillingRefusal, MediaExecutionError, } from "./execution-error.js";
12
12
  export { mediaUnits } from "./gateway-models.js";
13
13
  export { MediaOperationOwner, mediaOperationDestinationSchema, mediaOperationCoordinatesSchema, mediaOperationStateSchema, mediaImageSchema, mediaOperationResultSchema, } from "./media-operation-owner.js";
14
- const identifier = z.string().min(1).max(256);
14
+ const identifier = z.lazy(() => z.string().min(1).max(256));
15
15
  /** Decode relative service generation input. Identity comes from the host. */
16
16
  export const mediaRequestSchema = z.strictObject({
17
17
  /** Fixed destination or reference file path. */
@@ -51,6 +51,7 @@ function failure(error, refusalMessages) {
51
51
  stage: "provider",
52
52
  code: "SAFETY_FILTER_REFUSED",
53
53
  retryable: false,
54
+ provider: error.provider,
54
55
  }, { status: 400, headers });
55
56
  if (error instanceof MediaExecutionError &&
56
57
  error.cause instanceof MediaOutputFormatMismatch)
@@ -105,6 +106,7 @@ function failure(error, refusalMessages) {
105
106
  stage: error.stage,
106
107
  code: "HOST_FAILURE",
107
108
  retryable: error.stage !== "normalization" && error.stage !== "provider",
109
+ provider: error instanceof MediaExecutionError ? error.provider : undefined,
108
110
  }, {
109
111
  status: 503,
110
112
  headers,
@@ -19,12 +19,12 @@ const minimaxRoleWire = {
19
19
  /** MiniMax's documented task wrapper: `{task: {status, content: {url}}}`,
20
20
  * distinct from the Unified gateway's `{state, result}` shape Seedance and
21
21
  * Veo normalize into. https://developers.cloudflare.com/ai/models/minimax/h3-max/ */
22
- const minimaxTaskOutputSchema = z.looseObject({
22
+ const minimaxTaskOutputSchema = z.lazy(() => z.looseObject({
23
23
  task: z.looseObject({
24
24
  status: z.enum(["queued", "running", "succeeded", "failed", "cancelled"]),
25
25
  content: z.looseObject({ url: resultUrl.optional() }).optional(),
26
26
  }),
27
- });
27
+ }));
28
28
  export const minimaxVideoAdapter = {
29
29
  buildInput(checked, references, model) {
30
30
  if (checked.generateAudio !== undefined)