@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/loader.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;
@@ -441,22 +457,24 @@ var ExtractedAssetSchema = z.object({
441
457
  mimeType: z.string()
442
458
  });
443
459
  var CCv2LorebookEntrySchema = z2.object({
444
- keys: z2.array(z2.string()),
460
+ keys: z2.array(z2.string()).optional(),
461
+ // Some tools use 'key' instead
445
462
  content: z2.string(),
446
- enabled: z2.boolean(),
447
- insertion_order: z2.number().int(),
448
- // Optional fields
463
+ enabled: z2.boolean().default(true),
464
+ // Default to enabled if missing
465
+ insertion_order: z2.number().int().default(0),
466
+ // Optional fields - be lenient with nulls since wild data has them
449
467
  extensions: z2.record(z2.unknown()).optional(),
450
- case_sensitive: z2.boolean().optional(),
468
+ case_sensitive: z2.boolean().nullable().optional(),
451
469
  name: z2.string().optional(),
452
470
  priority: z2.number().int().optional(),
453
471
  id: z2.number().int().optional(),
454
472
  comment: z2.string().optional(),
455
- selective: z2.boolean().optional(),
473
+ selective: z2.boolean().nullable().optional(),
456
474
  secondary_keys: z2.array(z2.string()).optional(),
457
- constant: z2.boolean().optional(),
458
- position: z2.enum(["before_char", "after_char"]).optional()
459
- });
475
+ constant: z2.boolean().nullable().optional(),
476
+ position: z2.union([z2.enum(["before_char", "after_char"]), z2.number().int()]).nullable().optional()
477
+ }).passthrough();
460
478
  var CCv2CharacterBookSchema = z2.object({
461
479
  name: z2.string().optional(),
462
480
  description: z2.string().optional(),
@@ -504,31 +522,34 @@ function getV2Data(card) {
504
522
  return card;
505
523
  }
506
524
  var CCv3LorebookEntrySchema = z3.object({
507
- keys: z3.array(z3.string()),
525
+ keys: z3.array(z3.string()).optional(),
526
+ // Some tools use 'key' instead
508
527
  content: z3.string(),
509
- enabled: z3.boolean(),
510
- insertion_order: z3.number().int(),
511
- // Optional fields
512
- case_sensitive: z3.boolean().optional(),
528
+ enabled: z3.boolean().default(true),
529
+ // Default to enabled if missing
530
+ insertion_order: z3.number().int().default(0),
531
+ // Optional fields - be lenient with nulls since wild data has them
532
+ case_sensitive: z3.boolean().nullable().optional(),
513
533
  name: z3.string().optional(),
514
534
  priority: z3.number().int().optional(),
515
535
  id: z3.number().int().optional(),
516
536
  comment: z3.string().optional(),
517
- selective: z3.boolean().optional(),
537
+ selective: z3.boolean().nullable().optional(),
518
538
  secondary_keys: z3.array(z3.string()).optional(),
519
- constant: z3.boolean().optional(),
520
- position: z3.enum(["before_char", "after_char"]).optional(),
539
+ constant: z3.boolean().nullable().optional(),
540
+ position: z3.union([z3.enum(["before_char", "after_char"]), z3.number().int()]).nullable().optional(),
521
541
  extensions: z3.record(z3.unknown()).optional(),
522
- // v3 specific
542
+ // v3 specific - also lenient with types since SillyTavern uses numbers for enums
523
543
  automation_id: z3.string().optional(),
524
- role: z3.enum(["system", "user", "assistant"]).optional(),
544
+ role: z3.union([z3.enum(["system", "user", "assistant"]), z3.number().int()]).nullable().optional(),
525
545
  group: z3.string().optional(),
526
546
  scan_frequency: z3.number().int().nonnegative().optional(),
527
- probability: z3.number().min(0).max(1).optional(),
547
+ probability: z3.number().min(0).max(100).optional(),
548
+ // Some tools use 0-100 instead of 0-1
528
549
  use_regex: z3.boolean().optional(),
529
550
  depth: z3.number().int().nonnegative().optional(),
530
- selective_logic: z3.enum(["AND", "NOT"]).optional()
531
- });
551
+ selective_logic: z3.union([z3.enum(["AND", "NOT"]), z3.number().int()]).optional()
552
+ }).passthrough();
532
553
  var CCv3CharacterBookSchema = z3.object({
533
554
  name: z3.string().optional(),
534
555
  description: z3.string().optional(),
@@ -7725,6 +7746,11 @@ var DELTA_MAX_TOTAL_SIZE = 500 * 1024 * 1024;
7725
7746
  var DELTA_MAX_FILE_SIZE = 50 * 1024 * 1024;
7726
7747
 
7727
7748
  // ../normalizer/dist/index.js
7749
+ function normalizePosition(position) {
7750
+ if (position === void 0 || position === null) return "before_char";
7751
+ if (typeof position === "string") return position;
7752
+ return position;
7753
+ }
7728
7754
  function convertLorebookEntry(entry, index) {
7729
7755
  return {
7730
7756
  keys: entry.keys || [],
@@ -7740,7 +7766,7 @@ function convertLorebookEntry(entry, index) {
7740
7766
  selective: entry.selective ?? false,
7741
7767
  secondary_keys: entry.secondary_keys || [],
7742
7768
  constant: entry.constant ?? false,
7743
- position: entry.position || "before_char"
7769
+ position: normalizePosition(entry.position)
7744
7770
  };
7745
7771
  }
7746
7772
  function convertCharacterBook(book) {
@@ -8152,6 +8178,43 @@ var DEFAULT_OPTIONS3 = {
8152
8178
  maxTotalSize: 500 * 1024 * 1024,
8153
8179
  extractAssets: true
8154
8180
  };
8181
+ var ASSET_PREFIX_VARIANTS = [
8182
+ { prefix: "__asset:", format: "CCv3 (SillyTavern)" },
8183
+ { prefix: "asset:", format: "CCv2/CCv3 common" },
8184
+ { prefix: "pngchunk:", format: "Explicit PNG chunk" },
8185
+ { prefix: "chara-ext-asset_:", format: "RisuAI (with colon)" },
8186
+ { prefix: "chara-ext-asset_", format: "RisuAI" },
8187
+ { prefix: "__asset_", format: "Legacy underscore variant" }
8188
+ ];
8189
+ function isChunkReference(uri) {
8190
+ return ASSET_PREFIX_VARIANTS.some(({ prefix }) => uri.startsWith(prefix)) || !uri.includes(":");
8191
+ }
8192
+ function stripAssetPrefix(uri) {
8193
+ for (const { prefix } of ASSET_PREFIX_VARIANTS) {
8194
+ if (uri.startsWith(prefix)) {
8195
+ return uri.substring(prefix.length);
8196
+ }
8197
+ }
8198
+ return uri;
8199
+ }
8200
+ function generateChunkKeyCandidates(assetId, originalUri) {
8201
+ return [
8202
+ assetId,
8203
+ // Plain ID: "0"
8204
+ originalUri,
8205
+ // Original URI: "__asset:0"
8206
+ `asset:${assetId}`,
8207
+ // Common format
8208
+ `__asset:${assetId}`,
8209
+ // CCv3 format
8210
+ `__asset_${assetId}`,
8211
+ // Legacy underscore variant
8212
+ `chara-ext-asset_${assetId}`,
8213
+ // RisuAI format
8214
+ `chara-ext-asset_:${assetId}`
8215
+ // RisuAI format with colon
8216
+ ];
8217
+ }
8155
8218
  function estimateBase64DecodedSize(base64Length) {
8156
8219
  return Math.ceil(base64Length * 0.75);
8157
8220
  }
@@ -8219,39 +8282,22 @@ function parsePng(data, options) {
8219
8282
  if (extracted.extraChunks && options.extractAssets && card.data.assets) {
8220
8283
  const usedChunks = /* @__PURE__ */ new Set();
8221
8284
  const chunkMap = /* @__PURE__ */ new Map();
8285
+ const risuIndexPrefixes = ASSET_PREFIX_VARIANTS.filter((v) => v.prefix.startsWith("chara-ext-asset_"));
8222
8286
  for (const chunk of extracted.extraChunks) {
8223
8287
  chunkMap.set(chunk.keyword, chunk);
8224
- if (chunk.keyword.startsWith("chara-ext-asset_")) {
8225
- const suffix = chunk.keyword.replace("chara-ext-asset_", "");
8226
- chunkMap.set(suffix, chunk);
8227
- if (suffix.startsWith(":")) {
8228
- chunkMap.set(suffix.substring(1), chunk);
8288
+ for (const { prefix } of risuIndexPrefixes) {
8289
+ if (chunk.keyword.startsWith(prefix)) {
8290
+ const suffix = chunk.keyword.substring(prefix.length);
8291
+ chunkMap.set(suffix, chunk);
8292
+ break;
8229
8293
  }
8230
8294
  }
8231
8295
  }
8232
8296
  for (const descriptor of card.data.assets) {
8233
8297
  if (!descriptor.uri) continue;
8234
- if (descriptor.uri.startsWith("__asset:") || descriptor.uri.startsWith("asset:") || descriptor.uri.startsWith("pngchunk:") || !descriptor.uri.includes(":")) {
8235
- let assetId = descriptor.uri;
8236
- if (assetId.startsWith("__asset:")) assetId = assetId.substring(8);
8237
- else if (assetId.startsWith("asset:")) assetId = assetId.substring(6);
8238
- else if (assetId.startsWith("pngchunk:")) assetId = assetId.substring(9);
8239
- const candidates = [
8240
- assetId,
8241
- // "0"
8242
- descriptor.uri,
8243
- // "__asset:0"
8244
- `asset:${assetId}`,
8245
- // "asset:0"
8246
- `__asset:${assetId}`,
8247
- // "__asset:0"
8248
- `__asset_${assetId}`,
8249
- // "__asset_0"
8250
- `chara-ext-asset_${assetId}`,
8251
- // "chara-ext-asset_0"
8252
- `chara-ext-asset_:${assetId}`
8253
- // "chara-ext-asset_:0"
8254
- ];
8298
+ if (isChunkReference(descriptor.uri)) {
8299
+ const assetId = stripAssetPrefix(descriptor.uri);
8300
+ const candidates = generateChunkKeyCandidates(assetId, descriptor.uri);
8255
8301
  let chunk;
8256
8302
  for (const candidate of candidates) {
8257
8303
  chunk = chunkMap.get(candidate);
@@ -8298,13 +8344,15 @@ function parsePng(data, options) {
8298
8344
  }
8299
8345
  }
8300
8346
  }
8347
+ const risuPrefixes = ASSET_PREFIX_VARIANTS.filter((v) => v.prefix.startsWith("chara-ext-asset_"));
8301
8348
  for (const chunk of extracted.extraChunks) {
8302
8349
  if (!usedChunks.has(chunk.keyword)) {
8303
8350
  let assetId = null;
8304
- if (chunk.keyword.startsWith("chara-ext-asset_:")) {
8305
- assetId = chunk.keyword.substring("chara-ext-asset_:".length);
8306
- } else if (chunk.keyword.startsWith("chara-ext-asset_")) {
8307
- assetId = chunk.keyword.substring("chara-ext-asset_".length);
8351
+ for (const { prefix } of risuPrefixes) {
8352
+ if (chunk.keyword.startsWith(prefix)) {
8353
+ assetId = chunk.keyword.substring(prefix.length);
8354
+ break;
8355
+ }
8308
8356
  }
8309
8357
  if (assetId) {
8310
8358
  try {