@neta-art/generation 0.1.17 → 0.1.18

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.
@@ -1,4 +1,4 @@
1
- import { a as compactArray, c as slugifyFileName, i as cloneJson, l as MODEL_SCHEMA, n as getBuiltinGenerationModel, o as compactObject, r as listBuiltinGenerationModels, s as getBlockMeta, t as builtinGenerationModels } from "./builtins-BqqqQ7Ib.js";
1
+ import { a as compactArray, c as slugifyFileName, i as cloneJson, l as MODEL_SCHEMA, n as getBuiltinGenerationModel, o as compactObject, r as listBuiltinGenerationModels, s as getBlockMeta, t as builtinGenerationModels } from "./builtins-B4Agk9nt.js";
2
2
  import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
3
3
  import { extname, join } from "node:path";
4
4
  import { parse, stringify } from "yaml";
@@ -270,7 +270,7 @@ function mergeTextBlocks(declaration, content) {
270
270
 
271
271
  //#endregion
272
272
  //#region src/adapters/ark-video-generations.ts
273
- const REQUEST_TIMEOUT_MS$5 = 186e4;
273
+ const REQUEST_TIMEOUT_MS$6 = 186e4;
274
274
  const DEFAULT_POLL_INTERVAL_SEC$2 = 2;
275
275
  const DEFAULT_MAX_WAIT_SEC$2 = 600;
276
276
  function sleep$2(ms) {
@@ -406,7 +406,7 @@ async function requestJson$2(input, path, init) {
406
406
  "Content-Type": "application/json",
407
407
  ...init.headers
408
408
  }
409
- }, REQUEST_TIMEOUT_MS$5);
409
+ }, REQUEST_TIMEOUT_MS$6);
410
410
  if (!response.ok) {
411
411
  const body = await response.text().catch(() => response.statusText);
412
412
  throw new GenerationProviderError("Video generation provider request failed", {
@@ -510,6 +510,202 @@ async function arkVideoGenerationsAdapter(input) {
510
510
  throw new GenerationTimeoutError("Timed out waiting for video generation", { taskId });
511
511
  }
512
512
 
513
+ //#endregion
514
+ //#region src/adapters/audio-speech.ts
515
+ const REQUEST_TIMEOUT_MS$5 = 21e4;
516
+ const QWEN_MODELS = new Set([
517
+ "qwen-tts",
518
+ "qwen-audio-3.0-tts-plus",
519
+ "qwen-audio-3.0-tts-flash"
520
+ ]);
521
+ const QWEN_AUDIO_3_MODELS = new Set(["qwen-audio-3.0-tts-plus", "qwen-audio-3.0-tts-flash"]);
522
+ const HIGGS_MODEL = "higgs-tts";
523
+ function isRecord$4(value) {
524
+ return !!value && typeof value === "object" && !Array.isArray(value);
525
+ }
526
+ function textBlocks(input) {
527
+ return input.request.content.filter((block) => block.type === "text");
528
+ }
529
+ function audioBlocks(input) {
530
+ return input.request.content.filter((block) => block.type === "audio");
531
+ }
532
+ function validateMetaKeys(label, meta, allowed) {
533
+ for (const key of Object.keys(meta ?? {})) if (!allowed.has(key)) throw new GenerationValidationError(`Unknown ${label} field: ${key}`);
534
+ }
535
+ function validateHttpUrl(value, label) {
536
+ if (typeof value !== "string") throw new GenerationValidationError(`${label} must be a valid HTTP(S) URL`);
537
+ const trimmed = value.trim();
538
+ if (!trimmed) throw new GenerationValidationError(`${label} must be a non-empty HTTP(S) URL`);
539
+ try {
540
+ const url = new URL(trimmed);
541
+ if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error("unsupported protocol");
542
+ } catch {
543
+ throw new GenerationValidationError(`${label} must be a valid HTTP(S) URL`);
544
+ }
545
+ }
546
+ function validateCommonContent(input) {
547
+ const texts = textBlocks(input);
548
+ if (texts.length !== 1 || typeof texts[0]?.text !== "string" || !texts[0].text.trim()) throw new GenerationValidationError(`${input.declaration.model} requires exactly one non-empty text content block as input`);
549
+ const audio = audioBlocks(input);
550
+ for (const [index, block] of audio.entries()) {
551
+ if (block.source.type !== "url") throw new GenerationValidationError(`${input.declaration.model} reference audio must use a URL source`);
552
+ validateHttpUrl(block.source.url, `audio content block ${index} URL`);
553
+ }
554
+ return {
555
+ text: texts[0],
556
+ audio
557
+ };
558
+ }
559
+ function validateQwen(input, text, audio) {
560
+ if (audio.length > 1) throw new GenerationValidationError(`${input.declaration.model} supports at most one reference audio`);
561
+ const requestMetaKeys = new Set(["voice_prompt", "preview_text"]);
562
+ validateMetaKeys("request.metadata", input.request.metadata, requestMetaKeys);
563
+ validateMetaKeys("request.meta", input.request.meta, requestMetaKeys);
564
+ validateMetaKeys("text content meta", text.meta, /* @__PURE__ */ new Set());
565
+ for (const block of audio) validateMetaKeys("audio content meta", block.meta, /* @__PURE__ */ new Set());
566
+ const voicePrompt = input.meta.voice_prompt;
567
+ const hasVoicePrompt = typeof voicePrompt === "string" && voicePrompt.trim().length > 0;
568
+ if (voicePrompt !== void 0 && !hasVoicePrompt) throw new GenerationValidationError(`${input.declaration.model} meta.voice_prompt must be a non-empty string`);
569
+ if (audio.length === 0 && !hasVoicePrompt) throw new GenerationValidationError(`${input.declaration.model} requires one reference audio or meta.voice_prompt`);
570
+ if (audio.length > 0 && hasVoicePrompt) throw new GenerationValidationError(`${input.declaration.model} reference audio and meta.voice_prompt are mutually exclusive`);
571
+ if (QWEN_AUDIO_3_MODELS.has(input.declaration.model) && Array.from(text.text.trim()).length < 15) throw new GenerationValidationError(`${input.declaration.model} requires input of at least 15 Unicode code points`);
572
+ }
573
+ function hasOwnWeight(block) {
574
+ return Object.hasOwn(block.meta ?? {}, "weight");
575
+ }
576
+ function isPositiveFiniteNumber(value) {
577
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
578
+ }
579
+ function validateHiggs(input, text, audio) {
580
+ if (audio.length > 16) throw new GenerationValidationError(`${input.declaration.model} supports at most 16 references`);
581
+ validateMetaKeys("request.metadata", input.request.metadata, /* @__PURE__ */ new Set());
582
+ validateMetaKeys("request.meta", input.request.meta, /* @__PURE__ */ new Set());
583
+ validateMetaKeys("text content meta", text.meta, /* @__PURE__ */ new Set());
584
+ for (const [index, block] of audio.entries()) {
585
+ validateMetaKeys(`audio content block ${index} meta`, block.meta, new Set(["weight"]));
586
+ const weight = block.meta?.weight;
587
+ if (audio.length === 1 && (!hasOwnWeight(block) || weight === void 0)) continue;
588
+ if (!isPositiveFiniteNumber(weight)) throw new GenerationValidationError(`audio content block ${index} meta.weight must be a finite positive number`);
589
+ }
590
+ }
591
+ function validateAudioSpeechRequest(input) {
592
+ const { text, audio } = validateCommonContent(input);
593
+ if (QWEN_MODELS.has(input.declaration.model)) {
594
+ validateQwen(input, text, audio);
595
+ return;
596
+ }
597
+ if (input.declaration.model === HIGGS_MODEL) {
598
+ validateHiggs(input, text, audio);
599
+ return;
600
+ }
601
+ throw new GenerationValidationError(`Unsupported audio speech model: ${input.declaration.model}`);
602
+ }
603
+ function requestIdFromHeaders(headers) {
604
+ return headers.get("x-request-id")?.trim() || headers.get("x-oneapi-request-id")?.trim() || void 0;
605
+ }
606
+ function buildPayload$2(input) {
607
+ const text = textBlocks(input)[0];
608
+ if (!text) throw new GenerationValidationError("Audio speech input was not validated");
609
+ const audio = audioBlocks(input);
610
+ const payload = {
611
+ model: input.declaration.model,
612
+ input: text.text
613
+ };
614
+ if (QWEN_MODELS.has(input.declaration.model)) {
615
+ if (audio[0]?.source.type === "url") payload.ref_audio = audio[0].source.url.trim();
616
+ else payload.metadata = { voice_prompt: input.meta.voice_prompt };
617
+ return payload;
618
+ }
619
+ const firstAudio = audio[0];
620
+ if (audio.length === 1 && firstAudio && (!hasOwnWeight(firstAudio) || firstAudio.meta?.weight === void 0)) {
621
+ if (firstAudio.source.type === "url") payload.ref_audio = firstAudio.source.url.trim();
622
+ return payload;
623
+ }
624
+ if (audio.length > 0) payload.metadata = { references: audio.map((block) => ({
625
+ url: block.source.type === "url" ? block.source.url.trim() : "",
626
+ weight: block.meta?.weight
627
+ })) };
628
+ return payload;
629
+ }
630
+ function parseJson(rawBody) {
631
+ try {
632
+ return JSON.parse(rawBody);
633
+ } catch {
634
+ return;
635
+ }
636
+ }
637
+ function nonEmptyString(value) {
638
+ return typeof value === "string" && value.trim() ? value : void 0;
639
+ }
640
+ function providerError(response, rawBody) {
641
+ const requestId = requestIdFromHeaders(response.headers);
642
+ const contentType = (response.headers.get("content-type") ?? "").toLowerCase();
643
+ const parsed = contentType.includes("application/json") || contentType.includes("+json") ? parseJson(rawBody) : void 0;
644
+ const parsedRecord = isRecord$4(parsed) ? parsed : void 0;
645
+ const errorRecord = isRecord$4(parsedRecord?.error) ? parsedRecord.error : void 0;
646
+ const message = nonEmptyString(errorRecord?.message) ?? (rawBody.trim() ? rawBody : void 0) ?? (response.statusText.trim() ? response.statusText : void 0) ?? "Audio speech provider request failed";
647
+ const code = nonEmptyString(errorRecord?.code);
648
+ return new GenerationProviderError(message, {
649
+ status: response.status,
650
+ body: rawBody,
651
+ details: {
652
+ requestId,
653
+ code,
654
+ ...parsedRecord ? { error: parsedRecord } : {}
655
+ }
656
+ });
657
+ }
658
+ function unsupportedSuccessResponse(response, rawBody) {
659
+ const statusText = response.statusText.trim();
660
+ return new GenerationProviderError(response.status === 204 && statusText ? statusText : "Audio speech provider returned an unsupported success response", {
661
+ status: response.status,
662
+ body: rawBody,
663
+ details: { requestId: requestIdFromHeaders(response.headers) }
664
+ });
665
+ }
666
+ function parseSuccessResponse(response, rawBody) {
667
+ const parsed = parseJson(rawBody);
668
+ if (!isRecord$4(parsed)) throw unsupportedSuccessResponse(response, rawBody);
669
+ const urlValue = nonEmptyString(parsed.url);
670
+ const contentType = nonEmptyString(parsed.content_type);
671
+ if (!urlValue || parsed.media_type !== "audio" || !contentType || !/^audio\/[^\s/;]+(?:\s*;.*)?$/i.test(contentType)) throw unsupportedSuccessResponse(response, rawBody);
672
+ try {
673
+ const url = new URL(urlValue.trim());
674
+ if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error("unsupported protocol");
675
+ } catch {
676
+ throw unsupportedSuccessResponse(response, rawBody);
677
+ }
678
+ const size = parsed.size;
679
+ if (size !== void 0 && (typeof size !== "number" || !Number.isFinite(size) || !Number.isInteger(size) || size < 0)) throw unsupportedSuccessResponse(response, rawBody);
680
+ const requestId = requestIdFromHeaders(response.headers);
681
+ return {
682
+ type: "audio",
683
+ source: {
684
+ type: "url",
685
+ url: urlValue.trim()
686
+ },
687
+ meta: {
688
+ content_type: contentType,
689
+ ...size !== void 0 ? { size } : {},
690
+ ...requestId ? { request_id: requestId } : {}
691
+ }
692
+ };
693
+ }
694
+ async function generateAudioSpeech(input) {
695
+ const response = await fetchWithTimeout(input.context.fetch, joinUrl(input.context.baseUrl, "/v1/audio/speech"), {
696
+ method: "POST",
697
+ headers: {
698
+ Authorization: `Bearer ${input.context.apiKey}`,
699
+ "Content-Type": "application/json"
700
+ },
701
+ body: JSON.stringify(buildPayload$2(input))
702
+ }, REQUEST_TIMEOUT_MS$5);
703
+ const rawBody = await response.text().catch(() => "");
704
+ if (!response.ok) throw providerError(response, rawBody);
705
+ return [parseSuccessResponse(response, rawBody)];
706
+ }
707
+ const audioSpeechAdapter = Object.assign(generateAudioSpeech, { validate: validateAudioSpeechRequest });
708
+
513
709
  //#endregion
514
710
  //#region src/adapters/gemini-generate-content.ts
515
711
  const REQUEST_TIMEOUT_MS$4 = 3e5;
@@ -1391,14 +1587,18 @@ async function sunoTasksAdapter(input) {
1391
1587
  //#region src/adapters/index.ts
1392
1588
  const builtinGenerationAdapters = {
1393
1589
  "ark.videoGenerations": arkVideoGenerationsAdapter,
1590
+ "openai.audioSpeech": audioSpeechAdapter,
1394
1591
  "gemini.generateContent": geminiGenerateContentAdapter,
1395
1592
  "kling.videoGenerations": klingVideoGenerationsAdapter,
1396
1593
  "openai.imageEdits": openAiImageEditsAdapter,
1397
1594
  "openai.images": openAiImagesAdapter,
1398
1595
  "suno.tasks": sunoTasksAdapter
1399
1596
  };
1597
+ function tryGetGenerationAdapter(type, adapters = {}) {
1598
+ return adapters[type] ?? builtinGenerationAdapters[type];
1599
+ }
1400
1600
  function getGenerationAdapter(type, adapters = {}) {
1401
- const adapter = adapters[type] ?? builtinGenerationAdapters[type];
1601
+ const adapter = tryGetGenerationAdapter(type, adapters);
1402
1602
  if (!adapter) throw new GenerationUnsupportedAdapterError(type);
1403
1603
  return adapter;
1404
1604
  }
@@ -1499,6 +1699,14 @@ function stringValue(value) {
1499
1699
  function isRecord(value) {
1500
1700
  return !!value && typeof value === "object" && !Array.isArray(value);
1501
1701
  }
1702
+ function extractGenerationResultHeaderFields(headers) {
1703
+ const requestId = headers.get("x-request-id")?.trim() || void 0;
1704
+ const oneApiRequestId = headers.get("x-oneapi-request-id")?.trim() || void 0;
1705
+ return requestId || oneApiRequestId ? {
1706
+ ...requestId ? { requestId } : {},
1707
+ ...oneApiRequestId ? { oneApiRequestId } : {}
1708
+ } : void 0;
1709
+ }
1502
1710
  function extractGenerationResultFields(raw) {
1503
1711
  if (!isRecord(raw)) return void 0;
1504
1712
  const usage = isRecord(raw.usage) ? raw.usage : void 0;
@@ -1594,11 +1802,13 @@ function resolveModels(options) {
1594
1802
  function createResultFieldCaptureFetch(fetchFn, onFields) {
1595
1803
  return (async (input, init) => {
1596
1804
  const response = await fetchFn(input, init);
1805
+ const headerFields = extractGenerationResultHeaderFields(response.headers);
1597
1806
  const contentType = response.headers.get("content-type") ?? "";
1807
+ let fields;
1598
1808
  if (contentType.includes("application/json") || contentType.includes("+json")) try {
1599
- const fields = extractGenerationResultFields(await response.clone().json());
1600
- if (fields) onFields(fields);
1809
+ fields = extractGenerationResultFields(await response.clone().json());
1601
1810
  } catch {}
1811
+ if (fields || headerFields) onFields(fields, headerFields);
1602
1812
  return response;
1603
1813
  });
1604
1814
  }
@@ -1622,12 +1832,17 @@ function createGenerationClient(options = {}) {
1622
1832
  ...request.metadata ?? {},
1623
1833
  ...request.meta ?? {}
1624
1834
  }, request.content), request.content);
1625
- return {
1835
+ const resolved = {
1626
1836
  declaration: cloneJson(declaration),
1627
- request: cloneJson(request),
1837
+ request,
1628
1838
  parameters,
1629
1839
  meta
1630
1840
  };
1841
+ tryGetGenerationAdapter(declaration.adapter.type, options.adapters)?.validate?.(resolved);
1842
+ return {
1843
+ ...resolved,
1844
+ request: cloneJson(request)
1845
+ };
1631
1846
  }
1632
1847
  async function runAdapter(request, fetch) {
1633
1848
  const resolved = validateRequest(request);
@@ -1652,12 +1867,23 @@ function createGenerationClient(options = {}) {
1652
1867
  },
1653
1868
  async generateResult(request) {
1654
1869
  let capturedFields;
1870
+ let capturedBodyRequestId;
1871
+ let capturedRequestId;
1872
+ let capturedOneApiRequestId;
1655
1873
  return {
1656
- content: await runAdapter(request, createResultFieldCaptureFetch(adapterFetch, (fields) => {
1657
- capturedFields = {
1874
+ content: await runAdapter(request, createResultFieldCaptureFetch(adapterFetch, (fields, headerFields) => {
1875
+ if (fields) capturedFields = {
1658
1876
  ...capturedFields,
1659
1877
  ...fields
1660
1878
  };
1879
+ if (fields?.requestId) capturedBodyRequestId = fields.requestId;
1880
+ if (headerFields?.requestId) capturedRequestId = headerFields.requestId;
1881
+ if (headerFields?.oneApiRequestId) capturedOneApiRequestId = headerFields.oneApiRequestId;
1882
+ const requestId = capturedBodyRequestId ?? capturedRequestId ?? capturedOneApiRequestId;
1883
+ if (requestId) capturedFields = {
1884
+ ...capturedFields,
1885
+ requestId
1886
+ };
1661
1887
  })),
1662
1888
  ...capturedFields ?? {}
1663
1889
  };
@@ -1717,5 +1943,5 @@ async function exportBuiltinModelConfigs(directory) {
1717
1943
  }
1718
1944
 
1719
1945
  //#endregion
1720
- export { validateGenerationContent as A, klingVideoGenerationsAdapter as C, mergeTextBlocks as D, mergeGenerationMeta as E, GenerationUnsupportedAdapterError as F, GenerationValidationError as I, GenerationError as M, GenerationProviderError as N, resolveGenerationMeta as O, GenerationTimeoutError as P, openAiImageEditsAdapter as S, arkVideoGenerationsAdapter 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, GenerationConfigError as j, resolveGenerationParameters 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, geminiGenerateContentAdapter as w, openAiImagesAdapter as x, getGenerationAdapter as y };
1721
- //# sourceMappingURL=export-config-CIZi8HJ8.js.map
1946
+ export { resolveGenerationParameters as A, klingVideoGenerationsAdapter as C, mergeGenerationMeta as D, arkVideoGenerationsAdapter as E, GenerationTimeoutError as F, GenerationUnsupportedAdapterError as I, GenerationValidationError as L, GenerationConfigError as M, GenerationError as N, mergeTextBlocks as O, GenerationProviderError as P, openAiImageEditsAdapter as S, audioSpeechAdapter 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, validateGenerationContent as j, resolveGenerationMeta 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, geminiGenerateContentAdapter as w, openAiImagesAdapter as x, getGenerationAdapter as y };
1947
+ //# sourceMappingURL=export-config-DJdXXiMl.js.map