@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 +178 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +378 -16
- package/dist/index.d.ts +378 -16
- package/dist/index.js +167 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/entity-mention-slug.test.ts +380 -0
- package/src/__tests__/image-mention-slug.test.ts +303 -0
- package/src/__tests__/producer-types.test.ts +22 -0
- package/src/__tests__/prompt-length-limits.test.ts +2 -2
- package/src/__tests__/to-connected-references.test.ts +45 -0
- package/src/animals.ts +57 -0
- package/src/character-voice.ts +4 -3
- package/src/entity-mention-slug.ts +203 -0
- package/src/image-mention-slug.ts +187 -0
- package/src/index.ts +27 -0
- package/src/mention-token-grammar.ts +167 -0
- package/src/model-catalog.ts +12 -9
- package/src/model-constants.ts +8 -6
- package/src/model-tree.ts +1 -0
- package/src/producer-types.ts +6 -0
- package/src/to-connected-references.ts +16 -2
- package/src/types.ts +11 -5
- package/src/workflow-export.ts +34 -0
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
|
-
|
|
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
|
|
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
|
-
|
|
1988
|
-
|
|
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:
|
|
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":
|
|
2552
|
-
//
|
|
2553
|
-
"elevenlabs-dialogue":
|
|
2554
|
-
//
|
|
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;
|