/** * [ref] A9 域模块 —— 单会话面。 * * 路由:`/v1/sessions/:id` 的 init / settings / mcp / head / events(SSE)/ fork / DELETE / policy / workspace, * 外加同段的 `deps.sessionAudit` 只读审计面。 * * 单域独占状态(lens1 §C2 的 12 条里的 5 条)全部收进 `SessionsLocal`,每个 server 实例一份: * SSE 连接坑计数 `sseConnections`、owner 查探许可 `sseOwnerLookups`、`/mcp` 面板的短 TTL single-flight * 缓存 `mcpStatusCache` 与它的两个时限常量。 * * ⚠️ 搬运例外(仅此一处,语义等价):两个原为闭包 `let` 的计数器进了 local 盒子,于是 6 个使用点写成 * `sse.sseConnections` / `sse.sseOwnerLookups`——`let` 无法跨模块共享自增。判据/时机/配对释放逐字未动。 */ import type { IncomingMessage, ServerResponse } from "node:http"; import { type SessionMemoryStatus } from "@sema-agent/core"; import type { RouteCtx, RouteMatch, RouteIdsOf } from "../route-ctx.js"; /** 单域独占状态。每个 server 实例一份——模块级会把连接坑/缓存跨实例串味。 */ export interface SessionsLocal { sseConnections: number; sseOwnerLookups: number; mcpStatusCache: Map; }>; /** DESIGN-269 件4:`/a2a` 面板的短 TTL single-flight 缓存。与 `mcpStatusCache` **分开一张表**而不是 * 共用带前缀的键:两张面板的体不同形(`peers` vs `servers`),塞进一张表就得靠 unknown 兜住两形, * 于是「取到的是哪一形」变成运行期约定 —— 两张表让它回到类型上。 */ a2aStatusCache: Map; }>; /** [ref]①:memory-status 读面的短 TTL single-flight 缓存(理由见 `MEMORY_STATUS_TTL_MS` 注)。 * 键 = sessionId **裸键**(答案与调用方无关 —— 属主门在缓存读**之前**跑,外人到不了这张表; * mcp/a2a 按 (scenario, principal) 分键是因为它们的面按人裁,这张面不按人裁,分键只会白扩表)。 */ memoryStatusCache: Map; }>; } export declare function createSessionsLocal(): SessionsLocal; /** 路由体 = 从 `server.ts` 的 `handle()` 里**整段剪切**过来的原文(去缩进两格;sessions 另有一处见文件头说明)。 * 裸 `return;` 的语义原样 =「本域已应答」;走到函数尾才是「没匹配上」,置 `miss.fell` 交回装配器继续下一个域。 */ export declare function handleSessions(req: IncomingMessage, res: ServerResponse, match: RouteMatch, ctx: RouteCtx): Promise; export declare const SESSIONS_ROUTES: readonly [{ readonly id: "session-init"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id/$verb"; readonly methods: readonly ["GET"]; }, { readonly id: "session-settings"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id/$verb"; readonly methods: readonly ["GET"]; }, { readonly id: "session-mcp"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id/$verb"; readonly methods: readonly ["GET"]; }, { readonly id: "session-a2a"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id/$verb"; readonly methods: readonly ["GET"]; }, { readonly id: "session-head"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id/$verb"; readonly methods: readonly ["GET"]; }, { readonly id: "session-events"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id/$verb"; readonly methods: readonly ["GET"]; }, { readonly id: "session-fork"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id/$verb"; readonly methods: readonly ["POST"]; }, { readonly id: "session-policy-get"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id/$verb"; readonly methods: readonly ["GET"]; }, { readonly id: "session-policy-put"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id/$verb"; readonly methods: readonly ["PUT"]; }, { readonly id: "session-memory-erase"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id/memory/erase"; readonly methods: readonly ["POST"]; }, { readonly id: "session-memory-status"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id/memory-status"; readonly methods: readonly ["GET"]; }, { readonly id: "session-workspace"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id/workspace"; readonly methods: readonly ["GET"]; }, { readonly id: "session-detail"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id"; readonly methods: readonly ["GET"]; }, { readonly id: "session-delete"; readonly pattern: RegExp; readonly label: "/v1/sessions/:id"; readonly methods: readonly ["DELETE"]; }]; /** 本域可分派行的 `id` 闭集 —— handler 的 `switch` 按它判穷尽(漏一口 = 编译红)。 */ export type SessionsRouteId = RouteIdsOf; //# sourceMappingURL=sessions.d.ts.map