import type { AgentTickActivitySession } from "./types"; function envSessionId(): string | undefined { return process.env.AGENT_TICK_SESSION_ID?.trim() || undefined; } function envSessionTitle(): string | undefined { return process.env.AGENT_TICK_SESSION_TITLE?.trim() || undefined; } function normalizePiSessionId(sessionId: string | undefined): string | undefined { const trimmed = sessionId?.trim(); if (!trimmed) return undefined; const sanitized = trimmed.replace(/[^A-Za-z0-9_.:-]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 160); return sanitized ? `pi_${sanitized}` : undefined; } export function piSessionIdFromContext(ctx: unknown): string | undefined { const sessionManager = typeof ctx === "object" && ctx !== null && "sessionManager" in ctx ? (ctx as { sessionManager?: unknown }).sessionManager : undefined; if (!sessionManager || typeof sessionManager !== "object" || !("getSessionId" in sessionManager)) return undefined; const getSessionId = (sessionManager as { getSessionId?: unknown }).getSessionId; return typeof getSessionId === "function" ? String(getSessionId.call(sessionManager)) : undefined; } export class AgentTickSessionContext { private currentId = envSessionId(); private currentTitle = envSessionTitle(); usePiSessionId(piSessionId?: string): void { const normalizedPiSessionId = normalizePiSessionId(piSessionId); if (!envSessionId() && normalizedPiSessionId) this.currentId = normalizedPiSessionId; } startRun(title?: string, piSessionId?: string): AgentTickActivitySession { this.usePiSessionId(piSessionId); this.currentTitle = (envSessionTitle() ?? title?.trim()) || undefined; return this.current(); } current(): AgentTickActivitySession { const title = envSessionTitle() ?? this.currentTitle; return { ...(envSessionId() ?? this.currentId ? { sessionId: envSessionId() ?? this.currentId } : {}), ...(title ? { session: { title } } : {}), }; } } export function createAgentTickSessionContext(): AgentTickSessionContext { return new AgentTickSessionContext(); }