Skip to content

Make Telegram sendMessage actions durable#87261

Merged
mbelinky merged 2 commits into
mainfrom
codex/durable-outbound-final-send
May 27, 2026
Merged

Make Telegram sendMessage actions durable#87261
mbelinky merged 2 commits into
mainfrom
codex/durable-outbound-final-send

Conversation

@mbelinky

Copy link
Copy Markdown
Contributor

Summary

  • Routes Telegram sendMessage action delivery through the durable outbound final-send path instead of direct Telegram platform sends.
  • Preserves Telegram action payload features on the durable path, including buttons, quote/reply options, media/voice options, session context, gateway scopes, and delivery pin requests.
  • Extends delivery pin scope propagation through the core outbound adapter seam and adds queue-level retry/ack proof.

Verification

  • node scripts/run-vitest.mjs extensions/telegram/src/action-runtime.test.ts extensions/telegram/src/outbound-adapter.test.ts src/infra/outbound/deliver.test.ts src/plugin-sdk/channel-message.test.ts -- --reporter=verbose passed: 4 files, 180 tests.
  • node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.core.json src/plugin-sdk/channel-outbound.ts src/channels/plugins/outbound.types.ts src/infra/outbound/deliver.ts src/infra/outbound/deliver.test.ts passed.
  • node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.extensions.json extensions/telegram/src/action-runtime.ts extensions/telegram/src/action-runtime.test.ts extensions/telegram/src/outbound-adapter.ts extensions/telegram/src/outbound-adapter.test.ts passed.
  • git diff --check origin/main...HEAD passed.
  • AUTOREVIEW_AUTO_TESTS=0 /Users/marianobelinky/agent-shared/skills/autoreview/scripts/autoreview --mode branch --base origin/main passed with no accepted/actionable findings.

Real behavior proof

Behavior addressed: Telegram sendMessage actions now enqueue durable final deliveries before the Telegram platform send, so a slow or timed-out gateway/platform send leaves retryable state instead of losing the completed agent output.
Real environment tested: Local OpenClaw source checkout using the real durable outbound queue code with a temporary OPENCLAW_STATE_DIR; Telegram platform calls were fault-injected in the focused action-runtime test.
Exact steps or command run after this patch: node scripts/run-vitest.mjs extensions/telegram/src/action-runtime.test.ts extensions/telegram/src/outbound-adapter.test.ts src/infra/outbound/deliver.test.ts src/plugin-sdk/channel-message.test.ts -- --reporter=verbose.
Evidence after fix: The new action-runtime test observes the queue entry on disk before the Telegram send runs, verifies timeout leaves a pending retryable entry with retryCount: 1, and verifies a later successful durable send is acked/removed.
Observed result after fix: Focused tests passed, including retry persistence, successful ack, delivery pin preservation, and gateway scope propagation into Telegram pinning.
What was not tested: Live Telegram delivery against a real bot was not run in this PR; this is covered with local queue/platform fault injection only.

@openclaw-barnacle openclaw-barnacle Bot added channel: telegram Channel integration: telegram size: M maintainer Maintainer-authored PR labels May 27, 2026
@clawsweeper

clawsweeper Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed May 27, 2026, 8:24 AM ET / 12:24 UTC.

Summary
The PR routes Telegram sendMessage actions through sendDurableMessageBatch, preserves action payload options on that path, propagates gateway scopes into delivery pinning, and adds focused queue/pin tests plus a changelog entry.

PR surface: Source +33, Tests +290, Docs +6. Total +329 across 9 files.

Reproducibility: yes. from source inspection: current main sends Telegram action messages directly, while the PR moves them to the queue with required durability. I did not run the PR tests in this read-only review.

Review metrics: 1 noteworthy metric.

  • Plugin/outbound API surfaces: 2 changed, 0 removed. The PR widens sendDurableMessageBatch parameters and adds gatewayClientScopes to pinDeliveredMessage, which are compatibility-sensitive plugin/outbound seams.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🧂 unranked krab
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Add live Telegram proof or redacted runtime logs showing the changed action-send delivery path after the patch; redact API keys, phone numbers, IPs, and private endpoints.
  • Make Telegram action sends replay-safe before using required durability, or keep this path best-effort and prove the upgrade behavior.
  • Remove the CHANGELOG.md edit and keep release-note context in the PR body or merge message.

Proof guidance:
Needs real behavior proof before merge: Needs real behavior proof before merge: the PR body reports focused tests and fault injection only, not live Telegram transport or redacted runtime logs showing the changed path. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • durability: "required" on Telegram action sends can leave ambiguous platform-start failures unrecoverable because Telegram does not currently provide reconcileUnknownSend.
  • The PR changes public/plugin-adjacent outbound seams by adding gatewayClientScopes to pinDeliveredMessage and widening sendDurableMessageBatch parameters, so maintainers should explicitly accept the compatibility surface.
  • The real behavior proof is synthetic only; live Telegram transport proof or redacted runtime logs are still missing.

Maintainer options:

  1. Preserve Replay Safety First (recommended)
    Change the action path to best-effort durability or add Telegram reconcileUnknownSend plus recovery coverage before making action sends required.
  2. Accept Ambiguous-Send Failure
    Maintainers can intentionally accept that ambiguous Telegram action sends may move to failed instead of replaying, but that contract should be explicit before merge.
  3. Pause For Transport Proof
    Hold the PR until live Telegram proof or redacted runtime logs show the changed action delivery path in a real setup.

Next step before merge
Maintainer review is needed to choose the Telegram required-durability contract and accept or reject the plugin SDK seam changes; the protected maintainer label also blocks cleanup closing.

Security
Cleared: The diff does not add dependencies, workflow execution, secret handling, or new third-party code execution; the main concerns are delivery correctness and compatibility.

Review findings

  • [P1] Require replay-safe durability before required sends — extensions/telegram/src/action-runtime.ts:512
  • [P3] Remove the release-owned changelog edit — CHANGELOG.md:5-9
Review details

Best possible solution:

Keep the durable action-send refactor only after the Telegram path is replay-safe: either use best-effort durability for Telegram action sends for now, or add Telegram unknown-send reconciliation plus focused recovery tests before requiring the queue.

Do we have a high-confidence way to reproduce the issue?

Yes from source inspection: current main sends Telegram action messages directly, while the PR moves them to the queue with required durability. I did not run the PR tests in this read-only review.

Is this the best way to solve the issue?

No; the durable path is the right direction, but required durability is not the best current fix unless Telegram can reconcile unknown sends. A safer path is best-effort durability or the same required-send support gate used by the message tool.

Full review comments:

  • [P1] Require replay-safe durability before required sends — extensions/telegram/src/action-runtime.ts:512
    This new path forces durability: "required", but Telegram's message adapter is built from the outbound adapter and does not declare or implement reconcileUnknownSend. The existing required message-send path checks that capability before using required durability; without the same guard or a Telegram reconciler, a timeout after platform send starts leaves the queued action send unrecoverable rather than safely durable.
    Confidence: 0.9
  • [P3] Remove the release-owned changelog edit — CHANGELOG.md:5-9
    Normal PRs should not edit CHANGELOG.md; this release note context already belongs in the PR body or squash/merge message, and release generation owns the changelog file.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against d09eb437f261.

Label changes

Label justifications:

  • P1: The PR changes Telegram message delivery durability for completed agent output, and the unresolved ambiguity can affect real channel replies.
  • merge-risk: 🚨 compatibility: The diff changes plugin/outbound-facing types and a public SDK helper signature, so maintainers need to accept the seam expansion.
  • merge-risk: 🚨 message-delivery: Required Telegram action sends are not replay-safe without unknown-send reconciliation, which can leave completed replies unrecovered after timeout or crash.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: Needs real behavior proof before merge: the PR body reports focused tests and fault injection only, not live Telegram transport or redacted runtime logs showing the changed path. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +33, Tests +290, Docs +6. Total +329 across 9 files.

View PR surface stats
Area Files Added Removed Net
Source 5 95 62 +33
Tests 3 301 11 +290
Docs 1 6 0 +6
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 9 402 73 +329

What I checked:

Likely related people:

  • Vincent Koc: git blame attributes the current Telegram action-send path, durable queue plumbing, and required message-send guard in this checkout to commit 1ba4448 by Vincent Koc. (role: recent area contributor; confidence: medium; commits: 1ba4448a60b6; files: extensions/telegram/src/action-runtime.ts, src/infra/outbound/deliver.ts, src/infra/outbound/message.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. labels May 27, 2026
@clawsweeper

clawsweeper Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

@mbelinky mbelinky force-pushed the codex/durable-outbound-final-send branch from 0a90acb to 208d069 Compare May 27, 2026 11:18
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels May 27, 2026
@mbelinky mbelinky force-pushed the codex/durable-outbound-final-send branch from d4eb1ac to 20b4568 Compare May 27, 2026 12:09
@mbelinky mbelinky merged commit f3fe48e into main May 27, 2026
113 of 161 checks passed
@mbelinky mbelinky deleted the codex/durable-outbound-final-send branch May 27, 2026 12:34
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 28, 2026
Route Telegram sendMessage action replies through durable outbound delivery so completed agent responses remain retryable when the gateway send path times out.

Verified with focused Telegram/outbound tests, extension test typecheck, prepare build/check/full test gates, and green CI rerun for head 20b4568.
eleboucher pushed a commit to eleboucher/homelab that referenced this pull request May 28, 2026
…026.5.27) (#698)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/openclaw/openclaw](https://openclaw.ai) ([source](https://github.com/openclaw/openclaw)) | patch | `2026.5.26` → `2026.5.27` |

---

### Release Notes

<details>
<summary>openclaw/openclaw (ghcr.io/openclaw/openclaw)</summary>

### [`v2026.5.27`](https://github.com/openclaw/openclaw/blob/HEAD/CHANGELOG.md#2026527)

[Compare Source](openclaw/openclaw@v2026.5.26...v2026.5.27)

##### Highlights

- Safer local/runtime boundaries: OpenClaw now rejects unsafe command wrappers, malformed CLI numeric options, unsafe Node runtime env overrides, no-auth Tailscale exposure, and non-admin device-role pairing approvals before they can affect live runs. ([#&#8203;87308](openclaw/openclaw#87308), [#&#8203;87305](openclaw/openclaw#87305), [#&#8203;87292](openclaw/openclaw#87292), [#&#8203;87146](openclaw/openclaw#87146))
- Matrix and auto-reply delivery are steadier: mention previews stay inert, final mention replies deliver normally, shared-DM notices are awaited, MXID parsing ignores filenames, and reasoning-prefixed `NO_REPLY` responses stay suppressed.
- Provider and agent reliability improved across OpenAI-compatible embeddings, cached token usage, Anthropic/Codex/Claude runtime state, unsupported tool-schema quarantine, heartbeat templates, and session fallback errors. ([#&#8203;85269](openclaw/openclaw#85269), [#&#8203;82062](openclaw/openclaw#82062), [#&#8203;85416](openclaw/openclaw#85416), [#&#8203;86855](openclaw/openclaw#86855))
- Plugin and package release paths got tighter: Pixverse ships as an external video plugin with region selection, package exclusions and shrinkwrap inventory match the published npm shape, and release/package smoke commands fail bounded instead of hanging.
- Gateway hot paths do less rediscovery by reusing current plugin metadata fingerprints, stable plugin index fingerprints, read-only session metadata, active working stores, status fast paths, and auth/env snapshots. ([#&#8203;86439](openclaw/openclaw#86439))

##### Changes

- Memory: add a core OpenAI-compatible embedding provider for local and hosted OpenAI-style endpoints, with config, doctor, and docs support. ([#&#8203;85269](openclaw/openclaw#85269)) Thanks [@&#8203;dutifulbob](https://github.com/dutifulbob).
- Plugin SDK: mark memory-specific embedding provider registration as deprecated compatibility and surface non-bundled usage in plugin compatibility diagnostics. ([#&#8203;85072](openclaw/openclaw#85072)) Thanks [@&#8203;mbelinky](https://github.com/mbelinky).
- Pixverse: add video generation provider support, API region selection, and external plugin publishing.
- Plugins: expose approval action metadata for plugin-driven approval surfaces.

##### Fixes

- Security/CLI/runtime: harden hostname normalization for repeated trailing dots, block side-effecting command wrappers, reject unsafe Node runtime env overrides, reject loose numeric CLI and gateway options, require admin approval for node device-role pairing, and reject no-auth Tailscale exposure. ([#&#8203;87305](openclaw/openclaw#87305), [#&#8203;87292](openclaw/openclaw#87292), [#&#8203;87308](openclaw/openclaw#87308), [#&#8203;87146](openclaw/openclaw#87146)) Thanks [@&#8203;pgondhi987](https://github.com/pgondhi987).
- Doctor: validate runtime tool schemas for every configured embedded agent while skipping ACP-only profiles, so bad non-default plugin or MCP tools are reported before assistant turns.
- Telegram: route `sendMessage` action replies through durable outbound delivery so completed agent responses remain retryable when the gateway send path times out. ([#&#8203;87261](openclaw/openclaw#87261)) Thanks [@&#8203;mbelinky](https://github.com/mbelinky).
- Matrix/auto-reply: keep draft previews mention-inert, preserve final mention delivery, send mention finals normally, await shared DM notices, ignore filename-embedded MXIDs, and suppress reasoning-prefixed `NO_REPLY` responses.
- Agents/providers: add OpenAI-compatible cache retention, forward cached token usage in chat completions, preserve runtime context before active user turns, strip stale Anthropic thinking, load Claude CLI OAuth for Pi auth profiles, avoid false Codex runtime live switches, and quarantine unsupported tool schemas. ([#&#8203;82062](openclaw/openclaw#82062), [#&#8203;87167](openclaw/openclaw#87167), [#&#8203;86855](openclaw/openclaw#86855))
- Gateway/performance: cache plugin metadata fingerprints and stable plugin index fingerprints, borrow read-only session metadata safely, keep the active session working store hot, keep status on a bounded fast path, and preserve model auth profile suffixes. ([#&#8203;86439](openclaw/openclaw#86439))
- Package/install/release: align npm package exclusions and inventory, omit unpacked test helpers, skip Homebrew until macOS packages need it, cap tsdown heap in containers, bound install/release smoke waits, and harden post-publish verification.
- Codex/Auth: bound ChatGPT OAuth token exchange and refresh requests, and honor cancellation across Codex and Anthropic OAuth login flows.
- QA/E2E/CI: bound Telegram, kitchen-sink, Open WebUI, ClawHub, MCP, Discord, realtime, labeler, and GitHub API waits; fail empty explicit test, live-media, gateway CPU, startup benchmark, plugin gauntlet, and beta-smoke runs instead of false-greening.
- Agents/Codex: keep spawned agent bootstrap files rooted in the agent workspace while running task commands, transcripts, and compaction from the requested cwd. ([#&#8203;87218](openclaw/openclaw#87218)) Thanks [@&#8203;mbelinky](https://github.com/mbelinky).

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/698
SYU8384 pushed a commit to SYU8384/openclaw that referenced this pull request Jun 3, 2026
Route Telegram sendMessage action replies through durable outbound delivery so completed agent responses remain retryable when the gateway send path times out.

Verified with focused Telegram/outbound tests, extension test typecheck, prepare build/check/full test gates, and green CI rerun for head 20b4568.
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
Route Telegram sendMessage action replies through durable outbound delivery so completed agent responses remain retryable when the gateway send path times out.

Verified with focused Telegram/outbound tests, extension test typecheck, prepare build/check/full test gates, and green CI rerun for head 20b4568.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: telegram Channel integration: telegram maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant