Compare commits

..

1 Commits

Author SHA1 Message Date
zhi
fb2cbaa5b3 fix: only process assistant messages in before_message_write
before_message_write fires for both user (incoming) and assistant
(outgoing) messages. Without a role check, end symbols from other
agents' incoming messages incorrectly trigger turn advances.

Add role check to skip non-assistant messages early.
2026-03-02 11:20:39 +00:00
2 changed files with 16 additions and 22 deletions

View File

@@ -932,9 +932,17 @@ export default {
}
// Extract content from event.message (AgentMessage)
// IMPORTANT: Only process assistant messages — before_message_write fires for both
// user (incoming) and assistant (outgoing) messages. Processing user messages would
// incorrectly detect end symbols from OTHER agents' messages and advance the turn.
let content = "";
const msg = (event as Record<string, unknown>).message as Record<string, unknown> | undefined;
if (msg) {
const role = msg.role as string | undefined;
if (role && role !== "assistant") {
// Skip non-assistant messages (user messages, system messages, etc.)
return;
}
// AgentMessage may have content as string or nested
if (typeof msg.content === "string") {
content = msg.content;
@@ -960,17 +968,6 @@ 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);

View File

@@ -932,9 +932,17 @@ export default {
}
// Extract content from event.message (AgentMessage)
// IMPORTANT: Only process assistant messages — before_message_write fires for both
// user (incoming) and assistant (outgoing) messages. Processing user messages would
// incorrectly detect end symbols from OTHER agents' messages and advance the turn.
let content = "";
const msg = (event as Record<string, unknown>).message as Record<string, unknown> | undefined;
if (msg) {
const role = msg.role as string | undefined;
if (role && role !== "assistant") {
// Skip non-assistant messages (user messages, system messages, etc.)
return;
}
// AgentMessage may have content as string or nested
if (typeof msg.content === "string") {
content = msg.content;
@@ -960,17 +968,6 @@ 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);