export const DEFAULT_AGENT_ID = "main"; export const DEFAULT_MAIN_KEY = "main"; export const DEFAULT_ACCOUNT_ID = "default"; export type ParsedAgentSessionKey = { agentId: string; rest: string; }; export function resolveAgentIdFromSessionKey( sessionKey: string | undefined | null, ): string { const parsed = parseAgentSessionKey(sessionKey); return normalizeAgentId(parsed?.agentId ?? DEFAULT_AGENT_ID); } export function normalizeAgentId(value: string | undefined | null): string { const trimmed = (value ?? "").trim(); if (!trimmed) return DEFAULT_AGENT_ID; // Keep it path-safe + shell-friendly. if (/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(trimmed)) return trimmed; // Best-effort fallback: collapse invalid characters to "-" return ( trimmed .toLowerCase() .replace(/[^a-z0-9_-]+/g, "-") .replace(/^-+/, "") .replace(/-+$/, "") .slice(0, 64) || DEFAULT_AGENT_ID ); } export function normalizeAccountId(value: string | undefined | null): string { const trimmed = (value ?? "").trim(); if (!trimmed) return DEFAULT_ACCOUNT_ID; if (/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(trimmed)) return trimmed; return ( trimmed .toLowerCase() .replace(/[^a-z0-9_-]+/g, "-") .replace(/^-+/, "") .replace(/-+$/, "") .slice(0, 64) || DEFAULT_ACCOUNT_ID ); } export function parseAgentSessionKey( sessionKey: string | undefined | null, ): ParsedAgentSessionKey | null { const raw = (sessionKey ?? "").trim(); if (!raw) return null; const parts = raw.split(":").filter(Boolean); if (parts.length < 3) return null; if (parts[0] !== "agent") return null; const agentId = parts[1]?.trim(); const rest = parts.slice(2).join(":"); if (!agentId || !rest) return null; return { agentId, rest }; } export function isSubagentSessionKey( sessionKey: string | undefined | null, ): boolean { const raw = (sessionKey ?? "").trim(); if (!raw) return false; if (raw.toLowerCase().startsWith("subagent:")) return true; const parsed = parseAgentSessionKey(raw); return Boolean((parsed?.rest ?? "").toLowerCase().startsWith("subagent:")); } export function buildAgentMainSessionKey(params: { agentId: string; mainKey?: string | undefined; }): string { const agentId = normalizeAgentId(params.agentId); const mainKey = (params.mainKey ?? DEFAULT_MAIN_KEY).trim() || DEFAULT_MAIN_KEY; return `agent:${agentId}:${mainKey}`; } export function buildAgentPeerSessionKey(params: { agentId: string; mainKey?: string | undefined; provider: string; peerKind?: "dm" | "group" | "channel" | null; peerId?: string | null; }): string { const peerKind = params.peerKind ?? "dm"; if (peerKind === "dm") { return buildAgentMainSessionKey({ agentId: params.agentId, mainKey: params.mainKey, }); } const provider = (params.provider ?? "").trim().toLowerCase() || "unknown"; const peerId = (params.peerId ?? "").trim() || "unknown"; return `agent:${normalizeAgentId(params.agentId)}:${provider}:${peerKind}:${peerId}`; } export function resolveThreadSessionKeys(params: { baseSessionKey: string; threadId?: string | null; parentSessionKey?: string; useSuffix?: boolean; }): { sessionKey: string; parentSessionKey?: string } { const threadId = (params.threadId ?? "").trim(); if (!threadId) { return { sessionKey: params.baseSessionKey, parentSessionKey: undefined }; } const useSuffix = params.useSuffix ?? true; const sessionKey = useSuffix ? `${params.baseSessionKey}:thread:${threadId}` : params.baseSessionKey; return { sessionKey, parentSessionKey: params.parentSessionKey }; }