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); 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) { function getDefaultTaskProfileTemplateStamp(taskType) {
const template = getDefaultTaskProfileTemplate(taskType); const template = getDefaultTaskProfileTemplate(taskType);
return { return {
@@ -453,6 +468,7 @@ function getDefaultTaskProfileTemplateStamp(taskType) {
typeof template?.updatedAt === "string" && template.updatedAt typeof template?.updatedAt === "string" && template.updatedAt
? template.updatedAt ? template.updatedAt
: "", : "",
fingerprint: getDefaultTaskProfileTemplateFingerprint(taskType),
}; };
} }
@@ -804,11 +820,19 @@ function shouldRefreshBuiltinDefaultProfile(taskType, profile = {}) {
typeof metadata?.defaultTemplateUpdatedAt === "string" typeof metadata?.defaultTemplateUpdatedAt === "string"
? metadata.defaultTemplateUpdatedAt ? metadata.defaultTemplateUpdatedAt
: ""; : "";
const currentFingerprint =
typeof metadata?.defaultTemplateFingerprint === "string"
? metadata.defaultTemplateFingerprint
: "";
if (currentVersion < expectedStamp.version) { if (currentVersion < expectedStamp.version) {
return true; return true;
} }
if (expectedStamp.fingerprint && currentFingerprint !== expectedStamp.fingerprint) {
return true;
}
if ( if (
expectedStamp.updatedAt && expectedStamp.updatedAt &&
currentUpdatedAt && currentUpdatedAt &&
@@ -886,6 +910,7 @@ function createFallbackDefaultTaskProfile(taskType) {
legacyPromptField, legacyPromptField,
defaultTemplateVersion: templateStamp.version, defaultTemplateVersion: templateStamp.version,
defaultTemplateUpdatedAt: templateStamp.updatedAt, defaultTemplateUpdatedAt: templateStamp.updatedAt,
defaultTemplateFingerprint: templateStamp.fingerprint,
}, },
}; };
} }
@@ -946,6 +971,7 @@ export function createDefaultTaskProfile(taskType) {
legacyPromptField, legacyPromptField,
defaultTemplateVersion: templateStamp.version, defaultTemplateVersion: templateStamp.version,
defaultTemplateUpdatedAt: templateStamp.updatedAt, defaultTemplateUpdatedAt: templateStamp.updatedAt,
defaultTemplateFingerprint: templateStamp.fingerprint,
}, },
}; };
} }

View File

@@ -297,6 +297,10 @@ assert.equal(
refreshedDefaultExtract.metadata.defaultTemplateUpdatedAt, refreshedDefaultExtract.metadata.defaultTemplateUpdatedAt,
currentDefaultExtract.metadata.defaultTemplateUpdatedAt, currentDefaultExtract.metadata.defaultTemplateUpdatedAt,
); );
assert.equal(
refreshedDefaultExtract.metadata.defaultTemplateFingerprint,
currentDefaultExtract.metadata.defaultTemplateFingerprint,
);
assert.ok(preservedCustomExtract); assert.ok(preservedCustomExtract);
assert.equal( assert.equal(
preservedCustomExtract.blocks[0].content, preservedCustomExtract.blocks[0].content,
@@ -332,6 +336,41 @@ assert.equal(
?.content, ?.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( assert.deepEqual(
upgradedLegacyDefault.blocks upgradedLegacyDefault.blocks
.slice(6, 10) .slice(6, 10)