@shop-os/modelkit 0.8.0 → 0.9.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.
- package/CHANGELOG.md +20 -0
- package/README.md +7 -1
- package/dist/catalog.cjs +450 -13
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +110 -5
- package/dist/catalog.d.ts +110 -5
- package/dist/catalog.js +450 -13
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +954 -182
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +110 -4
- package/dist/index.d.ts +110 -4
- package/dist/index.js +951 -182
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/catalog.js
CHANGED
|
@@ -1219,6 +1219,303 @@ var VEED_SUBTITLES = {
|
|
|
1219
1219
|
}
|
|
1220
1220
|
};
|
|
1221
1221
|
|
|
1222
|
+
// src/catalog/voices-fish.ts
|
|
1223
|
+
var FISH_VOICES = [
|
|
1224
|
+
{
|
|
1225
|
+
id: "933563129e564b19a115bedd57b7406a",
|
|
1226
|
+
name: "Sarah",
|
|
1227
|
+
gender: "female",
|
|
1228
|
+
languages: ["en"],
|
|
1229
|
+
description: "An engaged speaker.",
|
|
1230
|
+
previewUrl: "https://platform.r2.fish.audio/task/4e204945670c460c86fdab57512cb308.mp3"
|
|
1231
|
+
},
|
|
1232
|
+
{
|
|
1233
|
+
id: "bf322df2096a46f18c579d0baa36f41d",
|
|
1234
|
+
name: "Adrian",
|
|
1235
|
+
gender: "male",
|
|
1236
|
+
languages: ["en"],
|
|
1237
|
+
description: "A steady and reliable narrator.",
|
|
1238
|
+
previewUrl: "https://platform.r2.fish.audio/task/d730b09f4a484316a77ecc86137e85fb.mp3"
|
|
1239
|
+
},
|
|
1240
|
+
{
|
|
1241
|
+
id: "536d3a5e000945adb7038665781a4aca",
|
|
1242
|
+
name: "Ethan",
|
|
1243
|
+
gender: "male",
|
|
1244
|
+
languages: ["en"],
|
|
1245
|
+
description: "A curious explainer.",
|
|
1246
|
+
previewUrl: "https://platform.r2.fish.audio/task/bdd677ed767744fc91f166468786264b.mp3"
|
|
1247
|
+
},
|
|
1248
|
+
{
|
|
1249
|
+
id: "b347db033a6549378b48d00acb0d06cd",
|
|
1250
|
+
name: "Selene",
|
|
1251
|
+
gender: "female",
|
|
1252
|
+
languages: ["en"],
|
|
1253
|
+
description: "A meditative female voice.",
|
|
1254
|
+
previewUrl: "https://platform.r2.fish.audio/task/fcf629b4a0b343558f461338ba1b9da4.mp3"
|
|
1255
|
+
},
|
|
1256
|
+
{
|
|
1257
|
+
id: "9a9cf47702da476aa4629e2506d4a857",
|
|
1258
|
+
name: "Hannah",
|
|
1259
|
+
gender: "female",
|
|
1260
|
+
languages: ["en"],
|
|
1261
|
+
description: "A conversation specialist.",
|
|
1262
|
+
previewUrl: "https://platform.r2.fish.audio/task/08d658835feb427db808e37060b78eb0.mp3"
|
|
1263
|
+
},
|
|
1264
|
+
{
|
|
1265
|
+
id: "79d0bd3e4e5444b18f7b6d89b5927bf1",
|
|
1266
|
+
name: "Jordan",
|
|
1267
|
+
gender: "male",
|
|
1268
|
+
languages: ["en"],
|
|
1269
|
+
description: "A motivational speaker.",
|
|
1270
|
+
previewUrl: "https://platform.r2.fish.audio/task/edecbc0bdd4c46c39eda8520a0f729ef.mp3"
|
|
1271
|
+
},
|
|
1272
|
+
{
|
|
1273
|
+
id: "e3cd384158934cc9a01029cd7d278634",
|
|
1274
|
+
name: "Laura",
|
|
1275
|
+
gender: "female",
|
|
1276
|
+
languages: ["en"],
|
|
1277
|
+
description: "A confident female narrator.",
|
|
1278
|
+
previewUrl: "https://platform.r2.fish.audio/task/e821bef995344d519caa1c93d808db23.mp3"
|
|
1279
|
+
},
|
|
1280
|
+
{
|
|
1281
|
+
id: "f3a2b90078d54a65af4b95f63bc7798e",
|
|
1282
|
+
name: "Sheila",
|
|
1283
|
+
gender: "female",
|
|
1284
|
+
accent: "american",
|
|
1285
|
+
languages: ["en"],
|
|
1286
|
+
description: "A young American English woman's voice.",
|
|
1287
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-24/9bb9e1a1cf3f47f38700da1c5c0a678a.mp3"
|
|
1288
|
+
},
|
|
1289
|
+
{
|
|
1290
|
+
id: "0db6e93af420470b9d9b9a886dbaa954",
|
|
1291
|
+
name: "Kai",
|
|
1292
|
+
gender: "male",
|
|
1293
|
+
languages: ["en"],
|
|
1294
|
+
description: "A friendly English man's voice for companion apps and everyday conversation.",
|
|
1295
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-24/13306f1172544c3ba3106d1e363feaa6.mp3"
|
|
1296
|
+
},
|
|
1297
|
+
{
|
|
1298
|
+
id: "8abfa9ebd4c24a3399b68c3cdac8c7b5",
|
|
1299
|
+
name: "Freya",
|
|
1300
|
+
gender: "female",
|
|
1301
|
+
accent: "british",
|
|
1302
|
+
languages: ["en"],
|
|
1303
|
+
description: "A natural, professional British English voice with a brisk, conversational pace. Clear and easy to follow, suited to voice assistants, customer support and everyday narration.",
|
|
1304
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-25/07918705a56b42daaab149f65392cea7.mp3"
|
|
1305
|
+
},
|
|
1306
|
+
{
|
|
1307
|
+
id: "2f64e528a4f2406691925ab1e0ed5b7f",
|
|
1308
|
+
name: "Ananya",
|
|
1309
|
+
gender: "female",
|
|
1310
|
+
languages: ["hi"],
|
|
1311
|
+
description: "\u0938\u093E\u092B\u093C \u0914\u0930 \u0906\u0924\u094D\u092E\u0935\u093F\u0936\u094D\u0935\u093E\u0938 \u092D\u0930\u0940 \u0906\u0935\u093E\u091C\u093C, \u091C\u094B \u0935\u0949\u0907\u0938 \u0905\u0938\u093F\u0938\u094D\u091F\u0947\u0902\u091F, \u0917\u094D\u0930\u093E\u0939\u0915 \u0938\u0947\u0935\u093E \u0914\u0930 \u092A\u094D\u0930\u0938\u094D\u0924\u0941\u0924\u093F\u092F\u094B\u0902 \u0915\u0947 \u0932\u093F\u090F \u0909\u092A\u092F\u0941\u0915\u094D\u0924 \u0939\u0948\u0964",
|
|
1312
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-25/a17a700668d8405f8316db120733145c.mp3"
|
|
1313
|
+
},
|
|
1314
|
+
{
|
|
1315
|
+
id: "cefd91a07b99468f9148e2580990082d",
|
|
1316
|
+
name: "Arjun",
|
|
1317
|
+
gender: "male",
|
|
1318
|
+
languages: ["hi"],
|
|
1319
|
+
description: "\u0938\u093E\u092B\u093C \u0914\u0930 \u0906\u0924\u094D\u092E\u0935\u093F\u0936\u094D\u0935\u093E\u0938 \u092D\u0930\u0940 \u0906\u0935\u093E\u091C\u093C, \u091C\u094B \u0935\u0949\u0907\u0938 \u0905\u0938\u093F\u0938\u094D\u091F\u0947\u0902\u091F, \u0917\u094D\u0930\u093E\u0939\u0915 \u0938\u0947\u0935\u093E \u0914\u0930 \u092A\u094D\u0930\u0938\u094D\u0924\u0941\u0924\u093F\u092F\u094B\u0902 \u0915\u0947 \u0932\u093F\u090F \u0909\u092A\u092F\u0941\u0915\u094D\u0924 \u0939\u0948\u0964",
|
|
1320
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-24/a0c4a8eadb7841cdae8e5e68031a2dfb.mp3"
|
|
1321
|
+
},
|
|
1322
|
+
{
|
|
1323
|
+
id: "3f065d660212478a9c697fa965b4d098",
|
|
1324
|
+
name: "Carmen",
|
|
1325
|
+
gender: "female",
|
|
1326
|
+
languages: ["es"],
|
|
1327
|
+
description: "Una voz clara y segura para asistentes de voz, atenci\xF3n al cliente y presentaciones.",
|
|
1328
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-25/3421be48b6cb4c28bf829c25188e7e74.mp3"
|
|
1329
|
+
},
|
|
1330
|
+
{
|
|
1331
|
+
id: "ec0718028a2445fb9be8e8bfb56a0150",
|
|
1332
|
+
name: "Rodrigo",
|
|
1333
|
+
gender: "male",
|
|
1334
|
+
languages: ["es"],
|
|
1335
|
+
description: "Una voz clara y segura para asistentes de voz, atenci\xF3n al cliente y presentaciones.",
|
|
1336
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-25/5a77c32365604800ad5b4eb13c5585df.mp3"
|
|
1337
|
+
},
|
|
1338
|
+
{
|
|
1339
|
+
id: "10a3a20742114a4ea6dd441e7591850f",
|
|
1340
|
+
name: "Manon",
|
|
1341
|
+
gender: "female",
|
|
1342
|
+
languages: ["fr"],
|
|
1343
|
+
description: "Une voix claire et vive, adapt\xE9e aux assistants vocaux et au support client.",
|
|
1344
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-25/f7b75ee1fa524e48a8cefb003cf72952.mp3"
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
id: "f69bca092b674168a8d02d61ca20943c",
|
|
1348
|
+
name: "Lucas",
|
|
1349
|
+
gender: "male",
|
|
1350
|
+
languages: ["fr"],
|
|
1351
|
+
description: "Une voix claire et assur\xE9e, adapt\xE9e aux assistants vocaux et au service client.",
|
|
1352
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-25/86fca3e56a014a3d8a11450854bb8311.mp3"
|
|
1353
|
+
},
|
|
1354
|
+
{
|
|
1355
|
+
id: "3937b44b604249f18b94913daef94043",
|
|
1356
|
+
name: "Lena",
|
|
1357
|
+
gender: "female",
|
|
1358
|
+
languages: ["de"],
|
|
1359
|
+
description: "Eine klare, souver\xE4ne Stimme f\xFCr Sprachassistenten, Kundenservice und Pr\xE4sentationen.",
|
|
1360
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-25/8659fec80b74442dab68a7755716a401.mp3"
|
|
1361
|
+
},
|
|
1362
|
+
{
|
|
1363
|
+
id: "c1e7cc926aa5469aa966c353094d4b0b",
|
|
1364
|
+
name: "Lukas",
|
|
1365
|
+
gender: "male",
|
|
1366
|
+
languages: ["de"],
|
|
1367
|
+
description: "Eine klare, souver\xE4ne Stimme f\xFCr Sprachassistenten, Kundenservice und Pr\xE4sentationen.",
|
|
1368
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-25/fb1d538126bb4fe38f8366250f6a2136.mp3"
|
|
1369
|
+
},
|
|
1370
|
+
{
|
|
1371
|
+
id: "b3c060cc41544a7da94a2c487647c902",
|
|
1372
|
+
name: "Let\xEDcia",
|
|
1373
|
+
gender: "female",
|
|
1374
|
+
accent: "brazilian",
|
|
1375
|
+
languages: ["pt"],
|
|
1376
|
+
description: "A Brazilian-accented Portuguese woman's voice, in her late twenties. Soft, warm, intimate. A freelance designer from Belo Horizonte who enjoys long walks in the park. Best suited to companion apps and casual everyday conversation.",
|
|
1377
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-10-12/13c6c0d96b5c4069951f89868ee15360.mp3"
|
|
1378
|
+
},
|
|
1379
|
+
{
|
|
1380
|
+
id: "add7bcb8d3c8423bbfa152ca232aad6e",
|
|
1381
|
+
name: "Ricardo",
|
|
1382
|
+
gender: "male",
|
|
1383
|
+
accent: "brazilian",
|
|
1384
|
+
languages: ["pt"],
|
|
1385
|
+
description: "A Brazilian-accented Portuguese man's voice, in his late forties. Clear, professional, monotone. A high school history teacher from Curitiba who loves classical music. Best suited to lessons, tutoring and explainer content.",
|
|
1386
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-10-12/67475fc717ae45cbb38e647a2dd37fe1.mp3"
|
|
1387
|
+
},
|
|
1388
|
+
{
|
|
1389
|
+
id: "b2d9d8db057042688a5e318b8f405bc2",
|
|
1390
|
+
name: "Kyoko",
|
|
1391
|
+
gender: "female",
|
|
1392
|
+
languages: ["ja"],
|
|
1393
|
+
description: "\u4E01\u5BE7\u3067\u843D\u3061\u7740\u3044\u305F\u8A71\u3057\u65B9\u304C\u7279\u5FB4\u306E\u5973\u6027\u306E\u58F0\u3002\u304A\u5BA2\u69D8\u5BFE\u5FDC\u3084\u60C5\u5831\u63D0\u4F9B\u306B\u6700\u9069\u3002",
|
|
1394
|
+
previewUrl: "https://platform.r2.fish.audio/task/993b3ccb52124341aff79580f1ce5a5a.mp3"
|
|
1395
|
+
},
|
|
1396
|
+
{
|
|
1397
|
+
id: "297a6fd278df47c3b9da9bfdf55ac89a",
|
|
1398
|
+
name: "Satoru",
|
|
1399
|
+
gender: "male",
|
|
1400
|
+
languages: ["ja"],
|
|
1401
|
+
description: "\u82E5\u3005\u3057\u304F\u3082\u843D\u3061\u7740\u304D\u306E\u3042\u308B\u7537\u6027\u306E\u58F0\u3002\u65E5\u5E38\u306E\u8A9E\u308A\u3084\u30EA\u30E9\u30C3\u30AF\u30B9\u3057\u305F\u30CA\u30EC\u30FC\u30B7\u30E7\u30F3\u306B\u6700\u9069\u3002",
|
|
1402
|
+
previewUrl: "https://platform.r2.fish.audio/task/1b4712fb831f4c149eef6b0133157418.mp3"
|
|
1403
|
+
},
|
|
1404
|
+
{
|
|
1405
|
+
id: "0b14f34a13a94ed88fe6113193749bb0",
|
|
1406
|
+
name: "Fatima",
|
|
1407
|
+
gender: "female",
|
|
1408
|
+
languages: ["ar"],
|
|
1409
|
+
description: "\u0635\u0648\u062A \u0648\u0627\u0636\u062D \u0648\u0648\u0627\u062B\u0642 \u064A\u0646\u0627\u0633\u0628 \u0627\u0644\u0645\u0633\u0627\u0639\u062F\u0627\u062A \u0627\u0644\u0635\u0648\u062A\u064A\u0629 \u0648\u062E\u062F\u0645\u0629 \u0627\u0644\u0639\u0645\u0644\u0627\u0621 \u0648\u0627\u0644\u0639\u0631\u0648\u0636 \u0627\u0644\u062A\u0642\u062F\u064A\u0645\u064A\u0629.",
|
|
1410
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-24/93406e1b905a4c4994306e3421243390.mp3"
|
|
1411
|
+
},
|
|
1412
|
+
{
|
|
1413
|
+
id: "74c6aba5cbf94a15bbdc547ffce5cb38",
|
|
1414
|
+
name: "Yutong",
|
|
1415
|
+
gender: "female",
|
|
1416
|
+
languages: ["zh"],
|
|
1417
|
+
description: "\u58F0\u97F3\u6E05\u6670\u81EA\u7136\uFF0C\u8868\u8FBE\u5229\u843D\uFF0C\u9002\u5408\u8BED\u97F3\u52A9\u624B\u3001\u5BA2\u670D\u548C\u65E5\u5E38\u64AD\u62A5\u3002",
|
|
1418
|
+
previewUrl: "https://platform.r2.fish.audio/tasks/2026-08-25/a48320f37fe44c4699549a1afc3778e8.mp3"
|
|
1419
|
+
}
|
|
1420
|
+
];
|
|
1421
|
+
|
|
1422
|
+
// src/catalog/speech-fish.ts
|
|
1423
|
+
var FISH_LOGO = "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/fishaudio.png";
|
|
1424
|
+
var PER_CALL = { unit: "images" };
|
|
1425
|
+
var PER_REQUEST = { unit: "requests" };
|
|
1426
|
+
var TTS_MAX_CHARS = 1e4;
|
|
1427
|
+
function fishTts(id, label, providerModelId, description) {
|
|
1428
|
+
return {
|
|
1429
|
+
id,
|
|
1430
|
+
aliases: [],
|
|
1431
|
+
label,
|
|
1432
|
+
type: "speech",
|
|
1433
|
+
adapter: "fish",
|
|
1434
|
+
providerModelId,
|
|
1435
|
+
lifecycle: "active",
|
|
1436
|
+
exposure: [],
|
|
1437
|
+
constraints: {
|
|
1438
|
+
voices: FISH_VOICES,
|
|
1439
|
+
outputFormats: ["mp3", "wav"],
|
|
1440
|
+
supports: [],
|
|
1441
|
+
prompt: { referenceSyntax: "numbered", maxChars: TTS_MAX_CHARS }
|
|
1442
|
+
},
|
|
1443
|
+
defaults: { voice: "9a9cf47702da476aa4629e2506d4a857", outputFormat: "mp3" },
|
|
1444
|
+
usage: PER_CALL,
|
|
1445
|
+
pricingKind: "flat",
|
|
1446
|
+
display: { provider: "fishaudio", logo: FISH_LOGO, description },
|
|
1447
|
+
capabilities: { customVoices: true }
|
|
1448
|
+
};
|
|
1449
|
+
}
|
|
1450
|
+
var FISH_MODELS = [
|
|
1451
|
+
fishTts(
|
|
1452
|
+
"fish-s2.1-pro",
|
|
1453
|
+
"Fish Audio S2.1 Pro",
|
|
1454
|
+
"s2.1-pro",
|
|
1455
|
+
"Fish Audio S2.1 Pro text to speech in 83 languages, with [bracket] directions and your own cloned voices."
|
|
1456
|
+
),
|
|
1457
|
+
fishTts(
|
|
1458
|
+
"fish-s2.1-pro-free",
|
|
1459
|
+
"Fish Audio S2.1 Pro Free",
|
|
1460
|
+
"s2.1-pro-free",
|
|
1461
|
+
"Fish Audio S2.1 Pro on the free developer tier: the same voices at no cost, without latency or data-processing guarantees."
|
|
1462
|
+
),
|
|
1463
|
+
fishTts(
|
|
1464
|
+
"fish-drama-3",
|
|
1465
|
+
"Fish Audio Drama 3",
|
|
1466
|
+
"drama-3",
|
|
1467
|
+
"Fish Audio Drama 3 text to speech you direct like an actor: [directions], sounds, pauses and per-word tags."
|
|
1468
|
+
),
|
|
1469
|
+
{
|
|
1470
|
+
id: "fish-voice-clone",
|
|
1471
|
+
aliases: [],
|
|
1472
|
+
label: "Fish Audio Voice Clone",
|
|
1473
|
+
type: "voice-clone",
|
|
1474
|
+
adapter: "fish",
|
|
1475
|
+
providerModelId: "voice-clone",
|
|
1476
|
+
lifecycle: "active",
|
|
1477
|
+
exposure: [],
|
|
1478
|
+
constraints: {
|
|
1479
|
+
// POST /model takes 1-20 voice files; Fish advises 10 s or more of clean speech each.
|
|
1480
|
+
references: { audios: 20, audioFormats: ["wav", "mp3", "m4a", "opus"] },
|
|
1481
|
+
supports: []
|
|
1482
|
+
},
|
|
1483
|
+
defaults: {},
|
|
1484
|
+
usage: PER_REQUEST,
|
|
1485
|
+
pricingKind: "flat",
|
|
1486
|
+
display: {
|
|
1487
|
+
provider: "fishaudio",
|
|
1488
|
+
logo: FISH_LOGO,
|
|
1489
|
+
description: "Clone a private, reusable voice from one or more clean recordings, then speak with it on the Fish Audio speech models."
|
|
1490
|
+
},
|
|
1491
|
+
capabilities: {}
|
|
1492
|
+
},
|
|
1493
|
+
{
|
|
1494
|
+
id: "fish-voice-design-1",
|
|
1495
|
+
aliases: [],
|
|
1496
|
+
label: "Fish Audio Voice Design",
|
|
1497
|
+
type: "voice-design",
|
|
1498
|
+
adapter: "fish",
|
|
1499
|
+
providerModelId: "voice-design-1",
|
|
1500
|
+
lifecycle: "active",
|
|
1501
|
+
exposure: [],
|
|
1502
|
+
constraints: {
|
|
1503
|
+
voiceDesign: { maxCandidates: 4, previewMaxChars: 150 },
|
|
1504
|
+
supports: [],
|
|
1505
|
+
prompt: { referenceSyntax: "numbered", maxChars: 2e3 }
|
|
1506
|
+
},
|
|
1507
|
+
defaults: {},
|
|
1508
|
+
usage: PER_REQUEST,
|
|
1509
|
+
pricingKind: "flat",
|
|
1510
|
+
display: {
|
|
1511
|
+
provider: "fishaudio",
|
|
1512
|
+
logo: FISH_LOGO,
|
|
1513
|
+
description: "Describe a voice and get up to four short candidates; keep one as a cloned voice."
|
|
1514
|
+
},
|
|
1515
|
+
capabilities: {}
|
|
1516
|
+
}
|
|
1517
|
+
];
|
|
1518
|
+
|
|
1222
1519
|
// src/catalog/languages-audio.ts
|
|
1223
1520
|
var ELEVENLABS_V4_LANGUAGES = [
|
|
1224
1521
|
{ code: "af", name: "Afrikaans" },
|
|
@@ -3300,7 +3597,7 @@ var ELEVENLABS_LOGO = "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.
|
|
|
3300
3597
|
var GOOGLE_LOGO = "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/192485d2-a76a-4657-9c06-930b2c70badd_compressed.png";
|
|
3301
3598
|
var MINIMAX_LOGO = "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/f4c2e906-28b7-4a4a-b491-df8fef7808ed.png";
|
|
3302
3599
|
var SYNC_LOGO = "https://cdn.jsdelivr.net/npm/@lobehub/icons-static-png@1.97.0/light/sync.png";
|
|
3303
|
-
var
|
|
3600
|
+
var PER_CALL2 = { unit: "images" };
|
|
3304
3601
|
var EXPOSURE4 = ["cowork", "space_builder"];
|
|
3305
3602
|
var LIPSYNC_AUDIO = { audioSeconds: { max: 30 } };
|
|
3306
3603
|
function elevenLabsTts(tts) {
|
|
@@ -3321,7 +3618,7 @@ function elevenLabsTts(tts) {
|
|
|
3321
3618
|
prompt: { referenceSyntax: "numbered", maxChars: tts.maxChars }
|
|
3322
3619
|
},
|
|
3323
3620
|
defaults: { voice: "Rachel", ...tts.formats && { outputFormat: "mp3_44100_128" } },
|
|
3324
|
-
usage:
|
|
3621
|
+
usage: PER_CALL2,
|
|
3325
3622
|
pricingKind: "flat",
|
|
3326
3623
|
display: { provider: "elevenlabs", logo: ELEVENLABS_LOGO, description: tts.description },
|
|
3327
3624
|
capabilities: {}
|
|
@@ -3345,7 +3642,7 @@ function geminiTts(id, label, description) {
|
|
|
3345
3642
|
prompt: { referenceSyntax: "numbered", maxChars: 8192 }
|
|
3346
3643
|
},
|
|
3347
3644
|
defaults: { voice: "Kore" },
|
|
3348
|
-
usage:
|
|
3645
|
+
usage: PER_CALL2,
|
|
3349
3646
|
pricingKind: "flat",
|
|
3350
3647
|
display: { provider: "google", logo: GOOGLE_LOGO, description },
|
|
3351
3648
|
capabilities: {}
|
|
@@ -3368,7 +3665,7 @@ function syncLipsync(id, label, providerModelId, syncModel, description) {
|
|
|
3368
3665
|
},
|
|
3369
3666
|
defaults: {},
|
|
3370
3667
|
...syncModel !== void 0 && { providerOptions: { fal: { model: syncModel } } },
|
|
3371
|
-
usage:
|
|
3668
|
+
usage: PER_CALL2,
|
|
3372
3669
|
pricingKind: "flat",
|
|
3373
3670
|
display: { provider: "sync", logo: SYNC_LOGO, description },
|
|
3374
3671
|
capabilities: { acceptsSourceVideo: true }
|
|
@@ -3429,7 +3726,7 @@ var MEDIA_NODE_MODELS = [
|
|
|
3429
3726
|
prompt: { referenceSyntax: "numbered", maxChars: 1e4 }
|
|
3430
3727
|
},
|
|
3431
3728
|
defaults: { voice: "Wise_Woman" },
|
|
3432
|
-
usage:
|
|
3729
|
+
usage: PER_CALL2,
|
|
3433
3730
|
pricingKind: "flat",
|
|
3434
3731
|
display: {
|
|
3435
3732
|
provider: "minimax",
|
|
@@ -3456,7 +3753,7 @@ var MEDIA_NODE_MODELS = [
|
|
|
3456
3753
|
supports: []
|
|
3457
3754
|
},
|
|
3458
3755
|
defaults: { voice: "Rachel", outputFormat: "mp3_44100_128" },
|
|
3459
|
-
usage:
|
|
3756
|
+
usage: PER_CALL2,
|
|
3460
3757
|
pricingKind: "flat",
|
|
3461
3758
|
display: {
|
|
3462
3759
|
provider: "elevenlabs",
|
|
@@ -3483,7 +3780,7 @@ var MEDIA_NODE_MODELS = [
|
|
|
3483
3780
|
supports: []
|
|
3484
3781
|
},
|
|
3485
3782
|
defaults: {},
|
|
3486
|
-
usage:
|
|
3783
|
+
usage: PER_CALL2,
|
|
3487
3784
|
pricingKind: "flat",
|
|
3488
3785
|
display: {
|
|
3489
3786
|
provider: "elevenlabs",
|
|
@@ -3530,7 +3827,7 @@ var MEDIA_NODE_MODELS = [
|
|
|
3530
3827
|
supports: []
|
|
3531
3828
|
},
|
|
3532
3829
|
defaults: {},
|
|
3533
|
-
usage:
|
|
3830
|
+
usage: PER_CALL2,
|
|
3534
3831
|
pricingKind: "flat",
|
|
3535
3832
|
display: {
|
|
3536
3833
|
provider: "veed",
|
|
@@ -3582,7 +3879,7 @@ var MEDIA_NODE_MODELS = [
|
|
|
3582
3879
|
supports: []
|
|
3583
3880
|
},
|
|
3584
3881
|
defaults: {},
|
|
3585
|
-
usage:
|
|
3882
|
+
usage: PER_CALL2,
|
|
3586
3883
|
pricingKind: "flat",
|
|
3587
3884
|
display: {
|
|
3588
3885
|
provider: "elevenlabs",
|
|
@@ -3591,7 +3888,8 @@ var MEDIA_NODE_MODELS = [
|
|
|
3591
3888
|
},
|
|
3592
3889
|
capabilities: {}
|
|
3593
3890
|
},
|
|
3594
|
-
SAM_3_IMAGE
|
|
3891
|
+
SAM_3_IMAGE,
|
|
3892
|
+
...FISH_MODELS
|
|
3595
3893
|
];
|
|
3596
3894
|
|
|
3597
3895
|
// src/catalog/model3d.ts
|
|
@@ -7232,7 +7530,8 @@ var ADAPTER_IDS = [
|
|
|
7232
7530
|
"prodia",
|
|
7233
7531
|
"higgsfield",
|
|
7234
7532
|
"xai-video",
|
|
7235
|
-
"luma"
|
|
7533
|
+
"luma",
|
|
7534
|
+
"fish"
|
|
7236
7535
|
];
|
|
7237
7536
|
var ModelTypeSchema = z3.enum([
|
|
7238
7537
|
"text",
|
|
@@ -7249,6 +7548,8 @@ var ModelTypeSchema = z3.enum([
|
|
|
7249
7548
|
"dubbing",
|
|
7250
7549
|
"lipsync",
|
|
7251
7550
|
"transcription",
|
|
7551
|
+
"voice-clone",
|
|
7552
|
+
"voice-design",
|
|
7252
7553
|
"model3d"
|
|
7253
7554
|
]);
|
|
7254
7555
|
var LifecycleSchema = z3.enum(["active", "deprecated", "retired"]);
|
|
@@ -7424,6 +7725,10 @@ var ModelConstraintsSchema = z3.looseObject({
|
|
|
7424
7725
|
supports: z3.array(SupportedOptionSchema).optional(),
|
|
7425
7726
|
ratioIgnoredWith: z3.array(z3.enum(["firstFrame", "sourceVideo"])).optional(),
|
|
7426
7727
|
voices: z3.array(VoiceOptionSchema).optional(),
|
|
7728
|
+
voiceDesign: z3.object({
|
|
7729
|
+
maxCandidates: z3.number().int().positive(),
|
|
7730
|
+
previewMaxChars: z3.number().int().positive()
|
|
7731
|
+
}).optional(),
|
|
7427
7732
|
languages: z3.array(LanguageOptionSchema).optional(),
|
|
7428
7733
|
outputFormats: z3.array(z3.string().min(1)).min(1).optional(),
|
|
7429
7734
|
sourceVideoSeconds: VideoSecondsLimitsSchema.omit({ total: true }).extend({ inReferenceTotal: z3.boolean().optional() }).optional(),
|
|
@@ -7522,6 +7827,7 @@ var CatalogDisplaySchema = z3.looseObject({
|
|
|
7522
7827
|
});
|
|
7523
7828
|
var CatalogCapabilitiesSchema = z3.looseObject({
|
|
7524
7829
|
acceptsSourceVideo: z3.boolean().optional(),
|
|
7830
|
+
customVoices: z3.boolean().optional(),
|
|
7525
7831
|
videoEdit: z3.boolean().optional(),
|
|
7526
7832
|
framesExcludeReferences: z3.boolean().optional(),
|
|
7527
7833
|
sourceVideoExcludesFrames: z3.boolean().optional(),
|
|
@@ -9400,8 +9706,17 @@ function resolveSpeechOptions(model, request, onUnsupported = "error") {
|
|
|
9400
9706
|
const warnings = [];
|
|
9401
9707
|
checkScript(model, request.text);
|
|
9402
9708
|
const resolved = { model: model.id, text: request.text };
|
|
9403
|
-
const
|
|
9404
|
-
if (
|
|
9709
|
+
const customVoice = request.customVoice?.trim();
|
|
9710
|
+
if (customVoice) {
|
|
9711
|
+
if (model.capabilities?.customVoices !== true) {
|
|
9712
|
+
throw unsupported3(model, "does not take a custom voice");
|
|
9713
|
+
}
|
|
9714
|
+
if (request.voice?.trim()) throw unsupported3(model, "takes voice or customVoice, not both");
|
|
9715
|
+
resolved.customVoice = customVoice;
|
|
9716
|
+
} else {
|
|
9717
|
+
const voice = resolveVoice(model, request.voice, onUnsupported, warnings);
|
|
9718
|
+
if (voice !== void 0) resolved.voice = voice;
|
|
9719
|
+
}
|
|
9405
9720
|
const language = resolveListed(
|
|
9406
9721
|
model,
|
|
9407
9722
|
{
|
|
@@ -9523,6 +9838,106 @@ function resolveTranscriptionOptions(model, request, onUnsupported = "error") {
|
|
|
9523
9838
|
return { request: resolved, warnings };
|
|
9524
9839
|
}
|
|
9525
9840
|
|
|
9841
|
+
// src/resolve-voice.ts
|
|
9842
|
+
function refuse(model, code, message) {
|
|
9843
|
+
return new ModelKitError({ code, message: `${model.label} ${message}`, model: model.id });
|
|
9844
|
+
}
|
|
9845
|
+
function checkSample(model, sample, index) {
|
|
9846
|
+
const limits = model.constraints.references?.audioSeconds;
|
|
9847
|
+
const length = sample.audio.durationSeconds;
|
|
9848
|
+
if (limits === void 0 || length === void 0) return;
|
|
9849
|
+
if (limits.min !== void 0 && length < limits.min || limits.max !== void 0 && length > limits.max) {
|
|
9850
|
+
const range2 = `${limits.min ?? 0}-${limits.max ?? "any"} s`;
|
|
9851
|
+
throw refuse(
|
|
9852
|
+
model,
|
|
9853
|
+
"unsupported_option",
|
|
9854
|
+
`takes samples of ${range2}; sample ${index + 1} is ${length} s`
|
|
9855
|
+
);
|
|
9856
|
+
}
|
|
9857
|
+
}
|
|
9858
|
+
function resolveVoiceCloneOptions(model, request) {
|
|
9859
|
+
const title = request.title.trim();
|
|
9860
|
+
if (!title) throw refuse(model, "missing_input", "needs a title");
|
|
9861
|
+
if (request.samples.length === 0) throw refuse(model, "missing_input", "needs a voice sample");
|
|
9862
|
+
const max = model.constraints.references?.audios;
|
|
9863
|
+
if (max !== void 0 && request.samples.length > max) {
|
|
9864
|
+
throw refuse(
|
|
9865
|
+
model,
|
|
9866
|
+
"unsupported_option",
|
|
9867
|
+
`takes up to ${max} samples; got ${request.samples.length}`
|
|
9868
|
+
);
|
|
9869
|
+
}
|
|
9870
|
+
request.samples.forEach((sample, index) => checkSample(model, sample, index));
|
|
9871
|
+
const total = model.constraints.references?.audioSeconds?.total;
|
|
9872
|
+
const seconds3 = request.samples.reduce((sum, s) => sum + (s.audio.durationSeconds ?? 0), 0);
|
|
9873
|
+
if (total !== void 0 && seconds3 > total) {
|
|
9874
|
+
throw refuse(
|
|
9875
|
+
model,
|
|
9876
|
+
"unsupported_option",
|
|
9877
|
+
`takes up to ${total} s of samples; got ${seconds3} s`
|
|
9878
|
+
);
|
|
9879
|
+
}
|
|
9880
|
+
for (const field of ["transcript", "designSignature"]) {
|
|
9881
|
+
const set = request.samples.filter((s) => s[field]?.trim()).length;
|
|
9882
|
+
if (set !== 0 && set !== request.samples.length) {
|
|
9883
|
+
throw refuse(model, "missing_input", `needs ${field} on every sample or on none`);
|
|
9884
|
+
}
|
|
9885
|
+
}
|
|
9886
|
+
return { request: { ...request, model: model.id, title }, warnings: [] };
|
|
9887
|
+
}
|
|
9888
|
+
function resolveVoiceDesignOptions(model, request, onUnsupported = "error") {
|
|
9889
|
+
const warnings = [];
|
|
9890
|
+
const prompt = request.prompt.trim();
|
|
9891
|
+
if (!prompt) throw refuse(model, "missing_input", "needs a voice description");
|
|
9892
|
+
const maxChars = promptConventions(model).maxChars;
|
|
9893
|
+
if (maxChars !== void 0 && prompt.length > maxChars) {
|
|
9894
|
+
throw refuse(
|
|
9895
|
+
model,
|
|
9896
|
+
"unsupported_option",
|
|
9897
|
+
`takes up to ${maxChars} characters; got ${prompt.length}`
|
|
9898
|
+
);
|
|
9899
|
+
}
|
|
9900
|
+
const limits = model.constraints.voiceDesign;
|
|
9901
|
+
const resolved = { model: model.id, prompt };
|
|
9902
|
+
const preview2 = request.previewText?.trim();
|
|
9903
|
+
if (preview2) {
|
|
9904
|
+
if (limits !== void 0 && preview2.length > limits.previewMaxChars) {
|
|
9905
|
+
throw refuse(
|
|
9906
|
+
model,
|
|
9907
|
+
"unsupported_option",
|
|
9908
|
+
`takes a preview line of up to ${limits.previewMaxChars} characters; got ${preview2.length}`
|
|
9909
|
+
);
|
|
9910
|
+
}
|
|
9911
|
+
resolved.previewText = preview2;
|
|
9912
|
+
}
|
|
9913
|
+
const language = request.language?.trim();
|
|
9914
|
+
if (language) resolved.language = language;
|
|
9915
|
+
if (request.seed !== void 0) resolved.seed = request.seed;
|
|
9916
|
+
const count2 = request.count ?? model.defaults.count;
|
|
9917
|
+
if (count2 !== void 0) {
|
|
9918
|
+
const cap = limits?.maxCandidates ?? count2;
|
|
9919
|
+
if (!Number.isInteger(count2) || count2 < 1 || count2 > cap) {
|
|
9920
|
+
if (onUnsupported === "error" || !Number.isInteger(count2)) {
|
|
9921
|
+
throw refuse(
|
|
9922
|
+
model,
|
|
9923
|
+
"unsupported_option",
|
|
9924
|
+
`returns 1-${cap} candidates; got ${count2}`
|
|
9925
|
+
);
|
|
9926
|
+
}
|
|
9927
|
+
const to = Math.min(Math.max(count2, 1), cap);
|
|
9928
|
+
warnings.push({
|
|
9929
|
+
code: "option_ignored",
|
|
9930
|
+
field: "count",
|
|
9931
|
+
from: String(count2),
|
|
9932
|
+
to: String(to),
|
|
9933
|
+
message: `count ${count2} replaced by ${to} for ${model.id}`
|
|
9934
|
+
});
|
|
9935
|
+
resolved.count = to;
|
|
9936
|
+
} else resolved.count = count2;
|
|
9937
|
+
}
|
|
9938
|
+
return { request: resolved, warnings };
|
|
9939
|
+
}
|
|
9940
|
+
|
|
9526
9941
|
// src/resolve-call.ts
|
|
9527
9942
|
var MEDIA_METHODS = {
|
|
9528
9943
|
text: [],
|
|
@@ -9538,6 +9953,9 @@ var MEDIA_METHODS = {
|
|
|
9538
9953
|
lipsync: ["lipsync"],
|
|
9539
9954
|
dubbing: ["dub"],
|
|
9540
9955
|
transcription: ["transcribe"],
|
|
9956
|
+
// deleteVoice runs on the voice-clone row too; it checks with assertMethod("createVoice").
|
|
9957
|
+
"voice-clone": ["createVoice"],
|
|
9958
|
+
"voice-design": ["designVoice"],
|
|
9541
9959
|
"video-tool": ["submitVideoTool"],
|
|
9542
9960
|
// 3D jobs run through submitModel3d, which checks the row type itself; their preflight
|
|
9543
9961
|
// is model3dInputRefusal, not resolveOptions.
|
|
@@ -9552,6 +9970,8 @@ var METHOD_NOUN = {
|
|
|
9552
9970
|
lipsync: "a lipsync model",
|
|
9553
9971
|
dub: "a dubbing model",
|
|
9554
9972
|
transcribe: "a transcription model",
|
|
9973
|
+
createVoice: "a voice cloning model",
|
|
9974
|
+
designVoice: "a voice design model",
|
|
9555
9975
|
submitVideoTool: "a video tool"
|
|
9556
9976
|
};
|
|
9557
9977
|
function assertMethod(model, method) {
|
|
@@ -9594,6 +10014,14 @@ function resolveTranscriptionCall(model, request, onUnsupported = "error") {
|
|
|
9594
10014
|
assertMethod(model, "transcribe");
|
|
9595
10015
|
return resolveTranscriptionOptions(model, request, onUnsupported);
|
|
9596
10016
|
}
|
|
10017
|
+
function resolveVoiceCloneCall(model, request) {
|
|
10018
|
+
assertMethod(model, "createVoice");
|
|
10019
|
+
return resolveVoiceCloneOptions(model, request);
|
|
10020
|
+
}
|
|
10021
|
+
function resolveVoiceDesignCall(model, request, onUnsupported = "error") {
|
|
10022
|
+
assertMethod(model, "designVoice");
|
|
10023
|
+
return resolveVoiceDesignOptions(model, request, onUnsupported);
|
|
10024
|
+
}
|
|
9597
10025
|
function resolveVideoToolCall(model, request) {
|
|
9598
10026
|
assertMethod(model, "submitVideoTool");
|
|
9599
10027
|
const plan = planVideoTool(model, request);
|
|
@@ -9640,6 +10068,13 @@ function resolveOptions(model, call, onUnsupported = "error") {
|
|
|
9640
10068
|
method: call.method,
|
|
9641
10069
|
...resolveTranscriptionCall(model, call.request, onUnsupported)
|
|
9642
10070
|
};
|
|
10071
|
+
case "createVoice":
|
|
10072
|
+
return { method: call.method, ...resolveVoiceCloneCall(model, call.request) };
|
|
10073
|
+
case "designVoice":
|
|
10074
|
+
return {
|
|
10075
|
+
method: call.method,
|
|
10076
|
+
...resolveVoiceDesignCall(model, call.request, onUnsupported)
|
|
10077
|
+
};
|
|
9643
10078
|
case "submitVideoTool":
|
|
9644
10079
|
return { method: call.method, ...resolveVideoToolCall(model, call.request) };
|
|
9645
10080
|
}
|
|
@@ -9699,6 +10134,8 @@ export {
|
|
|
9699
10134
|
resolveTranscriptionOptions,
|
|
9700
10135
|
resolveVideoOptions,
|
|
9701
10136
|
resolveVoiceChangeOptions,
|
|
10137
|
+
resolveVoiceCloneOptions,
|
|
10138
|
+
resolveVoiceDesignOptions,
|
|
9702
10139
|
sortCatalogRows,
|
|
9703
10140
|
takesTargetAspectRatio,
|
|
9704
10141
|
videoLengthViolation,
|