Skip to content

Commit 87c5f8b

Browse files
committed
fix(sdk): drop stale channel interaction callbacks instead of starting a turn
A channel interaction callback (for example a Slack button click) that resolves to a tool call with no matching pending tool part is a stale or duplicate callback. It was falling through to the inbound-message path, which acked, reacted, and ran a full agent turn. Such callbacks are now dropped: no turn runs and the run returns to its idle wait for the next message.
1 parent bbfb26e commit 87c5f8b

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

  • packages/trigger-sdk/src/v3

packages/trigger-sdk/src/v3/ai.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6925,6 +6925,7 @@ function chatAgent<
69256925
let channelConn: AnyChannelConnector | undefined;
69266926
let channelWorkingReaction: string | undefined;
69276927
let channelWireEvent: { event: unknown; deliveryId: string } | undefined;
6928+
let droppedStaleInteraction = false;
69286929
try {
69296930
// Extract turn-level context before entering the span. Slim
69306931
// wire: at most one delta message per record. `headStartMessages`
@@ -6962,6 +6963,14 @@ function chatAgent<
69626963
});
69636964
}
69646965
}
6966+
} else if (interaction) {
6967+
droppedStaleInteraction = true;
6968+
logger.debug(
6969+
"chat.agent: dropping stale channel interaction that matched no pending tool call",
6970+
{
6971+
deliveryId: wireChannelEvent.deliveryId,
6972+
}
6973+
);
69656974
} else {
69666975
effectiveIncomingMessage = toUserUIMessage(
69676976
channelConn.inbound(wireChannelEvent.event),
@@ -7244,7 +7253,7 @@ function chatAgent<
72447253
// snapshot + `session.out` replay (or `hydrateMessages`,
72457254
// which also fires per-turn below). Per-turn handling is
72467255
// therefore a delta merge, not a full-history reset.
7247-
if (currentWirePayload.trigger !== "action") {
7256+
if (currentWirePayload.trigger !== "action" && !droppedStaleInteraction) {
72487257
let cleanedUIMessages: TUIMessage[] = cleanedIncomingMessages;
72497258

72507259
// Turn-0 head-start with hydrateMessages: the boot seeding from
@@ -7543,7 +7552,7 @@ function chatAgent<
75437552
turn--;
75447553
}
75457554

7546-
if (!isAction) {
7555+
if (!isAction && !droppedStaleInteraction) {
75477556
// Mint a scoped public access token once per turn, reused for
75487557
// onChatStart, onTurnStart, onTurnComplete, and the turn-complete chunk.
75497558
const currentRunId = ctx.run.id;

0 commit comments

Comments
 (0)