Merge pull request #3660 from SillyTavern/group-pooled-order Add group pooled order

ebe30dceac64e88939ce2561cd9858f503581e75

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
2 files changed, +47 -0Ignore whitespace
public/index.html+1 -0
@@ -5382,6 +5382,7 @@
5382 <option value="2" data-i18n="Manual">Manual</option>5382 <option value="2" data-i18n="Manual">Manual</option>
5383 <option value="0" data-i18n="Natural order">Natural order</option>5383 <option value="0" data-i18n="Natural order">Natural order</option>
5384 <option value="1" data-i18n="List order">List order</option>5384 <option value="1" data-i18n="List order">List order</option>
5385 <option value="3" data-i18n="Pooled order">Pooled order</option>
5385 </select>5386 </select>
5386 </div>5387 </div>
5387 <div class="flex1 flexGap5">5388 <div class="flex1 flexGap5">
public/scripts/group-chats.js+46 -0
@@ -114,6 +114,7 @@ export const group_activation_strategy = {
114 NATURAL: 0,114 NATURAL: 0,
115 LIST: 1,115 LIST: 1,
116 MANUAL: 2,116 MANUAL: 2,
117 POOLED: 3,
117};118};
118119
119export const group_generation_mode = {120export const group_generation_mode = {
@@ -880,6 +881,9 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) {
880 else if (activationStrategy === group_activation_strategy.LIST) {881 else if (activationStrategy === group_activation_strategy.LIST) {
881 activatedMembers = activateListOrder(enabledMembers);882 activatedMembers = activateListOrder(enabledMembers);
882 }883 }
884 else if (activationStrategy === group_activation_strategy.POOLED) {
885 activatedMembers = activatePooledOrder(enabledMembers, lastMessage);
886 }
883 else if (activationStrategy === group_activation_strategy.MANUAL && !isUserInput) {887 else if (activationStrategy === group_activation_strategy.MANUAL && !isUserInput) {
884 activatedMembers = shuffle(enabledMembers).slice(0, 1).map(x => characters.findIndex(y => y.avatar === x)).filter(x => x !== -1);888 activatedMembers = shuffle(enabledMembers).slice(0, 1).map(x => characters.findIndex(y => y.avatar === x)).filter(x => x !== -1);
885 }889 }
@@ -1020,6 +1024,48 @@ function activateListOrder(members) {
1020 return memberIds;1024 return memberIds;
1021}1025}
10221026
1027/**
1028 * Activate group members based on the last message.
1029 * @param {string[]} members List of member avatars
1030 * @param {Object} lastMessage Last message
1031 * @returns {number[]} List of character ids
1032 */
1033function activatePooledOrder(members, lastMessage) {
1034 /** @type {string} */
1035 let activatedMember = null;
1036 /** @type {string[]} */
1037 const spokenSinceUser = [];
1038
1039 for (const message of chat.slice().reverse()) {
1040 if (message.is_user) {
1041 break;
1042 }
1043
1044 if (message.is_system || message.extra?.type === system_message_types.NARRATOR) {
1045 continue;
1046 }
1047
1048 if (message.original_avatar) {
1049 spokenSinceUser.push(message.original_avatar);
1050 }
1051 }
1052
1053 const haveNotSpoken = members.filter(x => !spokenSinceUser.includes(x));
1054
1055 if (haveNotSpoken.length) {
1056 activatedMember = haveNotSpoken[Math.floor(Math.random() * haveNotSpoken.length)];
1057 }
1058
1059 if (activatedMember === null) {
1060 const lastMessageAvatar = members.length > 1 && lastMessage && !lastMessage.is_user && lastMessage.original_avatar;
1061 const randomPool = lastMessageAvatar ? members.filter(x => x !== lastMessage.original_avatar) : members;
1062 activatedMember = randomPool[Math.floor(Math.random() * randomPool.length)];
1063 }
1064
1065 const memberId = characters.findIndex(y => y.avatar === activatedMember);
1066 return memberId !== -1 ? [memberId] : [];
1067}
1068
1023function activateNaturalOrder(members, input, lastMessage, allowSelfResponses, isUserInput) {1069function activateNaturalOrder(members, input, lastMessage, allowSelfResponses, isUserInput) {
1024 let activatedMembers = [];1070 let activatedMembers = [];
10251071