mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-16 04:20:44 +00:00
Fix configure startup stalls from outbound send-deps imports (#46301)
* fix: avoid configure startup plugin stalls * fix: credit configure startup changelog entry
This commit is contained in:
@@ -13,6 +13,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
- Z.AI/onboarding: detect a working default model even for explicit `zai-coding-*` endpoint choices, so Coding Plan setup can keep the selected endpoint while defaulting to `glm-5` when available or `glm-4.7` as fallback. (#45969)
|
||||
- Control UI/chat sessions: show human-readable labels in the grouped session dropdown again, keep unique scoped fallbacks when metadata is missing, and disambiguate duplicate labels only when needed. (#45130) thanks @luzhidong.
|
||||
- Configure/startup: move outbound send-deps resolution into a lightweight helper so `openclaw configure` no longer stalls after the banner while eagerly loading channel plugins. (#46301) thanks @scoootscooob.
|
||||
|
||||
## 2026.3.13
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ import {
|
||||
type ChannelPlugin,
|
||||
type ResolvedDiscordAccount,
|
||||
} from "openclaw/plugin-sdk/discord";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/deliver.js";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
import { getDiscordRuntime } from "./runtime.js";
|
||||
|
||||
type DiscordSendFn = ReturnType<
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { sendTextMediaPayload } from "../../../src/channels/plugins/outbound/direct-text-media.js";
|
||||
import type { ChannelOutboundAdapter } from "../../../src/channels/plugins/types.js";
|
||||
import type { OpenClawConfig } from "../../../src/config/config.js";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/deliver.js";
|
||||
import type { OutboundIdentity } from "../../../src/infra/outbound/identity.js";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
import { getThreadBindingManager, type ThreadBindingRecord } from "./monitor/thread-bindings.js";
|
||||
import { normalizeDiscordOutboundTarget } from "./normalize.js";
|
||||
import { sendMessageDiscord, sendPollDiscord, sendWebhookMessageDiscord } from "./send.js";
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
type ChannelPlugin,
|
||||
type ResolvedIMessageAccount,
|
||||
} from "openclaw/plugin-sdk/imessage";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/deliver.js";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
|
||||
import { getIMessageRuntime } from "./runtime.js";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ChannelOutboundAdapter } from "openclaw/plugin-sdk/matrix";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/deliver.js";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
import { sendMessageMatrix, sendPollMatrix } from "./matrix/send.js";
|
||||
import { getMatrixRuntime } from "./runtime.js";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ChannelOutboundAdapter } from "openclaw/plugin-sdk/msteams";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/deliver.js";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
import { createMSTeamsPollStoreFs } from "./polls.js";
|
||||
import { getMSTeamsRuntime } from "./runtime.js";
|
||||
import { sendMessageMSTeams, sendPollMSTeams } from "./send.js";
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
type ChannelPlugin,
|
||||
type ResolvedSignalAccount,
|
||||
} from "openclaw/plugin-sdk/signal";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/deliver.js";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
import { getSignalRuntime } from "./runtime.js";
|
||||
|
||||
const signalMessageActions: ChannelMessageActionAdapter = {
|
||||
|
||||
@@ -38,7 +38,7 @@ import {
|
||||
type ChannelPlugin,
|
||||
type ResolvedSlackAccount,
|
||||
} from "openclaw/plugin-sdk/slack";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/deliver.js";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
|
||||
import { getSlackRuntime } from "./runtime.js";
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ import {
|
||||
import {
|
||||
type OutboundSendDeps,
|
||||
resolveOutboundSendDep,
|
||||
} from "../../../src/infra/outbound/deliver.js";
|
||||
} from "../../../src/infra/outbound/send-deps.js";
|
||||
import { getTelegramRuntime } from "./runtime.js";
|
||||
|
||||
type TelegramSendFn = ReturnType<
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { ChannelOutboundAdapter } from "../../../src/channels/plugins/types
|
||||
import {
|
||||
resolveOutboundSendDep,
|
||||
type OutboundSendDeps,
|
||||
} from "../../../src/infra/outbound/deliver.js";
|
||||
} from "../../../src/infra/outbound/send-deps.js";
|
||||
import type { TelegramInlineButtons } from "./button-types.js";
|
||||
import { markdownToTelegramHtmlChunks } from "./format.js";
|
||||
import { parseTelegramReplyToMessageId, parseTelegramThreadId } from "./outbound-params.js";
|
||||
|
||||
@@ -2,7 +2,7 @@ import { chunkText } from "../../../src/auto-reply/chunk.js";
|
||||
import { sendTextMediaPayload } from "../../../src/channels/plugins/outbound/direct-text-media.js";
|
||||
import type { ChannelOutboundAdapter } from "../../../src/channels/plugins/types.js";
|
||||
import { shouldLogVerbose } from "../../../src/globals.js";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/deliver.js";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
import { resolveWhatsAppOutboundTarget } from "../../../src/whatsapp/resolve-outbound-target.js";
|
||||
import { sendMessageWhatsApp, sendPollWhatsApp } from "./send.js";
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { sendMessageIMessage } from "../../../../extensions/imessage/src/send.js";
|
||||
import { resolveOutboundSendDep, type OutboundSendDeps } from "../../../infra/outbound/deliver.js";
|
||||
import {
|
||||
resolveOutboundSendDep,
|
||||
type OutboundSendDeps,
|
||||
} from "../../../infra/outbound/send-deps.js";
|
||||
import {
|
||||
createScopedChannelMediaMaxBytesResolver,
|
||||
createDirectTextMediaOutbound,
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { sendMessageSignal } from "../../../../extensions/signal/src/send.js";
|
||||
import { resolveOutboundSendDep, type OutboundSendDeps } from "../../../infra/outbound/deliver.js";
|
||||
import {
|
||||
resolveOutboundSendDep,
|
||||
type OutboundSendDeps,
|
||||
} from "../../../infra/outbound/send-deps.js";
|
||||
import {
|
||||
createScopedChannelMediaMaxBytesResolver,
|
||||
createDirectTextMediaOutbound,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { parseSlackBlocksInput } from "../../../../extensions/slack/src/blocks-input.js";
|
||||
import { sendMessageSlack, type SlackSendIdentity } from "../../../../extensions/slack/src/send.js";
|
||||
import { resolveOutboundSendDep } from "../../../infra/outbound/deliver.js";
|
||||
import type { OutboundIdentity } from "../../../infra/outbound/identity.js";
|
||||
import { resolveOutboundSendDep } from "../../../infra/outbound/send-deps.js";
|
||||
import { getGlobalHookRunner } from "../../../plugins/hook-runner-global.js";
|
||||
import type { ChannelOutboundAdapter } from "../types.js";
|
||||
import { sendTextMediaPayload } from "./direct-text-media.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { resolveOutboundSendDep } from "../../infra/outbound/deliver.js";
|
||||
import { resolveOutboundSendDep } from "../../infra/outbound/send-deps.js";
|
||||
import type { PluginRuntimeChannel } from "../../plugins/runtime/types-channel.js";
|
||||
import { escapeRegExp } from "../../utils.js";
|
||||
import { resolveWhatsAppOutboundTarget } from "../../whatsapp/resolve-outbound-target.js";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { OutboundSendDeps } from "../infra/outbound/deliver.js";
|
||||
import type { OutboundSendDeps } from "../infra/outbound/send-deps.js";
|
||||
import { createOutboundSendDepsFromCliSource } from "./outbound-send-mapping.js";
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,57 +40,17 @@ import type { DeliveryMirror } from "./mirror.js";
|
||||
import type { NormalizedOutboundPayload } from "./payloads.js";
|
||||
import { normalizeReplyPayloadsForDelivery } from "./payloads.js";
|
||||
import { isPlainTextSurface, sanitizeForPlainText } from "./sanitize-text.js";
|
||||
import { resolveOutboundSendDep, type OutboundSendDeps } from "./send-deps.js";
|
||||
import type { OutboundSessionContext } from "./session-context.js";
|
||||
import type { OutboundChannel } from "./targets.js";
|
||||
|
||||
export type { NormalizedOutboundPayload } from "./payloads.js";
|
||||
export { normalizeOutboundPayloads } from "./payloads.js";
|
||||
export { resolveOutboundSendDep, type OutboundSendDeps } from "./send-deps.js";
|
||||
|
||||
const log = createSubsystemLogger("outbound/deliver");
|
||||
const TELEGRAM_TEXT_LIMIT = 4096;
|
||||
|
||||
type LegacyOutboundSendDeps = {
|
||||
sendWhatsApp?: unknown;
|
||||
sendTelegram?: unknown;
|
||||
sendDiscord?: unknown;
|
||||
sendSlack?: unknown;
|
||||
sendSignal?: unknown;
|
||||
sendIMessage?: unknown;
|
||||
sendMatrix?: unknown;
|
||||
sendMSTeams?: unknown;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dynamic bag of per-channel send functions, keyed by channel ID.
|
||||
* Each outbound adapter resolves its own function from this record and
|
||||
* falls back to a direct import when the key is absent.
|
||||
*/
|
||||
export type OutboundSendDeps = LegacyOutboundSendDeps & { [channelId: string]: unknown };
|
||||
|
||||
const LEGACY_SEND_DEP_KEYS = {
|
||||
whatsapp: "sendWhatsApp",
|
||||
telegram: "sendTelegram",
|
||||
discord: "sendDiscord",
|
||||
slack: "sendSlack",
|
||||
signal: "sendSignal",
|
||||
imessage: "sendIMessage",
|
||||
matrix: "sendMatrix",
|
||||
msteams: "sendMSTeams",
|
||||
} as const satisfies Record<string, keyof LegacyOutboundSendDeps>;
|
||||
|
||||
export function resolveOutboundSendDep<T>(
|
||||
deps: OutboundSendDeps | null | undefined,
|
||||
channelId: keyof typeof LEGACY_SEND_DEP_KEYS,
|
||||
): T | undefined {
|
||||
const dynamic = deps?.[channelId];
|
||||
if (dynamic !== undefined) {
|
||||
return dynamic as T;
|
||||
}
|
||||
const legacyKey = LEGACY_SEND_DEP_KEYS[channelId];
|
||||
const legacy = deps?.[legacyKey];
|
||||
return legacy as T | undefined;
|
||||
}
|
||||
|
||||
export type OutboundDeliveryResult = {
|
||||
channel: Exclude<OutboundChannel, "none">;
|
||||
messageId: string;
|
||||
|
||||
41
src/infra/outbound/send-deps.ts
Normal file
41
src/infra/outbound/send-deps.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
type LegacyOutboundSendDeps = {
|
||||
sendWhatsApp?: unknown;
|
||||
sendTelegram?: unknown;
|
||||
sendDiscord?: unknown;
|
||||
sendSlack?: unknown;
|
||||
sendSignal?: unknown;
|
||||
sendIMessage?: unknown;
|
||||
sendMatrix?: unknown;
|
||||
sendMSTeams?: unknown;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dynamic bag of per-channel send functions, keyed by channel ID.
|
||||
* Each outbound adapter resolves its own function from this record and
|
||||
* falls back to a direct import when the key is absent.
|
||||
*/
|
||||
export type OutboundSendDeps = LegacyOutboundSendDeps & { [channelId: string]: unknown };
|
||||
|
||||
const LEGACY_SEND_DEP_KEYS = {
|
||||
whatsapp: "sendWhatsApp",
|
||||
telegram: "sendTelegram",
|
||||
discord: "sendDiscord",
|
||||
slack: "sendSlack",
|
||||
signal: "sendSignal",
|
||||
imessage: "sendIMessage",
|
||||
matrix: "sendMatrix",
|
||||
msteams: "sendMSTeams",
|
||||
} as const satisfies Record<string, keyof LegacyOutboundSendDeps>;
|
||||
|
||||
export function resolveOutboundSendDep<T>(
|
||||
deps: OutboundSendDeps | null | undefined,
|
||||
channelId: keyof typeof LEGACY_SEND_DEP_KEYS,
|
||||
): T | undefined {
|
||||
const dynamic = deps?.[channelId];
|
||||
if (dynamic !== undefined) {
|
||||
return dynamic as T;
|
||||
}
|
||||
const legacyKey = LEGACY_SEND_DEP_KEYS[channelId];
|
||||
const legacy = deps?.[legacyKey];
|
||||
return legacy as T | undefined;
|
||||
}
|
||||
Reference in New Issue
Block a user