Detect default profile template changes by content

This commit is contained in:
Youzini-afk
2026-04-05 20:10:06 +08:00
parent 81ccc36859
commit 69a47c11b2
2 changed files with 65 additions and 0 deletions

View File

@@ -443,6 +443,21 @@ function getDefaultTaskProfileTemplate(taskType) {
return cloneJson(template);
}
function hashTemplateFingerprint(value = "") {
const text = String(value || "");
let hash = 2166136261;
for (let index = 0; index < text.length; index += 1) {
hash ^= text.charCodeAt(index);
hash = Math.imul(hash, 16777619);
}
return `fnv1a-${(hash >>> 0).toString(16).padStart(8, "0")}`;
}
function getDefaultTaskProfileTemplateFingerprint(taskType) {
const template = getDefaultTaskProfileTemplate(taskType);
return hashTemplateFingerprint(JSON.stringify(template || null));
}
function getDefaultTaskProfileTemplateStamp(taskType) {
const template = getDefaultTaskProfileTemplate(taskType);
return {
@@ -453,6 +468,7 @@ function getDefaultTaskProfileTemplateStamp(taskType) {
typeof template?.updatedAt === "string" && template.updatedAt
? template.updatedAt
: "",
fingerprint: getDefaultTaskProfileTemplateFingerprint(taskType),
};
}
@@ -804,11 +820,19 @@ function shouldRefreshBuiltinDefaultProfile(taskType, profile = {}) {
typeof metadata?.defaultTemplateUpdatedAt === "string"
? metadata.defaultTemplateUpdatedAt
: "";
const currentFingerprint =
typeof metadata?.defaultTemplateFingerprint === "string"
? metadata.defaultTemplateFingerprint
: "";
if (currentVersion < expectedStamp.version) {
return true;
}
if (expectedStamp.fingerprint && currentFingerprint !== expectedStamp.fingerprint) {
return true;
}
if (
expectedStamp.updatedAt &&
currentUpdatedAt &&
@@ -886,6 +910,7 @@ function createFallbackDefaultTaskProfile(taskType) {
legacyPromptField,
defaultTemplateVersion: templateStamp.version,
defaultTemplateUpdatedAt: templateStamp.updatedAt,
defaultTemplateFingerprint: templateStamp.fingerprint,
},
};
}
@@ -946,6 +971,7 @@ export function createDefaultTaskProfile(taskType) {
legacyPromptField,
defaultTemplateVersion: templateStamp.version,
defaultTemplateUpdatedAt: templateStamp.updatedAt,
defaultTemplateFingerprint: templateStamp.fingerprint,
},
};
}

View File

@@ -297,6 +297,10 @@ assert.equal(
refreshedDefaultExtract.metadata.defaultTemplateUpdatedAt,
currentDefaultExtract.metadata.defaultTemplateUpdatedAt,
);
assert.equal(
refreshedDefaultExtract.metadata.defaultTemplateFingerprint,
currentDefaultExtract.metadata.defaultTemplateFingerprint,
);
assert.ok(preservedCustomExtract);
assert.equal(
preservedCustomExtract.blocks[0].content,
@@ -332,6 +336,41 @@ assert.equal(
?.content,
"同版本下保留我的默认预设修改",
);
const sameTimestampButChangedTemplateDefaults = ensureTaskProfiles({
taskProfilesVersion: 3,
taskProfiles: {
extract: {
activeProfileId: "default",
profiles: [
{
...currentDefaultExtract,
blocks: currentDefaultExtract.blocks.map((block) =>
block.id === "default-role"
? { ...block, content: "老模板内容但时间戳没变" }
: block,
),
metadata: {
...(currentDefaultExtract.metadata || {}),
defaultTemplateFingerprint: "fnv1a-deadbeef",
},
},
],
},
},
});
const fingerprintRefreshedDefault =
sameTimestampButChangedTemplateDefaults.extract.profiles.find(
(profile) => profile.id === "default",
);
assert.equal(
fingerprintRefreshedDefault.blocks.find(
(block) => block.id === "default-role",
)?.content,
currentDefaultExtract.blocks.find((block) => block.id === "default-role")
?.content,
);
assert.deepEqual(
upgradedLegacyDefault.blocks
.slice(6, 10)