mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 03:45:46 -06:00
139 lines
5.0 KiB
TypeScript
139 lines
5.0 KiB
TypeScript
// Message channel helpers classify and format channel identifiers.
|
|
import {
|
|
GATEWAY_CLIENT_MODES,
|
|
GATEWAY_CLIENT_NAMES,
|
|
type GatewayClientMode,
|
|
type GatewayClientName,
|
|
normalizeGatewayClientMode,
|
|
normalizeGatewayClientName,
|
|
} from "../../packages/gateway-protocol/src/client-info.js";
|
|
import { listBundledChannelCatalogEntries } from "../channels/bundled-channel-catalog-read.js";
|
|
import { findChatChannelMeta } from "../channels/chat-meta.js";
|
|
import { getRegisteredChannelPluginMeta, normalizeChatChannelId } from "../channels/registry.js";
|
|
export {
|
|
isDeliverableMessageChannel,
|
|
isGatewayMessageChannel,
|
|
listDeliverableMessageChannels,
|
|
normalizeMessageChannel,
|
|
resolveGatewayMessageChannel,
|
|
resolveMessageChannel,
|
|
} from "./message-channel-normalize.js";
|
|
export {
|
|
INTERNAL_MESSAGE_CHANNEL,
|
|
isInternalNonDeliveryChannel,
|
|
} from "./message-channel-constants.js";
|
|
import { INTERNAL_MESSAGE_CHANNEL } from "./message-channel-constants.js";
|
|
import { normalizeMessageChannel } from "./message-channel-normalize.js";
|
|
|
|
/**
|
|
* Message channel and Gateway client classification helpers.
|
|
*
|
|
* This module keeps channel normalization, client identity checks, and markdown
|
|
* capability lookup in one place for send/render decisions.
|
|
*/
|
|
export { GATEWAY_CLIENT_NAMES, GATEWAY_CLIENT_MODES };
|
|
export type { GatewayClientName, GatewayClientMode };
|
|
|
|
type GatewayClientInfoLike = {
|
|
mode?: string | null;
|
|
id?: string | null;
|
|
};
|
|
|
|
/** Return whether a Gateway client is the CLI transport. */
|
|
export function isGatewayCliClient(client?: GatewayClientInfoLike | null): boolean {
|
|
return normalizeGatewayClientMode(client?.mode) === GATEWAY_CLIENT_MODES.CLI;
|
|
}
|
|
|
|
/**
|
|
* Return whether a Gateway client is an ephemeral control-plane connection.
|
|
* Test-mode clients stay excluded from this list: suites use them as stand-ins
|
|
* for real clients and assert presence propagation through the full pipeline.
|
|
*/
|
|
export function isEphemeralGatewayClient(client?: GatewayClientInfoLike | null): boolean {
|
|
const mode = normalizeGatewayClientMode(client?.mode);
|
|
return (
|
|
mode === GATEWAY_CLIENT_MODES.CLI ||
|
|
mode === GATEWAY_CLIENT_MODES.BACKEND ||
|
|
mode === GATEWAY_CLIENT_MODES.PROBE
|
|
);
|
|
}
|
|
|
|
/** Return whether a client is one of the operator UI clients. */
|
|
export function isOperatorUiClient(client?: GatewayClientInfoLike | null): boolean {
|
|
const clientId = normalizeGatewayClientName(client?.id);
|
|
return (
|
|
clientId === GATEWAY_CLIENT_NAMES.CONTROL_UI ||
|
|
clientId === GATEWAY_CLIENT_NAMES.BROWSER_COPILOT ||
|
|
clientId === GATEWAY_CLIENT_NAMES.TUI
|
|
);
|
|
}
|
|
|
|
/** Return whether a client is the browser Control UI. */
|
|
export function isBrowserOperatorUiClient(client?: GatewayClientInfoLike | null): boolean {
|
|
const clientId = normalizeGatewayClientName(client?.id);
|
|
return (
|
|
clientId === GATEWAY_CLIENT_NAMES.CONTROL_UI ||
|
|
clientId === GATEWAY_CLIENT_NAMES.BROWSER_COPILOT
|
|
);
|
|
}
|
|
|
|
/** Return whether a client is the first-party browser side-panel copilot. */
|
|
export function isBrowserCopilotClient(client?: GatewayClientInfoLike | null): boolean {
|
|
return normalizeGatewayClientName(client?.id) === GATEWAY_CLIENT_NAMES.BROWSER_COPILOT;
|
|
}
|
|
|
|
/** Return whether a raw channel id resolves to OpenClaw's internal channel. */
|
|
export function isInternalMessageChannel(
|
|
raw?: string | null,
|
|
): raw is typeof INTERNAL_MESSAGE_CHANNEL {
|
|
return normalizeMessageChannel(raw) === INTERNAL_MESSAGE_CHANNEL;
|
|
}
|
|
|
|
/** Return whether a channel can resolve exec approvals in the originating chat. */
|
|
export function isNativeApprovalChannel(value?: string | null): boolean {
|
|
if (!value) {
|
|
return false;
|
|
}
|
|
if (value === INTERNAL_MESSAGE_CHANNEL) {
|
|
return true;
|
|
}
|
|
return listBundledChannelCatalogEntries().some(
|
|
(entry) => entry.id === value && entry.channel.approvalFlags?.includes("native"),
|
|
);
|
|
}
|
|
|
|
/** Return whether a Gateway client is the public webchat surface. */
|
|
export function isWebchatClient(client?: GatewayClientInfoLike | null): boolean {
|
|
const mode = normalizeGatewayClientMode(client?.mode);
|
|
if (mode === GATEWAY_CLIENT_MODES.WEBCHAT) {
|
|
return true;
|
|
}
|
|
return normalizeGatewayClientName(client?.id) === GATEWAY_CLIENT_NAMES.WEBCHAT_UI;
|
|
}
|
|
|
|
/** Resolve whether a channel can receive markdown without plain-text downgrade. */
|
|
export function isMarkdownCapableMessageChannel(raw?: string | null): boolean {
|
|
const channel = normalizeMessageChannel(raw);
|
|
if (!channel) {
|
|
return false;
|
|
}
|
|
if (channel === INTERNAL_MESSAGE_CHANNEL || channel === "tui") {
|
|
return true;
|
|
}
|
|
const builtInChannel = normalizeChatChannelId(channel);
|
|
if (builtInChannel) {
|
|
const builtInMeta = findChatChannelMeta(builtInChannel);
|
|
if (builtInMeta) {
|
|
return builtInMeta.markdownCapable === true;
|
|
}
|
|
// Catalog metadata covers bundled channels whose runtime plugin is not loaded yet.
|
|
const catalogMeta = listBundledChannelCatalogEntries().find(
|
|
(entry) => entry.id === builtInChannel,
|
|
);
|
|
if (catalogMeta) {
|
|
return catalogMeta.channel.markdownCapable === true;
|
|
}
|
|
}
|
|
return getRegisteredChannelPluginMeta(channel)?.markdownCapable === true;
|
|
}
|