mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
Auto-refresh builtin default task profiles
This commit is contained in:
@@ -443,6 +443,19 @@ function getDefaultTaskProfileTemplate(taskType) {
|
|||||||
return cloneJson(template);
|
return cloneJson(template);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDefaultTaskProfileTemplateStamp(taskType) {
|
||||||
|
const template = getDefaultTaskProfileTemplate(taskType);
|
||||||
|
return {
|
||||||
|
version: Number.isFinite(Number(template?.version))
|
||||||
|
? Number(template.version)
|
||||||
|
: DEFAULT_TASK_PROFILE_VERSION,
|
||||||
|
updatedAt:
|
||||||
|
typeof template?.updatedAt === "string" && template.updatedAt
|
||||||
|
? template.updatedAt
|
||||||
|
: "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function buildDefaultTaskBlockTripletsFromTemplate(taskType) {
|
function buildDefaultTaskBlockTripletsFromTemplate(taskType) {
|
||||||
const template = getDefaultTaskProfileTemplate(taskType);
|
const template = getDefaultTaskProfileTemplate(taskType);
|
||||||
const blocks = Array.isArray(template?.blocks) ? template.blocks : [];
|
const blocks = Array.isArray(template?.blocks) ? template.blocks : [];
|
||||||
@@ -775,8 +788,45 @@ function mergeDefaultTaskProfileBlocks(taskType, existingBlocks = []) {
|
|||||||
return [...merged, ...extraBlocks];
|
return [...merged, ...extraBlocks];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function shouldRefreshBuiltinDefaultProfile(taskType, profile = {}) {
|
||||||
|
if (String(profile?.id || "") !== DEFAULT_PROFILE_ID || profile?.builtin === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedStamp = getDefaultTaskProfileTemplateStamp(taskType);
|
||||||
|
const metadata = profile?.metadata || {};
|
||||||
|
const currentVersion = Number.isFinite(Number(metadata?.defaultTemplateVersion))
|
||||||
|
? Number(metadata.defaultTemplateVersion)
|
||||||
|
: Number.isFinite(Number(profile?.version))
|
||||||
|
? Number(profile.version)
|
||||||
|
: 0;
|
||||||
|
const currentUpdatedAt =
|
||||||
|
typeof metadata?.defaultTemplateUpdatedAt === "string"
|
||||||
|
? metadata.defaultTemplateUpdatedAt
|
||||||
|
: "";
|
||||||
|
|
||||||
|
if (currentVersion < expectedStamp.version) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
expectedStamp.updatedAt &&
|
||||||
|
currentUpdatedAt &&
|
||||||
|
currentUpdatedAt !== expectedStamp.updatedAt
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expectedStamp.updatedAt && !currentUpdatedAt) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function createFallbackDefaultTaskProfile(taskType) {
|
function createFallbackDefaultTaskProfile(taskType) {
|
||||||
const legacyPromptField = LEGACY_PROMPT_FIELD_MAP[taskType];
|
const legacyPromptField = LEGACY_PROMPT_FIELD_MAP[taskType];
|
||||||
|
const templateStamp = getDefaultTaskProfileTemplateStamp(taskType);
|
||||||
return {
|
return {
|
||||||
id: DEFAULT_PROFILE_ID,
|
id: DEFAULT_PROFILE_ID,
|
||||||
name: "默认预设",
|
name: "默认预设",
|
||||||
@@ -834,6 +884,8 @@ function createFallbackDefaultTaskProfile(taskType) {
|
|||||||
metadata: {
|
metadata: {
|
||||||
migratedFromLegacy: false,
|
migratedFromLegacy: false,
|
||||||
legacyPromptField,
|
legacyPromptField,
|
||||||
|
defaultTemplateVersion: templateStamp.version,
|
||||||
|
defaultTemplateUpdatedAt: templateStamp.updatedAt,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -846,6 +898,7 @@ export function createDefaultTaskProfile(taskType) {
|
|||||||
|
|
||||||
const legacyPromptField = LEGACY_PROMPT_FIELD_MAP[taskType];
|
const legacyPromptField = LEGACY_PROMPT_FIELD_MAP[taskType];
|
||||||
const fallback = createFallbackDefaultTaskProfile(taskType);
|
const fallback = createFallbackDefaultTaskProfile(taskType);
|
||||||
|
const templateStamp = getDefaultTaskProfileTemplateStamp(taskType);
|
||||||
return {
|
return {
|
||||||
...fallback,
|
...fallback,
|
||||||
...template,
|
...template,
|
||||||
@@ -891,6 +944,8 @@ export function createDefaultTaskProfile(taskType) {
|
|||||||
...(template?.metadata || {}),
|
...(template?.metadata || {}),
|
||||||
migratedFromLegacy: false,
|
migratedFromLegacy: false,
|
||||||
legacyPromptField,
|
legacyPromptField,
|
||||||
|
defaultTemplateVersion: templateStamp.version,
|
||||||
|
defaultTemplateUpdatedAt: templateStamp.updatedAt,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -985,13 +1040,25 @@ export function ensureTaskProfiles(settings = {}) {
|
|||||||
for (const taskType of TASK_TYPES) {
|
for (const taskType of TASK_TYPES) {
|
||||||
const current = existing[taskType] || {};
|
const current = existing[taskType] || {};
|
||||||
const defaultBucket = defaults[taskType];
|
const defaultBucket = defaults[taskType];
|
||||||
const profiles =
|
let profiles =
|
||||||
Array.isArray(current.profiles) && current.profiles.length > 0
|
Array.isArray(current.profiles) && current.profiles.length > 0
|
||||||
? current.profiles.map((profile) =>
|
? current.profiles.map((profile) =>
|
||||||
normalizeTaskProfile(taskType, profile, settings),
|
normalizeTaskProfile(taskType, profile, settings),
|
||||||
)
|
)
|
||||||
: defaultBucket.profiles;
|
: defaultBucket.profiles;
|
||||||
|
|
||||||
|
const defaultIndex = profiles.findIndex(
|
||||||
|
(profile) => String(profile?.id || "") === DEFAULT_PROFILE_ID,
|
||||||
|
);
|
||||||
|
if (defaultIndex >= 0 && shouldRefreshBuiltinDefaultProfile(taskType, profiles[defaultIndex])) {
|
||||||
|
const refreshedDefault = createDefaultTaskProfile(taskType);
|
||||||
|
profiles = [
|
||||||
|
...profiles.slice(0, defaultIndex),
|
||||||
|
refreshedDefault,
|
||||||
|
...profiles.slice(defaultIndex + 1),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
const activeProfileId =
|
const activeProfileId =
|
||||||
typeof current.activeProfileId === "string" &&
|
typeof current.activeProfileId === "string" &&
|
||||||
profiles.some((profile) => profile.id === current.activeProfileId)
|
profiles.some((profile) => profile.id === current.activeProfileId)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import assert from "node:assert/strict";
|
import assert from "node:assert/strict";
|
||||||
import {
|
import {
|
||||||
createDefaultTaskProfiles,
|
createDefaultTaskProfiles,
|
||||||
|
ensureTaskProfiles,
|
||||||
getActiveTaskProfile,
|
getActiveTaskProfile,
|
||||||
migrateLegacyTaskProfiles,
|
migrateLegacyTaskProfiles,
|
||||||
} from "../prompt-profiles.js";
|
} from "../prompt-profiles.js";
|
||||||
@@ -218,6 +219,119 @@ assert.equal(upgradedLegacyDefault.blocks[10].content, "保留我自己的输出
|
|||||||
assert.equal(upgradedLegacyDefault.blocks[11].content, "保留我自己的行为规则");
|
assert.equal(upgradedLegacyDefault.blocks[11].content, "保留我自己的行为规则");
|
||||||
assert.equal(upgradedLegacyDefault.blocks[10].role, "user");
|
assert.equal(upgradedLegacyDefault.blocks[10].role, "user");
|
||||||
assert.equal(upgradedLegacyDefault.blocks[11].role, "user");
|
assert.equal(upgradedLegacyDefault.blocks[11].role, "user");
|
||||||
|
|
||||||
|
const currentDefaults = createDefaultTaskProfiles();
|
||||||
|
const currentDefaultExtract = currentDefaults.extract.profiles[0];
|
||||||
|
|
||||||
|
const staleBuiltinDefaults = ensureTaskProfiles({
|
||||||
|
taskProfilesVersion: 3,
|
||||||
|
taskProfiles: {
|
||||||
|
extract: {
|
||||||
|
activeProfileId: "default",
|
||||||
|
profiles: [
|
||||||
|
{
|
||||||
|
...currentDefaultExtract,
|
||||||
|
updatedAt: "2000-01-01T00:00:00.000Z",
|
||||||
|
blocks: currentDefaultExtract.blocks.map((block) =>
|
||||||
|
block.id === "default-role"
|
||||||
|
? { ...block, content: "这是过期的默认角色定义" }
|
||||||
|
: block,
|
||||||
|
),
|
||||||
|
metadata: {
|
||||||
|
...(currentDefaultExtract.metadata || {}),
|
||||||
|
defaultTemplateVersion:
|
||||||
|
Number(currentDefaultExtract.metadata?.defaultTemplateVersion || 3),
|
||||||
|
defaultTemplateUpdatedAt: "2000-01-01T00:00:00.000Z",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "extract-custom-1",
|
||||||
|
taskType: "extract",
|
||||||
|
builtin: false,
|
||||||
|
name: "我的自定义预设",
|
||||||
|
promptMode: "block-based",
|
||||||
|
enabled: true,
|
||||||
|
updatedAt: "2026-04-05T00:00:00.000Z",
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
id: "custom-block-1",
|
||||||
|
name: "自定义块",
|
||||||
|
type: "custom",
|
||||||
|
enabled: true,
|
||||||
|
role: "system",
|
||||||
|
sourceKey: "",
|
||||||
|
sourceField: "",
|
||||||
|
content: "保留我的自定义内容",
|
||||||
|
injectionMode: "append",
|
||||||
|
order: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
generation: { ...(currentDefaultExtract.generation || {}) },
|
||||||
|
regex: {
|
||||||
|
...(currentDefaultExtract.regex || {}),
|
||||||
|
localRules: [],
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
note: "custom-profile-should-stay",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const refreshedDefaultExtract = staleBuiltinDefaults.extract.profiles.find(
|
||||||
|
(profile) => profile.id === "default",
|
||||||
|
);
|
||||||
|
const preservedCustomExtract = staleBuiltinDefaults.extract.profiles.find(
|
||||||
|
(profile) => profile.id === "extract-custom-1",
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.ok(refreshedDefaultExtract);
|
||||||
|
assert.equal(
|
||||||
|
refreshedDefaultExtract.blocks.find((block) => block.id === "default-role")
|
||||||
|
?.content,
|
||||||
|
currentDefaultExtract.blocks.find((block) => block.id === "default-role")
|
||||||
|
?.content,
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
refreshedDefaultExtract.metadata.defaultTemplateUpdatedAt,
|
||||||
|
currentDefaultExtract.metadata.defaultTemplateUpdatedAt,
|
||||||
|
);
|
||||||
|
assert.ok(preservedCustomExtract);
|
||||||
|
assert.equal(
|
||||||
|
preservedCustomExtract.blocks[0].content,
|
||||||
|
"保留我的自定义内容",
|
||||||
|
);
|
||||||
|
|
||||||
|
const sameStampBuiltinDefault = ensureTaskProfiles({
|
||||||
|
taskProfilesVersion: 3,
|
||||||
|
taskProfiles: {
|
||||||
|
extract: {
|
||||||
|
activeProfileId: "default",
|
||||||
|
profiles: [
|
||||||
|
{
|
||||||
|
...currentDefaultExtract,
|
||||||
|
blocks: currentDefaultExtract.blocks.map((block) =>
|
||||||
|
block.id === "default-role"
|
||||||
|
? { ...block, content: "同版本下保留我的默认预设修改" }
|
||||||
|
: block,
|
||||||
|
),
|
||||||
|
metadata: {
|
||||||
|
...(currentDefaultExtract.metadata || {}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const sameStampDefaultExtract = sameStampBuiltinDefault.extract.profiles.find(
|
||||||
|
(profile) => profile.id === "default",
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
sameStampDefaultExtract.blocks.find((block) => block.id === "default-role")
|
||||||
|
?.content,
|
||||||
|
"同版本下保留我的默认预设修改",
|
||||||
|
);
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
upgradedLegacyDefault.blocks
|
upgradedLegacyDefault.blocks
|
||||||
.slice(6, 10)
|
.slice(6, 10)
|
||||||
|
|||||||
Reference in New Issue
Block a user