test: reduce extension runtime partial mocks

This commit is contained in:
Peter Steinberger
2026-04-03 18:32:18 +01:00
parent 14c863dc4a
commit f36ed7105f
26 changed files with 193 additions and 178 deletions

View File

@@ -0,0 +1,3 @@
export { loadConfig, resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
export { chunkTextWithMode, resolveChunkMode } from "openclaw/plugin-sdk/reply-runtime";
export { convertMarkdownTables } from "openclaw/plugin-sdk/text-runtime";

View File

@@ -17,31 +17,13 @@ vi.mock("../send.js", () => ({
sendMessageIMessageMock(to, message, opts),
}));
vi.mock("openclaw/plugin-sdk/config-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/config-runtime")>();
return {
...actual,
loadConfig: () => ({}),
resolveMarkdownTableMode: () => resolveMarkdownTableModeMock(),
};
});
vi.mock("openclaw/plugin-sdk/reply-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/reply-runtime")>();
return {
...actual,
chunkTextWithMode: (text: string) => chunkTextWithModeMock(text),
resolveChunkMode: () => resolveChunkModeMock(),
};
});
vi.mock("openclaw/plugin-sdk/text-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/text-runtime")>();
return {
...actual,
convertMarkdownTables: (text: string) => convertMarkdownTablesMock(text),
};
});
vi.mock("./deliver.runtime.js", () => ({
loadConfig: vi.fn(() => ({})),
resolveMarkdownTableMode: vi.fn(() => resolveMarkdownTableModeMock()),
chunkTextWithMode: (text: string) => chunkTextWithModeMock(text),
resolveChunkMode: vi.fn(() => resolveChunkModeMock()),
convertMarkdownTables: (text: string) => convertMarkdownTablesMock(text),
}));
let deliverReplies: typeof import("./deliver.js").deliverReplies;

View File

@@ -1,15 +1,18 @@
import { loadConfig } from "openclaw/plugin-sdk/config-runtime";
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
import {
deliverTextOrMediaReply,
resolveSendableOutboundReplyParts,
} from "openclaw/plugin-sdk/reply-payload";
import { chunkTextWithMode, resolveChunkMode } from "openclaw/plugin-sdk/reply-runtime";
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import { convertMarkdownTables } from "openclaw/plugin-sdk/text-runtime";
import type { createIMessageRpcClient } from "../client.js";
import { sendMessageIMessage } from "../send.js";
import {
chunkTextWithMode,
convertMarkdownTables,
loadConfig,
resolveChunkMode,
resolveMarkdownTableMode,
} from "./deliver.runtime.js";
import type { SentMessageCache } from "./echo-cache.js";
import { sanitizeOutboundText } from "./sanitize-outbound.js";

View File

@@ -1,7 +1,5 @@
import type { ChannelSetupAdapter } from "openclaw/plugin-sdk/channel-setup";
import { createSetupInputPresenceValidator } from "openclaw/plugin-sdk/setup-runtime";
import { resolveMattermostAccount, type ResolvedMattermostAccount } from "./mattermost/accounts.js";
import { normalizeMattermostBaseUrl } from "./mattermost/client.js";
import {
applyAccountNameToChannelSection,
applySetupAccountConfigPatch,
@@ -10,7 +8,12 @@ import {
normalizeAccountId,
type OpenClawConfig,
} from "./runtime-api.js";
import { hasConfiguredSecretInput } from "./secret-input.js";
import {
resolveMattermostAccount,
type ResolvedMattermostAccount,
} from "./setup.accounts.runtime.js";
import { normalizeMattermostBaseUrl } from "./setup.client.runtime.js";
import { hasConfiguredSecretInput } from "./setup.secret-input.runtime.js";
const channel = "mattermost" as const;

View File

@@ -3,19 +3,19 @@ import {
formatDocsLink,
type ChannelSetupWizard,
} from "openclaw/plugin-sdk/setup";
import { listMattermostAccountIds } from "./mattermost/accounts.js";
import { normalizeMattermostBaseUrl } from "./mattermost/client.js";
import {
applySetupAccountConfigPatch,
DEFAULT_ACCOUNT_ID,
type OpenClawConfig,
} from "./runtime-api.js";
import { hasConfiguredSecretInput } from "./secret-input.js";
import {
isMattermostConfigured,
mattermostSetupAdapter,
resolveMattermostAccountWithSecrets,
} from "./setup-core.js";
import { listMattermostAccountIds } from "./setup.accounts.runtime.js";
import { normalizeMattermostBaseUrl } from "./setup.client.runtime.js";
import { hasConfiguredSecretInput } from "./setup.secret-input.runtime.js";
const channel = "mattermost" as const;
export { mattermostSetupAdapter } from "./setup-core.js";

View File

@@ -0,0 +1,5 @@
export {
listMattermostAccountIds,
resolveMattermostAccount,
type ResolvedMattermostAccount,
} from "./mattermost/accounts.js";

View File

@@ -0,0 +1 @@
export { normalizeMattermostBaseUrl } from "./mattermost/client.js";

View File

@@ -0,0 +1 @@
export { hasConfiguredSecretInput } from "./secret-input.js";

View File

@@ -12,32 +12,39 @@ const resolveMattermostAccount = vi.hoisted(() => vi.fn());
const normalizeMattermostBaseUrl = vi.hoisted(() => vi.fn((value: string | undefined) => value));
const hasConfiguredSecretInput = vi.hoisted(() => vi.fn((value: unknown) => Boolean(value)));
vi.mock("./mattermost/accounts.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("./mattermost/accounts.js")>();
return {
...actual,
resolveMattermostAccount: (...args: Parameters<typeof actual.resolveMattermostAccount>) => {
const mocked = resolveMattermostAccount(...args);
return mocked === undefined ? actual.resolveMattermostAccount(...args) : mocked;
},
};
});
vi.mock("./setup.accounts.runtime.js", () => ({
listMattermostAccountIds: vi.fn((cfg: OpenClawConfig) => {
const accounts = cfg.channels?.mattermost?.accounts;
const ids = accounts ? Object.keys(accounts) : [];
return ids.length > 0 ? ids : [DEFAULT_ACCOUNT_ID];
}),
resolveMattermostAccount: (params: Parameters<typeof resolveMattermostAccount>[0]) => {
const mocked = resolveMattermostAccount(params);
return (
mocked ?? {
accountId: params.accountId ?? DEFAULT_ACCOUNT_ID,
enabled: params.cfg.channels?.mattermost?.enabled !== false,
botToken:
typeof params.cfg.channels?.mattermost?.botToken === "string"
? params.cfg.channels.mattermost.botToken
: undefined,
baseUrl: normalizeMattermostBaseUrl(params.cfg.channels?.mattermost?.baseUrl),
botTokenSource:
typeof params.cfg.channels?.mattermost?.botToken === "string" ? "config" : "none",
baseUrlSource: params.cfg.channels?.mattermost?.baseUrl ? "config" : "none",
config: params.cfg.channels?.mattermost ?? {},
}
);
},
}));
vi.mock("./mattermost/client.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("./mattermost/client.js")>();
return {
...actual,
normalizeMattermostBaseUrl,
};
});
vi.mock("./setup.client.runtime.js", () => ({
normalizeMattermostBaseUrl,
}));
vi.mock("./secret-input.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("./secret-input.js")>();
return {
...actual,
hasConfiguredSecretInput,
};
});
vi.mock("./setup.secret-input.runtime.js", () => ({
hasConfiguredSecretInput,
}));
function createApi(
registrationMode: OpenClawPluginApi["registrationMode"],

View File

@@ -0,0 +1,26 @@
export {
colorize,
defaultRuntime,
formatErrorMessage,
isRich,
resolveCommandSecretRefsViaGateway,
setVerbose,
shortenHomeInString,
shortenHomePath,
theme,
withManager,
withProgress,
withProgressTotals,
} from "openclaw/plugin-sdk/memory-core-host-runtime-cli";
export {
loadConfig,
resolveDefaultAgentId,
resolveSessionTranscriptsDirForAgent,
resolveStateDir,
type OpenClawConfig,
} from "openclaw/plugin-sdk/memory-core-host-runtime-core";
export {
listMemoryFiles,
normalizeExtraMemoryPaths,
} from "openclaw/plugin-sdk/memory-core-host-runtime-files";
export { getMemorySearchManager } from "./memory/index.js";

View File

@@ -2,34 +2,30 @@ import fsSync from "node:fs";
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { buildAgentSessionKey } from "openclaw/plugin-sdk/routing";
import {
colorize,
defaultRuntime,
formatErrorMessage,
getMemorySearchManager,
isRich,
listMemoryFiles,
loadConfig,
normalizeExtraMemoryPaths,
resolveCommandSecretRefsViaGateway,
resolveDefaultAgentId,
resolveSessionTranscriptsDirForAgent,
resolveStateDir,
setVerbose,
shortenHomeInString,
shortenHomePath,
theme,
type OpenClawConfig,
withManager,
withProgress,
withProgressTotals,
} from "openclaw/plugin-sdk/memory-core-host-runtime-cli";
import {
loadConfig,
resolveDefaultAgentId,
resolveSessionTranscriptsDirForAgent,
resolveStateDir,
type OpenClawConfig,
} from "openclaw/plugin-sdk/memory-core-host-runtime-core";
import {
listMemoryFiles,
normalizeExtraMemoryPaths,
} from "openclaw/plugin-sdk/memory-core-host-runtime-files";
import { buildAgentSessionKey } from "openclaw/plugin-sdk/routing";
} from "./cli.host.runtime.js";
import type { MemoryCommandOptions, MemorySearchCommandOptions } from "./cli.types.js";
import { getMemorySearchManager } from "./memory/index.js";
type MemoryManager = NonNullable<Awaited<ReturnType<typeof getMemorySearchManager>>["manager"]>;
type MemoryManagerPurpose = Parameters<typeof getMemorySearchManager>[0]["purpose"];

View File

@@ -20,30 +20,15 @@ const resolveCommandSecretRefsViaGateway = vi.hoisted(() =>
})),
);
vi.mock("openclaw/plugin-sdk/memory-core-host-runtime-core", async (importOriginal) => {
vi.mock("./cli.host.runtime.js", async () => {
const actual =
await importOriginal<typeof import("openclaw/plugin-sdk/memory-core-host-runtime-core")>();
return {
...actual,
loadConfig,
resolveDefaultAgentId,
};
});
vi.mock("openclaw/plugin-sdk/memory-core-host-runtime-cli", async (importOriginal) => {
const actual =
await importOriginal<typeof import("openclaw/plugin-sdk/memory-core-host-runtime-cli")>();
return {
...actual,
resolveCommandSecretRefsViaGateway,
};
});
vi.mock("./memory/index.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("./memory/index.js")>();
await vi.importActual<typeof import("./cli.host.runtime.js")>("./cli.host.runtime.js");
return {
...actual,
getMemorySearchManager,
loadConfig,
resolveCommandSecretRefsViaGateway,
resolveDefaultAgentId,
};
});

View File

@@ -189,45 +189,34 @@ export function resetSlackTestState(config: Record<string, unknown> = defaultSla
getSlackHandlers()?.clear();
}
vi.mock("openclaw/plugin-sdk/config-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/config-runtime")>();
vi.mock("./monitor/config.runtime.js", async () => {
const actual = await vi.importActual<typeof import("./monitor/config.runtime.js")>(
"./monitor/config.runtime.js",
);
return {
...actual,
loadConfig: () => slackTestState.config,
resolveStorePath: vi.fn(() => "/tmp/openclaw-sessions.json"),
updateLastRoute: (...args: unknown[]) => slackTestState.updateLastRouteMock(...args),
resolveSessionKey: vi.fn(),
readSessionUpdatedAt: vi.fn(() => undefined),
recordSessionMetaFromInbound: vi.fn().mockResolvedValue(undefined),
resolveStorePath: vi.fn(() => "/tmp/openclaw-sessions.json"),
updateLastRoute: (...args: unknown[]) => slackTestState.updateLastRouteMock(...args),
};
});
vi.mock("openclaw/plugin-sdk/reply-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/reply-runtime")>();
vi.mock("./monitor/reply.runtime.js", async () => {
const actual = await vi.importActual<typeof import("./monitor/reply.runtime.js")>(
"./monitor/reply.runtime.js",
);
const replyResolver: typeof actual.getReplyFromConfig = (...args) =>
slackTestState.replyMock(...args) as ReturnType<typeof actual.getReplyFromConfig>;
return {
...actual,
getReplyFromConfig: replyResolver,
dispatchInboundMessage: (params: Parameters<typeof actual.dispatchInboundMessage>[0]) =>
actual.dispatchInboundMessage({
...params,
replyResolver,
}),
dispatchInboundMessageWithBufferedDispatcher: (
params: Parameters<typeof actual.dispatchInboundMessageWithBufferedDispatcher>[0],
) =>
actual.dispatchInboundMessageWithBufferedDispatcher({
...params,
replyResolver,
}),
dispatchInboundMessageWithDispatcher: (
params: Parameters<typeof actual.dispatchInboundMessageWithDispatcher>[0],
) =>
actual.dispatchInboundMessageWithDispatcher({
...params,
replyResolver,
}),
getReplyFromConfig: replyResolver,
};
});
@@ -241,16 +230,16 @@ vi.mock("./resolve-users.js", () => ({
entries.map((input) => ({ input, resolved: false })),
}));
vi.mock("./send.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("./send.js")>();
vi.mock("./monitor/send.runtime.js", () => {
return {
...actual,
sendMessageSlack: (...args: unknown[]) => slackTestState.sendMock(...args),
};
});
vi.mock("openclaw/plugin-sdk/conversation-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/conversation-runtime")>();
vi.mock("./monitor/conversation.runtime.js", async () => {
const actual = await vi.importActual<typeof import("./monitor/conversation.runtime.js")>(
"./monitor/conversation.runtime.js",
);
return {
...actual,
readChannelAllowFromStore: (...args: unknown[]) =>

View File

@@ -0,0 +1,13 @@
export {
isDangerousNameMatchingEnabled,
loadConfig,
readSessionUpdatedAt,
recordSessionMetaFromInbound,
resolveChannelContextVisibilityMode,
resolveDefaultGroupPolicy,
resolveOpenProviderRuntimeGroupPolicy,
resolveSessionKey,
resolveStorePath,
updateLastRoute,
warnMissingProviderGroupPolicyFallbackOnce,
} from "openclaw/plugin-sdk/config-runtime";

View File

@@ -4,7 +4,7 @@ import type {
OpenClawConfig,
SlackReactionNotificationMode,
} from "openclaw/plugin-sdk/config-runtime";
import { resolveSessionKey, type SessionScope } from "openclaw/plugin-sdk/config-runtime";
import type { SessionScope } from "openclaw/plugin-sdk/config-runtime";
import type { DmPolicy, GroupPolicy } from "openclaw/plugin-sdk/config-runtime";
import { createDedupeCache } from "openclaw/plugin-sdk/core";
import type { HistoryEntry } from "openclaw/plugin-sdk/reply-history";
@@ -17,6 +17,7 @@ import { normalizeAllowList, normalizeAllowListLower, normalizeSlackSlug } from
import type { SlackChannelConfigEntries } from "./channel-config.js";
import { resolveSlackChannelConfig } from "./channel-config.js";
import { normalizeSlackChannelType } from "./channel-type.js";
import { resolveSessionKey } from "./config.runtime.js";
import { isSlackChannelAllowedByPolicy } from "./policy.js";
export { inferSlackChannelType, normalizeSlackChannelType } from "./channel-type.js";

View File

@@ -0,0 +1,9 @@
export {
buildPluginBindingResolvedText,
parsePluginBindingApprovalCustomId,
readChannelAllowFromStore,
recordInboundSession,
resolveConversationLabel,
resolvePluginConversationBindingApproval,
upsertChannelPairingRequest,
} from "openclaw/plugin-sdk/conversation-runtime";

View File

@@ -1,8 +1,8 @@
import { formatAllowlistMatchMeta } from "openclaw/plugin-sdk/allow-from";
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
import { upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
import { resolveSlackAllowListMatch } from "./allow-list.js";
import type { SlackMonitorContext } from "./context.js";
import { upsertChannelPairingRequest } from "./conversation.runtime.js";
export async function authorizeSlackDirectMessage(params: {
ctx: SlackMonitorContext;

View File

@@ -1,15 +1,15 @@
import type { SlackActionMiddlewareArgs } from "@slack/bolt";
import type { Block, KnownBlock } from "@slack/web-api";
import {
buildPluginBindingResolvedText,
parsePluginBindingApprovalCustomId,
resolvePluginConversationBindingApproval,
} from "openclaw/plugin-sdk/conversation-runtime";
import { enqueueSystemEvent } from "openclaw/plugin-sdk/infra-runtime";
import { dispatchPluginInteractiveHandler } from "openclaw/plugin-sdk/plugin-runtime";
import { SLACK_REPLY_BUTTON_ACTION_ID, SLACK_REPLY_SELECT_ACTION_ID } from "../../blocks-render.js";
import { authorizeSlackSystemEventSender } from "../auth.js";
import type { SlackMonitorContext } from "../context.js";
import {
buildPluginBindingResolvedText,
parsePluginBindingApprovalCustomId,
resolvePluginConversationBindingApproval,
} from "../conversation.runtime.js";
import { escapeSlackMrkdwn } from "../mrkdwn.js";
type InteractionMessageBlock = {

View File

@@ -8,12 +8,9 @@ import {
type StatusReactionAdapter,
} from "openclaw/plugin-sdk/channel-feedback";
import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
import { resolveStorePath, updateLastRoute } from "openclaw/plugin-sdk/config-runtime";
import { resolveAgentOutboundIdentity } from "openclaw/plugin-sdk/outbound-runtime";
import { clearHistoryEntriesIfEnabled } from "openclaw/plugin-sdk/reply-history";
import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
import { dispatchInboundMessage } from "openclaw/plugin-sdk/reply-runtime";
import { createReplyDispatcherWithTyping } from "openclaw/plugin-sdk/reply-runtime";
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
import { danger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
import { resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
@@ -31,12 +28,14 @@ import type { SlackStreamSession } from "../../streaming.js";
import { appendSlackStream, startSlackStream, stopSlackStream } from "../../streaming.js";
import { resolveSlackThreadTargets } from "../../threading.js";
import { normalizeSlackAllowOwnerEntry } from "../allow-list.js";
import { resolveStorePath, updateLastRoute } from "../config.runtime.js";
import {
createSlackReplyDeliveryPlan,
deliverReplies,
readSlackReplyBlocks,
resolveSlackThreadTs,
} from "../replies.js";
import { createReplyDispatcherWithTyping, dispatchInboundMessage } from "../reply.runtime.js";
import { finalizeSlackPreviewEdit } from "./preview-finalize.js";
import type { PreparedSlackMessage } from "./types.js";

View File

@@ -1,6 +1,5 @@
import { formatInboundEnvelope } from "openclaw/plugin-sdk/channel-inbound";
import type { ContextVisibilityMode } from "openclaw/plugin-sdk/config-runtime";
import { readSessionUpdatedAt } from "openclaw/plugin-sdk/config-runtime";
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
import {
filterSupplementalContextItems,
@@ -9,6 +8,7 @@ import {
import type { ResolvedSlackAccount } from "../../accounts.js";
import type { SlackMessageEvent } from "../../types.js";
import { resolveSlackAllowListMatch } from "../allow-list.js";
import { readSessionUpdatedAt } from "../config.runtime.js";
import type { SlackMonitorContext } from "../context.js";
import {
resolveSlackMedia,

View File

@@ -14,21 +14,11 @@ import {
import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth";
import { hasControlCommand } from "openclaw/plugin-sdk/command-auth";
import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-auth";
import {
readSessionUpdatedAt,
resolveChannelContextVisibilityMode,
resolveStorePath,
} from "openclaw/plugin-sdk/config-runtime";
import {
recordInboundSession,
resolveConversationLabel,
} from "openclaw/plugin-sdk/conversation-runtime";
import { enqueueSystemEvent } from "openclaw/plugin-sdk/infra-runtime";
import {
buildPendingHistoryContextFromMap,
recordPendingHistoryEntryIfEnabled,
} from "openclaw/plugin-sdk/reply-history";
import { finalizeInboundContext } from "openclaw/plugin-sdk/reply-runtime";
import type { FinalizedMsgContext } from "openclaw/plugin-sdk/reply-runtime";
import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
import { resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
@@ -36,7 +26,6 @@ import { logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
import { resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
import { resolveSlackReplyToMode, type ResolvedSlackAccount } from "../../accounts.js";
import { reactSlackMessage } from "../../actions.js";
import { sendMessageSlack } from "../../send.js";
import { hasSlackThreadParticipation } from "../../sent-thread-cache.js";
import { resolveSlackThreadContext } from "../../threading.js";
import type { SlackMessageEvent } from "../../types.js";
@@ -49,10 +38,18 @@ import {
import { resolveSlackEffectiveAllowFrom } from "../auth.js";
import { resolveSlackChannelConfig } from "../channel-config.js";
import { stripSlackMentionsForCommandDetection } from "../commands.js";
import {
readSessionUpdatedAt,
resolveChannelContextVisibilityMode,
resolveStorePath,
} from "../config.runtime.js";
import { normalizeSlackChannelType, type SlackMonitorContext } from "../context.js";
import { recordInboundSession, resolveConversationLabel } from "../conversation.runtime.js";
import { authorizeSlackDirectMessage } from "../dm-auth.js";
import { resolveSlackThreadStarter } from "../media.js";
import { finalizeInboundContext } from "../reply.runtime.js";
import { resolveSlackRoomContextHints } from "../room-context.js";
import { sendMessageSlack } from "../send.runtime.js";
import { resolveSlackMessageContent } from "./prepare-content.js";
import { resolveSlackThreadContextData } from "./prepare-thread-context.js";
import type { PreparedSlackMessage } from "./types.js";

View File

@@ -7,17 +7,9 @@ import {
patchAllowlistUsersInConfigEntries,
summarizeMapping,
} from "openclaw/plugin-sdk/allow-from";
import { loadConfig } from "openclaw/plugin-sdk/config-runtime";
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/config-runtime";
import {
resolveOpenProviderRuntimeGroupPolicy,
resolveDefaultGroupPolicy,
warnMissingProviderGroupPolicyFallbackOnce,
} from "openclaw/plugin-sdk/config-runtime";
import type { SessionScope } from "openclaw/plugin-sdk/config-runtime";
import { createConnectedChannelStatusPatch } from "openclaw/plugin-sdk/gateway-runtime";
import { DEFAULT_GROUP_HISTORY_LIMIT } from "openclaw/plugin-sdk/reply-history";
import { resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
import { normalizeMainKey } from "openclaw/plugin-sdk/routing";
import { warn } from "openclaw/plugin-sdk/runtime-env";
import {
@@ -39,6 +31,13 @@ import { resolveSlackUserAllowlist, type SlackUserResolution } from "../resolve-
import { resolveSlackAppToken, resolveSlackBotToken } from "../token.js";
import { normalizeAllowList } from "./allow-list.js";
import { resolveSlackSlashCommandConfig } from "./commands.js";
import {
isDangerousNameMatchingEnabled,
loadConfig,
resolveDefaultGroupPolicy,
resolveOpenProviderRuntimeGroupPolicy,
warnMissingProviderGroupPolicyFallbackOnce,
} from "./config.runtime.js";
import { createSlackMonitorContext } from "./context.js";
import { registerSlackMonitorEvents } from "./events.js";
import { SlackExecApprovalHandler } from "./exec-approvals.js";
@@ -50,6 +49,7 @@ import {
SLACK_SOCKET_RECONNECT_POLICY,
waitForSlackSocketDisconnect,
} from "./reconnect-policy.js";
import { resolveTextChunkLimit } from "./reply.runtime.js";
import { registerSlackMonitorSlashCommands } from "./slash.js";
import type { MonitorSlackOpts } from "./types.js";

View File

@@ -4,15 +4,18 @@ import {
resolveSendableOutboundReplyParts,
} from "openclaw/plugin-sdk/reply-payload";
import type { ChunkMode } from "openclaw/plugin-sdk/reply-runtime";
import { chunkMarkdownTextWithMode } from "openclaw/plugin-sdk/reply-runtime";
import { createReplyReferencePlanner } from "openclaw/plugin-sdk/reply-runtime";
import { isSilentReplyText, SILENT_REPLY_TOKEN } from "openclaw/plugin-sdk/reply-runtime";
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import { markdownToSlackMrkdwnChunks } from "../format.js";
import { SLACK_TEXT_LIMIT } from "../limits.js";
import { resolveSlackReplyBlocks } from "../reply-blocks.js";
import { sendMessageSlack, type SlackSendIdentity } from "../send.js";
import {
chunkMarkdownTextWithMode,
createReplyReferencePlanner,
isSilentReplyText,
SILENT_REPLY_TOKEN,
} from "./reply.runtime.js";
import { sendMessageSlack, type SlackSendIdentity } from "./send.runtime.js";
export function readSlackReplyBlocks(payload: ReplyPayload) {
return resolveSlackReplyBlocks(payload);

View File

@@ -0,0 +1,11 @@
export {
chunkMarkdownTextWithMode,
createReplyDispatcherWithTyping,
createReplyReferencePlanner,
dispatchInboundMessage,
finalizeInboundContext,
getReplyFromConfig,
isSilentReplyText,
resolveTextChunkLimit,
SILENT_REPLY_TOKEN,
} from "openclaw/plugin-sdk/reply-runtime";

View File

@@ -0,0 +1 @@
export { sendMessageSlack, type SlackSendIdentity } from "../send.js";

View File

@@ -11,41 +11,21 @@ const mocks = vi.hoisted(() => ({
resolveStorePathMock: vi.fn(),
}));
vi.mock("openclaw/plugin-sdk/reply-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/reply-runtime")>();
vi.mock("./slash-dispatch.runtime.js", async () => {
const actual = await vi.importActual<typeof import("./slash-dispatch.runtime.js")>(
"./slash-dispatch.runtime.js",
);
return {
...actual,
dispatchReplyWithDispatcher: (...args: unknown[]) => mocks.dispatchMock(...args),
finalizeInboundContext: (...args: unknown[]) => mocks.finalizeInboundContextMock(...args),
};
});
vi.mock("openclaw/plugin-sdk/routing", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/routing")>();
return {
...actual,
resolveAgentRoute: (...args: unknown[]) => mocks.resolveAgentRouteMock(...args),
};
});
vi.mock("openclaw/plugin-sdk/conversation-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/conversation-runtime")>();
return {
...actual,
resolveConversationLabel: (...args: unknown[]) => mocks.resolveConversationLabelMock(...args),
recordInboundSessionMetaSafe: (...args: unknown[]) =>
mocks.recordSessionMetaFromInboundMock(...args),
};
});
vi.mock("openclaw/plugin-sdk/config-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/config-runtime")>();
return {
...actual,
resolveStorePath: (...args: unknown[]) => mocks.resolveStorePathMock(...args),
};
});
type SlashHarnessMocks = {
dispatchMock: ReturnType<typeof vi.fn>;
readAllowFromStoreMock: ReturnType<typeof vi.fn>;