fix(discord): harden Carbon parity

This commit is contained in:
clawsweeper
2026-05-02 11:39:51 +00:00
parent 3895f20141
commit 4fa634ef1a
3 changed files with 36 additions and 2 deletions

View File

@@ -98,7 +98,7 @@ Docs: https://docs.openclaw.ai
- WhatsApp/Cron: keep DM pairing-store approvals out of implicit cron and heartbeat recipient fallback, so scheduled automation only uses explicit targets, active configured recipients, or configured `allowFrom` entries. Fixes #62339. Thanks @kelvinisly-collab.
- Google Meet: keep the agent-facing `google_meet` tool visible on non-macOS hosts but block local Chrome realtime actions with guidance, so Linux agents can still use transcribe, Twilio, chrome-node, and artifact flows without choosing the macOS-only BlackHole path. Refs #75950. Thanks @actual-software-inc.
- macOS/settings: keep opening General from rewriting `openclaw.json` during Tailscale settings hydration, preserving `gateway`, `auth`, `meta`, and `wizard` until the user changes a setting. Fixes #59545. Thanks @Tengdw.
- Discord: prioritize interaction callbacks ahead of stale background REST work, validate oversized gateway payloads and member-intent requests before send, and forward explicit component payloads from message actions. (#75363)
- Discord: prioritize interaction callbacks ahead of stale background REST work without polling active REST buckets, validate oversized gateway payloads and member-intent requests before send, and forward explicit component payloads from message actions. (#75363)
- Active Memory: use the configured recall timeout as the blocking prompt-build hook budget by default and move cold-start setup grace behind explicit `setupGraceTimeoutMs` config, so the plugin no longer silently extends 15000 ms configs to 45000 ms on the main lane. Fixes #75843. Thanks @vishutdhar.
- Plugins/web-provider: reuse the active gateway plugin registry for runtime web provider resolution after deriving the same candidate plugin ids as the loader path, avoiding a redundant `loadOpenClawPlugins` call on every request while preserving origin and scope filters. Fixes #75513. Thanks @jochen.
- Crestodian/CLI: exit non-zero when interactive Crestodian is invoked without a TTY, so scripts and CI no longer treat the setup error as success. Fixes #73646 and supersedes #73928 and #74059. Thanks @bittoby, @luyao618, and @Linux2010.

View File

@@ -408,7 +408,6 @@ export class RestScheduler<TData> {
continue;
}
if (bucket.active > 0) {
nextDelayMs = Math.min(nextDelayMs ?? 5, 5);
continue;
}
const waitMs = this.getBucketWaitMs(bucket, now);

View File

@@ -165,6 +165,41 @@ describe("RequestClient", () => {
);
});
it("drains same-bucket requests when the active request finishes without polling", async () => {
vi.useFakeTimers();
vi.setSystemTime(0);
const firstResponse = createDeferred<Response>();
const fetchSpy = vi.fn(async () =>
fetchSpy.mock.calls.length === 1
? await firstResponse.promise
: createJsonResponse({ id: "second" }),
);
const client = new RequestClient("test-token", {
fetch: fetchSpy,
scheduler: { maxConcurrency: 2 },
});
const first = client.get("/channels/c1/messages");
await Promise.resolve();
expect(fetchSpy).toHaveBeenCalledTimes(1);
const second = client.get("/channels/c1/messages");
await Promise.resolve();
expect(fetchSpy).toHaveBeenCalledTimes(1);
expect(vi.getTimerCount()).toBe(1);
await vi.advanceTimersByTimeAsync(20);
expect(fetchSpy).toHaveBeenCalledTimes(1);
expect(vi.getTimerCount()).toBe(1);
firstResponse.resolve(createJsonResponse({ id: "first" }));
await expect(first).resolves.toEqual({ id: "first" });
await expect(second).resolves.toEqual({ id: "second" });
expect(fetchSpy).toHaveBeenCalledTimes(2);
expect(vi.getTimerCount()).toBe(0);
});
it("runs independent route buckets concurrently", async () => {
const channelResponse = createDeferred<Response>();
const guildResponse = createDeferred<Response>();