diff --git a/public/script.js b/public/script.js index 528ba0d26..9e809fe4e 100644 --- a/public/script.js +++ b/public/script.js @@ -3230,6 +3230,8 @@ export function baseChatReplace(value, name1Override = null, name2Override = nul * @property {string} version Character version * @property {string} charDepthPrompt Character depth note * @property {string} creatorNotes Character creator notes + * @property {string} firstMessage Character first message / greeting + * @property {string[]} alternateGreetings Character alternate greetings */ /** @@ -3316,6 +3318,17 @@ export function getCharacterCardFieldsLazy({ chid = undefined } = {}) { const exampleDialog = chat_metadata.mes_example || character.mes_example || ''; return baseChatReplace(exampleDialog.trim()); }, + firstMessage: () => { + if (!character) return ''; + const firstMes = character.first_mes?.trim() || ''; + return baseChatReplace(firstMes); + }, + alternateGreetings: () => { + if (!character) return []; + const altGreetings = character.data?.alternate_greetings; + if (!Array.isArray(altGreetings)) return []; + return altGreetings.map(greeting => baseChatReplace(greeting?.trim())); + }, }; return createLazyFields(resolvers); @@ -3342,6 +3355,8 @@ export function getCharacterCardFields({ chid = undefined } = {}) { version: lazy.version, charDepthPrompt: lazy.charDepthPrompt, creatorNotes: lazy.creatorNotes, + firstMessage: lazy.firstMessage, + alternateGreetings: lazy.alternateGreetings, }; } diff --git a/public/scripts/macros/definitions/env-macros.js b/public/scripts/macros/definitions/env-macros.js index ded9ced14..a62566090 100644 --- a/public/scripts/macros/definitions/env-macros.js +++ b/public/scripts/macros/definitions/env-macros.js @@ -140,6 +140,30 @@ export function registerEnvMacros() { handler: ({ env }) => env.character.creatorNotes ?? '', }); + MacroRegistry.registerMacro('charFirstMessage', { + aliases: [{ alias: 'greeting' }], + category: MacroCategory.CHARACTER, + unnamedArgs: [ + { + name: 'index', + optional: true, + defaultValue: '0', + type: MacroValueType.INTEGER, + description: '0-based index. 0 (default) returns the main greeting, 1 and up return alternate greetings.', + }, + ], + description: 'The character\'s first message / greeting. Optionally specify an index to access alternate greetings.', + returns: 'Character greeting at the given index, or empty string if out of bounds.', + exampleUsage: ['{{greeting}}', '{{greeting::0}}', '{{greeting::1}}'], + handler: ({ env, unnamedArgs: [index] }) => { + const i = Number(index ?? 0); + if (i === 0) return env.character.firstMessage ?? ''; + const altGreetings = env.character.alternateGreetings; + if (!Array.isArray(altGreetings)) return ''; + return altGreetings[i - 1] ?? ''; + }, + }); + // Character version macros (legacy variants and documented {{charVersion}}) MacroRegistry.registerMacro('charVersion', { aliases: [ diff --git a/public/scripts/macros/engine/MacroEnv.types.js b/public/scripts/macros/engine/MacroEnv.types.js index 40de21cf7..0d42af344 100644 --- a/public/scripts/macros/engine/MacroEnv.types.js +++ b/public/scripts/macros/engine/MacroEnv.types.js @@ -38,6 +38,8 @@ * @property {string} [charDepthPrompt] * @property {string} [creatorNotes] * @property {string} [version] + * @property {string} [firstMessage] + * @property {string[]} [alternateGreetings] */ /** diff --git a/public/scripts/macros/engine/MacroEnvBuilder.js b/public/scripts/macros/engine/MacroEnvBuilder.js index 99a7b0603..e25cc65d3 100644 --- a/public/scripts/macros/engine/MacroEnvBuilder.js +++ b/public/scripts/macros/engine/MacroEnvBuilder.js @@ -109,10 +109,19 @@ class MacroEnvBuilder { ['version', 'version'], ['charDepthPrompt', 'charDepthPrompt'], ['creatorNotes', 'creatorNotes'], + ['firstMessage', 'firstMessage'], + ['alternateGreetings', 'alternateGreetings'], ]); for (const [envKey, fieldKey] of fieldMappings) { Object.defineProperty(env.character, envKey, { - get() { return fields[fieldKey] || ''; }, + get() { + const value = fields[fieldKey]; + // alternateGreetings should default to [] instead of '' + if (envKey === 'alternateGreetings') { + return Array.isArray(value) ? value : []; + } + return value || ''; + }, enumerable: true, configurable: true, }); diff --git a/tests/frontend/MacroEnvBuilder.e2e.js b/tests/frontend/MacroEnvBuilder.e2e.js index b035d39c0..fe7e90ef5 100644 --- a/tests/frontend/MacroEnvBuilder.e2e.js +++ b/tests/frontend/MacroEnvBuilder.e2e.js @@ -98,6 +98,8 @@ test.describe('MacroEnvBuilder', () => { 'version', 'charDepthPrompt', 'creatorNotes', + 'firstMessage', + 'alternateGreetings', ])); });