




















@@ -15,6 +15,10 @@ import {
1515import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth";
1616import { hasControlCommand } from "openclaw/plugin-sdk/command-auth";
1717import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-auth";
18+import {
19+resolveRuntimeConversationBindingRoute,
20+type RuntimeConversationBindingRouteResult,
21+} from "openclaw/plugin-sdk/conversation-runtime";
1822import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
1923import { enqueueSystemEvent } from "openclaw/plugin-sdk/infra-runtime";
2024import {
@@ -106,6 +110,7 @@ type SlackAuthorizationContext = {
106110107111type SlackRoutingContext = {
108112route: ReturnType<typeof resolveAgentRoute>;
113+runtimeBinding: RuntimeConversationBindingRouteResult["bindingRecord"];
109114chatType: "direct" | "group" | "channel";
110115replyToMode: ReturnType<typeof resolveSlackReplyToMode>;
111116threadContext: ReturnType<typeof resolveSlackThreadContext>;
@@ -116,6 +121,15 @@ type SlackRoutingContext = {
116121historyKey: string;
117122};
118123124+function resolveSlackBaseConversationId(params: {
125+message: SlackMessageEvent;
126+isDirectMessage: boolean;
127+}): string {
128+return params.isDirectMessage
129+ ? `user:${params.message.user ?? "unknown"}`
130+ : params.message.channel;
131+}
132+119133async function resolveSlackConversationContext(params: {
120134ctx: SlackMonitorContext;
121135account: ResolvedSlackAccount;
@@ -272,7 +286,7 @@ function resolveSlackRoutingContext(params: {
272286isRoomish: boolean;
273287}): SlackRoutingContext {
274288const { ctx, account, message, isDirectMessage, isGroupDm, isRoom, isRoomish } = params;
275-const route = resolveAgentRoute({
289+let route = resolveAgentRoute({
276290cfg: ctx.cfg,
277291channel: "slack",
278292accountId: account.accountId,
@@ -302,17 +316,45 @@ function resolveSlackRoutingContext(params: {
302316// isolated sessions per message (regression from #10686).
303317const roomThreadId = isThreadReply && threadTs ? threadTs : undefined;
304318const canonicalThreadId = isRoomish ? roomThreadId : isThreadReply ? threadTs : autoThreadId;
305-const threadKeys = resolveThreadSessionKeys({
306-baseSessionKey: route.sessionKey,
307-threadId: canonicalThreadId,
308-parentSessionKey: canonicalThreadId && ctx.threadInheritParent ? route.sessionKey : undefined,
309-});
319+const baseConversationId = resolveSlackBaseConversationId({ message, isDirectMessage });
320+const boundThreadRoute = canonicalThreadId
321+ ? resolveRuntimeConversationBindingRoute({
322+ route,
323+conversation: {
324+channel: "slack",
325+accountId: account.accountId,
326+conversationId: canonicalThreadId,
327+parentConversationId: baseConversationId,
328+},
329+})
330+ : null;
331+const runtimeRoute =
332+boundThreadRoute?.boundSessionKey || boundThreadRoute?.bindingRecord
333+ ? boundThreadRoute
334+ : resolveRuntimeConversationBindingRoute({
335+ route,
336+conversation: {
337+channel: "slack",
338+accountId: account.accountId,
339+conversationId: baseConversationId,
340+},
341+});
342+route = runtimeRoute.route;
343+const threadKeys = runtimeRoute.boundSessionKey
344+ ? { sessionKey: route.sessionKey, parentSessionKey: undefined }
345+ : resolveThreadSessionKeys({
346+baseSessionKey: route.sessionKey,
347+threadId: canonicalThreadId,
348+parentSessionKey:
349+canonicalThreadId && ctx.threadInheritParent ? route.sessionKey : undefined,
350+});
310351const sessionKey = threadKeys.sessionKey;
311352const historyKey =
312353isThreadReply && ctx.threadHistoryScope === "thread" ? sessionKey : message.channel;
313354314355return {
315356 route,
357+runtimeBinding: runtimeRoute.bindingRecord,
316358 chatType,
317359 replyToMode,
318360 threadContext,
@@ -364,6 +406,7 @@ export async function prepareSlackMessage(params: {
364406});
365407const {
366408 route,
409+ runtimeBinding,
367410 replyToMode,
368411 threadContext,
369412 threadTs,
@@ -372,6 +415,11 @@ export async function prepareSlackMessage(params: {
372415 sessionKey,
373416 historyKey,
374417} = routing;
418+if (runtimeBinding && shouldLogVerbose()) {
419+logVerbose(
420+`slack: routed via bound conversation ${runtimeBinding.conversation.conversationId} -> ${runtimeBinding.targetSessionKey}`,
421+);
422+}
375423376424const mentionRegexes = resolveCachedMentionRegexes(ctx, route.agentId);
377425const hasAnyMention = /<@[^>]+>/.test(message.text ?? "");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。