feat: Add {{notChar}} macro for participant list (#4579) * feat: Add {{notChar}} macro for participant list * implement impersonation logic consistently. * docs: Document the new {{notChar}} macro * docs: Fix format for {{notChar}} and remove examples. * docs: Add span tag * docs: fix extra quote mark * docs: Add suggested fixes
Signed| @@ -2253,6 +2253,33 @@ export function substituteParams(content, _name1, _name2, _original, _group, _re | ||
| 2253 | 2253 | } |
| 2254 | 2254 | }; |
| 2255 | 2255 | |
| 2256 | + const getNotCharValue = () => { | |
| 2257 | + const currentUser = _name1 ?? name1; | |
| 2258 | + const currentSpeaker = _name2 ?? name2; | |
| 2259 | + | |
| 2260 | + // Single character chat | |
| 2261 | + if (!selected_group) { | |
| 2262 | + return currentUser; | |
| 2263 | + } | |
| 2264 | + | |
| 2265 | + // Group chat | |
| 2266 | + const members = groups.find(x => x.id === selected_group)?.members; | |
| 2267 | + | |
| 2268 | + if (!Array.isArray(members)) { | |
| 2269 | + return currentUser; | |
| 2270 | + } | |
| 2271 | + | |
| 2272 | + const memberNames = members | |
| 2273 | + .map(m => characters.find(c => c.avatar === m)?.name) | |
| 2274 | + .filter(Boolean); // Filter out any null/undefined names | |
| 2275 | + | |
| 2276 | + // Filter out the current speaker and add the user | |
| 2277 | + const otherMembers = memberNames.filter(name => name !== currentSpeaker); | |
| 2278 | + otherMembers.push(currentUser); | |
| 2279 | + | |
| 2280 | + return otherMembers.join(', '); | |
| 2281 | + }; | |
| 2282 | + | |
| 2256 | 2283 | if (_replaceCharacterCard) { |
| 2257 | 2284 | const fields = getCharacterCardFields(); |
| 2258 | 2285 | environment.charPrompt = fields.system || ''; |
| @@ -2282,6 +2309,7 @@ export function substituteParams(content, _name1, _name2, _original, _group, _re | ||
| 2282 | 2309 | environment.char = _name2 ?? name2; |
| 2283 | 2310 | environment.group = environment.charIfNotGroup = getGroupValue(true); |
| 2284 | 2311 | environment.groupNotMuted = getGroupValue(false); |
| 2312 | + environment.notChar = getNotCharValue(); | |
| 2285 | 2313 | environment.model = getGeneratingModel(); |
| 2286 | 2314 | |
| 2287 | 2315 | if (additionalMacro && typeof additionalMacro === 'object') { |
| @@ -25,6 +25,7 @@ | ||
| 25 | 25 | <li><tt>{{outlet::(name)}}</tt> – <span data-i18n="help_macros_outletName">the WI entry content for the outlet with the specified name</span></li> |
| 26 | 26 | <li><tt>{{group}}</tt> – <span data-i18n="help_macros_18">a comma-separated list of group member names (including muted) or the character name in solo chats. Alias: {{charIfNotGroup}}</span></li> |
| 27 | 27 | <li><tt>{{groupNotMuted}}</tt> – <span data-i18n="help_groupNotMuted">the same as {{group}}, but excludes muted members</span></li> |
| 28 | + <li><tt>{{notChar}}</tt> – <span data-i18n="help_notChar">a comma-separated list of all participants in the conversation except for the current speaker ({{char}}). In group chats, this includes muted characters. When not in a generation, the list include all characters.</span></li> | |
| 28 | 29 | <li><tt>{{model}}</tt> – <span data-i18n="help_macros_19">a text generation model name for the currently selected API. </span><b data-i18n="Can be inaccurate!">Can be inaccurate!</b></li> |
| 29 | 30 | <li><tt>{{lastMessage}}</tt> – <span data-i18n="help_macros_20">the text of the latest chat message.</span></li> |
| 30 | 31 | <li><tt>{{lastUserMessage}}</tt> – <span data-i18n="help_macros_lastUser">the text of the latest user chat message.</span></li> |