mirror of https://github.com/openclaw/openclaw.git
Approvals: tag Matrix suppression payloads
This commit is contained in:
parent
1b992f0bde
commit
d9f048e827
|
|
@ -159,6 +159,51 @@ describe("matrix exec approvals", () => {
|
|||
).toBe(false);
|
||||
});
|
||||
|
||||
it("suppresses local prompts for generic exec payloads when metadata matches filters", () => {
|
||||
const payload = {
|
||||
channelData: {
|
||||
execApproval: {
|
||||
approvalId: "req-1",
|
||||
approvalSlug: "req-1",
|
||||
approvalKind: "exec",
|
||||
agentId: "ops-agent",
|
||||
sessionKey: "agent:ops-agent:matrix:channel:!ops:example.org",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(
|
||||
shouldSuppressLocalMatrixExecApprovalPrompt({
|
||||
cfg: buildConfig({
|
||||
enabled: true,
|
||||
approvers: ["@owner:example.org"],
|
||||
agentFilter: ["ops-agent"],
|
||||
sessionFilter: ["matrix:channel:"],
|
||||
}),
|
||||
payload,
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("does not suppress local prompts for plugin approval payloads", () => {
|
||||
const payload = {
|
||||
channelData: {
|
||||
execApproval: {
|
||||
approvalId: "plugin:req-1",
|
||||
approvalSlug: "plugin:r",
|
||||
approvalKind: "plugin",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(
|
||||
shouldSuppressLocalMatrixExecApprovalPrompt({
|
||||
cfg: buildConfig({ enabled: true, approvers: ["@owner:example.org"] }),
|
||||
payload,
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("normalizes prefixed approver ids", () => {
|
||||
expect(normalizeMatrixApproverId("matrix:@owner:example.org")).toBe("@owner:example.org");
|
||||
expect(normalizeMatrixApproverId("user:@owner:example.org")).toBe("@owner:example.org");
|
||||
|
|
|
|||
|
|
@ -117,6 +117,9 @@ export function shouldSuppressLocalMatrixExecApprovalPrompt(params: {
|
|||
if (!metadata) {
|
||||
return false;
|
||||
}
|
||||
if (metadata.approvalKind !== "exec") {
|
||||
return false;
|
||||
}
|
||||
const request = buildFilterCheckRequest({
|
||||
metadata,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -483,6 +483,31 @@ describe("exec approval forwarder", () => {
|
|||
);
|
||||
});
|
||||
|
||||
it("stores exec metadata on generic forwarded fallback payloads", async () => {
|
||||
vi.useFakeTimers();
|
||||
const { deliver, forwarder } = createForwarder({ cfg: TARGETS_CFG });
|
||||
|
||||
await expect(forwarder.handleRequested(baseRequest)).resolves.toBe(true);
|
||||
|
||||
expect(deliver).toHaveBeenCalledTimes(1);
|
||||
expect(deliver.mock.calls[0]?.[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
payloads: [
|
||||
expect.objectContaining({
|
||||
channelData: expect.objectContaining({
|
||||
execApproval: expect.objectContaining({
|
||||
approvalId: "req-1",
|
||||
approvalKind: "exec",
|
||||
agentId: "main",
|
||||
sessionKey: "agent:main:main",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("formats single-line commands as inline code", async () => {
|
||||
vi.useFakeTimers();
|
||||
const { deliver, forwarder } = createForwarder({ cfg: TARGETS_CFG });
|
||||
|
|
|
|||
|
|
@ -353,7 +353,9 @@ function buildExecPendingPayload(params: {
|
|||
approvalId: params.request.id,
|
||||
approvalSlug: params.request.id.slice(0, 8),
|
||||
text: buildRequestMessage(params.request, params.nowMs),
|
||||
agentId: params.request.request.agentId ?? null,
|
||||
allowedDecisions: resolveExecApprovalRequestAllowedDecisions(params.request.request),
|
||||
sessionKey: params.request.request.sessionKey ?? null,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ describe("exec approval reply helpers", () => {
|
|||
).toEqual({
|
||||
approvalId: "req-1",
|
||||
approvalSlug: "slug-1",
|
||||
approvalKind: "exec",
|
||||
agentId: "agent-1",
|
||||
allowedDecisions: ["allow-once", "deny", "allow-always"],
|
||||
sessionKey: "session-1",
|
||||
|
|
@ -108,6 +109,7 @@ describe("exec approval reply helpers", () => {
|
|||
execApproval: {
|
||||
approvalId: "req-1",
|
||||
approvalSlug: "slug-1",
|
||||
approvalKind: "exec",
|
||||
agentId: undefined,
|
||||
allowedDecisions: ["allow-once", "allow-always", "deny"],
|
||||
sessionKey: undefined,
|
||||
|
|
@ -157,6 +159,7 @@ describe("exec approval reply helpers", () => {
|
|||
execApproval: {
|
||||
approvalId: "req-ask-always",
|
||||
approvalSlug: "slug-always",
|
||||
approvalKind: "exec",
|
||||
allowedDecisions: ["allow-once", "deny"],
|
||||
},
|
||||
});
|
||||
|
|
@ -200,6 +203,7 @@ describe("exec approval reply helpers", () => {
|
|||
execApproval: {
|
||||
approvalId: "req-meta",
|
||||
approvalSlug: "slug-meta",
|
||||
approvalKind: "exec",
|
||||
agentId: "ops-agent",
|
||||
allowedDecisions: ["allow-once", "allow-always", "deny"],
|
||||
sessionKey: "agent:ops-agent:matrix:channel:!room:example.org",
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ export type ExecApprovalUnavailableReason =
|
|||
export type ExecApprovalReplyMetadata = {
|
||||
approvalId: string;
|
||||
approvalSlug: string;
|
||||
approvalKind: "exec" | "plugin";
|
||||
agentId?: string;
|
||||
allowedDecisions?: readonly ExecApprovalReplyDecision[];
|
||||
sessionKey?: string;
|
||||
|
|
@ -229,6 +230,7 @@ export function getExecApprovalReplyMetadata(
|
|||
if (!approvalId || !approvalSlug) {
|
||||
return null;
|
||||
}
|
||||
const approvalKind = record.approvalKind === "plugin" ? "plugin" : "exec";
|
||||
const allowedDecisions = Array.isArray(record.allowedDecisions)
|
||||
? record.allowedDecisions.filter(
|
||||
(value): value is ExecApprovalReplyDecision =>
|
||||
|
|
@ -242,6 +244,7 @@ export function getExecApprovalReplyMetadata(
|
|||
return {
|
||||
approvalId,
|
||||
approvalSlug,
|
||||
approvalKind,
|
||||
agentId,
|
||||
allowedDecisions,
|
||||
sessionKey,
|
||||
|
|
@ -307,6 +310,7 @@ export function buildExecApprovalPendingReplyPayload(
|
|||
execApproval: {
|
||||
approvalId: params.approvalId,
|
||||
approvalSlug: params.approvalSlug,
|
||||
approvalKind: "exec",
|
||||
agentId: params.agentId?.trim() || undefined,
|
||||
allowedDecisions,
|
||||
sessionKey: params.sessionKey?.trim() || undefined,
|
||||
|
|
|
|||
|
|
@ -89,9 +89,12 @@ describe("plugin-sdk/approval-renderers", () => {
|
|||
},
|
||||
channelDataExpected: {
|
||||
execApproval: {
|
||||
agentId: undefined,
|
||||
approvalId: "plugin-approval-123",
|
||||
approvalKind: "plugin",
|
||||
approvalSlug: "custom-slug",
|
||||
allowedDecisions: ["allow-once", "allow-always", "deny"],
|
||||
sessionKey: undefined,
|
||||
state: "pending",
|
||||
},
|
||||
telegram: {
|
||||
|
|
|
|||
|
|
@ -13,10 +13,13 @@ import {
|
|||
const DEFAULT_ALLOWED_DECISIONS = ["allow-once", "allow-always", "deny"] as const;
|
||||
|
||||
export function buildApprovalPendingReplyPayload(params: {
|
||||
approvalKind?: "exec" | "plugin";
|
||||
approvalId: string;
|
||||
approvalSlug: string;
|
||||
text: string;
|
||||
agentId?: string | null;
|
||||
allowedDecisions?: readonly ExecApprovalReplyDecision[];
|
||||
sessionKey?: string | null;
|
||||
channelData?: Record<string, unknown>;
|
||||
}): ReplyPayload {
|
||||
const allowedDecisions = params.allowedDecisions ?? DEFAULT_ALLOWED_DECISIONS;
|
||||
|
|
@ -30,7 +33,10 @@ export function buildApprovalPendingReplyPayload(params: {
|
|||
execApproval: {
|
||||
approvalId: params.approvalId,
|
||||
approvalSlug: params.approvalSlug,
|
||||
approvalKind: params.approvalKind ?? "exec",
|
||||
agentId: params.agentId?.trim() || undefined,
|
||||
allowedDecisions,
|
||||
sessionKey: params.sessionKey?.trim() || undefined,
|
||||
state: "pending",
|
||||
},
|
||||
...params.channelData,
|
||||
|
|
@ -66,6 +72,7 @@ export function buildPluginApprovalPendingReplyPayload(params: {
|
|||
channelData?: Record<string, unknown>;
|
||||
}): ReplyPayload {
|
||||
return buildApprovalPendingReplyPayload({
|
||||
approvalKind: "plugin",
|
||||
approvalId: params.request.id,
|
||||
approvalSlug: params.approvalSlug ?? params.request.id.slice(0, 8),
|
||||
text: params.text ?? buildPluginApprovalRequestMessage(params.request, params.nowMs),
|
||||
|
|
|
|||
Loading…
Reference in New Issue