From 4beb231fd845cbae6697abe2795a23a9dcd62135 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 28 Mar 2026 04:08:23 +0000 Subject: [PATCH] refactor: move heartbeat helpers onto channel runtime --- docs/.generated/plugin-sdk-api-baseline.json | 94 ++++++++++++++++++- docs/.generated/plugin-sdk-api-baseline.jsonl | 14 ++- .../src/auto-reply/heartbeat-runner.test.ts | 4 +- .../src/auto-reply/heartbeat-runner.ts | 7 +- src/plugin-sdk/channel-runtime.ts | 2 + 5 files changed, 113 insertions(+), 8 deletions(-) diff --git a/docs/.generated/plugin-sdk-api-baseline.json b/docs/.generated/plugin-sdk-api-baseline.json index 72116946a42..3d5e7f1d0bd 100644 --- a/docs/.generated/plugin-sdk-api-baseline.json +++ b/docs/.generated/plugin-sdk-api-baseline.json @@ -1404,7 +1404,7 @@ } }, { - "declaration": "export type ReplyPrefixContext = import(\"src/auto-reply/reply/response-prefix-template\").ResponsePrefixContext;", + "declaration": "export type ReplyPrefixContext = import(\"../auto-reply/reply/response-prefix-template.ts\").ResponsePrefixContext;", "exportName": "ReplyPrefixContext", "kind": "type", "source": { @@ -1486,6 +1486,33 @@ "path": "src/channels/typing.ts" } }, + { + "declaration": "export function emitHeartbeatEvent(evt: Omit): void;", + "exportName": "emitHeartbeatEvent", + "kind": "function", + "source": { + "line": 51, + "path": "src/infra/heartbeat-events.ts" + } + }, + { + "declaration": "export function enqueueSystemEvent(text: string, options: SystemEventOptions): boolean;", + "exportName": "enqueueSystemEvent", + "kind": "function", + "source": { + "line": 91, + "path": "src/infra/system-events.ts" + } + }, + { + "declaration": "export function getLastHeartbeatEvent(): HeartbeatEventPayload | null;", + "exportName": "getLastHeartbeatEvent", + "kind": "function", + "source": { + "line": 61, + "path": "src/infra/heartbeat-events.ts" + } + }, { "declaration": "export function isWhatsAppGroupJid(value: string): boolean;", "exportName": "isWhatsAppGroupJid", @@ -1603,6 +1630,15 @@ "path": "extensions/whatsapp/src/normalize-target.ts" } }, + { + "declaration": "export function onHeartbeatEvent(listener: (evt: HeartbeatEventPayload) => void): () => void;", + "exportName": "onHeartbeatEvent", + "kind": "function", + "source": { + "line": 57, + "path": "src/infra/heartbeat-events.ts" + } + }, { "declaration": "export function recordChannelActivity(params: { channel: ChannelId; accountId?: string | null | undefined; direction: ChannelDirection; at?: number | undefined; }): void;", "exportName": "recordChannelActivity", @@ -1621,6 +1657,33 @@ "path": "src/channels/plugins/outbound/interactive.ts" } }, + { + "declaration": "export function resetHeartbeatEventsForTest(): void;", + "exportName": "resetHeartbeatEventsForTest", + "kind": "function", + "source": { + "line": 65, + "path": "src/infra/heartbeat-events.ts" + } + }, + { + "declaration": "export function resolveHeartbeatVisibility(params: { cfg: OpenClawConfig; channel: GatewayMessageChannel; accountId?: string | undefined; }): ResolvedHeartbeatVisibility;", + "exportName": "resolveHeartbeatVisibility", + "kind": "function", + "source": { + "line": 22, + "path": "src/infra/heartbeat-visibility.ts" + } + }, + { + "declaration": "export function resolveIndicatorType(status: \"sent\" | \"ok-empty\" | \"ok-token\" | \"skipped\" | \"failed\"): HeartbeatIndicatorType | undefined;", + "exportName": "resolveIndicatorType", + "kind": "function", + "source": { + "line": 23, + "path": "src/infra/heartbeat-events.ts" + } + }, { "declaration": "export function resolvePollMaxSelections(optionCount: number, allowMultiselect: boolean | undefined): number;", "exportName": "resolvePollMaxSelections", @@ -2332,6 +2395,24 @@ "path": "src/channels/typing.ts" } }, + { + "declaration": "export type HeartbeatEventPayload = HeartbeatEventPayload;", + "exportName": "HeartbeatEventPayload", + "kind": "type", + "source": { + "line": 6, + "path": "src/infra/heartbeat-events.ts" + } + }, + { + "declaration": "export type HeartbeatIndicatorType = HeartbeatIndicatorType;", + "exportName": "HeartbeatIndicatorType", + "kind": "type", + "source": { + "line": 4, + "path": "src/infra/heartbeat-events.ts" + } + }, { "declaration": "export type NormalizedPollInput = NormalizedPollInput;", "exportName": "NormalizedPollInput", @@ -2368,6 +2449,15 @@ "path": "src/channels/reply-prefix.ts" } }, + { + "declaration": "export type ResolvedHeartbeatVisibility = ResolvedHeartbeatVisibility;", + "exportName": "ResolvedHeartbeatVisibility", + "kind": "type", + "source": { + "line": 5, + "path": "src/infra/heartbeat-visibility.ts" + } + }, { "declaration": "export type TypingCallbacks = TypingCallbacks;", "exportName": "TypingCallbacks", @@ -3581,7 +3671,7 @@ } }, { - "declaration": "export type ChannelOutboundSessionRouteParams = { cfg: OpenClawConfig; agentId: string; accountId?: string | null; target: string; resolvedTarget?: { to: string; kind: import(\"src/channels/plugins/types.core\").ChannelDirectoryEntryKind | \"channel\"; display?: string; source: \"normalized\" | \"directory\"; }; replyToId?: string | null; threadId?: string | number | null;};", + "declaration": "export type ChannelOutboundSessionRouteParams = { cfg: OpenClawConfig; agentId: string; accountId?: string | null; target: string; resolvedTarget?: { to: string; kind: import(\"../channels/plugins/types.core.js\").ChannelDirectoryEntryKind | \"channel\"; display?: string; source: \"normalized\" | \"directory\"; }; replyToId?: string | null; threadId?: string | number | null;};", "exportName": "ChannelOutboundSessionRouteParams", "kind": "type", "source": { diff --git a/docs/.generated/plugin-sdk-api-baseline.jsonl b/docs/.generated/plugin-sdk-api-baseline.jsonl index 888d01335d8..4a4fdb644e4 100644 --- a/docs/.generated/plugin-sdk-api-baseline.jsonl +++ b/docs/.generated/plugin-sdk-api-baseline.jsonl @@ -153,7 +153,7 @@ {"declaration":"export function createChannelReplyPipeline(params: { cfg: OpenClawConfig; agentId: string; channel?: string | undefined; accountId?: string | undefined; typing?: CreateTypingCallbacksParams | undefined; typingCallbacks?: TypingCallbacks | undefined; }): ChannelReplyPipeline;","entrypoint":"channel-reply-pipeline","exportName":"createChannelReplyPipeline","importSpecifier":"openclaw/plugin-sdk/channel-reply-pipeline","kind":"function","recordType":"export","sourceLine":20,"sourcePath":"src/plugin-sdk/channel-reply-pipeline.ts"} {"declaration":"export type ChannelReplyPipeline = ChannelReplyPipeline;","entrypoint":"channel-reply-pipeline","exportName":"ChannelReplyPipeline","importSpecifier":"openclaw/plugin-sdk/channel-reply-pipeline","kind":"type","recordType":"export","sourceLine":16,"sourcePath":"src/plugin-sdk/channel-reply-pipeline.ts"} {"declaration":"export type CreateTypingCallbacksParams = CreateTypingCallbacksParams;","entrypoint":"channel-reply-pipeline","exportName":"CreateTypingCallbacksParams","importSpecifier":"openclaw/plugin-sdk/channel-reply-pipeline","kind":"type","recordType":"export","sourceLine":11,"sourcePath":"src/channels/typing.ts"} -{"declaration":"export type ReplyPrefixContext = import(\"src/auto-reply/reply/response-prefix-template\").ResponsePrefixContext;","entrypoint":"channel-reply-pipeline","exportName":"ReplyPrefixContext","importSpecifier":"openclaw/plugin-sdk/channel-reply-pipeline","kind":"type","recordType":"export","sourceLine":12,"sourcePath":"src/plugin-sdk/channel-reply-pipeline.ts"} +{"declaration":"export type ReplyPrefixContext = import(\"../auto-reply/reply/response-prefix-template.ts\").ResponsePrefixContext;","entrypoint":"channel-reply-pipeline","exportName":"ReplyPrefixContext","importSpecifier":"openclaw/plugin-sdk/channel-reply-pipeline","kind":"type","recordType":"export","sourceLine":12,"sourcePath":"src/plugin-sdk/channel-reply-pipeline.ts"} {"declaration":"export type ReplyPrefixContextBundle = ReplyPrefixContextBundle;","entrypoint":"channel-reply-pipeline","exportName":"ReplyPrefixContextBundle","importSpecifier":"openclaw/plugin-sdk/channel-reply-pipeline","kind":"type","recordType":"export","sourceLine":12,"sourcePath":"src/channels/reply-prefix.ts"} {"declaration":"export type ReplyPrefixOptions = ReplyPrefixOptions;","entrypoint":"channel-reply-pipeline","exportName":"ReplyPrefixOptions","importSpecifier":"openclaw/plugin-sdk/channel-reply-pipeline","kind":"type","recordType":"export","sourceLine":20,"sourcePath":"src/channels/reply-prefix.ts"} {"declaration":"export type TypingCallbacks = TypingCallbacks;","entrypoint":"channel-reply-pipeline","exportName":"TypingCallbacks","importSpecifier":"openclaw/plugin-sdk/channel-reply-pipeline","kind":"type","recordType":"export","sourceLine":4,"sourcePath":"src/channels/typing.ts"} @@ -162,6 +162,9 @@ {"declaration":"export function createReplyPrefixContext(params: { cfg: OpenClawConfig; agentId: string; channel?: string | undefined; accountId?: string | undefined; }): ReplyPrefixContextBundle;","entrypoint":"channel-runtime","exportName":"createReplyPrefixContext","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":28,"sourcePath":"src/channels/reply-prefix.ts"} {"declaration":"export function createReplyPrefixOptions(params: { cfg: OpenClawConfig; agentId: string; channel?: string | undefined; accountId?: string | undefined; }): ReplyPrefixOptions;","entrypoint":"channel-runtime","exportName":"createReplyPrefixOptions","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":64,"sourcePath":"src/channels/reply-prefix.ts"} {"declaration":"export function createTypingCallbacks(params: CreateTypingCallbacksParams): TypingCallbacks;","entrypoint":"channel-runtime","exportName":"createTypingCallbacks","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":23,"sourcePath":"src/channels/typing.ts"} +{"declaration":"export function emitHeartbeatEvent(evt: Omit): void;","entrypoint":"channel-runtime","exportName":"emitHeartbeatEvent","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":51,"sourcePath":"src/infra/heartbeat-events.ts"} +{"declaration":"export function enqueueSystemEvent(text: string, options: SystemEventOptions): boolean;","entrypoint":"channel-runtime","exportName":"enqueueSystemEvent","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":91,"sourcePath":"src/infra/system-events.ts"} +{"declaration":"export function getLastHeartbeatEvent(): HeartbeatEventPayload | null;","entrypoint":"channel-runtime","exportName":"getLastHeartbeatEvent","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":61,"sourcePath":"src/infra/heartbeat-events.ts"} {"declaration":"export function isWhatsAppGroupJid(value: string): boolean;","entrypoint":"channel-runtime","exportName":"isWhatsAppGroupJid","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":17,"sourcePath":"extensions/whatsapp/src/normalize-target.ts"} {"declaration":"export function isWhatsAppUserTarget(value: string): boolean;","entrypoint":"channel-runtime","exportName":"isWhatsAppUserTarget","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":30,"sourcePath":"extensions/whatsapp/src/normalize-target.ts"} {"declaration":"export function keepHttpServerTaskAlive(params: { server: CloseAwareServer; abortSignal?: AbortSignal | undefined; onAbort?: (() => void | Promise) | undefined; }): Promise;","entrypoint":"channel-runtime","exportName":"keepHttpServerTaskAlive","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":79,"sourcePath":"src/plugin-sdk/channel-lifecycle.ts"} @@ -175,8 +178,12 @@ {"declaration":"export function normalizeWhatsAppAllowFromEntries(allowFrom: (string | number)[]): string[];","entrypoint":"channel-runtime","exportName":"normalizeWhatsAppAllowFromEntries","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":12,"sourcePath":"src/channels/plugins/normalize/whatsapp.ts"} {"declaration":"export function normalizeWhatsAppMessagingTarget(raw: string): string | undefined;","entrypoint":"channel-runtime","exportName":"normalizeWhatsAppMessagingTarget","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":4,"sourcePath":"src/channels/plugins/normalize/whatsapp.ts"} {"declaration":"export function normalizeWhatsAppTarget(value: string): string | null;","entrypoint":"channel-runtime","exportName":"normalizeWhatsAppTarget","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":47,"sourcePath":"extensions/whatsapp/src/normalize-target.ts"} +{"declaration":"export function onHeartbeatEvent(listener: (evt: HeartbeatEventPayload) => void): () => void;","entrypoint":"channel-runtime","exportName":"onHeartbeatEvent","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":57,"sourcePath":"src/infra/heartbeat-events.ts"} {"declaration":"export function recordChannelActivity(params: { channel: ChannelId; accountId?: string | null | undefined; direction: ChannelDirection; at?: number | undefined; }): void;","entrypoint":"channel-runtime","exportName":"recordChannelActivity","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":26,"sourcePath":"src/infra/channel-activity.ts"} {"declaration":"export function reduceInteractiveReply(interactive: InteractiveReply | undefined, initialState: TState, reduce: (state: TState, block: InteractiveReplyBlock, index: number) => TState): TState;","entrypoint":"channel-runtime","exportName":"reduceInteractiveReply","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":3,"sourcePath":"src/channels/plugins/outbound/interactive.ts"} +{"declaration":"export function resetHeartbeatEventsForTest(): void;","entrypoint":"channel-runtime","exportName":"resetHeartbeatEventsForTest","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":65,"sourcePath":"src/infra/heartbeat-events.ts"} +{"declaration":"export function resolveHeartbeatVisibility(params: { cfg: OpenClawConfig; channel: GatewayMessageChannel; accountId?: string | undefined; }): ResolvedHeartbeatVisibility;","entrypoint":"channel-runtime","exportName":"resolveHeartbeatVisibility","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":22,"sourcePath":"src/infra/heartbeat-visibility.ts"} +{"declaration":"export function resolveIndicatorType(status: \"sent\" | \"ok-empty\" | \"ok-token\" | \"skipped\" | \"failed\"): HeartbeatIndicatorType | undefined;","entrypoint":"channel-runtime","exportName":"resolveIndicatorType","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":23,"sourcePath":"src/infra/heartbeat-events.ts"} {"declaration":"export function resolvePollMaxSelections(optionCount: number, allowMultiselect: boolean | undefined): number;","entrypoint":"channel-runtime","exportName":"resolvePollMaxSelections","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":29,"sourcePath":"src/polls.ts"} {"declaration":"export function resolveWhatsAppHeartbeatRecipients(cfg: OpenClawConfig, opts?: HeartbeatRecipientsOpts): HeartbeatRecipientsResult;","entrypoint":"channel-runtime","exportName":"resolveWhatsAppHeartbeatRecipients","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":48,"sourcePath":"src/channels/plugins/whatsapp-heartbeat.ts"} {"declaration":"export function waitUntilAbort(signal?: AbortSignal | undefined, onAbort?: (() => void | Promise) | undefined): Promise;","entrypoint":"channel-runtime","exportName":"waitUntilAbort","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"function","recordType":"export","sourceLine":38,"sourcePath":"src/plugin-sdk/channel-lifecycle.ts"} @@ -256,10 +263,13 @@ {"declaration":"export type ChannelToolSend = ChannelToolSend;","entrypoint":"channel-runtime","exportName":"ChannelToolSend","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":509,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChatType = ChatType;","entrypoint":"channel-runtime","exportName":"ChatType","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":1,"sourcePath":"src/channels/chat-type.ts"} {"declaration":"export type CreateTypingCallbacksParams = CreateTypingCallbacksParams;","entrypoint":"channel-runtime","exportName":"CreateTypingCallbacksParams","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":11,"sourcePath":"src/channels/typing.ts"} +{"declaration":"export type HeartbeatEventPayload = HeartbeatEventPayload;","entrypoint":"channel-runtime","exportName":"HeartbeatEventPayload","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":6,"sourcePath":"src/infra/heartbeat-events.ts"} +{"declaration":"export type HeartbeatIndicatorType = HeartbeatIndicatorType;","entrypoint":"channel-runtime","exportName":"HeartbeatIndicatorType","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":4,"sourcePath":"src/infra/heartbeat-events.ts"} {"declaration":"export type NormalizedPollInput = NormalizedPollInput;","entrypoint":"channel-runtime","exportName":"NormalizedPollInput","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":17,"sourcePath":"src/polls.ts"} {"declaration":"export type PollInput = PollInput;","entrypoint":"channel-runtime","exportName":"PollInput","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":1,"sourcePath":"src/polls.ts"} {"declaration":"export type ReplyPrefixContextBundle = ReplyPrefixContextBundle;","entrypoint":"channel-runtime","exportName":"ReplyPrefixContextBundle","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":12,"sourcePath":"src/channels/reply-prefix.ts"} {"declaration":"export type ReplyPrefixOptions = ReplyPrefixOptions;","entrypoint":"channel-runtime","exportName":"ReplyPrefixOptions","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":20,"sourcePath":"src/channels/reply-prefix.ts"} +{"declaration":"export type ResolvedHeartbeatVisibility = ResolvedHeartbeatVisibility;","entrypoint":"channel-runtime","exportName":"ResolvedHeartbeatVisibility","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":5,"sourcePath":"src/infra/heartbeat-visibility.ts"} {"declaration":"export type TypingCallbacks = TypingCallbacks;","entrypoint":"channel-runtime","exportName":"TypingCallbacks","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":4,"sourcePath":"src/channels/typing.ts"} {"category":"channel","entrypoint":"channel-setup","importSpecifier":"openclaw/plugin-sdk/channel-setup","recordType":"module","sourceLine":1,"sourcePath":"src/plugin-sdk/channel-setup.ts"} {"declaration":"export function createOptionalChannelSetupAdapter(params: OptionalChannelSetupParams): ChannelSetupAdapter;","entrypoint":"channel-setup","exportName":"createOptionalChannelSetupAdapter","importSpecifier":"openclaw/plugin-sdk/channel-setup","kind":"function","recordType":"export","sourceLine":22,"sourcePath":"src/plugin-sdk/optional-channel-setup.ts"} @@ -394,7 +404,7 @@ {"declaration":"export type ChannelMessageActionContext = ChannelMessageActionContext;","entrypoint":"core","exportName":"ChannelMessageActionContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":482,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelMessagingAdapter = ChannelMessagingAdapter;","entrypoint":"core","exportName":"ChannelMessagingAdapter","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":395,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelOutboundSessionRoute = ChannelOutboundSessionRoute;","entrypoint":"core","exportName":"ChannelOutboundSessionRoute","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":309,"sourcePath":"src/channels/plugins/types.core.ts"} -{"declaration":"export type ChannelOutboundSessionRouteParams = { cfg: OpenClawConfig; agentId: string; accountId?: string | null; target: string; resolvedTarget?: { to: string; kind: import(\"src/channels/plugins/types.core\").ChannelDirectoryEntryKind | \"channel\"; display?: string; source: \"normalized\" | \"directory\"; }; replyToId?: string | null; threadId?: string | number | null;};","entrypoint":"core","exportName":"ChannelOutboundSessionRouteParams","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":159,"sourcePath":"src/plugin-sdk/core.ts"} +{"declaration":"export type ChannelOutboundSessionRouteParams = { cfg: OpenClawConfig; agentId: string; accountId?: string | null; target: string; resolvedTarget?: { to: string; kind: import(\"../channels/plugins/types.core.js\").ChannelDirectoryEntryKind | \"channel\"; display?: string; source: \"normalized\" | \"directory\"; }; replyToId?: string | null; threadId?: string | number | null;};","entrypoint":"core","exportName":"ChannelOutboundSessionRouteParams","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":159,"sourcePath":"src/plugin-sdk/core.ts"} {"declaration":"export type ChannelPlugin = ChannelPlugin;","entrypoint":"core","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":76,"sourcePath":"src/channels/plugins/types.plugin.ts"} {"declaration":"export type GatewayBindUrlResult = GatewayBindUrlResult;","entrypoint":"core","exportName":"GatewayBindUrlResult","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":1,"sourcePath":"src/shared/gateway-bind-url.ts"} {"declaration":"export type GatewayRequestHandlerOptions = GatewayRequestHandlerOptions;","entrypoint":"core","exportName":"GatewayRequestHandlerOptions","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":115,"sourcePath":"src/gateway/server-methods/types.ts"} diff --git a/extensions/whatsapp/src/auto-reply/heartbeat-runner.test.ts b/extensions/whatsapp/src/auto-reply/heartbeat-runner.test.ts index 7e8a7467421..c770c0b5e55 100644 --- a/extensions/whatsapp/src/auto-reply/heartbeat-runner.test.ts +++ b/extensions/whatsapp/src/auto-reply/heartbeat-runner.test.ts @@ -57,8 +57,8 @@ vi.mock("openclaw/plugin-sdk/routing", async (importOriginal) => { }; }); -vi.mock("openclaw/plugin-sdk/infra-runtime", async (importOriginal) => { - const actual = await importOriginal(); +vi.mock("openclaw/plugin-sdk/channel-runtime", async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, resolveHeartbeatVisibility: () => state.visibility, diff --git a/extensions/whatsapp/src/auto-reply/heartbeat-runner.ts b/extensions/whatsapp/src/auto-reply/heartbeat-runner.ts index 8c8c8639734..deaeb585956 100644 --- a/extensions/whatsapp/src/auto-reply/heartbeat-runner.ts +++ b/extensions/whatsapp/src/auto-reply/heartbeat-runner.ts @@ -1,4 +1,9 @@ import { appendCronStyleCurrentTimeLine } from "openclaw/plugin-sdk/agent-runtime"; +import { + emitHeartbeatEvent, + resolveHeartbeatVisibility, + resolveIndicatorType, +} from "openclaw/plugin-sdk/channel-runtime"; import { loadConfig } from "openclaw/plugin-sdk/config-runtime"; import { loadSessionStore, @@ -6,8 +11,6 @@ import { resolveStorePath, updateSessionStore, } from "openclaw/plugin-sdk/config-runtime"; -import { emitHeartbeatEvent, resolveIndicatorType } from "openclaw/plugin-sdk/infra-runtime"; -import { resolveHeartbeatVisibility } from "openclaw/plugin-sdk/infra-runtime"; import { hasOutboundReplyContent, resolveSendableOutboundReplyParts, diff --git a/src/plugin-sdk/channel-runtime.ts b/src/plugin-sdk/channel-runtime.ts index bc15df49749..bf9751951d2 100644 --- a/src/plugin-sdk/channel-runtime.ts +++ b/src/plugin-sdk/channel-runtime.ts @@ -13,6 +13,8 @@ export * from "../channels/plugins/whatsapp-heartbeat.js"; export * from "../polls.js"; export { enqueueSystemEvent } from "../infra/system-events.js"; export { recordChannelActivity } from "../infra/channel-activity.js"; +export * from "../infra/heartbeat-events.ts"; +export * from "../infra/heartbeat-visibility.ts"; export { isWhatsAppGroupJid, isWhatsAppUserTarget,