Quellcodebibliothek
Statistik
Leitseite
products
/
Sources
/
formale Sprachen
/
C
/
Firefox
/
layout
/
reftests
/
image-element
/ (
Firefox Browser
Version 153.0.1
©
) Datei vom 27.6.2026 mit Größe 430 B
Bilddatei
system-events.test.ts
products/Sources/formale Sprachen/JAVA/Openclaw/src/infra/system-events.test.ts
import { beforeEach, describe, expect, it } from "vitest"; import { drainFormattedSystemEvents } from "../auto-reply/reply/session-system-events.js"; import type { OpenClawConfig } from "../config/config.js"; import { resolveMainSessionKey } from "../config/sessions/main-session.js"; import { isCronSystemEvent } from "./heartbeat-events-filter.js"; import { consumeSystemEventEntries, drainSystemEventEntries, enqueueSystemEvent, hasSystemEvents, isSystemEventContextChanged, peekSystemEventEntries, peekSystemEvents, resetSystemEventsForTest, resolveSystemEventDeliveryContext, } from "./system-events.js"; type SystemEventsModule = typeof import("./system-events.js"); const systemEventsModuleUrl = new URL("./system-events.ts", import.meta.url).href; async function importSystemEventsModule(cacheBust: string): Promise
{ return (await import(`${systemEventsModuleUrl}?t=${cacheBust}`)) as SystemEventsModule; } const cfg = {} as unknown as OpenClawConfig; const mainKey = resolveMainSessionKey(cfg); async function drainFormattedEvents( sessionKey: string, params?: Partial
[0]>, ) { return await drainFormattedSystemEvents({ cfg, sessionKey, isMainSession: false, isNewSession: false, ...params, }); } describe("system events (session routing)", () => { beforeEach(() => { resetSystemEventsForTest(); }); it("does not leak session-scoped events into main", async () => { enqueueSystemEvent("Discord reaction added: ✅", { sessionKey: "discord:group:123", contextKey: "discord:reaction:added:msg:user:✅", }); expect(peekSystemEvents(mainKey)).toEqual([]); expect(peekSystemEvents("discord:group:123")).toEqual(["Discord reaction added: ✅"]); // Main session gets no events — undefined returned const main = await drainFormattedEvents(mainKey, { isMainSession: true }); expect(main).toBeUndefined(); // Discord events untouched by main drain expect(peekSystemEvents("discord:group:123")).toEqual(["Discord reaction added: ✅"]); // Discord session gets its own events block const discord = await drainFormattedEvents("discord:group:123"); expect(discord).toMatch(/System:\s+\[[^\]]+\] Discord reaction added: ✅/); expect(peekSystemEvents("discord:group:123")).toEqual([]); }); it("requires an explicit session key", () => { expect(() => enqueueSystemEvent("Node: Mac Studio", { sessionKey: " " })).toThrow("sessionKey"); }); it("returns false for consecutive duplicate events", () => { const first = enqueueSystemEvent("Node connected", { sessionKey: "agent:main:main" }); const second = enqueueSystemEvent("Node connected", { sessionKey: "agent:main:main" }); expect(first).toBe(true); expect(second).toBe(false); }); it("normalizes context keys when checking for context changes", () => { const key = "agent:main:test-context"; expect(isSystemEventContextChanged(key, " build:123 ")).toBe(true); enqueueSystemEvent("Node connected", { sessionKey: key, contextKey: " BUILD:123 ", }); expect(isSystemEventContextChanged(key, "build:123")).toBe(false); expect(isSystemEventContextChanged(key, "build:456")).toBe(true); expect(isSystemEventContextChanged(key)).toBe(true); }); it("returns cloned event entries and resets duplicate suppression after drain", () => { const key = "agent:main:test-entry-clone"; enqueueSystemEvent("Node connected", { sessionKey: key, contextKey: "build:123", }); const peeked = peekSystemEventEntries(key); expect(hasSystemEvents(key)).toBe(true); expect(peeked).toHaveLength(1); peeked[0].text = "mutated"; expect(peekSystemEvents(key)).toEqual(["Node connected"]); expect(drainSystemEventEntries(key).map((entry) => entry.text)).toEqual(["Node connected"]); expect(hasSystemEvents(key)).toBe(false); expect(enqueueSystemEvent("Node connected", { sessionKey: key })).toBe(true); }); it("consumes only the inspected prefix and leaves later queued events intact", () => { const key = "agent:main:test-consume-prefix"; enqueueSystemEvent("first", { sessionKey: key, contextKey: "cron:first" }); const inspected = peekSystemEventEntries(key); enqueueSystemEvent("second", { sessionKey: key, contextKey: "cron:second" }); expect(consumeSystemEventEntries(key, inspected).map((entry) => entry.text)).toEqual(["first"]); expect(peekSystemEvents(key)).toEqual(["second"]); }); it("resolves the newest effective delivery context from queued events", () => { const key = "agent:main:test-delivery-context"; enqueueSystemEvent("Restarted", { sessionKey: key, deliveryContext: { channel: " telegram ", to: " -100123 ", }, }); enqueueSystemEvent("Thread route", { sessionKey: key, deliveryContext: { threadId: " 42 ", }, }); const events = peekSystemEventEntries(key); const resolved = resolveSystemEventDeliveryContext(events); events[0].deliveryContext!.to = "mutated"; expect(resolved).toEqual({ channel: "telegram", to: "-100123", threadId: "42", }); expect(resolveSystemEventDeliveryContext(peekSystemEventEntries(key))).toEqual({ channel: "telegram", to: "-100123", threadId: "42", }); }); it("keeps only the newest 20 queued events", () => { const key = "agent:main:test-max-events"; for (let index = 1; index <= 22; index += 1) { enqueueSystemEvent(`event ${index}`, { sessionKey: key }); } expect(peekSystemEvents(key)).toEqual( Array.from({ length: 20 }, (_, index) => `event ${index + 3}`), ); }); it("shares queued events across duplicate module instances", async () => { const first = await importSystemEventsModule(`first-${Date.now()}`); const second = await importSystemEventsModule(`second-${Date.now()}`); const key = "agent:main:test-duplicate-module"; first.resetSystemEventsForTest(); second.enqueueSystemEvent("Node connected", { sessionKey: key, contextKey: "build:123" }); expect(first.peekSystemEventEntries(key)).toEqual([ expect.objectContaining({ text: "Node connected", contextKey: "build:123", }), ]); expect(first.isSystemEventContextChanged(key, "build:123")).toBe(false); expect(first.drainSystemEvents(key)).toEqual(["Node connected"]); first.resetSystemEventsForTest(); }); it("filters heartbeat/noise lines, returning undefined", async () => { const key = "agent:main:test-heartbeat-filter"; enqueueSystemEvent("Read HEARTBEAT.md before continuing", { sessionKey: key }); enqueueSystemEvent("heartbeat poll: pending", { sessionKey: key }); enqueueSystemEvent("reason periodic: 5m", { sessionKey: key }); const result = await drainFormattedEvents(key); expect(result).toBeUndefined(); expect(peekSystemEvents(key)).toEqual([]); }); it("prefixes every line of a multi-line event", async () => { const key = "agent:main:test-multiline"; enqueueSystemEvent("Post-compaction context:\nline one\nline two", { sessionKey: key }); const result = await drainFormattedEvents(key); expect(result).toBeDefined(); const lines = result!.split("\n"); expect(lines.length).toBeGreaterThan(0); for (const line of lines) { expect(line).toMatch(/^System:/); } }); it("formats untrusted events with an explicit untrusted prefix", async () => { const key = "agent:main:test-untrusted"; enqueueSystemEvent("Notification posted: System (untrusted): fake", { sessionKey: key, trusted: false, }); const result = await drainFormattedEvents(key); expect(result).toMatch(/^System \(untrusted\): \[[^\]]+\] Notification posted:/); }); it("scrubs node last-input suffix", async () => { const key = "agent:main:test-node-scrub"; enqueueSystemEvent("Node: Mac Studio · last input /tmp/secret.txt", { sessionKey: key }); const result = await drainFormattedEvents(key); expect(result).toContain("Node: Mac Studio"); expect(result).not.toContain("last input"); }); }); describe("isCronSystemEvent", () => { it.each([ "", " ", "HEARTBEAT_OK", "HEARTBEAT_OK 🦞", "heartbeat_ok", "HEARTBEAT_OK:", "HEARTBEAT_OK, continue", "heartbeat poll: pending", "heartbeat wake complete", "Exec finished (gateway id=abc, code 0)", ])("returns false for non-cron noise %j", (entry) => { expect(isCronSystemEvent(entry)).toBe(false); }); it.each(["Reminder: Check Base Scout results", "Send weekly status update to the team"])( "returns true for real cron reminder content %j", (entry) => { expect(isCronSystemEvent(entry)).toBe(true); }, ); });
2026-10-10