Add group pooled order Closes #3650

ad225138b48e12b1738ec519ad6651a33145b6db

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

2 files changed, +47 -0Showing whitespace changes
public/index.html+1 -0
@@ -5382,6 +5382,7 @@
53825382 <option value="2" data-i18n="Manual">Manual</option>
53835383 <option value="0" data-i18n="Natural order">Natural order</option>
53845384 <option value="1" data-i18n="List order">List order</option>
5385+ <option value="3" data-i18n="Pooled order">Pooled order</option>
53855386 </select>
53865387 </div>
53875388 <div class="flex1 flexGap5">
public/scripts/group-chats.js+46 -0
@@ -114,6 +114,7 @@ export const group_activation_strategy = {
114114 NATURAL: 0,
115115 LIST: 1,
116116 MANUAL: 2,
117+ POOLED: 3,
117118};
118119
119120export const group_generation_mode = {
@@ -880,6 +881,9 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) {
880881 else if (activationStrategy === group_activation_strategy.LIST) {
881882 activatedMembers = activateListOrder(enabledMembers);
882883 }
884+ else if (activationStrategy === group_activation_strategy.POOLED) {
885+ activatedMembers = activatePooledOrder(enabledMembers, lastMessage);
886+ }
883887 else if (activationStrategy === group_activation_strategy.MANUAL && !isUserInput) {
884888 activatedMembers = shuffle(enabledMembers).slice(0, 1).map(x => characters.findIndex(y => y.avatar === x)).filter(x => x !== -1);
885889 }
@@ -1020,6 +1024,48 @@ function activateListOrder(members) {
10201024 return memberIds;
10211025}
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+ */
1033+function activatePooledOrder(members, lastMessage) {
1034+ const activatedMembers = [];
1035+ const spokenSinceUser = [];
1036+
1037+ for (const message of chat.slice().reverse()) {
1038+ if (message.is_user) {
1039+ break;
1040+ }
1041+
1042+ if (message.is_system || message.extra?.type === system_message_types.NARRATOR) {
1043+ continue;
1044+ }
1045+
1046+ if (message.original_avatar) {
1047+ spokenSinceUser.push(message.original_avatar);
1048+ }
1049+ }
1050+
1051+ const haveNotSpoken = members.filter(x => !spokenSinceUser.includes(x));
1052+
1053+ if (haveNotSpoken.length) {
1054+ activatedMembers.push(haveNotSpoken[Math.floor(Math.random() * haveNotSpoken.length)]);
1055+ }
1056+
1057+ if (activatedMembers.length === 0) {
1058+ const lastMessageAvatar = members.length > 1 && lastMessage && !lastMessage.is_user && lastMessage.original_avatar;
1059+ const randomPool = lastMessageAvatar ? members.filter(x => x !== lastMessage.original_avatar) : members;
1060+ activatedMembers.push(randomPool[Math.floor(Math.random() * randomPool.length)]);
1061+ }
1062+
1063+ const memberIds = activatedMembers
1064+ .map((x) => characters.findIndex((y) => y.avatar === x))
1065+ .filter((x) => x !== -1);
1066+ return memberIds;
1067+}
1068+
10231069function activateNaturalOrder(members, input, lastMessage, allowSelfResponses, isUserInput) {
10241070 let activatedMembers = [];
10251071