mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-09 15:59:30 +00:00
264 lines
11 KiB
TypeScript
264 lines
11 KiB
TypeScript
import type { FastMode } from "@openclaw/normalization-core/string-coerce";
|
|
/** Public option types for reply generation callbacks, streaming, and delivery policy. */
|
|
import type { ImageContent } from "../llm/types.js";
|
|
import type { PromptImageOrderEntry } from "../media/prompt-image-order.js";
|
|
import type { UserTurnTranscriptRecorder } from "../sessions/user-turn-transcript.types.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;
|
|
};
|
|
|
|
/** Typing indicator class for channel-owned UX policy. */
|
|
export type TypingPolicy =
|
|
| "auto"
|
|
| "user_message"
|
|
| "system_event"
|
|
| "internal_webchat"
|
|
| "heartbeat";
|
|
|
|
/** Per-turn policy for source-message reply threading. */
|
|
export type ReplyThreadingPolicy = {
|
|
/** Override implicit reply-to-current behavior for the current turn. */
|
|
implicitCurrentMessage?: "default" | "allow" | "deny";
|
|
};
|
|
|
|
export type SourceReplyDeliveryMode = "automatic" | "message_tool_only";
|
|
|
|
/** Correlates queued reply ownership transfer with later delivery drains. */
|
|
export type QueuedReplyDeliveryCorrelation = {
|
|
begin: () => (() => void) | void;
|
|
};
|
|
|
|
/** Lifecycle hooks for queued follow-up replies. */
|
|
export type QueuedReplyLifecycle = {
|
|
/** Stable cancellation owner used to keep collect-mode batches authorization-safe. */
|
|
ownerKey?: string;
|
|
/** Return false when the external owner rejects this queue identity. */
|
|
onEnqueued?: () => boolean | void;
|
|
/** Retires this source's cancellation ownership while retaining its live identity. */
|
|
onCancellationRetired?: () => void;
|
|
/** Called after the queued turn owns the reply lane, before model/tool execution. */
|
|
onAdmitted?: () => void;
|
|
onComplete?: () => void;
|
|
};
|
|
|
|
/** Partial assistant payload emitted during streaming or replacement updates. */
|
|
export type PartialReplyPayload = Pick<ReplyPayload, "text" | "mediaUrls"> & {
|
|
delta?: string;
|
|
replace?: true;
|
|
};
|
|
|
|
type ReasoningStreamPayload = Pick<
|
|
ReplyPayload,
|
|
"text" | "mediaUrls" | "isReasoning" | "isReasoningSnapshot"
|
|
> & {
|
|
requiresReasoningProgressOptIn?: boolean;
|
|
};
|
|
|
|
type ReasoningProgressPayload = {
|
|
progressTokens: number;
|
|
};
|
|
|
|
/** Reply generation options shared by auto-reply, webchat, channels, and tests. */
|
|
export type GetReplyOptions = {
|
|
/** Override run id for agent events (defaults to random UUID). */
|
|
runId?: string;
|
|
/** Stable provider prompt-cache affinity key; distinct from run id/idempotency. */
|
|
promptCacheKey?: 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;
|
|
/** Shared lifecycle owner for the current user-turn transcript append. */
|
|
userTurnTranscriptRecorder?: UserTurnTranscriptRecorder;
|
|
onReplyStart?: () => Promise<void> | void;
|
|
/** Called when the typing controller cleans up (e.g., run ended with NO_REPLY). */
|
|
onTypingCleanup?: () => void;
|
|
onTypingController?: (typing: TypingController) => void;
|
|
/** If false, send only the initial typing signal without periodic keepalive refreshes. */
|
|
typingKeepalive?: boolean;
|
|
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;
|
|
/** One-shot thinking level override for this run; does not persist to the session. */
|
|
thinkingLevelOverride?: string;
|
|
/** One-shot fast-mode override for this run; does not persist to the session. */
|
|
fastModeOverride?: FastMode;
|
|
/** One-shot auto fast-mode cutoff override in seconds; does not persist to the session. */
|
|
fastModeAutoOnSecondsOverride?: number;
|
|
/** Controls bootstrap workspace context injection (default: full). */
|
|
bootstrapContextMode?: "full" | "lightweight";
|
|
/** If true, suppress tool error warning payloads for this run. */
|
|
suppressToolErrorWarnings?: boolean;
|
|
/** Dynamic form used when verbose progress visibility can change mid-run. */
|
|
shouldSuppressToolErrorWarnings?: () => boolean | undefined;
|
|
/** If true, run the model without OpenClaw tools for this turn. */
|
|
disableTools?: boolean;
|
|
/** Runtime tool allow-list for this turn. Empty means no tools. */
|
|
toolsAllow?: string[];
|
|
/** If true, include the heartbeat response tool for structured heartbeat outcomes. */
|
|
enableHeartbeatTool?: boolean;
|
|
/** If true, keep the heartbeat response tool available even under narrow tool profiles. */
|
|
forceHeartbeatTool?: boolean;
|
|
/**
|
|
* If true, dispatch skips default tool/progress text messages and expects the
|
|
* channel to surface progress via its own streaming/edit UX.
|
|
*/
|
|
suppressDefaultToolProgressMessages?: boolean;
|
|
/** Allow channel-owned tool lifecycle feedback while text progress remains hidden. */
|
|
allowToolLifecycleWhenProgressHidden?: boolean;
|
|
/**
|
|
* Called before dispatch with a live getter for whether verbose standalone
|
|
* progress messages are active for this run. Channels that render tool or
|
|
* commentary progress inside an ephemeral streaming draft should yield those
|
|
* draft lines while the getter returns true, so progress is not rendered in
|
|
* both lanes at once.
|
|
*/
|
|
onVerboseProgressVisibility?: (isActive: () => boolean) => void;
|
|
onPartialReply?: (payload: PartialReplyPayload) => Promise<void> | void;
|
|
onReasoningStream?: (payload: ReasoningStreamPayload) => Promise<void> | void;
|
|
onReasoningProgress?: (payload: ReasoningProgressPayload) => Promise<void> | void;
|
|
streamReasoningInNonStreamModes?: boolean;
|
|
/** Called when a thinking/reasoning block ends. */
|
|
onReasoningEnd?: () => Promise<void> | void;
|
|
/** Called when a new assistant message starts (e.g., after tool call or thinking block). */
|
|
onAssistantMessageStart?: () => Promise<void> | 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> | void;
|
|
onBlockReply?: (payload: ReplyPayload, context?: BlockReplyContext) => Promise<void> | void;
|
|
onToolResult?: (payload: ReplyPayload) => Promise<void> | void;
|
|
/** Called when a tool phase starts/updates, before summary payloads are emitted. */
|
|
onToolStart?: (payload: {
|
|
itemId?: string;
|
|
toolCallId?: string;
|
|
name?: string;
|
|
phase?: string;
|
|
args?: Record<string, unknown>;
|
|
detailMode?: "explain" | "raw";
|
|
}) => Promise<void> | void;
|
|
/** Called when a concrete work item starts, updates, or completes. */
|
|
onItemEvent?: (payload: {
|
|
itemId?: string;
|
|
toolCallId?: string;
|
|
kind?: string;
|
|
title?: string;
|
|
name?: string;
|
|
phase?: string;
|
|
status?: string;
|
|
summary?: string;
|
|
progressText?: string;
|
|
meta?: string;
|
|
approvalId?: string;
|
|
approvalSlug?: string;
|
|
}) => Promise<void> | void;
|
|
/** In progress mode, classify Claude pre-tool text; true also renders it as commentary. */
|
|
commentaryProgressEnabled?: boolean;
|
|
/** Deliver durable reasoning payloads to channels that own a separate reasoning lane. */
|
|
reasoningPayloadsEnabled?: boolean;
|
|
/** Deliver durable commentary (💬) payloads to channels that own a separate commentary lane. */
|
|
commentaryPayloadsEnabled?: boolean;
|
|
/** Called when the agent emits a structured plan update. */
|
|
onPlanUpdate?: (payload: {
|
|
phase?: string;
|
|
title?: string;
|
|
explanation?: string;
|
|
steps?: string[];
|
|
source?: string;
|
|
}) => Promise<void> | 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;
|
|
scope?: "turn" | "session";
|
|
message?: string;
|
|
}) => Promise<void> | 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> | 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> | void;
|
|
/** Called when context auto-compaction starts (allows UX feedback during the pause). */
|
|
onCompactionStart?: () => Promise<void> | void;
|
|
/** Called when context auto-compaction completes. */
|
|
onCompactionEnd?: () => Promise<void> | 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;
|
|
/**
|
|
* Controls whether normal assistant replies are automatically delivered to
|
|
* the source conversation. `message_tool_only` prefers message-tool visible
|
|
* delivery and keeps normal final text, block output, and preview output
|
|
* private unless dispatch explicitly marks a source reply as deliverable.
|
|
*/
|
|
sourceReplyDeliveryMode?: SourceReplyDeliveryMode;
|
|
/** Starts delivery tracking when this turn later drains as a queued followup. */
|
|
queuedDeliveryCorrelations?: QueuedReplyDeliveryCorrelation[];
|
|
/** Tracks ownership transfer when this turn later drains as a queued followup. */
|
|
queuedFollowupLifecycle?: QueuedReplyLifecycle;
|
|
/** Allow channel-owned progress UI while final/source reply delivery remains message-tool-only. */
|
|
allowProgressCallbacksWhenSourceDeliverySuppressed?: boolean;
|
|
/** Called when a suppressed source reply mode observes visible delivery through another path. */
|
|
onObservedReplyDelivery?: () => Promise<void> | void;
|
|
/** Emit tool result summaries for channel-owned progress UI even when verbose is off. */
|
|
forceToolResultProgress?: boolean;
|
|
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;
|
|
};
|