@nodaro/shared 2.15.0 → 2.16.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 +85 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +141 -11
- package/dist/index.d.ts +141 -11
- package/dist/index.js +81 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/image-mention-slug.test.ts +303 -0
- package/src/__tests__/prompt-length-limits.test.ts +2 -2
- package/src/__tests__/to-connected-references.test.ts +45 -0
- package/src/character-voice.ts +4 -3
- package/src/image-mention-slug.ts +236 -0
- package/src/index.ts +9 -0
- package/src/model-catalog.ts +10 -7
- package/src/model-constants.ts +8 -6
- package/src/model-tree.ts +1 -0
- package/src/to-connected-references.ts +16 -2
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": {
|
|
@@ -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;
|
|
@@ -9917,6 +9916,65 @@ function findLocationMentionTokens(prompt, knownLocationSlugs) {
|
|
|
9917
9916
|
return tokens;
|
|
9918
9917
|
}
|
|
9919
9918
|
|
|
9919
|
+
// src/image-mention-slug.ts
|
|
9920
|
+
var IMAGE_SLUG_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
9921
|
+
function imageMentionSlug(name) {
|
|
9922
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
9923
|
+
}
|
|
9924
|
+
function parseImageMentionToken(text) {
|
|
9925
|
+
if (!text.startsWith("@")) return null;
|
|
9926
|
+
let rest = text.slice(1);
|
|
9927
|
+
if (rest.length === 0 || !/^[a-z]/.test(rest)) return null;
|
|
9928
|
+
let lockField = {};
|
|
9929
|
+
if (rest.endsWith("~nolock")) {
|
|
9930
|
+
rest = rest.slice(0, -"~nolock".length);
|
|
9931
|
+
lockField = { lock: false };
|
|
9932
|
+
} else if (rest.endsWith("~lock")) {
|
|
9933
|
+
rest = rest.slice(0, -"~lock".length);
|
|
9934
|
+
lockField = { lock: true };
|
|
9935
|
+
}
|
|
9936
|
+
const parts = rest.split(":");
|
|
9937
|
+
if (parts.length < 2 || parts.length > 3) return null;
|
|
9938
|
+
const [imageSlug, indexStr, third] = parts;
|
|
9939
|
+
if (!IMAGE_SLUG_PATTERN.test(imageSlug)) return null;
|
|
9940
|
+
if (!/^\d+$/.test(indexStr)) return null;
|
|
9941
|
+
const imageIndex = parseInt(indexStr, 10);
|
|
9942
|
+
if (!Number.isInteger(imageIndex) || imageIndex < 1) return null;
|
|
9943
|
+
if (parts.length === 2) return { imageSlug, imageIndex, ...lockField };
|
|
9944
|
+
if (!IMAGE_SLUG_PATTERN.test(third)) return null;
|
|
9945
|
+
return { imageSlug, imageIndex, role: third, ...lockField };
|
|
9946
|
+
}
|
|
9947
|
+
function findImageMentionTokens(prompt, knownImageSlugs) {
|
|
9948
|
+
const tokens = [];
|
|
9949
|
+
const 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;
|
|
9950
|
+
const knownSet = new Set(knownImageSlugs);
|
|
9951
|
+
for (const match of prompt.matchAll(regex)) {
|
|
9952
|
+
const token = match[1];
|
|
9953
|
+
const offset = (match.index ?? 0) + (match[0].length - token.length);
|
|
9954
|
+
if (/^\/[a-z]/.test(prompt.slice(offset + token.length))) continue;
|
|
9955
|
+
const parsed = parseImageMentionToken(token);
|
|
9956
|
+
if (parsed && knownSet.has(parsed.imageSlug)) {
|
|
9957
|
+
tokens.push({ token, ...parsed, offset });
|
|
9958
|
+
}
|
|
9959
|
+
}
|
|
9960
|
+
return tokens;
|
|
9961
|
+
}
|
|
9962
|
+
function imageMentionSlugForRef(r) {
|
|
9963
|
+
if (r.source !== "wired-image" && r.source !== "manual") return null;
|
|
9964
|
+
if (r.isExtraRef === true) return null;
|
|
9965
|
+
if (!r.url || !r.defaultName) return null;
|
|
9966
|
+
const slug = imageMentionSlug(r.defaultName);
|
|
9967
|
+
return IMAGE_SLUG_PATTERN.test(slug) ? slug : null;
|
|
9968
|
+
}
|
|
9969
|
+
function knownImageSlugsFromRefs(refs) {
|
|
9970
|
+
const out = /* @__PURE__ */ new Set();
|
|
9971
|
+
for (const r of refs) {
|
|
9972
|
+
const slug = imageMentionSlugForRef(r);
|
|
9973
|
+
if (slug) out.add(slug);
|
|
9974
|
+
}
|
|
9975
|
+
return [...out];
|
|
9976
|
+
}
|
|
9977
|
+
|
|
9920
9978
|
// src/to-connected-references.ts
|
|
9921
9979
|
function toConnectedReference(entity) {
|
|
9922
9980
|
if (entity.kind === "character") {
|
|
@@ -9932,6 +9990,15 @@ function toConnectedReference(entity) {
|
|
|
9932
9990
|
variantDisplayName: entity.variant ?? "canonical"
|
|
9933
9991
|
};
|
|
9934
9992
|
}
|
|
9993
|
+
if (entity.kind === "image") {
|
|
9994
|
+
return {
|
|
9995
|
+
id: entity.id,
|
|
9996
|
+
defaultName: entity.name,
|
|
9997
|
+
source: "wired-image",
|
|
9998
|
+
url: entity.url ?? "",
|
|
9999
|
+
...entity.description ? { description: entity.description } : {}
|
|
10000
|
+
};
|
|
10001
|
+
}
|
|
9935
10002
|
if (entity.kind === "creature") {
|
|
9936
10003
|
return {
|
|
9937
10004
|
id: entity.id,
|
|
@@ -12818,6 +12885,7 @@ var MODE_TO_NODE = {
|
|
|
12818
12885
|
"dubbing": "dubbing",
|
|
12819
12886
|
"forced-alignment": "forced-alignment",
|
|
12820
12887
|
"stt": "transcribe",
|
|
12888
|
+
"dialogue": "text-to-dialogue",
|
|
12821
12889
|
"video-analysis": "video-analysis"
|
|
12822
12890
|
};
|
|
12823
12891
|
function modelToNodeTarget(modelId) {
|
|
@@ -14235,6 +14303,7 @@ exports.extractVideoDurationFromNode = extractVideoDurationFromNode;
|
|
|
14235
14303
|
exports.fieldKeyFromHandle = fieldKeyFromHandle;
|
|
14236
14304
|
exports.filterCloneNodes = filterCloneNodes;
|
|
14237
14305
|
exports.findCharacterMentionTokens = findCharacterMentionTokens;
|
|
14306
|
+
exports.findImageMentionTokens = findImageMentionTokens;
|
|
14238
14307
|
exports.findLocationMentionTokens = findLocationMentionTokens;
|
|
14239
14308
|
exports.findSeedance2AudioOverLimit = findSeedance2AudioOverLimit;
|
|
14240
14309
|
exports.firstSightExtraRole = firstSightExtraRole;
|
|
@@ -14289,6 +14358,8 @@ exports.hasContiguousSegmentDurations = hasContiguousSegmentDurations;
|
|
|
14289
14358
|
exports.hasFeature = hasFeature;
|
|
14290
14359
|
exports.hexToRgbaArray = hexToRgbaArray;
|
|
14291
14360
|
exports.humanizeSlotSid = humanizeSlotSid;
|
|
14361
|
+
exports.imageMentionSlug = imageMentionSlug;
|
|
14362
|
+
exports.imageMentionSlugForRef = imageMentionSlugForRef;
|
|
14292
14363
|
exports.imageReferenceLimit = imageReferenceLimit;
|
|
14293
14364
|
exports.inferMusicVideo = inferMusicVideo;
|
|
14294
14365
|
exports.isAggregateableType = isAggregateableType;
|
|
@@ -14314,6 +14385,7 @@ exports.isVeoProvider = isVeoProvider;
|
|
|
14314
14385
|
exports.isVideoAnalysisMixedTier = isVideoAnalysisMixedTier;
|
|
14315
14386
|
exports.isVideoAnalysisTier = isVideoAnalysisTier;
|
|
14316
14387
|
exports.jsonResultToList = jsonResultToList;
|
|
14388
|
+
exports.knownImageSlugsFromRefs = knownImageSlugsFromRefs;
|
|
14317
14389
|
exports.listBoardTemplates = listBoardTemplates;
|
|
14318
14390
|
exports.listModels = listModels;
|
|
14319
14391
|
exports.listSlotSids = listSlotSids;
|
|
@@ -14348,6 +14420,7 @@ exports.parseAttributedDialogue = parseAttributedDialogue;
|
|
|
14348
14420
|
exports.parseCharacterMentionToken = parseCharacterMentionToken;
|
|
14349
14421
|
exports.parseGroupHandle = parseGroupHandle;
|
|
14350
14422
|
exports.parseHandleId = parseHandleId;
|
|
14423
|
+
exports.parseImageMentionToken = parseImageMentionToken;
|
|
14351
14424
|
exports.parseListExpression = parseListExpression;
|
|
14352
14425
|
exports.parseLocationMentionToken = parseLocationMentionToken;
|
|
14353
14426
|
exports.parseNodePresetExport = parseNodePresetExport;
|