diff --git a/.oxlintrc.json b/.oxlintrc.json index c077e1a1071..51ef3fbac41 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -25,7 +25,6 @@ "eslint/no-sequences": "error", "eslint/no-self-compare": "error", "eslint/no-shadow": "off", - "eslint/no-underscore-dangle": "off", "eslint/no-var": "error", "eslint/no-useless-call": "error", "eslint/no-useless-computed-key": "error", diff --git a/src/auto-reply/commands-registry.ts b/src/auto-reply/commands-registry.ts index 2f59c777382..314a31ffa67 100644 --- a/src/auto-reply/commands-registry.ts +++ b/src/auto-reply/commands-registry.ts @@ -6,17 +6,14 @@ import { import type { SkillCommandSpec } from "../agents/skills.js"; import { getChannelPlugin, getLoadedChannelPlugin } from "../channels/plugins/index.js"; import type { OpenClawConfig } from "../config/types.js"; -import { - normalizeLowercaseStringOrEmpty, - normalizeOptionalLowercaseString, -} from "../shared/string-coerce.js"; +import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js"; import { isCommandEnabled, listChatCommands, listChatCommandsForConfig, } from "./commands-registry-list.js"; import { normalizeCommandBody, resolveTextCommand } from "./commands-registry-normalize.js"; -import { getChatCommands, getNativeCommandSurfaces } from "./commands-registry.data.js"; +import { getChatCommands } from "./commands-registry.data.js"; import type { ChatCommandDefinition, CommandArgChoiceContext, @@ -27,7 +24,6 @@ import type { CommandDetection, CommandNormalizeOptions, NativeCommandSpec, - ShouldHandleTextCommandsParams, } from "./commands-registry.types.js"; import type { ThinkingCatalogEntry } from "./thinking.shared.js"; @@ -44,6 +40,8 @@ export { resolveTextCommand, } from "./commands-registry-normalize.js"; +export { isNativeCommandSurface, shouldHandleTextCommands } from "./commands-text-routing.js"; + export type { ChatCommandDefinition, CommandArgChoiceContext, @@ -371,20 +369,3 @@ export function isCommandMessage(raw: string): boolean { const trimmed = normalizeCommandBody(raw); return trimmed.startsWith("/"); } - -export function isNativeCommandSurface(surface?: string): boolean { - if (!surface) { - return false; - } - return getNativeCommandSurfaces().has(normalizeLowercaseStringOrEmpty(surface)); -} - -export function shouldHandleTextCommands(params: ShouldHandleTextCommandsParams): boolean { - if (params.commandSource === "native") { - return true; - } - if (params.cfg.commands?.text !== false) { - return true; - } - return !isNativeCommandSurface(params.surface); -} diff --git a/src/auto-reply/reply/dispatch-acp-command-bypass.ts b/src/auto-reply/reply/dispatch-acp-command-bypass.ts index 0399e9cf409..134713c3f16 100644 --- a/src/auto-reply/reply/dispatch-acp-command-bypass.ts +++ b/src/auto-reply/reply/dispatch-acp-command-bypass.ts @@ -1,9 +1,7 @@ import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { - isCommandEnabled, - maybeResolveTextAlias, - shouldHandleTextCommands, -} from "../commands-registry.js"; +import { isCommandEnabled } from "../commands-registry-list.js"; +import { maybeResolveTextAlias } from "../commands-registry-normalize.js"; +import { shouldHandleTextCommands } from "../commands-text-routing.js"; import type { FinalizedMsgContext } from "../templating.js"; function resolveFirstContextText( diff --git a/src/auto-reply/reply/dispatch-from-config.test.ts b/src/auto-reply/reply/dispatch-from-config.test.ts index a1edc20e0dc..5d82dfa6026 100644 --- a/src/auto-reply/reply/dispatch-from-config.test.ts +++ b/src/auto-reply/reply/dispatch-from-config.test.ts @@ -146,6 +146,9 @@ const ttsMocks = vi.hoisted(() => { resolveTtsConfig: vi.fn((_cfg: OpenClawConfig) => ({ mode: "final" })), }; }); +const transcriptMocks = vi.hoisted(() => ({ + persistAcpDispatchTranscript: vi.fn(async (_params: unknown) => undefined), +})); const replyMediaPathMocks = vi.hoisted(() => ({ createReplyMediaPathNormalizer: vi.fn( (_params?: unknown) => async (payload: ReplyPayload) => payload, @@ -473,6 +476,10 @@ vi.mock("../../tts/status-config.js", () => ({ vi.mock("./dispatch-acp-tts.runtime.js", () => ({ maybeApplyTtsToPayload: (params: unknown) => ttsMocks.maybeApplyTtsToPayload(params), })); +vi.mock("./dispatch-acp-transcript.runtime.js", () => ({ + persistAcpDispatchTranscript: (params: unknown) => + transcriptMocks.persistAcpDispatchTranscript(params), +})); vi.mock("./dispatch-acp-session.runtime.js", () => ({ readAcpSessionEntry: (params: { sessionKey: string; cfg?: OpenClawConfig }) => acpMocks.readAcpSessionEntry(params), @@ -794,6 +801,7 @@ describe("dispatchReplyFromConfig", () => { ttsMocks.resolveTtsConfig.mockReturnValue({ mode: "final", }); + transcriptMocks.persistAcpDispatchTranscript.mockClear(); replyMediaPathMocks.createReplyMediaPathNormalizer.mockReset(); replyMediaPathMocks.createReplyMediaPathNormalizer.mockReturnValue( async (payload: ReplyPayload) => payload, @@ -2798,7 +2806,7 @@ describe("dispatchReplyFromConfig", () => { RawBody: "who are you", Body: "who are you", MessageSid: "msg-claim-1", - SessionKey: "agent:main:telegram:group:-10099:77", + SessionKey: "agent:main:hook-test", }); const replyResolver = vi.fn(async () => ({ text: "core reply" }) satisfies ReplyPayload); @@ -2829,7 +2837,7 @@ describe("dispatchReplyFromConfig", () => { expect.objectContaining({ type: "message", action: "received", - sessionKey: "agent:main:telegram:group:-10099:77", + sessionKey: "agent:main:hook-test", }), ); expect(replyResolver).toHaveBeenCalledTimes(1); diff --git a/src/plugin-sdk/command-surface.ts b/src/plugin-sdk/command-surface.ts index 552e6f47ba6..553a3010838 100644 --- a/src/plugin-sdk/command-surface.ts +++ b/src/plugin-sdk/command-surface.ts @@ -1 +1,2 @@ -export { normalizeCommandBody, shouldHandleTextCommands } from "../auto-reply/commands-registry.js"; +export { normalizeCommandBody } from "../auto-reply/commands-registry-normalize.js"; +export { shouldHandleTextCommands } from "../auto-reply/commands-text-routing.js";