@nodaro/shared 1.5.0 → 1.7.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
@@ -4,8 +4,11 @@ var zod = require('zod');
4
4
 
5
5
  // src/types.ts
6
6
  var DEFAULT_LABEL_BY_SOURCE = {
7
- "manual": "object",
8
- "wired-image": "object",
7
+ // Media references default to "ref-only" — the empty label, i.e. a bare
8
+ // {image:N} token that injects only "reference image A" (image) / "@image_N"
9
+ // (video) with no descriptive role phrase. Pick a role on the pill to change.
10
+ "manual": "",
11
+ "wired-image": "",
9
12
  "wired-character": "person",
10
13
  "wired-face": "face",
11
14
  "wired-object": "object",
@@ -60,6 +63,7 @@ var VIDEO_RATIOS_HVS = ["16:9", "9:16", "1:1"];
60
63
  var WAN_27_IMAGE_RATIOS = ["1:1", "16:9", "9:16", "4:3", "3:4", "21:9", "8:1", "1:8"];
61
64
  var VIDEO_RATIOS_HVS345 = ["16:9", "9:16", "1:1", "4:3", "3:4"];
62
65
  var VIDEO_RATIOS_SEEDANCE_2 = ["16:9", "9:16", "1:1", "4:3", "3:4", "21:9", "adaptive"];
66
+ var VIDEO_RATIOS_HAPPYHORSE_11 = ["16:9", "9:16", "1:1", "4:3", "3:4", "4:5", "5:4", "21:9", "9:21"];
63
67
  var IMAGE_MODELS = {
64
68
  // ── Google Nano Banana ──
65
69
  "nano-banana": {
@@ -1238,21 +1242,22 @@ var VIDEO_MODELS = {
1238
1242
  { identifier: "wan-2.7-t2v", credits: 19, note: "5s 720p default" }
1239
1243
  ]
1240
1244
  },
1241
- // ── HappyHorse ──
1245
+ // ── HappyHorse (1.1 — ids kept version-less; repointed in place when KIE
1246
+ // delisted 1.0, same param surface, so saved workflows keep working) ──
1242
1247
  "happyhorse": {
1243
1248
  id: "happyhorse",
1244
1249
  kind: "video",
1245
1250
  modes: ["t2v"],
1246
1251
  family: "HappyHorse",
1247
- label: "HappyHorse",
1252
+ label: "HappyHorse 1.1",
1248
1253
  series: "HappyHorse",
1249
- description: "HappyHorse text-to-video \u2014 3\u201315s at 720p/1080p.",
1254
+ description: "HappyHorse 1.1 text-to-video \u2014 3\u201315s at 720p/1080p, 9 aspect ratios incl. 21:9/9:21, per-second pricing.",
1250
1255
  useCases: ["motion", "creative"],
1251
- aspectRatios: VIDEO_RATIOS_HVS345,
1256
+ aspectRatios: VIDEO_RATIOS_HAPPYHORSE_11,
1252
1257
  durations: [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
1253
1258
  resolutions: ["720p", "1080p"],
1254
1259
  pricing: [
1255
- { identifier: "happyhorse", credits: 13, note: "5s 720p default" }
1260
+ { identifier: "happyhorse", credits: 29, note: "5s 720p default \u2014 per-second: ~5.7 cr/s @720p, ~7.3 cr/s @1080p" }
1256
1261
  ]
1257
1262
  },
1258
1263
  "happyhorse-i2v": {
@@ -1260,14 +1265,14 @@ var VIDEO_MODELS = {
1260
1265
  kind: "video",
1261
1266
  modes: ["i2v"],
1262
1267
  family: "HappyHorse",
1263
- label: "HappyHorse I2V",
1268
+ label: "HappyHorse 1.1 I2V",
1264
1269
  series: "HappyHorse",
1265
- description: "HappyHorse image-to-video \u2014 3\u201315s at 720p/1080p, aspect ratio inferred from input image.",
1270
+ description: "HappyHorse 1.1 image-to-video \u2014 3\u201315s at 720p/1080p, aspect ratio inferred from input image, per-second pricing.",
1266
1271
  useCases: ["motion", "creative"],
1267
1272
  durations: [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
1268
1273
  resolutions: ["720p", "1080p"],
1269
1274
  pricing: [
1270
- { identifier: "happyhorse-i2v", credits: 13, note: "5s 720p default" }
1275
+ { identifier: "happyhorse-i2v", credits: 29, note: "5s 720p default \u2014 per-second: ~5.7 cr/s @720p, ~7.3 cr/s @1080p" }
1271
1276
  ]
1272
1277
  },
1273
1278
  "happyhorse-ref2v": {
@@ -1275,16 +1280,16 @@ var VIDEO_MODELS = {
1275
1280
  kind: "video",
1276
1281
  modes: ["i2v"],
1277
1282
  family: "HappyHorse",
1278
- label: "HappyHorse Ref2V",
1283
+ label: "HappyHorse 1.1 Ref2V",
1279
1284
  series: "HappyHorse",
1280
- description: "HappyHorse reference-to-video \u2014 1\u20139 reference images, 3\u201315s at 720p/1080p.",
1285
+ description: "HappyHorse 1.1 reference-to-video \u2014 1\u20139 reference images, 3\u201315s at 720p/1080p, per-second pricing.",
1281
1286
  useCases: ["motion", "reference"],
1282
- aspectRatios: VIDEO_RATIOS_HVS345,
1287
+ aspectRatios: VIDEO_RATIOS_HAPPYHORSE_11,
1283
1288
  durations: [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
1284
1289
  resolutions: ["720p", "1080p"],
1285
1290
  features: ["reference-image"],
1286
1291
  pricing: [
1287
- { identifier: "happyhorse-ref2v", credits: 15, note: "5s 720p default" }
1292
+ { identifier: "happyhorse-ref2v", credits: 29, note: "5s 720p default \u2014 per-second: ~5.7 cr/s @720p, ~7.3 cr/s @1080p" }
1288
1293
  ]
1289
1294
  },
1290
1295
  "happyhorse-edit": {
@@ -1298,7 +1303,7 @@ var VIDEO_MODELS = {
1298
1303
  useCases: ["v2v", "restyle"],
1299
1304
  resolutions: ["720p", "1080p"],
1300
1305
  pricing: [
1301
- { identifier: "happyhorse-edit", credits: 20, note: "720p default" }
1306
+ { identifier: "happyhorse-edit", credits: 35, note: "720p default (5s-equivalent flat rate)" }
1302
1307
  ]
1303
1308
  },
1304
1309
  // ── Bytedance video lite/pro ──
@@ -2750,7 +2755,10 @@ var DURATION_PRICED_PROVIDERS = /* @__PURE__ */ new Set([
2750
2755
  "seedance-2",
2751
2756
  "seedance-2-fast",
2752
2757
  "seedance-2-mini",
2753
- "grok-imagine-video-1.5"
2758
+ "grok-imagine-video-1.5",
2759
+ "happyhorse",
2760
+ "happyhorse-i2v",
2761
+ "happyhorse-ref2v"
2754
2762
  ]);
2755
2763
  var SEEDANCE_2_PROVIDERS = /* @__PURE__ */ new Set([
2756
2764
  "seedance-2",
@@ -2829,7 +2837,14 @@ var RESOLUTION_DURATION_PRICING = {
2829
2837
  "grok-imagine-video-1.5": ["480p", "720p"],
2830
2838
  // seedance-2-extend always uses a video ref, so pricing has no -ref
2831
2839
  // dimension — duration tier + ":res" only (rates = seedance-2 -ref + stitch).
2832
- "seedance-2-extend": ["480p", "720p", "1080p"]
2840
+ "seedance-2-extend": ["480p", "720p", "1080p"],
2841
+ // HappyHorse 1.1 — per-second billing at two published resolution rates
2842
+ // (kie.ai/happyhorse-1-1: 22.5 cr/s @720p, 29 cr/s @1080p, uniform across
2843
+ // t2v/i2v/ref2v). 720p first = billing default; the KIE-side default is
2844
+ // pinned to 720p via extraParams in backend kie/models.ts so render matches.
2845
+ "happyhorse": ["720p", "1080p"],
2846
+ "happyhorse-i2v": ["720p", "1080p"],
2847
+ "happyhorse-ref2v": ["720p", "1080p"]
2833
2848
  };
2834
2849
  var NATIVE_ADAPTIVE_ASPECT = {
2835
2850
  "seedance-2": "adaptive",
@@ -2905,6 +2920,10 @@ var VIDEO_VARIABLE_PRICING = {
2905
2920
  // Grok Imagine Video 1.5 — per-second billing split 480p/720p (no video-ref dimension).
2906
2921
  "grok-imagine-video-1.5": "duration+resolution"
2907
2922
  };
2923
+ var HAPPYHORSE_DURATION_TIERS = Array.from(
2924
+ { length: 13 },
2925
+ (_, i) => ({ maxSeconds: i + 3, suffix: `${i + 3}s` })
2926
+ );
2908
2927
  var VIDEO_DURATION_TIERS = {
2909
2928
  "kling-3.0": [
2910
2929
  { maxSeconds: 5, suffix: "5s" },
@@ -2998,7 +3017,15 @@ var VIDEO_DURATION_TIERS = {
2998
3017
  { maxSeconds: 13, suffix: "13s" },
2999
3018
  { maxSeconds: 14, suffix: "14s" },
3000
3019
  { maxSeconds: 15, suffix: "15s" }
3001
- ]
3020
+ ],
3021
+ // HappyHorse 1.1 (t2v / i2v / ref2v) — true per-second billing (KIE 22.5 cr/s
3022
+ // @720p, 29 cr/s @1080p, published on kie.ai/happyhorse-1-1). One tier per
3023
+ // allowed second (3–15s) so the composite identifier maps 1:1 to the seeded
3024
+ // price, combined with RESOLUTION_DURATION_PRICING for the ":720p"/":1080p"
3025
+ // suffix (e.g. "happyhorse-i2v:5s:720p").
3026
+ "happyhorse": HAPPYHORSE_DURATION_TIERS,
3027
+ "happyhorse-i2v": HAPPYHORSE_DURATION_TIERS,
3028
+ "happyhorse-ref2v": HAPPYHORSE_DURATION_TIERS
3002
3029
  };
3003
3030
  var COMPOSER_PLAN_MAP = {
3004
3031
  "video-composer": { planType: "scene-graph", planField: "sceneGraph" },
@@ -8565,8 +8592,11 @@ function parseCharacterMentionToken(text, _knownCharacterSlugs) {
8565
8592
  }
8566
8593
  if (parts.length === 4) {
8567
8594
  if (!/^[a-z][a-z0-9-]*$/.test(third)) return null;
8568
- if (!isUsageMode(fourth)) return null;
8569
- return { characterSlug, imageIndex, variantSlug: third, usageMode: fourth, ...lockField };
8595
+ if (!/^[a-z][a-z0-9-]*$/.test(fourth)) return null;
8596
+ if (isUsageMode(fourth)) {
8597
+ return { characterSlug, imageIndex, variantSlug: third, usageMode: fourth, ...lockField };
8598
+ }
8599
+ return { characterSlug, imageIndex, variantSlug: third, usageMode: null, role: fourth, ...lockField };
8570
8600
  }
8571
8601
  return null;
8572
8602
  }
@@ -8641,6 +8671,35 @@ function characterMentionableAssetArrays(data) {
8641
8671
  boards: characterBoardItems(data)
8642
8672
  };
8643
8673
  }
8674
+ var CHARACTER_PICKER_DISPLAY_ORDER = [
8675
+ "boards",
8676
+ "sheets",
8677
+ ...CHARACTER_VARIANT_ASSET_BUCKETS
8678
+ ];
8679
+ function characterBucketDisplayRank(bucket) {
8680
+ if (bucket === void 0) return -1;
8681
+ const i = CHARACTER_PICKER_DISPLAY_ORDER.indexOf(bucket);
8682
+ return i === -1 ? CHARACTER_PICKER_DISPLAY_ORDER.length : i;
8683
+ }
8684
+ function sortCharacterEntriesForDisplay(items) {
8685
+ const out = [];
8686
+ let i = 0;
8687
+ while (i < items.length) {
8688
+ const slug = items[i].characterSlug;
8689
+ if (!slug) {
8690
+ out.push(items[i]);
8691
+ i++;
8692
+ continue;
8693
+ }
8694
+ let j = i;
8695
+ while (j < items.length && items[j].characterSlug === slug) j++;
8696
+ const run = items.slice(i, j);
8697
+ const ranked = run.map((it, k) => ({ it, k, r: characterBucketDisplayRank(it.bucket) })).sort((a, b) => a.r - b.r || a.k - b.k).map((x) => x.it);
8698
+ out.push(...ranked);
8699
+ i = j;
8700
+ }
8701
+ return out;
8702
+ }
8644
8703
 
8645
8704
  // src/location-mention-slug.ts
8646
8705
  var LOCATION_USAGE_MODES = [
@@ -8734,8 +8793,11 @@ function parseLocationMentionToken(text) {
8734
8793
  const variant = third.slice(slashAt + 1);
8735
8794
  if (!/^[a-z][a-z0-9-]*$/.test(bucket)) return null;
8736
8795
  if (!/^[a-z][a-z0-9-]*$/.test(variant)) return null;
8737
- if (!isLocationUsageMode(fourth)) return null;
8738
- return { locationSlug, imageIndex, bucket, variant, usageMode: fourth, ...lockField };
8796
+ if (!/^[a-z][a-z0-9-]*$/.test(fourth)) return null;
8797
+ if (isLocationUsageMode(fourth)) {
8798
+ return { locationSlug, imageIndex, bucket, variant, usageMode: fourth, ...lockField };
8799
+ }
8800
+ return { locationSlug, imageIndex, bucket, variant, usageMode: null, role: fourth, ...lockField };
8739
8801
  }
8740
8802
  return null;
8741
8803
  }
@@ -9059,7 +9121,7 @@ var ShotSpecSchema = zod.z.object({
9059
9121
  // v4.1 Method 10 — parametric 3D camera path
9060
9122
  camera_path_directive: zod.z.object({
9061
9123
  path_kind: zod.z.enum(["orbit", "dolly", "crane", "arc", "reveal"]),
9062
- parameters: zod.z.record(zod.z.unknown()).optional()
9124
+ parameters: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
9063
9125
  }).optional(),
9064
9126
  // ─── Execution state (engine writes; null on planning) ─────────────────────
9065
9127
  // Phase 1C.1: per-shot execution state lands directly on the shot record so
@@ -9804,7 +9866,7 @@ var StageAwaitingSubGateEventSchema = zod.z.object({
9804
9866
  pipelineId: zod.z.string().uuid(),
9805
9867
  stageName: zod.z.enum(["animate_audio_edit", "scene_images"]),
9806
9868
  subGate: SubGateNameSchema,
9807
- payload: zod.z.record(zod.z.unknown()).optional()
9869
+ payload: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
9808
9870
  });
9809
9871
  var PipelineMusicReadyEventSchema = zod.z.object({
9810
9872
  type: zod.z.literal("pipeline:music_ready"),
@@ -11060,7 +11122,10 @@ var CHARACTER_ATTACH_COLUMNS = [
11060
11122
  // locations don't have an outfit dimension).
11061
11123
  "sheets",
11062
11124
  "detail_closeups",
11063
- "outfit_variations"
11125
+ "outfit_variations",
11126
+ // Named composite reference boards (migration 250) — identity-collage
11127
+ // sheets auto-attached by the ffmpeg image-collage worker.
11128
+ "boards"
11064
11129
  ];
11065
11130
  var CHARACTER_ASSET_VARIANTS = {
11066
11131
  expressions: [
@@ -11658,12 +11723,15 @@ function resolveEffectiveSourceType(rawSourceType, sourceHandleId) {
11658
11723
  }
11659
11724
  return rawSourceType ?? "";
11660
11725
  }
11726
+ function sourceRefKey(nodeId, sourceHandleId, rawSourceType) {
11727
+ return sourceHandleId === "image" && ENTITY_IMAGE_HANDLE_TYPES.has(rawSourceType ?? "") ? `${nodeId}::image` : nodeId;
11728
+ }
11661
11729
 
11662
11730
  // src/reference-roles.ts
11663
11731
  var REFERENCE_ROLE_PRESETS = {
11664
- "wired-character": ["person", "face", "clothes", "hair", "pose", "expression", "style"],
11732
+ "wired-character": ["ref-only", "person", "face", "clothes", "hair", "pose", "expression", "style"],
11665
11733
  "wired-face": ["face", "person", "expression", "style"],
11666
- "wired-location": ["background", "atmosphere", "as-is", "empty background", "layout", "lighting", "style"],
11734
+ "wired-location": ["ref-only", "background", "atmosphere", "as-is", "empty background", "layout", "lighting", "style"],
11667
11735
  "wired-object": ["object", "shape", "material", "color", "texture", "style"],
11668
11736
  "wired-creature": ["creature", "anatomy", "markings", "pose", "color", "style"],
11669
11737
  "wired-image": ["object", "person", "face", "clothes", "background", "style", "pose", "texture"],
@@ -11676,6 +11744,8 @@ function roleToPhrase(role, binding) {
11676
11744
  const r = role.trim();
11677
11745
  if (!r) return binding;
11678
11746
  switch (r) {
11747
+ case "ref-only":
11748
+ return binding;
11679
11749
  case "as-is":
11680
11750
  return `${binding}, used as-is`;
11681
11751
  case "empty background":
@@ -11872,6 +11942,7 @@ exports.CHARACTER_FACETS = CHARACTER_FACETS;
11872
11942
  exports.CHARACTER_FACET_IDS = CHARACTER_FACET_IDS;
11873
11943
  exports.CHARACTER_LORA_TRAINING_JOB_TYPE = CHARACTER_LORA_TRAINING_JOB_TYPE;
11874
11944
  exports.CHARACTER_MOTION_PROVIDERS = CHARACTER_MOTION_PROVIDERS;
11945
+ exports.CHARACTER_PICKER_DISPLAY_ORDER = CHARACTER_PICKER_DISPLAY_ORDER;
11875
11946
  exports.CHARACTER_REFERENCE_PHOTO_KINDS = CHARACTER_REFERENCE_PHOTO_KINDS;
11876
11947
  exports.CHARACTER_STYLES = CHARACTER_STYLES;
11877
11948
  exports.CHARACTER_VARIANT_ASSET_BUCKETS = CHARACTER_VARIANT_ASSET_BUCKETS;
@@ -12255,6 +12326,7 @@ exports.calculateMonetizedCost = calculateMonetizedCost;
12255
12326
  exports.calculateProgress = calculateProgress;
12256
12327
  exports.canonicalVarName = canonicalVarName;
12257
12328
  exports.characterBoardItems = characterBoardItems;
12329
+ exports.characterBucketDisplayRank = characterBucketDisplayRank;
12258
12330
  exports.characterMentionSlug = characterMentionSlug;
12259
12331
  exports.characterMentionableAssetArrays = characterMentionableAssetArrays;
12260
12332
  exports.characterSheetRefItems = characterSheetRefItems;
@@ -12468,7 +12540,9 @@ exports.selectListItems = selectListItems;
12468
12540
  exports.selectLoraRoutingForMentions = selectLoraRoutingForMentions;
12469
12541
  exports.selectRandom = selectRandom;
12470
12542
  exports.settledWithLimit = settledWithLimit;
12543
+ exports.sortCharacterEntriesForDisplay = sortCharacterEntriesForDisplay;
12471
12544
  exports.sortListItems = sortListItems;
12545
+ exports.sourceRefKey = sourceRefKey;
12472
12546
  exports.spliceDelimitedRows = spliceDelimitedRows;
12473
12547
  exports.splitByLoopDelimiter = splitByLoopDelimiter;
12474
12548
  exports.splitGeneratedItems = splitGeneratedItems;