Files
openclaw/extensions/slack/src/channel-actions.ts
2026-04-01 00:07:50 +09:00

72 lines
2.4 KiB
TypeScript

import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import { Type } from "@sinclair/typebox";
import {
type ChannelMessageActionAdapter,
type ChannelMessageToolDiscovery,
} from "openclaw/plugin-sdk/channel-contract";
import type { SlackActionContext } from "./action-runtime.js";
import { handleSlackAction } from "./action-runtime.js";
import { isSlackInteractiveRepliesEnabled } from "./interactive-replies.js";
import { handleSlackMessageAction } from "./message-action-dispatch.js";
import { extractSlackToolSend, listSlackMessageActions } from "./message-actions.js";
import { createSlackMessageToolBlocksSchema } from "./message-tool-schema.js";
import { resolveSlackChannelId } from "./targets.js";
type SlackActionInvoke = (
action: Record<string, unknown>,
cfg: unknown,
toolContext: unknown,
) => Promise<AgentToolResult<unknown>>;
export function createSlackActions(
providerId: string,
options?: { invoke?: SlackActionInvoke },
): ChannelMessageActionAdapter {
function describeMessageTool({
cfg,
}: Parameters<
NonNullable<ChannelMessageActionAdapter["describeMessageTool"]>
>[0]): ChannelMessageToolDiscovery {
const actions = listSlackMessageActions(cfg);
const capabilities = new Set<"blocks" | "interactive">();
if (actions.includes("send")) {
capabilities.add("blocks");
}
if (isSlackInteractiveRepliesEnabled({ cfg })) {
capabilities.add("interactive");
}
return {
actions,
capabilities: Array.from(capabilities),
schema: actions.includes("send")
? {
properties: {
blocks: Type.Optional(createSlackMessageToolBlocksSchema()),
},
}
: null,
};
}
return {
describeMessageTool,
extractToolSend: ({ args }) => extractSlackToolSend(args),
handleAction: async (ctx) => {
return await handleSlackMessageAction({
providerId,
ctx,
normalizeChannelId: resolveSlackChannelId,
includeReadThreadId: true,
invoke: async (action, cfg, toolContext) =>
await (options?.invoke
? options.invoke(action, cfg, toolContext)
: handleSlackAction(action, cfg, {
...(toolContext as SlackActionContext | undefined),
mediaLocalRoots: ctx.mediaLocalRoots,
mediaReadFile: ctx.mediaReadFile,
})),
});
},
};
}