@nodaro/shared 2.15.0 → 2.17.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/dist/index.cjs CHANGED
@@ -1978,18 +1978,17 @@ var AUDIO_MODELS = {
1978
1978
  "elevenlabs-dialogue": {
1979
1979
  id: "elevenlabs-dialogue",
1980
1980
  kind: "audio",
1981
- modes: ["tts"],
1981
+ // Its own mode, never "tts": the script shape (inputs[]) doesn't fit the
1982
+ // single-text generate_speech contract, so list_models must never offer
1983
+ // it there. The dialogue-capable MCP verb is `generate_dialogue`.
1984
+ modes: ["dialogue"],
1982
1985
  family: "ElevenLabs",
1983
1986
  label: "ElevenLabs Dialogue v3",
1984
1987
  series: "ElevenLabs",
1985
- description: "Multi-speaker dialogue TTS \u2014 give it a script, it voices each role.",
1988
+ description: "Multi-speaker dialogue via the direct ElevenLabs API \u2014 give it a script, it voices each role (any voice: premade, library, or cloned).",
1986
1989
  useCases: ["tts", "dialogue", "multi-speaker"],
1987
- pricing: [{ identifier: "elevenlabs-dialogue", credits: 25, note: "per 1K chars" }],
1988
- // Driven only via the dialogue/character-voice path (multi-speaker script
1989
- // shape), NOT the single-text generate_speech verb. Hide from MCP
1990
- // list_models so generate_speech (TTS_PROVIDERS) can't advertise it and
1991
- // then 400. Re-expose if a dialogue-capable MCP verb is added.
1992
- mcpHidden: true
1990
+ features: ["audio-tags", "voice-cloning"],
1991
+ pricing: [{ identifier: "elevenlabs-dialogue", credits: 25, note: "per 1K chars" }]
1993
1992
  },
1994
1993
  // ── ElevenLabs voice utilities ──
1995
1994
  "voice-clone": {
@@ -2054,9 +2053,9 @@ var AUDIO_MODELS = {
2054
2053
  family: "ElevenLabs",
2055
2054
  label: "ElevenLabs Dubbing",
2056
2055
  series: "ElevenLabs",
2057
- description: "Translate + dub a video into a new language. Async.",
2056
+ description: "Translate + dub audio or a whole video into a new language \u2014 video in, dubbed video out. Async.",
2058
2057
  useCases: ["dubbing", "multilingual"],
2059
- pricing: [{ identifier: "elevenlabs-dubbing", credits: 80 }]
2058
+ pricing: [{ identifier: "elevenlabs-dubbing", credits: 40, note: "per minute of the dubbed span (min 1)" }]
2060
2059
  },
2061
2060
  "elevenlabs-forced-alignment": {
2062
2061
  id: "elevenlabs-forced-alignment",
@@ -2548,10 +2547,10 @@ var MAX_TTS_CHARS_BY_PROVIDER = {
2548
2547
  // == eleven_flash_v2_5 (functionally equivalent)
2549
2548
  "elevenlabs-multilingual": 1e4,
2550
2549
  // eleven_multilingual_v2
2551
- "elevenlabs-v3": 3e3,
2552
- // conservative (official 5000 / API-reported 3000)
2553
- "elevenlabs-dialogue": 2e3
2554
- // text-to-dialogue recommended per-request max
2550
+ "elevenlabs-v3": 5e3,
2551
+ // official cap (probed: 5,200 chars accepted; keep the clamp)
2552
+ "elevenlabs-dialogue": 5e3
2553
+ // total across lines; ≤2,000 recommended for best quality
2555
2554
  };
2556
2555
  function getMaxTtsChars(provider) {
2557
2556
  return provider && MAX_TTS_CHARS_BY_PROVIDER[provider] || TTS_TEXT_MAX;
@@ -8858,6 +8857,18 @@ function getAnimalLabel(id, fallback) {
8858
8857
  if (fallback !== void 0) return fallback;
8859
8858
  return (id ?? "").replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
8860
8859
  }
8860
+ function getAnimalPromptHint(id) {
8861
+ const a = getAnimal(id);
8862
+ return a ? `featuring a ${a.label.toLowerCase()}, ${a.description}` : "";
8863
+ }
8864
+ var PARENTHETICAL = /\([^)]*\)/g;
8865
+ function deriveAnimalTerm(label) {
8866
+ return label.replace(PARENTHETICAL, " ").toLowerCase().replace(/\s+/g, " ").trim();
8867
+ }
8868
+ function getAnimalTerm(id) {
8869
+ const a = getAnimal(id);
8870
+ return a ? a.term ?? deriveAnimalTerm(a.label) : "";
8871
+ }
8861
8872
  ANIMALS.map((a) => a.id);
8862
8873
  var ANIMAL_SUBCATEGORY_LABELS = {
8863
8874
  cats: "Cats",
@@ -9917,6 +9928,131 @@ function findLocationMentionTokens(prompt, knownLocationSlugs) {
9917
9928
  return tokens;
9918
9929
  }
9919
9930
 
9931
+ // src/mention-token-grammar.ts
9932
+ var MENTION_SLUG_PATTERN = /^[a-z][a-z0-9-]*$/;
9933
+ function mentionNameSlug(name) {
9934
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
9935
+ }
9936
+ function parseMentionToken(text) {
9937
+ if (!text.startsWith("@")) return null;
9938
+ let rest = text.slice(1);
9939
+ if (rest.length === 0 || !/^[a-z]/.test(rest)) return null;
9940
+ let lockField = {};
9941
+ if (rest.endsWith("~nolock")) {
9942
+ rest = rest.slice(0, -"~nolock".length);
9943
+ lockField = { lock: false };
9944
+ } else if (rest.endsWith("~lock")) {
9945
+ rest = rest.slice(0, -"~lock".length);
9946
+ lockField = { lock: true };
9947
+ }
9948
+ const parts = rest.split(":");
9949
+ if (parts.length < 2 || parts.length > 3) return null;
9950
+ const [slug, indexStr, third] = parts;
9951
+ if (!MENTION_SLUG_PATTERN.test(slug)) return null;
9952
+ if (!/^\d+$/.test(indexStr)) return null;
9953
+ const index = parseInt(indexStr, 10);
9954
+ if (!Number.isInteger(index) || index < 1) return null;
9955
+ if (parts.length === 2) return { slug, index, ...lockField };
9956
+ if (!MENTION_SLUG_PATTERN.test(third)) return null;
9957
+ return { slug, index, role: third, ...lockField };
9958
+ }
9959
+ var MENTION_TOKEN_REGEX = /(?:^|[^a-zA-Z0-9])(@[a-z][a-z0-9-]*:\d+(?::[a-z][a-z0-9-]*)?(?:~(?:no)?lock(?![a-z0-9-]))?)(?![:a-z0-9-])/g;
9960
+ function findMentionTokens(prompt, knownSlugs) {
9961
+ const tokens = [];
9962
+ const regex = new RegExp(MENTION_TOKEN_REGEX.source, "g");
9963
+ const knownSet = new Set(knownSlugs);
9964
+ for (const match of prompt.matchAll(regex)) {
9965
+ const token = match[1];
9966
+ const offset = (match.index ?? 0) + (match[0].length - token.length);
9967
+ if (/^\/[a-z]/.test(prompt.slice(offset + token.length))) continue;
9968
+ const parsed = parseMentionToken(token);
9969
+ if (parsed && knownSet.has(parsed.slug)) {
9970
+ tokens.push({ token, ...parsed, offset });
9971
+ }
9972
+ }
9973
+ return tokens;
9974
+ }
9975
+
9976
+ // src/image-mention-slug.ts
9977
+ function imageMentionSlug(name) {
9978
+ return mentionNameSlug(name);
9979
+ }
9980
+ function parseImageMentionToken(text) {
9981
+ const parsed = parseMentionToken(text);
9982
+ if (!parsed) return null;
9983
+ return {
9984
+ imageSlug: parsed.slug,
9985
+ imageIndex: parsed.index,
9986
+ ...parsed.role !== void 0 ? { role: parsed.role } : {},
9987
+ ...parsed.lock !== void 0 ? { lock: parsed.lock } : {}
9988
+ };
9989
+ }
9990
+ function findImageMentionTokens(prompt, knownImageSlugs) {
9991
+ return findMentionTokens(prompt, knownImageSlugs).map((t2) => ({
9992
+ token: t2.token,
9993
+ imageSlug: t2.slug,
9994
+ imageIndex: t2.index,
9995
+ ...t2.role !== void 0 ? { role: t2.role } : {},
9996
+ ...t2.lock !== void 0 ? { lock: t2.lock } : {},
9997
+ offset: t2.offset
9998
+ }));
9999
+ }
10000
+ function imageMentionSlugForRef(r) {
10001
+ if (r.source !== "wired-image" && r.source !== "manual") return null;
10002
+ if (r.isExtraRef === true) return null;
10003
+ if (!r.url || !r.defaultName) return null;
10004
+ const slug = imageMentionSlug(r.defaultName);
10005
+ return MENTION_SLUG_PATTERN.test(slug) ? slug : null;
10006
+ }
10007
+ function knownImageSlugsFromRefs(refs) {
10008
+ const out = /* @__PURE__ */ new Set();
10009
+ for (const r of refs) {
10010
+ const slug = imageMentionSlugForRef(r);
10011
+ if (slug) out.add(slug);
10012
+ }
10013
+ return [...out];
10014
+ }
10015
+
10016
+ // src/entity-mention-slug.ts
10017
+ function entityMentionSlug(name) {
10018
+ return mentionNameSlug(name);
10019
+ }
10020
+ function parseEntityMentionToken(text) {
10021
+ const parsed = parseMentionToken(text);
10022
+ if (!parsed) return null;
10023
+ return {
10024
+ entitySlug: parsed.slug,
10025
+ entityIndex: parsed.index,
10026
+ ...parsed.role !== void 0 ? { role: parsed.role } : {},
10027
+ ...parsed.lock !== void 0 ? { lock: parsed.lock } : {}
10028
+ };
10029
+ }
10030
+ function findEntityMentionTokens(prompt, knownEntitySlugs) {
10031
+ return findMentionTokens(prompt, knownEntitySlugs).map((t2) => ({
10032
+ token: t2.token,
10033
+ entitySlug: t2.slug,
10034
+ entityIndex: t2.index,
10035
+ ...t2.role !== void 0 ? { role: t2.role } : {},
10036
+ ...t2.lock !== void 0 ? { lock: t2.lock } : {},
10037
+ offset: t2.offset
10038
+ }));
10039
+ }
10040
+ function entityMentionSlugForRef(r) {
10041
+ if (r.source !== "wired-creature" && r.source !== "wired-object") return null;
10042
+ if (r.isExtraRef === true) return null;
10043
+ if (!r.url || !r.defaultName) return null;
10044
+ const slug = entityMentionSlug(r.defaultName);
10045
+ return MENTION_SLUG_PATTERN.test(slug) ? slug : null;
10046
+ }
10047
+ function knownEntitySlugsFromRefs(refs) {
10048
+ const out = /* @__PURE__ */ new Set();
10049
+ for (const r of refs) {
10050
+ const slug = entityMentionSlugForRef(r);
10051
+ if (slug) out.add(slug);
10052
+ }
10053
+ return [...out];
10054
+ }
10055
+
9920
10056
  // src/to-connected-references.ts
9921
10057
  function toConnectedReference(entity) {
9922
10058
  if (entity.kind === "character") {
@@ -9932,6 +10068,15 @@ function toConnectedReference(entity) {
9932
10068
  variantDisplayName: entity.variant ?? "canonical"
9933
10069
  };
9934
10070
  }
10071
+ if (entity.kind === "image") {
10072
+ return {
10073
+ id: entity.id,
10074
+ defaultName: entity.name,
10075
+ source: "wired-image",
10076
+ url: entity.url ?? "",
10077
+ ...entity.description ? { description: entity.description } : {}
10078
+ };
10079
+ }
9935
10080
  if (entity.kind === "creature") {
9936
10081
  return {
9937
10082
  id: entity.id,
@@ -12065,6 +12210,12 @@ var DYNAMIC_PRODUCER_TYPES = /* @__PURE__ */ new Set([
12065
12210
  // EVERY producer set or its outputs can't connect (was the "cannot connect
12066
12211
  // the outputs of voice-changer-pro" bug). Guarded by producer-types.test.ts.
12067
12212
  "voice-changer-pro",
12213
+ // Dubbing joined the dual-mode family with the full-surface upgrade:
12214
+ // audio in → dubbed audio; video in (or a video sourceUrl) → dubbed VIDEO
12215
+ // (+ audio sidecar). Same wiring contract as voice-changer; stays in
12216
+ // AUDIO_PRODUCER_TYPES as its default. Explicitly asserted in
12217
+ // producer-types.test.ts (the suite does not fail on omission).
12218
+ "dubbing",
12068
12219
  "reduce",
12069
12220
  // Dual-output time chunker (UI label "Split into Chunks"; type id stays
12070
12221
  // "split-media"): video in → video chunks, audio in → audio chunks — two
@@ -12818,6 +12969,7 @@ var MODE_TO_NODE = {
12818
12969
  "dubbing": "dubbing",
12819
12970
  "forced-alignment": "forced-alignment",
12820
12971
  "stt": "transcribe",
12972
+ "dialogue": "text-to-dialogue",
12821
12973
  "video-analysis": "video-analysis"
12822
12974
  };
12823
12975
  function modelToNodeTarget(modelId) {
@@ -14210,6 +14362,8 @@ exports.effectiveReasoningEffort = effectiveReasoningEffort;
14210
14362
  exports.encodeProviderItem = encodeProviderItem;
14211
14363
  exports.ensureLocaleCatalogLoaded = ensureLocaleCatalogLoaded;
14212
14364
  exports.entityHydrationColumns = entityHydrationColumns;
14365
+ exports.entityMentionSlug = entityMentionSlug;
14366
+ exports.entityMentionSlugForRef = entityMentionSlugForRef;
14213
14367
  exports.entityScalarFields = entityScalarFields;
14214
14368
  exports.entitySlotSchema = entitySlotSchema;
14215
14369
  exports.entryMatchesQuery = entryMatchesQuery;
@@ -14235,12 +14389,16 @@ exports.extractVideoDurationFromNode = extractVideoDurationFromNode;
14235
14389
  exports.fieldKeyFromHandle = fieldKeyFromHandle;
14236
14390
  exports.filterCloneNodes = filterCloneNodes;
14237
14391
  exports.findCharacterMentionTokens = findCharacterMentionTokens;
14392
+ exports.findEntityMentionTokens = findEntityMentionTokens;
14393
+ exports.findImageMentionTokens = findImageMentionTokens;
14238
14394
  exports.findLocationMentionTokens = findLocationMentionTokens;
14239
14395
  exports.findSeedance2AudioOverLimit = findSeedance2AudioOverLimit;
14240
14396
  exports.firstSightExtraRole = firstSightExtraRole;
14241
14397
  exports.flattenItems = flattenItems;
14242
14398
  exports.getAnimal = getAnimal;
14243
14399
  exports.getAnimalLabel = getAnimalLabel;
14400
+ exports.getAnimalPromptHint = getAnimalPromptHint;
14401
+ exports.getAnimalTerm = getAnimalTerm;
14244
14402
  exports.getAspectRatioOptions = getAspectRatioOptions;
14245
14403
  exports.getAudioCrossfadeCurve = getAudioCrossfadeCurve;
14246
14404
  exports.getCharacterFacet = getCharacterFacet;
@@ -14289,6 +14447,8 @@ exports.hasContiguousSegmentDurations = hasContiguousSegmentDurations;
14289
14447
  exports.hasFeature = hasFeature;
14290
14448
  exports.hexToRgbaArray = hexToRgbaArray;
14291
14449
  exports.humanizeSlotSid = humanizeSlotSid;
14450
+ exports.imageMentionSlug = imageMentionSlug;
14451
+ exports.imageMentionSlugForRef = imageMentionSlugForRef;
14292
14452
  exports.imageReferenceLimit = imageReferenceLimit;
14293
14453
  exports.inferMusicVideo = inferMusicVideo;
14294
14454
  exports.isAggregateableType = isAggregateableType;
@@ -14314,6 +14474,8 @@ exports.isVeoProvider = isVeoProvider;
14314
14474
  exports.isVideoAnalysisMixedTier = isVideoAnalysisMixedTier;
14315
14475
  exports.isVideoAnalysisTier = isVideoAnalysisTier;
14316
14476
  exports.jsonResultToList = jsonResultToList;
14477
+ exports.knownEntitySlugsFromRefs = knownEntitySlugsFromRefs;
14478
+ exports.knownImageSlugsFromRefs = knownImageSlugsFromRefs;
14317
14479
  exports.listBoardTemplates = listBoardTemplates;
14318
14480
  exports.listModels = listModels;
14319
14481
  exports.listSlotSids = listSlotSids;
@@ -14346,8 +14508,10 @@ exports.normalizeRoleSlug = normalizeRoleSlug;
14346
14508
  exports.orderedLlmModels = orderedLlmModels;
14347
14509
  exports.parseAttributedDialogue = parseAttributedDialogue;
14348
14510
  exports.parseCharacterMentionToken = parseCharacterMentionToken;
14511
+ exports.parseEntityMentionToken = parseEntityMentionToken;
14349
14512
  exports.parseGroupHandle = parseGroupHandle;
14350
14513
  exports.parseHandleId = parseHandleId;
14514
+ exports.parseImageMentionToken = parseImageMentionToken;
14351
14515
  exports.parseListExpression = parseListExpression;
14352
14516
  exports.parseLocationMentionToken = parseLocationMentionToken;
14353
14517
  exports.parseNodePresetExport = parseNodePresetExport;