mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-17 04:01:05 +00:00
fix(cycles): narrow channel runtime surface
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
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-adapter-runtime";
|
||||
import type { ChannelRuntimeSurface } from "openclaw/plugin-sdk/channel-contract";
|
||||
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
||||
import {
|
||||
listNativeCommandSpecsForConfig,
|
||||
@@ -95,7 +96,7 @@ export type MonitorDiscordOpts = {
|
||||
accountId?: string;
|
||||
config?: OpenClawConfig;
|
||||
runtime?: RuntimeEnv;
|
||||
channelRuntime?: import("openclaw/plugin-sdk/channel-core").PluginRuntime["channel"];
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
abortSignal?: AbortSignal;
|
||||
mediaMaxMb?: number;
|
||||
historyLimit?: number;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { format } from "node:util";
|
||||
import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
|
||||
import type { ChannelRuntimeSurface } from "openclaw/plugin-sdk/channel-contract";
|
||||
import { waitUntilAbort } from "openclaw/plugin-sdk/channel-lifecycle";
|
||||
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
||||
import {
|
||||
@@ -45,7 +46,7 @@ import { createMatrixMonitorTaskRunner } from "./task-runner.js";
|
||||
|
||||
export type MonitorMatrixOpts = {
|
||||
runtime?: RuntimeEnv;
|
||||
channelRuntime?: import("openclaw/plugin-sdk/channel-core").PluginRuntime["channel"];
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
abortSignal?: AbortSignal;
|
||||
mediaMaxMb?: number;
|
||||
initialSyncLimit?: number;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { PluginRuntime } from "openclaw/plugin-sdk/channel-core";
|
||||
import type { ChannelRuntimeSurface } from "openclaw/plugin-sdk/channel-contract";
|
||||
import type { OpenClawConfig, SlackSlashCommandConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
import type { SlackFile, SlackMessageEvent } from "../types.js";
|
||||
@@ -10,7 +10,7 @@ export type MonitorSlackOpts = {
|
||||
mode?: "socket" | "http";
|
||||
config?: OpenClawConfig;
|
||||
runtime?: RuntimeEnv;
|
||||
channelRuntime?: PluginRuntime["channel"];
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
abortSignal?: AbortSignal;
|
||||
mediaMaxMb?: number;
|
||||
slashCommand?: SlackSlashCommandConfig;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { PluginRuntime } from "openclaw/plugin-sdk/channel-core";
|
||||
import type { ChannelRuntimeSurface } from "openclaw/plugin-sdk/channel-contract";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
|
||||
@@ -7,7 +7,7 @@ export type MonitorTelegramOpts = {
|
||||
accountId?: string;
|
||||
config?: OpenClawConfig;
|
||||
runtime?: RuntimeEnv;
|
||||
channelRuntime?: PluginRuntime["channel"];
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
abortSignal?: AbortSignal;
|
||||
useWebhook?: boolean;
|
||||
webhookPath?: string;
|
||||
|
||||
43
src/channels/plugins/channel-runtime-surface.types.ts
Normal file
43
src/channels/plugins/channel-runtime-surface.types.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
export type ChannelRuntimeContextKey = {
|
||||
channelId: string;
|
||||
accountId?: string | null;
|
||||
capability: string;
|
||||
};
|
||||
|
||||
export type ChannelRuntimeContextEvent = {
|
||||
type: "registered" | "unregistered";
|
||||
key: {
|
||||
channelId: string;
|
||||
accountId?: string;
|
||||
capability: string;
|
||||
};
|
||||
context?: unknown;
|
||||
};
|
||||
|
||||
export type ChannelRuntimeContextRegistry = {
|
||||
register: (
|
||||
params: ChannelRuntimeContextKey & {
|
||||
context: unknown;
|
||||
abortSignal?: AbortSignal;
|
||||
},
|
||||
) => { dispose: () => void };
|
||||
get: <T = unknown>(params: ChannelRuntimeContextKey) => T | undefined;
|
||||
watch: (params: {
|
||||
channelId?: string;
|
||||
accountId?: string | null;
|
||||
capability?: string;
|
||||
onEvent: (event: ChannelRuntimeContextEvent) => void;
|
||||
}) => () => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* Minimal channel-runtime surface threaded through gateway/setup flows.
|
||||
*
|
||||
* Most callers only pass this object through or use `runtimeContexts`.
|
||||
* Keeping this leaf contract small avoids dragging the full plugin runtime
|
||||
* graph into generic channel adapter types.
|
||||
*/
|
||||
export type ChannelRuntimeSurface = {
|
||||
runtimeContexts: ChannelRuntimeContextRegistry;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
@@ -10,11 +10,11 @@ import type {
|
||||
PluginApprovalRequest,
|
||||
PluginApprovalResolved,
|
||||
} from "../../infra/plugin-approvals.js";
|
||||
import type { PluginRuntime } from "../../plugins/runtime/types.js";
|
||||
import type { RuntimeEnv } from "../../runtime.js";
|
||||
import type { ResolverContext, SecretDefaults } from "../../secrets/runtime-shared.js";
|
||||
import type { SecretTargetRegistryEntry } from "../../secrets/target-registry-types.js";
|
||||
import type { ChannelApprovalNativeAdapter } from "./approval-native.types.js";
|
||||
import type { ChannelRuntimeSurface } from "./channel-runtime-surface.types.js";
|
||||
import type { ConfigWriteTarget } from "./config-writes.js";
|
||||
export type {
|
||||
ChannelOutboundAdapter,
|
||||
@@ -305,7 +305,7 @@ export type ChannelGatewayContext<ResolvedAccount = unknown> = {
|
||||
* @since Plugin SDK 2026.2.19
|
||||
* @see {@link https://docs.openclaw.ai/plugins/developing-plugins | Plugin SDK documentation}
|
||||
*/
|
||||
channelRuntime?: PluginRuntime["channel"];
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
};
|
||||
|
||||
export type ChannelLogoutResult = {
|
||||
|
||||
@@ -48,6 +48,7 @@ export type {
|
||||
ChannelSetupAdapter,
|
||||
ChannelStatusAdapter,
|
||||
} from "./types.adapters.js";
|
||||
export type { ChannelRuntimeSurface } from "./channel-runtime-surface.types.js";
|
||||
export type {
|
||||
ChannelAccountSnapshot,
|
||||
ChannelAccountState,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { ChannelRuntimeSurface } from "../channels/plugins/channel-runtime-surface.types.js";
|
||||
import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js";
|
||||
import { type ChannelId, getChannelPlugin, listChannelPlugins } from "../channels/plugins/index.js";
|
||||
import type { ChannelAccountSnapshot } from "../channels/plugins/types.public.js";
|
||||
@@ -8,7 +9,6 @@ import { createTaskScopedChannelRuntime } from "../infra/channel-runtime-context
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import { resetDirectoryCache } from "../infra/outbound/target-resolver.js";
|
||||
import type { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
import type { PluginRuntime } from "../plugins/runtime/types.js";
|
||||
import { resolveAccountEntry, resolveNormalizedAccountEntry } from "../routing/account-lookup.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
@@ -125,7 +125,7 @@ type ChannelManagerOptions = {
|
||||
* @since Plugin SDK 2026.2.19
|
||||
* @see {@link ChannelGatewayContext.channelRuntime}
|
||||
*/
|
||||
channelRuntime?: PluginRuntime["channel"];
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
/**
|
||||
* Lazily resolves optional channel runtime helpers for external channel plugins.
|
||||
*
|
||||
@@ -134,7 +134,7 @@ type ChannelManagerOptions = {
|
||||
* a channel account actually starts. The resolved value must be a real
|
||||
* `createPluginRuntime().channel` surface.
|
||||
*/
|
||||
resolveChannelRuntime?: () => PluginRuntime["channel"];
|
||||
resolveChannelRuntime?: () => ChannelRuntimeSurface;
|
||||
};
|
||||
|
||||
type StartChannelOptions = {
|
||||
@@ -252,7 +252,7 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage
|
||||
return next;
|
||||
};
|
||||
|
||||
const getChannelRuntime = (): PluginRuntime["channel"] | undefined => {
|
||||
const getChannelRuntime = (): ChannelRuntimeSurface | undefined => {
|
||||
return channelRuntime ?? resolveChannelRuntime?.();
|
||||
};
|
||||
|
||||
@@ -299,7 +299,7 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage
|
||||
let handedOffTask = false;
|
||||
const log = channelLogs[channelId];
|
||||
let scopedChannelRuntime: ReturnType<typeof createTaskScopedChannelRuntime> | null = null;
|
||||
let channelRuntimeForTask: PluginRuntime["channel"] | undefined;
|
||||
let channelRuntimeForTask: ChannelRuntimeSurface | undefined;
|
||||
let stopApprovalBootstrap: () => Promise<void> = async () => {};
|
||||
const stopTaskScopedApprovalRuntime = async () => {
|
||||
const scopedRuntime = scopedChannelRuntime;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { resolveChannelApprovalCapability } from "../channels/plugins/approvals.js";
|
||||
import type { ChannelRuntimeSurface } from "../channels/plugins/channel-runtime-surface.types.js";
|
||||
import type { ChannelPlugin } from "../channels/plugins/types.plugin.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
import type { PluginRuntime } from "../plugins/runtime/types.js";
|
||||
import {
|
||||
CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY,
|
||||
createChannelApprovalHandlerFromCapability,
|
||||
@@ -20,7 +20,7 @@ export async function startChannelApprovalHandlerBootstrap(params: {
|
||||
plugin: Pick<ChannelPlugin, "id" | "meta" | "approvalCapability">;
|
||||
cfg: OpenClawConfig;
|
||||
accountId: string;
|
||||
channelRuntime?: PluginRuntime["channel"];
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
logger?: ReturnType<typeof createSubsystemLogger>;
|
||||
}): Promise<() => Promise<void>> {
|
||||
const capability = resolveChannelApprovalCapability(params.plugin);
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import type { PluginRuntime } from "../plugins/runtime/types.js";
|
||||
|
||||
export type ChannelRuntimeContextKey = {
|
||||
channelId: string;
|
||||
accountId?: string | null;
|
||||
capability: string;
|
||||
};
|
||||
import type {
|
||||
ChannelRuntimeContextKey,
|
||||
ChannelRuntimeSurface,
|
||||
} from "../channels/plugins/channel-runtime-surface.types.js";
|
||||
|
||||
const NOOP_DISPOSE = () => {};
|
||||
|
||||
function resolveScopedRuntimeContextRegistry(params: {
|
||||
channelRuntime: PluginRuntime["channel"];
|
||||
}): PluginRuntime["channel"]["runtimeContexts"] {
|
||||
channelRuntime: ChannelRuntimeSurface;
|
||||
}): ChannelRuntimeSurface["runtimeContexts"] {
|
||||
const runtimeContexts = resolveRuntimeContextRegistry(params);
|
||||
if (
|
||||
runtimeContexts &&
|
||||
@@ -26,14 +23,14 @@ function resolveScopedRuntimeContextRegistry(params: {
|
||||
}
|
||||
|
||||
function resolveRuntimeContextRegistry(params: {
|
||||
channelRuntime?: PluginRuntime["channel"];
|
||||
}): PluginRuntime["channel"]["runtimeContexts"] | null {
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
}): ChannelRuntimeSurface["runtimeContexts"] | null {
|
||||
return params.channelRuntime?.runtimeContexts ?? null;
|
||||
}
|
||||
|
||||
export function registerChannelRuntimeContext(
|
||||
params: ChannelRuntimeContextKey & {
|
||||
channelRuntime?: PluginRuntime["channel"];
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
context: unknown;
|
||||
abortSignal?: AbortSignal;
|
||||
},
|
||||
@@ -53,7 +50,7 @@ export function registerChannelRuntimeContext(
|
||||
|
||||
export function getChannelRuntimeContext<T = unknown>(
|
||||
params: ChannelRuntimeContextKey & {
|
||||
channelRuntime?: PluginRuntime["channel"];
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
},
|
||||
): T | undefined {
|
||||
const runtimeContexts = resolveRuntimeContextRegistry(params);
|
||||
@@ -69,8 +66,8 @@ export function getChannelRuntimeContext<T = unknown>(
|
||||
|
||||
export function watchChannelRuntimeContexts(
|
||||
params: ChannelRuntimeContextKey & {
|
||||
channelRuntime?: PluginRuntime["channel"];
|
||||
onEvent: Parameters<PluginRuntime["channel"]["runtimeContexts"]["watch"]>[0]["onEvent"];
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
onEvent: Parameters<ChannelRuntimeSurface["runtimeContexts"]["watch"]>[0]["onEvent"];
|
||||
},
|
||||
): (() => void) | null {
|
||||
const runtimeContexts = resolveRuntimeContextRegistry(params);
|
||||
@@ -86,9 +83,9 @@ export function watchChannelRuntimeContexts(
|
||||
}
|
||||
|
||||
export function createTaskScopedChannelRuntime(params: {
|
||||
channelRuntime?: PluginRuntime["channel"];
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
}): {
|
||||
channelRuntime?: PluginRuntime["channel"];
|
||||
channelRuntime?: ChannelRuntimeSurface;
|
||||
dispose: () => void;
|
||||
} {
|
||||
const baseRuntime = params.channelRuntime;
|
||||
@@ -116,7 +113,7 @@ export function createTaskScopedChannelRuntime(params: {
|
||||
};
|
||||
};
|
||||
|
||||
const scopedRuntime: PluginRuntime["channel"] = {
|
||||
const scopedRuntime: ChannelRuntimeSurface = {
|
||||
...baseRuntime,
|
||||
runtimeContexts: {
|
||||
...runtimeContexts,
|
||||
|
||||
@@ -35,3 +35,4 @@ export type {
|
||||
ChannelGatewayContext,
|
||||
ChannelOutboundAdapter,
|
||||
} from "../channels/plugins/types.adapters.js";
|
||||
export type { ChannelRuntimeSurface } from "../channels/plugins/channel-runtime-surface.types.js";
|
||||
|
||||
Reference in New Issue
Block a user