diff --git a/public/index.html b/public/index.html index 54e54de1f..9403982b0 100644 --- a/public/index.html +++ b/public/index.html @@ -5382,6 +5382,7 @@ +
diff --git a/public/scripts/group-chats.js b/public/scripts/group-chats.js index 0fbd5b543..601432741 100644 --- a/public/scripts/group-chats.js +++ b/public/scripts/group-chats.js @@ -114,6 +114,7 @@ export const group_activation_strategy = { NATURAL: 0, LIST: 1, MANUAL: 2, + POOLED: 3, }; export const group_generation_mode = { @@ -880,6 +881,9 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) { else if (activationStrategy === group_activation_strategy.LIST) { activatedMembers = activateListOrder(enabledMembers); } + else if (activationStrategy === group_activation_strategy.POOLED) { + activatedMembers = activatePooledOrder(enabledMembers, lastMessage); + } else if (activationStrategy === group_activation_strategy.MANUAL && !isUserInput) { activatedMembers = shuffle(enabledMembers).slice(0, 1).map(x => characters.findIndex(y => y.avatar === x)).filter(x => x !== -1); } @@ -1020,6 +1024,48 @@ function activateListOrder(members) { return memberIds; } +/** + * Activate group members based on the last message. + * @param {string[]} members List of member avatars + * @param {Object} lastMessage Last message + * @returns {number[]} List of character ids + */ +function activatePooledOrder(members, lastMessage) { + const activatedMembers = []; + const spokenSinceUser = []; + + for (const message of chat.slice().reverse()) { + if (message.is_user) { + break; + } + + if (message.is_system || message.extra?.type === system_message_types.NARRATOR) { + continue; + } + + if (message.original_avatar) { + spokenSinceUser.push(message.original_avatar); + } + } + + const haveNotSpoken = members.filter(x => !spokenSinceUser.includes(x)); + + if (haveNotSpoken.length) { + activatedMembers.push(haveNotSpoken[Math.floor(Math.random() * haveNotSpoken.length)]); + } + + if (activatedMembers.length === 0) { + const lastMessageAvatar = members.length > 1 && lastMessage && !lastMessage.is_user && lastMessage.original_avatar; + const randomPool = lastMessageAvatar ? members.filter(x => x !== lastMessage.original_avatar) : members; + activatedMembers.push(randomPool[Math.floor(Math.random() * randomPool.length)]); + } + + const memberIds = activatedMembers + .map((x) => characters.findIndex((y) => y.avatar === x)) + .filter((x) => x !== -1); + return memberIds; +} + function activateNaturalOrder(members, input, lastMessage, allowSelfResponses, isUserInput) { let activatedMembers = [];