mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-05 22:32:12 +00:00
fix(control-ui): keep session key helpers browser-safe
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { deriveSessionChatType } from "../sessions/session-chat-type.js";
|
||||
import {
|
||||
deriveSessionChatType,
|
||||
getSubagentDepth,
|
||||
isCronSessionKey,
|
||||
parseThreadSessionSuffix,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { normalizeChatType } from "../channels/chat-type.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { SessionChatType, SessionEntry } from "../config/sessions.js";
|
||||
import { deriveSessionChatType } from "./session-key-utils.js";
|
||||
import { deriveSessionChatType } from "./session-chat-type.js";
|
||||
|
||||
export type SessionSendPolicyDecision = "allow" | "deny";
|
||||
|
||||
|
||||
62
src/sessions/session-chat-type.ts
Normal file
62
src/sessions/session-chat-type.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { getBundledChannelContractSurfaces } from "../channels/plugins/contract-surfaces.js";
|
||||
import { parseAgentSessionKey } from "./session-key-utils.js";
|
||||
|
||||
export type SessionKeyChatType = "direct" | "group" | "channel" | "unknown";
|
||||
|
||||
type LegacySessionChatTypeSurface = {
|
||||
deriveLegacySessionChatType?: (sessionKey: string) => "direct" | "group" | "channel" | undefined;
|
||||
};
|
||||
|
||||
function listLegacySessionChatTypeSurfaces(): LegacySessionChatTypeSurface[] {
|
||||
return getBundledChannelContractSurfaces() as LegacySessionChatTypeSurface[];
|
||||
}
|
||||
|
||||
function deriveBuiltInLegacySessionChatType(
|
||||
scopedSessionKey: string,
|
||||
): SessionKeyChatType | undefined {
|
||||
if (/^group:[^:]+$/.test(scopedSessionKey)) {
|
||||
return "group";
|
||||
}
|
||||
if (/^[0-9]+(?:-[0-9]+)*@g\.us$/.test(scopedSessionKey)) {
|
||||
return "group";
|
||||
}
|
||||
if (/^whatsapp:(?!.*:group:).+@g\.us$/.test(scopedSessionKey)) {
|
||||
return "group";
|
||||
}
|
||||
if (/^discord:(?:[^:]+:)?guild-[^:]+:channel-[^:]+$/.test(scopedSessionKey)) {
|
||||
return "channel";
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Best-effort chat-type extraction from session keys across canonical and legacy formats.
|
||||
*/
|
||||
export function deriveSessionChatType(sessionKey: string | undefined | null): SessionKeyChatType {
|
||||
const raw = (sessionKey ?? "").trim().toLowerCase();
|
||||
if (!raw) {
|
||||
return "unknown";
|
||||
}
|
||||
const scoped = parseAgentSessionKey(raw)?.rest ?? raw;
|
||||
const tokens = new Set(scoped.split(":").filter(Boolean));
|
||||
if (tokens.has("group")) {
|
||||
return "group";
|
||||
}
|
||||
if (tokens.has("channel")) {
|
||||
return "channel";
|
||||
}
|
||||
if (tokens.has("direct") || tokens.has("dm")) {
|
||||
return "direct";
|
||||
}
|
||||
const builtInLegacy = deriveBuiltInLegacySessionChatType(scoped);
|
||||
if (builtInLegacy) {
|
||||
return builtInLegacy;
|
||||
}
|
||||
for (const surface of listLegacySessionChatTypeSurfaces()) {
|
||||
const derived = surface.deriveLegacySessionChatType?.(scoped);
|
||||
if (derived) {
|
||||
return derived;
|
||||
}
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
import { getBundledChannelContractSurfaces } from "../channels/plugins/contract-surfaces.js";
|
||||
|
||||
export type ParsedAgentSessionKey = {
|
||||
agentId: string;
|
||||
rest: string;
|
||||
};
|
||||
|
||||
export type SessionKeyChatType = "direct" | "group" | "channel" | "unknown";
|
||||
export type ParsedThreadSessionSuffix = {
|
||||
baseSessionKey: string | undefined;
|
||||
threadId: string | undefined;
|
||||
@@ -18,14 +15,6 @@ export type RawSessionConversationRef = {
|
||||
prefix: string;
|
||||
};
|
||||
|
||||
type LegacySessionChatTypeSurface = {
|
||||
deriveLegacySessionChatType?: (sessionKey: string) => "direct" | "group" | "channel" | undefined;
|
||||
};
|
||||
|
||||
function listLegacySessionChatTypeSurfaces(): LegacySessionChatTypeSurface[] {
|
||||
return getBundledChannelContractSurfaces() as LegacySessionChatTypeSurface[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse agent-scoped session keys in a canonical, case-insensitive way.
|
||||
* Returned values are normalized to lowercase for stable comparisons/routing.
|
||||
@@ -52,34 +41,6 @@ export function parseAgentSessionKey(
|
||||
return { agentId, rest };
|
||||
}
|
||||
|
||||
/**
|
||||
* Best-effort chat-type extraction from session keys across canonical and legacy formats.
|
||||
*/
|
||||
export function deriveSessionChatType(sessionKey: string | undefined | null): SessionKeyChatType {
|
||||
const raw = (sessionKey ?? "").trim().toLowerCase();
|
||||
if (!raw) {
|
||||
return "unknown";
|
||||
}
|
||||
const scoped = parseAgentSessionKey(raw)?.rest ?? raw;
|
||||
const tokens = new Set(scoped.split(":").filter(Boolean));
|
||||
if (tokens.has("group")) {
|
||||
return "group";
|
||||
}
|
||||
if (tokens.has("channel")) {
|
||||
return "channel";
|
||||
}
|
||||
if (tokens.has("direct") || tokens.has("dm")) {
|
||||
return "direct";
|
||||
}
|
||||
for (const surface of listLegacySessionChatTypeSurfaces()) {
|
||||
const derived = surface.deriveLegacySessionChatType?.(scoped);
|
||||
if (derived) {
|
||||
return derived;
|
||||
}
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
export function isCronRunSessionKey(sessionKey: string | undefined | null): boolean {
|
||||
const parsed = parseAgentSessionKey(sessionKey);
|
||||
if (!parsed) {
|
||||
|
||||
Reference in New Issue
Block a user