mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-14 18:51:04 +00:00
Plugin SDK: split approval adapter seams
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-runtime";
|
||||
import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
||||
import { resolveApprovalRequestSessionConversation } from "openclaw/plugin-sdk/approval-native-runtime";
|
||||
import type { DiscordExecApprovalConfig, OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import type { ExecApprovalRequest, PluginApprovalRequest } from "openclaw/plugin-sdk/infra-runtime";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Button, type ButtonInteraction, type ComponentData } from "@buape/carbon";
|
||||
import { ButtonStyle } from "discord-api-types/v10";
|
||||
import { resolveApprovalOverGateway } from "openclaw/plugin-sdk/approval-handler-runtime";
|
||||
import { resolveApprovalOverGateway } from "openclaw/plugin-sdk/approval-gateway-runtime";
|
||||
import type { DiscordExecApprovalConfig, OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import type {
|
||||
ExecApprovalDecision,
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
} from "@buape/carbon";
|
||||
import { GatewayCloseCodes, type GatewayPlugin } from "@buape/carbon/gateway";
|
||||
import { Routes } from "discord-api-types/v10";
|
||||
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-runtime";
|
||||
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
||||
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
||||
import {
|
||||
listNativeCommandSpecsForConfig,
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
createApproverRestrictedNativeApprovalCapability,
|
||||
splitChannelApprovalCapability,
|
||||
} from "openclaw/plugin-sdk/approval-delivery-runtime";
|
||||
import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-runtime";
|
||||
import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
||||
import {
|
||||
createChannelNativeOriginTargetResolver,
|
||||
resolveApprovalRequestSessionConversation,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { resolveApprovalOverGateway } from "openclaw/plugin-sdk/approval-handler-runtime";
|
||||
import { resolveApprovalOverGateway } from "openclaw/plugin-sdk/approval-gateway-runtime";
|
||||
import type { ExecApprovalReplyDecision } from "openclaw/plugin-sdk/approval-runtime";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { isApprovalNotFoundError } from "openclaw/plugin-sdk/error-runtime";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { format } from "node:util";
|
||||
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-runtime";
|
||||
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
||||
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
||||
import {
|
||||
GROUP_POLICY_BLOCKED_LABEL,
|
||||
|
||||
@@ -2,7 +2,7 @@ import {
|
||||
createApproverRestrictedNativeApprovalCapability,
|
||||
splitChannelApprovalCapability,
|
||||
} from "openclaw/plugin-sdk/approval-delivery-runtime";
|
||||
import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-runtime";
|
||||
import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
||||
import {
|
||||
createChannelApproverDmTargetResolver,
|
||||
createChannelNativeOriginTargetResolver,
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
patchAllowlistUsersInConfigEntries,
|
||||
summarizeMapping,
|
||||
} from "openclaw/plugin-sdk/allow-from";
|
||||
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-runtime";
|
||||
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
||||
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
||||
import type { SessionScope } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { createConnectedChannelStatusPatch } from "openclaw/plugin-sdk/gateway-runtime";
|
||||
|
||||
@@ -2,7 +2,7 @@ import {
|
||||
createApproverRestrictedNativeApprovalCapability,
|
||||
splitChannelApprovalCapability,
|
||||
} from "openclaw/plugin-sdk/approval-delivery-runtime";
|
||||
import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-runtime";
|
||||
import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
||||
import {
|
||||
createChannelApproverDmTargetResolver,
|
||||
createChannelNativeOriginTargetResolver,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { resolveApprovalOverGateway } from "openclaw/plugin-sdk/approval-handler-runtime";
|
||||
import { resolveApprovalOverGateway } from "openclaw/plugin-sdk/approval-gateway-runtime";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import type { ExecApprovalReplyDecision } from "openclaw/plugin-sdk/infra-runtime";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { RunOptions } from "@grammyjs/runner";
|
||||
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-runtime";
|
||||
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
||||
import type { PluginRuntime } from "openclaw/plugin-sdk/channel-core";
|
||||
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
||||
import { resolveAgentMaxConcurrent } from "openclaw/plugin-sdk/config-runtime";
|
||||
|
||||
@@ -116,6 +116,14 @@
|
||||
"types": "./dist/plugin-sdk/approval-delivery-runtime.d.ts",
|
||||
"default": "./dist/plugin-sdk/approval-delivery-runtime.js"
|
||||
},
|
||||
"./plugin-sdk/approval-gateway-runtime": {
|
||||
"types": "./dist/plugin-sdk/approval-gateway-runtime.d.ts",
|
||||
"default": "./dist/plugin-sdk/approval-gateway-runtime.js"
|
||||
},
|
||||
"./plugin-sdk/approval-handler-adapter-runtime": {
|
||||
"types": "./dist/plugin-sdk/approval-handler-adapter-runtime.d.ts",
|
||||
"default": "./dist/plugin-sdk/approval-handler-adapter-runtime.js"
|
||||
},
|
||||
"./plugin-sdk/approval-handler-runtime": {
|
||||
"types": "./dist/plugin-sdk/approval-handler-runtime.d.ts",
|
||||
"default": "./dist/plugin-sdk/approval-handler-runtime.js"
|
||||
|
||||
85
src/infra/approval-handler-adapter-runtime.ts
Normal file
85
src/infra/approval-handler-adapter-runtime.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { createLazyRuntimeModule } from "../shared/lazy-runtime.js";
|
||||
import type {
|
||||
ChannelApprovalNativeAvailabilityAdapter,
|
||||
ChannelApprovalNativeRuntimeAdapter,
|
||||
} from "./approval-handler-runtime.js";
|
||||
import type { ExecApprovalChannelRuntimeEventKind } from "./exec-approval-channel-runtime.js";
|
||||
|
||||
export const CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY = "approval.native";
|
||||
|
||||
type LazyChannelApprovalNativeRuntimeParams = {
|
||||
load: () => Promise<ChannelApprovalNativeRuntimeAdapter>;
|
||||
isConfigured: ChannelApprovalNativeAvailabilityAdapter["isConfigured"];
|
||||
shouldHandle: ChannelApprovalNativeAvailabilityAdapter["shouldHandle"];
|
||||
eventKinds?: readonly ExecApprovalChannelRuntimeEventKind[];
|
||||
resolveApprovalKind?: ChannelApprovalNativeRuntimeAdapter["resolveApprovalKind"];
|
||||
};
|
||||
|
||||
export function createLazyChannelApprovalNativeRuntimeAdapter(
|
||||
params: LazyChannelApprovalNativeRuntimeParams,
|
||||
): ChannelApprovalNativeRuntimeAdapter {
|
||||
const loadRuntime = createLazyRuntimeModule(params.load);
|
||||
let loadedRuntime: ChannelApprovalNativeRuntimeAdapter | null = null;
|
||||
const loadResolvedRuntime = async (): Promise<ChannelApprovalNativeRuntimeAdapter> => {
|
||||
const runtime = await loadRuntime();
|
||||
loadedRuntime = runtime;
|
||||
return runtime;
|
||||
};
|
||||
const loadRequired = async <TResult>(
|
||||
select: (runtime: ChannelApprovalNativeRuntimeAdapter) => TResult,
|
||||
): Promise<TResult> => select(await loadResolvedRuntime());
|
||||
const loadOptional = async <TResult>(
|
||||
select: (runtime: ChannelApprovalNativeRuntimeAdapter) => TResult | undefined,
|
||||
): Promise<TResult | undefined> => select(await loadResolvedRuntime());
|
||||
|
||||
return {
|
||||
...(params.eventKinds ? { eventKinds: params.eventKinds } : {}),
|
||||
...(params.resolveApprovalKind ? { resolveApprovalKind: params.resolveApprovalKind } : {}),
|
||||
availability: {
|
||||
isConfigured: params.isConfigured,
|
||||
shouldHandle: params.shouldHandle,
|
||||
},
|
||||
presentation: {
|
||||
buildPendingPayload: async (runtimeParams) =>
|
||||
(await loadRequired((runtime) => runtime.presentation.buildPendingPayload))(runtimeParams),
|
||||
buildResolvedResult: async (runtimeParams) =>
|
||||
(await loadRequired((runtime) => runtime.presentation.buildResolvedResult))(runtimeParams),
|
||||
buildExpiredResult: async (runtimeParams) =>
|
||||
(await loadRequired((runtime) => runtime.presentation.buildExpiredResult))(runtimeParams),
|
||||
},
|
||||
transport: {
|
||||
prepareTarget: async (runtimeParams) =>
|
||||
(await loadRequired((runtime) => runtime.transport.prepareTarget))(runtimeParams),
|
||||
deliverPending: async (runtimeParams) =>
|
||||
(await loadRequired((runtime) => runtime.transport.deliverPending))(runtimeParams),
|
||||
updateEntry: async (runtimeParams) =>
|
||||
await (
|
||||
await loadOptional((runtime) => runtime.transport.updateEntry)
|
||||
)?.(runtimeParams),
|
||||
deleteEntry: async (runtimeParams) =>
|
||||
await (
|
||||
await loadOptional((runtime) => runtime.transport.deleteEntry)
|
||||
)?.(runtimeParams),
|
||||
},
|
||||
interactions: {
|
||||
bindPending: async (runtimeParams) =>
|
||||
(await loadOptional((runtime) => runtime.interactions?.bindPending))?.(runtimeParams),
|
||||
unbindPending: async (runtimeParams) =>
|
||||
await (
|
||||
await loadOptional((runtime) => runtime.interactions?.unbindPending)
|
||||
)?.(runtimeParams),
|
||||
clearPendingActions: async (runtimeParams) =>
|
||||
await (
|
||||
await loadOptional((runtime) => runtime.interactions?.clearPendingActions)
|
||||
)?.(runtimeParams),
|
||||
},
|
||||
observe: {
|
||||
// Observe hooks are fire-and-forget at call sites. Reuse the already
|
||||
// loaded runtime instead of introducing unawaited lazy-load promises.
|
||||
onDeliveryError: (runtimeParams) => loadedRuntime?.observe?.onDeliveryError?.(runtimeParams),
|
||||
onDuplicateSkipped: (runtimeParams) =>
|
||||
loadedRuntime?.observe?.onDuplicateSkipped?.(runtimeParams),
|
||||
onDelivered: (runtimeParams) => loadedRuntime?.observe?.onDelivered?.(runtimeParams),
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -5,8 +5,11 @@ import type {
|
||||
} from "../channels/plugins/types.adapters.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
import { createLazyRuntimeModule } from "../shared/lazy-runtime.js";
|
||||
import { resolveApprovalOverGateway } from "./approval-gateway-resolver.js";
|
||||
import {
|
||||
CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY,
|
||||
createLazyChannelApprovalNativeRuntimeAdapter,
|
||||
} from "./approval-handler-adapter-runtime.js";
|
||||
import type { ChannelApprovalNativePlannedTarget } from "./approval-native-delivery.js";
|
||||
import {
|
||||
createChannelNativeApprovalRuntime,
|
||||
@@ -46,10 +49,13 @@ export type {
|
||||
ResolvedApprovalView,
|
||||
} from "./approval-view-model.js";
|
||||
export { resolveApprovalOverGateway };
|
||||
export {
|
||||
CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY,
|
||||
createLazyChannelApprovalNativeRuntimeAdapter,
|
||||
};
|
||||
|
||||
type ApprovalRequest = ExecApprovalRequest | PluginApprovalRequest;
|
||||
type ApprovalResolved = ExecApprovalResolved | PluginApprovalResolved;
|
||||
export const CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY = "approval.native";
|
||||
|
||||
export type ChannelApprovalHandler<
|
||||
TRequest extends ApprovalRequest = ApprovalRequest,
|
||||
@@ -584,83 +590,6 @@ export function createChannelApprovalNativeRuntimeAdapter<
|
||||
};
|
||||
}
|
||||
|
||||
type LazyChannelApprovalNativeRuntimeParams = {
|
||||
load: () => Promise<ChannelApprovalNativeRuntimeAdapter>;
|
||||
isConfigured: ChannelApprovalNativeAvailabilityAdapter["isConfigured"];
|
||||
shouldHandle: ChannelApprovalNativeAvailabilityAdapter["shouldHandle"];
|
||||
eventKinds?: readonly ExecApprovalChannelRuntimeEventKind[];
|
||||
resolveApprovalKind?: ChannelApprovalNativeRuntimeAdapter["resolveApprovalKind"];
|
||||
};
|
||||
|
||||
export function createLazyChannelApprovalNativeRuntimeAdapter(
|
||||
params: LazyChannelApprovalNativeRuntimeParams,
|
||||
): ChannelApprovalNativeRuntimeAdapter {
|
||||
const loadRuntime = createLazyRuntimeModule(params.load);
|
||||
let loadedRuntime: ChannelApprovalNativeRuntimeAdapter | null = null;
|
||||
const loadResolvedRuntime = async (): Promise<ChannelApprovalNativeRuntimeAdapter> => {
|
||||
const runtime = await loadRuntime();
|
||||
loadedRuntime = runtime;
|
||||
return runtime;
|
||||
};
|
||||
const loadRequired = async <TResult>(
|
||||
select: (runtime: ChannelApprovalNativeRuntimeAdapter) => TResult,
|
||||
): Promise<TResult> => select(await loadResolvedRuntime());
|
||||
const loadOptional = async <TResult>(
|
||||
select: (runtime: ChannelApprovalNativeRuntimeAdapter) => TResult | undefined,
|
||||
): Promise<TResult | undefined> => select(await loadResolvedRuntime());
|
||||
|
||||
return {
|
||||
...(params.eventKinds ? { eventKinds: params.eventKinds } : {}),
|
||||
...(params.resolveApprovalKind ? { resolveApprovalKind: params.resolveApprovalKind } : {}),
|
||||
availability: {
|
||||
isConfigured: params.isConfigured,
|
||||
shouldHandle: params.shouldHandle,
|
||||
},
|
||||
presentation: {
|
||||
buildPendingPayload: async (runtimeParams) =>
|
||||
(await loadRequired((runtime) => runtime.presentation.buildPendingPayload))(runtimeParams),
|
||||
buildResolvedResult: async (runtimeParams) =>
|
||||
(await loadRequired((runtime) => runtime.presentation.buildResolvedResult))(runtimeParams),
|
||||
buildExpiredResult: async (runtimeParams) =>
|
||||
(await loadRequired((runtime) => runtime.presentation.buildExpiredResult))(runtimeParams),
|
||||
},
|
||||
transport: {
|
||||
prepareTarget: async (runtimeParams) =>
|
||||
(await loadRequired((runtime) => runtime.transport.prepareTarget))(runtimeParams),
|
||||
deliverPending: async (runtimeParams) =>
|
||||
(await loadRequired((runtime) => runtime.transport.deliverPending))(runtimeParams),
|
||||
updateEntry: async (runtimeParams) =>
|
||||
await (
|
||||
await loadOptional((runtime) => runtime.transport.updateEntry)
|
||||
)?.(runtimeParams),
|
||||
deleteEntry: async (runtimeParams) =>
|
||||
await (
|
||||
await loadOptional((runtime) => runtime.transport.deleteEntry)
|
||||
)?.(runtimeParams),
|
||||
},
|
||||
interactions: {
|
||||
bindPending: async (runtimeParams) =>
|
||||
(await loadOptional((runtime) => runtime.interactions?.bindPending))?.(runtimeParams),
|
||||
unbindPending: async (runtimeParams) =>
|
||||
await (
|
||||
await loadOptional((runtime) => runtime.interactions?.unbindPending)
|
||||
)?.(runtimeParams),
|
||||
clearPendingActions: async (runtimeParams) =>
|
||||
await (
|
||||
await loadOptional((runtime) => runtime.interactions?.clearPendingActions)
|
||||
)?.(runtimeParams),
|
||||
},
|
||||
observe: {
|
||||
// Observe hooks are fire-and-forget at call sites. Reuse the already
|
||||
// loaded runtime instead of introducing unawaited lazy-load promises.
|
||||
onDeliveryError: (runtimeParams) => loadedRuntime?.observe?.onDeliveryError?.(runtimeParams),
|
||||
onDuplicateSkipped: (runtimeParams) =>
|
||||
loadedRuntime?.observe?.onDuplicateSkipped?.(runtimeParams),
|
||||
onDelivered: (runtimeParams) => loadedRuntime?.observe?.onDelivered?.(runtimeParams),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export type ChannelApprovalHandlerRuntimeSpec<TRequest extends ApprovalRequest> = {
|
||||
label: string;
|
||||
clientDisplayName: string;
|
||||
|
||||
1
src/plugin-sdk/approval-gateway-runtime.ts
Normal file
1
src/plugin-sdk/approval-gateway-runtime.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { resolveApprovalOverGateway } from "../infra/approval-gateway-resolver.js";
|
||||
4
src/plugin-sdk/approval-handler-adapter-runtime.ts
Normal file
4
src/plugin-sdk/approval-handler-adapter-runtime.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export {
|
||||
CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY,
|
||||
createLazyChannelApprovalNativeRuntimeAdapter,
|
||||
} from "../infra/approval-handler-adapter-runtime.js";
|
||||
@@ -3,7 +3,6 @@ export {
|
||||
createChannelApprovalNativeRuntimeAdapter,
|
||||
createChannelApprovalHandlerFromCapability,
|
||||
createLazyChannelApprovalNativeRuntimeAdapter,
|
||||
resolveApprovalOverGateway,
|
||||
CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY,
|
||||
type ApprovalActionView,
|
||||
type ApprovalMetadataView,
|
||||
@@ -29,3 +28,4 @@ export {
|
||||
type PluginApprovalResolvedView,
|
||||
type ResolvedApprovalView,
|
||||
} from "../infra/approval-handler-runtime.js";
|
||||
export { resolveApprovalOverGateway } from "./approval-gateway-runtime.js";
|
||||
|
||||
Reference in New Issue
Block a user