mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-03 13:22:14 +00:00
refactor: share approval interactive renderers
This commit is contained in:
@@ -1,10 +1,45 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
buildApprovalPendingReplyPayload,
|
||||
buildPluginApprovalPendingReplyPayload,
|
||||
buildPluginApprovalResolvedReplyPayload,
|
||||
} from "./approval-renderers.js";
|
||||
|
||||
describe("plugin-sdk/approval-renderers", () => {
|
||||
it("builds shared approval payloads with generic interactive commands", () => {
|
||||
const payload = buildApprovalPendingReplyPayload({
|
||||
approvalId: "plugin:approval-123",
|
||||
approvalSlug: "plugin:a",
|
||||
text: "Approval required @everyone",
|
||||
});
|
||||
|
||||
expect(payload.text).toContain("@\u200beveryone");
|
||||
expect(payload.interactive).toEqual({
|
||||
blocks: [
|
||||
{
|
||||
type: "buttons",
|
||||
buttons: [
|
||||
{
|
||||
label: "Allow Once",
|
||||
value: "/approve plugin:approval-123 allow-once",
|
||||
style: "success",
|
||||
},
|
||||
{
|
||||
label: "Allow Always",
|
||||
value: "/approve plugin:approval-123 always",
|
||||
style: "primary",
|
||||
},
|
||||
{
|
||||
label: "Deny",
|
||||
value: "/approve plugin:approval-123 deny",
|
||||
style: "danger",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("builds plugin pending payloads with approval metadata and extra channel data", () => {
|
||||
const payload = buildPluginApprovalPendingReplyPayload({
|
||||
request: {
|
||||
@@ -20,12 +55,36 @@ describe("plugin-sdk/approval-renderers", () => {
|
||||
approvalSlug: "custom-slug",
|
||||
channelData: {
|
||||
telegram: {
|
||||
buttons: [[{ text: "Allow Once", callback_data: "/approve id allow-once" }]],
|
||||
quoteText: "quoted",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(payload.text).toContain("Plugin approval required");
|
||||
expect(payload.interactive).toEqual({
|
||||
blocks: [
|
||||
{
|
||||
type: "buttons",
|
||||
buttons: [
|
||||
{
|
||||
label: "Allow Once",
|
||||
value: "/approve plugin-approval-123 allow-once",
|
||||
style: "success",
|
||||
},
|
||||
{
|
||||
label: "Allow Always",
|
||||
value: "/approve plugin-approval-123 always",
|
||||
style: "primary",
|
||||
},
|
||||
{
|
||||
label: "Deny",
|
||||
value: "/approve plugin-approval-123 deny",
|
||||
style: "danger",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(payload.channelData).toMatchObject({
|
||||
execApproval: {
|
||||
approvalId: "plugin-approval-123",
|
||||
@@ -33,7 +92,7 @@ describe("plugin-sdk/approval-renderers", () => {
|
||||
allowedDecisions: ["allow-once", "allow-always", "deny"],
|
||||
},
|
||||
telegram: {
|
||||
buttons: [[{ text: "Allow Once", callback_data: "/approve id allow-once" }]],
|
||||
quoteText: "quoted",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import type { ReplyPayload } from "../auto-reply/types.js";
|
||||
import type { ExecApprovalReplyDecision } from "../infra/exec-approval-reply.js";
|
||||
import {
|
||||
buildApprovalInteractiveReply,
|
||||
type ExecApprovalReplyDecision,
|
||||
} from "../infra/exec-approval-reply.js";
|
||||
import {
|
||||
buildPluginApprovalRequestMessage,
|
||||
buildPluginApprovalResolvedMessage,
|
||||
@@ -9,6 +12,39 @@ import {
|
||||
|
||||
const DEFAULT_ALLOWED_DECISIONS = ["allow-once", "allow-always", "deny"] as const;
|
||||
|
||||
function neutralizeApprovalText(value: string): string {
|
||||
return value
|
||||
.replace(/@everyone/gi, "@\u200beveryone")
|
||||
.replace(/@here/gi, "@\u200bhere")
|
||||
.replace(/<@/g, "<@\u200b")
|
||||
.replace(/<#/g, "<#\u200b");
|
||||
}
|
||||
|
||||
export function buildApprovalPendingReplyPayload(params: {
|
||||
approvalId: string;
|
||||
approvalSlug: string;
|
||||
text: string;
|
||||
allowedDecisions?: readonly ExecApprovalReplyDecision[];
|
||||
channelData?: Record<string, unknown>;
|
||||
}): ReplyPayload {
|
||||
const allowedDecisions = params.allowedDecisions ?? DEFAULT_ALLOWED_DECISIONS;
|
||||
return {
|
||||
text: neutralizeApprovalText(params.text),
|
||||
interactive: buildApprovalInteractiveReply({
|
||||
approvalId: params.approvalId,
|
||||
allowedDecisions,
|
||||
}),
|
||||
channelData: {
|
||||
execApproval: {
|
||||
approvalId: params.approvalId,
|
||||
approvalSlug: params.approvalSlug,
|
||||
allowedDecisions,
|
||||
},
|
||||
...params.channelData,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function buildPluginApprovalPendingReplyPayload(params: {
|
||||
request: PluginApprovalRequest;
|
||||
nowMs: number;
|
||||
@@ -17,17 +53,13 @@ export function buildPluginApprovalPendingReplyPayload(params: {
|
||||
allowedDecisions?: readonly ExecApprovalReplyDecision[];
|
||||
channelData?: Record<string, unknown>;
|
||||
}): ReplyPayload {
|
||||
return {
|
||||
return buildApprovalPendingReplyPayload({
|
||||
approvalId: params.request.id,
|
||||
approvalSlug: params.approvalSlug ?? params.request.id.slice(0, 8),
|
||||
text: params.text ?? buildPluginApprovalRequestMessage(params.request, params.nowMs),
|
||||
channelData: {
|
||||
execApproval: {
|
||||
approvalId: params.request.id,
|
||||
approvalSlug: params.approvalSlug ?? params.request.id.slice(0, 8),
|
||||
allowedDecisions: params.allowedDecisions ?? DEFAULT_ALLOWED_DECISIONS,
|
||||
},
|
||||
...params.channelData,
|
||||
},
|
||||
};
|
||||
allowedDecisions: params.allowedDecisions,
|
||||
channelData: params.channelData,
|
||||
});
|
||||
}
|
||||
|
||||
export function buildPluginApprovalResolvedReplyPayload(params: {
|
||||
@@ -37,10 +69,14 @@ export function buildPluginApprovalResolvedReplyPayload(params: {
|
||||
}): ReplyPayload {
|
||||
return params.channelData
|
||||
? {
|
||||
text: params.text ?? buildPluginApprovalResolvedMessage(params.resolved),
|
||||
text: neutralizeApprovalText(
|
||||
params.text ?? buildPluginApprovalResolvedMessage(params.resolved),
|
||||
),
|
||||
channelData: params.channelData,
|
||||
}
|
||||
: {
|
||||
text: params.text ?? buildPluginApprovalResolvedMessage(params.resolved),
|
||||
text: neutralizeApprovalText(
|
||||
params.text ?? buildPluginApprovalResolvedMessage(params.resolved),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ export {
|
||||
} from "../infra/plugin-approvals.js";
|
||||
export { createApproverRestrictedNativeApprovalAdapter } from "./approval-delivery-helpers.js";
|
||||
export {
|
||||
buildApprovalPendingReplyPayload,
|
||||
buildPluginApprovalPendingReplyPayload,
|
||||
buildPluginApprovalResolvedReplyPayload,
|
||||
} from "./approval-renderers.js";
|
||||
|
||||
Reference in New Issue
Block a user