openclaw / src /auto-reply /command-turn-detection.ts
SaylorTwift's picture
SaylorTwift HF Staff
Add files using upload-large-folder tool
76289e7 verified
Raw History Blame Contribute Delete
2.04 kB
/** Fallback command-turn detection for mixed native/text channel metadata. */
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { isControlCommandMessage } from "./command-detection.js";
import {
isExplicitCommandTurn,
resolveCommandBody,
resolveCommandTurnContext,
type CommandTurnContextInput,
} from "./command-turn-context.js";
function resolveVisibleMessageBody(input: CommandTurnContextInput): string | undefined {
if (typeof input.rawText === "string") {
return input.rawText;
}
return normalizeOptionalString(input.RawBody) ?? normalizeOptionalString(input.Body);
}
function resolveStructuredNormalFallbackBody(input: CommandTurnContextInput): string | undefined {
const visibleBody = resolveVisibleMessageBody(input);
if (!/^[!/]/.test(visibleBody ?? "")) {
return undefined;
}
// Structured normal turns may carry a command-only body hidden from the visible message text.
return resolveCommandBody(input) ?? visibleBody;
}
function hasCommandSourceMetadata(input: CommandTurnContextInput): boolean {
return (
input.CommandSource === "native" ||
input.CommandSource === "text" ||
input.CommandSource === "message"
);
}
/** Returns true when inbound metadata or command text identifies an explicit command turn. */
export function isExplicitCommandTurnContext(
input: CommandTurnContextInput,
cfg: OpenClawConfig,
): boolean {
if (isExplicitCommandTurn(resolveCommandTurnContext(input))) {
return true;
}
if (input.CommandSource === "native" || input.CommandSource === "text") {
return false;
}
const fallbackBody =
input.CommandTurn !== undefined || hasCommandSourceMetadata(input)
? resolveStructuredNormalFallbackBody(input)
: resolveCommandBody(input);
return (
input.CommandAuthorized === true &&
isControlCommandMessage(fallbackBody, cfg, {
botUsername: normalizeOptionalString(input.BotUsername),
})
);
}