From 7fd7f6f355916ef1dbe3b5f0176a80ef44157a50 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Wed, 6 May 2026 02:06:40 -0700 Subject: [PATCH] fix(gateway): mark chat slash commands as text --- .../chat.directive-tags.test.ts | 22 +++++++++++++++++++ src/gateway/server-methods/chat.ts | 2 ++ 2 files changed, 24 insertions(+) diff --git a/src/gateway/server-methods/chat.directive-tags.test.ts b/src/gateway/server-methods/chat.directive-tags.test.ts index 72b69c582d7..a1d076ee1a4 100644 --- a/src/gateway/server-methods/chat.directive-tags.test.ts +++ b/src/gateway/server-methods/chat.directive-tags.test.ts @@ -1173,6 +1173,28 @@ describe("chat directive tag stripping for non-streaming final payloads", () => ); }); + it("chat.send marks user slash commands as text command sources", async () => { + createTranscriptFixture("openclaw-chat-send-text-command-source-"); + mockState.finalText = "ok"; + const respond = vi.fn(); + const context = createChatContext(); + + await runNonStreamingChatSend({ + context, + respond, + idempotencyKey: "idem-text-command-source", + message: "/codex status", + expectBroadcast: false, + }); + + expect(mockState.lastDispatchCtx).toEqual( + expect.objectContaining({ + BodyForCommands: "/codex status", + CommandSource: "text", + }), + ); + }); + it("chat.send keeps explicit delivery routes for Feishu channel-scoped sessions", async () => { createTranscriptFixture("openclaw-chat-send-feishu-origin-routing-"); mockState.finalText = "ok"; diff --git a/src/gateway/server-methods/chat.ts b/src/gateway/server-methods/chat.ts index 8f2575532fb..e04cd5b7a6b 100644 --- a/src/gateway/server-methods/chat.ts +++ b/src/gateway/server-methods/chat.ts @@ -2195,6 +2195,7 @@ export const chatHandlers: GatewayRequestHandlers = { p.thinking && trimmedMessage && !trimmedMessage.startsWith("/"), ); const commandBody = injectThinking ? `/think ${p.thinking} ${parsedMessage}` : parsedMessage; + const commandSource = trimmedMessage.startsWith("/") ? "text" : undefined; const messageForAgent = systemProvenanceReceipt ? [systemProvenanceReceipt, parsedMessage].filter(Boolean).join("\n\n") : parsedMessage; @@ -2226,6 +2227,7 @@ export const chatHandlers: GatewayRequestHandlers = { AccountId: accountId, MessageThreadId: messageThreadId, ChatType: "direct", + ...(commandSource ? { CommandSource: commandSource } : {}), CommandAuthorized: true, MessageSid: clientRunId, SenderId: clientInfo?.id,