@character-foundry/character-foundry 0.1.8 → 0.1.9-dev.1765932375

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.
Files changed (71) hide show
  1. package/dist/app-framework.cjs +291 -95
  2. package/dist/app-framework.cjs.map +1 -1
  3. package/dist/app-framework.d.cts +1 -1
  4. package/dist/app-framework.d.ts +1 -1
  5. package/dist/app-framework.js +292 -96
  6. package/dist/app-framework.js.map +1 -1
  7. package/dist/charx.cjs +44 -23
  8. package/dist/charx.cjs.map +1 -1
  9. package/dist/charx.d.cts +368 -207
  10. package/dist/charx.d.ts +368 -207
  11. package/dist/charx.js +44 -23
  12. package/dist/charx.js.map +1 -1
  13. package/dist/exporter.cjs +27 -22
  14. package/dist/exporter.cjs.map +1 -1
  15. package/dist/exporter.d.cts +368 -207
  16. package/dist/exporter.d.ts +368 -207
  17. package/dist/exporter.js +27 -22
  18. package/dist/exporter.js.map +1 -1
  19. package/dist/federation.cjs +16 -4
  20. package/dist/federation.cjs.map +1 -1
  21. package/dist/federation.d.cts +368 -207
  22. package/dist/federation.d.ts +368 -207
  23. package/dist/federation.js +16 -4
  24. package/dist/federation.js.map +1 -1
  25. package/dist/image-utils.cjs.map +1 -1
  26. package/dist/image-utils.d.cts +12 -0
  27. package/dist/image-utils.d.ts +12 -0
  28. package/dist/image-utils.js.map +1 -1
  29. package/dist/index.cjs +102 -54
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +708 -423
  32. package/dist/index.d.ts +708 -423
  33. package/dist/index.js +102 -54
  34. package/dist/index.js.map +1 -1
  35. package/dist/loader.cjs +102 -54
  36. package/dist/loader.cjs.map +1 -1
  37. package/dist/loader.d.cts +564 -318
  38. package/dist/loader.d.ts +564 -318
  39. package/dist/loader.js +102 -54
  40. package/dist/loader.js.map +1 -1
  41. package/dist/lorebook.cjs +5 -5
  42. package/dist/lorebook.cjs.map +1 -1
  43. package/dist/lorebook.d.cts +674 -381
  44. package/dist/lorebook.d.ts +674 -381
  45. package/dist/lorebook.js +5 -5
  46. package/dist/lorebook.js.map +1 -1
  47. package/dist/normalizer.cjs +33 -23
  48. package/dist/normalizer.cjs.map +1 -1
  49. package/dist/normalizer.d.cts +896 -560
  50. package/dist/normalizer.d.ts +896 -560
  51. package/dist/normalizer.js +33 -23
  52. package/dist/normalizer.js.map +1 -1
  53. package/dist/png.cjs +27 -22
  54. package/dist/png.cjs.map +1 -1
  55. package/dist/png.d.cts +512 -312
  56. package/dist/png.d.ts +512 -312
  57. package/dist/png.js +27 -22
  58. package/dist/png.js.map +1 -1
  59. package/dist/schemas.cjs +27 -22
  60. package/dist/schemas.cjs.map +1 -1
  61. package/dist/schemas.d.cts +1444 -896
  62. package/dist/schemas.d.ts +1444 -896
  63. package/dist/schemas.js +27 -22
  64. package/dist/schemas.js.map +1 -1
  65. package/dist/voxta.cjs +44 -23
  66. package/dist/voxta.cjs.map +1 -1
  67. package/dist/voxta.d.cts +564 -318
  68. package/dist/voxta.d.ts +564 -318
  69. package/dist/voxta.js +44 -23
  70. package/dist/voxta.js.map +1 -1
  71. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -104,7 +104,23 @@ function streamingUnzipSync(data, limits = DEFAULT_ZIP_LIMITS) {
104
104
  if (unsafePathHandling === "warn" && limits.onUnsafePath) {
105
105
  limits.onUnsafePath(file.name, reason);
106
106
  }
107
- file.ondata = () => {
107
+ file.ondata = (err, chunk, _final) => {
108
+ if (error) return;
109
+ if (err) {
110
+ error = err;
111
+ return;
112
+ }
113
+ if (chunk && chunk.length > 0) {
114
+ totalBytes += chunk.length;
115
+ if (totalBytes > limits.maxTotalSize) {
116
+ error = new ZipPreflightError(
117
+ `Total actual size ${totalBytes} exceeds limit ${limits.maxTotalSize}`,
118
+ totalBytes,
119
+ limits.maxTotalSize
120
+ );
121
+ file.terminate();
122
+ }
123
+ }
108
124
  };
109
125
  file.start();
110
126
  return;
@@ -564,22 +580,24 @@ var ExtractedAssetSchema = z.object({
564
580
  mimeType: z.string()
565
581
  });
566
582
  var CCv2LorebookEntrySchema = z2.object({
567
- keys: z2.array(z2.string()),
583
+ keys: z2.array(z2.string()).optional(),
584
+ // Some tools use 'key' instead
568
585
  content: z2.string(),
569
- enabled: z2.boolean(),
570
- insertion_order: z2.number().int(),
571
- // Optional fields
586
+ enabled: z2.boolean().default(true),
587
+ // Default to enabled if missing
588
+ insertion_order: z2.number().int().default(0),
589
+ // Optional fields - be lenient with nulls since wild data has them
572
590
  extensions: z2.record(z2.unknown()).optional(),
573
- case_sensitive: z2.boolean().optional(),
591
+ case_sensitive: z2.boolean().nullable().optional(),
574
592
  name: z2.string().optional(),
575
593
  priority: z2.number().int().optional(),
576
594
  id: z2.number().int().optional(),
577
595
  comment: z2.string().optional(),
578
- selective: z2.boolean().optional(),
596
+ selective: z2.boolean().nullable().optional(),
579
597
  secondary_keys: z2.array(z2.string()).optional(),
580
- constant: z2.boolean().optional(),
581
- position: z2.enum(["before_char", "after_char"]).optional()
582
- });
598
+ constant: z2.boolean().nullable().optional(),
599
+ position: z2.union([z2.enum(["before_char", "after_char"]), z2.number().int()]).nullable().optional()
600
+ }).passthrough();
583
601
  var CCv2CharacterBookSchema = z2.object({
584
602
  name: z2.string().optional(),
585
603
  description: z2.string().optional(),
@@ -627,31 +645,34 @@ function getV2Data(card) {
627
645
  return card;
628
646
  }
629
647
  var CCv3LorebookEntrySchema = z3.object({
630
- keys: z3.array(z3.string()),
648
+ keys: z3.array(z3.string()).optional(),
649
+ // Some tools use 'key' instead
631
650
  content: z3.string(),
632
- enabled: z3.boolean(),
633
- insertion_order: z3.number().int(),
634
- // Optional fields
635
- case_sensitive: z3.boolean().optional(),
651
+ enabled: z3.boolean().default(true),
652
+ // Default to enabled if missing
653
+ insertion_order: z3.number().int().default(0),
654
+ // Optional fields - be lenient with nulls since wild data has them
655
+ case_sensitive: z3.boolean().nullable().optional(),
636
656
  name: z3.string().optional(),
637
657
  priority: z3.number().int().optional(),
638
658
  id: z3.number().int().optional(),
639
659
  comment: z3.string().optional(),
640
- selective: z3.boolean().optional(),
660
+ selective: z3.boolean().nullable().optional(),
641
661
  secondary_keys: z3.array(z3.string()).optional(),
642
- constant: z3.boolean().optional(),
643
- position: z3.enum(["before_char", "after_char"]).optional(),
662
+ constant: z3.boolean().nullable().optional(),
663
+ position: z3.union([z3.enum(["before_char", "after_char"]), z3.number().int()]).nullable().optional(),
644
664
  extensions: z3.record(z3.unknown()).optional(),
645
- // v3 specific
665
+ // v3 specific - also lenient with types since SillyTavern uses numbers for enums
646
666
  automation_id: z3.string().optional(),
647
- role: z3.enum(["system", "user", "assistant"]).optional(),
667
+ role: z3.union([z3.enum(["system", "user", "assistant"]), z3.number().int()]).nullable().optional(),
648
668
  group: z3.string().optional(),
649
669
  scan_frequency: z3.number().int().nonnegative().optional(),
650
- probability: z3.number().min(0).max(1).optional(),
670
+ probability: z3.number().min(0).max(100).optional(),
671
+ // Some tools use 0-100 instead of 0-1
651
672
  use_regex: z3.boolean().optional(),
652
673
  depth: z3.number().int().nonnegative().optional(),
653
- selective_logic: z3.enum(["AND", "NOT"]).optional()
654
- });
674
+ selective_logic: z3.union([z3.enum(["AND", "NOT"]), z3.number().int()]).optional()
675
+ }).passthrough();
655
676
  var CCv3CharacterBookSchema = z3.object({
656
677
  name: z3.string().optional(),
657
678
  description: z3.string().optional(),
@@ -8329,6 +8350,11 @@ var DELTA_MAX_TOTAL_SIZE = 500 * 1024 * 1024;
8329
8350
  var DELTA_MAX_FILE_SIZE = 50 * 1024 * 1024;
8330
8351
 
8331
8352
  // ../normalizer/dist/index.js
8353
+ function normalizePosition(position) {
8354
+ if (position === void 0 || position === null) return "before_char";
8355
+ if (typeof position === "string") return position;
8356
+ return position;
8357
+ }
8332
8358
  function convertLorebookEntry(entry, index) {
8333
8359
  return {
8334
8360
  keys: entry.keys || [],
@@ -8344,7 +8370,7 @@ function convertLorebookEntry(entry, index) {
8344
8370
  selective: entry.selective ?? false,
8345
8371
  secondary_keys: entry.secondary_keys || [],
8346
8372
  constant: entry.constant ?? false,
8347
- position: entry.position || "before_char"
8373
+ position: normalizePosition(entry.position)
8348
8374
  };
8349
8375
  }
8350
8376
  function convertCharacterBook(book) {
@@ -8507,6 +8533,43 @@ var DEFAULT_OPTIONS3 = {
8507
8533
  maxTotalSize: 500 * 1024 * 1024,
8508
8534
  extractAssets: true
8509
8535
  };
8536
+ var ASSET_PREFIX_VARIANTS = [
8537
+ { prefix: "__asset:", format: "CCv3 (SillyTavern)" },
8538
+ { prefix: "asset:", format: "CCv2/CCv3 common" },
8539
+ { prefix: "pngchunk:", format: "Explicit PNG chunk" },
8540
+ { prefix: "chara-ext-asset_:", format: "RisuAI (with colon)" },
8541
+ { prefix: "chara-ext-asset_", format: "RisuAI" },
8542
+ { prefix: "__asset_", format: "Legacy underscore variant" }
8543
+ ];
8544
+ function isChunkReference(uri) {
8545
+ return ASSET_PREFIX_VARIANTS.some(({ prefix }) => uri.startsWith(prefix)) || !uri.includes(":");
8546
+ }
8547
+ function stripAssetPrefix(uri) {
8548
+ for (const { prefix } of ASSET_PREFIX_VARIANTS) {
8549
+ if (uri.startsWith(prefix)) {
8550
+ return uri.substring(prefix.length);
8551
+ }
8552
+ }
8553
+ return uri;
8554
+ }
8555
+ function generateChunkKeyCandidates(assetId, originalUri) {
8556
+ return [
8557
+ assetId,
8558
+ // Plain ID: "0"
8559
+ originalUri,
8560
+ // Original URI: "__asset:0"
8561
+ `asset:${assetId}`,
8562
+ // Common format
8563
+ `__asset:${assetId}`,
8564
+ // CCv3 format
8565
+ `__asset_${assetId}`,
8566
+ // Legacy underscore variant
8567
+ `chara-ext-asset_${assetId}`,
8568
+ // RisuAI format
8569
+ `chara-ext-asset_:${assetId}`
8570
+ // RisuAI format with colon
8571
+ ];
8572
+ }
8510
8573
  function estimateBase64DecodedSize(base64Length) {
8511
8574
  return Math.ceil(base64Length * 0.75);
8512
8575
  }
@@ -8574,39 +8637,22 @@ function parsePng(data, options) {
8574
8637
  if (extracted.extraChunks && options.extractAssets && card.data.assets) {
8575
8638
  const usedChunks = /* @__PURE__ */ new Set();
8576
8639
  const chunkMap = /* @__PURE__ */ new Map();
8640
+ const risuIndexPrefixes = ASSET_PREFIX_VARIANTS.filter((v) => v.prefix.startsWith("chara-ext-asset_"));
8577
8641
  for (const chunk of extracted.extraChunks) {
8578
8642
  chunkMap.set(chunk.keyword, chunk);
8579
- if (chunk.keyword.startsWith("chara-ext-asset_")) {
8580
- const suffix = chunk.keyword.replace("chara-ext-asset_", "");
8581
- chunkMap.set(suffix, chunk);
8582
- if (suffix.startsWith(":")) {
8583
- chunkMap.set(suffix.substring(1), chunk);
8643
+ for (const { prefix } of risuIndexPrefixes) {
8644
+ if (chunk.keyword.startsWith(prefix)) {
8645
+ const suffix = chunk.keyword.substring(prefix.length);
8646
+ chunkMap.set(suffix, chunk);
8647
+ break;
8584
8648
  }
8585
8649
  }
8586
8650
  }
8587
8651
  for (const descriptor of card.data.assets) {
8588
8652
  if (!descriptor.uri) continue;
8589
- if (descriptor.uri.startsWith("__asset:") || descriptor.uri.startsWith("asset:") || descriptor.uri.startsWith("pngchunk:") || !descriptor.uri.includes(":")) {
8590
- let assetId = descriptor.uri;
8591
- if (assetId.startsWith("__asset:")) assetId = assetId.substring(8);
8592
- else if (assetId.startsWith("asset:")) assetId = assetId.substring(6);
8593
- else if (assetId.startsWith("pngchunk:")) assetId = assetId.substring(9);
8594
- const candidates = [
8595
- assetId,
8596
- // "0"
8597
- descriptor.uri,
8598
- // "__asset:0"
8599
- `asset:${assetId}`,
8600
- // "asset:0"
8601
- `__asset:${assetId}`,
8602
- // "__asset:0"
8603
- `__asset_${assetId}`,
8604
- // "__asset_0"
8605
- `chara-ext-asset_${assetId}`,
8606
- // "chara-ext-asset_0"
8607
- `chara-ext-asset_:${assetId}`
8608
- // "chara-ext-asset_:0"
8609
- ];
8653
+ if (isChunkReference(descriptor.uri)) {
8654
+ const assetId = stripAssetPrefix(descriptor.uri);
8655
+ const candidates = generateChunkKeyCandidates(assetId, descriptor.uri);
8610
8656
  let chunk;
8611
8657
  for (const candidate of candidates) {
8612
8658
  chunk = chunkMap.get(candidate);
@@ -8653,13 +8699,15 @@ function parsePng(data, options) {
8653
8699
  }
8654
8700
  }
8655
8701
  }
8702
+ const risuPrefixes = ASSET_PREFIX_VARIANTS.filter((v) => v.prefix.startsWith("chara-ext-asset_"));
8656
8703
  for (const chunk of extracted.extraChunks) {
8657
8704
  if (!usedChunks.has(chunk.keyword)) {
8658
8705
  let assetId = null;
8659
- if (chunk.keyword.startsWith("chara-ext-asset_:")) {
8660
- assetId = chunk.keyword.substring("chara-ext-asset_:".length);
8661
- } else if (chunk.keyword.startsWith("chara-ext-asset_")) {
8662
- assetId = chunk.keyword.substring("chara-ext-asset_".length);
8706
+ for (const { prefix } of risuPrefixes) {
8707
+ if (chunk.keyword.startsWith(prefix)) {
8708
+ assetId = chunk.keyword.substring(prefix.length);
8709
+ break;
8710
+ }
8663
8711
  }
8664
8712
  if (assetId) {
8665
8713
  try {