feat(session): add dmScope for multi-user DM isolation
Co-authored-by: Alphonse-arianee <Alphonse-arianee@users.noreply.github.com>
This commit is contained in:
committed by
Peter Steinberger
parent
e6364d031d
commit
ca9688b5cc
@@ -18,6 +18,32 @@ describe("resolveAgentRoute", () => {
|
||||
expect(route.matchedBy).toBe("default");
|
||||
});
|
||||
|
||||
test("dmScope=per-peer isolates DM sessions by sender id", () => {
|
||||
const cfg: ClawdbotConfig = {
|
||||
session: { dmScope: "per-peer" },
|
||||
};
|
||||
const route = resolveAgentRoute({
|
||||
cfg,
|
||||
channel: "whatsapp",
|
||||
accountId: null,
|
||||
peer: { kind: "dm", id: "+15551234567" },
|
||||
});
|
||||
expect(route.sessionKey).toBe("agent:main:dm:+15551234567");
|
||||
});
|
||||
|
||||
test("dmScope=per-channel-peer isolates DM sessions per channel and sender", () => {
|
||||
const cfg: ClawdbotConfig = {
|
||||
session: { dmScope: "per-channel-peer" },
|
||||
};
|
||||
const route = resolveAgentRoute({
|
||||
cfg,
|
||||
channel: "whatsapp",
|
||||
accountId: null,
|
||||
peer: { kind: "dm", id: "+15551234567" },
|
||||
});
|
||||
expect(route.sessionKey).toBe("agent:main:whatsapp:dm:+15551234567");
|
||||
});
|
||||
|
||||
test("peer binding wins over account binding", () => {
|
||||
const cfg: ClawdbotConfig = {
|
||||
bindings: [
|
||||
|
||||
@@ -68,6 +68,8 @@ export function buildAgentSessionKey(params: {
|
||||
agentId: string;
|
||||
channel: string;
|
||||
peer?: RoutePeer | null;
|
||||
/** DM session scope. */
|
||||
dmScope?: "main" | "per-peer" | "per-channel-peer";
|
||||
}): string {
|
||||
const channel = normalizeToken(params.channel) || "unknown";
|
||||
const peer = params.peer;
|
||||
@@ -77,6 +79,7 @@ export function buildAgentSessionKey(params: {
|
||||
channel,
|
||||
peerKind: peer?.kind ?? "dm",
|
||||
peerId: peer ? normalizeId(peer.id) || "unknown" : null,
|
||||
dmScope: params.dmScope,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -149,6 +152,8 @@ export function resolveAgentRoute(input: ResolveAgentRouteInput): ResolvedAgentR
|
||||
return matchesAccountId(binding.match?.accountId, accountId);
|
||||
});
|
||||
|
||||
const dmScope = input.cfg.session?.dmScope ?? "main";
|
||||
|
||||
const choose = (agentId: string, matchedBy: ResolvedAgentRoute["matchedBy"]) => {
|
||||
const resolvedAgentId = pickFirstExistingAgentId(input.cfg, agentId);
|
||||
return {
|
||||
@@ -159,6 +164,7 @@ export function resolveAgentRoute(input: ResolveAgentRouteInput): ResolvedAgentR
|
||||
agentId: resolvedAgentId,
|
||||
channel,
|
||||
peer,
|
||||
dmScope,
|
||||
}),
|
||||
mainSessionKey: buildAgentMainSessionKey({
|
||||
agentId: resolvedAgentId,
|
||||
|
||||
@@ -88,9 +88,20 @@ export function buildAgentPeerSessionKey(params: {
|
||||
channel: string;
|
||||
peerKind?: "dm" | "group" | "channel" | null;
|
||||
peerId?: string | null;
|
||||
/** DM session scope. */
|
||||
dmScope?: "main" | "per-peer" | "per-channel-peer";
|
||||
}): string {
|
||||
const peerKind = params.peerKind ?? "dm";
|
||||
if (peerKind === "dm") {
|
||||
const dmScope = params.dmScope ?? "main";
|
||||
const peerId = (params.peerId ?? "").trim();
|
||||
if (dmScope === "per-channel-peer" && peerId) {
|
||||
const channel = (params.channel ?? "").trim().toLowerCase() || "unknown";
|
||||
return `agent:${normalizeAgentId(params.agentId)}:${channel}:dm:${peerId}`;
|
||||
}
|
||||
if (dmScope === "per-peer" && peerId) {
|
||||
return `agent:${normalizeAgentId(params.agentId)}:dm:${peerId}`;
|
||||
}
|
||||
return buildAgentMainSessionKey({
|
||||
agentId: params.agentId,
|
||||
mainKey: params.mainKey,
|
||||
|
||||
Reference in New Issue
Block a user