mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-18 22:57:28 +00:00
refactor: unify peer kind to ChatType, rename dm to direct (#11881)
* fix: use .js extension for ESM imports of RoutePeerKind
The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.
* fix tsconfig
* refactor: unify peer kind to ChatType, rename dm to direct
- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType
BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.
* fix tests
* test: update session key expectations for dmdirect migration
- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat
* fix: accept legacy 'dm' in session key parsing for backward compat
getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.
* test: add explicit backward compat tests for dmdirect migration
- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work
* feat: backward compat for resetByType.dm config key
* test: skip unix-path Nix tests on Windows
This commit is contained in:
@@ -1804,7 +1804,7 @@ async function processMessage(
|
||||
channel: "bluebubbles",
|
||||
accountId: account.accountId,
|
||||
peer: {
|
||||
kind: isGroup ? "group" : "dm",
|
||||
kind: isGroup ? "group" : "direct",
|
||||
id: peerId,
|
||||
},
|
||||
});
|
||||
@@ -2442,7 +2442,7 @@ async function processReaction(
|
||||
channel: "bluebubbles",
|
||||
accountId: account.accountId,
|
||||
peer: {
|
||||
kind: reaction.isGroup ? "group" : "dm",
|
||||
kind: reaction.isGroup ? "group" : "direct",
|
||||
id: peerId,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -652,7 +652,7 @@ export async function handleFeishuMessage(params: {
|
||||
channel: "feishu",
|
||||
accountId: account.accountId,
|
||||
peer: {
|
||||
kind: isGroup ? "group" : "dm",
|
||||
kind: isGroup ? "group" : "direct",
|
||||
id: isGroup ? ctx.chatId : ctx.senderOpenId,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -615,7 +615,7 @@ async function processMessageWithPipeline(params: {
|
||||
channel: "googlechat",
|
||||
accountId: account.accountId,
|
||||
peer: {
|
||||
kind: isGroup ? "group" : "dm",
|
||||
kind: isGroup ? "group" : "direct",
|
||||
id: spaceId,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -453,7 +453,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
|
||||
cfg,
|
||||
channel: "matrix",
|
||||
peer: {
|
||||
kind: isDirectMessage ? "dm" : "channel",
|
||||
kind: isDirectMessage ? "direct" : "channel",
|
||||
id: isDirectMessage ? senderId : roomId,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type {
|
||||
ChannelAccountSnapshot,
|
||||
ChatType,
|
||||
OpenClawConfig,
|
||||
ReplyPayload,
|
||||
RuntimeEnv,
|
||||
@@ -131,13 +132,13 @@ function isSystemPost(post: MattermostPost): boolean {
|
||||
return Boolean(type);
|
||||
}
|
||||
|
||||
function channelKind(channelType?: string | null): "dm" | "group" | "channel" {
|
||||
function channelKind(channelType?: string | null): ChatType {
|
||||
if (!channelType) {
|
||||
return "channel";
|
||||
}
|
||||
const normalized = channelType.trim().toUpperCase();
|
||||
if (normalized === "D") {
|
||||
return "dm";
|
||||
return "direct";
|
||||
}
|
||||
if (normalized === "G") {
|
||||
return "group";
|
||||
@@ -145,8 +146,8 @@ function channelKind(channelType?: string | null): "dm" | "group" | "channel" {
|
||||
return "channel";
|
||||
}
|
||||
|
||||
function channelChatType(kind: "dm" | "group" | "channel"): "direct" | "group" | "channel" {
|
||||
if (kind === "dm") {
|
||||
function channelChatType(kind: ChatType): "direct" | "group" | "channel" {
|
||||
if (kind === "direct") {
|
||||
return "direct";
|
||||
}
|
||||
if (kind === "group") {
|
||||
@@ -469,11 +470,11 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
hasControlCommand,
|
||||
});
|
||||
const commandAuthorized =
|
||||
kind === "dm"
|
||||
kind === "direct"
|
||||
? dmPolicy === "open" || senderAllowedForCommands
|
||||
: commandGate.commandAuthorized;
|
||||
|
||||
if (kind === "dm") {
|
||||
if (kind === "direct") {
|
||||
if (dmPolicy === "disabled") {
|
||||
logVerboseMessage(`mattermost: drop dm (dmPolicy=disabled sender=${senderId})`);
|
||||
return;
|
||||
@@ -524,7 +525,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
}
|
||||
}
|
||||
|
||||
if (kind !== "dm" && commandGate.shouldBlock) {
|
||||
if (kind !== "direct" && commandGate.shouldBlock) {
|
||||
logInboundDrop({
|
||||
log: logVerboseMessage,
|
||||
channel: "mattermost",
|
||||
@@ -547,7 +548,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
teamId,
|
||||
peer: {
|
||||
kind,
|
||||
id: kind === "dm" ? senderId : channelId,
|
||||
id: kind === "direct" ? senderId : channelId,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -559,11 +560,11 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
parentSessionKey: threadRootId ? baseSessionKey : undefined,
|
||||
});
|
||||
const sessionKey = threadKeys.sessionKey;
|
||||
const historyKey = kind === "dm" ? null : sessionKey;
|
||||
const historyKey = kind === "direct" ? null : sessionKey;
|
||||
|
||||
const mentionRegexes = core.channel.mentions.buildMentionRegexes(cfg, route.agentId);
|
||||
const wasMentioned =
|
||||
kind !== "dm" &&
|
||||
kind !== "direct" &&
|
||||
((botUsername ? rawText.toLowerCase().includes(`@${botUsername.toLowerCase()}`) : false) ||
|
||||
core.channel.mentions.matchesMentionPatterns(rawText, mentionRegexes));
|
||||
const pendingBody =
|
||||
@@ -590,7 +591,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
});
|
||||
};
|
||||
|
||||
const oncharEnabled = account.chatmode === "onchar" && kind !== "dm";
|
||||
const oncharEnabled = account.chatmode === "onchar" && kind !== "direct";
|
||||
const oncharPrefixes = oncharEnabled ? resolveOncharPrefixes(account.oncharPrefixes) : [];
|
||||
const oncharResult = oncharEnabled
|
||||
? stripOncharPrefix(rawText, oncharPrefixes)
|
||||
@@ -598,7 +599,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
const oncharTriggered = oncharResult.triggered;
|
||||
|
||||
const shouldRequireMention =
|
||||
kind !== "dm" &&
|
||||
kind !== "direct" &&
|
||||
core.channel.groups.resolveRequireMention({
|
||||
cfg,
|
||||
channel: "mattermost",
|
||||
@@ -615,7 +616,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
return;
|
||||
}
|
||||
|
||||
if (kind !== "dm" && shouldRequireMention && canDetectMention) {
|
||||
if (kind !== "direct" && shouldRequireMention && canDetectMention) {
|
||||
if (!effectiveWasMentioned) {
|
||||
recordPendingHistory();
|
||||
return;
|
||||
@@ -637,7 +638,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
});
|
||||
|
||||
const fromLabel = formatInboundFromLabel({
|
||||
isGroup: kind !== "dm",
|
||||
isGroup: kind !== "direct",
|
||||
groupLabel: channelDisplay || roomLabel,
|
||||
groupId: channelId,
|
||||
groupFallback: roomLabel || "Channel",
|
||||
@@ -647,7 +648,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
|
||||
const preview = bodyText.replace(/\s+/g, " ").slice(0, 160);
|
||||
const inboundLabel =
|
||||
kind === "dm"
|
||||
kind === "direct"
|
||||
? `Mattermost DM from ${senderName}`
|
||||
: `Mattermost message in ${roomLabel} from ${senderName}`;
|
||||
core.system.enqueueSystemEvent(`${inboundLabel}: ${preview}`, {
|
||||
@@ -685,14 +686,14 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
});
|
||||
}
|
||||
|
||||
const to = kind === "dm" ? `user:${senderId}` : `channel:${channelId}`;
|
||||
const to = kind === "direct" ? `user:${senderId}` : `channel:${channelId}`;
|
||||
const mediaPayload = buildMattermostMediaPayload(mediaList);
|
||||
const ctxPayload = core.channel.reply.finalizeInboundContext({
|
||||
Body: combinedBody,
|
||||
RawBody: bodyText,
|
||||
CommandBody: bodyText,
|
||||
From:
|
||||
kind === "dm"
|
||||
kind === "direct"
|
||||
? `mattermost:${senderId}`
|
||||
: kind === "group"
|
||||
? `mattermost:group:${channelId}`
|
||||
@@ -703,7 +704,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
AccountId: route.accountId,
|
||||
ChatType: chatType,
|
||||
ConversationLabel: fromLabel,
|
||||
GroupSubject: kind !== "dm" ? channelDisplay || roomLabel : undefined,
|
||||
GroupSubject: kind !== "direct" ? channelDisplay || roomLabel : undefined,
|
||||
GroupChannel: channelName ? `#${channelName}` : undefined,
|
||||
GroupSpace: teamId,
|
||||
SenderName: senderName,
|
||||
@@ -718,14 +719,14 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
ReplyToId: threadRootId,
|
||||
MessageThreadId: threadRootId,
|
||||
Timestamp: typeof post.create_at === "number" ? post.create_at : undefined,
|
||||
WasMentioned: kind !== "dm" ? effectiveWasMentioned : undefined,
|
||||
WasMentioned: kind !== "direct" ? effectiveWasMentioned : undefined,
|
||||
CommandAuthorized: commandAuthorized,
|
||||
OriginatingChannel: "mattermost" as const,
|
||||
OriginatingTo: to,
|
||||
...mediaPayload,
|
||||
});
|
||||
|
||||
if (kind === "dm") {
|
||||
if (kind === "direct") {
|
||||
const sessionCfg = cfg.session;
|
||||
const storePath = core.channel.session.resolveStorePath(sessionCfg?.store, {
|
||||
agentId: route.agentId,
|
||||
|
||||
@@ -342,7 +342,7 @@ export function createMSTeamsMessageHandler(deps: MSTeamsMessageHandlerDeps) {
|
||||
cfg,
|
||||
channel: "msteams",
|
||||
peer: {
|
||||
kind: isDirectMessage ? "dm" : isChannel ? "channel" : "group",
|
||||
kind: isDirectMessage ? "direct" : isChannel ? "channel" : "group",
|
||||
id: isDirectMessage ? senderId : conversationId,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -228,7 +228,7 @@ export async function handleNextcloudTalkInbound(params: {
|
||||
channel: CHANNEL_ID,
|
||||
accountId: account.accountId,
|
||||
peer: {
|
||||
kind: isGroup ? "group" : "dm",
|
||||
kind: isGroup ? "group" : "direct",
|
||||
id: isGroup ? roomToken : senderId,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -101,7 +101,7 @@ const tlonOutbound: ChannelOutboundAdapter = {
|
||||
error: new Error(`Invalid Tlon target. Use ${formatTargetHint()}`),
|
||||
};
|
||||
}
|
||||
if (parsed.kind === "dm") {
|
||||
if (parsed.kind === "direct") {
|
||||
return { ok: true, to: parsed.ship };
|
||||
}
|
||||
return { ok: true, to: parsed.nest };
|
||||
@@ -127,7 +127,7 @@ const tlonOutbound: ChannelOutboundAdapter = {
|
||||
|
||||
try {
|
||||
const fromShip = normalizeShip(account.ship);
|
||||
if (parsed.kind === "dm") {
|
||||
if (parsed.kind === "direct") {
|
||||
return await sendDm({
|
||||
api,
|
||||
fromShip,
|
||||
@@ -298,7 +298,7 @@ export const tlonPlugin: ChannelPlugin = {
|
||||
if (!parsed) {
|
||||
return target.trim();
|
||||
}
|
||||
if (parsed.kind === "dm") {
|
||||
if (parsed.kind === "direct") {
|
||||
return parsed.ship;
|
||||
}
|
||||
return parsed.nest;
|
||||
|
||||
@@ -343,7 +343,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
|
||||
channel: "tlon",
|
||||
accountId: opts.accountId ?? undefined,
|
||||
peer: {
|
||||
kind: isGroup ? "group" : "dm",
|
||||
kind: isGroup ? "group" : "direct",
|
||||
id: isGroup ? (groupChannel ?? senderShip) : senderShip,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export type TlonTarget =
|
||||
| { kind: "dm"; ship: string }
|
||||
| { kind: "direct"; ship: string }
|
||||
| { kind: "group"; nest: string; hostShip: string; channelName: string };
|
||||
|
||||
const SHIP_RE = /^~?[a-z-]+$/i;
|
||||
@@ -32,7 +32,7 @@ export function parseTlonTarget(raw?: string | null): TlonTarget | null {
|
||||
|
||||
const dmPrefix = withoutPrefix.match(/^dm[/:](.+)$/i);
|
||||
if (dmPrefix) {
|
||||
return { kind: "dm", ship: normalizeShip(dmPrefix[1]) };
|
||||
return { kind: "direct", ship: normalizeShip(dmPrefix[1]) };
|
||||
}
|
||||
|
||||
const groupPrefix = withoutPrefix.match(/^(group|room)[/:](.+)$/i);
|
||||
@@ -78,7 +78,7 @@ export function parseTlonTarget(raw?: string | null): TlonTarget | null {
|
||||
}
|
||||
|
||||
if (SHIP_RE.test(withoutPrefix)) {
|
||||
return { kind: "dm", ship: normalizeShip(withoutPrefix) };
|
||||
return { kind: "direct", ship: normalizeShip(withoutPrefix) };
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -515,7 +515,7 @@ async function processMessageWithPipeline(params: {
|
||||
channel: "zalo",
|
||||
accountId: account.accountId,
|
||||
peer: {
|
||||
kind: isGroup ? "group" : "dm",
|
||||
kind: isGroup ? "group" : "direct",
|
||||
id: chatId,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user