mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-10 00:11:19 +00:00
fix(googlechat): cap approval binding registries (#101744)
Co-authored-by: NIO <nocodet@mail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
6ad8a77b51
commit
32dee52329
2 changed files with 83 additions and 0 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import {
|
||||
clearGoogleChatApprovalCardBindingsForTest,
|
||||
getGoogleChatApprovalCardBinding,
|
||||
registerGoogleChatManualApprovalFollowupSuppression,
|
||||
registerGoogleChatApprovalCardBinding,
|
||||
shouldSuppressGoogleChatManualExecApprovalFollowupPayload,
|
||||
|
|
@ -110,4 +111,72 @@ describe("Google Chat approval card action registry", () => {
|
|||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("evicts oldest approval card bindings once the cache exceeds its cap", () => {
|
||||
const firstToken = "token-first";
|
||||
registerGoogleChatApprovalCardBinding({
|
||||
token: firstToken,
|
||||
accountId: "default",
|
||||
approvalId: "approval-first",
|
||||
approvalKind: "exec",
|
||||
decision: "allow-once",
|
||||
allowedDecisions: ["allow-once", "deny"],
|
||||
spaceName: "spaces/AAA",
|
||||
messageName: "spaces/AAA/messages/msg-1",
|
||||
expiresAtMs: Date.now() + 60_000,
|
||||
});
|
||||
expect(getGoogleChatApprovalCardBinding(firstToken)).not.toBeNull();
|
||||
|
||||
for (let i = 1; i <= 1024; i += 1) {
|
||||
registerGoogleChatApprovalCardBinding({
|
||||
token: `token-fill-${i}`,
|
||||
accountId: "default",
|
||||
approvalId: `approval-fill-${i}`,
|
||||
approvalKind: "exec",
|
||||
decision: "allow-once",
|
||||
allowedDecisions: ["allow-once", "deny"],
|
||||
spaceName: "spaces/AAA",
|
||||
messageName: `spaces/AAA/messages/msg-${i}`,
|
||||
expiresAtMs: Date.now() + 60_000,
|
||||
});
|
||||
}
|
||||
|
||||
expect(getGoogleChatApprovalCardBinding(firstToken)).toBeNull();
|
||||
expect(getGoogleChatApprovalCardBinding("token-fill-1024")).not.toBeNull();
|
||||
});
|
||||
|
||||
it("evicts oldest manual approval follow-up suppressions once the cache exceeds its cap", () => {
|
||||
const firstApprovalId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa";
|
||||
registerGoogleChatManualApprovalFollowupSuppression({
|
||||
approvalId: firstApprovalId,
|
||||
approvalKind: "exec",
|
||||
allowedDecisions: ["allow-once", "deny"],
|
||||
expiresAtMs: Date.now() + 60_000,
|
||||
});
|
||||
expect(
|
||||
shouldSuppressGoogleChatManualExecApprovalFollowupText(
|
||||
`/approve ${firstApprovalId.slice(0, 8)} allow-once`,
|
||||
),
|
||||
).toBe(true);
|
||||
|
||||
for (let i = 1; i <= 1024; i += 1) {
|
||||
registerGoogleChatManualApprovalFollowupSuppression({
|
||||
approvalId: `${i.toString().padStart(8, "0")}-aaaa-aaaa-aaaa-aaaaaaaaaaaa`,
|
||||
approvalKind: "exec",
|
||||
allowedDecisions: ["allow-once", "deny"],
|
||||
expiresAtMs: Date.now() + 60_000,
|
||||
});
|
||||
}
|
||||
|
||||
expect(
|
||||
shouldSuppressGoogleChatManualExecApprovalFollowupText(
|
||||
`/approve ${firstApprovalId.slice(0, 8)} allow-once`,
|
||||
),
|
||||
).toBe(false);
|
||||
expect(
|
||||
shouldSuppressGoogleChatManualExecApprovalFollowupText(
|
||||
`/approve ${"1024".padStart(8, "0")} allow-once`,
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import crypto from "node:crypto";
|
||||
import type { ExecApprovalDecision } from "openclaw/plugin-sdk/approval-runtime";
|
||||
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import type { GoogleChatActionParameter, GoogleChatEvent } from "./types.js";
|
||||
|
||||
|
|
@ -25,6 +26,8 @@ type GoogleChatApprovalCardBinding = {
|
|||
|
||||
const approvalCardBindings = new Map<string, GoogleChatApprovalCardBinding>();
|
||||
const approvalCardResolvingTokens = new Set<string>();
|
||||
const GOOGLECHAT_APPROVAL_CARD_BINDING_MAX_ENTRIES = 1024;
|
||||
const GOOGLECHAT_MANUAL_APPROVAL_SUPPRESSION_MAX_ENTRIES = 1024;
|
||||
|
||||
type GoogleChatManualApprovalSuppressionPayload = {
|
||||
text?: string;
|
||||
|
|
@ -113,7 +116,11 @@ export function registerGoogleChatApprovalCardBinding(
|
|||
if (binding.expiresAtMs <= Date.now()) {
|
||||
return false;
|
||||
}
|
||||
if (approvalCardBindings.has(binding.token)) {
|
||||
approvalCardBindings.delete(binding.token);
|
||||
}
|
||||
approvalCardBindings.set(binding.token, binding);
|
||||
pruneMapToMaxSize(approvalCardBindings, GOOGLECHAT_APPROVAL_CARD_BINDING_MAX_ENTRIES);
|
||||
registerGoogleChatManualApprovalFollowupSuppression({
|
||||
approvalId: binding.approvalId,
|
||||
approvalKind: binding.approvalKind,
|
||||
|
|
@ -156,7 +163,14 @@ export function registerGoogleChatManualApprovalFollowupSuppression(
|
|||
if (!key) {
|
||||
return false;
|
||||
}
|
||||
if (manualApprovalFollowupSuppressions.has(key)) {
|
||||
manualApprovalFollowupSuppressions.delete(key);
|
||||
}
|
||||
manualApprovalFollowupSuppressions.set(key, suppression);
|
||||
pruneMapToMaxSize(
|
||||
manualApprovalFollowupSuppressions,
|
||||
GOOGLECHAT_MANUAL_APPROVAL_SUPPRESSION_MAX_ENTRIES,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue