import { type WebSocket } from 'ws'; export interface ClientConnection { ws: WebSocket; id: string; agent: string; } /** In-flight web chat runs — Stop button aborts the matching controller. */ export declare const webRunAborts: Map; export declare const USER_INTERRUPTED_TEXT = "\u7528\u6237\u6253\u65AD\u4E86\u6267\u884C"; export declare function formatWebAgentUnavailableMessage(agentName: string): string; /** * Send a JSON message to a WebSocket client */ export declare function sendToClient(ws: WebSocket, data: Record): void; /** * Wait until `ws.bufferedAmount` drops below the highwater mark, or the * socket closes, or the timeout fires. Used by the streaming chunk loop to * stop piling up frames at slow clients. * * Polls every 50 ms — node's `ws` doesn't emit a `drain` event we can hook, * but the buffered amount drops monotonically once the kernel ACKs flush. * Bounded by AGIM_WS_BACKPRESSURE_TIMEOUT_MS (default 5 s) so a frozen * client can't wedge the agent's chunk producer indefinitely. */ export declare function awaitWsDrain(ws: WebSocket): Promise; /** Latest durable assistant message id for a web thread (for done → SPA). */ export declare function latestWebAssistantMessageId(threadId: string): Promise; /** * Send session history to a client. * * Always emit a `history` frame when a session exists — including an empty * message list — so the SPA can adopt the sticky agent after MESSAGES_TTL * cleared the transcript. Previously we skipped empty histories, which left * the agent picker on the process default after refresh. * * Large transcripts are windowed: the first frame is the newest slice * (count + byte budget, activity previews capped). Older turns follow as * `history-prepend` so first paint is not one giant JSON.parse + markdown * pass. Disk `.log` is unchanged. * * After history, replay any in-flight (or recently finished) ActiveRun so * tab-switch / refresh can restore the activity accordion and "接收中". */ export declare function sendSessionHistory(ws: WebSocket, client: ClientConnection, _defaultAgent: string): Promise; /** * Handle a message from a web client */ export declare function handleClientMessage(client: ClientConnection, msg: { type: string; text?: string; agent?: string; threadId?: string; jobId?: number; workspacePath?: string; }, defaultAgent: string, /** Notify the caller that the client's id changed mid-handler so the * WS handler can keep its `clients` map in sync when a browser refresh resumes * with its persisted threadId. Without this the approval-card sender (which * does clients.get(threadId)) silently misses the rekeyed client. */ onRekey?: (oldId: string, newId: string) => void, /** R9: token id of the connecting peer (or 'anon' on loopback / * auth-off). Used to enforce thread ownership on get-history rekey. */ tokenId?: string, /** R9: shared threadId → tokenId store (persisted). The handler * validates ownership before adopting a client-supplied threadId. */ threadOwners?: { get(threadId: string): string | undefined; set(threadId: string, tokenId: string): void; delete(threadId: string): void; rekey?(oldId: string, newId: string): void; }, /** Live client registry — used to retarget chunk/activity frames after * a reconnect (the closure `ws` may already be CLOSED). */ clients?: Map): Promise; //# sourceMappingURL=ws-chat.d.ts.map