From 5ce7aee33b046afe82ba54dec26036b5a1590619 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 3 Apr 2026 23:41:37 +0900 Subject: [PATCH] test(cron): localize core channel outbound test loads --- ...gent.direct-delivery-core-channels.test.ts | 92 ++++++++++++++++--- src/cron/isolated-agent.test-setup.ts | 34 ++++++- ...tbeat-runner.returns-default-unset.test.ts | 18 +++- 3 files changed, 125 insertions(+), 19 deletions(-) diff --git a/src/cron/isolated-agent.direct-delivery-core-channels.test.ts b/src/cron/isolated-agent.direct-delivery-core-channels.test.ts index c477ded7f7d..a8ceb5002b8 100644 --- a/src/cron/isolated-agent.direct-delivery-core-channels.test.ts +++ b/src/cron/isolated-agent.direct-delivery-core-channels.test.ts @@ -1,16 +1,13 @@ import "./isolated-agent.mocks.js"; import { beforeEach, describe, expect, it } from "vitest"; -import { - discordOutbound, - imessageOutbound, - signalOutbound, - slackOutbound, - telegramOutbound, - whatsappOutbound, -} from "../../test/channel-outbounds.js"; import { runSubagentAnnounceFlow } from "../agents/subagent-announce.js"; +import type { ChannelOutboundAdapter } from "../channels/plugins/types.js"; import type { CliDeps } from "../cli/deps.js"; import { setActivePluginRegistry } from "../plugins/runtime.js"; +import { + loadBundledPluginPublicSurfaceSync, + loadBundledPluginTestApiSync, +} from "../test-utils/bundled-plugin-public-surface.js"; import { createOutboundTestPlugin, createTestRegistry } from "../test-utils/channel-plugins.js"; import { createCliDeps, mockAgentPayloads } from "./isolated-agent.delivery.test-helpers.js"; import { runCronIsolatedAgentTurn } from "./isolated-agent.js"; @@ -33,6 +30,73 @@ type ChannelCase = { expectedTo: string; }; +let discordOutboundCache: ChannelOutboundAdapter | undefined; +let imessageOutboundCache: ChannelOutboundAdapter | undefined; +let signalOutboundCache: ChannelOutboundAdapter | undefined; +let slackOutboundCache: ChannelOutboundAdapter | undefined; +let telegramOutboundCache: ChannelOutboundAdapter | undefined; +let whatsappOutboundCache: ChannelOutboundAdapter | undefined; + +function getDiscordOutbound(): ChannelOutboundAdapter { + if (!discordOutboundCache) { + ({ discordOutbound: discordOutboundCache } = loadBundledPluginTestApiSync<{ + discordOutbound: ChannelOutboundAdapter; + }>("discord")); + } + return discordOutboundCache; +} + +function getIMessageOutbound(): ChannelOutboundAdapter { + if (!imessageOutboundCache) { + ({ imessageOutbound: imessageOutboundCache } = loadBundledPluginPublicSurfaceSync<{ + imessageOutbound: ChannelOutboundAdapter; + }>({ + pluginId: "imessage", + artifactBasename: "src/outbound-adapter.js", + })); + } + return imessageOutboundCache; +} + +function getSignalOutbound(): ChannelOutboundAdapter { + if (!signalOutboundCache) { + ({ signalOutbound: signalOutboundCache } = loadBundledPluginTestApiSync<{ + signalOutbound: ChannelOutboundAdapter; + }>("signal")); + } + return signalOutboundCache; +} + +function getSlackOutbound(): ChannelOutboundAdapter { + if (!slackOutboundCache) { + ({ slackOutbound: slackOutboundCache } = loadBundledPluginTestApiSync<{ + slackOutbound: ChannelOutboundAdapter; + }>("slack")); + } + return slackOutboundCache; +} + +function getTelegramOutbound(): ChannelOutboundAdapter { + if (!telegramOutboundCache) { + ({ telegramOutbound: telegramOutboundCache } = loadBundledPluginPublicSurfaceSync<{ + telegramOutbound: ChannelOutboundAdapter; + }>({ + pluginId: "telegram", + artifactBasename: "src/outbound-adapter.js", + })); + } + return telegramOutboundCache; +} + +function getWhatsAppOutbound(): ChannelOutboundAdapter { + if (!whatsappOutboundCache) { + ({ whatsappOutbound: whatsappOutboundCache } = loadBundledPluginTestApiSync<{ + whatsappOutbound: ChannelOutboundAdapter; + }>("whatsapp")); + } + return whatsappOutboundCache; +} + const CASES: ChannelCase[] = [ { name: "Slack", @@ -95,32 +159,32 @@ describe("runCronIsolatedAgentTurn core-channel direct delivery", () => { createTestRegistry([ { pluginId: "telegram", - plugin: createOutboundTestPlugin({ id: "telegram", outbound: telegramOutbound }), + plugin: createOutboundTestPlugin({ id: "telegram", outbound: getTelegramOutbound() }), source: "test", }, { pluginId: "signal", - plugin: createOutboundTestPlugin({ id: "signal", outbound: signalOutbound }), + plugin: createOutboundTestPlugin({ id: "signal", outbound: getSignalOutbound() }), source: "test", }, { pluginId: "slack", - plugin: createOutboundTestPlugin({ id: "slack", outbound: slackOutbound }), + plugin: createOutboundTestPlugin({ id: "slack", outbound: getSlackOutbound() }), source: "test", }, { pluginId: "discord", - plugin: createOutboundTestPlugin({ id: "discord", outbound: discordOutbound }), + plugin: createOutboundTestPlugin({ id: "discord", outbound: getDiscordOutbound() }), source: "test", }, { pluginId: "whatsapp", - plugin: createOutboundTestPlugin({ id: "whatsapp", outbound: whatsappOutbound }), + plugin: createOutboundTestPlugin({ id: "whatsapp", outbound: getWhatsAppOutbound() }), source: "test", }, { pluginId: "imessage", - plugin: createOutboundTestPlugin({ id: "imessage", outbound: imessageOutbound }), + plugin: createOutboundTestPlugin({ id: "imessage", outbound: getIMessageOutbound() }), source: "test", }, ]), diff --git a/src/cron/isolated-agent.test-setup.ts b/src/cron/isolated-agent.test-setup.ts index f3ac83c21b2..b5e879cbde7 100644 --- a/src/cron/isolated-agent.test-setup.ts +++ b/src/cron/isolated-agent.test-setup.ts @@ -1,12 +1,40 @@ import { vi } from "vitest"; -import { signalOutbound, telegramOutbound } from "../../test/channel-outbounds.js"; import { loadModelCatalog } from "../agents/model-catalog.js"; import { runEmbeddedPiAgent } from "../agents/pi-embedded.js"; import { runSubagentAnnounceFlow } from "../agents/subagent-announce.js"; +import type { ChannelOutboundAdapter } from "../channels/plugins/types.js"; import { callGateway } from "../gateway/call.js"; import { setActivePluginRegistry } from "../plugins/runtime.js"; +import { + loadBundledPluginPublicSurfaceSync, + loadBundledPluginTestApiSync, +} from "../test-utils/bundled-plugin-public-surface.js"; import { createOutboundTestPlugin, createTestRegistry } from "../test-utils/channel-plugins.js"; +let signalOutboundCache: ChannelOutboundAdapter | undefined; +let telegramOutboundCache: ChannelOutboundAdapter | undefined; + +function getSignalOutbound(): ChannelOutboundAdapter { + if (!signalOutboundCache) { + ({ signalOutbound: signalOutboundCache } = loadBundledPluginTestApiSync<{ + signalOutbound: ChannelOutboundAdapter; + }>("signal")); + } + return signalOutboundCache; +} + +function getTelegramOutbound(): ChannelOutboundAdapter { + if (!telegramOutboundCache) { + ({ telegramOutbound: telegramOutboundCache } = loadBundledPluginPublicSurfaceSync<{ + telegramOutbound: ChannelOutboundAdapter; + }>({ + pluginId: "telegram", + artifactBasename: "src/outbound-adapter.js", + })); + } + return telegramOutboundCache; +} + function parseTelegramTargetForTest(raw: string): { chatId: string; messageThreadId?: number; @@ -60,7 +88,7 @@ export function setupIsolatedAgentTurnMocks(params?: { fast?: boolean }): void { pluginId: "telegram", plugin: createOutboundTestPlugin({ id: "telegram", - outbound: telegramOutbound, + outbound: getTelegramOutbound(), messaging: { parseExplicitTarget: ({ raw }) => { const target = parseTelegramTargetForTest(raw); @@ -76,7 +104,7 @@ export function setupIsolatedAgentTurnMocks(params?: { fast?: boolean }): void { }, { pluginId: "signal", - plugin: createOutboundTestPlugin({ id: "signal", outbound: signalOutbound }), + plugin: createOutboundTestPlugin({ id: "signal", outbound: getSignalOutbound() }), source: "test", }, ]), diff --git a/src/infra/heartbeat-runner.returns-default-unset.test.ts b/src/infra/heartbeat-runner.returns-default-unset.test.ts index f8b6a794675..3282812a984 100644 --- a/src/infra/heartbeat-runner.returns-default-unset.test.ts +++ b/src/infra/heartbeat-runner.returns-default-unset.test.ts @@ -2,9 +2,9 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { whatsappOutbound } from "../../test/channel-outbounds.js"; import { HEARTBEAT_PROMPT } from "../auto-reply/heartbeat.js"; import * as replyModule from "../auto-reply/reply.js"; +import type { ChannelOutboundAdapter } from "../channels/plugins/types.js"; import type { OpenClawConfig } from "../config/config.js"; import { resolveAgentIdFromSessionKey, @@ -14,6 +14,7 @@ import { } from "../config/sessions.js"; import { getActivePluginRegistry, setActivePluginRegistry } from "../plugins/runtime.js"; import { buildAgentPeerSessionKey } from "../routing/session-key.js"; +import { loadBundledPluginTestApiSync } from "../test-utils/bundled-plugin-public-surface.js"; import { createOutboundTestPlugin, createTestRegistry } from "../test-utils/channel-plugins.js"; import { typedCases } from "../test-utils/typed-cases.js"; import { @@ -35,6 +36,16 @@ let testRegistry: ReturnType | null = null; let fixtureRoot = ""; let fixtureCount = 0; +let whatsappOutboundCache: ChannelOutboundAdapter | undefined; + +function getWhatsAppOutbound(): ChannelOutboundAdapter { + if (!whatsappOutboundCache) { + ({ whatsappOutbound: whatsappOutboundCache } = loadBundledPluginTestApiSync<{ + whatsappOutbound: ChannelOutboundAdapter; + }>("whatsapp")); + } + return whatsappOutboundCache; +} const createCaseDir = async (prefix: string) => { const dir = path.join(fixtureRoot, `${prefix}-${fixtureCount++}`); @@ -45,7 +56,10 @@ const createCaseDir = async (prefix: string) => { beforeAll(async () => { previousRegistry = getActivePluginRegistry(); - const whatsappPlugin = createOutboundTestPlugin({ id: "whatsapp", outbound: whatsappOutbound }); + const whatsappPlugin = createOutboundTestPlugin({ + id: "whatsapp", + outbound: getWhatsAppOutbound(), + }); whatsappPlugin.config = { ...whatsappPlugin.config, resolveAllowFrom: ({ cfg }) =>