import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { ChannelApprovalNativePlannedTarget } from "./approval-native-delivery.js"; import type { PreparedChannelNativeApprovalTarget } from "./approval-native-runtime.js"; import type { ExpiredApprovalView, PendingApprovalView, ResolvedApprovalView, } from "./approval-view-model.js"; import type { ExecApprovalChannelRuntimeEventKind } from "./exec-approval-channel-runtime.js"; import type { ExecApprovalRequest, ExecApprovalResolved } from "./exec-approvals.js"; import type { PluginApprovalRequest, PluginApprovalResolved } from "./plugin-approvals.js"; export type ApprovalRequest = ExecApprovalRequest | PluginApprovalRequest; export type ApprovalResolved = ExecApprovalResolved | PluginApprovalResolved; export type ChannelApprovalKind = "exec" | "plugin"; export type ChannelApprovalCapabilityHandlerContext = { cfg: OpenClawConfig; accountId?: string | null; gatewayUrl?: string; context?: unknown; }; export type ChannelApprovalNativeFinalAction = | { kind: "update"; payload: TPayload } | { kind: "delete" } | { kind: "clear-actions" } | { kind: "leave" }; export type ChannelApprovalNativeAvailabilityAdapter = { isConfigured: (params: ChannelApprovalCapabilityHandlerContext) => boolean; shouldHandle: ( params: ChannelApprovalCapabilityHandlerContext & { request: ApprovalRequest }, ) => boolean; }; export type ChannelApprovalNativePresentationAdapter< TPendingPayload = unknown, TFinalPayload = unknown, > = { buildPendingPayload: ( params: ChannelApprovalCapabilityHandlerContext & { request: ApprovalRequest; approvalKind: ChannelApprovalKind; nowMs: number; view: PendingApprovalView; }, ) => TPendingPayload | Promise; buildResolvedResult: ( params: ChannelApprovalCapabilityHandlerContext & { request: ApprovalRequest; resolved: ApprovalResolved; view: ResolvedApprovalView; entry: unknown; }, ) => | ChannelApprovalNativeFinalAction | Promise>; buildExpiredResult: ( params: ChannelApprovalCapabilityHandlerContext & { request: ApprovalRequest; view: ExpiredApprovalView; entry: unknown; }, ) => | ChannelApprovalNativeFinalAction | Promise>; }; export type ChannelApprovalNativeTransportAdapter< TPreparedTarget = unknown, TPendingEntry = unknown, TPendingPayload = unknown, TFinalPayload = unknown, > = { prepareTarget: ( params: ChannelApprovalCapabilityHandlerContext & { plannedTarget: ChannelApprovalNativePlannedTarget; request: ApprovalRequest; approvalKind: ChannelApprovalKind; view: PendingApprovalView; pendingPayload: TPendingPayload; }, ) => | PreparedChannelNativeApprovalTarget | null | Promise | null>; deliverPending: ( params: ChannelApprovalCapabilityHandlerContext & { plannedTarget: ChannelApprovalNativePlannedTarget; preparedTarget: TPreparedTarget; request: ApprovalRequest; approvalKind: ChannelApprovalKind; view: PendingApprovalView; pendingPayload: TPendingPayload; }, ) => TPendingEntry | null | Promise; updateEntry?: ( params: ChannelApprovalCapabilityHandlerContext & { entry: TPendingEntry; payload: TFinalPayload; phase: "resolved" | "expired"; }, ) => Promise; deleteEntry?: ( params: ChannelApprovalCapabilityHandlerContext & { entry: TPendingEntry; phase: "resolved" | "expired"; }, ) => Promise; }; export type ChannelApprovalNativeInteractionAdapter = { bindPending?: ( params: ChannelApprovalCapabilityHandlerContext & { entry: TPendingEntry; request: ApprovalRequest; approvalKind: ChannelApprovalKind; view: PendingApprovalView; pendingPayload: unknown; }, ) => TBinding | null | Promise; unbindPending?: ( params: ChannelApprovalCapabilityHandlerContext & { entry: TPendingEntry; binding: TBinding; request: ApprovalRequest; approvalKind: ChannelApprovalKind; }, ) => Promise | void; clearPendingActions?: ( params: ChannelApprovalCapabilityHandlerContext & { entry: TPendingEntry; phase: "resolved" | "expired"; }, ) => Promise; }; export type ChannelApprovalNativeObserveAdapter< TPreparedTarget = unknown, TPendingPayload = unknown, TPendingEntry = unknown, > = { onDeliveryError?: ( params: ChannelApprovalCapabilityHandlerContext & { error: unknown; plannedTarget: ChannelApprovalNativePlannedTarget; request: ApprovalRequest; approvalKind: ChannelApprovalKind; view: PendingApprovalView; pendingPayload: TPendingPayload; }, ) => void; onDuplicateSkipped?: ( params: ChannelApprovalCapabilityHandlerContext & { plannedTarget: ChannelApprovalNativePlannedTarget; preparedTarget: PreparedChannelNativeApprovalTarget; request: ApprovalRequest; approvalKind: ChannelApprovalKind; view: PendingApprovalView; pendingPayload: TPendingPayload; }, ) => void; onDelivered?: ( params: ChannelApprovalCapabilityHandlerContext & { plannedTarget: ChannelApprovalNativePlannedTarget; preparedTarget: PreparedChannelNativeApprovalTarget; request: ApprovalRequest; approvalKind: ChannelApprovalKind; view: PendingApprovalView; pendingPayload: TPendingPayload; entry: TPendingEntry; }, ) => void; }; export type ChannelApprovalNativeRuntimeAdapter< TPendingPayload = unknown, TPreparedTarget = unknown, TPendingEntry = unknown, TBinding = unknown, TFinalPayload = unknown, > = { eventKinds?: readonly ExecApprovalChannelRuntimeEventKind[]; resolveApprovalKind?: (request: ApprovalRequest) => ChannelApprovalKind; availability: ChannelApprovalNativeAvailabilityAdapter; presentation: ChannelApprovalNativePresentationAdapter; transport: ChannelApprovalNativeTransportAdapter< TPreparedTarget, TPendingEntry, TPendingPayload, TFinalPayload >; interactions?: ChannelApprovalNativeInteractionAdapter; observe?: ChannelApprovalNativeObserveAdapter; }; export type ChannelApprovalNativeRuntimeSpec< TPendingPayload, TPreparedTarget, TPendingEntry, TBinding = unknown, TFinalPayload = unknown, TPendingView extends PendingApprovalView = PendingApprovalView, TResolvedView extends ResolvedApprovalView = ResolvedApprovalView, TExpiredView extends ExpiredApprovalView = ExpiredApprovalView, > = { eventKinds?: readonly ExecApprovalChannelRuntimeEventKind[]; resolveApprovalKind?: (request: ApprovalRequest) => ChannelApprovalKind; availability: ChannelApprovalNativeAvailabilityAdapter; presentation: { buildPendingPayload: ( params: ChannelApprovalCapabilityHandlerContext & { request: ApprovalRequest; approvalKind: ChannelApprovalKind; nowMs: number; view: TPendingView; }, ) => TPendingPayload | Promise; buildResolvedResult: ( params: ChannelApprovalCapabilityHandlerContext & { request: ApprovalRequest; resolved: ApprovalResolved; view: TResolvedView; entry: TPendingEntry; }, ) => | ChannelApprovalNativeFinalAction | Promise>; buildExpiredResult: ( params: ChannelApprovalCapabilityHandlerContext & { request: ApprovalRequest; view: TExpiredView; entry: TPendingEntry; }, ) => | ChannelApprovalNativeFinalAction | Promise>; }; transport: { prepareTarget: ( params: ChannelApprovalCapabilityHandlerContext & { plannedTarget: ChannelApprovalNativePlannedTarget; request: ApprovalRequest; approvalKind: ChannelApprovalKind; view: TPendingView; pendingPayload: TPendingPayload; }, ) => | PreparedChannelNativeApprovalTarget | null | Promise | null>; deliverPending: ( params: ChannelApprovalCapabilityHandlerContext & { plannedTarget: ChannelApprovalNativePlannedTarget; preparedTarget: TPreparedTarget; request: ApprovalRequest; approvalKind: ChannelApprovalKind; view: TPendingView; pendingPayload: TPendingPayload; }, ) => TPendingEntry | null | Promise; updateEntry?: ( params: ChannelApprovalCapabilityHandlerContext & { entry: TPendingEntry; payload: TFinalPayload; phase: "resolved" | "expired"; }, ) => Promise; deleteEntry?: ( params: ChannelApprovalCapabilityHandlerContext & { entry: TPendingEntry; phase: "resolved" | "expired"; }, ) => Promise; }; interactions?: { bindPending?: ( params: ChannelApprovalCapabilityHandlerContext & { entry: TPendingEntry; request: ApprovalRequest; approvalKind: ChannelApprovalKind; view: TPendingView; pendingPayload: TPendingPayload; }, ) => TBinding | null | Promise; unbindPending?: ( params: ChannelApprovalCapabilityHandlerContext & { entry: TPendingEntry; binding: TBinding; request: ApprovalRequest; approvalKind: ChannelApprovalKind; }, ) => Promise | void; clearPendingActions?: ( params: ChannelApprovalCapabilityHandlerContext & { entry: TPendingEntry; phase: "resolved" | "expired"; }, ) => Promise; }; observe?: { onDeliveryError?: ( params: ChannelApprovalCapabilityHandlerContext & { error: unknown; plannedTarget: ChannelApprovalNativePlannedTarget; request: ApprovalRequest; approvalKind: ChannelApprovalKind; view: TPendingView; pendingPayload: TPendingPayload; }, ) => void; onDuplicateSkipped?: ( params: ChannelApprovalCapabilityHandlerContext & { plannedTarget: ChannelApprovalNativePlannedTarget; preparedTarget: PreparedChannelNativeApprovalTarget; request: ApprovalRequest; approvalKind: ChannelApprovalKind; view: TPendingView; pendingPayload: TPendingPayload; }, ) => void; onDelivered?: ( params: ChannelApprovalCapabilityHandlerContext & { plannedTarget: ChannelApprovalNativePlannedTarget; preparedTarget: PreparedChannelNativeApprovalTarget; request: ApprovalRequest; approvalKind: ChannelApprovalKind; view: TPendingView; pendingPayload: TPendingPayload; entry: TPendingEntry; }, ) => void; }; };