@character-foundry/character-foundry 0.4.3-dev.1766103111 → 0.4.3
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/charx.cjs +52 -85
- package/dist/charx.cjs.map +1 -1
- package/dist/charx.d.cts +22 -22
- package/dist/charx.d.ts +22 -22
- package/dist/charx.js +52 -85
- package/dist/charx.js.map +1 -1
- package/dist/exporter.cjs +54 -104
- package/dist/exporter.cjs.map +1 -1
- package/dist/exporter.d.cts +19 -19
- package/dist/exporter.d.ts +19 -19
- package/dist/exporter.js +54 -104
- package/dist/exporter.js.map +1 -1
- package/dist/federation.cjs +36 -104
- package/dist/federation.cjs.map +1 -1
- package/dist/federation.d.cts +19 -54
- package/dist/federation.d.ts +19 -54
- package/dist/federation.js +36 -104
- package/dist/federation.js.map +1 -1
- package/dist/index.cjs +54 -104
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -29
- package/dist/index.d.ts +29 -29
- package/dist/index.js +54 -104
- package/dist/index.js.map +1 -1
- package/dist/loader.cjs +31 -171
- package/dist/loader.cjs.map +1 -1
- package/dist/loader.d.cts +23 -37
- package/dist/loader.d.ts +23 -37
- package/dist/loader.js +31 -171
- package/dist/loader.js.map +1 -1
- package/dist/lorebook.d.cts +23 -23
- package/dist/lorebook.d.ts +23 -23
- package/dist/normalizer.cjs +18 -72
- package/dist/normalizer.cjs.map +1 -1
- package/dist/normalizer.d.cts +37 -37
- package/dist/normalizer.d.ts +37 -37
- package/dist/normalizer.js +18 -72
- package/dist/normalizer.js.map +1 -1
- package/dist/png.cjs +18 -72
- package/dist/png.cjs.map +1 -1
- package/dist/png.d.cts +25 -25
- package/dist/png.d.ts +25 -25
- package/dist/png.js +18 -72
- package/dist/png.js.map +1 -1
- package/dist/schemas.cjs +23 -80
- package/dist/schemas.cjs.map +1 -1
- package/dist/schemas.d.cts +67 -85
- package/dist/schemas.d.ts +67 -85
- package/dist/schemas.js +23 -80
- package/dist/schemas.js.map +1 -1
- package/dist/voxta.cjs +20 -91
- package/dist/voxta.cjs.map +1 -1
- package/dist/voxta.d.cts +23 -23
- package/dist/voxta.d.ts +23 -23
- package/dist/voxta.js +20 -91
- package/dist/voxta.js.map +1 -1
- package/package.json +5 -5
package/dist/loader.cjs
CHANGED
|
@@ -21,7 +21,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var loader_exports = {};
|
|
22
22
|
__export(loader_exports, {
|
|
23
23
|
computeContentHash: () => computeContentHash,
|
|
24
|
-
computeContentHashV2: () => computeContentHashV2,
|
|
25
24
|
detectFormat: () => detectFormat,
|
|
26
25
|
getContainerFormat: () => getContainerFormat,
|
|
27
26
|
mightBeCard: () => mightBeCard,
|
|
@@ -444,58 +443,6 @@ var import_zod = require("zod");
|
|
|
444
443
|
var import_zod2 = require("zod");
|
|
445
444
|
var import_zod3 = require("zod");
|
|
446
445
|
var import_zod4 = require("zod");
|
|
447
|
-
function preprocessTimestamp(val) {
|
|
448
|
-
if (val === null || val === void 0) return void 0;
|
|
449
|
-
let num;
|
|
450
|
-
if (typeof val === "number") {
|
|
451
|
-
num = val;
|
|
452
|
-
} else if (typeof val === "string") {
|
|
453
|
-
const trimmed = val.trim();
|
|
454
|
-
if (!trimmed) return void 0;
|
|
455
|
-
const parsed = Number(trimmed);
|
|
456
|
-
if (!isNaN(parsed)) {
|
|
457
|
-
num = parsed;
|
|
458
|
-
} else {
|
|
459
|
-
const date = new Date(trimmed);
|
|
460
|
-
if (isNaN(date.getTime())) return void 0;
|
|
461
|
-
num = Math.floor(date.getTime() / 1e3);
|
|
462
|
-
}
|
|
463
|
-
} else {
|
|
464
|
-
return void 0;
|
|
465
|
-
}
|
|
466
|
-
if (num > 1e10) {
|
|
467
|
-
num = Math.floor(num / 1e3);
|
|
468
|
-
}
|
|
469
|
-
if (num < 0) return void 0;
|
|
470
|
-
return num;
|
|
471
|
-
}
|
|
472
|
-
function preprocessNumeric(val) {
|
|
473
|
-
if (val === null || val === void 0) return void 0;
|
|
474
|
-
if (typeof val === "number") {
|
|
475
|
-
return isNaN(val) ? void 0 : val;
|
|
476
|
-
}
|
|
477
|
-
if (typeof val === "string") {
|
|
478
|
-
const trimmed = val.trim();
|
|
479
|
-
if (!trimmed) return void 0;
|
|
480
|
-
const parsed = Number(trimmed);
|
|
481
|
-
return isNaN(parsed) ? void 0 : parsed;
|
|
482
|
-
}
|
|
483
|
-
return void 0;
|
|
484
|
-
}
|
|
485
|
-
var KNOWN_ASSET_TYPES = /* @__PURE__ */ new Set([
|
|
486
|
-
"icon",
|
|
487
|
-
"background",
|
|
488
|
-
"emotion",
|
|
489
|
-
"user_icon",
|
|
490
|
-
"sound",
|
|
491
|
-
"video",
|
|
492
|
-
"custom",
|
|
493
|
-
"x-risu-asset"
|
|
494
|
-
]);
|
|
495
|
-
function preprocessAssetType(val) {
|
|
496
|
-
if (typeof val !== "string") return "custom";
|
|
497
|
-
return KNOWN_ASSET_TYPES.has(val) ? val : "custom";
|
|
498
|
-
}
|
|
499
446
|
var ISO8601Schema = import_zod.z.string().datetime();
|
|
500
447
|
var UUIDSchema = import_zod.z.string().uuid();
|
|
501
448
|
var SpecSchema = import_zod.z.enum(["v2", "v3"]);
|
|
@@ -518,19 +465,16 @@ var SourceFormatSchema = import_zod.z.enum([
|
|
|
518
465
|
// VoxPkg format
|
|
519
466
|
]);
|
|
520
467
|
var OriginalShapeSchema = import_zod.z.enum(["wrapped", "unwrapped", "legacy"]);
|
|
521
|
-
var AssetTypeSchema = import_zod.z.
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
"x-risu-asset"
|
|
532
|
-
])
|
|
533
|
-
);
|
|
468
|
+
var AssetTypeSchema = import_zod.z.enum([
|
|
469
|
+
"icon",
|
|
470
|
+
"background",
|
|
471
|
+
"emotion",
|
|
472
|
+
"user_icon",
|
|
473
|
+
"sound",
|
|
474
|
+
"video",
|
|
475
|
+
"custom",
|
|
476
|
+
"x-risu-asset"
|
|
477
|
+
]);
|
|
534
478
|
var AssetDescriptorSchema = import_zod.z.object({
|
|
535
479
|
type: AssetTypeSchema,
|
|
536
480
|
uri: import_zod.z.string(),
|
|
@@ -564,8 +508,8 @@ var CCv2LorebookEntrySchema = import_zod2.z.object({
|
|
|
564
508
|
var CCv2CharacterBookSchema = import_zod2.z.object({
|
|
565
509
|
name: import_zod2.z.string().optional(),
|
|
566
510
|
description: import_zod2.z.string().optional(),
|
|
567
|
-
scan_depth: import_zod2.z.
|
|
568
|
-
token_budget: import_zod2.z.
|
|
511
|
+
scan_depth: import_zod2.z.number().int().nonnegative().optional(),
|
|
512
|
+
token_budget: import_zod2.z.number().int().nonnegative().optional(),
|
|
569
513
|
recursive_scanning: import_zod2.z.boolean().optional(),
|
|
570
514
|
extensions: import_zod2.z.record(import_zod2.z.unknown()).optional(),
|
|
571
515
|
entries: import_zod2.z.array(CCv2LorebookEntrySchema)
|
|
@@ -639,8 +583,8 @@ var CCv3LorebookEntrySchema = import_zod3.z.object({
|
|
|
639
583
|
var CCv3CharacterBookSchema = import_zod3.z.object({
|
|
640
584
|
name: import_zod3.z.string().optional(),
|
|
641
585
|
description: import_zod3.z.string().optional(),
|
|
642
|
-
scan_depth: import_zod3.z.
|
|
643
|
-
token_budget: import_zod3.z.
|
|
586
|
+
scan_depth: import_zod3.z.number().int().nonnegative().optional(),
|
|
587
|
+
token_budget: import_zod3.z.number().int().nonnegative().optional(),
|
|
644
588
|
recursive_scanning: import_zod3.z.boolean().optional(),
|
|
645
589
|
extensions: import_zod3.z.record(import_zod3.z.unknown()).optional(),
|
|
646
590
|
entries: import_zod3.z.array(CCv3LorebookEntrySchema)
|
|
@@ -672,9 +616,10 @@ var CCv3DataInnerSchema = import_zod3.z.object({
|
|
|
672
616
|
nickname: import_zod3.z.string().optional(),
|
|
673
617
|
creator_notes_multilingual: import_zod3.z.record(import_zod3.z.string()).optional(),
|
|
674
618
|
source: import_zod3.z.array(import_zod3.z.string()).optional(),
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
modification_date: import_zod3.z.
|
|
619
|
+
creation_date: import_zod3.z.number().int().nonnegative().optional(),
|
|
620
|
+
// Unix timestamp in seconds
|
|
621
|
+
modification_date: import_zod3.z.number().int().nonnegative().optional()
|
|
622
|
+
// Unix timestamp in seconds
|
|
678
623
|
});
|
|
679
624
|
var CCv3DataSchema = import_zod3.z.object({
|
|
680
625
|
spec: import_zod3.z.literal("chara_card_v3"),
|
|
@@ -8782,7 +8727,7 @@ function defaultTokenCounter(_card) {
|
|
|
8782
8727
|
total: 0
|
|
8783
8728
|
};
|
|
8784
8729
|
}
|
|
8785
|
-
function
|
|
8730
|
+
function getCanonicalContent(card) {
|
|
8786
8731
|
const normalized = {
|
|
8787
8732
|
name: card.data.name,
|
|
8788
8733
|
description: card.data.description || "",
|
|
@@ -8804,69 +8749,6 @@ function getCanonicalContentV1(card) {
|
|
|
8804
8749
|
};
|
|
8805
8750
|
return JSON.stringify(normalized, Object.keys(normalized).sort());
|
|
8806
8751
|
}
|
|
8807
|
-
function stableStringify(value) {
|
|
8808
|
-
if (value === null) return "null";
|
|
8809
|
-
switch (typeof value) {
|
|
8810
|
-
case "string":
|
|
8811
|
-
return JSON.stringify(value);
|
|
8812
|
-
case "number":
|
|
8813
|
-
return Number.isFinite(value) ? String(value) : "null";
|
|
8814
|
-
case "boolean":
|
|
8815
|
-
return value ? "true" : "false";
|
|
8816
|
-
case "bigint":
|
|
8817
|
-
return JSON.stringify(value.toString());
|
|
8818
|
-
case "undefined":
|
|
8819
|
-
case "function":
|
|
8820
|
-
case "symbol":
|
|
8821
|
-
return "null";
|
|
8822
|
-
case "object": {
|
|
8823
|
-
if (Array.isArray(value)) {
|
|
8824
|
-
const parts2 = value.map((item) => {
|
|
8825
|
-
if (item === void 0 || typeof item === "function" || typeof item === "symbol") {
|
|
8826
|
-
return "null";
|
|
8827
|
-
}
|
|
8828
|
-
return stableStringify(item);
|
|
8829
|
-
});
|
|
8830
|
-
return `[${parts2.join(",")}]`;
|
|
8831
|
-
}
|
|
8832
|
-
const obj = value;
|
|
8833
|
-
const keys = Object.keys(obj).sort();
|
|
8834
|
-
const parts = [];
|
|
8835
|
-
for (const key of keys) {
|
|
8836
|
-
const v = obj[key];
|
|
8837
|
-
if (v === void 0 || typeof v === "function" || typeof v === "symbol") {
|
|
8838
|
-
continue;
|
|
8839
|
-
}
|
|
8840
|
-
parts.push(`${JSON.stringify(key)}:${stableStringify(v)}`);
|
|
8841
|
-
}
|
|
8842
|
-
return `{${parts.join(",")}}`;
|
|
8843
|
-
}
|
|
8844
|
-
default:
|
|
8845
|
-
return "null";
|
|
8846
|
-
}
|
|
8847
|
-
}
|
|
8848
|
-
function getCanonicalContentV2(card) {
|
|
8849
|
-
const normalized = {
|
|
8850
|
-
name: card.data.name,
|
|
8851
|
-
description: card.data.description || "",
|
|
8852
|
-
personality: card.data.personality || "",
|
|
8853
|
-
scenario: card.data.scenario || "",
|
|
8854
|
-
first_mes: card.data.first_mes || "",
|
|
8855
|
-
mes_example: card.data.mes_example || "",
|
|
8856
|
-
system_prompt: card.data.system_prompt || "",
|
|
8857
|
-
post_history_instructions: card.data.post_history_instructions || "",
|
|
8858
|
-
alternate_greetings: card.data.alternate_greetings || [],
|
|
8859
|
-
character_book: card.data.character_book ? {
|
|
8860
|
-
entries: (card.data.character_book.entries || []).map((e) => ({
|
|
8861
|
-
keys: e.keys,
|
|
8862
|
-
content: e.content,
|
|
8863
|
-
enabled: e.enabled
|
|
8864
|
-
}))
|
|
8865
|
-
} : null,
|
|
8866
|
-
creator_notes: card.data.creator_notes || ""
|
|
8867
|
-
};
|
|
8868
|
-
return stableStringify(normalized);
|
|
8869
|
-
}
|
|
8870
8752
|
function isWithinTolerance(clientValue, computedValue, tolerance) {
|
|
8871
8753
|
if (clientValue === void 0) return false;
|
|
8872
8754
|
if (computedValue === 0) return clientValue === 0;
|
|
@@ -8887,18 +8769,15 @@ async function validateClientMetadata(clientMetadata, parseResult, options = {})
|
|
|
8887
8769
|
const warnings = [];
|
|
8888
8770
|
const errors = [];
|
|
8889
8771
|
const computedTokens = countTokens(card);
|
|
8890
|
-
const
|
|
8891
|
-
const
|
|
8892
|
-
const computedHashV1 = await computeHash(canonicalContentV1);
|
|
8893
|
-
const computedHashV2 = await computeHash(canonicalContentV2);
|
|
8772
|
+
const canonicalContent = getCanonicalContent(card);
|
|
8773
|
+
const computedHash = await computeHash(canonicalContent);
|
|
8894
8774
|
const entries = card.data.character_book?.entries || [];
|
|
8895
8775
|
const computedHasLorebook = entries.length > 0;
|
|
8896
8776
|
const computedLorebookCount = entries.length;
|
|
8897
8777
|
const authoritative = {
|
|
8898
8778
|
name: card.data.name,
|
|
8899
8779
|
tokens: computedTokens,
|
|
8900
|
-
contentHash:
|
|
8901
|
-
contentHashV2: computedHashV2,
|
|
8780
|
+
contentHash: computedHash,
|
|
8902
8781
|
hasLorebook: computedHasLorebook,
|
|
8903
8782
|
lorebookEntriesCount: computedLorebookCount
|
|
8904
8783
|
};
|
|
@@ -8910,27 +8789,21 @@ async function validateClientMetadata(clientMetadata, parseResult, options = {})
|
|
|
8910
8789
|
withinTolerance: false
|
|
8911
8790
|
});
|
|
8912
8791
|
}
|
|
8913
|
-
|
|
8914
|
-
const matchesV2 = clientMetadata.contentHash === computedHashV2;
|
|
8915
|
-
if (!matchesV1 && !matchesV2) {
|
|
8792
|
+
if (clientMetadata.contentHash !== computedHash) {
|
|
8916
8793
|
const disc = {
|
|
8917
8794
|
field: "contentHash",
|
|
8918
8795
|
clientValue: clientMetadata.contentHash,
|
|
8919
|
-
computedValue:
|
|
8796
|
+
computedValue: computedHash,
|
|
8920
8797
|
withinTolerance: false
|
|
8921
8798
|
};
|
|
8922
8799
|
discrepancies.push(disc);
|
|
8923
8800
|
if (allowHashMismatch) {
|
|
8924
8801
|
warnings.push(
|
|
8925
|
-
`Content hash mismatch: client=${clientMetadata.contentHash.substring(0, 8)}..., server
|
|
8802
|
+
`Content hash mismatch: client=${clientMetadata.contentHash.substring(0, 8)}..., server=${computedHash.substring(0, 8)}...`
|
|
8926
8803
|
);
|
|
8927
8804
|
} else {
|
|
8928
8805
|
errors.push("Content hash mismatch - possible tampering or encoding difference");
|
|
8929
8806
|
}
|
|
8930
|
-
} else if (matchesV1 && !matchesV2) {
|
|
8931
|
-
warnings.push(
|
|
8932
|
-
"Client contentHash matches legacy v1 canonicalization. Prefer authoritative.contentHashV2 for new storage."
|
|
8933
|
-
);
|
|
8934
8807
|
}
|
|
8935
8808
|
const tokenFields = [
|
|
8936
8809
|
"description",
|
|
@@ -9011,11 +8884,7 @@ async function validateClientMetadata(clientMetadata, parseResult, options = {})
|
|
|
9011
8884
|
};
|
|
9012
8885
|
}
|
|
9013
8886
|
async function computeContentHash(card) {
|
|
9014
|
-
const content =
|
|
9015
|
-
return sha256Hash(content);
|
|
9016
|
-
}
|
|
9017
|
-
async function computeContentHashV2(card) {
|
|
9018
|
-
const content = getCanonicalContentV2(card);
|
|
8887
|
+
const content = getCanonicalContent(card);
|
|
9019
8888
|
return sha256Hash(content);
|
|
9020
8889
|
}
|
|
9021
8890
|
function validateClientMetadataSync(clientMetadata, parseResult, options) {
|
|
@@ -9031,18 +8900,15 @@ function validateClientMetadataSync(clientMetadata, parseResult, options) {
|
|
|
9031
8900
|
const warnings = [];
|
|
9032
8901
|
const errors = [];
|
|
9033
8902
|
const computedTokens = countTokens(card);
|
|
9034
|
-
const
|
|
9035
|
-
const
|
|
9036
|
-
const computedHashV1 = computeHash(canonicalContentV1);
|
|
9037
|
-
const computedHashV2 = computeHash(canonicalContentV2);
|
|
8903
|
+
const canonicalContent = getCanonicalContent(card);
|
|
8904
|
+
const computedHash = computeHash(canonicalContent);
|
|
9038
8905
|
const entries = card.data.character_book?.entries || [];
|
|
9039
8906
|
const computedHasLorebook = entries.length > 0;
|
|
9040
8907
|
const computedLorebookCount = entries.length;
|
|
9041
8908
|
const authoritative = {
|
|
9042
8909
|
name: card.data.name,
|
|
9043
8910
|
tokens: computedTokens,
|
|
9044
|
-
contentHash:
|
|
9045
|
-
contentHashV2: computedHashV2,
|
|
8911
|
+
contentHash: computedHash,
|
|
9046
8912
|
hasLorebook: computedHasLorebook,
|
|
9047
8913
|
lorebookEntriesCount: computedLorebookCount
|
|
9048
8914
|
};
|
|
@@ -9054,13 +8920,11 @@ function validateClientMetadataSync(clientMetadata, parseResult, options) {
|
|
|
9054
8920
|
withinTolerance: false
|
|
9055
8921
|
});
|
|
9056
8922
|
}
|
|
9057
|
-
|
|
9058
|
-
const matchesV2 = clientMetadata.contentHash === computedHashV2;
|
|
9059
|
-
if (!matchesV1 && !matchesV2) {
|
|
8923
|
+
if (clientMetadata.contentHash !== computedHash) {
|
|
9060
8924
|
discrepancies.push({
|
|
9061
8925
|
field: "contentHash",
|
|
9062
8926
|
clientValue: clientMetadata.contentHash,
|
|
9063
|
-
computedValue:
|
|
8927
|
+
computedValue: computedHash,
|
|
9064
8928
|
withinTolerance: false
|
|
9065
8929
|
});
|
|
9066
8930
|
if (allowHashMismatch) {
|
|
@@ -9068,10 +8932,6 @@ function validateClientMetadataSync(clientMetadata, parseResult, options) {
|
|
|
9068
8932
|
} else {
|
|
9069
8933
|
errors.push("Content hash mismatch");
|
|
9070
8934
|
}
|
|
9071
|
-
} else if (matchesV1 && !matchesV2) {
|
|
9072
|
-
warnings.push(
|
|
9073
|
-
"Client contentHash matches legacy v1 canonicalization. Prefer authoritative.contentHashV2 for new storage."
|
|
9074
|
-
);
|
|
9075
8935
|
}
|
|
9076
8936
|
const tokenFields = [
|
|
9077
8937
|
"description",
|