From f1351bcbcf29d68046de4d49af9528dccd9ddb38 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 15 May 2026 16:13:01 +0100 Subject: [PATCH] fix: carry room event gateway actions --- extensions/telegram/src/bot-message.test.ts | 22 +++++++++++++++++++++ extensions/telegram/src/bot-message.ts | 8 +++++--- src/gateway/protocol/schema/agent.ts | 1 + src/gateway/server-methods/send.test.ts | 4 ++++ src/gateway/server-methods/send.ts | 2 ++ 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/extensions/telegram/src/bot-message.test.ts b/extensions/telegram/src/bot-message.test.ts index f0b26a1cbd94..ca6e9111254e 100644 --- a/extensions/telegram/src/bot-message.test.ts +++ b/extensions/telegram/src/bot-message.test.ts @@ -138,6 +138,28 @@ describe("telegram bot message processor", () => { ); }); + it("does not send early typing cues for room events", async () => { + const sendTyping = vi.fn().mockResolvedValue(undefined); + buildTelegramMessageContext.mockResolvedValue( + createMessageContext({ + sendTyping, + ctxPayload: { + From: "telegram:123", + To: "telegram:123", + ChatType: "group", + RawBody: "ambient", + InboundTurnKind: "room_event", + }, + }), + ); + + const processMessage = createTelegramMessageProcessor(baseDeps); + await processSampleMessage(processMessage); + + expect(sendTyping).not.toHaveBeenCalled(); + expect(dispatchTelegramMessage).toHaveBeenCalledTimes(1); + }); + it("skips dispatch when no context is produced", async () => { buildTelegramMessageContext.mockResolvedValue(null); const processMessage = createTelegramMessageProcessor(baseDeps); diff --git a/extensions/telegram/src/bot-message.ts b/extensions/telegram/src/bot-message.ts index 67baf263de91..6df70ae7fb36 100644 --- a/extensions/telegram/src/bot-message.ts +++ b/extensions/telegram/src/bot-message.ts @@ -155,9 +155,11 @@ export const createTelegramMessageProcessor = (deps: TelegramMessageProcessorDep (options?.ingressBuffer ? ` buffer=${options.ingressBuffer}` : ""), ); } - void context.sendTyping().catch((err) => { - logVerbose(`telegram early typing cue failed for chat ${context.chatId}: ${String(err)}`); - }); + if (context.ctxPayload.InboundTurnKind !== "room_event") { + void context.sendTyping().catch((err) => { + logVerbose(`telegram early typing cue failed for chat ${context.chatId}: ${String(err)}`); + }); + } telegramInboundLog.info( formatTelegramInboundLogLine({ from: context.ctxPayload.From, diff --git a/src/gateway/protocol/schema/agent.ts b/src/gateway/protocol/schema/agent.ts index e59375a1f05d..95fbffa5d903 100644 --- a/src/gateway/protocol/schema/agent.ts +++ b/src/gateway/protocol/schema/agent.ts @@ -79,6 +79,7 @@ export const MessageActionParamsSchema = Type.Object( senderIsOwner: Type.Optional(Type.Boolean()), sessionKey: Type.Optional(Type.String()), sessionId: Type.Optional(Type.String()), + inboundTurnKind: Type.Optional(Type.String({ enum: ["user_request", "room_event"] })), agentId: Type.Optional(Type.String()), toolContext: Type.Optional(MessageActionToolContextSchema), idempotencyKey: NonEmptyString, diff --git a/src/gateway/server-methods/send.test.ts b/src/gateway/server-methods/send.test.ts index 6ef666bf769a..321530c9cf9a 100644 --- a/src/gateway/server-methods/send.test.ts +++ b/src/gateway/server-methods/send.test.ts @@ -1265,6 +1265,7 @@ describe("gateway send mirroring", () => { emoji: "✅", }, requesterSenderId: "trusted-user", + inboundTurnKind: "room_event", toolContext: { currentGraphChannelId: "graph:team/chan", currentChannelProvider: "whatsapp", @@ -1291,6 +1292,9 @@ describe("gateway send mirroring", () => { undefined, { channel: "whatsapp" }, ); + expect(mocks.dispatchChannelMessageAction).toHaveBeenCalledWith( + expect.objectContaining({ inboundTurnKind: "room_event" }), + ); }); it("passes agent-scoped media roots to gateway message actions", async () => { diff --git a/src/gateway/server-methods/send.ts b/src/gateway/server-methods/send.ts index b059461dd88c..dba46bf67901 100644 --- a/src/gateway/server-methods/send.ts +++ b/src/gateway/server-methods/send.ts @@ -287,6 +287,7 @@ export const sendHandlers: GatewayRequestHandlers = { senderIsOwner?: boolean; sessionKey?: string; sessionId?: string; + inboundTurnKind?: "user_request" | "room_event"; agentId?: string; toolContext?: { currentChannelId?: string; @@ -364,6 +365,7 @@ export const sendHandlers: GatewayRequestHandlers = { senderIsOwner, sessionKey: normalizeOptionalString(request.sessionKey) ?? undefined, sessionId: normalizeOptionalString(request.sessionId) ?? undefined, + inboundTurnKind: request.inboundTurnKind, agentId: normalizeOptionalString(request.agentId) ?? undefined, mediaLocalRoots: getAgentScopedMediaLocalRoots( cfg,