export { C as ChatStore, d as ChatStoreFactory, e as ConversationOwnershipError, L as ListMessagesOptions, c as SaveTurnInput, S as StoredAttachment, a as StoredConversation, b as StoredMessage, U as UsageRecord } from '../chat-store-dqaTB0vU.js'; import { i as CreateChatHandlerOptions, j as ChatRequestContext } from '../mordn-handler-D1Xf5rbX.js'; export { N as BuiltTools, q as CHAT_ERROR_DATA_TYPE, r as CHAT_ERROR_HEADER, p as CHAT_ERROR_VERSION, k as ChatErrorKind, v as ChatErrorMetadata, x as ChatLogEvent, y as ChatLogFields, w as ChatLogger, l as ClassifiedChatError, C as CreateMordnHandlerOptions, J as FeedbackEvent, I as HostedAgentConfig, L as LogLevel, M as ManagedSandboxIntegration, h as ManagedSandboxStatus, O as MemoryConfig, a as MordnAdvancedOptions, R as RetrievalConfig, S as ServerFollowUpConfig, K as ServerTitleConfig, G as TRACE_HEADER, T as TurnLogger, U as UploadPolicy, m as classifyError, z as createConsoleLogger, c as createMordnHandler, A as createTurnLogger, B as errorFields, n as isAbortError, o as messageForErrorKind, D as newTraceId, E as noopLogger, t as parseChatErrorHeader, s as parseChatErrorMetadata, F as resolveTraceId, u as toChatErrorMetadata } from '../mordn-handler-D1Xf5rbX.js'; export { S as StorageAdapter, a as StorageAdapterFactory, U as UploadInput, b as UploadResult } from '../storage-adapter-Dv_hy7k9.js'; import { LanguageModel, ModelMessage } from 'ai'; export { f as AGENT_CONFIG_SCHEMA_VERSION, c as AgentBootstrap, b as AgentClientConfig, A as AgentConfig, a as AgentRuntimeConfig, R as ConfigReadIssue, e as ConfigReadResult, P as PublishedAgentConfig, S as SerializableMemoryConfig, d as SerializableSandboxConfig, g as formatConfigIssues, i as isAgentBootstrap, h as isAgentConfig, r as readAgentBootstrap, j as readAgentConfig } from '../config-CgqlRgyG.js'; export { C as ChunkMetadata, E as Embedder, f as IngestOptions, e as IngestProgress, g as IngestReport, I as IngestSource, b as KnowledgeDoc, d as KnowledgeStore, K as KnowledgeStoreFactory, N as Namespace, h as NamespaceAccessError, Q as QueryOptions, a as RetrievedChunk, c as Retriever, R as RetrieverFactory, S as SourceInfo, U as UpsertResult } from '../types-B0JV4XZ0.js'; export { M as Memory, c as MemoryAdapter, d as MemoryAdapterFactory, b as RecordOptions, R as RetrieveOptions } from '../types-B_kkAV7t.js'; /** * createChatHandler — the request router and the "OWN loop". * * This is the heart of the redesign. It owns every piece of shared, * dangerous-to-get-wrong plumbing so a host app never writes it: * * • authentication gate (401 when getUserId returns null) * • conversation ownership (create-or-reject; never write a foreign row) * • idempotent user-message persistence * • sliding-window context pruning + defensive per-message capping * • per-request tool resources with guaranteed single teardown * • streaming the model response * • save-on-finish persistence of the assistant turn * • history list + history-by-id with attachment re-signing * • uploads to private storage with server-side policy enforcement * * It exposes only the seams in `CreateChatHandlerOptions`. Nothing security- * or correctness-critical is configurable, by design. * * Mounting: the returned `{ GET, POST }` is designed to sit on a single * catch-all route, `app/api/chat/[[...chat]]/route.ts`, so one file mounts the * whole backend. The handler dispatches on the trailing path segments: * * POST /api/chat → chat (stream) * GET /api/chat/bootstrap → authenticated client config + storage scope * POST /api/chat/upload → attachment upload * GET /api/chat/history → conversation list * GET /api/chat/history/:id → one conversation + messages * DELETE /api/chat/history/:id → delete a conversation */ declare function createChatHandler(options: CreateChatHandlerOptions): { GET: (request: Request) => Promise; POST: (request: Request) => Promise; DELETE: (request: Request) => Promise; OPTIONS: (request: Request) => Promise; }; /** * Ready-made history summarizer for `createChatHandler({ summarizeHistory })`. * * When a conversation overflows the sliding window, the handler hands the DROPPED * (oldest) messages to `summarizeHistory`; this helper condenses them with a * small/fast model via the AI SDK (`generateText`) so the early thread survives * as a compact system-prompt block instead of being lost. * * Use a CHEAP model here — summarization runs only on overflow turns, but it's on * the request path, so latency/cost matter. Pass any AI SDK `LanguageModel` (a * gateway string like 'google/gemini-2.5-flash' works). * * import { createLlmSummarizer } from '@mordn/chat-widget/server' * createChatHandler({ * summarizeHistory: createLlmSummarizer({ model: 'google/gemini-2.5-flash' }), * }) * * Best-effort by contract: this returns '' on any failure (the handler then falls * back to a plain drop), so a summarizer hiccup never breaks a turn. */ interface LlmSummarizerOptions { /** The (ideally small/fast) model used to summarize. */ model: LanguageModel; /** Cap on the summary length the model is asked for. Default 1200. */ maxChars?: number; /** Override the instruction if you want a domain-specific summary shape. */ systemPrompt?: string; } declare function createLlmSummarizer(opts: LlmSummarizerOptions): (dropped: ModelMessage[], ctx: ChatRequestContext) => Promise; /** * streamHealthCheck — a CI/staging probe for production streaming. * * "Streaming works on localhost but arrives as one blob in production" is the * most common deployment failure for SSE chat backends, almost always caused by * a reverse proxy / CDN buffering the response. It is invisible until a human * notices the answer appears all-at-once. * * This utility makes that failure *testable*: point it at your deployed chat * route, and it reports whether the response actually arrived incrementally * (many chunks over time) or as a single late blob (buffered). Run it in CI * against a staging deploy, or as a smoke test after release, so a buffering * misconfiguration fails the pipeline instead of reaching users. * * It validates the transport, not model correctness — it only cares that bytes * stream back over time. */ interface StreamHealthResult { /** True when the response streamed incrementally (not buffered) with a 2xx. */ ok: boolean; /** HTTP status of the probe response (0 if the request never completed). */ status: number; /** Number of non-empty network reads observed from the response body. */ chunks: number; /** Time (ms) from request start to the first non-empty chunk, or null. */ firstChunkMs: number | null; /** Total time (ms) from request start to stream end. */ totalMs: number; /** Heuristic: the response looks buffered (arrived as ~one late chunk). */ likelyBuffered: boolean; /** Human-readable summary / remediation pointer. */ note: string; } interface StreamHealthCheckOptions { /** * Absolute URL of the mounted chat route's POST endpoint * (e.g. `https://staging.example.com/api/chat`). */ url: string; /** * Headers used to authenticate the probe. Your `getUserId` must accept these * (e.g. a session cookie or a test bearer token). Without valid auth the * endpoint returns 401 and the probe reports `ok: false`. */ headers?: Record; /** Probe message text. Default: `"ping"`. */ message?: string; /** Conversation id for the probe turn. Default: an ephemeral `health-*` id. */ conversationId?: string; /** Abort the probe after this many ms. Default: 20000. */ timeoutMs?: number; /** Custom fetch implementation (default: global `fetch`). */ fetchImpl?: typeof fetch; } /** * Probe a deployed chat endpoint and report whether it streams incrementally. * Never throws — failures are returned as `{ ok: false, note }`. */ declare function streamHealthCheck(options: StreamHealthCheckOptions): Promise; export { ChatRequestContext, CreateChatHandlerOptions, type LlmSummarizerOptions, type StreamHealthCheckOptions, type StreamHealthResult, createChatHandler, createLlmSummarizer, streamHealthCheck };