fix(approvals): make exec approval fallback guidance channel-specific (#61424)

Merged via squash.

Prepared head SHA: cb5d3c249c
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
Gustavo Madeira Santana
2026-04-05 14:26:46 -04:00
committed by GitHub
parent 84e76f7cce
commit 0ef9383487
23 changed files with 462 additions and 30 deletions

View File

@@ -4,7 +4,7 @@ import path from "node:path";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { describe, expect, it } from "vitest";
import { clearSessionStoreCacheForTest } from "../../../src/config/sessions.js";
import { telegramNativeApprovalAdapter } from "./approval-native.js";
import { telegramApprovalCapability, telegramNativeApprovalAdapter } from "./approval-native.js";
function buildConfig(
overrides?: Partial<NonNullable<NonNullable<OpenClawConfig["channels"]>["telegram"]>>,
@@ -32,6 +32,31 @@ function writeStore(store: Record<string, unknown>) {
}
describe("telegram native approval adapter", () => {
it("describes the correct Telegram exec-approval setup path", () => {
const text = telegramApprovalCapability.describeExecApprovalSetup?.({
channel: "telegram",
channelLabel: "Telegram",
});
expect(text).toContain("`channels.telegram.execApprovals.approvers`");
expect(text).toContain("`channels.telegram.allowFrom`");
expect(text).toContain("`channels.telegram.defaultTo`");
expect(text).not.toContain("`channels.telegram.dm.allowFrom`");
});
it("describes the named-account Telegram exec-approval setup path", () => {
const text = telegramApprovalCapability.describeExecApprovalSetup?.({
channel: "telegram",
channelLabel: "Telegram",
accountId: "work",
});
expect(text).toContain("`channels.telegram.accounts.work.execApprovals.approvers`");
expect(text).toContain("`channels.telegram.accounts.work.allowFrom`");
expect(text).toContain("`channels.telegram.accounts.work.defaultTo`");
expect(text).not.toContain("`channels.telegram.allowFrom`");
});
it("normalizes direct-chat origin targets so DM dedupe can converge", async () => {
const target = await telegramNativeApprovalAdapter.native?.resolveOriginTarget?.({
cfg: buildConfig(),

View File

@@ -91,6 +91,13 @@ const resolveTelegramApproverDmTargets = createChannelApproverDmTargetResolver({
const telegramNativeApprovalCapability = createApproverRestrictedNativeApprovalCapability({
channel: "telegram",
channelLabel: "Telegram",
describeExecApprovalSetup: ({ accountId }) => {
const prefix =
accountId && accountId !== "default"
? `channels.telegram.accounts.${accountId}`
: "channels.telegram";
return `Approve it from the Web UI or terminal UI for now. Telegram supports native exec approvals for this account. Configure \`${prefix}.execApprovals.approvers\`; if you leave it unset, OpenClaw can infer numeric owner IDs from \`${prefix}.allowFrom\` or direct-message \`${prefix}.defaultTo\` when possible. Leave \`${prefix}.execApprovals.enabled\` unset/\`auto\` or set it to \`true\`.`;
},
listAccountIds: listTelegramAccountIds,
hasApprovers: ({ cfg, accountId }) =>
getTelegramExecApprovalApprovers({ cfg, accountId }).length > 0,