From a88fbf0f64765dfd96fd79b49000248c0b368903 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 11 Apr 2026 22:24:55 +0100 Subject: [PATCH] fix(cycles): split reply payload and option contracts --- src/agents/btw.ts | 3 +- src/agents/command/delivery.ts | 2 +- src/agents/pi-embedded-runner/run/params.ts | 2 +- src/agents/pi-embedded-subscribe.ts | 2 +- src/agents/pi-embedded-subscribe.types.ts | 2 +- src/auto-reply/get-reply-options.types.ts | 149 +++++++++++++ src/auto-reply/reply-payload.ts | 46 ++++ src/auto-reply/reply/dispatch-from-config.ts | 3 +- .../reply/dispatch-from-config.types.ts | 2 +- src/auto-reply/reply/get-reply.ts | 3 +- src/auto-reply/reply/get-reply.types.ts | 3 +- .../reply/provider-dispatcher.types.ts | 2 +- src/auto-reply/types.ts | 203 +----------------- src/channels/plugins/exec-approval-local.ts | 2 +- src/channels/plugins/outbound.types.ts | 2 +- src/channels/plugins/types.adapters.ts | 2 +- src/channels/plugins/types.core.ts | 2 +- src/channels/reply-prefix.ts | 2 +- src/cron/isolated-agent/delivery-dispatch.ts | 2 +- src/cron/isolated-agent/helpers.ts | 2 +- .../server-methods/chat-webchat-media.ts | 2 +- src/gateway/server-methods/chat.ts | 2 +- .../server.chat.gateway-server-chat-b.test.ts | 2 +- src/gateway/test-helpers.runtime-state.ts | 3 +- src/plugin-sdk/approval-client-helpers.ts | 2 +- src/plugin-sdk/approval-renderers.ts | 2 +- src/plugin-sdk/channel-reply-pipeline.ts | 2 +- src/plugin-sdk/core.ts | 2 +- src/plugin-sdk/feishu.ts | 2 +- src/plugin-sdk/inbound-reply-dispatch.ts | 2 +- src/plugin-sdk/index.ts | 2 +- src/plugin-sdk/line.ts | 2 +- src/plugin-sdk/matrix.ts | 3 +- src/plugin-sdk/mattermost.ts | 2 +- src/plugin-sdk/msteams.ts | 2 +- src/plugin-sdk/reply-chunking.ts | 2 +- src/plugin-sdk/reply-dispatch-runtime.ts | 2 +- src/plugin-sdk/reply-payload.ts | 2 +- src/plugin-sdk/reply-reference.ts | 2 +- src/plugin-sdk/reply-runtime.ts | 4 +- src/plugin-sdk/tlon.ts | 2 +- src/plugin-sdk/twitch.ts | 2 +- src/plugin-sdk/zalo.ts | 2 +- src/plugin-sdk/zalouser.ts | 2 +- src/plugins/conversation-binding.ts | 2 +- src/plugins/conversation-binding.types.ts | 2 +- src/plugins/hook-types.ts | 2 +- src/plugins/types.ts | 2 +- 48 files changed, 256 insertions(+), 240 deletions(-) create mode 100644 src/auto-reply/get-reply-options.types.ts create mode 100644 src/auto-reply/reply-payload.ts diff --git a/src/agents/btw.ts b/src/agents/btw.ts index b3b2938d121..ab71d9e9b22 100644 --- a/src/agents/btw.ts +++ b/src/agents/btw.ts @@ -8,8 +8,9 @@ import { type TextContent, } from "@mariozechner/pi-ai"; import { SessionManager } from "@mariozechner/pi-coding-agent"; +import type { GetReplyOptions } from "../auto-reply/get-reply-options.types.js"; +import type { ReplyPayload } from "../auto-reply/reply-payload.js"; import type { ReasoningLevel, ThinkLevel } from "../auto-reply/thinking.js"; -import type { GetReplyOptions, ReplyPayload } from "../auto-reply/types.js"; import { resolveSessionFilePath, resolveSessionFilePathOptions, diff --git a/src/agents/command/delivery.ts b/src/agents/command/delivery.ts index 1f8e766a02a..9a26577c9ec 100644 --- a/src/agents/command/delivery.ts +++ b/src/agents/command/delivery.ts @@ -1,6 +1,6 @@ import { resolveSessionAgentId } from "../../agents/agent-scope.js"; +import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import { normalizeReplyPayload } from "../../auto-reply/reply/normalize-reply.js"; -import type { ReplyPayload } from "../../auto-reply/types.js"; import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js"; import { createReplyPrefixContext } from "../../channels/reply-prefix.js"; import { createOutboundSendDeps, type CliDeps } from "../../cli/outbound-send-deps.js"; diff --git a/src/agents/pi-embedded-runner/run/params.ts b/src/agents/pi-embedded-runner/run/params.ts index 6227a0c7d29..74d6839d578 100644 --- a/src/agents/pi-embedded-runner/run/params.ts +++ b/src/agents/pi-embedded-runner/run/params.ts @@ -1,7 +1,7 @@ import type { ImageContent } from "@mariozechner/pi-ai"; +import type { ReplyPayload } from "../../../auto-reply/reply-payload.js"; import type { ReplyOperation } from "../../../auto-reply/reply/reply-run-registry.js"; import type { ReasoningLevel, ThinkLevel, VerboseLevel } from "../../../auto-reply/thinking.js"; -import type { ReplyPayload } from "../../../auto-reply/types.js"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import type { PromptImageOrderEntry } from "../../../media/prompt-image-order.js"; import type { CommandQueueEnqueueFn } from "../../../process/command-queue.types.js"; diff --git a/src/agents/pi-embedded-subscribe.ts b/src/agents/pi-embedded-subscribe.ts index 0d61a8e0446..c960572d5e1 100644 --- a/src/agents/pi-embedded-subscribe.ts +++ b/src/agents/pi-embedded-subscribe.ts @@ -1,9 +1,9 @@ import type { AgentMessage } from "@mariozechner/pi-agent-core"; +import { setReplyPayloadMetadata } from "../auto-reply/reply-payload.js"; import { parseReplyDirectives } from "../auto-reply/reply/reply-directives.js"; import { createStreamingDirectiveAccumulator } from "../auto-reply/reply/streaming-directives.js"; import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js"; import { formatToolAggregate } from "../auto-reply/tool-meta.js"; -import { setReplyPayloadMetadata } from "../auto-reply/types.js"; import { emitAgentEvent } from "../infra/agent-events.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import type { InlineCodeState } from "../markdown/code-spans.js"; diff --git a/src/agents/pi-embedded-subscribe.types.ts b/src/agents/pi-embedded-subscribe.types.ts index e4431a44be2..9673ae5f651 100644 --- a/src/agents/pi-embedded-subscribe.types.ts +++ b/src/agents/pi-embedded-subscribe.types.ts @@ -1,6 +1,6 @@ import type { AgentSession } from "@mariozechner/pi-coding-agent"; +import type { ReplyPayload } from "../auto-reply/reply-payload.js"; import type { ReasoningLevel, VerboseLevel } from "../auto-reply/thinking.js"; -import type { ReplyPayload } from "../auto-reply/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { HookRunner } from "../plugins/hooks.js"; import type { AgentInternalEvent } from "./internal-events.js"; diff --git a/src/auto-reply/get-reply-options.types.ts b/src/auto-reply/get-reply-options.types.ts new file mode 100644 index 00000000000..82af92dc0ec --- /dev/null +++ b/src/auto-reply/get-reply-options.types.ts @@ -0,0 +1,149 @@ +import type { ImageContent } from "@mariozechner/pi-ai"; +import type { PromptImageOrderEntry } from "../media/prompt-image-order.js"; +import type { ReplyPayload } from "./reply-payload.js"; +import type { TypingController } from "./reply/typing.js"; + +export type BlockReplyContext = { + abortSignal?: AbortSignal; + timeoutMs?: number; + /** Source assistant message index from the upstream stream, when available. */ + assistantMessageIndex?: number; +}; + +/** Context passed to onModelSelected callback with actual model used. */ +export type ModelSelectedContext = { + provider: string; + model: string; + thinkLevel: string | undefined; +}; + +export type TypingPolicy = + | "auto" + | "user_message" + | "system_event" + | "internal_webchat" + | "heartbeat"; + +export type ReplyThreadingPolicy = { + /** Override implicit reply-to-current behavior for the current turn. */ + implicitCurrentMessage?: "default" | "allow" | "deny"; +}; + +export type GetReplyOptions = { + /** Override run id for agent events (defaults to random UUID). */ + runId?: string; + /** Abort signal for the underlying agent run. */ + abortSignal?: AbortSignal; + /** Optional inbound images (used for webchat attachments). */ + images?: ImageContent[]; + /** Original inline/offloaded attachment order for inbound images. */ + imageOrder?: PromptImageOrderEntry[]; + /** Notifies when an agent run actually starts (useful for webchat command handling). */ + onAgentRunStart?: (runId: string) => void; + onReplyStart?: () => Promise | void; + /** Called when the typing controller cleans up (e.g., run ended with NO_REPLY). */ + onTypingCleanup?: () => void; + onTypingController?: (typing: TypingController) => void; + isHeartbeat?: boolean; + /** Policy-level typing control for run classes (user/system/internal/heartbeat). */ + typingPolicy?: TypingPolicy; + /** Force-disable typing indicators for this run (system/internal/cross-channel routes). */ + suppressTyping?: boolean; + /** Resolved heartbeat model override (provider/model string from merged per-agent config). */ + heartbeatModelOverride?: string; + /** Controls bootstrap workspace context injection (default: full). */ + bootstrapContextMode?: "full" | "lightweight"; + /** If true, suppress tool error warning payloads for this run. */ + suppressToolErrorWarnings?: boolean; + onPartialReply?: (payload: ReplyPayload) => Promise | void; + onReasoningStream?: (payload: ReplyPayload) => Promise | void; + /** Called when a thinking/reasoning block ends. */ + onReasoningEnd?: () => Promise | void; + /** Called when a new assistant message starts (e.g., after tool call or thinking block). */ + onAssistantMessageStart?: () => Promise | void; + /** Called synchronously when a block reply is logically emitted, before async + * delivery drains. Useful for channels that need to rotate preview state at + * block boundaries without waiting for transport acks. */ + onBlockReplyQueued?: (payload: ReplyPayload, context?: BlockReplyContext) => Promise | void; + onBlockReply?: (payload: ReplyPayload, context?: BlockReplyContext) => Promise | void; + onToolResult?: (payload: ReplyPayload) => Promise | void; + /** Called when a tool phase starts/updates, before summary payloads are emitted. */ + onToolStart?: (payload: { name?: string; phase?: string }) => Promise | void; + /** Called when a concrete work item starts, updates, or completes. */ + onItemEvent?: (payload: { + itemId?: string; + kind?: string; + title?: string; + name?: string; + phase?: string; + status?: string; + summary?: string; + progressText?: string; + approvalId?: string; + approvalSlug?: string; + }) => Promise | void; + /** Called when the agent emits a structured plan update. */ + onPlanUpdate?: (payload: { + phase?: string; + title?: string; + explanation?: string; + steps?: string[]; + source?: string; + }) => Promise | void; + /** Called when an approval becomes pending or resolves. */ + onApprovalEvent?: (payload: { + phase?: string; + kind?: string; + status?: string; + title?: string; + itemId?: string; + toolCallId?: string; + approvalId?: string; + approvalSlug?: string; + command?: string; + host?: string; + reason?: string; + message?: string; + }) => Promise | void; + /** Called when command output streams or completes. */ + onCommandOutput?: (payload: { + itemId?: string; + phase?: string; + title?: string; + toolCallId?: string; + name?: string; + output?: string; + status?: string; + exitCode?: number | null; + durationMs?: number; + cwd?: string; + }) => Promise | void; + /** Called when a patch completes with a file summary. */ + onPatchSummary?: (payload: { + itemId?: string; + phase?: string; + title?: string; + toolCallId?: string; + name?: string; + added?: string[]; + modified?: string[]; + deleted?: string[]; + summary?: string; + }) => Promise | void; + /** Called when context auto-compaction starts (allows UX feedback during the pause). */ + onCompactionStart?: () => Promise | void; + /** Called when context auto-compaction completes. */ + onCompactionEnd?: () => Promise | void; + /** Called when the actual model is selected (including after fallback). + * Use this to get model/provider/thinkLevel for responsePrefix template interpolation. */ + onModelSelected?: (ctx: ModelSelectedContext) => void; + disableBlockStreaming?: boolean; + /** Timeout for block reply delivery (ms). */ + blockReplyTimeoutMs?: number; + /** If provided, only load these skills for this session (empty = no skills). */ + skillFilter?: string[]; + /** Mutable ref to track if a reply was sent (for Slack "first" threading mode). */ + hasRepliedRef?: { value: boolean }; + /** Override agent timeout in seconds (0 = no timeout). Threads through to resolveAgentTimeoutMs. */ + timeoutOverrideSeconds?: number; +}; diff --git a/src/auto-reply/reply-payload.ts b/src/auto-reply/reply-payload.ts new file mode 100644 index 00000000000..6660fc83df2 --- /dev/null +++ b/src/auto-reply/reply-payload.ts @@ -0,0 +1,46 @@ +import type { InteractiveReply } from "../interactive/payload.js"; + +export type ReplyPayload = { + text?: string; + mediaUrl?: string; + mediaUrls?: string[]; + interactive?: InteractiveReply; + btw?: { + question: string; + }; + replyToId?: string; + replyToTag?: boolean; + /** True when [[reply_to_current]] was present but not yet mapped to a message id. */ + replyToCurrent?: boolean; + /** Send audio as voice message (bubble) instead of audio file. Defaults to false. */ + audioAsVoice?: boolean; + isError?: boolean; + /** Marks this payload as a reasoning/thinking block. Channels that do not + * have a dedicated reasoning lane (e.g. WhatsApp, web) should suppress it. */ + isReasoning?: boolean; + /** Marks this payload as a compaction status notice (start/end). + * Should be excluded from TTS transcript accumulation so compaction + * status lines are not synthesised into the spoken assistant reply. */ + isCompactionNotice?: boolean; + /** Channel-specific payload data (per-channel envelope). */ + channelData?: Record; +}; + +export type ReplyPayloadMetadata = { + assistantMessageIndex?: number; +}; + +const replyPayloadMetadata = new WeakMap(); + +export function setReplyPayloadMetadata( + payload: T, + metadata: ReplyPayloadMetadata, +): T { + const previous = replyPayloadMetadata.get(payload); + replyPayloadMetadata.set(payload, { ...previous, ...metadata }); + return payload; +} + +export function getReplyPayloadMetadata(payload: object): ReplyPayloadMetadata | undefined { + return replyPayloadMetadata.get(payload); +} diff --git a/src/auto-reply/reply/dispatch-from-config.ts b/src/auto-reply/reply/dispatch-from-config.ts index d37d3a095f2..7370606f2c5 100644 --- a/src/auto-reply/reply/dispatch-from-config.ts +++ b/src/auto-reply/reply/dispatch-from-config.ts @@ -48,9 +48,10 @@ import { shouldAttemptTtsPayload, } from "../../tts/tts-config.js"; import { INTERNAL_MESSAGE_CHANNEL, normalizeMessageChannel } from "../../utils/message-channel.js"; +import type { BlockReplyContext } from "../get-reply-options.types.js"; +import { getReplyPayloadMetadata, type ReplyPayload } from "../reply-payload.js"; import type { FinalizedMsgContext } from "../templating.js"; import { normalizeVerboseLevel } from "../thinking.js"; -import { getReplyPayloadMetadata, type BlockReplyContext, type ReplyPayload } from "../types.js"; import { createInternalHookEvent, loadSessionStore, diff --git a/src/auto-reply/reply/dispatch-from-config.types.ts b/src/auto-reply/reply/dispatch-from-config.types.ts index 03b3ac0341f..5483d2f52e3 100644 --- a/src/auto-reply/reply/dispatch-from-config.types.ts +++ b/src/auto-reply/reply/dispatch-from-config.types.ts @@ -1,6 +1,6 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js"; +import type { GetReplyOptions } from "../get-reply-options.types.js"; import type { FinalizedMsgContext } from "../templating.js"; -import type { GetReplyOptions } from "../types.js"; import type { ReplyDispatchKind, ReplyDispatcher } from "./reply-dispatcher.types.js"; export type DispatchFromConfigResult = { diff --git a/src/auto-reply/reply/get-reply.ts b/src/auto-reply/reply/get-reply.ts index 3dcd77e6a64..605f27a59b5 100644 --- a/src/auto-reply/reply/get-reply.ts +++ b/src/auto-reply/reply/get-reply.ts @@ -13,10 +13,11 @@ import { type OpenClawConfig, loadConfig } from "../../config/config.js"; import { defaultRuntime } from "../../runtime.js"; import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { normalizeStringEntries } from "../../shared/string-normalization.js"; +import type { GetReplyOptions } from "../get-reply-options.types.js"; +import type { ReplyPayload } from "../reply-payload.js"; import type { MsgContext } from "../templating.js"; import { normalizeVerboseLevel } from "../thinking.js"; import { SILENT_REPLY_TOKEN } from "../tokens.js"; -import type { GetReplyOptions, ReplyPayload } from "../types.js"; import { resolveDefaultModel } from "./directive-handling.defaults.js"; import { clearInlineDirectives } from "./get-reply-directives-utils.js"; import { resolveReplyDirectives } from "./get-reply-directives.js"; diff --git a/src/auto-reply/reply/get-reply.types.ts b/src/auto-reply/reply/get-reply.types.ts index 9e7e1039f64..58e75b25954 100644 --- a/src/auto-reply/reply/get-reply.types.ts +++ b/src/auto-reply/reply/get-reply.types.ts @@ -1,6 +1,7 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js"; +import type { GetReplyOptions } from "../get-reply-options.types.js"; +import type { ReplyPayload } from "../reply-payload.js"; import type { MsgContext } from "../templating.js"; -import type { GetReplyOptions, ReplyPayload } from "../types.js"; export type GetReplyFromConfig = ( ctx: MsgContext, diff --git a/src/auto-reply/reply/provider-dispatcher.types.ts b/src/auto-reply/reply/provider-dispatcher.types.ts index 1f944a05a37..3259efe8ad0 100644 --- a/src/auto-reply/reply/provider-dispatcher.types.ts +++ b/src/auto-reply/reply/provider-dispatcher.types.ts @@ -1,6 +1,6 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js"; +import type { GetReplyOptions } from "../get-reply-options.types.js"; import type { FinalizedMsgContext, MsgContext } from "../templating.js"; -import type { GetReplyOptions } from "../types.js"; import type { DispatchFromConfigResult } from "./dispatch-from-config.types.js"; import type { GetReplyFromConfig } from "./get-reply.types.js"; import type { diff --git a/src/auto-reply/types.ts b/src/auto-reply/types.ts index b01afbb52d6..dc2266da704 100644 --- a/src/auto-reply/types.ts +++ b/src/auto-reply/types.ts @@ -1,194 +1,9 @@ -import type { ImageContent } from "@mariozechner/pi-ai"; -import type { InteractiveReply } from "../interactive/payload.js"; -import type { PromptImageOrderEntry } from "../media/prompt-image-order.js"; -import type { TypingController } from "./reply/typing.js"; - -export type BlockReplyContext = { - abortSignal?: AbortSignal; - timeoutMs?: number; - /** Source assistant message index from the upstream stream, when available. */ - assistantMessageIndex?: number; -}; - -/** Context passed to onModelSelected callback with actual model used. */ -export type ModelSelectedContext = { - provider: string; - model: string; - thinkLevel: string | undefined; -}; - -export type TypingPolicy = - | "auto" - | "user_message" - | "system_event" - | "internal_webchat" - | "heartbeat"; - -export type ReplyThreadingPolicy = { - /** Override implicit reply-to-current behavior for the current turn. */ - implicitCurrentMessage?: "default" | "allow" | "deny"; -}; - -export type GetReplyOptions = { - /** Override run id for agent events (defaults to random UUID). */ - runId?: string; - /** Abort signal for the underlying agent run. */ - abortSignal?: AbortSignal; - /** Optional inbound images (used for webchat attachments). */ - images?: ImageContent[]; - /** Original inline/offloaded attachment order for inbound images. */ - imageOrder?: PromptImageOrderEntry[]; - /** Notifies when an agent run actually starts (useful for webchat command handling). */ - onAgentRunStart?: (runId: string) => void; - onReplyStart?: () => Promise | void; - /** Called when the typing controller cleans up (e.g., run ended with NO_REPLY). */ - onTypingCleanup?: () => void; - onTypingController?: (typing: TypingController) => void; - isHeartbeat?: boolean; - /** Policy-level typing control for run classes (user/system/internal/heartbeat). */ - typingPolicy?: TypingPolicy; - /** Force-disable typing indicators for this run (system/internal/cross-channel routes). */ - suppressTyping?: boolean; - /** Resolved heartbeat model override (provider/model string from merged per-agent config). */ - heartbeatModelOverride?: string; - /** Controls bootstrap workspace context injection (default: full). */ - bootstrapContextMode?: "full" | "lightweight"; - /** If true, suppress tool error warning payloads for this run. */ - suppressToolErrorWarnings?: boolean; - onPartialReply?: (payload: ReplyPayload) => Promise | void; - onReasoningStream?: (payload: ReplyPayload) => Promise | void; - /** Called when a thinking/reasoning block ends. */ - onReasoningEnd?: () => Promise | void; - /** Called when a new assistant message starts (e.g., after tool call or thinking block). */ - onAssistantMessageStart?: () => Promise | void; - /** Called synchronously when a block reply is logically emitted, before async - * delivery drains. Useful for channels that need to rotate preview state at - * block boundaries without waiting for transport acks. */ - onBlockReplyQueued?: (payload: ReplyPayload, context?: BlockReplyContext) => Promise | void; - onBlockReply?: (payload: ReplyPayload, context?: BlockReplyContext) => Promise | void; - onToolResult?: (payload: ReplyPayload) => Promise | void; - /** Called when a tool phase starts/updates, before summary payloads are emitted. */ - onToolStart?: (payload: { name?: string; phase?: string }) => Promise | void; - /** Called when a concrete work item starts, updates, or completes. */ - onItemEvent?: (payload: { - itemId?: string; - kind?: string; - title?: string; - name?: string; - phase?: string; - status?: string; - summary?: string; - progressText?: string; - approvalId?: string; - approvalSlug?: string; - }) => Promise | void; - /** Called when the agent emits a structured plan update. */ - onPlanUpdate?: (payload: { - phase?: string; - title?: string; - explanation?: string; - steps?: string[]; - source?: string; - }) => Promise | void; - /** Called when an approval becomes pending or resolves. */ - onApprovalEvent?: (payload: { - phase?: string; - kind?: string; - status?: string; - title?: string; - itemId?: string; - toolCallId?: string; - approvalId?: string; - approvalSlug?: string; - command?: string; - host?: string; - reason?: string; - message?: string; - }) => Promise | void; - /** Called when command output streams or completes. */ - onCommandOutput?: (payload: { - itemId?: string; - phase?: string; - title?: string; - toolCallId?: string; - name?: string; - output?: string; - status?: string; - exitCode?: number | null; - durationMs?: number; - cwd?: string; - }) => Promise | void; - /** Called when a patch completes with a file summary. */ - onPatchSummary?: (payload: { - itemId?: string; - phase?: string; - title?: string; - toolCallId?: string; - name?: string; - added?: string[]; - modified?: string[]; - deleted?: string[]; - summary?: string; - }) => Promise | void; - /** Called when context auto-compaction starts (allows UX feedback during the pause). */ - onCompactionStart?: () => Promise | void; - /** Called when context auto-compaction completes. */ - onCompactionEnd?: () => Promise | void; - /** Called when the actual model is selected (including after fallback). - * Use this to get model/provider/thinkLevel for responsePrefix template interpolation. */ - onModelSelected?: (ctx: ModelSelectedContext) => void; - disableBlockStreaming?: boolean; - /** Timeout for block reply delivery (ms). */ - blockReplyTimeoutMs?: number; - /** If provided, only load these skills for this session (empty = no skills). */ - skillFilter?: string[]; - /** Mutable ref to track if a reply was sent (for Slack "first" threading mode). */ - hasRepliedRef?: { value: boolean }; - /** Override agent timeout in seconds (0 = no timeout). Threads through to resolveAgentTimeoutMs. */ - timeoutOverrideSeconds?: number; -}; - -export type ReplyPayload = { - text?: string; - mediaUrl?: string; - mediaUrls?: string[]; - interactive?: InteractiveReply; - btw?: { - question: string; - }; - replyToId?: string; - replyToTag?: boolean; - /** True when [[reply_to_current]] was present but not yet mapped to a message id. */ - replyToCurrent?: boolean; - /** Send audio as voice message (bubble) instead of audio file. Defaults to false. */ - audioAsVoice?: boolean; - isError?: boolean; - /** Marks this payload as a reasoning/thinking block. Channels that do not - * have a dedicated reasoning lane (e.g. WhatsApp, web) should suppress it. */ - isReasoning?: boolean; - /** Marks this payload as a compaction status notice (start/end). - * Should be excluded from TTS transcript accumulation so compaction - * status lines are not synthesised into the spoken assistant reply. */ - isCompactionNotice?: boolean; - /** Channel-specific payload data (per-channel envelope). */ - channelData?: Record; -}; - -export type ReplyPayloadMetadata = { - assistantMessageIndex?: number; -}; - -const replyPayloadMetadata = new WeakMap(); - -export function setReplyPayloadMetadata( - payload: T, - metadata: ReplyPayloadMetadata, -): T { - const previous = replyPayloadMetadata.get(payload); - replyPayloadMetadata.set(payload, { ...previous, ...metadata }); - return payload; -} - -export function getReplyPayloadMetadata(payload: object): ReplyPayloadMetadata | undefined { - return replyPayloadMetadata.get(payload); -} +export type { + BlockReplyContext, + GetReplyOptions, + ModelSelectedContext, + ReplyThreadingPolicy, + TypingPolicy, +} from "./get-reply-options.types.js"; +export { getReplyPayloadMetadata, setReplyPayloadMetadata } from "./reply-payload.js"; +export type { ReplyPayload, ReplyPayloadMetadata } from "./reply-payload.js"; diff --git a/src/channels/plugins/exec-approval-local.ts b/src/channels/plugins/exec-approval-local.ts index 2157ba91ae6..5c01d753a09 100644 --- a/src/channels/plugins/exec-approval-local.ts +++ b/src/channels/plugins/exec-approval-local.ts @@ -1,4 +1,4 @@ -import type { ReplyPayload } from "../../auto-reply/types.js"; +import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { getChannelPlugin, normalizeChannelId } from "./registry.js"; diff --git a/src/channels/plugins/outbound.types.ts b/src/channels/plugins/outbound.types.ts index c170a8ddfe3..2c78a68f0f0 100644 --- a/src/channels/plugins/outbound.types.ts +++ b/src/channels/plugins/outbound.types.ts @@ -1,4 +1,4 @@ -import type { ReplyPayload } from "../../auto-reply/types.js"; +import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { OutboundDeliveryResult } from "../../infra/outbound/deliver-types.js"; import type { OutboundIdentity } from "../../infra/outbound/identity-types.js"; diff --git a/src/channels/plugins/types.adapters.ts b/src/channels/plugins/types.adapters.ts index c94c8a91757..5bf7468a015 100644 --- a/src/channels/plugins/types.adapters.ts +++ b/src/channels/plugins/types.adapters.ts @@ -1,4 +1,4 @@ -import type { ReplyPayload } from "../../auto-reply/types.js"; +import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import type { LegacyConfigRule } from "../../config/legacy.shared.js"; import type { AgentBinding } from "../../config/types.agents.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; diff --git a/src/channels/plugins/types.core.ts b/src/channels/plugins/types.core.ts index b435b9481a7..065db04e7eb 100644 --- a/src/channels/plugins/types.core.ts +++ b/src/channels/plugins/types.core.ts @@ -1,7 +1,7 @@ import type { AgentTool, AgentToolResult } from "@mariozechner/pi-agent-core"; import type { TSchema } from "@sinclair/typebox"; +import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import type { MsgContext } from "../../auto-reply/templating.js"; -import type { ReplyPayload } from "../../auto-reply/types.js"; import type { MarkdownTableMode } from "../../config/types.base.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import type { GatewayClientMode, GatewayClientName } from "../../gateway/protocol/client-info.js"; diff --git a/src/channels/reply-prefix.ts b/src/channels/reply-prefix.ts index 733af56b996..3a1b785e651 100644 --- a/src/channels/reply-prefix.ts +++ b/src/channels/reply-prefix.ts @@ -1,9 +1,9 @@ import { resolveAgentIdentity, resolveEffectiveMessagesConfig } from "../agents/identity.js"; +import type { GetReplyOptions } from "../auto-reply/get-reply-options.types.js"; import { extractShortModelName, type ResponsePrefixContext, } from "../auto-reply/reply/response-prefix-template.js"; -import type { GetReplyOptions } from "../auto-reply/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeOptionalString } from "../shared/string-coerce.js"; diff --git a/src/cron/isolated-agent/delivery-dispatch.ts b/src/cron/isolated-agent/delivery-dispatch.ts index 344111d9b0a..87014a49b89 100644 --- a/src/cron/isolated-agent/delivery-dispatch.ts +++ b/src/cron/isolated-agent/delivery-dispatch.ts @@ -1,6 +1,6 @@ import { countActiveDescendantRuns } from "../../agents/subagent-registry-read.js"; +import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../../auto-reply/tokens.js"; -import type { ReplyPayload } from "../../auto-reply/types.js"; import type { CliDeps } from "../../cli/outbound-send-deps.js"; import { resolveAgentMainSessionKey, diff --git a/src/cron/isolated-agent/helpers.ts b/src/cron/isolated-agent/helpers.ts index 77d3c071a6f..1a822215db2 100644 --- a/src/cron/isolated-agent/helpers.ts +++ b/src/cron/isolated-agent/helpers.ts @@ -1,6 +1,6 @@ import { hasOutboundReplyContent } from "openclaw/plugin-sdk/reply-payload"; import { DEFAULT_HEARTBEAT_ACK_MAX_CHARS } from "../../auto-reply/heartbeat.js"; -import type { ReplyPayload } from "../../auto-reply/types.js"; +import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import { normalizeOptionalString } from "../../shared/string-coerce.js"; import { truncateUtf16Safe } from "../../utils.js"; import { shouldSkipHeartbeatOnlyDelivery } from "../heartbeat-policy.js"; diff --git a/src/gateway/server-methods/chat-webchat-media.ts b/src/gateway/server-methods/chat-webchat-media.ts index 7fa23fb9749..c6ee258f4ea 100644 --- a/src/gateway/server-methods/chat-webchat-media.ts +++ b/src/gateway/server-methods/chat-webchat-media.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; -import type { ReplyPayload } from "../../auto-reply/types.js"; +import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import { isAudioFileName } from "../../media/mime.js"; import { resolveSendableOutboundReplyParts } from "../../plugin-sdk/reply-payload.js"; import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; diff --git a/src/gateway/server-methods/chat.ts b/src/gateway/server-methods/chat.ts index 717e588df75..660d3eedf4e 100644 --- a/src/gateway/server-methods/chat.ts +++ b/src/gateway/server-methods/chat.ts @@ -7,9 +7,9 @@ import { resolveThinkingDefault } from "../../agents/model-selection.js"; import { rewriteTranscriptEntriesInSessionFile } from "../../agents/pi-embedded-runner/transcript-rewrite.js"; import { resolveAgentTimeoutMs } from "../../agents/timeout.js"; import { dispatchInboundMessage } from "../../auto-reply/dispatch.js"; +import type { ReplyPayload } from "../../auto-reply/reply-payload.js"; import { createReplyDispatcher } from "../../auto-reply/reply/reply-dispatcher.js"; import type { MsgContext } from "../../auto-reply/templating.js"; -import type { ReplyPayload } from "../../auto-reply/types.js"; import { extractCanvasFromText } from "../../chat/canvas-render.js"; import { resolveSessionFilePath } from "../../config/sessions.js"; import { jsonUtf8Bytes } from "../../infra/json-utf8-bytes.js"; diff --git a/src/gateway/server.chat.gateway-server-chat-b.test.ts b/src/gateway/server.chat.gateway-server-chat-b.test.ts index 8e2dcf557a5..1039405181f 100644 --- a/src/gateway/server.chat.gateway-server-chat-b.test.ts +++ b/src/gateway/server.chat.gateway-server-chat-b.test.ts @@ -2,7 +2,7 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { afterAll, beforeAll, describe, expect, test, vi } from "vitest"; -import type { GetReplyOptions } from "../auto-reply/types.js"; +import type { GetReplyOptions } from "../auto-reply/get-reply-options.types.js"; import { clearConfigCache } from "../config/config.js"; import { __setMaxChatHistoryMessagesBytesForTest } from "./server-constants.js"; import { diff --git a/src/gateway/test-helpers.runtime-state.ts b/src/gateway/test-helpers.runtime-state.ts index 90badb57fa4..357c798ff15 100644 --- a/src/gateway/test-helpers.runtime-state.ts +++ b/src/gateway/test-helpers.runtime-state.ts @@ -2,8 +2,9 @@ import crypto from "node:crypto"; import os from "node:os"; import path from "node:path"; import { Mock, vi } from "vitest"; +import type { GetReplyOptions } from "../auto-reply/get-reply-options.types.js"; +import type { ReplyPayload } from "../auto-reply/reply-payload.js"; import type { MsgContext } from "../auto-reply/templating.js"; -import type { GetReplyOptions, ReplyPayload } from "../auto-reply/types.js"; import type { AgentBinding } from "../config/types.agents.js"; import type { HooksConfig } from "../config/types.hooks.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; diff --git a/src/plugin-sdk/approval-client-helpers.ts b/src/plugin-sdk/approval-client-helpers.ts index 5941bf8e9bb..4988ebcee5a 100644 --- a/src/plugin-sdk/approval-client-helpers.ts +++ b/src/plugin-sdk/approval-client-helpers.ts @@ -1,4 +1,4 @@ -import type { ReplyPayload } from "../auto-reply/types.js"; +import type { ReplyPayload } from "../auto-reply/reply-payload.js"; import type { ExecApprovalForwardTarget } from "../config/types.approvals.js"; import { matchesApprovalRequestFilters } from "../infra/approval-request-filters.js"; import { getExecApprovalReplyMetadata } from "../infra/exec-approval-reply.js"; diff --git a/src/plugin-sdk/approval-renderers.ts b/src/plugin-sdk/approval-renderers.ts index 5fe6eedb15e..e36c0d127d5 100644 --- a/src/plugin-sdk/approval-renderers.ts +++ b/src/plugin-sdk/approval-renderers.ts @@ -1,4 +1,4 @@ -import type { ReplyPayload } from "../auto-reply/types.js"; +import type { ReplyPayload } from "../auto-reply/reply-payload.js"; import { buildApprovalInteractiveReply, type ExecApprovalReplyDecision, diff --git a/src/plugin-sdk/channel-reply-pipeline.ts b/src/plugin-sdk/channel-reply-pipeline.ts index 1bb647aa3d5..b616cb8ede5 100644 --- a/src/plugin-sdk/channel-reply-pipeline.ts +++ b/src/plugin-sdk/channel-reply-pipeline.ts @@ -1,4 +1,4 @@ -import type { ReplyPayload } from "../auto-reply/types.js"; +import type { ReplyPayload } from "../auto-reply/reply-payload.js"; import { getChannelPlugin, normalizeChannelId } from "../channels/plugins/index.js"; import { createReplyPrefixContext, diff --git a/src/plugin-sdk/core.ts b/src/plugin-sdk/core.ts index eed93097f35..3c0eb1905b6 100644 --- a/src/plugin-sdk/core.ts +++ b/src/plugin-sdk/core.ts @@ -99,7 +99,7 @@ export type { export type { OpenClawConfig } from "../config/config.js"; export type { OutboundIdentity } from "../infra/outbound/identity.js"; export type { HistoryEntry } from "../auto-reply/reply/history.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export type { AllowlistMatch } from "../channels/allowlist-match.js"; export type { BaseProbeResult, diff --git a/src/plugin-sdk/feishu.ts b/src/plugin-sdk/feishu.ts index a546beda0a9..57dbf05ed76 100644 --- a/src/plugin-sdk/feishu.ts +++ b/src/plugin-sdk/feishu.ts @@ -8,7 +8,7 @@ export { DEFAULT_GROUP_HISTORY_LIMIT, recordPendingHistoryEntryIfEnabled, } from "../auto-reply/reply/history.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export { logTypingFailure } from "../channels/logging.js"; export type { AllowlistMatch } from "../channels/plugins/allowlist-match.js"; export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js"; diff --git a/src/plugin-sdk/inbound-reply-dispatch.ts b/src/plugin-sdk/inbound-reply-dispatch.ts index 1be59e0a636..bb9fb41a95f 100644 --- a/src/plugin-sdk/inbound-reply-dispatch.ts +++ b/src/plugin-sdk/inbound-reply-dispatch.ts @@ -1,4 +1,5 @@ import { withReplyDispatcher } from "../auto-reply/dispatch.js"; +import type { GetReplyOptions } from "../auto-reply/get-reply-options.types.js"; import { dispatchReplyFromConfig, type DispatchFromConfigResult, @@ -6,7 +7,6 @@ import { import type { DispatchReplyWithBufferedBlockDispatcher } from "../auto-reply/reply/provider-dispatcher.types.js"; import type { ReplyDispatcher } from "../auto-reply/reply/reply-dispatcher.types.js"; import type { FinalizedMsgContext } from "../auto-reply/templating.js"; -import type { GetReplyOptions } from "../auto-reply/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { createChannelReplyPipeline } from "./channel-reply-pipeline.js"; import { createNormalizedOutboundDeliverer, type OutboundReplyPayload } from "./reply-payload.js"; diff --git a/src/plugin-sdk/index.ts b/src/plugin-sdk/index.ts index 7789c5f1c09..917cdfdb748 100644 --- a/src/plugin-sdk/index.ts +++ b/src/plugin-sdk/index.ts @@ -90,7 +90,7 @@ export * from "./music-generation.js"; export type { SecretInput, SecretRef } from "../config/types.secrets.js"; export type { RuntimeEnv } from "../runtime.js"; export type { HookEntry } from "../hooks/types.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export type { WizardPrompter } from "../wizard/prompts.js"; export type { ContextEngineFactory } from "../context-engine/registry.js"; export type { DiagnosticEventPayload } from "../infra/diagnostic-events.js"; diff --git a/src/plugin-sdk/line.ts b/src/plugin-sdk/line.ts index 61e4c57fac0..7ae99f5c058 100644 --- a/src/plugin-sdk/line.ts +++ b/src/plugin-sdk/line.ts @@ -5,7 +5,7 @@ export type { } from "../channels/plugins/types.public.js"; export type { ChannelPlugin } from "../channels/plugins/types.plugin.js"; export type { OpenClawConfig } from "../config/config.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export type { ChannelSetupAdapter } from "../channels/plugins/types.adapters.js"; export type { OpenClawPluginApi, PluginRuntime } from "./channel-plugin-common.js"; diff --git a/src/plugin-sdk/matrix.ts b/src/plugin-sdk/matrix.ts index ba194fcf100..e63901659db 100644 --- a/src/plugin-sdk/matrix.ts +++ b/src/plugin-sdk/matrix.ts @@ -24,7 +24,8 @@ export { readStringArrayParam, readStringParam, } from "../agents/tools/common.js"; -export type { BlockReplyContext, ReplyPayload } from "../auto-reply/types.js"; +export type { BlockReplyContext } from "../auto-reply/get-reply-options.types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export { resolveAckReaction } from "../agents/identity.js"; export { compileAllowlist, diff --git a/src/plugin-sdk/mattermost.ts b/src/plugin-sdk/mattermost.ts index 1bd0841bbd6..2a771521ccf 100644 --- a/src/plugin-sdk/mattermost.ts +++ b/src/plugin-sdk/mattermost.ts @@ -10,7 +10,7 @@ export { recordPendingHistoryEntryIfEnabled, } from "../auto-reply/reply/history.js"; export { listSkillCommandsForAgents } from "../auto-reply/skill-commands.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export type { ChatType } from "../channels/chat-type.js"; export { resolveControlCommandGate } from "../channels/command-gating.js"; export { logInboundDrop, logTypingFailure } from "../channels/logging.js"; diff --git a/src/plugin-sdk/msteams.ts b/src/plugin-sdk/msteams.ts index 7edee933e83..81459ea3b3a 100644 --- a/src/plugin-sdk/msteams.ts +++ b/src/plugin-sdk/msteams.ts @@ -12,7 +12,7 @@ export { recordPendingHistoryEntryIfEnabled, } from "../auto-reply/reply/history.js"; export { isSilentReplyText, SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export { mergeAllowlist, summarizeMapping } from "../channels/allowlists/resolve-utils.js"; export { resolveControlCommandGate, diff --git a/src/plugin-sdk/reply-chunking.ts b/src/plugin-sdk/reply-chunking.ts index bd9fd4a9a5b..456b689e090 100644 --- a/src/plugin-sdk/reply-chunking.ts +++ b/src/plugin-sdk/reply-chunking.ts @@ -7,4 +7,4 @@ export { } from "../auto-reply/chunk.js"; export type { ChunkMode } from "../auto-reply/chunk.js"; export { isSilentReplyText } from "../auto-reply/tokens.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; diff --git a/src/plugin-sdk/reply-dispatch-runtime.ts b/src/plugin-sdk/reply-dispatch-runtime.ts index 94001c2e80f..9d7054b38ea 100644 --- a/src/plugin-sdk/reply-dispatch-runtime.ts +++ b/src/plugin-sdk/reply-dispatch-runtime.ts @@ -4,4 +4,4 @@ export { dispatchReplyWithBufferedBlockDispatcher, dispatchReplyWithDispatcher, } from "../auto-reply/reply/provider-dispatcher.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; diff --git a/src/plugin-sdk/reply-payload.ts b/src/plugin-sdk/reply-payload.ts index 7493e8b6938..d67902f89f0 100644 --- a/src/plugin-sdk/reply-payload.ts +++ b/src/plugin-sdk/reply-payload.ts @@ -3,7 +3,7 @@ import { readStringValue } from "../shared/string-coerce.js"; export type { MediaPayload, MediaPayloadInput } from "../channels/plugins/media-payload.js"; export { buildMediaPayload } from "../channels/plugins/media-payload.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export type OutboundReplyPayload = { text?: string; diff --git a/src/plugin-sdk/reply-reference.ts b/src/plugin-sdk/reply-reference.ts index f1449690cef..b792e2f26fb 100644 --- a/src/plugin-sdk/reply-reference.ts +++ b/src/plugin-sdk/reply-reference.ts @@ -3,4 +3,4 @@ export { isSingleUseReplyToMode, } from "../auto-reply/reply/reply-reference.js"; export { resolveBatchedReplyThreadingPolicy } from "../auto-reply/reply/reply-threading.js"; -export type { ReplyThreadingPolicy } from "../auto-reply/types.js"; +export type { ReplyThreadingPolicy } from "../auto-reply/get-reply-options.types.js"; diff --git a/src/plugin-sdk/reply-runtime.ts b/src/plugin-sdk/reply-runtime.ts index 680ec1c8035..ade9710f2cd 100644 --- a/src/plugin-sdk/reply-runtime.ts +++ b/src/plugin-sdk/reply-runtime.ts @@ -53,8 +53,8 @@ export type { ReplyDispatcherWithTypingOptions, } from "../auto-reply/reply/reply-dispatcher.js"; export { createReplyReferencePlanner } from "../auto-reply/reply/reply-reference.js"; -export type { GetReplyOptions, ReplyPayload } from "../auto-reply/types.js"; -export type { BlockReplyContext } from "../auto-reply/types.js"; +export type { GetReplyOptions, BlockReplyContext } from "../auto-reply/get-reply-options.types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export type { FinalizedMsgContext, MsgContext } from "../auto-reply/templating.js"; export { generateConversationLabel } from "../auto-reply/reply/conversation-label-generator.js"; export type { ConversationLabelParams } from "../auto-reply/reply/conversation-label-generator.js"; diff --git a/src/plugin-sdk/tlon.ts b/src/plugin-sdk/tlon.ts index 40918a2bb88..c21806bfb2d 100644 --- a/src/plugin-sdk/tlon.ts +++ b/src/plugin-sdk/tlon.ts @@ -3,7 +3,7 @@ import { createOptionalChannelSetupSurface } from "./channel-setup.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js"; export { applyAccountNameToChannelSection, diff --git a/src/plugin-sdk/twitch.ts b/src/plugin-sdk/twitch.ts index bb42f8727f9..f889fb01083 100644 --- a/src/plugin-sdk/twitch.ts +++ b/src/plugin-sdk/twitch.ts @@ -3,7 +3,7 @@ import { createOptionalChannelSetupSurface } from "./channel-setup.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js"; export type { ChannelGatewayContext, diff --git a/src/plugin-sdk/zalo.ts b/src/plugin-sdk/zalo.ts index ff5d7643d42..fcd97a3e619 100644 --- a/src/plugin-sdk/zalo.ts +++ b/src/plugin-sdk/zalo.ts @@ -2,7 +2,7 @@ // Keep this list additive and scoped to the bundled Zalo surface. export { jsonResult, readStringParam } from "../agents/tools/common.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export { deleteAccountFromConfigSection, setAccountEnabledInConfigSection, diff --git a/src/plugin-sdk/zalouser.ts b/src/plugin-sdk/zalouser.ts index f2324b0d831..9bd997fac31 100644 --- a/src/plugin-sdk/zalouser.ts +++ b/src/plugin-sdk/zalouser.ts @@ -3,7 +3,7 @@ import { createOptionalChannelSetupSurface } from "./channel-setup.js"; -export type { ReplyPayload } from "../auto-reply/types.js"; +export type { ReplyPayload } from "../auto-reply/reply-payload.js"; export { mergeAllowlist, summarizeMapping } from "../channels/allowlists/resolve-utils.js"; export { resolveMentionGating, diff --git a/src/plugins/conversation-binding.ts b/src/plugins/conversation-binding.ts index 9a33a9ad13d..79bd6094b46 100644 --- a/src/plugins/conversation-binding.ts +++ b/src/plugins/conversation-binding.ts @@ -1,7 +1,7 @@ import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; -import type { ReplyPayload } from "../auto-reply/types.js"; +import type { ReplyPayload } from "../auto-reply/reply-payload.js"; import { createConversationBindingRecord, resolveConversationBindingRecord, diff --git a/src/plugins/conversation-binding.types.ts b/src/plugins/conversation-binding.types.ts index a4423745047..efe5f444b94 100644 --- a/src/plugins/conversation-binding.types.ts +++ b/src/plugins/conversation-binding.types.ts @@ -1,4 +1,4 @@ -import type { ReplyPayload } from "../auto-reply/types.js"; +import type { ReplyPayload } from "../auto-reply/reply-payload.js"; export type PluginConversationBindingRequestParams = { summary?: string; diff --git a/src/plugins/hook-types.ts b/src/plugins/hook-types.ts index 76d4a54b382..a5186685f52 100644 --- a/src/plugins/hook-types.ts +++ b/src/plugins/hook-types.ts @@ -1,10 +1,10 @@ import type { AgentMessage } from "@mariozechner/pi-agent-core"; +import type { ReplyPayload } from "../auto-reply/reply-payload.js"; import type { ReplyDispatchKind, ReplyDispatcher, } from "../auto-reply/reply/reply-dispatcher.types.js"; import type { FinalizedMsgContext } from "../auto-reply/templating.js"; -import type { ReplyPayload } from "../auto-reply/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { TtsAutoMode } from "../config/types.tts.js"; import { diff --git a/src/plugins/types.ts b/src/plugins/types.ts index 645fab3f788..f15a59a45c9 100644 --- a/src/plugins/types.ts +++ b/src/plugins/types.ts @@ -17,8 +17,8 @@ import type { ModelProviderRequestTransportOverrides } from "../agents/provider- import type { ProviderSystemPromptContribution } from "../agents/system-prompt-contribution.js"; import type { PromptMode } from "../agents/system-prompt.types.js"; import type { AnyAgentTool } from "../agents/tools/common.js"; +import type { ReplyPayload } from "../auto-reply/reply-payload.js"; import type { ThinkLevel } from "../auto-reply/thinking.shared.js"; -import type { ReplyPayload } from "../auto-reply/types.js"; import type { ChannelPlugin } from "../channels/plugins/types.plugin.js"; import type { ChannelId } from "../channels/plugins/types.public.js"; import type { ModelProviderConfig } from "../config/types.js";