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 = [];