refactor: move channel messaging hooks into plugins

This commit is contained in:
Peter Steinberger
2026-03-15 22:38:49 -07:00
parent 680eff63fb
commit ad97c581e2
22 changed files with 658 additions and 399 deletions

View File

@@ -38,6 +38,7 @@ import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
import { getSlackRuntime } from "./runtime.js";
import { createSlackSetupWizardProxy, slackSetupAdapter } from "./setup-core.js";
import { parseSlackTarget } from "./targets.js";
const meta = getChatChannelMeta("slack");
@@ -94,6 +95,37 @@ function resolveSlackSendContext(params: {
return { send, threadTsValue, tokenOverride };
}
function resolveSlackAutoThreadId(params: {
cfg: Parameters<typeof resolveSlackAccount>[0]["cfg"];
accountId?: string | null;
to: string;
toolContext?: {
currentChannelId?: string;
currentThreadTs?: string;
replyToMode?: "off" | "first" | "all";
hasRepliedRef?: { value: boolean };
};
}): string | undefined {
const context = params.toolContext;
if (!context?.currentThreadTs || !context.currentChannelId) {
return undefined;
}
if (context.replyToMode !== "all" && context.replyToMode !== "first") {
return undefined;
}
const parsedTarget = parseSlackTarget(params.to, { defaultKind: "channel" });
if (!parsedTarget || parsedTarget.kind !== "channel") {
return undefined;
}
if (parsedTarget.id.toLowerCase() !== context.currentChannelId.toLowerCase()) {
return undefined;
}
if (context.replyToMode === "first" && context.hasRepliedRef?.value) {
return undefined;
}
return context.currentThreadTs;
}
const slackConfigAccessors = createScopedAccountConfigAccessors({
resolveAccount: ({ cfg, accountId }) => resolveSlackAccount({ cfg, accountId }),
resolveAllowFrom: (account: ResolvedSlackAccount) => account.dm?.allowFrom,
@@ -235,9 +267,24 @@ export const slackPlugin: ChannelPlugin<ResolvedSlackAccount> = {
resolveSlackReplyToMode(resolveSlackAccount({ cfg, accountId }), chatType),
allowExplicitReplyTagsWhenOff: false,
buildToolContext: (params) => buildSlackThreadingToolContext(params),
resolveAutoThreadId: ({ cfg, accountId, to, toolContext, replyToId }) =>
replyToId
? undefined
: resolveSlackAutoThreadId({
cfg,
accountId,
to,
toolContext,
}),
resolveReplyTransport: ({ threadId, replyToId }) => ({
replyToId: replyToId ?? (threadId != null && threadId !== "" ? String(threadId) : undefined),
threadId: null,
}),
},
messaging: {
normalizeTarget: normalizeSlackMessagingTarget,
enableInteractiveReplies: ({ cfg, accountId }) =>
isSlackInteractiveRepliesEnabled({ cfg, accountId }),
targetResolver: {
looksLikeId: looksLikeSlackTargetId,
hint: "<channelId|user:ID|channel:ID>",