From d7ede3cd68ed0d3703e358565f49f4879499ba78 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 29 Jan 2026 07:15:37 +0000 Subject: [PATCH] fix(googlechat): space events response and thread context Two fixes for Google Chat reliability: 1. Space Events Response (Fixes 'Can't handle app response' error): - Return proper JSON response for non-MESSAGE events in groups - Handles ADDED_TO_SPACE, REMOVED_FROM_SPACE, etc. - Previously returned empty '{}' which caused errors 2. Thread Reply Context (Adds missing context): - Add threadReply field to GoogleChatMessage type - Add quotedMessageMetadata field for quoted messages - Pass IsThreadReply and QuotedMessageId to agent context - Agent now knows when a message is a reply vs root message Both fixes improve Google Chat reliability and agent context awareness. --- extensions/googlechat/src/monitor.ts | 16 ++++++++++++++++ extensions/googlechat/src/types.ts | 9 +++++++++ 2 files changed, 25 insertions(+) diff --git a/extensions/googlechat/src/monitor.ts b/extensions/googlechat/src/monitor.ts index b3ad36049..459902795 100644 --- a/extensions/googlechat/src/monitor.ts +++ b/extensions/googlechat/src/monitor.ts @@ -264,6 +264,19 @@ export async function handleGoogleChatWebhookRequest( } selected.statusSink?.({ lastInboundAt: Date.now() }); + + // For synchronous responses in spaces, handle non-MESSAGE events immediately + const evtType = (event.type ?? (event as { eventType?: string }).eventType)?.toUpperCase(); + const isGroup = event.space?.type?.toUpperCase() !== "DM"; + + // For non-MESSAGE events in groups (like ADDED_TO_SPACE), return an acknowledgment + if (isGroup && evtType !== "MESSAGE") { + res.statusCode = 200; + res.setHeader("Content-Type", "application/json"); + res.end(JSON.stringify({ text: "Hello! I'm ready to help. 🦞" })); + return true; + } + processGoogleChatEvent(event, selected).catch((err) => { selected?.runtime.error?.( `[${selected.account.accountId}] Google Chat webhook failed: ${String(err)}`, @@ -642,6 +655,9 @@ async function processMessageWithPipeline(params: { GroupSystemPrompt: isGroup ? groupSystemPrompt : undefined, OriginatingChannel: "googlechat", OriginatingTo: `googlechat:${spaceId}`, + // Thread reply context + IsThreadReply: message.threadReply, + QuotedMessageId: message.quotedMessageMetadata?.name, }); void core.channel.session diff --git a/extensions/googlechat/src/types.ts b/extensions/googlechat/src/types.ts index 820c96425..74c9d7867 100644 --- a/extensions/googlechat/src/types.ts +++ b/extensions/googlechat/src/types.ts @@ -47,6 +47,11 @@ export type GoogleChatAnnotation = { customEmojiMetadata?: Record; }; +export type GoogleChatQuotedMessageMetadata = { + name?: string; + lastUpdateTime?: string; +}; + export type GoogleChatMessage = { name?: string; text?: string; @@ -55,6 +60,10 @@ export type GoogleChatMessage = { thread?: GoogleChatThread; attachment?: GoogleChatAttachment[]; annotations?: GoogleChatAnnotation[]; + /** True if this message is a reply in a thread */ + threadReply?: boolean; + /** Metadata about the quoted/original message being replied to */ + quotedMessageMetadata?: GoogleChatQuotedMessageMetadata; }; export type GoogleChatEvent = {