fix: advance turn in before_message_write to prevent race condition
When a speaker finishes with an end symbol, the turn was only advanced in the message_sent hook. But by that time, the message had already been broadcast to other agents, whose before_model_resolve ran with the old turn state, causing them to be blocked by the turn gate (forced no-reply). Fix: - Move turn advance for both NO_REPLY and end-symbol cases to before_message_write, which fires before the message is broadcast. - Only the current speaker's before_message_write advances the turn. Other agents (forced no-reply or not in turn) are skipped early. - Use sessionTurnHandled set to prevent double-advancing in message_sent.
This commit is contained in:
11
dist/whispergate/index.ts
vendored
11
dist/whispergate/index.ts
vendored
@@ -960,6 +960,17 @@ export default {
|
||||
|
||||
if (!key || !channelId || !accountId) return;
|
||||
|
||||
// Only the current speaker should advance the turn.
|
||||
// Other agents also trigger before_message_write (for incoming messages or forced no-reply),
|
||||
// but they must not affect turn state.
|
||||
const currentTurn = getTurnDebugInfo(channelId);
|
||||
if (currentTurn.currentSpeaker !== accountId) {
|
||||
api.logger.info(
|
||||
`whispergate: before_message_write skipping non-current-speaker session=${key} accountId=${accountId} currentSpeaker=${currentTurn.currentSpeaker}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const live = getLivePluginConfig(api, baseConfig as WhisperGateConfig) as WhisperGateConfig & DebugConfig;
|
||||
ensurePolicyStateLoaded(api, live);
|
||||
const policy = resolvePolicy(live, channelId, policyState.channelPolicies);
|
||||
|
||||
@@ -960,6 +960,17 @@ export default {
|
||||
|
||||
if (!key || !channelId || !accountId) return;
|
||||
|
||||
// Only the current speaker should advance the turn.
|
||||
// Other agents also trigger before_message_write (for incoming messages or forced no-reply),
|
||||
// but they must not affect turn state.
|
||||
const currentTurn = getTurnDebugInfo(channelId);
|
||||
if (currentTurn.currentSpeaker !== accountId) {
|
||||
api.logger.info(
|
||||
`whispergate: before_message_write skipping non-current-speaker session=${key} accountId=${accountId} currentSpeaker=${currentTurn.currentSpeaker}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const live = getLivePluginConfig(api, baseConfig as WhisperGateConfig) as WhisperGateConfig & DebugConfig;
|
||||
ensurePolicyStateLoaded(api, live);
|
||||
const policy = resolvePolicy(live, channelId, policyState.channelPolicies);
|
||||
|
||||
Reference in New Issue
Block a user