/** * Auto-generated session titles. * * SHAPE: fire-and-forget at FIRST task submit for a session (the objective is known then — no need to wait * for the run to finish, and the web Recents gets the title sooner). Write-once (`setTitleIfNull`, store-side * `WHERE title IS NULL`) — the USER-facing rename lives BFF-side as a label overlay (user label wins * over engine title, two layers never fight). Generation = one cheap-model one-liner via the deployment's * hookLlm face (summarize role → MODEL_CHEAP_ID when configured, else the main model; bounded + timed out). * * FAILURE POSTURE: everything is best-effort — a generation/store failure logs and leaves title null (the * list falls back to objectivePreview). An in-process pending set dedupes concurrent submits on the same * session; the store's IS NULL guard closes the cross-replica race (double generation costs one extra cheap * call at worst, and exactly one title lands). */ export interface SessionTitlerDeps { /** Secret scrub applied to the RAW llm text before sanitize/persist (workflow audit 2026-07-13: the * objective may carry a pasted secret and the model can echo it into the title — titles are persisted, * listed over HTTP, and logged, all outside the trace redact pipeline; wire src/trace/redact.ts here). */ redact?: (text: string) => string; /** Write-once store leg (SQL twins / local sidecar). Resolves false when a title already existed. */ setTitleIfNull(sessionId: string, title: string): Promise; /** Cheap pre-LLM probe: "titled" = skip (a restart/evicted-seen/another replica * already paid — don't re-spend an LLM call); "untitled" = generate; "none" = the session_meta row hasn't * been REGISTERED yet (createRun fires before the Runner's session acquire) — retry after a grace window, * and if still absent, release the seen slot so the NEXT submit retries (never a permanently-untitled * session via a swallowed early UPDATE-0). Local lane has no row-existence dimension → never "none". */ probeTitle(sessionId: string): Promise<"none" | "untitled" | "titled">; /** The deployment's cheap one-shot LLM face (main.ts hookLlm — summarize role default). */ llm(opts: { prompt: string; timeoutMs: number; model?: string; }): Promise<{ ok: true; text: string; } | { ok: false; error: string; }>; logger?: { debug?(msg: string, meta?: unknown): void; info?(msg: string, meta?: unknown): void; warn?(msg: string, meta?: unknown): void; }; metrics?: { inc(name: string, labels?: Record): void; }; } export interface SessionTitler { /** Fire-and-forget: maybe generate + persist a title for this session. Never throws, never blocks the caller. */ /** `model`([ref]②)= 本 turn 真实驱动的模型——带上则标题 hook 同链路,不再裸落 env 缺省。 */ maybeTitle(sessionId: string, objective: string, model?: string): void; } export declare const TITLE_MAX_CHARS = 80; /** Single line, control chars stripped, hard cap; surrounding quotes (a common LLM tic) trimmed. */ export declare function sanitizeTitle(raw: string): string; export declare function buildTitlePrompt(objective: string): string; export declare function createSessionTitler(deps: SessionTitlerDeps): SessionTitler; //# sourceMappingURL=session-titler.d.ts.map