@neta-art/generation 0.1.19 → 0.1.21

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 CHANGED
@@ -515,13 +515,20 @@ console.log(resolved.parameters);
515
515
  ## Error handling
516
516
 
517
517
  ```ts
518
- import { GenerationValidationError, GenerationProviderError } from "@neta-art/generation";
518
+ import {
519
+ GenerationProviderError,
520
+ GenerationTransportError,
521
+ GenerationValidationError,
522
+ } from "@neta-art/generation";
519
523
 
520
524
  try {
521
525
  await client.generate(request);
522
526
  } catch (error) {
523
527
  if (error instanceof GenerationValidationError) {
524
528
  console.error("Invalid request", error.message);
529
+ } else if (error instanceof GenerationTransportError) {
530
+ console.error("Provider transport failed", error.message);
531
+ console.error(error.details?.causeCode, error.details?.causeSyscall);
525
532
  } else if (error instanceof GenerationProviderError) {
526
533
  console.error("Provider failed", error.message);
527
534
  console.error(error.status, error.details?.requestId, error.details?.code);
package/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { r as listBuiltinGenerationModels } from "../builtins-B4Agk9nt.js";
3
- import { h as stringifyGenerationModelDeclaration, i as createGenerationClient, n as exportBuiltinModelConfigs, t as exportBuiltinModelConfig } from "../export-config-2OmCf-nP.js";
3
+ import { h as stringifyGenerationModelDeclaration, i as createGenerationClient, n as exportBuiltinModelConfigs, t as exportBuiltinModelConfig } from "../export-config-Ct9_V_Pj.js";
4
4
  import { mkdir, writeFile } from "node:fs/promises";
5
5
  import { dirname, join } from "node:path";
6
6
 
@@ -40,12 +40,33 @@ var GenerationProviderError = class extends GenerationError {
40
40
  this.details = options?.details;
41
41
  }
42
42
  };
43
+ var GenerationTransportError = class extends GenerationProviderError {
44
+ constructor(details, cause) {
45
+ super(transportErrorMessage(details), { details });
46
+ this.name = "GenerationTransportError";
47
+ this.cause = cause;
48
+ }
49
+ };
43
50
  var GenerationTimeoutError = class extends GenerationProviderError {
44
51
  constructor(message = "Generation request timed out", details) {
45
52
  super(message, details ? { details } : void 0);
46
53
  this.name = "GenerationTimeoutError";
47
54
  }
48
55
  };
56
+ function transportErrorMessage(details) {
57
+ return [
58
+ "Generation transport failed",
59
+ `method=${details.method}`,
60
+ details.host ? `host=${details.host}` : void 0,
61
+ `path=${details.path}`,
62
+ `elapsed_ms=${details.elapsedMs}`,
63
+ details.causeCode ? `cause_code=${details.causeCode}` : void 0,
64
+ details.causeName ? `cause_name=${details.causeName}` : void 0,
65
+ details.causeSyscall ? `cause_syscall=${details.causeSyscall}` : void 0,
66
+ details.causeAddress ? `cause_address=${details.causeAddress}` : void 0,
67
+ details.causePort !== void 0 ? `cause_port=${details.causePort}` : void 0
68
+ ].filter((part) => part !== void 0).join(" ");
69
+ }
49
70
 
50
71
  //#endregion
51
72
  //#region src/http.ts
@@ -78,14 +99,25 @@ function pickTraceHeaders(headers) {
78
99
  for (const [key, value] of Object.entries(headers)) if (TRACE_HEADER_PATTERN.test(key)) output[key] = value;
79
100
  return output;
80
101
  }
102
+ var DebugObserverError = class extends Error {
103
+ constructor(cause) {
104
+ super("Generation debug observer failed");
105
+ this.name = "DebugObserverError";
106
+ this.cause = cause;
107
+ }
108
+ };
81
109
  function emitDebugRequest(debug, url, init) {
82
- debug.logger({
83
- type: "request",
84
- url,
85
- method: init.method ?? "GET",
86
- headers: headersToRecord(init.headers),
87
- body: parseDebugBody(init.body)
88
- });
110
+ try {
111
+ debug.logger({
112
+ type: "request",
113
+ url,
114
+ method: init.method ?? "GET",
115
+ headers: headersToRecord(init.headers),
116
+ body: parseDebugBody(init.body)
117
+ });
118
+ } catch (cause) {
119
+ throw new DebugObserverError(cause);
120
+ }
89
121
  return Date.now();
90
122
  }
91
123
  async function readDebugResponseBody(response) {
@@ -95,17 +127,21 @@ async function readDebugResponseBody(response) {
95
127
  return "[non-text body]";
96
128
  }
97
129
  async function emitDebugResponse(debug, url, response, startedAt) {
98
- const headers = headersToRecord(response.headers);
99
- debug.logger({
100
- type: "response",
101
- url,
102
- status: response.status,
103
- statusText: response.statusText,
104
- headers,
105
- trace: pickTraceHeaders(headers),
106
- elapsedMs: Date.now() - startedAt,
107
- ...debug.includeResponseBody ? { body: await readDebugResponseBody(response) } : {}
108
- });
130
+ try {
131
+ const headers = headersToRecord(response.headers);
132
+ debug.logger({
133
+ type: "response",
134
+ url,
135
+ status: response.status,
136
+ statusText: response.statusText,
137
+ headers,
138
+ trace: pickTraceHeaders(headers),
139
+ elapsedMs: Date.now() - startedAt,
140
+ ...debug.includeResponseBody ? { body: await readDebugResponseBody(response) } : {}
141
+ });
142
+ } catch (cause) {
143
+ throw new DebugObserverError(cause);
144
+ }
109
145
  }
110
146
  function createDebugFetch(fetchFn, debug) {
111
147
  return (async (input, init) => {
@@ -119,14 +155,16 @@ function createDebugFetch(fetchFn, debug) {
119
155
  async function fetchWithTimeout(fetchFn, url, init, timeoutMs) {
120
156
  const controller = new AbortController();
121
157
  const timeout = setTimeout(() => controller.abort(), timeoutMs);
158
+ const startedAt = Date.now();
122
159
  try {
123
160
  return await fetchFn(url, {
124
161
  ...init,
125
162
  signal: controller.signal
126
163
  });
127
164
  } catch (error) {
165
+ if (error instanceof DebugObserverError) throw error.cause;
128
166
  if (error instanceof Error && error.name === "AbortError") throw new GenerationTimeoutError();
129
- throw error;
167
+ throw new GenerationTransportError(transportErrorDetails(url, init, startedAt, error), error);
130
168
  } finally {
131
169
  clearTimeout(timeout);
132
170
  }
@@ -134,6 +172,56 @@ async function fetchWithTimeout(fetchFn, url, init, timeoutMs) {
134
172
  function joinUrl(baseUrl, path) {
135
173
  return `${baseUrl.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
136
174
  }
175
+ function transportErrorDetails(rawUrl, init, startedAt, error) {
176
+ const summary = transportErrorSummary(error);
177
+ return compactObject({
178
+ method: (init.method ?? "GET").toUpperCase(),
179
+ ...transportErrorTarget(rawUrl),
180
+ elapsedMs: Date.now() - startedAt,
181
+ causeName: summary.causeName ?? summary.name,
182
+ causeCode: summary.causeCode,
183
+ causeSyscall: summary.causeSyscall,
184
+ causeAddress: summary.causeAddress,
185
+ causePort: summary.causePort
186
+ });
187
+ }
188
+ function transportErrorTarget(rawUrl) {
189
+ try {
190
+ const url = new URL(rawUrl);
191
+ return {
192
+ host: url.host,
193
+ path: url.pathname
194
+ };
195
+ } catch {
196
+ const suffixIndex = rawUrl.search(/[?#]/);
197
+ return { path: suffixIndex === -1 ? rawUrl : rawUrl.slice(0, suffixIndex) };
198
+ }
199
+ }
200
+ function transportErrorSummary(error) {
201
+ const outer = error instanceof Error ? error : new Error(String(error));
202
+ const cause = isRecord$6(outer.cause) ? outer.cause : void 0;
203
+ return compactObject({
204
+ name: outer.name,
205
+ causeName: stringProperty(cause, "name"),
206
+ causeCode: stringProperty(cause, "code") ?? stringProperty(outer, "code"),
207
+ causeSyscall: stringProperty(cause, "syscall") ?? stringProperty(outer, "syscall"),
208
+ causeAddress: stringProperty(cause, "address") ?? stringProperty(outer, "address"),
209
+ causePort: stringOrNumberProperty(cause, "port") ?? stringOrNumberProperty(outer, "port")
210
+ });
211
+ }
212
+ function stringProperty(value, key) {
213
+ if (!isRecord$6(value)) return void 0;
214
+ const item = value[key];
215
+ return typeof item === "string" && item.trim() ? item.trim() : void 0;
216
+ }
217
+ function stringOrNumberProperty(value, key) {
218
+ if (!isRecord$6(value)) return void 0;
219
+ const item = value[key];
220
+ return typeof item === "string" || typeof item === "number" ? item : void 0;
221
+ }
222
+ function isRecord$6(value) {
223
+ return typeof value === "object" && value !== null;
224
+ }
137
225
 
138
226
  //#endregion
139
227
  //#region src/validation.ts
@@ -1088,6 +1176,8 @@ const MAX_MEDIA_COUNT = 12;
1088
1176
  const MAX_REFERENCE_IMAGES = 9;
1089
1177
  const MAX_REFERENCE_VIDEOS = 3;
1090
1178
  const MAX_REFERENCE_AUDIO = 3;
1179
+ const DEFAULT_RATIO = "16:9";
1180
+ const ADAPTIVE_RATIO = "adaptive";
1091
1181
  const H3_RATIOS = [
1092
1182
  "adaptive",
1093
1183
  "21:9",
@@ -1173,11 +1263,10 @@ function classifyMedia(media) {
1173
1263
  if (referenceImages > MAX_REFERENCE_IMAGES) throw new GenerationValidationError(`MiniMax H3 supports at most ${MAX_REFERENCE_IMAGES} reference images`);
1174
1264
  if (referenceVideos > MAX_REFERENCE_VIDEOS) throw new GenerationValidationError(`MiniMax H3 supports at most ${MAX_REFERENCE_VIDEOS} reference videos`);
1175
1265
  if (referenceAudio > MAX_REFERENCE_AUDIO) throw new GenerationValidationError(`MiniMax H3 supports at most ${MAX_REFERENCE_AUDIO} reference audio files`);
1176
- if (media.length > MAX_MEDIA_COUNT) throw new GenerationValidationError(`MiniMax H3 supports at most ${MAX_MEDIA_COUNT} media items`);
1266
+ if (media.length > MAX_MEDIA_COUNT) throw new GenerationValidationError(`MiniMax H3 supports at most ${MAX_MEDIA_COUNT} media items; received ${referenceImages} reference images, ${referenceVideos} reference videos, ${referenceAudio} reference audio inputs, and ${firstFrames + lastFrames} frame images`);
1177
1267
  const hasFrames = firstFrames + lastFrames > 0;
1178
1268
  const hasReferences = referenceImages + referenceVideos + referenceAudio > 0;
1179
1269
  if (hasFrames && hasReferences) throw new GenerationValidationError("MiniMax H3 cannot mix frame images with reference materials");
1180
- if (referenceAudio > 0 && referenceImages + referenceVideos === 0) throw new GenerationValidationError("MiniMax H3 reference audio requires a reference image or video");
1181
1270
  if (hasFrames) return "frame";
1182
1271
  if (hasReferences) return "reference";
1183
1272
  return "text";
@@ -1222,13 +1311,10 @@ function resolveDuration(value) {
1222
1311
  return duration;
1223
1312
  }
1224
1313
  function resolveRatio(value, mode) {
1225
- const requested = asString$1(value) ?? "16:9";
1314
+ const requested = asString$1(value) ?? DEFAULT_RATIO;
1226
1315
  if (!H3_RATIOS.includes(requested)) throw new GenerationValidationError(`MiniMax H3 ratio must be one of: ${H3_RATIOS.join(", ")}`);
1227
- if (mode === "text") {
1228
- if (requested === "adaptive") throw new GenerationValidationError("MiniMax H3 text-to-video ratio cannot be adaptive");
1229
- return requested;
1230
- }
1231
- return "adaptive";
1316
+ if (mode === "text") return requested === ADAPTIVE_RATIO ? DEFAULT_RATIO : requested;
1317
+ return ADAPTIVE_RATIO;
1232
1318
  }
1233
1319
  function extractTaskId$1(response) {
1234
1320
  const data = isRecord$3(response.data) ? response.data : void 0;
@@ -1236,19 +1322,36 @@ function extractTaskId$1(response) {
1236
1322
  if (!taskId) throw new GenerationProviderError("MiniMax H3 provider did not return a task id", { details: { response } });
1237
1323
  return taskId;
1238
1324
  }
1325
+ function isTaskPayload(value) {
1326
+ return [
1327
+ "status",
1328
+ "task",
1329
+ "result_url",
1330
+ "video_url",
1331
+ "url",
1332
+ "error",
1333
+ "progress",
1334
+ "fail_reason"
1335
+ ].some((key) => key in value);
1336
+ }
1337
+ function unwrapTaskPayload(response) {
1338
+ const data = isRecord$3(response.data) ? response.data : void 0;
1339
+ return data && !isTaskPayload(response) ? data : response;
1340
+ }
1239
1341
  function extractTaskStatus(response) {
1240
- const task = isRecord$3(response.task) ? response.task : void 0;
1241
- const metadata = isRecord$3(response.metadata) ? response.metadata : void 0;
1242
- const content = isRecord$3(task?.content) ? task.content : void 0;
1243
- const status = normalizeStatus$1(response.status ?? task?.status);
1244
- const videoUrl = asString$1(metadata?.url) ?? asString$1(response.result_url) ?? asString$1(response.video_url) ?? asString$1(response.url) ?? asString$1(content?.url);
1245
- const error = isRecord$3(response.error) ? response.error : isRecord$3(task?.error) ? task.error : void 0;
1246
- const message = asString$1(error?.message) ?? asString$1(response.message) ?? asString$1(task?.message);
1342
+ const payload = unwrapTaskPayload(response);
1343
+ const task = isRecord$3(payload.task) ? payload.task : payload;
1344
+ const metadata = isRecord$3(payload.metadata) ? payload.metadata : isRecord$3(task.metadata) ? task.metadata : void 0;
1345
+ const content = isRecord$3(task.content) ? task.content : void 0;
1346
+ const status = normalizeStatus$1(payload.status ?? task.status);
1347
+ const videoUrl = asString$1(metadata?.url) ?? asString$1(payload.result_url) ?? asString$1(payload.video_url) ?? asString$1(payload.url) ?? asString$1(task.result_url) ?? asString$1(task.video_url) ?? asString$1(task.url) ?? asString$1(content?.video_url) ?? asString$1(content?.url);
1348
+ const error = isRecord$3(payload.error) ? payload.error : isRecord$3(task.error) ? task.error : void 0;
1349
+ const message = asString$1(error?.message) ?? asString$1(payload.fail_reason) ?? asString$1(payload.message) ?? asString$1(task.fail_reason) ?? asString$1(task.message) ?? asString$1(response.message);
1247
1350
  const outputMetadata = compactObject({
1248
- progress: response.progress ?? task?.progress,
1249
- resolution: response.resolution ?? task?.resolution,
1250
- duration: response.duration ?? task?.duration,
1251
- ratio: response.ratio ?? task?.ratio
1351
+ progress: payload.progress ?? task.progress,
1352
+ resolution: payload.resolution ?? task.resolution,
1353
+ duration: payload.duration ?? task.duration,
1354
+ ratio: payload.ratio ?? task.ratio
1252
1355
  });
1253
1356
  return {
1254
1357
  status: error && status === "unknown" ? "failed" : status,
@@ -2206,5 +2309,5 @@ async function exportBuiltinModelConfigs(directory) {
2206
2309
  }
2207
2310
 
2208
2311
  //#endregion
2209
- export { resolveGenerationMeta as A, minimaxH3VideoGenerationsAdapter as C, arkVideoGenerationsAdapter as D, audioSpeechAdapter as E, GenerationProviderError as F, GenerationTimeoutError as I, GenerationUnsupportedAdapterError as L, validateGenerationContent as M, GenerationConfigError as N, mergeGenerationMeta as O, GenerationError as P, GenerationValidationError as R, openAiImageEditsAdapter as S, geminiGenerateContentAdapter as T, writeGenerationModelDeclarations as _, createGenerationClientFromDirectory as a, sunoTasksAdapter as b, defaultGenerationSourceResolver as c, parseGenerationModelDeclaration as d, readGenerationModelDeclaration as f, writeGenerationModelDeclaration as g, stringifyGenerationModelDeclaration as h, createGenerationClient as i, resolveGenerationParameters as j, mergeTextBlocks as k, isGenerationModelDeclaration as l, readGenerationModelDeclarationsFromFiles as m, exportBuiltinModelConfigs as n, createGenerationClientFromFile as o, readGenerationModelDeclarationsFromDirectory as p, stringifyBuiltinModelConfig as r, createGenerationClientFromFiles as s, exportBuiltinModelConfig as t, mergeGenerationModelDeclarations as u, builtinGenerationAdapters as v, klingVideoGenerationsAdapter as w, openAiImagesAdapter as x, getGenerationAdapter as y };
2210
- //# sourceMappingURL=export-config-2OmCf-nP.js.map
2312
+ export { resolveGenerationMeta as A, minimaxH3VideoGenerationsAdapter as C, arkVideoGenerationsAdapter as D, audioSpeechAdapter as E, GenerationProviderError as F, GenerationTimeoutError as I, GenerationTransportError as L, validateGenerationContent as M, GenerationConfigError as N, mergeGenerationMeta as O, GenerationError as P, GenerationUnsupportedAdapterError as R, openAiImageEditsAdapter as S, geminiGenerateContentAdapter as T, writeGenerationModelDeclarations as _, createGenerationClientFromDirectory as a, sunoTasksAdapter as b, defaultGenerationSourceResolver as c, parseGenerationModelDeclaration as d, readGenerationModelDeclaration as f, writeGenerationModelDeclaration as g, stringifyGenerationModelDeclaration as h, createGenerationClient as i, resolveGenerationParameters as j, mergeTextBlocks as k, isGenerationModelDeclaration as l, readGenerationModelDeclarationsFromFiles as m, exportBuiltinModelConfigs as n, createGenerationClientFromFile as o, readGenerationModelDeclarationsFromDirectory as p, stringifyBuiltinModelConfig as r, createGenerationClientFromFiles as s, exportBuiltinModelConfig as t, mergeGenerationModelDeclarations as u, builtinGenerationAdapters as v, klingVideoGenerationsAdapter as w, openAiImagesAdapter as x, getGenerationAdapter as y, GenerationValidationError as z };
2313
+ //# sourceMappingURL=export-config-Ct9_V_Pj.js.map