fix(regression): restore slack probe fallback without runtime

This commit is contained in:
Tak Hoffman
2026-03-27 19:53:33 -05:00
parent b598cdf968
commit 3ec1df86fa
3 changed files with 56 additions and 6 deletions

View File

@@ -3,8 +3,9 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
import { createRuntimeEnv } from "../../../test/helpers/extensions/runtime-env.js";
import { slackPlugin } from "./channel.js";
import { slackOutbound } from "./outbound-adapter.js";
import * as probeModule from "./probe.js";
import type { OpenClawConfig } from "./runtime-api.js";
import { setSlackRuntime } from "./runtime.js";
import { clearSlackRuntime, setSlackRuntime } from "./runtime.js";
const handleSlackActionMock = vi.fn();
@@ -144,6 +145,41 @@ describe("slackPlugin actions", () => {
});
});
describe("slackPlugin status", () => {
it("uses the direct Slack probe helper when runtime is not initialized", async () => {
const probeSpy = vi.spyOn(probeModule, "probeSlack").mockResolvedValueOnce({
ok: true,
status: 200,
bot: { id: "B1", name: "openclaw-bot" },
team: { id: "T1", name: "OpenClaw" },
});
clearSlackRuntime();
const cfg = {
channels: {
slack: {
botToken: "xoxb-test",
appToken: "xapp-test",
},
},
} as OpenClawConfig;
const account = slackPlugin.config.resolveAccount(cfg, "default");
const result = await slackPlugin.status!.probeAccount!({
account,
timeoutMs: 2500,
cfg,
});
expect(probeSpy).toHaveBeenCalledWith("xoxb-test", 2500);
expect(result).toEqual({
ok: true,
status: 200,
bot: { id: "B1", name: "openclaw-bot" },
team: { id: "T1", name: "OpenClaw" },
});
});
});
describe("slackPlugin security", () => {
it("normalizes dm allowlist entries with trimmed prefixes", () => {
const resolveDmPolicy = slackPlugin.security?.resolveDmPolicy;

View File

@@ -49,7 +49,7 @@ import { resolveSlackGroupRequireMention, resolveSlackGroupToolPolicy } from "./
import { isSlackInteractiveRepliesEnabled } from "./interactive-replies.js";
import { SLACK_TEXT_LIMIT } from "./limits.js";
import { slackOutbound } from "./outbound-adapter.js";
import type { SlackProbe } from "./probe.js";
import { probeSlack, type SlackProbe } from "./probe.js";
import { resolveSlackUserAllowlist } from "./resolve-users.js";
import {
DEFAULT_ACCOUNT_ID,
@@ -86,6 +86,17 @@ const resolveSlackDmPolicy = createScopedDmSecurityResolver<ResolvedSlackAccount
.trim(),
});
function resolveSlackProbe() {
try {
return getSlackRuntime().channel.slack.probeSlack;
} catch (error) {
if (error instanceof Error && error.message === "Slack runtime not initialized") {
return probeSlack;
}
throw error;
}
}
// Select the appropriate Slack token for read/write operations.
function getTokenForOperation(
account: ResolvedSlackAccount,
@@ -380,7 +391,7 @@ export const slackPlugin: ChannelPlugin<ResolvedSlackAccount, SlackProbe> = crea
if (!token) {
return { ok: false, error: "missing token" };
}
return await getSlackRuntime().channel.slack.probeSlack(token, timeoutMs);
return await resolveSlackProbe()(token, timeoutMs);
},
formatCapabilitiesProbe: ({ probe }) => {
const slackProbe = probe as SlackProbe | undefined;

View File

@@ -1,6 +1,9 @@
import type { PluginRuntime } from "openclaw/plugin-sdk/core";
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
const { setRuntime: setSlackRuntime, getRuntime: getSlackRuntime } =
createPluginRuntimeStore<PluginRuntime>("Slack runtime not initialized");
export { getSlackRuntime, setSlackRuntime };
const {
setRuntime: setSlackRuntime,
clearRuntime: clearSlackRuntime,
getRuntime: getSlackRuntime,
} = createPluginRuntimeStore<PluginRuntime>("Slack runtime not initialized");
export { clearSlackRuntime, getSlackRuntime, setSlackRuntime };