130 lines
4.4 KiB
TypeScript
130 lines
4.4 KiB
TypeScript
import {
|
|
CHANNEL_IDS,
|
|
listChatChannelAliases,
|
|
normalizeChatChannelId,
|
|
} from "../channels/registry.js";
|
|
import type { ChannelId } from "../channels/plugins/types.js";
|
|
import {
|
|
GATEWAY_CLIENT_MODES,
|
|
GATEWAY_CLIENT_NAMES,
|
|
type GatewayClientMode,
|
|
type GatewayClientName,
|
|
normalizeGatewayClientMode,
|
|
normalizeGatewayClientName,
|
|
} from "../gateway/protocol/client-info.js";
|
|
import { getActivePluginRegistry } from "../plugins/runtime.js";
|
|
|
|
export const INTERNAL_MESSAGE_CHANNEL = "webchat" as const;
|
|
export type InternalMessageChannel = typeof INTERNAL_MESSAGE_CHANNEL;
|
|
|
|
const MARKDOWN_CAPABLE_CHANNELS = new Set<string>([
|
|
"slack",
|
|
"telegram",
|
|
"signal",
|
|
"discord",
|
|
"tui",
|
|
INTERNAL_MESSAGE_CHANNEL,
|
|
]);
|
|
|
|
export { GATEWAY_CLIENT_NAMES, GATEWAY_CLIENT_MODES };
|
|
export type { GatewayClientName, GatewayClientMode };
|
|
export { normalizeGatewayClientName, normalizeGatewayClientMode };
|
|
|
|
type GatewayClientInfoLike = {
|
|
mode?: string | null;
|
|
id?: string | null;
|
|
};
|
|
|
|
export function isGatewayCliClient(client?: GatewayClientInfoLike | null): boolean {
|
|
return normalizeGatewayClientMode(client?.mode) === GATEWAY_CLIENT_MODES.CLI;
|
|
}
|
|
|
|
export function isInternalMessageChannel(raw?: string | null): raw is InternalMessageChannel {
|
|
return normalizeMessageChannel(raw) === INTERNAL_MESSAGE_CHANNEL;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
export function normalizeMessageChannel(raw?: string | null): string | undefined {
|
|
const normalized = raw?.trim().toLowerCase();
|
|
if (!normalized) return undefined;
|
|
if (normalized === INTERNAL_MESSAGE_CHANNEL) return INTERNAL_MESSAGE_CHANNEL;
|
|
const builtIn = normalizeChatChannelId(normalized);
|
|
if (builtIn) return builtIn;
|
|
const registry = getActivePluginRegistry();
|
|
const pluginMatch = registry?.channels.find((entry) => {
|
|
if (entry.plugin.id.toLowerCase() === normalized) return true;
|
|
return (entry.plugin.meta.aliases ?? []).some(
|
|
(alias) => alias.trim().toLowerCase() === normalized,
|
|
);
|
|
});
|
|
return pluginMatch?.plugin.id ?? normalized;
|
|
}
|
|
|
|
const listPluginChannelIds = (): string[] => {
|
|
const registry = getActivePluginRegistry();
|
|
if (!registry) return [];
|
|
return registry.channels.map((entry) => entry.plugin.id);
|
|
};
|
|
|
|
const listPluginChannelAliases = (): string[] => {
|
|
const registry = getActivePluginRegistry();
|
|
if (!registry) return [];
|
|
return registry.channels.flatMap((entry) => entry.plugin.meta.aliases ?? []);
|
|
};
|
|
|
|
export const listDeliverableMessageChannels = (): ChannelId[] =>
|
|
Array.from(new Set([...CHANNEL_IDS, ...listPluginChannelIds()]));
|
|
|
|
export type DeliverableMessageChannel = ChannelId;
|
|
|
|
export type GatewayMessageChannel = DeliverableMessageChannel | InternalMessageChannel;
|
|
|
|
export const listGatewayMessageChannels = (): GatewayMessageChannel[] => [
|
|
...listDeliverableMessageChannels(),
|
|
INTERNAL_MESSAGE_CHANNEL,
|
|
];
|
|
|
|
export const listGatewayAgentChannelAliases = (): string[] =>
|
|
Array.from(new Set([...listChatChannelAliases(), ...listPluginChannelAliases()]));
|
|
|
|
export type GatewayAgentChannelHint = GatewayMessageChannel | "last";
|
|
|
|
export const listGatewayAgentChannelValues = (): string[] =>
|
|
Array.from(
|
|
new Set([...listGatewayMessageChannels(), "last", ...listGatewayAgentChannelAliases()]),
|
|
);
|
|
|
|
export function isGatewayMessageChannel(value: string): value is GatewayMessageChannel {
|
|
return listGatewayMessageChannels().includes(value as GatewayMessageChannel);
|
|
}
|
|
|
|
export function isDeliverableMessageChannel(value: string): value is DeliverableMessageChannel {
|
|
return listDeliverableMessageChannels().includes(value as DeliverableMessageChannel);
|
|
}
|
|
|
|
export function resolveGatewayMessageChannel(
|
|
raw?: string | null,
|
|
): GatewayMessageChannel | undefined {
|
|
const normalized = normalizeMessageChannel(raw);
|
|
if (!normalized) return undefined;
|
|
return isGatewayMessageChannel(normalized) ? normalized : undefined;
|
|
}
|
|
|
|
export function resolveMessageChannel(
|
|
primary?: string | null,
|
|
fallback?: string | null,
|
|
): string | undefined {
|
|
return normalizeMessageChannel(primary) ?? normalizeMessageChannel(fallback);
|
|
}
|
|
|
|
export function isMarkdownCapableMessageChannel(raw?: string | null): boolean {
|
|
const channel = normalizeMessageChannel(raw);
|
|
if (!channel) return false;
|
|
return MARKDOWN_CAPABLE_CHANNELS.has(channel);
|
|
}
|