Initial commit: Discord-Claude Gateway with event-driven agent runtime

This commit is contained in:
2026-02-22 13:59:57 -05:00
parent b4f340b610
commit f2247ea3ac
28 changed files with 2056 additions and 205 deletions

View File

@@ -2,6 +2,17 @@ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import { HeartbeatScheduler, type HeartbeatCheck } from "../../src/heartbeat-scheduler.js";
import type { Event } from "../../src/event-queue.js";
vi.mock("../../src/logger.js", () => ({
logger: {
info: vi.fn(),
debug: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
},
}));
import { logger } from "../../src/logger.js";
type EnqueueFn = (event: Omit<Event, "id" | "timestamp">) => Event | null;
describe("HeartbeatScheduler", () => {
@@ -9,6 +20,7 @@ describe("HeartbeatScheduler", () => {
beforeEach(() => {
vi.useFakeTimers();
vi.mocked(logger.warn).mockClear();
scheduler = new HeartbeatScheduler();
});
@@ -95,7 +107,6 @@ Instruction: Do something`;
});
it("rejects checks with interval < 60 seconds with a warning", () => {
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
const enqueue: EnqueueFn = () => null;
const checks: HeartbeatCheck[] = [
@@ -104,18 +115,14 @@ Instruction: Do something`;
scheduler.start(checks, enqueue);
expect(warnSpy).toHaveBeenCalledWith(
expect.stringContaining("too-fast")
);
expect(warnSpy).toHaveBeenCalledWith(
expect.stringContaining("below the minimum")
expect(logger.warn).toHaveBeenCalledWith(
expect.objectContaining({ name: "too-fast" }),
expect.stringContaining("below minimum")
);
// Advance time — no events should be enqueued
vi.advanceTimersByTime(60_000);
// No way to check enqueue wasn't called since it returns null, but the warn confirms rejection
warnSpy.mockRestore();
});
it("starts valid checks and skips invalid ones in the same batch", () => {
@@ -124,7 +131,6 @@ Instruction: Do something`;
enqueued.push(event);
return { ...event, id: enqueued.length, timestamp: new Date() } as Event;
};
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
const checks: HeartbeatCheck[] = [
{ name: "too-fast", instruction: "Bad check", intervalSeconds: 10 },
@@ -133,13 +139,11 @@ Instruction: Do something`;
scheduler.start(checks, enqueue);
expect(warnSpy).toHaveBeenCalledTimes(1);
expect(logger.warn).toHaveBeenCalledTimes(1);
vi.advanceTimersByTime(60_000);
expect(enqueued).toHaveLength(1);
expect(enqueued[0].payload).toEqual({ instruction: "Good check", checkName: "valid-check" });
warnSpy.mockRestore();
});
});