diff --git a/default-task-profile-templates.js b/default-task-profile-templates.js index 36329b9..47ae4e2 100644 --- a/default-task-profile-templates.js +++ b/default-task-profile-templates.js @@ -189,13 +189,10 @@ export const DEFAULT_TASK_PROFILE_TEMPLATES = { "character": true }, "stages": { - "finalPrompt": true, "input.userMessage": false, "input.recentMessages": false, "input.candidateText": false, "input.finalPrompt": false, - "rawResponse": false, - "beforeParse": false, "output.rawResponse": false, "output.beforeParse": false, "input": true, @@ -396,13 +393,10 @@ export const DEFAULT_TASK_PROFILE_TEMPLATES = { "character": true }, "stages": { - "finalPrompt": true, "input.userMessage": false, "input.recentMessages": false, "input.candidateText": false, "input.finalPrompt": false, - "rawResponse": false, - "beforeParse": false, "output.rawResponse": false, "output.beforeParse": false, "input": true, @@ -579,13 +573,10 @@ export const DEFAULT_TASK_PROFILE_TEMPLATES = { "character": true }, "stages": { - "finalPrompt": true, "input.userMessage": false, "input.recentMessages": false, "input.candidateText": false, "input.finalPrompt": false, - "rawResponse": false, - "beforeParse": false, "output.rawResponse": false, "output.beforeParse": false, "input": true, @@ -774,13 +765,10 @@ export const DEFAULT_TASK_PROFILE_TEMPLATES = { "character": true }, "stages": { - "finalPrompt": true, "input.userMessage": false, "input.recentMessages": false, "input.candidateText": false, "input.finalPrompt": false, - "rawResponse": false, - "beforeParse": false, "output.rawResponse": false, "output.beforeParse": false, "input": true, @@ -981,13 +969,10 @@ export const DEFAULT_TASK_PROFILE_TEMPLATES = { "character": true }, "stages": { - "finalPrompt": true, "input.userMessage": false, "input.recentMessages": false, "input.candidateText": false, "input.finalPrompt": false, - "rawResponse": false, - "beforeParse": false, "output.rawResponse": false, "output.beforeParse": false, "input": true, @@ -1200,13 +1185,10 @@ export const DEFAULT_TASK_PROFILE_TEMPLATES = { "character": true }, "stages": { - "finalPrompt": true, "input.userMessage": false, "input.recentMessages": false, "input.candidateText": false, "input.finalPrompt": false, - "rawResponse": false, - "beforeParse": false, "output.rawResponse": false, "output.beforeParse": false, "input": true, diff --git a/prompt-profiles.js b/prompt-profiles.js index 695997e..aece4cc 100644 --- a/prompt-profiles.js +++ b/prompt-profiles.js @@ -637,15 +637,13 @@ export function normalizeTaskRegexStages(stages = {}) { for (const [legacyKey, canonicalKey] of Object.entries( TASK_REGEX_STAGE_ALIAS_MAP, )) { - if (Object.prototype.hasOwnProperty.call(source, legacyKey)) { - // Older exports may carry both legacy and canonical keys at the same - // time. When that happens, keep the legacy intent instead of letting a - // newer placeholder default silently flip stage timing. - normalized[canonicalKey] = Boolean(source[legacyKey]); + if (Object.prototype.hasOwnProperty.call(source, canonicalKey)) { + // Respect an explicitly stored canonical key when both forms are + // present. Legacy aliases should only backfill older exports. continue; } - if (Object.prototype.hasOwnProperty.call(source, canonicalKey)) { - normalized[canonicalKey] = Boolean(source[canonicalKey]); + if (Object.prototype.hasOwnProperty.call(source, legacyKey)) { + normalized[canonicalKey] = Boolean(source[legacyKey]); } } @@ -893,13 +891,10 @@ function createFallbackDefaultTaskProfile(taskType) { character: true, }, stages: normalizeTaskRegexStages({ - finalPrompt: true, "input.userMessage": false, "input.recentMessages": false, "input.candidateText": false, "input.finalPrompt": false, - rawResponse: false, - beforeParse: false, "output.rawResponse": false, "output.beforeParse": false, }), @@ -954,10 +949,10 @@ export function createDefaultTaskProfile(taskType) { ...fallback.regex.sources, ...(template?.regex?.sources || {}), }, - stages: normalizeTaskRegexStages({ - ...fallback.regex.stages, - ...(template?.regex?.stages || {}), - }), + stages: { + ...normalizeTaskRegexStages(fallback.regex.stages || {}), + ...normalizeTaskRegexStages(template?.regex?.stages || {}), + }, localRules: Array.isArray(template?.regex?.localRules) ? template.regex.localRules.map((rule, index) => normalizeRegexLocalRule(rule, taskType, index), @@ -1148,10 +1143,10 @@ export function normalizeTaskProfile(taskType, profile = {}, settings = {}) { ...base.regex.sources, ...(profile?.regex?.sources || {}), }, - stages: normalizeTaskRegexStages({ - ...base.regex.stages, - ...(profile?.regex?.stages || {}), - }), + stages: { + ...normalizeTaskRegexStages(base.regex.stages || {}), + ...normalizeTaskRegexStages(profile?.regex?.stages || {}), + }, localRules: Array.isArray(profile?.regex?.localRules) ? profile.regex.localRules.map((rule, index) => normalizeRegexLocalRule(rule, taskType, index), diff --git a/tests/task-regex.mjs b/tests/task-regex.mjs index eba3653..8bad23c 100644 --- a/tests/task-regex.mjs +++ b/tests/task-regex.mjs @@ -156,6 +156,7 @@ try { const { createDefaultTaskProfiles, isTaskRegexStageEnabled, + normalizeTaskProfile, normalizeTaskRegexStages, } = await import("../prompt-profiles.js"); @@ -170,7 +171,7 @@ try { "output.rawResponse": false, "output.beforeParse": false, }); - assert.equal(normalizedLegacyStages["input.finalPrompt"], true); + assert.equal(normalizedLegacyStages["input.finalPrompt"], false); assert.equal(normalizedLegacyStages["input.userMessage"], false); assert.equal(normalizedLegacyStages["input.recentMessages"], false); assert.equal(normalizedLegacyStages["input.candidateText"], false); @@ -178,7 +179,7 @@ try { assert.equal(normalizedLegacyStages["output.beforeParse"], false); assert.equal( isTaskRegexStageEnabled(normalizedLegacyStages, "input.finalPrompt"), - true, + false, ); assert.equal( isTaskRegexStageEnabled(normalizedLegacyStages, "input.userMessage"), @@ -198,7 +199,7 @@ try { defaultProfiles.extract?.profiles?.[0]?.regex?.stages || {}; assert.equal( isTaskRegexStageEnabled(defaultExtractStages, "input.finalPrompt"), - true, + false, ); assert.equal( isTaskRegexStageEnabled(defaultExtractStages, "input.userMessage"), @@ -213,6 +214,27 @@ try { false, ); + const normalizedLegacyOnlyProfile = normalizeTaskProfile( + "extract", + { + id: "legacy-only-profile", + name: "legacy only", + regex: { + stages: { + finalPrompt: true, + }, + }, + }, + {}, + ); + assert.equal( + isTaskRegexStageEnabled( + normalizedLegacyOnlyProfile.regex?.stages || {}, + "input.finalPrompt", + ), + true, + ); + globalThis.getTavernRegexes = () => { throw new Error("legacy global getter should not be used in regex tests"); };