Skip to content

fix(googlechat): keep off-mode replies out of threads#104402

Merged
steipete merged 6 commits into
mainfrom
codex/fix-googlechat-reply-targets
Jul 11, 2026
Merged

fix(googlechat): keep off-mode replies out of threads#104402
steipete merged 6 commits into
mainfrom
codex/fix-googlechat-reply-targets

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Supersedes #89790.

Fixes #42510.

Carries forward focused source work from #74235, #43112, #67055, and #30965.

What Problem This Solves

Fixes an issue where Google Chat users configured with default or explicit replyToMode: "off" could still see typing placeholders or durable final replies routed into the inbound thread.

Why This Change Was Made

The Google Chat monitor now records each typing placeholder together with the thread where it was created, chooses that initial thread from the configured reply mode, and replaces the placeholder when the resolved final target differs. Durable top-level replies pass an explicit null reply target so shared delivery cannot fall back to stale inbound thread metadata.

The single placeholder value replaces the prior parallel optional-name/thread shape, keeping placeholder identity and location consistent through cleanup, edit, and fallback sends.

User Impact

Default and off-mode Google Chat replies remain top-level, while threaded modes and explicit reply directives still target the intended thread. Typing placeholders no longer leave the final answer on a different conversation surface.

Evidence

  • Blacksmith Testbox through Crabbox: tbx_01kx8b9hmbtq5nrq4t2snwfc9t.
  • Focused: pnpm test extensions/googlechat/src/monitor-durable.test.ts extensions/googlechat/src/monitor.reply-delivery.test.ts extensions/googlechat/src/monitor.test.ts — 3 files, 26 tests passed.
  • Broad: pnpm test extensions/googlechat — 20 files, 199 tests passed.
  • Changed gate: pnpm check:changed — extension typechecks, lint, changelog attribution, dependency, import-cycle, and repository guards passed.
  • Fresh Codex autoreview: clean, no accepted or actionable findings.
  • Google Chat API contract checked against the current official spaces.messages.create documentation: omitting thread starts a new thread, while replying to an existing thread requires its thread.name plus messageReplyOption.
  • Live provider round-trip not run: the local maintainer profile, hydrated Testbox, and repository Actions secrets have no Google Chat service-account credential or live Google Chat workflow. No mock result is presented as live proof.

Co-authored-by: Jai Govindani <[email protected]>

Co-authored-by: Neerav Makwana <[email protected]>

Co-authored-by: banddude <[email protected]>

Co-authored-by: Novan Adrian <[email protected]>
@steipete steipete self-assigned this Jul 11, 2026
@openclaw-barnacle openclaw-barnacle Bot added channel: googlechat Channel integration: googlechat size: S maintainer Maintainer-authored PR labels Jul 11, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5a7674e7c6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread CHANGELOG.md Outdated
- **iOS Share Extension drafts:** preserve legitimate shared text beginning with scaffold-like prefixes, remove only exact legacy scaffold lines, avoid treating scheme-like prose as a URL, and deduplicate host-mirrored content. (#103453) Thanks @lin-hongkuan.
- **Telegram reasoning previews:** reposition split reasoning previews through deferred deletion so prior preview messages do not remain stale while preserving client scroll position. (#97828) Thanks @ly-wang19.
- **Feishu native-card threading:** normalize whitespace reply targets once and reuse the shared reply mode for card and media parts so native-card topic replies stay in their thread. (#102804) Thanks @sunlit-deng.
- **Google Chat reply targeting:** honor default and explicit off modes before creating typing placeholders, replace placeholders when explicit final targets differ, and suppress durable fallback to stale inbound threads. (#89790, #42510) Thanks @jai, @neeravmakwana, @banddude, and @novan.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove normal-fix changelog entry

For this normal Google Chat fix, adding an Unreleased entry conflicts with the root AGENTS.md changelog rule that CHANGELOG.md is release-only and generated from merged PRs/direct commits. Leaving this in the diff risks duplicate or stale release notes when the release generator rebuilds the changelog; keep the release-note context in the commit/PR text and remove this entry.

Useful? React with 👍 / 👎.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: matrix Channel integration: matrix app: web-ui App: web-ui gateway Gateway runtime size: XL and removed size: S labels Jul 11, 2026
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. labels Jul 11, 2026
@clawsweeper

clawsweeper Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Codex review: stale review; fresh review needed.

Summary
The latest durable ClawSweeper review was for head 638487dd27e0d7d995d79f5ac9cee685eab5b00d, but the PR head is now 4a16f6b70ab488a81e840f91625cad7f40b66eff. Its old verdict and PR readiness labels are no longer current.

Next step
Run or wait for a fresh ClawSweeper review on the current PR head.

Review history (1 earlier review cycle)
  • reviewed 2026-07-11T10:46:07.984Z sha 715cd99 :: needs real behavior proof before merge. :: none

@openclaw-barnacle openclaw-barnacle Bot added the app: macos App: macos label Jul 11, 2026
@clawsweeper clawsweeper Bot removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 11, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4a16f6b70a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

});
typingMessageName = result?.messageName;
if (result?.messageName) {
typingMessage = { name: result.messageName, thread: typingMessageThreadName };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Track fallback thread before editing typing message

When Google Chat falls back while creating the typing placeholder, this records the requested thread instead of the thread returned by the API. sendGoogleChatMessage opts into REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD whenever thread is provided and returns threadName from the created message; the official spaces.messages.create docs say that option starts a new thread if replying fails (https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages/create). In that fallback case the final payload can still target the original thread, typingMessageThreadName === replyThreadName here, so delivery edits the placeholder that actually lives in the fallback thread instead of deleting it and sending the final reply to the intended thread.

Useful? React with 👍 / 👎.

@steipete

Copy link
Copy Markdown
Contributor Author

Land-ready proof on exact PR head 4a16f6b70ab488a81e840f91625cad7f40b66eff:

  • Blacksmith Testbox tbx_01kx8b9hmbtq5nrq4t2snwfc9t: focused Google Chat delivery suite passed (3 files, 26 tests).
  • Same Testbox: full extensions/googlechat suite passed (20 files, 199 tests).
  • Same Testbox: pnpm check:changed passed extension typechecks, lint, dependency/import-cycle/database guards, and repository checks.
  • Fresh Codex autoreview reported no accepted/actionable findings.
  • Exact-head hosted CI succeeded: https://github.com/openclaw/openclaw/actions/runs/29149958216
  • Native prepare completed with hosted exact/recent-rebase gates and verified the remote PR tree.

The implementation keeps placeholder identity and thread location together, resolves the final thread target once, replaces rather than edits a placeholder when that target changes, and uses the shared explicit-null durable-delivery contract to prevent stale inbound reply metadata from returning. This matches Google Chat's API contract: omitting thread creates a top-level message, while threaded replies provide thread.name and a reply option: https://developers.google.com/workspace/chat/create-messages

Live Google Chat service proof is the remaining explicit gap: neither the local profile, the hydrated Testbox, nor repository Actions secrets expose a Google Chat service-account credential or a live Google Chat workflow. No mocked check is represented here as live provider proof.

@steipete
steipete merged commit 8756cc4 into main Jul 11, 2026
116 of 122 checks passed
@steipete
steipete deleted the codex/fix-googlechat-reply-targets branch July 11, 2026 10:57
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 12, 2026
* fix(googlechat): align reply and typing targets

Co-authored-by: Jai Govindani <[email protected]>

Co-authored-by: Neerav Makwana <[email protected]>

Co-authored-by: banddude <[email protected]>

Co-authored-by: Novan Adrian <[email protected]>

* chore(googlechat): leave changelog to release automation

* style(googlechat): apply canonical formatting

* chore(googlechat): leave changelog to release automation

* style(googlechat): keep monitor imports canonical

* style(googlechat): keep monitor imports canonical

---------

Co-authored-by: Novan Adrian <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: macos App: macos app: web-ui App: web-ui channel: googlechat Channel integration: googlechat channel: matrix Channel integration: matrix docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR P1 High-priority user-facing bug, regression, or broken workflow. size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Google Chat: replyToMode: "off" does not suppress thread replies

1 participant