refactor(channels): centralize inbound orchestration and remove internal compat (#109716)

* refactor(channels): centralize inbound turn orchestration

* refactor(runtime): remove stale compatibility paths

* chore(guards): reject internal deprecated API use

* refactor(channels): simplify core turn planning

* chore(guards): keep deprecated checks boundary-focused

* refactor(memory): keep modern config off compat barrel

* fix(msteams): preserve feedback learning

* test(channels): align modern inbound fixtures

* refactor(channels): finish modern inbound migration

* refactor(channels): tighten core inbound kernel

* fix(channels): preserve turn assembly narrowing

* test(sdk): keep runtime mock binding immutable

* test(matrix): isolate read policy runtime

* test(msteams): mock canonical reply factory

* test(slack): mock core inbound turn dispatch

* test(telegram): inject core session recorder

* test(signal): inject core session recorder

* test(googlechat): assert canonical inbound routing

* test(synology-chat): align core turn fixture

* fix(sdk): preserve direct DM runtime compat

* refactor(channels): own inbound envelope compat in core

* refactor(channels): trim inbound dispatch seams

* refactor(channels): remove redundant async wrappers

* test(synology-chat): type canonical dispatcher mock

* refactor(channels): remove remaining dead compat seams

* chore(sdk): refresh API baseline after rebase

* fix(channels): preserve direct DM identity metadata
This commit is contained in:
Peter Steinberger
2026-07-17 00:56:46 -07:00
committed by GitHub
parent 765bb37364
commit 0e792b6de3
159 changed files with 3884 additions and 4332 deletions
@@ -1,2 +1,5 @@
/** Vitest shim re-export for media runtime compatibility in capability tests. */
export { isVoiceCompatibleAudio } from "../../media/audio.js";
export {
isVoiceMessageCompatibleAudio,
isVoiceMessageCompatibleAudio as isVoiceCompatibleAudio,
} from "../../media/audio.js";
+2 -2
View File
@@ -806,7 +806,7 @@ const PLUGIN_COMPAT_RECORDS = [
"WhatsApp monitorWebInbox onMessage callback",
"WhatsApp monitorWebChannel listenerFactory injected messages",
],
diagnostics: ["TypeScript @deprecated WebInboundMessage flat field annotations"],
diagnostics: ["TypeScript deprecated WebInboundMessage flat field annotations"],
tests: ["src/plugins/compat/registry.test.ts"],
releaseNote:
"WhatsApp WebInboundMessage flat fields remain wired as deprecated aliases while callbacks migrate to nested inbound contexts.",
@@ -827,7 +827,7 @@ const PLUGIN_COMPAT_RECORDS = [
"WhatsApp monitorWebInbox onMessage callback",
"WhatsApp monitorWebChannel listenerFactory injected messages",
],
diagnostics: ["TypeScript @deprecated WebInboundMessage admission field annotations"],
diagnostics: ["TypeScript deprecated WebInboundMessage admission field annotations"],
tests: ["src/plugins/compat/registry.test.ts"],
releaseNote:
"WhatsApp WebInboundMessage top-level admission fields remain available while callbacks migrate to the admission envelope.",
@@ -53,7 +53,7 @@ const BUNDLED_LIVE_CONFIG_HOOK_GUARDS = {
],
"extensions/memory-core/src/dreaming.ts": [
'params.reason === "runtime"',
"resolveMemoryCorePluginConfig(startupCfg)",
"resolveMemoryDreamingPluginConfig(startupCfg)",
"api.runtime.config?.current?.() ?? api.config",
],
"extensions/memory-lancedb/index.ts": ["resolveLivePluginConfigObject(", '"memory-lancedb"'],
@@ -102,7 +102,6 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
'export type { GoogleChatAccountConfig, GoogleChatConfig } from "openclaw/plugin-sdk/config-contracts";',
'export { extractToolSend } from "openclaw/plugin-sdk/tool-send";',
'export { resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-inbound";',
'export { resolveInboundRouteEnvelopeBuilderWithRuntime } from "openclaw/plugin-sdk/inbound-envelope";',
'export { resolveWebhookPath } from "openclaw/plugin-sdk/webhook-ingress";',
'export { registerWebhookTargetWithPluginRoute, resolveWebhookTargetWithAuthOrReject, withResolvedWebhookRequestPipeline } from "openclaw/plugin-sdk/webhook-targets";',
'export { createWebhookInFlightLimiter, readJsonWebhookBodyOrReject, type WebhookInFlightLimiter } from "openclaw/plugin-sdk/webhook-request-guards";',
+4 -7
View File
@@ -54,6 +54,7 @@ import {
import { loadChannelOutboundAdapter } from "../../channels/plugins/outbound/load.js";
import { recordInboundSession } from "../../channels/session.js";
import {
dispatchChannelInboundTurn,
dispatchChannelInboundReply,
runChannelInboundEvent,
runPreparedInboundReply,
@@ -71,12 +72,7 @@ import {
updateSessionLastRoute,
} from "../../config/sessions/session-accessor.js";
import { getChannelActivity, recordChannelActivity } from "../../infra/channel-activity.js";
import {
fetchRemoteMedia,
readRemoteMediaBuffer,
saveRemoteMedia,
saveResponseMedia,
} from "../../media/fetch.js";
import { readRemoteMediaBuffer, saveRemoteMedia, saveResponseMedia } from "../../media/fetch.js";
import { saveMediaBuffer } from "../../media/store.js";
import { buildPairingReply } from "../../pairing/pairing-messages.js";
import {
@@ -154,7 +150,7 @@ export function createRuntimeChannel(): PluginRuntime["channel"] {
},
media: {
readRemoteMediaBuffer,
fetchRemoteMedia,
fetchRemoteMedia: readRemoteMediaBuffer,
saveRemoteMedia,
saveResponseMedia,
saveMediaBuffer,
@@ -198,6 +194,7 @@ export function createRuntimeChannel(): PluginRuntime["channel"] {
buildContext: buildChannelInboundEventContext,
run: runChannelInboundEvent,
runPreparedReply: runPreparedInboundReply,
dispatch: dispatchChannelInboundTurn,
dispatchReply: dispatchChannelInboundReply,
},
threadBindings: {
+2 -2
View File
@@ -1,7 +1,7 @@
// Runtime media helpers load and classify media attachments for plugin runtimes.
import { mediaKindFromMime } from "@openclaw/media-core/constants";
import { detectMime } from "@openclaw/media-core/mime";
import { isVoiceCompatibleAudio } from "../../media/audio.js";
import { isVoiceMessageCompatibleAudio } from "../../media/audio.js";
import { getImageMetadata, resizeToJpeg } from "../../media/media-services.js";
import { loadWebMedia } from "../../media/web-media.js";
import type { PluginRuntime } from "./types.js";
@@ -12,7 +12,7 @@ export function createRuntimeMedia(): PluginRuntime["media"] {
loadWebMedia,
detectMime,
mediaKindFromMime,
isVoiceCompatibleAudio,
isVoiceCompatibleAudio: isVoiceMessageCompatibleAudio,
getImageMetadata,
resizeToJpeg,
};
+2
View File
@@ -189,6 +189,8 @@ export type PluginRuntimeChannel = {
run: typeof import("../../channels/turn/kernel.js").runChannelInboundEvent;
/** @deprecated Prefer `run` for raw inbound events or `dispatchReply` for assembled contexts. */
runPreparedReply: typeof import("../../channels/turn/kernel.js").runPreparedInboundReply;
dispatch: typeof import("../../channels/turn/kernel.js").dispatchChannelInboundTurn;
/** Compatibility escape hatch; prefer `dispatch`, which keeps session wiring in core. */
dispatchReply: typeof import("../../channels/turn/kernel.js").dispatchChannelInboundReply;
};
threadBindings: {