Fix Telegram plugin callback routing#97174
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 1, 2026, 2:46 PM ET / 18:46 UTC. Summary Reproducibility: yes. Current-main source can miss registry-backed plugin handlers and fall through to Review metrics: 2 noteworthy metrics.
Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land the narrowed current-main merge result once maintainers accept the callback precedence boundary and exact current-head/current-main checks are green. Do we have a high-confidence way to reproduce the issue? Yes. Current-main source can miss registry-backed plugin handlers and fall through to Is this the best way to solve the issue? Yes. Resolving through live plugin registries keeps ownership at the plugin runtime boundary, avoids Telegram-specific plugin hardcoding, and avoids copying handlers back into stale global state. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 24ce672e06a8. Label changesLabel justifications:
Evidence reviewedWhat I checked:
Likely related people:
What the crustacean ranks mean
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
|
4dd6c35 to
9d3e68e
Compare
|
@openclaw-mantis telegram desktop proof: verify code-agent Telegram callback buttons route to the plugin handler, clear buttons, and do not send fallback callback_data text. |
|
Local Telegram Desktop proof for PR #97174 is complete. Sensitive Telegram identifiers are intentionally redacted from this public comment. Environment:
What was verified:
Final click artifact summary, redacted: {
"chatId": "<redacted-supergroup-id>",
"messageId": "<redacted-tdlib-message-id>",
"button": {
"text": "Approve",
"data": "<base64 callback data for code-agent:instrumented-proof-97174>"
},
"answer": {
"@type": "callbackQueryAnswer",
"show_alert": false,
"text": "",
"url": ""
},
"ok": true
}Plugin handler marker for the same callback, redacted: {"stage":"received","callbackId":"<redacted>","chatId":"<redacted-supergroup-id>","messageId":"<redacted-bot-message-id>","namespace":"code-agent","payload":"instrumented-proof-97174","senderId":"<redacted-qa-user-id>"}
{"stage":"clearButtons:ok","callbackId":"<redacted>","chatId":"<redacted-supergroup-id>","messageId":"<redacted-bot-message-id>","namespace":"code-agent","payload":"instrumented-proof-97174","senderId":"<redacted-qa-user-id>"}
{"stage":"reply:ok","callbackId":"<redacted>","chatId":"<redacted-supergroup-id>","messageId":"<redacted-bot-message-id>","namespace":"code-agent","payload":"instrumented-proof-97174","senderId":"<redacted-qa-user-id>"}
{"stage":"return","callbackId":"<redacted>","chatId":"<redacted-supergroup-id>","messageId":"<redacted-bot-message-id>","namespace":"code-agent","payload":"instrumented-proof-97174","senderId":"<redacted-qa-user-id>"}TDLib search proof: {
"queries": [
{ "query": "PR #97174 proof handled", "count": 5 },
{ "query": "callback_data:", "count": 0 },
{ "query": "instrumented plugin handler", "count": 1 }
]
}Validation run locally:
I also pushed follow-up coverage/tooling in
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Land-ready after maintainer fixups.
Verification:
The contributor's real Telegram Desktop proof on this PR remains the live user-path evidence. I did not repeat that external Telegram run after the lifecycle refactor; the focused retirement regression and exact-head hosted CI cover the maintainer changes. |
|
Merged via squash.
|
* fix telegram plugin callback routing * Add Telegram callback proof coverage * Fix proof script lint * Fix Telegram proof CI regressions * test: fix telegram callback proof CI regressions * fix: retire registry-owned callbacks * fix: retire registry-owned callbacks --------- Co-authored-by: Peter Steinberger <[email protected]>
* fix telegram plugin callback routing * Add Telegram callback proof coverage * Fix proof script lint * Fix Telegram proof CI regressions * test: fix telegram callback proof CI regressions * fix: retire registry-owned callbacks * fix: retire registry-owned callbacks --------- Co-authored-by: Peter Steinberger <[email protected]>
* fix telegram plugin callback routing * Add Telegram callback proof coverage * Fix proof script lint * Fix Telegram proof CI regressions * test: fix telegram callback proof CI regressions * fix: retire registry-owned callbacks * fix: retire registry-owned callbacks --------- Co-authored-by: Peter Steinberger <[email protected]>
* fix telegram plugin callback routing * Add Telegram callback proof coverage * Fix proof script lint * Fix Telegram proof CI regressions * test: fix telegram callback proof CI regressions * fix: retire registry-owned callbacks * fix: retire registry-owned callbacks --------- Co-authored-by: Peter Steinberger <[email protected]>
What Problem This Solves
Telegram inline-button callbacks such as
code-agent:<uuid>can fall through to the generic callback text path when the global plugin interactive handler state is empty, causing rawcallback_data: code-agent:<uuid>messages to be sent instead of routing to the OpenClaw Code Agent plugin handler.Why This Change Was Made
The fix restores plugin interactive handlers from the live plugin registry before reporting an interactive callback as unmatched, keeps the existing raw callback_data fallback for callbacks no plugin claims, and makes registry-stored interactive handlers participate in loader snapshot/restore rollback so failed plugin registration cannot leave executable handlers reachable.
User Impact
Telegram users pressing OpenClaw Code Agent inline buttons should get the intended plugin action, including button cleanup, instead of seeing raw callback data text in the chat. Failed plugin registration also no longer leaves stale interactive handlers available through the registry-backed recovery path.
Evidence
node scripts/run-vitest.mjs src/plugins/loader.test.ts -- -t "rolls back global side effects when registration fails"node scripts/run-vitest.mjs src/plugins/interactive.test.ts extensions/telegram/src/bot.test.ts -- -t "restores active registry interactive handlers before reporting unmatched callbacks|routes code-agent callbacks to plugin handlers and clears original buttons"Notes
This is the clean re-cut of the single task commit onto current origin/main, avoiding the release/2026.6.10 branch history that made the previous worktree appear thousands of commits ahead.