diff --git a/src/channels/conversation-binding-context.ts b/src/channels/conversation-binding-context.ts index 484fd0fc413..5136157ca43 100644 --- a/src/channels/conversation-binding-context.ts +++ b/src/channels/conversation-binding-context.ts @@ -12,14 +12,20 @@ export type ConversationBindingContext = { threadId?: string; }; -export type ResolveConversationBindingContextInput = ResolveCommandConversationResolutionInput & { +export type ResolveConversationBindingContextInput = Omit< + ResolveCommandConversationResolutionInput, + "includePlacementHint" +> & { cfg: OpenClawConfig; }; export function resolveConversationBindingContext( params: ResolveConversationBindingContextInput, ): ConversationBindingContext | null { - const resolution = resolveCommandConversationResolution(params); + const resolution = resolveCommandConversationResolution({ + ...params, + includePlacementHint: false, + }); if (!resolution) { return null; } diff --git a/src/channels/conversation-resolution.test.ts b/src/channels/conversation-resolution.test.ts index 3a1ae48a595..5016f4c51e2 100644 --- a/src/channels/conversation-resolution.test.ts +++ b/src/channels/conversation-resolution.test.ts @@ -77,6 +77,39 @@ describe("conversation resolution", () => { }); }); + it("can skip placement hints for callers that do not consume them", () => { + registerChannelPlugin({ + ...createChannelTestPluginBase({ + id: "discord", + label: "Discord", + }), + conversationBindings: { + supportsCurrentConversationBinding: true, + defaultTopLevelPlacement: "child", + }, + bindings: { + ...createBindingProviderDefaults(), + resolveCommandConversation: () => ({ conversationId: "channel:123" }), + }, + }); + + expect( + resolveCommandConversationResolution({ + cfg: testConfig, + channel: "discord", + originatingTo: "discord:channel:123", + includePlacementHint: false, + }), + ).toEqual({ + canonical: { + channel: "discord", + accountId: "default", + conversationId: "channel:123", + }, + source: "command-provider", + }); + }); + it("applies provider-owned self-parent defaults in one core path", () => { registerChannelPlugin({ ...createChannelTestPluginBase({ id: "line", label: "LINE" }), diff --git a/src/channels/conversation-resolution.ts b/src/channels/conversation-resolution.ts index 7c711b69ac0..1aa8b6f3944 100644 --- a/src/channels/conversation-resolution.ts +++ b/src/channels/conversation-resolution.ts @@ -53,6 +53,7 @@ export type ResolveCommandConversationResolutionInput = { fallbackTo?: string | null; from?: string | null; nativeChannelId?: string | null; + includePlacementHint?: boolean; }; export type ResolveInboundConversationResolutionInput = { @@ -114,6 +115,7 @@ function normalizeResolutionTarget(params: { source: ConversationResolutionSource; threadId?: string; plugin?: ChannelPlugin; + includePlacementHint?: boolean; }): ConversationResolution | null { const conversationId = normalizeOptionalString(params.conversation?.conversationId); if (!conversationId) { @@ -131,6 +133,10 @@ function normalizeResolutionTarget(params: { const normalizedParentConversationId = defaultParentToSelf ? normalized.conversationId : normalized.parentConversationId; + const placementHint = + params.includePlacementHint === false + ? undefined + : resolveChannelDefaultBindingPlacement(params.channel); return { canonical: { channel: params.channel, @@ -141,7 +147,7 @@ function normalizeResolutionTarget(params: { : {}), }, ...(params.threadId ? { threadId: params.threadId } : {}), - placementHint: resolveChannelDefaultBindingPlacement(params.channel), + ...(placementHint ? { placementHint } : {}), source: params.source, }; } @@ -273,6 +279,7 @@ export function resolveCommandConversationResolution( source: "command-provider", threadId, plugin, + includePlacementHint: params.includePlacementHint, }); if (providerResolution) { return providerResolution; @@ -297,6 +304,7 @@ export function resolveCommandConversationResolution( source: "focused-binding", threadId, plugin, + includePlacementHint: params.includePlacementHint, }); if (focusedResolution) { return focusedResolution; @@ -337,6 +345,7 @@ export function resolveCommandConversationResolution( source: "command-fallback", threadId, plugin, + includePlacementHint: params.includePlacementHint, }); }