fix(telegram): preserve inline buttons when capabilities array is empty#96109
fix(telegram): preserve inline buttons when capabilities array is empty#96109hanZeng-08 wants to merge 1 commit into
Conversation
Empty array capabilities should not disable inline buttons. The default
inline buttons scope ('allowlist') should still apply when the user has
set an empty capabilities array, rather than treating it as an explicit
'off' signal.
Fixes openclaw#96098
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close: this PR is a useful same-root-cause fix, but #96468 is the stronger canonical landing path for the linked Telegram regression because it is open, mergeable, proof-positive, and covers the same empty-array behavior plus prompt/action/account fallback cases. Canonical path: Close this PR in favor of #96468 as the canonical landing path for #96098, then close the issue after one fix lands. So I’m closing this here and keeping the remaining discussion on #96468 and #96098. Review detailsBest possible solution: Close this PR in favor of #96468 as the canonical landing path for #96098, then close the issue after one fix lands. Do we have a high-confidence way to reproduce the issue? Yes from source: current main and v2026.6.10 route an empty Telegram legacy capabilities array to Is this the best way to solve the issue? No for this branch as the landing path: the resolver fix is plausible, but #96468 is the safer solution because it includes the same behavior change with live proof and broader regression coverage. Security review: Security review cleared: The diff only changes pure Telegram config normalization and a colocated test; it does not touch dependencies, CI, secrets, package metadata, or code-execution surfaces. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against fa2379dbc883. |
|
@clawsweeper re-review I don't have a live Telegram bot environment, so I added config-layer proof instead. Before fix (old code): $ npx tsx -e "import { resolveTelegramInlineButtonsScope } from './extensions/telegram/src/inline-buttons.ts'; const cfg = { channels: { telegram: { capabilities: [] } } } as any; console.log(resolveTelegramInlineButtonsScope({ cfg }));"
offAfter fix (new code): $ npx tsx -e "import { resolveTelegramInlineButtonsScope } from './extensions/telegram/src/inline-buttons.ts'; const cfg = { channels: { telegram: { capabilities: [] } } } as any; console.log(resolveTelegramInlineButtonsScope({ cfg }));"
allowlistThe fix is at the config-normalization layer ( |
|
🦞🧹 I asked ClawSweeper to review this item again. |
Real behavior proof (alternative — no live Telegram environment available)I do not have a live Telegram bot environment to provide a screenshot. However, the fix is a pure config-logic change, and the behavior difference can be demonstrated with a standalone Node script that isolates the exact function. Before fix (old code behavior)$ node -e "
// Simulated old resolveTelegramInlineButtonsScopeFromCapabilities
const DEFAULT_INLINE_BUTTONS_SCOPE = 'allowlist';
function resolveTelegramInlineButtonsScopeFromCapabilities(capabilities) {
if (!capabilities) return DEFAULT_INLINE_BUTTONS_SCOPE;
if (Array.isArray(capabilities)) {
const enabled = capabilities.some(
(entry) => (String(entry).trim().toLowerCase()) === 'inlinebuttons'
);
return enabled ? 'all' : 'off';
}
return DEFAULT_INLINE_BUTTONS_SCOPE;
}
console.log('[]:', resolveTelegramInlineButtonsScopeFromCapabilities([]));
console.log('[\"inlinebuttons\"]:', resolveTelegramInlineButtonsScopeFromCapabilities(['inlinebuttons']));
console.log('undefined:', resolveTelegramInlineButtonsScopeFromCapabilities(undefined));
console.log('{ inlineButtons: \"off\" }:', resolveTelegramInlineButtonsScopeFromCapabilities({ inlineButtons: 'off' }));
"Output: Problem: After fix (new code behavior)$ node -e "
const DEFAULT_INLINE_BUTTONS_SCOPE = 'allowlist';
function resolveTelegramInlineButtonsScopeFromCapabilities(capabilities) {
if (!capabilities) return DEFAULT_INLINE_BUTTONS_SCOPE;
if (Array.isArray(capabilities)) {
const normalized = capabilities
.map((entry) => String(entry).trim().toLowerCase())
.filter(Boolean);
if (normalized.length === 0) return DEFAULT_INLINE_BUTTONS_SCOPE;
return normalized.includes('inlinebuttons') ? 'all' : 'off';
}
return DEFAULT_INLINE_BUTTONS_SCOPE;
}
console.log('[]:', resolveTelegramInlineButtonsScopeFromCapabilities([]));
console.log('[\"inlinebuttons\"]:', resolveTelegramInlineButtonsScopeFromCapabilities(['inlinebuttons']));
console.log('undefined:', resolveTelegramInlineButtonsScopeFromCapabilities(undefined));
console.log('{ inlineButtons: \"off\" }:', resolveTelegramInlineButtonsScopeFromCapabilities({ inlineButtons: 'off' }));
"Output: Fix: Tests pass$ pnpm test extensions/telegram/src/inline-buttons.test.ts
Test Files 1 passed (1)
Tests 15 passed (15)The new regression test ( What was not tested
Proof limitationsThe evidence is unit-test-based and standalone script output. No live Telegram interaction was exercised. The config logic change is narrow and deterministic; the regression test is the primary guard. |
|
@clawsweeper re-review |
|
closing this duplicate after the canonical fix landed in #96468. #96468 preserves the documented default for Canonical merge: 3217165 |
Fixes #96098
What Problem This Solves
Fixes an issue where Telegram bots would stop generating inline keyboard buttons when
channels.telegram.capabilitiesis set to an empty array[]. After updating to 2026.6.9, users observed that button options were rendered as plain text lists (e.g.,- Option A\n- Option B) instead of clickable inline keyboards, breaking interactive workflows.Why This Change Was Made
resolveTelegramInlineButtonsScopeFromCapabilitieswas returningundefinedwhen given an empty capabilities array, which is not a validTelegramInlineButtonsScopevalue. An empty array should mean "no explicit capabilities declared" and fall back to the default"allowlist"scope, rather than being interpreted as a signal to disable inline buttons. The fix changes one line: returnDEFAULT_INLINE_BUTTONS_SCOPEinstead ofundefinedwhen the normalized array is empty.User Impact
Telegram users with an empty
capabilitiesarray in their config will now see inline buttons restored to their normal behavior. Users who explicitly setcapabilities: ["inlinebuttons"]orcapabilities: { inlineButtons: "off" }are unaffected.Evidence
Environment: Linux, Node v22.23.0, pnpm v11.2.2, worktree SHA 2af0604
Before fix (new regression test on old code):
After fix (new regression test on new code):
$ pnpm test extensions/telegram/src/inline-buttons.test.ts Test Files 1 passed (1) Tests 16 passed (16)No other tests broken:
$ pnpm test src/config/channel-capabilities.test.ts Test Files 1 passed (1) Tests 7 passed (7)Lint/format clean: