diff --git a/extensions/signal/src/monitor.tool-result.sends-tool-summaries-responseprefix.test.ts b/extensions/signal/src/monitor.tool-result.sends-tool-summaries-responseprefix.test.ts index ccefd20b064..812895a15e6 100644 --- a/extensions/signal/src/monitor.tool-result.sends-tool-summaries-responseprefix.test.ts +++ b/extensions/signal/src/monitor.tool-result.sends-tool-summaries-responseprefix.test.ts @@ -1,9 +1,8 @@ import { describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../../src/config/config.js"; -import { peekSystemEvents } from "../../../src/infra/system-events.js"; +import type { SignalDaemonExitEvent } from "./daemon.js"; import { resolveAgentRoute } from "../../../src/routing/resolve-route.js"; import { normalizeE164 } from "../../../src/utils.js"; -import type { SignalDaemonExitEvent } from "./daemon.js"; import { createMockSignalDaemonHandle, config, @@ -16,7 +15,11 @@ import { installSignalToolResultTestHooks(); // Import after the harness registers `vi.mock(...)` for Signal internals. -const { monitorSignalProvider } = await import("./monitor.js"); +vi.resetModules(); +const [{ peekSystemEvents }, { monitorSignalProvider }] = await Promise.all([ + import("openclaw/plugin-sdk/infra-runtime"), + import("./monitor.js"), +]); const { replyMock, @@ -76,6 +79,7 @@ function createAutoAbortController() { async function runMonitorWithMocks(opts: MonitorSignalProviderOptions) { return monitorSignalProvider({ config: config as OpenClawConfig, + waitForTransportReady: waitForTransportReadyMock as any, ...opts, }); } diff --git a/extensions/signal/src/monitor.tool-result.test-harness.ts b/extensions/signal/src/monitor.tool-result.test-harness.ts index 7445fc0ffb7..ad81a4d6da2 100644 --- a/extensions/signal/src/monitor.tool-result.test-harness.ts +++ b/extensions/signal/src/monitor.tool-result.test-harness.ts @@ -171,7 +171,7 @@ export function installSignalToolResultTestHooks() { replyMock.mockReset(); updateLastRouteMock.mockReset(); streamMock.mockReset(); - signalCheckMock.mockReset().mockResolvedValue({}); + signalCheckMock.mockReset().mockResolvedValue({ ok: true }); signalRpcRequestMock.mockReset().mockResolvedValue({}); spawnSignalDaemonMock.mockReset().mockReturnValue(createMockSignalDaemonHandle()); readAllowFromStoreMock.mockReset().mockResolvedValue([]); diff --git a/extensions/signal/src/monitor.ts b/extensions/signal/src/monitor.ts index 20f0c943823..bdc3da35baf 100644 --- a/extensions/signal/src/monitor.ts +++ b/extensions/signal/src/monitor.ts @@ -1,12 +1,13 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; +import type { SignalReactionNotificationMode } from "openclaw/plugin-sdk/config-runtime"; +import type { BackoffPolicy } from "openclaw/plugin-sdk/infra-runtime"; +import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime"; import { loadConfig } from "openclaw/plugin-sdk/config-runtime"; import { resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce, } from "openclaw/plugin-sdk/config-runtime"; -import type { SignalReactionNotificationMode } from "openclaw/plugin-sdk/config-runtime"; -import type { BackoffPolicy } from "openclaw/plugin-sdk/infra-runtime"; import { waitForTransportReady } from "openclaw/plugin-sdk/infra-runtime"; import { saveMediaBuffer } from "openclaw/plugin-sdk/media-runtime"; import { @@ -19,20 +20,19 @@ import { resolveTextChunkLimit, } from "openclaw/plugin-sdk/reply-runtime"; import { DEFAULT_GROUP_HISTORY_LIMIT, type HistoryEntry } from "openclaw/plugin-sdk/reply-runtime"; -import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime"; import { createNonExitingRuntime, type RuntimeEnv } from "openclaw/plugin-sdk/runtime-env"; import { normalizeStringEntries } from "openclaw/plugin-sdk/text-runtime"; import { normalizeE164 } from "openclaw/plugin-sdk/text-runtime"; -import { resolveSignalAccount } from "./accounts.js"; -import { signalCheck, signalRpcRequest } from "./client.js"; -import { formatSignalDaemonExit, spawnSignalDaemon, type SignalDaemonHandle } from "./daemon.js"; -import { isSignalSenderAllowed, type resolveSignalSender } from "./identity.js"; -import { createSignalEventHandler } from "./monitor/event-handler.js"; import type { SignalAttachment, SignalReactionMessage, SignalReactionTarget, } from "./monitor/event-handler.types.js"; +import { resolveSignalAccount } from "./accounts.js"; +import { signalCheck, signalRpcRequest } from "./client.js"; +import { formatSignalDaemonExit, spawnSignalDaemon, type SignalDaemonHandle } from "./daemon.js"; +import { isSignalSenderAllowed, type resolveSignalSender } from "./identity.js"; +import { createSignalEventHandler } from "./monitor/event-handler.js"; import { sendMessageSignal } from "./send.js"; import { runSignalSseLoop } from "./sse-reconnect.js"; @@ -56,6 +56,7 @@ export type MonitorSignalOpts = { groupAllowFrom?: Array; mediaMaxMb?: number; reconnectPolicy?: Partial; + waitForTransportReady?: typeof waitForTransportReady; }; function resolveRuntime(opts: MonitorSignalOpts): RuntimeEnv { @@ -217,8 +218,10 @@ async function waitForSignalDaemonReady(params: { logAfterMs: number; logIntervalMs?: number; runtime: RuntimeEnv; + waitForTransportReadyFn?: typeof waitForTransportReady; }): Promise { - await waitForTransportReady({ + const waitForTransportReadyFn = params.waitForTransportReadyFn ?? waitForTransportReady; + await waitForTransportReadyFn({ label: "signal daemon", timeoutMs: params.timeoutMs, logAfterMs: params.logAfterMs, @@ -374,6 +377,7 @@ export async function monitorSignalProvider(opts: MonitorSignalOpts = {}): Promi const mediaMaxBytes = (opts.mediaMaxMb ?? accountInfo.config.mediaMaxMb ?? 8) * 1024 * 1024; const ignoreAttachments = opts.ignoreAttachments ?? accountInfo.config.ignoreAttachments ?? false; const sendReadReceipts = Boolean(opts.sendReadReceipts ?? accountInfo.config.sendReadReceipts); + const waitForTransportReadyFn = opts.waitForTransportReady ?? waitForTransportReady; const autoStart = opts.autoStart ?? accountInfo.config.autoStart ?? !accountInfo.config.httpUrl; const startupTimeoutMs = Math.min( @@ -416,6 +420,7 @@ export async function monitorSignalProvider(opts: MonitorSignalOpts = {}): Promi logAfterMs: 10_000, logIntervalMs: 10_000, runtime, + waitForTransportReadyFn, }); const daemonExitError = daemonLifecycle.getExitError(); if (daemonExitError) {