Merge pull request 'fix(turn): preserve mention override during membership refresh' (#17) from debug/mention-override-reset into feat/split-tools-and-mention-override
Reviewed-on: #17
This commit was merged in pull request #17.
This commit is contained in:
@@ -104,14 +104,24 @@ export async function ensureTurnOrder(api: OpenClawPluginApi, channelId: string)
|
|||||||
loadCache(api);
|
loadCache(api);
|
||||||
let botAccounts = getChannelBotAccountIds(api, channelId);
|
let botAccounts = getChannelBotAccountIds(api, channelId);
|
||||||
|
|
||||||
|
api.logger.info(
|
||||||
|
`dirigent: turn-debug ensureTurnOrder enter channel=${channelId} cached=${JSON.stringify(botAccounts)} bootstrapTried=${channelBootstrapTried.has(channelId)}`,
|
||||||
|
);
|
||||||
|
|
||||||
if (botAccounts.length === 0 && !channelBootstrapTried.has(channelId)) {
|
if (botAccounts.length === 0 && !channelBootstrapTried.has(channelId)) {
|
||||||
channelBootstrapTried.add(channelId);
|
channelBootstrapTried.add(channelId);
|
||||||
const discovered = await fetchVisibleChannelBotAccountIds(api, channelId).catch(() => [] as string[]);
|
const discovered = await fetchVisibleChannelBotAccountIds(api, channelId).catch(() => [] as string[]);
|
||||||
|
api.logger.info(
|
||||||
|
`dirigent: turn-debug ensureTurnOrder bootstrap-discovered channel=${channelId} discovered=${JSON.stringify(discovered)}`,
|
||||||
|
);
|
||||||
for (const aid of discovered) recordChannelAccount(api, channelId, aid);
|
for (const aid of discovered) recordChannelAccount(api, channelId, aid);
|
||||||
botAccounts = getChannelBotAccountIds(api, channelId);
|
botAccounts = getChannelBotAccountIds(api, channelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (botAccounts.length > 0) {
|
if (botAccounts.length > 0) {
|
||||||
|
api.logger.info(
|
||||||
|
`dirigent: turn-debug ensureTurnOrder initTurnOrder channel=${channelId} members=${JSON.stringify(botAccounts)}`,
|
||||||
|
);
|
||||||
initTurnOrder(channelId, botAccounts);
|
initTurnOrder(channelId, botAccounts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,20 +55,66 @@ function shuffleArray<T>(arr: T[]): T[] {
|
|||||||
export function initTurnOrder(channelId: string, botAccountIds: string[]): void {
|
export function initTurnOrder(channelId: string, botAccountIds: string[]): void {
|
||||||
const existing = channelTurns.get(channelId);
|
const existing = channelTurns.get(channelId);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
// Check if membership changed
|
// Compare membership against base order.
|
||||||
const oldSet = new Set(existing.turnOrder);
|
// If mention override is active, turnOrder is temporary; use savedTurnOrder for stable comparison.
|
||||||
|
const baseOrder = existing.savedTurnOrder || existing.turnOrder;
|
||||||
|
const oldSet = new Set(baseOrder);
|
||||||
const newSet = new Set(botAccountIds);
|
const newSet = new Set(botAccountIds);
|
||||||
const same = oldSet.size === newSet.size && [...oldSet].every(id => newSet.has(id));
|
const same = oldSet.size === newSet.size && [...oldSet].every(id => newSet.has(id));
|
||||||
if (same) return; // no change
|
if (same) return; // no change
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[dirigent][turn-debug] initTurnOrder membership-changed channel=${channelId} ` +
|
||||||
|
`oldOrder=${JSON.stringify(existing.turnOrder)} oldCurrent=${existing.currentSpeaker} ` +
|
||||||
|
`oldOverride=${JSON.stringify(existing.savedTurnOrder || null)} newMembers=${JSON.stringify(botAccountIds)}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const nextOrder = shuffleArray(botAccountIds);
|
||||||
|
|
||||||
|
// Mention override active: update only the saved base order.
|
||||||
|
// Keep temporary turnOrder/currentSpeaker intact so @mention routing is not clobbered.
|
||||||
|
if (existing.savedTurnOrder) {
|
||||||
|
existing.savedTurnOrder = nextOrder;
|
||||||
|
existing.lastChangedAt = Date.now();
|
||||||
|
console.log(
|
||||||
|
`[dirigent][turn-debug] initTurnOrder applied-base-only channel=${channelId} ` +
|
||||||
|
`savedOrder=${JSON.stringify(nextOrder)} keptOverrideOrder=${JSON.stringify(existing.turnOrder)} ` +
|
||||||
|
`keptCurrent=${existing.currentSpeaker}`,
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Non-mention flow: preserve previous behavior (re-init to dormant).
|
||||||
channelTurns.set(channelId, {
|
channelTurns.set(channelId, {
|
||||||
turnOrder: shuffleArray(botAccountIds),
|
turnOrder: nextOrder,
|
||||||
currentSpeaker: null, // start dormant
|
currentSpeaker: null, // start dormant
|
||||||
noRepliedThisCycle: new Set(),
|
noRepliedThisCycle: new Set(),
|
||||||
lastChangedAt: Date.now(),
|
lastChangedAt: Date.now(),
|
||||||
waitingForHuman: false,
|
waitingForHuman: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[dirigent][turn-debug] initTurnOrder applied channel=${channelId} newOrder=${JSON.stringify(nextOrder)} newCurrent=null`,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[dirigent][turn-debug] initTurnOrder first-init channel=${channelId} members=${JSON.stringify(botAccountIds)}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const nextOrder = shuffleArray(botAccountIds);
|
||||||
|
channelTurns.set(channelId, {
|
||||||
|
turnOrder: nextOrder,
|
||||||
|
currentSpeaker: null, // start dormant
|
||||||
|
noRepliedThisCycle: new Set(),
|
||||||
|
lastChangedAt: Date.now(),
|
||||||
|
waitingForHuman: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[dirigent][turn-debug] initTurnOrder applied channel=${channelId} newOrder=${JSON.stringify(nextOrder)} newCurrent=null`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -190,12 +236,21 @@ export function setMentionOverride(channelId: string, mentionedAccountIds: strin
|
|||||||
const state = channelTurns.get(channelId);
|
const state = channelTurns.get(channelId);
|
||||||
if (!state || mentionedAccountIds.length === 0) return false;
|
if (!state || mentionedAccountIds.length === 0) return false;
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[dirigent][turn-debug] setMentionOverride start channel=${channelId} ` +
|
||||||
|
`mentioned=${JSON.stringify(mentionedAccountIds)} current=${state.currentSpeaker} ` +
|
||||||
|
`order=${JSON.stringify(state.turnOrder)} saved=${JSON.stringify(state.savedTurnOrder || null)}`,
|
||||||
|
);
|
||||||
|
|
||||||
// Restore any existing override first
|
// Restore any existing override first
|
||||||
restoreOriginalOrder(state);
|
restoreOriginalOrder(state);
|
||||||
|
|
||||||
// Filter to agents actually in the turn order
|
// Filter to agents actually in the turn order
|
||||||
const validIds = mentionedAccountIds.filter(id => state.turnOrder.includes(id));
|
const validIds = mentionedAccountIds.filter(id => state.turnOrder.includes(id));
|
||||||
if (validIds.length === 0) return false;
|
if (validIds.length === 0) {
|
||||||
|
console.log(`[dirigent][turn-debug] setMentionOverride ignored channel=${channelId} reason=no-valid-mentioned`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Order by their position in the current turn order
|
// Order by their position in the current turn order
|
||||||
validIds.sort((a, b) => state.turnOrder.indexOf(a) - state.turnOrder.indexOf(b));
|
validIds.sort((a, b) => state.turnOrder.indexOf(a) - state.turnOrder.indexOf(b));
|
||||||
@@ -208,6 +263,12 @@ export function setMentionOverride(channelId: string, mentionedAccountIds: strin
|
|||||||
state.noRepliedThisCycle = new Set();
|
state.noRepliedThisCycle = new Set();
|
||||||
state.lastChangedAt = Date.now();
|
state.lastChangedAt = Date.now();
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[dirigent][turn-debug] setMentionOverride applied channel=${channelId} ` +
|
||||||
|
`overrideOrder=${JSON.stringify(state.turnOrder)} current=${state.currentSpeaker} ` +
|
||||||
|
`savedOriginal=${JSON.stringify(state.savedTurnOrder || null)}`,
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user