@deuz-sdk/react 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/use-chat.ts","../src/use-object.ts","../src/components.tsx"],"names":["applyUIPart","filesToImageParts","useState","uiFromMessages","useRef","useCallback","useEffect","createAssistantTurn","readDeuzStream","sealAssistantTurn","assistantMessageFromTurn","clientToolResultMessage","userMessageFromInput","dropTrailingAssistant","branchBeforeUserMessage","canonicalFromUI","connectDeuzStream","jsx","Fragment","jsxs"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * useChat — the React binding over `@deuz-sdk/core/chat` + the Deuz UI wire.\n *\n * THIN by contract: every chat-state transformation is a core call\n * (`createAssistantTurn`/`applyUIPart`/`sealAssistantTurn`/\n * `assistantMessageFromTurn`/`clientToolResultMessage`/`uiFromMessages`/\n * `canonicalFromUI`/`userMessageFromInput`/`dropTrailingAssistant`/\n * `branchBeforeUserMessage`). This hook only owns React state, the fetch\n * round-trips, and abort wiring. Supersedes the frozen `@deuz-sdk/core/react`.\n *\n * 1.9 (Sprint 3) adds five things, all ADDITIVE:\n * - WRITABLE state — `setHistory`/`setMessages`/`addToolResult`/`clearError`.\n * Deleting a rendered message, switching chats after mount, resolving a\n * client tool from OUTSIDE the hook, and dismissing an error were all\n * impossible before: the transcript had no setter, and a tool needing user\n * interaction (an approve/deny UI, a wallet signature, a file picker) could\n * only be answered from inside `onToolCall`, which DEADLOCKED the round-trip.\n * - multimodal input — `sendMessage(input: ChatInput)`, so \"attach a screenshot\n * and ask about it\" works. `partsFromFiles` feeds it from a file picker.\n * - ONE React commit per fold instead of seven `setState` calls, plus optional\n * `throttleMs` coalescing (a fast model emits hundreds of text deltas per\n * second; each one used to re-render the whole transcript seven times).\n * - `resume.auto` — the resume machinery had no TRIGGER, so surviving a refresh\n * mid-generation still required the app to call `reconnect()` itself.\n * - the newer wire fields reach the consumer: ordered `parts` per message,\n * `steps`, `verifications`, reconciled `dataParts`, tool `denied`, plus the\n * three channels the wiring pass gave producers — `warnings`, `falseFinishes`\n * and `subAgents` (a delegated `agentTool` run used to be invisible here).\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type {\n FinishReason,\n ImagePart,\n Message,\n ToolApprovalRequest,\n ToolApprovalResponse,\n Usage,\n} from '@deuz-sdk/core';\nimport {\n applyUIPart,\n assistantMessageFromTurn,\n branchBeforeUserMessage,\n canonicalFromUI,\n clientToolResultMessage,\n createAssistantTurn,\n dropTrailingAssistant,\n filesToImageParts,\n sealAssistantTurn,\n uiFromMessages,\n userMessageFromInput,\n} from '@deuz-sdk/core/chat';\nimport type {\n AssistantTurnState,\n ChatHistory,\n ChatInput,\n UIMessage,\n UIToolCall,\n} from '@deuz-sdk/core/chat';\nimport type { DeuzUIPart } from '@deuz-sdk/core/ui';\nimport { connectDeuzStream, readDeuzStream } from '@deuz-sdk/core/ui';\n\n/**\n * Fold one wire part via the core reducer. Current core versions preserve the\n * approval token; the defensive re-attach keeps the adapter compatible with\n * early 1.7.0 builds that dropped it while constructing the approval entry.\n */\nfunction foldPart(\n turn: AssistantTurnState,\n part: Parameters<typeof applyUIPart>[1],\n): AssistantTurnState {\n const next = applyUIPart(turn, part);\n if (part.type === 'tool-approval-request' && part.token !== undefined) {\n return {\n ...next,\n approvals: next.approvals.map((a) =>\n a.approvalId === part.approvalId && a.token === undefined ? { ...a, token: part.token } : a,\n ),\n };\n }\n return next;\n}\n\n/** Local id fallback — this package is not edge-lint-constrained. */\nconst defaultGenerateId = (): string =>\n typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'\n ? crypto.randomUUID()\n : `deuz-ui-${Math.random().toString(36).slice(2)}`;\n\n/**\n * Picked files → canonical parts for a {@link ChatInput}. A thin, null-tolerant\n * wrapper over core's `filesToImageParts`: the bytes work (Web APIs only, no\n * `FileReader`, no `Buffer`) lives THERE and is deliberately not reimplemented\n * here. `ImagePart` is the single carrier for all binary media, so images and\n * PDFs both ride this call.\n *\n * ```tsx\n * <input type=\"file\" multiple onChange={async (e) => {\n * const parts = await partsFromFiles(e.target.files);\n * await sendMessage({ text: 'what is in these?', parts });\n * }} />\n * ```\n */\nexport async function partsFromFiles(\n files: FileList | Iterable<Blob & { type?: string }> | null | undefined,\n): Promise<ImagePart[]> {\n if (!files) return [];\n // `FileList` is iterable (lib.dom), so one cast covers both shapes.\n const list: Array<Blob & { type?: string }> = Array.from(\n files as Iterable<Blob & { type?: string }>,\n );\n return list.length === 0 ? [] : filesToImageParts(list);\n}\n\n/** Live cumulative USD cost, from the wire's `cost` parts (last one wins). */\nexport interface UseChatCost {\n costUsd: number;\n cacheSavingsUsd?: number;\n}\n\n/** The server's budget guardrail tripped (`budget-exceeded` part). */\nexport interface UseChatBudgetExceeded {\n kind: 'usd' | 'tokens';\n limit: number;\n value: number;\n}\n\n/**\n * Where the resume cursor lives ACROSS a page reload.\n *\n * An adapter rather than a hardcoded `localStorage`: core's own\n * `connectDeuzStream` frames the cursor as the caller's choice, and hardcoding\n * web storage would break SSR (no `window`), React Native (no `localStorage`)\n * and privacy modes that throw on write. Both methods may throw — the hook\n * swallows it, because losing a cursor must never kill a live stream.\n */\nexport interface UseChatCursorStore {\n /** The persisted cursor, or `undefined` when there is nothing to resume. */\n load(): string | undefined;\n /** Persist the cursor. Called on every advance. */\n save(id: string): void;\n}\n\nexport interface UseChatResumeOptions {\n /**\n * Resume endpoint (see core's `resumeDeuzStreamResponse`): a GET URL or a\n * factory returning the `Response` for a given cursor. Do NOT point it at\n * the generating POST route — that would re-run the model.\n */\n endpoint: string | ((ctx: { lastEventId?: string }) => Response | Promise<Response>);\n /** Cursor to resume from (e.g. persisted across a page reload). */\n lastEventId?: string;\n /**\n * Attempt `reconnect()` ONCE per mounted hook — the canonical scenario\n * resumability exists for (the user refreshes mid-generation) with zero app\n * wiring. Fires exactly once under React 18/19 StrictMode's deliberate\n * mount → unmount → mount double-invoke.\n *\n * An AUTOMATIC attempt that fails is NOT an error state and does NOT reach\n * `onError`: the user did not ask for it, and every cold load of a chat app\n * whose resume endpoint answers 404 (nothing in flight) would otherwise paint\n * a permanent error. A caught-up endpoint (immediate `[DONE]`) is a silent\n * no-op — no bubble, no state change. Call `reconnect()` yourself when you\n * want the failure surfaced.\n */\n auto?: boolean;\n /** Cursor persistence adapter (see {@link UseChatCursorStore}). */\n cursor?: UseChatCursorStore;\n}\n\nexport interface UseChatOptions {\n /** Endpoint serving `toDeuzStreamResponse` output. */\n api: string;\n /**\n * Seed canonical history (e.g. restored from a ChatStore) — rendered via\n * `uiFromMessages`.\n *\n * READ ONCE, at mount, like any `useState` initial value. It is deliberately\n * NOT re-adopted when the prop changes: apps pass an inline array literal, so\n * a new identity arrives on EVERY render and adopting it would reset the\n * transcript continuously — and mid-stream it would clobber the turn being\n * folded. Switching chats or hydrating later is an explicit action: call\n * `setHistory` (both views) or `setMessages` (re-derives canonical).\n */\n initialMessages?: Message[];\n headers?: Record<string, string>;\n /** Extra fields merged into every request body. */\n body?: Record<string, unknown>;\n /** Chat identity — merged into every request body (server-side ChatStore persistence). */\n chatId?: string;\n /** Enables `reconnect()` / `resume.auto` against a resume endpoint (wire v2). */\n resume?: UseChatResumeOptions;\n /** Id source for UI messages/turns. Default: `crypto.randomUUID` (with a fallback). */\n generateId?: () => string;\n /**\n * Coalesce React commits to at most one per `throttleMs` (trailing edge).\n * Default `0` — commit on every wire part, exactly as 1.8 did.\n *\n * A fast model emits hundreds of text deltas per second; with markdown\n * rendering over a long transcript that visibly janks. The terminal frame is\n * ALWAYS flushed (stream end, error, abort, an external tool result), so the\n * final text can never be lost to coalescing. A plain `setTimeout` is fine\n * here: unlike core's `src/**`, this package is not edge-lint-constrained and\n * has no `deps.clock` seam.\n */\n throttleMs?: number;\n /**\n * Client-tool executor: called for every streamed tool call the SERVER did\n * not execute. The return value is appended as its tool_result and the chat\n * auto-continues; a throw self-heals as an is_error result.\n *\n * OMIT it to drive client tools from outside the hook instead: the\n * round-trip PARKS, the calls appear in `pendingToolCalls`, and\n * `addToolResult` answers them.\n */\n onToolCall?: (call: {\n toolCallId: string;\n toolName: string;\n input: unknown;\n }) => Promise<unknown> | unknown;\n /**\n * Fired for every `data-{name}` part as it arrives, BEFORE reconciliation —\n * so a caller sees each intermediate write of an addressable `(name, id)`\n * entry, which `dataParts` collapses to the last one. A throw is swallowed\n * (G2: a consumer callback is not a transport error).\n */\n onData?: (data: { name: string; id?: string; payload: unknown }) => void;\n onError?: (error: Error) => void;\n /**\n * How a NON-2xx response from `api` is reported (default `'error-part'`: the\n * failure becomes `status: 'error'` instead of an empty assistant bubble).\n * Forwarded verbatim to core's `readDeuzStream`.\n */\n onHttpError?: 'error-part' | 'ignore';\n /** Injectable for tests / custom transports. Defaults to global fetch. */\n fetch?: typeof fetch;\n}\n\nexport interface UseChatResult {\n /** The render view. Each message carries its ordered `parts` (1.9) when it has any. */\n messages: UIMessage[];\n /**\n * BOTH views in one object (`{ ui, canonical }`). Only the canonical one is\n * POSTable and only it survives a round-trip through a provider, so an app\n * that persists a chat should persist `history.canonical`. Identity is stable\n * until either view changes.\n */\n history: ChatHistory;\n status: 'idle' | 'streaming' | 'error';\n error: Error | undefined;\n /** Gated tool calls awaiting verdicts — the chat is PAUSED while non-empty. */\n pendingApprovals: ToolApprovalRequest[];\n /**\n * Client tool calls the round-trip is PARKED on (no `onToolCall` executor).\n * Answer each with `addToolResult`; the chat continues once all are answered.\n */\n pendingToolCalls: UIToolCall[];\n /** Live cumulative cost from the wire's `cost` parts (last one wins). */\n cost?: UseChatCost;\n /** Set when the server's budget guardrail tripped this turn. */\n budgetExceeded?: UseChatBudgetExceeded;\n /**\n * This turn's app-defined `data-{name}` parts. Entries written with an `id`\n * are RECONCILED by `(name, id)` — one live status widget stays one entry, at\n * its original position — while id-less entries stay append-only (1.7/1.8).\n */\n dataParts: Array<{ name: string; id?: string; payload: unknown }>;\n /** This turn's RAG citations. */\n citations: AssistantTurnState['citations'];\n /** Latest live plan snapshot for this turn (autonomous runs, 1.8). */\n plan?: AssistantTurnState['plan'];\n /** This turn's live activity feed (\"Computer\" view, 1.8). */\n activity: AssistantTurnState['activity'];\n /** This turn's `verifyStep` verdicts, in arrival order (1.9). */\n verifications?: AssistantTurnState['verifications'];\n /**\n * Non-fatal execution notices for this turn, in arrival order (1.9): a\n * sampling param the wire could not carry, a clamped ceiling, an unknown model\n * slug served from the conservative fallback row. Render them as a dismissible\n * banner — the run itself succeeded.\n */\n warnings?: AssistantTurnState['warnings'];\n /**\n * `false-finish` rejections for this turn (1.9): the server's guard decided\n * the work was not actually done. A trailing entry with `willRetry: false`\n * means the guard's budget ran out, so the answer on screen is the one it\n * stopped on rather than one it was happy with.\n */\n falseFinishes?: AssistantTurnState['falseFinishes'];\n /**\n * Live sub-agent (`agentTool`) frames for this turn, one per `agentPath`\n * (1.9). Each holds the child's OWN turn — its text, ordered `parts` and tool\n * cards — so a delegated run is renderable instead of invisible, and\n * `afterPart` says where in the parent's `parts` it belongs. Nothing here is\n * mixed into the parent's `content`: a sub-agent's words are its own.\n */\n subAgents?: AssistantTurnState['subAgents'];\n /** Per-step usage/finish from `step-finish` parts, in arrival order (1.9). */\n steps?: AssistantTurnState['steps'];\n /** Terminal token usage for this turn, from the wire's `finish` part (1.9). */\n usage?: Usage;\n /** Terminal finish reason (1.9) — `'length'` means the answer was truncated. */\n finishReason?: FinishReason;\n /**\n * Send one user turn: plain text (1.8-identical, including the canonical\n * `content` string) or text plus canonical parts — images/PDFs from\n * {@link partsFromFiles}, `imagePart`/`filePart`, anything the wires accept.\n */\n sendMessage: (input: ChatInput) => Promise<void>;\n /** Abort the in-flight stream (not an error). */\n stop: () => void;\n /** Drop the trailing assistant/tool turns (core `dropTrailingAssistant`) and re-run. */\n regenerate: () => Promise<void>;\n /** Cut history before `messageId` (core `branchBeforeUserMessage`) and send `input`. */\n editAndResend: (messageId: string, input: ChatInput) => Promise<void>;\n /**\n * Replace BOTH views in one commit — the honest primitive, because Deuz keeps\n * two of them and only the canonical one is POSTable. Use it to switch chats,\n * hydrate after mount, or delete/edit a rendered message while keeping a\n * system prompt and provider round-trip data that the UI view cannot carry.\n *\n * Pending gates (approvals, parked client tool calls) are DROPPED: they were\n * anchored to the transcript you just replaced.\n */\n setHistory: (update: ChatHistory | ((prev: ChatHistory) => ChatHistory)) => void;\n /**\n * Sugar over `setHistory`: re-derives the canonical view with core's\n * `canonicalFromUI`. That inverse projection is LOSSY — system messages,\n * `Message.providerMetadata` and UI-only state do not survive it, and a\n * message without ordered `parts` loses its attachments entirely — so drive\n * `setHistory` directly when your history has any of those.\n */\n setMessages: (update: UIMessage[] | ((prev: UIMessage[]) => UIMessage[])) => void;\n /**\n * Answer ONE parked client tool call from outside the hook. Feeds the exact\n * path `onToolCall`'s return value takes (core `clientToolResultMessage`), so\n * the chat auto-continues once every call in `pendingToolCalls` is answered.\n * A result for an id that is not parked is ignored — an orphan `tool_result`\n * would 400 the next request.\n */\n addToolResult: (result: {\n toolCallId: string;\n output: unknown;\n isError?: boolean;\n }) => Promise<void>;\n /** Dismiss the error: `status: 'error'` → `'idle'`. Leaves a live stream alone. */\n clearError: () => void;\n /**\n * Record one verdict (the request's signed `token` is auto-preserved). Once\n * EVERY pending approval has a verdict, the chat auto-resumes with\n * `approvalResponses` in the request body.\n */\n addToolApprovalResponse: (response: ToolApprovalResponse) => Promise<void>;\n /**\n * Re-read the stream from `resume.endpoint` via `connectDeuzStream` and fold\n * the parts into the current turn. No-op unless `options.resume` is set.\n */\n reconnect: () => Promise<void>;\n}\n\n/**\n * ONE React state cell (3.4a). 1.8 held eight — `messages` plus a `useState`\n * per readout — and `syncTurn` set seven of them on EVERY wire part, so a fast\n * model re-rendered the whole transcript several times per token. Collapsing\n * them costs nothing and makes the two history views structurally inseparable:\n * `ui` and `canonical` are published in the SAME commit, so no render can ever\n * see one of them a frame behind the other.\n */\ninterface ChatSnapshot {\n history: ChatHistory;\n cost?: UseChatCost;\n budgetExceeded?: UseChatBudgetExceeded;\n dataParts: Array<{ name: string; id?: string; payload: unknown }>;\n citations: AssistantTurnState['citations'];\n plan?: AssistantTurnState['plan'];\n activity: AssistantTurnState['activity'];\n verifications?: AssistantTurnState['verifications'];\n warnings?: AssistantTurnState['warnings'];\n falseFinishes?: AssistantTurnState['falseFinishes'];\n subAgents?: AssistantTurnState['subAgents'];\n steps?: AssistantTurnState['steps'];\n usage?: Usage;\n finishReason?: FinishReason;\n}\n\n/**\n * Cursor persistence is the CALLER's: a throwing adapter (a quota-exceeded\n * private-mode write, storage disabled) must never kill a live stream.\n */\nfunction loadCursor(resume: UseChatResumeOptions): string | undefined {\n try {\n return resume.cursor?.load();\n } catch {\n return undefined;\n }\n}\n\nfunction saveCursor(resume: UseChatResumeOptions, id: string): void {\n try {\n resume.cursor?.save(id);\n } catch {\n /* a persistence failure is not a transport failure */\n }\n}\n\nexport function useChat(options: UseChatOptions): UseChatResult {\n const genId = options.generateId ?? defaultGenerateId;\n const [snapshot, setSnapshot] = useState<ChatSnapshot>(() => ({\n history: {\n ui: uiFromMessages(options.initialMessages ?? [], genId),\n canonical: options.initialMessages ? [...options.initialMessages] : [],\n },\n dataParts: [],\n citations: [],\n activity: [],\n }));\n const [status, setStatus] = useState<'idle' | 'streaming' | 'error'>('idle');\n const [error, setError] = useState<Error | undefined>(undefined);\n const [pendingApprovals, setPendingApprovals] = useState<ToolApprovalRequest[]>([]);\n const [pendingToolCalls, setPendingToolCalls] = useState<UIToolCall[]>([]);\n\n /** Authoritative snapshot: replaced (never mutated) by `commit`, published to React by `publish`. */\n const snapshotRef = useRef<ChatSnapshot>(snapshot);\n /** The in-flight turn — kept across a drop so `reconnect()` can continue it. */\n const turnRef = useRef<AssistantTurnState | undefined>(undefined);\n /** The turn PARKED on client tool results, so `addToolResult` folds into the same one. */\n const parkedTurnRef = useRef<AssistantTurnState | undefined>(undefined);\n const clientToolsRef = useRef<UIToolCall[]>([]);\n const toolResultsRef = useRef<Array<{ toolCallId: string; result: unknown; isError?: boolean }>>(\n [],\n );\n const approvalsRef = useRef<ToolApprovalRequest[]>([]);\n const verdictsRef = useRef<ToolApprovalResponse[]>([]);\n const abortRef = useRef<AbortController | null>(null);\n const lastEventIdRef = useRef<string | undefined>(options.resume?.lastEventId);\n /**\n * Id of the turn's message AS IT SITS in `ui`. The wire's `start` part\n * RENAMES the message (`applyUIPart`), so the id is not stable across a turn\n * — tracking the last published one lets `syncTurn` address the turn by\n * identity instead of by position. That is what makes `setMessages` safe\n * mid-stream: 1.8 spliced the LAST element blindly, so replacing the\n * transcript under a live stream clobbered whatever the app had put there.\n */\n const placedIdRef = useRef<string | undefined>(undefined);\n\n // --- Commit plumbing: one React update per fold, optionally coalesced ---\n\n const throttleMs = options.throttleMs ?? 0;\n const flushTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const dirtyRef = useRef(false);\n\n const publish = useCallback((): void => {\n flushTimerRef.current = undefined;\n dirtyRef.current = false;\n setSnapshot(snapshotRef.current);\n }, []);\n\n /** Record a new snapshot; publish it now, or on the trailing edge of `throttleMs`. */\n const commit = useCallback(\n (next: ChatSnapshot): void => {\n snapshotRef.current = next;\n if (throttleMs <= 0) {\n publish();\n return;\n }\n dirtyRef.current = true;\n if (flushTimerRef.current === undefined) {\n flushTimerRef.current = setTimeout(publish, throttleMs);\n }\n },\n [throttleMs, publish],\n );\n\n /** Force the pending frame out. Every terminal boundary calls this. */\n const flush = useCallback((): void => {\n if (flushTimerRef.current !== undefined) {\n clearTimeout(flushTimerRef.current);\n flushTimerRef.current = undefined;\n }\n if (dirtyRef.current) publish();\n }, [publish]);\n\n /** A coalesced frame must not fire into an unmounted tree. */\n useEffect(\n () => () => {\n if (flushTimerRef.current !== undefined) clearTimeout(flushTimerRef.current);\n },\n [],\n );\n\n /** Sync ALL turn-derived state in ONE commit. */\n const syncTurn = useCallback(\n (turn: AssistantTurnState): void => {\n const previous = snapshotRef.current;\n const placed = placedIdRef.current;\n const ui = previous.history.ui;\n const index = placed === undefined ? -1 : ui.findIndex((m) => m.id === placed);\n placedIdRef.current = turn.message.id;\n commit({\n ...previous,\n history: {\n // NEW array either way — the turn's message is never spliced in place.\n ui:\n index === -1\n ? [...ui, turn.message]\n : [...ui.slice(0, index), turn.message, ...ui.slice(index + 1)],\n canonical: previous.history.canonical,\n },\n // `cost` is CUMULATIVE for the chat, so an absent reading keeps the\n // previous one (1.7 behaviour, verbatim); every other readout is\n // turn-scoped and resets when the turn does.\n cost:\n turn.costUsd !== undefined\n ? {\n costUsd: turn.costUsd,\n ...(turn.cacheSavingsUsd !== undefined\n ? { cacheSavingsUsd: turn.cacheSavingsUsd }\n : {}),\n }\n : previous.cost,\n budgetExceeded: turn.budgetExceeded,\n dataParts: turn.dataParts,\n citations: turn.citations,\n plan: turn.plan,\n activity: turn.activity,\n verifications: turn.verifications,\n warnings: turn.warnings,\n falseFinishes: turn.falseFinishes,\n subAgents: turn.subAgents,\n steps: turn.steps,\n usage: turn.usage,\n finishReason: turn.finishReason,\n });\n },\n [commit],\n );\n\n /** Append to the canonical view. NEW array — never a splice (immutable history). */\n const appendCanonical = useCallback(\n (message: Message): void => {\n const previous = snapshotRef.current;\n commit({\n ...previous,\n history: {\n ui: previous.history.ui,\n canonical: [...previous.history.canonical, message],\n },\n });\n },\n [commit],\n );\n\n /** Drop every parked gate — the turn they belonged to is no longer current. */\n const clearGates = useCallback((): void => {\n approvalsRef.current = [];\n verdictsRef.current = [];\n clientToolsRef.current = [];\n toolResultsRef.current = [];\n parkedTurnRef.current = undefined;\n setPendingApprovals([]);\n setPendingToolCalls([]);\n }, []);\n\n /** Core reducer + the `onData` notification (the only side channel the fold has). */\n const fold = useCallback(\n (turn: AssistantTurnState, part: DeuzUIPart): AssistantTurnState => {\n const next = foldPart(turn, part);\n const onData = options.onData;\n if (onData && typeof part.type === 'string' && part.type.startsWith('data-')) {\n const data = part as Extract<DeuzUIPart, { payload: unknown }>;\n try {\n onData({\n name: data.type.slice('data-'.length),\n ...(typeof data.id === 'string' ? { id: data.id } : {}),\n payload: data.payload,\n });\n } catch {\n /* G2: a consumer callback is not a transport error */\n }\n }\n return next;\n },\n [options.onData],\n );\n\n const stop = useCallback((): void => {\n abortRef.current?.abort();\n }, []);\n\n const run = useCallback(\n async (approvalResponses?: ToolApprovalResponse[]): Promise<void> => {\n const controller = new AbortController();\n abortRef.current = controller;\n setStatus('streaming');\n setError(undefined);\n try {\n // One iteration per model round; client-tool results loop back in.\n for (;;) {\n const doFetch = options.fetch ?? fetch;\n const res = await doFetch(options.api, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...options.headers },\n body: JSON.stringify({\n messages: snapshotRef.current.history.canonical,\n ...(options.chatId !== undefined ? { chatId: options.chatId } : {}),\n ...(approvalResponses?.length ? { approvalResponses } : {}),\n ...options.body,\n }),\n signal: controller.signal,\n });\n approvalResponses = undefined; // consumed by the first round only\n\n let turn = createAssistantTurn(genId());\n turnRef.current = turn;\n placedIdRef.current = undefined; // a fresh turn owns no slot yet\n syncTurn(turn); // appends the bubble AND resets this-turn state\n flush(); // \"thinking\" feedback must never wait on a throttle window\n\n // A non-2xx route (500 + an HTML error page, 401, 429) yields a\n // single `error` part → turn.error → the throw below → status 'error'.\n // Before 1.9 it streamed nothing and rendered an empty bubble.\n for await (const part of readDeuzStream(res, {\n ...(options.onHttpError ? { onHttpError: options.onHttpError } : {}),\n })) {\n turn = fold(turn, part);\n turnRef.current = turn;\n syncTurn(turn);\n }\n // A stream that ended WITHOUT `finish`/`error` (a dropped connection)\n // leaves the tail text/reasoning part 'streaming' by design — that\n // boundary belongs to the binding, so close it here. Returns the SAME\n // object when there is nothing to seal, hence no wasted render.\n const sealed = sealAssistantTurn(turn);\n if (sealed !== turn) {\n turn = sealed;\n turnRef.current = turn;\n syncTurn(turn);\n }\n flush(); // terminal frame — never coalesced away\n if (turn.error !== undefined) throw new Error(turn.error);\n\n // Append the canonical assistant turn (client-tools reconstruction).\n appendCanonical(assistantMessageFromTurn(turn));\n turnRef.current = undefined;\n\n // Approval pause: verdicts arrive via addToolApprovalResponse.\n if (turn.approvals.length > 0) {\n approvalsRef.current = turn.approvals;\n verdictsRef.current = [];\n setPendingApprovals(turn.approvals);\n return;\n }\n\n // Client tools: everything the server didn't execute.\n const toolCalls = turn.message.toolCalls ?? [];\n const serverResults = new Set(turn.serverResults);\n const clientPending = toolCalls.filter((t) => !serverResults.has(t.toolCallId));\n if (clientPending.length === 0) return;\n if (!options.onToolCall) {\n // No in-hook executor: PARK the round-trip instead of abandoning\n // it. 1.8 returned here and the `tool_use` never got its\n // `tool_result`, so a tool that needs user interaction was\n // unanswerable. `addToolResult` folds the verdicts into THIS turn.\n parkedTurnRef.current = turn;\n clientToolsRef.current = clientPending;\n toolResultsRef.current = [];\n setPendingToolCalls(clientPending);\n return;\n }\n const results: Array<{ toolCallId: string; result: unknown; isError?: boolean }> = [];\n for (const call of clientPending) {\n try {\n const out = await options.onToolCall({\n toolCallId: call.toolCallId,\n toolName: call.toolName,\n input: call.input,\n });\n results.push({ toolCallId: call.toolCallId, result: out });\n turn = applyUIPart(turn, {\n type: 'tool-result',\n toolCallId: call.toolCallId,\n toolName: call.toolName,\n output: out,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n results.push({ toolCallId: call.toolCallId, result: message, isError: true });\n turn = applyUIPart(turn, {\n type: 'tool-result',\n toolCallId: call.toolCallId,\n toolName: call.toolName,\n output: message,\n isError: true,\n });\n }\n syncTurn(turn);\n }\n appendCanonical(clientToolResultMessage(results));\n // loop → next round POSTs the extended history\n }\n } catch (err) {\n if (controller.signal.aborted) {\n // User abort — not an error. No `finish` arrived, so the tail part is\n // still 'streaming'; sealing it is the binding's job (see core's\n // `sealAssistantTurn` docstring).\n const open = turnRef.current;\n if (open) {\n const sealed = sealAssistantTurn(open);\n turnRef.current = sealed;\n if (sealed !== open) syncTurn(sealed);\n }\n return;\n }\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n setStatus('error');\n options.onError?.(e);\n return;\n } finally {\n setStatus((s) => (s === 'error' ? s : 'idle'));\n flush(); // every exit path publishes the last frame\n }\n },\n [\n options.api,\n options.fetch,\n options.headers,\n options.body,\n options.chatId,\n options.generateId,\n options.onToolCall,\n options.onError,\n options.onHttpError,\n appendCanonical,\n fold,\n flush,\n syncTurn,\n ],\n );\n\n const sendMessage = useCallback(\n async (input: ChatInput): Promise<void> => {\n // ONE core projection feeds both views, so the user bubble carries its\n // ordered `parts` (incl. `file` elements for attachments) with no\n // React-side message building. A bare string is byte-identical to 1.8:\n // `userMessageFromInput` keeps `content` a plain STRING, so a prompt-cache\n // prefix does not move when a caller upgrades.\n const message = userMessageFromInput(input);\n const bubble = uiFromMessages([message], genId)[0];\n const previous = snapshotRef.current;\n commit({\n ...previous,\n history: {\n ui: bubble ? [...previous.history.ui, bubble] : previous.history.ui,\n canonical: [...previous.history.canonical, message],\n },\n });\n clearGates();\n flush();\n await run();\n },\n [run, commit, clearGates, flush, options.generateId],\n );\n\n const regenerate = useCallback(async (): Promise<void> => {\n const previous = snapshotRef.current;\n commit({ ...previous, history: dropTrailingAssistant(previous.history) });\n clearGates();\n flush();\n await run();\n }, [run, commit, clearGates, flush]);\n\n const editAndResend = useCallback(\n async (messageId: string, input: ChatInput): Promise<void> => {\n const previous = snapshotRef.current;\n const cut = branchBeforeUserMessage(previous.history, messageId);\n if (!cut) return; // not a user message — nothing to branch\n commit({ ...previous, history: cut });\n clearGates();\n flush();\n await sendMessage(input);\n },\n [sendMessage, commit, clearGates, flush],\n );\n\n const setHistory = useCallback(\n (update: ChatHistory | ((prev: ChatHistory) => ChatHistory)): void => {\n const previous = snapshotRef.current;\n const next = typeof update === 'function' ? update(previous.history) : update;\n // Replace BOTH views WHOLESALE, in ONE commit. Never splice the canonical\n // array in place: the loops and prompt caching depend on prior arrays\n // staying stable (immutable history). `placedIdRef` is left alone — it is\n // only a lookup key, and `syncTurn` appends when the id is gone, so a\n // live turn survives a replacement that keeps it and re-appends when not.\n commit({\n ...previous,\n history: { ui: [...next.ui], canonical: [...next.canonical] },\n });\n clearGates();\n flush();\n },\n [commit, clearGates, flush],\n );\n\n const setMessages = useCallback(\n (update: UIMessage[] | ((prev: UIMessage[]) => UIMessage[])): void => {\n setHistory((prev) => {\n const ui = typeof update === 'function' ? update(prev.ui) : update;\n return { ui, canonical: canonicalFromUI(ui) };\n });\n },\n [setHistory],\n );\n\n const clearError = useCallback((): void => {\n setError(undefined);\n // Only the terminal error state is dismissible — a live stream is not.\n setStatus((s) => (s === 'error' ? 'idle' : s));\n }, []);\n\n const addToolResult = useCallback(\n async (result: { toolCallId: string; output: unknown; isError?: boolean }): Promise<void> => {\n const parked = clientToolsRef.current;\n const call = parked.find((c) => c.toolCallId === result.toolCallId);\n // Nothing parked under that id: ignore. An orphan `tool_result` (one with\n // no matching `tool_use`) 400s the next request, so it must never be\n // POSTed — same invariant the core tool loop enforces server-side.\n if (!call) return;\n toolResultsRef.current = [\n ...toolResultsRef.current.filter((r) => r.toolCallId !== result.toolCallId),\n {\n toolCallId: result.toolCallId,\n result: result.output,\n ...(result.isError ? { isError: true } : {}),\n },\n ];\n const turn = parkedTurnRef.current;\n if (turn) {\n // Same reducer path the in-hook executor takes, so the card renders\n // 'result' identically whichever side answered it.\n const next = applyUIPart(turn, {\n type: 'tool-result',\n toolCallId: result.toolCallId,\n toolName: call.toolName,\n output: result.output,\n ...(result.isError ? { isError: true } : {}),\n });\n parkedTurnRef.current = next;\n syncTurn(next);\n flush(); // a user action, not a stream delta — show it now\n }\n const answered = toolResultsRef.current;\n if (!parked.every((c) => answered.some((r) => r.toolCallId === c.toolCallId))) return;\n clientToolsRef.current = [];\n toolResultsRef.current = [];\n parkedTurnRef.current = undefined;\n setPendingToolCalls([]);\n appendCanonical(clientToolResultMessage(answered));\n await run();\n },\n [run, appendCanonical, syncTurn, flush],\n );\n\n const addToolApprovalResponse = useCallback(\n async (response: ToolApprovalResponse): Promise<void> => {\n // Preserve the request's signed token unless the caller set one.\n const request = approvalsRef.current.find((p) => p.approvalId === response.approvalId);\n const verdict =\n response.token === undefined && request?.token !== undefined\n ? { ...response, token: request.token }\n : response;\n verdictsRef.current = [\n ...verdictsRef.current.filter((v) => v.approvalId !== verdict.approvalId),\n verdict,\n ];\n const verdicts = verdictsRef.current;\n const allSettled = approvalsRef.current.every((p) =>\n verdicts.some((v) => v.approvalId === p.approvalId),\n );\n if (!allSettled) return;\n approvalsRef.current = [];\n verdictsRef.current = [];\n setPendingApprovals([]);\n await run(verdicts);\n },\n [run],\n );\n\n /**\n * The resume read. `silent` marks the AUTOMATIC on-mount attempt: a failure\n * there is invisible (see `resume.auto`), because nothing the user did failed\n * and a dead endpoint would otherwise paint an error on every cold load.\n */\n const runResume = useCallback(\n async (silent: boolean): Promise<void> => {\n const resume = options.resume;\n if (!resume) return;\n const controller = new AbortController();\n abortRef.current = controller;\n setStatus('streaming');\n setError(undefined);\n let folded = 0;\n try {\n // In-memory cursor (this session's stream, or `resume.lastEventId`)\n // beats the persisted one — it is strictly the more recent of the two.\n const cursor = lastEventIdRef.current ?? loadCursor(resume);\n const inFlight = turnRef.current;\n let turn = inFlight;\n if (turn === undefined || cursor === undefined) {\n // No cursor → full replay rebuilds the turn from the start. It takes\n // the place of a partial turn already on screen (`placedIdRef` keeps\n // pointing at it); with nothing on screen the turn stays UNPLACED\n // until the first part arrives, so a caught-up endpoint answering\n // `[DONE]` immediately is a silent no-op rather than an empty bubble.\n if (inFlight === undefined) placedIdRef.current = undefined;\n turn = createAssistantTurn(genId());\n }\n turnRef.current = turn;\n const parts = connectDeuzStream(resume.endpoint, {\n ...(cursor !== undefined ? { lastEventId: cursor } : {}),\n onCursor: (id) => {\n lastEventIdRef.current = id;\n saveCursor(resume, id);\n },\n signal: controller.signal,\n ...(options.fetch ? { fetch: options.fetch } : {}),\n ...(options.headers ? { headers: options.headers } : {}),\n });\n for await (const part of parts) {\n folded++;\n turn = fold(turn, part);\n turnRef.current = turn;\n syncTurn(turn);\n }\n if (folded === 0) {\n // Already caught up: nothing arrived, so nothing changed and nothing\n // may be appended to the canonical history (an empty assistant\n // message would poison the next request). Not an error. The turn we\n // speculatively created is discarded; a real in-flight one is kept\n // (sealed — no `finish` is coming for it now).\n turnRef.current = inFlight === undefined ? undefined : sealAssistantTurn(inFlight);\n return;\n }\n const sealed = sealAssistantTurn(turn);\n if (sealed !== turn) {\n turn = sealed;\n syncTurn(turn);\n }\n turnRef.current = turn;\n if (turn.error !== undefined) throw new Error(turn.error);\n appendCanonical(assistantMessageFromTurn(turn));\n turnRef.current = undefined;\n if (turn.approvals.length > 0) {\n approvalsRef.current = turn.approvals;\n verdictsRef.current = [];\n setPendingApprovals(turn.approvals);\n }\n } catch (err) {\n if (controller.signal.aborted) return; // user abort — not an error\n if (silent) return; // best-effort auto attempt — invisible by contract\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n setStatus('error');\n options.onError?.(e);\n return;\n } finally {\n setStatus((s) => (s === 'error' ? s : 'idle'));\n flush();\n }\n },\n [\n options.resume,\n options.fetch,\n options.headers,\n options.generateId,\n options.onError,\n appendCanonical,\n fold,\n flush,\n syncTurn,\n ],\n );\n\n const reconnect = useCallback((): Promise<void> => runResume(false), [runResume]);\n\n /**\n * `resume.auto`: ONE attempt per mounted hook. The ref guard is what makes\n * React 18/19 StrictMode's deliberate mount → unmount → mount effect\n * double-invoke fire a single request — refs survive it, an effect body does\n * not. Deliberately not undone on cleanup for exactly that reason.\n */\n const autoResumedRef = useRef(false);\n useEffect(() => {\n if (options.resume?.auto !== true || autoResumedRef.current) return;\n autoResumedRef.current = true;\n void runResume(true);\n }, [options.resume?.auto, runResume]);\n\n return {\n messages: snapshot.history.ui,\n history: snapshot.history,\n status,\n error,\n pendingApprovals,\n pendingToolCalls,\n ...(snapshot.cost !== undefined ? { cost: snapshot.cost } : {}),\n ...(snapshot.budgetExceeded !== undefined ? { budgetExceeded: snapshot.budgetExceeded } : {}),\n dataParts: snapshot.dataParts,\n citations: snapshot.citations,\n ...(snapshot.plan !== undefined ? { plan: snapshot.plan } : {}),\n activity: snapshot.activity,\n ...(snapshot.verifications !== undefined ? { verifications: snapshot.verifications } : {}),\n ...(snapshot.warnings !== undefined ? { warnings: snapshot.warnings } : {}),\n ...(snapshot.falseFinishes !== undefined ? { falseFinishes: snapshot.falseFinishes } : {}),\n ...(snapshot.subAgents !== undefined ? { subAgents: snapshot.subAgents } : {}),\n ...(snapshot.steps !== undefined ? { steps: snapshot.steps } : {}),\n ...(snapshot.usage !== undefined ? { usage: snapshot.usage } : {}),\n ...(snapshot.finishReason !== undefined ? { finishReason: snapshot.finishReason } : {}),\n sendMessage,\n stop,\n regenerate,\n editAndResend,\n setHistory,\n setMessages,\n addToolResult,\n clearError,\n addToolApprovalResponse,\n reconnect,\n };\n}\n","/**\n * useObject — streams `toDeuzObjectStreamResponse` output (`object-delta`\n * parts) into React state. Ported from the frozen `@deuz-sdk/core/react` hook.\n *\n * 1.9 adds the two options `useChat` grew for the same reasons: `onHttpError`\n * (forwarded verbatim to core's `readDeuzStream`) and `throttleMs` — a\n * structured-output stream emits one partial per token, and each partial\n * REPLACES the object wholesale, so an unthrottled render tree rebuilds on\n * every token.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { DeepPartial } from '@deuz-sdk/core';\nimport { readDeuzStream } from '@deuz-sdk/core/ui';\n\nexport interface UseObjectOptions {\n /** Endpoint serving `toDeuzObjectStreamResponse` output. */\n api: string;\n headers?: Record<string, string>;\n /**\n * How a NON-2xx response from `api` is reported (default `'error-part'`,\n * which lands in `error`). Forwarded verbatim to core's `readDeuzStream`.\n */\n onHttpError?: 'error-part' | 'ignore';\n /**\n * Coalesce partials to at most one React commit per `throttleMs` (trailing\n * edge). Default `0` — commit every partial, exactly as 1.8 did. The final\n * partial is ALWAYS flushed, so the completed object is never lost.\n */\n throttleMs?: number;\n /** Injectable for tests / custom transports. Defaults to global fetch. */\n fetch?: typeof fetch;\n}\n\nexport interface UseObjectResult<T> {\n /** Latest partial (each `object-delta` replaces it wholesale). */\n object: DeepPartial<T> | undefined;\n isLoading: boolean;\n error: Error | undefined;\n /** POSTs `{ input }` to `api` and streams partials into `object`. */\n submit: (input: unknown) => Promise<void>;\n /** Abort the in-flight stream (not an error). */\n stop: () => void;\n}\n\nexport function useObject<T = unknown>(options: UseObjectOptions): UseObjectResult<T> {\n const [object, setObject] = useState<DeepPartial<T> | undefined>(undefined);\n const [isLoading, setLoading] = useState(false);\n const [error, setError] = useState<Error | undefined>(undefined);\n const abortRef = useRef<AbortController | null>(null);\n\n // Coalescing plumbing (same trailing-edge shape as `useChat`, one value wide).\n const throttleMs = options.throttleMs ?? 0;\n const latestRef = useRef<DeepPartial<T> | undefined>(undefined);\n const timerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const dirtyRef = useRef(false);\n\n const publish = useCallback((): void => {\n timerRef.current = undefined;\n dirtyRef.current = false;\n setObject(latestRef.current);\n }, []);\n\n const commit = useCallback(\n (next: DeepPartial<T> | undefined): void => {\n latestRef.current = next;\n if (throttleMs <= 0) {\n publish();\n return;\n }\n dirtyRef.current = true;\n if (timerRef.current === undefined) timerRef.current = setTimeout(publish, throttleMs);\n },\n [throttleMs, publish],\n );\n\n const flush = useCallback((): void => {\n if (timerRef.current !== undefined) {\n clearTimeout(timerRef.current);\n timerRef.current = undefined;\n }\n if (dirtyRef.current) publish();\n }, [publish]);\n\n /** A coalesced frame must not fire into an unmounted tree. */\n useEffect(\n () => () => {\n if (timerRef.current !== undefined) clearTimeout(timerRef.current);\n },\n [],\n );\n\n const stop = useCallback((): void => {\n abortRef.current?.abort();\n }, []);\n\n const submit = useCallback(\n async (input: unknown): Promise<void> => {\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n setLoading(true);\n setError(undefined);\n commit(undefined);\n flush(); // clearing the previous object is immediate, never coalesced\n try {\n const doFetch = options.fetch ?? fetch;\n const res = await doFetch(options.api, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...options.headers },\n body: JSON.stringify({ input }),\n signal: controller.signal,\n });\n for await (const part of readDeuzStream(res, {\n ...(options.onHttpError ? { onHttpError: options.onHttpError } : {}),\n })) {\n if (part.type === 'object-delta') {\n commit(part.object as DeepPartial<T>);\n } else if (part.type === 'error') {\n setError(new Error(part.message));\n break;\n }\n }\n } catch (err) {\n if (!controller.signal.aborted) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n } finally {\n setLoading(false);\n flush(); // the completed object is never lost to a throttle window\n }\n },\n [options.api, options.fetch, options.headers, options.onHttpError, commit, flush],\n );\n\n return { object, isLoading, error, submit, stop };\n}\n","/**\n * Headless chat components — zero styling, zero business logic. They only\n * wire core types (`ToolApprovalRequest`/`ToolApprovalResponse`, the useChat\n * cost state) to DOM events; presentation is overridable via render props.\n */\nimport type { ReactNode } from 'react';\nimport type { ToolApprovalRequest, ToolApprovalResponse } from '@deuz-sdk/core';\nimport type { UseChatCost } from './use-chat';\n\nexport interface ToolApprovalCardProps {\n approval: ToolApprovalRequest;\n /** Feed this straight into `useChat().addToolApprovalResponse`. */\n onRespond: (response: ToolApprovalResponse) => void;\n /** Override presentation; the component supplies the wired callbacks. */\n render?: (ctx: {\n approval: ToolApprovalRequest;\n approve: () => void;\n deny: (reason?: string) => void;\n }) => ReactNode;\n}\n\n/**\n * One pending tool approval. The verdict always carries the request's signed\n * `token` (D4) — callers never have to thread it themselves.\n */\nexport function ToolApprovalCard({ approval, onRespond, render }: ToolApprovalCardProps) {\n const respond = (approved: boolean, reason?: string): void =>\n onRespond({\n approvalId: approval.approvalId,\n approved,\n ...(reason !== undefined ? { reason } : {}),\n ...(approval.token !== undefined ? { token: approval.token } : {}),\n });\n const approve = (): void => respond(true);\n const deny = (reason?: string): void => respond(false, reason);\n\n if (render) return <>{render({ approval, approve, deny })}</>;\n return (\n <div data-deuz=\"tool-approval\">\n <span data-deuz=\"tool-approval-name\">{approval.toolName}</span>\n <pre data-deuz=\"tool-approval-input\">{JSON.stringify(approval.input, null, 2)}</pre>\n <button type=\"button\" onClick={approve}>\n Approve\n </button>\n <button type=\"button\" onClick={() => deny()}>\n Deny\n </button>\n </div>\n );\n}\n\nexport interface CostBadgeProps {\n /** The `useChat` cost state (undefined until the first `cost` part arrives). */\n cost: UseChatCost | undefined;\n /** Override presentation. */\n format?: (cost: UseChatCost) => ReactNode;\n}\n\n/** Live cost readout: `$X.XXXX`, plus ` (saved $Y.YYYY)` when caching saved money. */\nexport function CostBadge({ cost, format }: CostBadgeProps) {\n if (cost === undefined) return null;\n if (format) return <>{format(cost)}</>;\n const saved =\n cost.cacheSavingsUsd !== undefined && cost.cacheSavingsUsd > 0\n ? ` (saved $${cost.cacheSavingsUsd.toFixed(4)})`\n : '';\n return <span data-deuz=\"cost-badge\">{`$${cost.costUsd.toFixed(4)}${saved}`}</span>;\n}\n"]}
1
+ {"version":3,"sources":["../src/use-chat.ts","../src/use-object.ts","../src/components.tsx"],"names":["applyUIPart","filesToImageParts","useState","uiFromMessages","useRef","useCallback","useEffect","clientToolResultMessage","assistantMessageFromTurn","createAssistantTurn","readDeuzStream","sealAssistantTurn","userMessageFromInput","dropTrailingAssistant","branchBeforeUserMessage","canonicalFromUI","connectDeuzStream","jsx","Fragment","jsxs"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * useChat — the React binding over `@deuz-sdk/core/chat` + the Deuz UI wire.\n *\n * THIN by contract: every chat-state transformation is a core call\n * (`createAssistantTurn`/`applyUIPart`/`sealAssistantTurn`/\n * `assistantMessageFromTurn`/`clientToolResultMessage`/`uiFromMessages`/\n * `canonicalFromUI`/`userMessageFromInput`/`dropTrailingAssistant`/\n * `branchBeforeUserMessage`). This hook only owns React state, the fetch\n * round-trips, and abort wiring. Supersedes the frozen `@deuz-sdk/core/react`.\n *\n * 1.9 (Sprint 3) adds five things, all ADDITIVE:\n * - WRITABLE state — `setHistory`/`setMessages`/`addToolResult`/`clearError`.\n * Deleting a rendered message, switching chats after mount, resolving a\n * client tool from OUTSIDE the hook, and dismissing an error were all\n * impossible before: the transcript had no setter, and a tool needing user\n * interaction (an approve/deny UI, a wallet signature, a file picker) could\n * only be answered from inside `onToolCall`, which DEADLOCKED the round-trip.\n * - multimodal input — `sendMessage(input: ChatInput)`, so \"attach a screenshot\n * and ask about it\" works. `partsFromFiles` feeds it from a file picker.\n * - ONE React commit per fold instead of seven `setState` calls, plus optional\n * `throttleMs` coalescing (a fast model emits hundreds of text deltas per\n * second; each one used to re-render the whole transcript seven times).\n * - `resume.auto` — the resume machinery had no TRIGGER, so surviving a refresh\n * mid-generation still required the app to call `reconnect()` itself.\n * - the newer wire fields reach the consumer: ordered `parts` per message,\n * `steps`, `verifications`, reconciled `dataParts`, tool `denied`, plus the\n * three channels the wiring pass gave producers — `warnings`, `falseFinishes`\n * and `subAgents` (a delegated `agentTool` run used to be invisible here).\n *\n * 2.3 fixes two settlement holes, no API change:\n * - F06 — a verdict resumes the chat only when it answers the gate the chat is\n * paused on. One with nothing pending (a double click, a stale card, another\n * run's verdict) used to POST a fresh round and render an empty bubble.\n * - F07 — a turn read back through `reconnect()` settles exactly like one read\n * from the POST (`settleTurn`). Its unresolved client calls used to reach\n * neither `onToolCall` nor `pendingToolCalls`; and a call the replay\n * re-delivers after this client answered it is not dispatched again. A\n * result settles only the call or gate that came before it, so a provider\n * that recycles call ids (`tool_0` in every response) keeps a later one open.\n *\n * 2.3 also drives a NATIVE agent route (`toDeuzAgentStreamResponse` over\n * `streamAgent` / `resumeStreamAgent`), additively: core's `applyUIPart` folds\n * the route's `data-agent` frames into `turn.agent`, and when that state says\n * the run is suspended, its terminal frame is the authority on what it waits\n * for. The hook then answers with the run's id, and with every verdict and\n * every client result in ONE request (`runId`, `approvalResponses`,\n * `clientToolResults`), because a native resume proceeds only with all of\n * them. A chat route never sends a frame, so its requests are unchanged. No\n * new core export is imported: with a core older than 2.3 there is no\n * `turn.agent`, and the hook behaves as before.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type {\n FinishReason,\n ImagePart,\n Message,\n ToolApprovalRequest,\n ToolApprovalResponse,\n Usage,\n} from '@deuz-sdk/core';\nimport {\n applyUIPart,\n assistantMessageFromTurn,\n branchBeforeUserMessage,\n canonicalFromUI,\n clientToolResultMessage,\n createAssistantTurn,\n dropTrailingAssistant,\n filesToImageParts,\n sealAssistantTurn,\n uiFromMessages,\n userMessageFromInput,\n} from '@deuz-sdk/core/chat';\nimport type {\n AssistantTurnState,\n ChatHistory,\n ChatInput,\n UIMessage,\n UIToolCall,\n} from '@deuz-sdk/core/chat';\nimport type { DeuzUIPart } from '@deuz-sdk/core/ui';\nimport { connectDeuzStream, readDeuzStream } from '@deuz-sdk/core/ui';\n\n/**\n * Fold one wire part via the core reducer. Current core versions preserve the\n * approval token; the defensive re-attach keeps the adapter compatible with\n * early 1.7.0 builds that dropped it while constructing the approval entry.\n */\nfunction foldPart(\n turn: AssistantTurnState,\n part: Parameters<typeof applyUIPart>[1],\n): AssistantTurnState {\n const next = applyUIPart(turn, part);\n if (part.type === 'tool-approval-request' && part.token !== undefined) {\n return {\n ...next,\n approvals: next.approvals.map((a) =>\n a.approvalId === part.approvalId && a.token === undefined ? { ...a, token: part.token } : a,\n ),\n };\n }\n return next;\n}\n\n/**\n * Verdict ↔ request identity (2.3): the approval id plus the request's signed\n * token. A RECORDED verdict always carries its request's exact token, so this\n * pairs the two one-to-one.\n */\nfunction sameTarget(\n a: { approvalId: string; token?: string },\n b: { approvalId: string; token?: string },\n): boolean {\n return a.approvalId === b.approvalId && a.token === b.token;\n}\n\n/**\n * Does the caller's verdict answer `request`? (2.3, F06.) The approval id must\n * match and, when the verdict carries a signed token, it must be THIS\n * request's token: a token is minted per run and call (`createApprovalSigner`),\n * so a different one means the verdict was issued for another run — a card\n * left over from an earlier turn, or another chat whose provider recycled the\n * same call id.\n */\nfunction answersRequest(verdict: ToolApprovalResponse, request: ToolApprovalRequest): boolean {\n return (\n verdict.approvalId === request.approvalId &&\n (verdict.token === undefined || verdict.token === request.token)\n );\n}\n\n/** One request delivered twice (a repeated frame), as opposed to two calls sharing an id. */\nfunction sameRequest(a: ToolApprovalRequest, b: ToolApprovalRequest): boolean {\n return (\n sameTarget(a, b) &&\n a.toolCallId === b.toolCallId &&\n (a.agentPath ?? []).join('\\u0000') === (b.agentPath ?? []).join('\\u0000')\n );\n}\n\n/**\n * What a resume read saw in ARRIVAL order (2.3), which the reducer's state\n * cannot tell: it merges the calls that share an id into one entry, and a\n * provider without call ids gets `tool_0`, `tool_1`, … from core's adapter\n * afresh in every model response, so one id can name several calls of one\n * exchange. Kept with the cursor turn (`cursorLedgerRef`), so a turn continued\n * from the cursor carries it across reads.\n */\ninterface ReplayLedger {\n /** Indexes into the turn's `approvals` whose call got a result AFTER the request. */\n readonly answeredApprovals: Set<number>;\n /** Per invocation key (`invocationKey`): how many finished legs delivered that call. */\n readonly legs: Map<string, number>;\n /** Invocation keys of the calls the current, unfinished leg delivered. */\n readonly openLeg: Set<string>;\n /** The cursor the turn's first read sent. */\n readonly cursor: string | undefined;\n /**\n * Whether the endpoint resumed AFTER that cursor: the first event id it\n * delivered is a later one. Unknown until an id arrives, and unknown (no id,\n * no cursor, ids that are not sequence numbers) counts as no.\n */\n afterCursor?: boolean;\n}\n\nconst newLedger = (cursor?: string): ReplayLedger => ({\n answeredApprovals: new Set(),\n legs: new Map(),\n openLeg: new Set(),\n cursor,\n});\n\n/** Note one wire part of a resume read, BEFORE it folds into `turn`. */\nfunction recordPart(ledger: ReplayLedger, turn: AssistantTurnState, part: DeuzUIPart): void {\n switch (part.type) {\n case 'tool-result':\n // A result settles the requests that came before it, never a later one\n // that reuses its call id.\n turn.approvals.forEach((request, index) => {\n if (request.toolCallId === part.toolCallId) ledger.answeredApprovals.add(index);\n });\n return;\n case 'tool-call':\n // Once per leg: a frame the wire repeats is one delivery.\n ledger.openLeg.add(invocationKey(part.toolCallId, part.toolName, part.input));\n return;\n case 'finish':\n // Every leg ends with one, and a replay sails through leg boundaries.\n for (const key of ledger.openLeg) ledger.legs.set(key, (ledger.legs.get(key) ?? 0) + 1);\n ledger.openLeg.clear();\n return;\n }\n}\n\n/** How many legs of a replayed turn delivered the call: at least once, as it is in the turn. */\nconst deliveries = (ledger: ReplayLedger, key: string): number =>\n Math.max(1, (ledger.legs.get(key) ?? 0) + (ledger.openLeg.has(key) ? 1 : 0));\n\n/** Whether event id `id` comes after `cursor`; no when either is not a sequence number. */\nfunction isLaterId(id: string, cursor: string | undefined): boolean {\n return (\n cursor !== undefined && /^\\d+$/.test(id) && /^\\d+$/.test(cursor) && Number(id) > Number(cursor)\n );\n}\n\nconst NO_INDEXES: ReadonlySet<number> = new Set();\n\n/**\n * The approvals a settled turn actually PAUSES on (2.3). `turn.approvals` is\n * the reducer's raw arrival log, so it keeps a request the wire repeated —\n * one question, asked once: the latest delivery stands for it. On a REPLAY it\n * can also hold a request whose call already has its result (`answered`): a\n * journal that spans an approval leg and the continuation that settled it\n * folds both into one turn, and an executed call cannot be approved again.\n * Only a result that arrived after the request settles it: an earlier one\n * belongs to an earlier call that used the same id. A fresh POST leg settles\n * none (`answered` is empty): the loop breaks right after emitting its\n * approvals.\n */\nfunction openApprovals(\n turn: AssistantTurnState,\n answered: ReadonlySet<number>,\n): ToolApprovalRequest[] {\n const open: ToolApprovalRequest[] = [];\n turn.approvals.forEach((request, index) => {\n if (answered.has(index)) return;\n const seen = open.findIndex((entry) => sameRequest(entry, request));\n if (seen === -1) open.push(request);\n else open[seen] = request;\n });\n return open;\n}\n\n/** JSON replacer that emits object keys in sorted order — see `invocationKey`. */\nfunction sortedKeys(_key: string, value: unknown): unknown {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return value;\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).sort(([a], [b]) =>\n a < b ? -1 : a > b ? 1 : 0,\n ),\n );\n}\n\n/**\n * Identity of ONE client tool invocation (2.3, F07): the server-issued id plus\n * what it invokes. The id alone is not enough — an OpenAI-compatible server\n * that omits call ids gets `tool_${index}` from core's adapter, so one id\n * recurs across the rounds of an exchange — but a replay re-delivers the SAME\n * call, not merely the same id. Key order does not count: a history restored\n * from a store that reorders object keys (Postgres `jsonb` does) still holds\n * the same input.\n */\nfunction invocationKey(toolCallId: string, toolName: string, input: unknown): string {\n try {\n return JSON.stringify([toolCallId, toolName, input ?? null], sortedKeys);\n } catch {\n // Not JSON-serializable (a restored history can hold anything).\n return JSON.stringify([toolCallId, toolName]);\n }\n}\n\nconst keyOfCall = (call: UIToolCall): string =>\n invocationKey(call.toolCallId, call.toolName, call.input);\n\n/**\n * How often the canonical history already ANSWERS each client tool invocation\n * within its current exchange (after the last user message): a `tool_use`\n * followed by a `tool_result` for its id (2.3, F07). That result is the only\n * durable evidence this hook has that a client call completed, which is why it\n * — not a set of ids seen so far — decides whether a REPLAYED call may be\n * dispatched: it survives a reload exactly when the app restores\n * `history.canonical`. It is a count, not a set, because a provider without\n * call ids can ask the identical call (`tool_0`, same input) again in a later\n * leg, and one answer covers one delivery.\n *\n * `behind` holds the messages a read that resumed after its cursor cannot\n * deliver again (`behindCursorRef`): their answers do not count.\n */\nfunction answeredInvocations(\n history: Message[],\n behind?: ReadonlySet<Message>,\n): Map<string, number> {\n const answered = new Map<string, number>();\n const results = new Set<string>();\n // Backwards, so a result is seen before the call it answers. A paired id is\n // consumed: an older `tool_use` that recycled it is not answered by it.\n for (let i = history.length - 1; i >= 0; i--) {\n const message = history[i]!;\n if (message.role === 'user') break;\n if (!Array.isArray(message.content)) continue;\n for (const part of message.content) {\n if (part.type === 'tool_result') results.add(part.toolUseId);\n }\n if (message.role !== 'assistant') continue;\n for (const part of message.content) {\n if (part.type === 'tool_use' && results.delete(part.id) && !behind?.has(message)) {\n const key = invocationKey(part.id, part.name, part.input);\n answered.set(key, (answered.get(key) ?? 0) + 1);\n }\n }\n }\n return answered;\n}\n\n/**\n * The native agent run a turn carries (2.3): core's `DeuzAgentState`, read off\n * `AssistantTurnState.agent`. Derived rather than imported, so these types\n * still compile against a core older than 2.3 (where it is `unknown`).\n */\nexport type UseChatAgent = AssistantTurnState extends { agent?: infer A }\n ? Exclude<A, undefined>\n : unknown;\n\n/** The provider's explanation of a stop (2.3): core's `StopDetails`, derived like `UseChatAgent`. */\nexport type UseChatStopDetails = AssistantTurnState extends { stopDetails?: infer S }\n ? Exclude<S, undefined>\n : unknown;\n\n/** A client result as a native resume takes it (`AgentRunOptions.clientToolResults`). */\ninterface ClientToolResult {\n toolCallId: string;\n output: unknown;\n isError?: boolean;\n}\n\n/** One answered client call, as a native resume takes it. */\nfunction asClientToolResult(answer: {\n toolCallId: string;\n result: unknown;\n isError?: boolean;\n}): ClientToolResult {\n return {\n toolCallId: answer.toolCallId,\n output: answer.result,\n ...(answer.isError ? { isError: true } : {}),\n };\n}\n\n/**\n * What the next POST carries besides the history (2.3). A chat route only\n * ever gets `approvalResponses`; `runId` and `clientToolResults` resume a\n * native run.\n */\ninterface Continuation {\n approvalResponses?: ToolApprovalResponse[];\n runId?: string;\n clientToolResults?: ClientToolResult[];\n}\n\n/**\n * A suspended native run (2.3), from the terminal frame folded into the turn:\n * its id, the approvals it waits for, and its client calls, as the turn's\n * cards when the leg streamed them (a resume leg that changed nothing streams\n * none, so a call can exist only in the frame).\n */\nfunction nativeSuspension(\n turn: AssistantTurnState,\n): { runId: string; approvals: ToolApprovalRequest[]; clientCalls: UIToolCall[] } | undefined {\n const agent = turn.agent;\n if (agent?.status !== 'suspended' || agent.runId === undefined) return undefined;\n const cards = turn.message.toolCalls ?? [];\n return {\n runId: agent.runId,\n approvals: agent.pendingApprovals,\n clientCalls: agent.pendingClientCalls.map(\n (call) =>\n cards.find((card) => card.toolCallId === call.toolCallId && card.input !== undefined) ?? {\n toolCallId: call.toolCallId,\n toolName: call.toolName,\n input: call.input,\n state: 'call',\n },\n ),\n };\n}\n\n/** The verdicts and the run a native gate's client calls resume with (2.3). */\ninterface NativeResume {\n runId: string;\n approvalResponses?: ToolApprovalResponse[];\n}\n\n/**\n * A native gate whose last verdict landed (2.3): its client calls run as the\n * first step of the round that resumes the run with their results.\n */\ninterface NativeGateRound {\n turn: AssistantTurnState;\n clientCalls: UIToolCall[];\n resume: NativeResume;\n}\n\n/**\n * The ids of the `tool_use` parts the current exchange (after the last user\n * message) has not answered yet (2.3). A server-run call that an earlier leg\n * paused on (an approval) gets its result in a later leg, where it is no\n * assembled card of the turn: these are the calls such results answer.\n */\nfunction unansweredCalls(history: Message[]): Set<string> {\n const results = new Set<string>();\n const open = new Set<string>();\n for (let i = history.length - 1; i >= 0; i--) {\n const message = history[i]!;\n if (message.role === 'user') break;\n if (!Array.isArray(message.content)) continue;\n for (const part of message.content) {\n if (part.type === 'tool_result') results.add(part.toolUseId);\n if (part.type === 'tool_use' && !results.has(part.id)) open.add(part.id);\n }\n }\n return open;\n}\n\n/** Local id fallback — this package is not edge-lint-constrained. */\nconst defaultGenerateId = (): string =>\n typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'\n ? crypto.randomUUID()\n : `deuz-ui-${Math.random().toString(36).slice(2)}`;\n\n/**\n * Picked files → canonical parts for a {@link ChatInput}. A thin, null-tolerant\n * wrapper over core's `filesToImageParts`: the bytes work (Web APIs only, no\n * `FileReader`, no `Buffer`) lives THERE and is deliberately not reimplemented\n * here. `ImagePart` is the single carrier for all binary media, so images and\n * PDFs both ride this call.\n *\n * ```tsx\n * <input type=\"file\" multiple onChange={async (e) => {\n * const parts = await partsFromFiles(e.target.files);\n * await sendMessage({ text: 'what is in these?', parts });\n * }} />\n * ```\n */\nexport async function partsFromFiles(\n files: FileList | Iterable<Blob & { type?: string }> | null | undefined,\n): Promise<ImagePart[]> {\n if (!files) return [];\n // `FileList` is iterable (lib.dom), so one cast covers both shapes.\n const list: Array<Blob & { type?: string }> = Array.from(\n files as Iterable<Blob & { type?: string }>,\n );\n return list.length === 0 ? [] : filesToImageParts(list);\n}\n\n/** Live cumulative USD cost, from the wire's `cost` parts (last one wins). */\nexport interface UseChatCost {\n costUsd: number;\n cacheSavingsUsd?: number;\n}\n\n/** The server's budget guardrail tripped (`budget-exceeded` part). */\nexport interface UseChatBudgetExceeded {\n kind: 'usd' | 'tokens';\n limit: number;\n value: number;\n}\n\n/**\n * Where the resume cursor lives ACROSS a page reload.\n *\n * An adapter rather than a hardcoded `localStorage`: core's own\n * `connectDeuzStream` frames the cursor as the caller's choice, and hardcoding\n * web storage would break SSR (no `window`), React Native (no `localStorage`)\n * and privacy modes that throw on write. Both methods may throw — the hook\n * swallows it, because losing a cursor must never kill a live stream.\n */\nexport interface UseChatCursorStore {\n /** The persisted cursor, or `undefined` when there is nothing to resume. */\n load(): string | undefined;\n /** Persist the cursor. Called on every advance. */\n save(id: string): void;\n}\n\nexport interface UseChatResumeOptions {\n /**\n * Resume endpoint (see core's `resumeDeuzStreamResponse`): a GET URL or a\n * factory returning the `Response` for a given cursor. Do NOT point it at\n * the generating POST route — that would re-run the model.\n */\n endpoint: string | ((ctx: { lastEventId?: string }) => Response | Promise<Response>);\n /** Cursor to resume from (e.g. persisted across a page reload). */\n lastEventId?: string;\n /**\n * Attempt `reconnect()` ONCE per mounted hook — the canonical scenario\n * resumability exists for (the user refreshes mid-generation) with zero app\n * wiring. Fires exactly once under React 18/19 StrictMode's deliberate\n * mount → unmount → mount double-invoke.\n *\n * An AUTOMATIC attempt that fails is NOT an error state and does NOT reach\n * `onError`: the user did not ask for it, and every cold load of a chat app\n * whose resume endpoint answers 404 (nothing in flight) would otherwise paint\n * a permanent error. A caught-up endpoint (immediate `[DONE]`) is a silent\n * no-op — no bubble, no state change. Call `reconnect()` yourself when you\n * want the failure surfaced. Only the READ is silent: when the replayed turn\n * continues the chat (2.3 — `onToolCall` answered its client calls), that\n * POST to `api` reports a failure like any other.\n */\n auto?: boolean;\n /**\n * Cursor persistence adapter (see {@link UseChatCursorStore}). Only reads\n * through `endpoint` save the cursor, so it marks how far the RESUME reads\n * got. (Since 2.3 a POST response that carries the journal's `id:` lines\n * moves the hook's in-memory cursor too, so a `reconnect()` within the same\n * mounted hook resumes after what the POST read delivered; it is not saved\n * here, because a reload mid-turn must replay that turn from its start.\n * `setHistory` drops that in-memory cursor, so a chat switch never sends\n * one chat's cursor to another chat's endpoint.)\n */\n cursor?: UseChatCursorStore;\n}\n\nexport interface UseChatOptions {\n /** Endpoint serving `toDeuzStreamResponse` output. */\n api: string;\n /**\n * Seed canonical history (e.g. restored from a ChatStore) — rendered via\n * `uiFromMessages`.\n *\n * READ ONCE, at mount, like any `useState` initial value. It is deliberately\n * NOT re-adopted when the prop changes: apps pass an inline array literal, so\n * a new identity arrives on EVERY render and adopting it would reset the\n * transcript continuously — and mid-stream it would clobber the turn being\n * folded. Switching chats or hydrating later is an explicit action: call\n * `setHistory` (both views) or `setMessages` (re-derives canonical).\n */\n initialMessages?: Message[];\n headers?: Record<string, string>;\n /** Extra fields merged into every request body. */\n body?: Record<string, unknown>;\n /** Chat identity — merged into every request body (server-side ChatStore persistence). */\n chatId?: string;\n /** Enables `reconnect()` / `resume.auto` against a resume endpoint (wire v2). */\n resume?: UseChatResumeOptions;\n /** Id source for UI messages/turns. Default: `crypto.randomUUID` (with a fallback). */\n generateId?: () => string;\n /**\n * Coalesce React commits to at most one per `throttleMs` (trailing edge).\n * Default `0` — commit on every wire part, exactly as 1.8 did.\n *\n * A fast model emits hundreds of text deltas per second; with markdown\n * rendering over a long transcript that visibly janks. The terminal frame is\n * ALWAYS flushed (stream end, error, abort, an external tool result), so the\n * final text can never be lost to coalescing. A plain `setTimeout` is fine\n * here: unlike core's `src/**`, this package is not edge-lint-constrained and\n * has no `deps.clock` seam.\n */\n throttleMs?: number;\n /**\n * Client-tool executor: called for every streamed tool call the SERVER did\n * not execute. The return value is appended as its tool_result and the chat\n * auto-continues; a throw self-heals as an is_error result. A result that\n * lands after the chat moved on (a new message, a regenerate, a replaced\n * history) is dropped (2.3).\n *\n * OMIT it to drive client tools from outside the hook instead: the\n * round-trip PARKS, the calls appear in `pendingToolCalls`, and\n * `addToolResult` answers them.\n *\n * Since 2.3 a turn read back through `reconnect()` / `resume.auto` reaches\n * this the same way. A replayed call is dispatched AT MOST ONCE per mounted\n * hook: not when the canonical history already holds its result, and not\n * while it is parked or still running. Across a reload that evidence is the\n * history the app restored — a call whose result was not persisted before\n * the page went away runs again, so make such tools idempotent, or omit\n * `onToolCall` and confirm parked calls yourself. A tab that only WATCHES a\n * stream another tab drives should omit it too, or it would run that tab's\n * calls.\n */\n onToolCall?: (call: {\n toolCallId: string;\n toolName: string;\n input: unknown;\n }) => Promise<unknown> | unknown;\n /**\n * Fired for every `data-{name}` part as it arrives, BEFORE reconciliation —\n * so a caller sees each intermediate write of an addressable `(name, id)`\n * entry, which `dataParts` collapses to the last one. A throw is swallowed\n * (G2: a consumer callback is not a transport error).\n */\n onData?: (data: { name: string; id?: string; payload: unknown }) => void;\n onError?: (error: Error) => void;\n /**\n * How a NON-2xx response from `api` is reported (default `'error-part'`: the\n * failure becomes `status: 'error'` instead of an empty assistant bubble).\n * Forwarded verbatim to core's `readDeuzStream`.\n */\n onHttpError?: 'error-part' | 'ignore';\n /** Injectable for tests / custom transports. Defaults to global fetch. */\n fetch?: typeof fetch;\n}\n\nexport interface UseChatResult {\n /** The render view. Each message carries its ordered `parts` (1.9) when it has any. */\n messages: UIMessage[];\n /**\n * BOTH views in one object (`{ ui, canonical }`). Only the canonical one is\n * POSTable and only it survives a round-trip through a provider, so an app\n * that persists a chat should persist `history.canonical`. Identity is stable\n * until either view changes.\n */\n history: ChatHistory;\n status: 'idle' | 'streaming' | 'error';\n error: Error | undefined;\n /**\n * Gated tool calls awaiting verdicts — the chat is PAUSED while non-empty.\n * One entry per request: a repeated wire frame does not add a second card.\n */\n pendingApprovals: ToolApprovalRequest[];\n /**\n * Client tool calls the round-trip is PARKED on (no `onToolCall` executor).\n * Answer each with `addToolResult`; the chat continues once all are answered.\n * A turn read back through `reconnect()` parks its calls here too (2.3).\n */\n pendingToolCalls: UIToolCall[];\n /** Live cumulative cost from the wire's `cost` parts (last one wins). */\n cost?: UseChatCost;\n /** Set when the server's budget guardrail tripped this turn. */\n budgetExceeded?: UseChatBudgetExceeded;\n /**\n * This turn's app-defined `data-{name}` parts. Entries written with an `id`\n * are RECONCILED by `(name, id)` — one live status widget stays one entry, at\n * its original position — while id-less entries stay append-only (1.7/1.8).\n */\n dataParts: Array<{ name: string; id?: string; payload: unknown }>;\n /** This turn's RAG citations. */\n citations: AssistantTurnState['citations'];\n /** Latest live plan snapshot for this turn (autonomous runs, 1.8). */\n plan?: AssistantTurnState['plan'];\n /** This turn's live activity feed (\"Computer\" view, 1.8). */\n activity: AssistantTurnState['activity'];\n /** This turn's `verifyStep` verdicts, in arrival order (1.9). */\n verifications?: AssistantTurnState['verifications'];\n /**\n * Non-fatal execution notices for this turn, in arrival order (1.9): a\n * sampling param the wire could not carry, a clamped ceiling, an unknown model\n * slug served from the conservative fallback row. Render them as a dismissible\n * banner — the run itself succeeded.\n */\n warnings?: AssistantTurnState['warnings'];\n /**\n * `false-finish` rejections for this turn (1.9): the server's guard decided\n * the work was not actually done. A trailing entry with `willRetry: false`\n * means the guard's budget ran out, so the answer on screen is the one it\n * stopped on rather than one it was happy with.\n */\n falseFinishes?: AssistantTurnState['falseFinishes'];\n /**\n * Live sub-agent (`agentTool`) frames for this turn, one per `agentPath`\n * (1.9). Each holds the child's OWN turn — its text, ordered `parts` and tool\n * cards — so a delegated run is renderable instead of invisible, and\n * `afterPart` says where in the parent's `parts` it belongs. Nothing here is\n * mixed into the parent's `content`: a sub-agent's words are its own.\n */\n subAgents?: AssistantTurnState['subAgents'];\n /** Per-step usage/finish from `step-finish` parts, in arrival order (1.9). */\n steps?: AssistantTurnState['steps'];\n /** Terminal token usage for this turn, from the wire's `finish` part (1.9). */\n usage?: Usage;\n /** Terminal finish reason (1.9) — `'length'` means the answer was truncated. */\n finishReason?: FinishReason;\n /**\n * The provider's explanation of this turn's stop (2.3), from the wire's\n * `finish`: with `finishReason: 'content_filter'`, a refusal's `category`\n * and `explanation`. Absent when the provider explained nothing.\n */\n stopDetails?: UseChatStopDetails;\n /**\n * The native agent run behind this turn (2.3), on a route that serves\n * `toDeuzAgentStreamResponse`: its `runId`, `status` (`'running'`,\n * `'suspended'`, `'completed'`, `'stopped'`, `'failed'`), the latest `partial`\n * draft while it runs, and — only once `completed` — the `output` the server\n * validated. Absent on a chat route. Pending approvals and client calls of a\n * suspended run also appear in `pendingApprovals` / `pendingToolCalls`, and\n * the hook resumes the run with them.\n */\n agent?: UseChatAgent;\n /**\n * Send one user turn: plain text (1.8-identical, including the canonical\n * `content` string) or text plus canonical parts — images/PDFs from\n * {@link partsFromFiles}, `imagePart`/`filePart`, anything the wires accept.\n */\n sendMessage: (input: ChatInput) => Promise<void>;\n /** Abort the in-flight stream (not an error). */\n stop: () => void;\n /** Drop the trailing assistant/tool turns (core `dropTrailingAssistant`) and re-run. */\n regenerate: () => Promise<void>;\n /** Cut history before `messageId` (core `branchBeforeUserMessage`) and send `input`. */\n editAndResend: (messageId: string, input: ChatInput) => Promise<void>;\n /**\n * Replace BOTH views in one commit — the honest primitive, because Deuz keeps\n * two of them and only the canonical one is POSTable. Use it to switch chats,\n * hydrate after mount, or delete/edit a rendered message while keeping a\n * system prompt and provider round-trip data that the UI view cannot carry.\n *\n * Pending gates (approvals, parked client tool calls) are DROPPED: they were\n * anchored to the transcript you just replaced. So is the in-memory resume\n * cursor (2.3), which addresses that transcript's stream: the next\n * `reconnect()` reads from the persisted cursor or from the start.\n */\n setHistory: (update: ChatHistory | ((prev: ChatHistory) => ChatHistory)) => void;\n /**\n * Sugar over `setHistory`: re-derives the canonical view with core's\n * `canonicalFromUI`. That inverse projection is LOSSY — system messages,\n * `Message.providerMetadata` and UI-only state do not survive it, and a\n * message without ordered `parts` loses its attachments entirely — so drive\n * `setHistory` directly when your history has any of those.\n */\n setMessages: (update: UIMessage[] | ((prev: UIMessage[]) => UIMessage[])) => void;\n /**\n * Answer ONE parked client tool call from outside the hook. Feeds the exact\n * path `onToolCall`'s return value takes (core `clientToolResultMessage`), so\n * the chat auto-continues once every call in `pendingToolCalls` is answered.\n * A result for an id that is not parked is ignored — an orphan `tool_result`\n * would 400 the next request.\n */\n addToolResult: (result: {\n toolCallId: string;\n output: unknown;\n isError?: boolean;\n }) => Promise<void>;\n /** Dismiss the error: `status: 'error'` → `'idle'`. Leaves a live stream alone. */\n clearError: () => void;\n /**\n * Record one verdict (the request's signed `token` is auto-preserved). Once\n * EVERY pending approval has a verdict, the chat auto-resumes ONCE with\n * `approvalResponses` in the request body.\n *\n * The verdict must answer an approval in `pendingApprovals`: its\n * `approvalId`, and — when the verdict carries a `token` — that request's\n * token, which binds it to the run that issued it. ANYTHING ELSE IS A NO-OP\n * (2.3): no request, no state change, and the promise resolves — the same\n * contract as `addToolResult`. That covers a verdict with nothing pending, a\n * repeat of one already sent (a double click), a card left over from an\n * earlier turn or a replaced transcript, and another run's verdict. Before\n * the last verdict lands, answering an approval again replaces its verdict.\n */\n addToolApprovalResponse: (response: ToolApprovalResponse) => Promise<void>;\n /**\n * Re-read the stream from `resume.endpoint` via `connectDeuzStream` and fold\n * the parts into the current turn. No-op unless `options.resume` is set.\n *\n * The read turn settles exactly like a streamed one (2.3): its approvals\n * pause the chat, its unresolved client calls reach `onToolCall` (and the\n * chat continues with a POST) or `pendingToolCalls`, and a call the replay\n * re-delivers after this client answered it is not dispatched again. A\n * `stop()` during the read settles nothing; the next call continues it.\n *\n * Since 2.3 a POST read whose response carries the journal's event ids\n * moves the cursor too, so a reconnect after a settled turn resumes after\n * it and appends nothing the hook already holds.\n */\n reconnect: () => Promise<void>;\n}\n\n/**\n * ONE React state cell (3.4a). 1.8 held eight — `messages` plus a `useState`\n * per readout — and `syncTurn` set seven of them on EVERY wire part, so a fast\n * model re-rendered the whole transcript several times per token. Collapsing\n * them costs nothing and makes the two history views structurally inseparable:\n * `ui` and `canonical` are published in the SAME commit, so no render can ever\n * see one of them a frame behind the other.\n */\ninterface ChatSnapshot {\n history: ChatHistory;\n cost?: UseChatCost;\n budgetExceeded?: UseChatBudgetExceeded;\n dataParts: Array<{ name: string; id?: string; payload: unknown }>;\n citations: AssistantTurnState['citations'];\n plan?: AssistantTurnState['plan'];\n activity: AssistantTurnState['activity'];\n verifications?: AssistantTurnState['verifications'];\n warnings?: AssistantTurnState['warnings'];\n falseFinishes?: AssistantTurnState['falseFinishes'];\n subAgents?: AssistantTurnState['subAgents'];\n steps?: AssistantTurnState['steps'];\n usage?: Usage;\n finishReason?: FinishReason;\n stopDetails?: UseChatStopDetails;\n agent?: UseChatAgent;\n}\n\n/**\n * Cursor persistence is the CALLER's: a throwing adapter (a quota-exceeded\n * private-mode write, storage disabled) must never kill a live stream.\n */\nfunction loadCursor(resume: UseChatResumeOptions): string | undefined {\n try {\n return resume.cursor?.load();\n } catch {\n return undefined;\n }\n}\n\nfunction saveCursor(resume: UseChatResumeOptions, id: string): void {\n try {\n resume.cursor?.save(id);\n } catch {\n /* a persistence failure is not a transport failure */\n }\n}\n\nexport function useChat(options: UseChatOptions): UseChatResult {\n const genId = options.generateId ?? defaultGenerateId;\n const [snapshot, setSnapshot] = useState<ChatSnapshot>(() => ({\n history: {\n ui: uiFromMessages(options.initialMessages ?? [], genId),\n canonical: options.initialMessages ? [...options.initialMessages] : [],\n },\n dataParts: [],\n citations: [],\n activity: [],\n }));\n const [status, setStatus] = useState<'idle' | 'streaming' | 'error'>('idle');\n const [error, setError] = useState<Error | undefined>(undefined);\n const [pendingApprovals, setPendingApprovals] = useState<ToolApprovalRequest[]>([]);\n const [pendingToolCalls, setPendingToolCalls] = useState<UIToolCall[]>([]);\n\n /** Authoritative snapshot: replaced (never mutated) by `commit`, published to React by `publish`. */\n const snapshotRef = useRef<ChatSnapshot>(snapshot);\n /** The in-flight turn — kept across a drop so `reconnect()` can continue it. */\n const turnRef = useRef<AssistantTurnState | undefined>(undefined);\n /** The turn PARKED on client tool results, so `addToolResult` folds into the same one. */\n const parkedTurnRef = useRef<AssistantTurnState | undefined>(undefined);\n const clientToolsRef = useRef<UIToolCall[]>([]);\n const toolResultsRef = useRef<Array<{ toolCallId: string; result: unknown; isError?: boolean }>>(\n [],\n );\n /**\n * The gate the chat is PAUSED on: the open approvals of the last settled turn\n * (deduplicated, see `openApprovals`). Emptied the moment its verdicts are\n * sent, so a verdict that arrives later answers nothing (2.3, F06).\n */\n const approvalsRef = useRef<ToolApprovalRequest[]>([]);\n const verdictsRef = useRef<ToolApprovalResponse[]>([]);\n /**\n * A native run paused on approvals (2.3): the turn and the client calls it\n * also waits for. They run once the verdicts are in, and the verdicts ride\n * the same resume request as their results.\n */\n const nativeGateRef = useRef<\n { runId: string; turn: AssistantTurnState; clientCalls: UIToolCall[] } | undefined\n >(undefined);\n /** The native run (and its verdicts) the parked client calls resume (2.3). */\n const parkedNativeRef = useRef<NativeResume | undefined>(undefined);\n /**\n * Bumped by `clearGates` (2.3). An `onToolCall` batch that started under an\n * older value belongs to a gate that was dropped meanwhile (a new message, a\n * regenerate, a replaced transcript): its results join nothing.\n */\n const gateGenerationRef = useRef(0);\n /**\n * The results the current turn streamed for calls of an EARLIER leg (2.3):\n * a server-run call the chat paused on (an approval) executes in the resumed\n * leg, which streams its state and result but not the call, so it is no\n * assembled card of that leg's turn. They answer the history's open\n * `tool_use`s when the turn settles.\n */\n const priorResultsRef = useRef<Array<{ toolCallId: string; result: unknown; isError?: boolean }>>(\n [],\n );\n /**\n * Invocation keys (`invocationKey`) of client calls an `onToolCall` batch is\n * running right now. Parked calls live in `clientToolsRef`; together they are\n * the calls a concurrent replay must not dispatch a second time (2.3, F07).\n */\n const executingRef = useRef<Set<string>>(new Set());\n const abortRef = useRef<AbortController | null>(null);\n const lastEventIdRef = useRef<string | undefined>(options.resume?.lastEventId);\n /**\n * The turn `lastEventIdRef` is a cursor INTO (2.3). A reconnect may fold\n * into the in-flight turn only when that turn is the one the cursor\n * addresses. The resume read advances the cursor, and so does a POST read\n * whose response carries the journal's ids (`readDeuzStream`'s `onEventId`,\n * 2.3). A turn a POST read built without ids (a route that does not journal,\n * or a core before 2.3) is rebuilt from the cursor instead; folding the\n * replay into it would apply its already-received parts twice.\n */\n const cursorTurnRef = useRef<AssistantTurnState | undefined>(undefined);\n /** What the reads of `cursorTurnRef`'s turn saw in arrival order (see `ReplayLedger`). */\n const cursorLedgerRef = useRef<ReplayLedger>(newLedger());\n /**\n * The canonical history as it stood when the last replayed turn settled\n * (2.3). Its read ended on the cursor, so a read that resumes after the\n * cursor cannot deliver any of these messages' calls again, and their\n * answers are no evidence about the calls it does deliver.\n */\n const behindCursorRef = useRef<readonly Message[]>([]);\n /**\n * Id of the turn's message AS IT SITS in `ui`. The wire's `start` part\n * RENAMES the message (`applyUIPart`), so the id is not stable across a turn\n * — tracking the last published one lets `syncTurn` address the turn by\n * identity instead of by position. That is what makes `setMessages` safe\n * mid-stream: 1.8 spliced the LAST element blindly, so replacing the\n * transcript under a live stream clobbered whatever the app had put there.\n */\n const placedIdRef = useRef<string | undefined>(undefined);\n\n // --- Commit plumbing: one React update per fold, optionally coalesced ---\n\n const throttleMs = options.throttleMs ?? 0;\n const flushTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const dirtyRef = useRef(false);\n\n const publish = useCallback((): void => {\n flushTimerRef.current = undefined;\n dirtyRef.current = false;\n setSnapshot(snapshotRef.current);\n }, []);\n\n /** Record a new snapshot; publish it now, or on the trailing edge of `throttleMs`. */\n const commit = useCallback(\n (next: ChatSnapshot): void => {\n snapshotRef.current = next;\n if (throttleMs <= 0) {\n publish();\n return;\n }\n dirtyRef.current = true;\n if (flushTimerRef.current === undefined) {\n flushTimerRef.current = setTimeout(publish, throttleMs);\n }\n },\n [throttleMs, publish],\n );\n\n /** Force the pending frame out. Every terminal boundary calls this. */\n const flush = useCallback((): void => {\n if (flushTimerRef.current !== undefined) {\n clearTimeout(flushTimerRef.current);\n flushTimerRef.current = undefined;\n }\n if (dirtyRef.current) publish();\n }, [publish]);\n\n /** A coalesced frame must not fire into an unmounted tree. */\n useEffect(\n () => () => {\n if (flushTimerRef.current !== undefined) clearTimeout(flushTimerRef.current);\n },\n [],\n );\n\n /** Sync ALL turn-derived state in ONE commit. */\n const syncTurn = useCallback(\n (turn: AssistantTurnState): void => {\n const previous = snapshotRef.current;\n const placed = placedIdRef.current;\n const ui = previous.history.ui;\n // The LAST message with the id (2.3): the turn's bubble was appended\n // after every earlier one, and a route that names each response's\n // message the same ('deuz-msg' without a `messageId`) must not have a\n // later leg write into an earlier leg's bubble.\n let index = -1;\n if (placed !== undefined) {\n for (let i = ui.length - 1; i >= 0; i--) {\n if (ui[i]!.id === placed) {\n index = i;\n break;\n }\n }\n }\n placedIdRef.current = turn.message.id;\n commit({\n ...previous,\n history: {\n // NEW array either way — the turn's message is never spliced in place.\n ui:\n index === -1\n ? [...ui, turn.message]\n : [...ui.slice(0, index), turn.message, ...ui.slice(index + 1)],\n canonical: previous.history.canonical,\n },\n // `cost` is CUMULATIVE for the chat, so an absent reading keeps the\n // previous one (1.7 behaviour, verbatim); every other readout is\n // turn-scoped and resets when the turn does.\n cost:\n turn.costUsd !== undefined\n ? {\n costUsd: turn.costUsd,\n ...(turn.cacheSavingsUsd !== undefined\n ? { cacheSavingsUsd: turn.cacheSavingsUsd }\n : {}),\n }\n : previous.cost,\n budgetExceeded: turn.budgetExceeded,\n dataParts: turn.dataParts,\n citations: turn.citations,\n plan: turn.plan,\n activity: turn.activity,\n verifications: turn.verifications,\n warnings: turn.warnings,\n falseFinishes: turn.falseFinishes,\n subAgents: turn.subAgents,\n steps: turn.steps,\n usage: turn.usage,\n finishReason: turn.finishReason,\n stopDetails: turn.stopDetails,\n agent: turn.agent,\n });\n },\n [commit],\n );\n\n /** Append to the canonical view. NEW array — never a splice (immutable history). */\n const appendCanonical = useCallback(\n (message: Message): void => {\n const previous = snapshotRef.current;\n commit({\n ...previous,\n history: {\n ui: previous.history.ui,\n canonical: [...previous.history.canonical, message],\n },\n });\n },\n [commit],\n );\n\n /** Drop every parked gate — the turn they belonged to is no longer current. */\n const clearGates = useCallback((): void => {\n gateGenerationRef.current++;\n approvalsRef.current = [];\n verdictsRef.current = [];\n nativeGateRef.current = undefined;\n parkedNativeRef.current = undefined;\n clientToolsRef.current = [];\n toolResultsRef.current = [];\n parkedTurnRef.current = undefined;\n setPendingApprovals([]);\n setPendingToolCalls([]);\n }, []);\n\n /** Core reducer + the `onData` notification (the only side channel the fold has). */\n const fold = useCallback(\n (turn: AssistantTurnState, part: DeuzUIPart): AssistantTurnState => {\n const next = foldPart(turn, part);\n const onData = options.onData;\n // A native run's `data-agent` frame (2.3) is not app data: core folds it\n // into `turn.agent` and leaves `dataParts` alone. With an older core it\n // stays an ordinary data part and is reported as before.\n const agentFrame = part.type === 'data-agent' && next.dataParts === turn.dataParts;\n if (onData && !agentFrame && typeof part.type === 'string' && part.type.startsWith('data-')) {\n const data = part as Extract<DeuzUIPart, { payload: unknown }>;\n try {\n onData({\n name: data.type.slice('data-'.length),\n ...(typeof data.id === 'string' ? { id: data.id } : {}),\n payload: data.payload,\n });\n } catch {\n /* G2: a consumer callback is not a transport error */\n }\n }\n // A result for a call of an earlier leg (2.3, see `priorResultsRef`): the\n // turn has no card for it, or only one a `tool-state` frame opened.\n if (\n part.type === 'tool-result' &&\n !(turn.message.toolCalls ?? []).some(\n (call) => call.toolCallId === part.toolCallId && call.input !== undefined,\n )\n ) {\n priorResultsRef.current = [\n ...priorResultsRef.current,\n {\n toolCallId: part.toolCallId,\n result: part.output,\n ...(part.isError ? { isError: true } : {}),\n },\n ];\n }\n return next;\n },\n [options.onData],\n );\n\n const stop = useCallback((): void => {\n abortRef.current?.abort();\n }, []);\n\n /**\n * Run or park the client calls a settled turn waits for. ONE path for a\n * turn's own settlement and for a native gate whose verdicts just landed\n * (2.3).\n *\n * Without `onToolCall` the round-trip PARKS instead of being abandoned: 1.8\n * returned here and the `tool_use` never got its `tool_result`, so a tool\n * that needs user interaction was unanswerable. `addToolResult` folds the\n * results into THIS turn. With it, every call runs once, its result is folded\n * into the turn, and the results join the canonical history.\n *\n * `native` resumes a native run: its id, and the verdicts that must ride\n * the same request. Resolves the next POST's continuation, or `undefined`\n * when the chat is done or parked, or when the gate was dropped while the\n * calls ran (2.3: a new message, a regenerate or a replaced transcript).\n * Such a batch folds and appends nothing: its results answer a turn that is\n * no longer current, and a `role: 'tool'` message after the new exchange\n * would make the next request invalid.\n */\n const settleClientCalls = useCallback(\n async (\n settled: AssistantTurnState,\n pending: UIToolCall[],\n native?: NativeResume,\n ): Promise<Continuation | undefined> => {\n let turn = settled;\n if (pending.length === 0) {\n // A native gate without client calls resumes with its verdicts alone.\n return native?.approvalResponses?.length ? { ...native } : undefined;\n }\n if (!options.onToolCall) {\n parkedTurnRef.current = turn;\n parkedNativeRef.current = native;\n clientToolsRef.current = pending;\n toolResultsRef.current = [];\n setPendingToolCalls(pending);\n return undefined;\n }\n const generation = gateGenerationRef.current;\n const running = pending.map(keyOfCall);\n for (const key of running) executingRef.current.add(key);\n try {\n const results: Array<{ toolCallId: string; result: unknown; isError?: boolean }> = [];\n for (const call of pending) {\n let answer: { toolCallId: string; result: unknown; isError?: boolean };\n try {\n const out = await options.onToolCall({\n toolCallId: call.toolCallId,\n toolName: call.toolName,\n input: call.input,\n });\n answer = { toolCallId: call.toolCallId, result: out };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n answer = { toolCallId: call.toolCallId, result: message, isError: true };\n }\n if (gateGenerationRef.current !== generation) return undefined;\n results.push(answer);\n turn = applyUIPart(turn, {\n type: 'tool-result',\n toolCallId: call.toolCallId,\n toolName: call.toolName,\n output: answer.result,\n ...(answer.isError ? { isError: true } : {}),\n });\n // The settled turn's own bubble (2.3): a reconnect while the chat\n // waited (a caught-up read) unplaces the slot, and `syncTurn` would\n // append the turn a second time.\n placedIdRef.current = turn.message.id;\n syncTurn(turn);\n }\n appendCanonical(clientToolResultMessage(results));\n return native ? { ...native, clientToolResults: results.map(asClientToolResult) } : {};\n } finally {\n for (const key of running) executingRef.current.delete(key);\n }\n },\n [options.onToolCall, appendCanonical, syncTurn],\n );\n\n /**\n * Settle a turn whose stream ENDED cleanly: append it to the canonical\n * history, then pause on its approvals, park or run its client tool calls,\n * or finish. ONE implementation behind both reads (2.3, F07) — before 2.3\n * only the POST round-trip settled client tools, so an unresolved call that\n * arrived through `reconnect()` reached neither `onToolCall` nor\n * `pendingToolCalls`, and the transcript kept a `tool_use` nobody answered.\n *\n * `replay` marks a turn read back from `resume.endpoint`, with what its\n * reads saw in arrival order. A replay re-delivers whatever the journal\n * holds after the cursor — with a lost cursor, or a journal holding the leg\n * before the one in flight, that includes calls this client already\n * answered. So for a replayed turn a call is dispatched only while the read\n * delivered it more often than the canonical history answers it (one answer\n * per leg that asked it), and not while it is parked or running: within a\n * mounted hook, at most once per invocation. A fresh POST leg skips those\n * checks — it cannot repeat a call, and providers that number their calls\n * (`tool_0`, …) legitimately recycle an answered id in the next round.\n * `cursorRead` marks a POST read whose event ids moved the cursor (2.3).\n *\n * A native run (2.3) is settled from its terminal frame: the approvals and\n * client calls it reports are what it waits for, and the continuation\n * carries its `runId`.\n *\n * Resolves the next POST's continuation when client results were appended,\n * `undefined` when the chat is done or paused.\n */\n const settleTurn = useCallback(\n async (\n settled: AssistantTurnState,\n replay?: { ledger: ReplayLedger },\n cursorRead = false,\n ): Promise<Continuation | undefined> => {\n const turn = settled;\n // Completion evidence for a replay, read BEFORE this turn joins it. A\n // read that resumed after its cursor cannot have delivered the calls of\n // the turns settled behind that cursor again.\n const history = snapshotRef.current.history.canonical;\n const behind = replay?.ledger.afterCursor ? new Set(behindCursorRef.current) : undefined;\n // Results for calls an earlier leg paused on (2.3), such as an approved\n // call the resumed leg executed, answer them first, so a later request's\n // history leaves no `tool_use` open. Before 2.3 such a result reached the\n // screen but never the history, and the next request failed on the open call.\n const open = unansweredCalls(history);\n const answers = priorResultsRef.current.filter(\n (entry, index, all) =>\n open.has(entry.toolCallId) &&\n all.findIndex((other) => other.toolCallId === entry.toolCallId) === index,\n );\n priorResultsRef.current = [];\n if (answers.length > 0) appendCanonical(clientToolResultMessage(answers));\n // Append the canonical assistant turn (client-tools reconstruction).\n appendCanonical(assistantMessageFromTurn(turn));\n // The calls the server ran within this leg (2.3) keep their `tool_use` in\n // that message and their result on the card: it answers them right after\n // it, as `canonicalFromUI` does. Before 2.3 the next request carried them\n // open: a provider rejects that, and a chat route's approval continuation\n // ran them again, since it settles every call the history leaves open.\n const ran = (turn.message.toolCalls ?? []).filter(\n (call) => call.input !== undefined && call.state === 'result',\n );\n if (ran.length > 0) {\n appendCanonical(\n clientToolResultMessage(\n ran.map((call) => ({\n toolCallId: call.toolCallId,\n result: call.output,\n ...(call.isError ? { isError: true } : {}),\n })),\n ),\n );\n }\n turnRef.current = undefined;\n // Its read ended on the cursor: this turn and all before it are behind it now.\n if (replay || cursorRead) behindCursorRef.current = snapshotRef.current.history.canonical;\n\n // A suspended native run says itself what it waits for (2.3). One that\n // did not suspend waits for nothing: a call its stream showed (a refused\n // turn's, say) is no client call, and a POST would start a new run.\n const native = nativeSuspension(turn);\n if (!native && turn.agent !== undefined) return undefined;\n // Client tools: every call no result followed (for a native run, the\n // calls its frame reports) — on a replay, minus what this client already\n // answered or is answering right now. The reducer merges the calls that\n // share an id and keeps the latest one's state, so a result for an\n // earlier call under a recycled id (`tool_0` again) leaves this one a\n // 'call'. Testing the id against `turn.serverResults` took the later call\n // for the executed one.\n const answered = replay ? answeredInvocations(history, behind) : undefined;\n const parked = new Set(clientToolsRef.current.map(keyOfCall));\n const candidates = native\n ? native.clientCalls\n : (turn.message.toolCalls ?? []).filter(\n // A card without input is a call of an earlier leg, never one to run.\n (call) => call.state === 'call' && call.input !== undefined,\n );\n const clientPending = candidates.filter((call) => {\n if (!replay || !answered) return true;\n const key = keyOfCall(call);\n return (\n deliveries(replay.ledger, key) > (answered.get(key) ?? 0) &&\n !parked.has(key) &&\n !executingRef.current.has(key)\n );\n });\n\n // Approval pause: verdicts arrive via addToolApprovalResponse. A native\n // run's client calls wait for them, since one request resumes it.\n const gate = native\n ? native.approvals\n : openApprovals(turn, replay?.ledger.answeredApprovals ?? NO_INDEXES);\n if (gate.length > 0) {\n approvalsRef.current = gate;\n verdictsRef.current = [];\n nativeGateRef.current = native\n ? { runId: native.runId, turn, clientCalls: clientPending }\n : undefined;\n setPendingApprovals(gate);\n return undefined;\n }\n return settleClientCalls(turn, clientPending, native ? { runId: native.runId } : undefined);\n },\n [appendCanonical, settleClientCalls],\n );\n\n const run = useCallback(\n async (initial?: Continuation, gate?: NativeGateRound): Promise<void> => {\n const controller = new AbortController();\n abortRef.current = controller;\n setStatus('streaming');\n setError(undefined);\n let continuation = initial;\n try {\n if (gate) {\n // A native gate's client calls (2.3) run as this round's first step,\n // under its controller and while it is 'streaming': a `stop()` while\n // they run cancels the resume POST, as a stop between the rounds of\n // a chat route does, and a gate dropped meanwhile resumes nothing.\n continuation = await settleClientCalls(gate.turn, gate.clientCalls, gate.resume);\n if (!continuation || controller.signal.aborted) return;\n }\n // One iteration per model round; client-tool results loop back in.\n for (;;) {\n const doFetch = options.fetch ?? fetch;\n const res = await doFetch(options.api, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...options.headers },\n body: JSON.stringify({\n messages: snapshotRef.current.history.canonical,\n ...(options.chatId !== undefined ? { chatId: options.chatId } : {}),\n ...(continuation?.approvalResponses?.length\n ? { approvalResponses: continuation.approvalResponses }\n : {}),\n // A native run's resume (2.3); a chat route never gets these.\n ...(continuation?.runId !== undefined ? { runId: continuation.runId } : {}),\n ...(continuation?.clientToolResults?.length\n ? { clientToolResults: continuation.clientToolResults }\n : {}),\n ...options.body,\n }),\n signal: controller.signal,\n });\n continuation = undefined; // consumed by this round only\n\n let turn = createAssistantTurn(genId());\n turnRef.current = turn;\n priorResultsRef.current = [];\n placedIdRef.current = undefined; // a fresh turn owns no slot yet\n syncTurn(turn); // appends the bubble AND resets this-turn state\n flush(); // \"thinking\" feedback must never wait on a throttle window\n\n // A response journaled for `resume.endpoint` carries its event ids\n // (2.3): they move the cursor, so a reconnect resumes after what this\n // read delivered instead of replaying it into the transcript again.\n // The persisted cursor (`resume.cursor`) still moves on resume reads\n // only. A core older than 2.3 reports no ids; nothing changes then.\n const resume = options.resume;\n let cursorRead = false;\n const ledger = newLedger(lastEventIdRef.current);\n ledger.afterCursor = true; // a POST leg is new: none of it came before\n // A non-2xx route (500 + an HTML error page, 401, 429) yields a\n // single `error` part → turn.error → the throw below → status 'error'.\n // Before 1.9 it streamed nothing and rendered an empty bubble.\n for await (const part of readDeuzStream(res, {\n ...(options.onHttpError ? { onHttpError: options.onHttpError } : {}),\n ...(resume\n ? {\n onEventId: (id: string) => {\n lastEventIdRef.current = id;\n cursorRead = true;\n },\n }\n : {}),\n })) {\n if (resume) recordPart(ledger, turn, part);\n turn = fold(turn, part);\n turnRef.current = turn;\n if (cursorRead) {\n cursorTurnRef.current = turn;\n cursorLedgerRef.current = ledger;\n }\n syncTurn(turn);\n }\n // A stream that ended WITHOUT `finish`/`error` (a dropped connection)\n // leaves the tail text/reasoning part 'streaming' by design — that\n // boundary belongs to the binding, so close it here. Returns the SAME\n // object when there is nothing to seal, hence no wasted render.\n const sealed = sealAssistantTurn(turn);\n if (sealed !== turn) {\n turn = sealed;\n turnRef.current = turn;\n if (cursorRead) cursorTurnRef.current = turn;\n syncTurn(turn);\n }\n flush(); // terminal frame — never coalesced away\n if (turn.error !== undefined) throw new Error(turn.error);\n\n // The settlement `reconnect()` shares (F07): done or paused → stop.\n const next = await settleTurn(turn, undefined, cursorRead);\n if (!next) return;\n continuation = next; // loop → next round POSTs the extended history\n }\n } catch (err) {\n if (controller.signal.aborted) {\n // User abort — not an error. No `finish` arrived, so the tail part is\n // still 'streaming'; sealing it is the binding's job (see core's\n // `sealAssistantTurn` docstring).\n const open = turnRef.current;\n if (open) {\n const sealed = sealAssistantTurn(open);\n turnRef.current = sealed;\n if (cursorTurnRef.current === open) cursorTurnRef.current = sealed;\n if (sealed !== open) syncTurn(sealed);\n }\n return;\n }\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n setStatus('error');\n options.onError?.(e);\n return;\n } finally {\n // Only the current round ends the streaming status (2.3): a round a\n // newer one replaced, such as a gate's whose client calls were still\n // running when a message was sent, must not flip that stream to idle.\n if (abortRef.current === controller) setStatus((s) => (s === 'error' ? s : 'idle'));\n flush(); // every exit path publishes the last frame\n }\n },\n [\n options.api,\n options.fetch,\n options.headers,\n options.body,\n options.chatId,\n options.generateId,\n options.onError,\n options.onHttpError,\n options.resume,\n fold,\n flush,\n settleClientCalls,\n settleTurn,\n syncTurn,\n ],\n );\n\n const sendMessage = useCallback(\n async (input: ChatInput): Promise<void> => {\n // ONE core projection feeds both views, so the user bubble carries its\n // ordered `parts` (incl. `file` elements for attachments) with no\n // React-side message building. A bare string is byte-identical to 1.8:\n // `userMessageFromInput` keeps `content` a plain STRING, so a prompt-cache\n // prefix does not move when a caller upgrades.\n const message = userMessageFromInput(input);\n const bubble = uiFromMessages([message], genId)[0];\n const previous = snapshotRef.current;\n commit({\n ...previous,\n history: {\n ui: bubble ? [...previous.history.ui, bubble] : previous.history.ui,\n canonical: [...previous.history.canonical, message],\n },\n });\n clearGates();\n flush();\n await run();\n },\n [run, commit, clearGates, flush, options.generateId],\n );\n\n const regenerate = useCallback(async (): Promise<void> => {\n const previous = snapshotRef.current;\n commit({ ...previous, history: dropTrailingAssistant(previous.history) });\n clearGates();\n flush();\n await run();\n }, [run, commit, clearGates, flush]);\n\n const editAndResend = useCallback(\n async (messageId: string, input: ChatInput): Promise<void> => {\n const previous = snapshotRef.current;\n const cut = branchBeforeUserMessage(previous.history, messageId);\n if (!cut) return; // not a user message — nothing to branch\n commit({ ...previous, history: cut });\n clearGates();\n flush();\n await sendMessage(input);\n },\n [sendMessage, commit, clearGates, flush],\n );\n\n const setHistory = useCallback(\n (update: ChatHistory | ((prev: ChatHistory) => ChatHistory)): void => {\n const previous = snapshotRef.current;\n const next = typeof update === 'function' ? update(previous.history) : update;\n // Replace BOTH views WHOLESALE, in ONE commit. Never splice the canonical\n // array in place: the loops and prompt caching depend on prior arrays\n // staying stable (immutable history). `placedIdRef` is left alone — it is\n // only a lookup key, and `syncTurn` appends when the id is gone, so a\n // live turn survives a replacement that keeps it and re-appends when not.\n commit({\n ...previous,\n history: { ui: [...next.ui], canonical: [...next.canonical] },\n });\n clearGates();\n // The in-memory resume cursor (2.3: POST reads move it too) addresses\n // the stream of the transcript just replaced, like the gates. After a\n // chat switch it would send the old chat's position to the new chat's\n // endpoint, so the next reconnect reads from the persisted cursor\n // (`resume.cursor`) or from the start, as before 2.3. Not in\n // `clearGates`: a send, regenerate or edit continues the same stream.\n lastEventIdRef.current = undefined;\n cursorTurnRef.current = undefined;\n cursorLedgerRef.current = newLedger();\n behindCursorRef.current = [];\n flush();\n },\n [commit, clearGates, flush],\n );\n\n const setMessages = useCallback(\n (update: UIMessage[] | ((prev: UIMessage[]) => UIMessage[])): void => {\n setHistory((prev) => {\n const ui = typeof update === 'function' ? update(prev.ui) : update;\n return { ui, canonical: canonicalFromUI(ui) };\n });\n },\n [setHistory],\n );\n\n const clearError = useCallback((): void => {\n setError(undefined);\n // Only the terminal error state is dismissible — a live stream is not.\n setStatus((s) => (s === 'error' ? 'idle' : s));\n }, []);\n\n const addToolResult = useCallback(\n async (result: { toolCallId: string; output: unknown; isError?: boolean }): Promise<void> => {\n const parked = clientToolsRef.current;\n const call = parked.find((c) => c.toolCallId === result.toolCallId);\n // Nothing parked under that id: ignore. An orphan `tool_result` (one with\n // no matching `tool_use`) 400s the next request, so it must never be\n // POSTed — same invariant the core tool loop enforces server-side.\n if (!call) return;\n toolResultsRef.current = [\n ...toolResultsRef.current.filter((r) => r.toolCallId !== result.toolCallId),\n {\n toolCallId: result.toolCallId,\n result: result.output,\n ...(result.isError ? { isError: true } : {}),\n },\n ];\n const turn = parkedTurnRef.current;\n if (turn) {\n // Same reducer path the in-hook executor takes, so the card renders\n // 'result' identically whichever side answered it.\n const next = applyUIPart(turn, {\n type: 'tool-result',\n toolCallId: result.toolCallId,\n toolName: call.toolName,\n output: result.output,\n ...(result.isError ? { isError: true } : {}),\n });\n parkedTurnRef.current = next;\n // Into the parked turn's own bubble, as `settleClientCalls` does (2.3).\n placedIdRef.current = next.message.id;\n syncTurn(next);\n flush(); // a user action, not a stream delta — show it now\n }\n const answered = toolResultsRef.current;\n if (!parked.every((c) => answered.some((r) => r.toolCallId === c.toolCallId))) return;\n // A parked native run (2.3) resumes with these results and its verdicts.\n const native = parkedNativeRef.current;\n clientToolsRef.current = [];\n toolResultsRef.current = [];\n parkedTurnRef.current = undefined;\n parkedNativeRef.current = undefined;\n setPendingToolCalls([]);\n appendCanonical(clientToolResultMessage(answered));\n await run(\n native ? { ...native, clientToolResults: answered.map(asClientToolResult) } : undefined,\n );\n },\n [run, appendCanonical, syncTurn, flush],\n );\n\n const addToolApprovalResponse = useCallback(\n async (response: ToolApprovalResponse): Promise<void> => {\n const gate = approvalsRef.current;\n // F06 (2.3): a verdict must answer a request of the gate the chat is\n // paused on; anything else is a NO-OP — the `addToolResult` contract: no\n // request, no state change. Before, `every()` over an EMPTY gate was\n // `true`, so a verdict with nothing pending (a double click after the\n // gate completed, a stale card, another run's verdict) POSTed a fresh\n // round and rendered an empty bubble, and a foreign verdict recorded\n // while a gate was open rode along in its `approvalResponses`.\n const targets = gate.filter((request) => answersRequest(response, request));\n if (targets.length === 0) return;\n // One verdict per request identity, carrying that request's signed token\n // unless the caller set one (`answersRequest` proved it equal). Answering\n // the same request again before the gate completes REPLACES the verdict.\n const recorded: ToolApprovalResponse[] = [];\n for (const request of targets) {\n const verdict =\n response.token === undefined && request.token !== undefined\n ? { ...response, token: request.token }\n : response;\n if (!recorded.some((v) => sameTarget(v, verdict))) recorded.push(verdict);\n }\n verdictsRef.current = [\n ...verdictsRef.current.filter((v) => !recorded.some((r) => sameTarget(r, v))),\n ...recorded,\n ];\n const verdicts = verdictsRef.current;\n if (!gate.every((request) => verdicts.some((v) => sameTarget(v, request)))) return;\n // Consumed. Cleared BEFORE the round starts, so a verdict that lands while\n // it is in flight finds no gate and is a no-op too.\n approvalsRef.current = [];\n verdictsRef.current = [];\n setPendingApprovals([]);\n // A native run (2.3) resumes only with every verdict AND every client\n // result in one request: its client calls run (or park) first, inside\n // the round that resumes it.\n const native = nativeGateRef.current;\n nativeGateRef.current = undefined;\n if (native) {\n await run(undefined, {\n turn: native.turn,\n clientCalls: native.clientCalls,\n resume: { runId: native.runId, approvalResponses: verdicts },\n });\n return;\n }\n await run({ approvalResponses: verdicts });\n },\n [run],\n );\n\n /**\n * The resume read. `silent` marks the AUTOMATIC on-mount attempt: a failure\n * there is invisible (see `resume.auto`), because nothing the user did failed\n * and a dead endpoint would otherwise paint an error on every cold load.\n */\n const runResume = useCallback(\n async (silent: boolean): Promise<void> => {\n const resume = options.resume;\n if (!resume) return;\n const controller = new AbortController();\n abortRef.current = controller;\n setStatus('streaming');\n setError(undefined);\n let folded = 0;\n try {\n // In-memory cursor (this session's stream, or `resume.lastEventId`)\n // beats the persisted one — it is strictly the more recent of the two.\n const cursor = lastEventIdRef.current ?? loadCursor(resume);\n const inFlight = turnRef.current;\n // The replay continues the in-flight turn only when the cursor\n // addresses THAT turn (2.3, see `cursorTurnRef`). Otherwise it rebuilds\n // the turn — from the start without a cursor, from the cursor when the\n // in-flight turn is one a POST read built without ids — and the rebuilt\n // turn takes the place of a partial one already on screen\n // (`placedIdRef` keeps pointing at it). With nothing on screen the turn\n // stays UNPLACED until the first part arrives, so a caught-up endpoint\n // answering `[DONE]` immediately is a silent no-op, not an empty bubble.\n const continuing =\n inFlight !== undefined && cursor !== undefined && cursorTurnRef.current === inFlight;\n if (inFlight === undefined) placedIdRef.current = undefined;\n let turn = continuing && inFlight ? inFlight : createAssistantTurn(genId());\n turnRef.current = turn;\n cursorTurnRef.current = turn;\n if (!continuing) priorResultsRef.current = [];\n // A continued turn keeps what its earlier reads saw.\n const ledger = continuing ? cursorLedgerRef.current : newLedger(cursor);\n cursorLedgerRef.current = ledger;\n const parts = connectDeuzStream(resume.endpoint, {\n ...(cursor !== undefined ? { lastEventId: cursor } : {}),\n onCursor: (id) => {\n ledger.afterCursor ??= isLaterId(id, ledger.cursor);\n lastEventIdRef.current = id;\n saveCursor(resume, id);\n },\n signal: controller.signal,\n ...(options.fetch ? { fetch: options.fetch } : {}),\n ...(options.headers ? { headers: options.headers } : {}),\n });\n for await (const part of parts) {\n folded++;\n recordPart(ledger, turn, part);\n turn = fold(turn, part);\n turnRef.current = turn;\n cursorTurnRef.current = turn;\n syncTurn(turn);\n }\n if (folded === 0) {\n // Already caught up: nothing arrived, so nothing changed and nothing\n // may be appended to the canonical history (an empty assistant\n // message would poison the next request). Not an error. The turn we\n // speculatively created is discarded; a real in-flight one is kept\n // (sealed — no `finish` is coming for it now).\n const kept = inFlight === undefined ? undefined : sealAssistantTurn(inFlight);\n turnRef.current = kept;\n cursorTurnRef.current = continuing ? kept : undefined;\n return;\n }\n if (controller.signal.aborted) {\n // `connectDeuzStream` ends QUIETLY on a user abort, so the loop above\n // just stops. That ends the read, not the turn: like the POST path's\n // abort, seal what arrived and settle nothing (2.3) — settling would\n // append a turn the user stopped and run its client tools. The cursor\n // still addresses this turn, so the next `reconnect()` continues it.\n const stopped = sealAssistantTurn(turn);\n turnRef.current = stopped;\n cursorTurnRef.current = stopped;\n if (stopped !== turn) syncTurn(stopped);\n return;\n }\n const sealed = sealAssistantTurn(turn);\n if (sealed !== turn) {\n turn = sealed;\n syncTurn(turn);\n }\n turnRef.current = turn;\n cursorTurnRef.current = turn;\n if (turn.error !== undefined) throw new Error(turn.error);\n // The settlement the POST path uses (F07): approvals pause the chat and\n // unresolved client calls reach `onToolCall` or `pendingToolCalls`.\n // Results from `onToolCall` continue the chat with a POST, as the POST\n // path's loop does — unless the user stopped it while they ran.\n const next = await settleTurn(turn, { ledger });\n if (next && !controller.signal.aborted) await run(next);\n } catch (err) {\n if (controller.signal.aborted) return; // user abort — not an error\n if (silent) return; // best-effort auto attempt — invisible by contract\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n setStatus('error');\n options.onError?.(e);\n return;\n } finally {\n setStatus((s) => (s === 'error' ? s : 'idle'));\n flush();\n }\n },\n [\n options.resume,\n options.fetch,\n options.headers,\n options.generateId,\n options.onError,\n fold,\n flush,\n run,\n settleTurn,\n syncTurn,\n ],\n );\n\n const reconnect = useCallback((): Promise<void> => runResume(false), [runResume]);\n\n /**\n * `resume.auto`: ONE attempt per mounted hook. The ref guard is what makes\n * React 18/19 StrictMode's deliberate mount → unmount → mount effect\n * double-invoke fire a single request — refs survive it, an effect body does\n * not. Deliberately not undone on cleanup for exactly that reason.\n */\n const autoResumedRef = useRef(false);\n useEffect(() => {\n if (options.resume?.auto !== true || autoResumedRef.current) return;\n autoResumedRef.current = true;\n void runResume(true);\n }, [options.resume?.auto, runResume]);\n\n return {\n messages: snapshot.history.ui,\n history: snapshot.history,\n status,\n error,\n pendingApprovals,\n pendingToolCalls,\n ...(snapshot.cost !== undefined ? { cost: snapshot.cost } : {}),\n ...(snapshot.budgetExceeded !== undefined ? { budgetExceeded: snapshot.budgetExceeded } : {}),\n dataParts: snapshot.dataParts,\n citations: snapshot.citations,\n ...(snapshot.plan !== undefined ? { plan: snapshot.plan } : {}),\n activity: snapshot.activity,\n ...(snapshot.verifications !== undefined ? { verifications: snapshot.verifications } : {}),\n ...(snapshot.warnings !== undefined ? { warnings: snapshot.warnings } : {}),\n ...(snapshot.falseFinishes !== undefined ? { falseFinishes: snapshot.falseFinishes } : {}),\n ...(snapshot.subAgents !== undefined ? { subAgents: snapshot.subAgents } : {}),\n ...(snapshot.steps !== undefined ? { steps: snapshot.steps } : {}),\n ...(snapshot.usage !== undefined ? { usage: snapshot.usage } : {}),\n ...(snapshot.finishReason !== undefined ? { finishReason: snapshot.finishReason } : {}),\n ...(snapshot.stopDetails !== undefined ? { stopDetails: snapshot.stopDetails } : {}),\n ...(snapshot.agent !== undefined ? { agent: snapshot.agent } : {}),\n sendMessage,\n stop,\n regenerate,\n editAndResend,\n setHistory,\n setMessages,\n addToolResult,\n clearError,\n addToolApprovalResponse,\n reconnect,\n };\n}\n","/**\n * useObject — streams `toDeuzObjectStreamResponse` output (`object-delta`\n * parts) into React state. Ported from the frozen `@deuz-sdk/core/react` hook.\n *\n * 1.9 adds the two options `useChat` grew for the same reasons: `onHttpError`\n * (forwarded verbatim to core's `readDeuzStream`) and `throttleMs` — a\n * structured-output stream emits one partial per token, and each partial\n * REPLACES the object wholesale, so an unthrottled render tree rebuilds on\n * every token.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { DeepPartial } from '@deuz-sdk/core';\nimport { readDeuzStream } from '@deuz-sdk/core/ui';\n\nexport interface UseObjectOptions {\n /** Endpoint serving `toDeuzObjectStreamResponse` output. */\n api: string;\n headers?: Record<string, string>;\n /**\n * How a NON-2xx response from `api` is reported (default `'error-part'`,\n * which lands in `error`). Forwarded verbatim to core's `readDeuzStream`.\n */\n onHttpError?: 'error-part' | 'ignore';\n /**\n * Coalesce partials to at most one React commit per `throttleMs` (trailing\n * edge). Default `0` — commit every partial, exactly as 1.8 did. The final\n * partial is ALWAYS flushed, so the completed object is never lost.\n */\n throttleMs?: number;\n /** Injectable for tests / custom transports. Defaults to global fetch. */\n fetch?: typeof fetch;\n}\n\nexport interface UseObjectResult<T> {\n /** Latest partial (each `object-delta` replaces it wholesale). */\n object: DeepPartial<T> | undefined;\n isLoading: boolean;\n error: Error | undefined;\n /** POSTs `{ input }` to `api` and streams partials into `object`. */\n submit: (input: unknown) => Promise<void>;\n /** Abort the in-flight stream (not an error). */\n stop: () => void;\n}\n\nexport function useObject<T = unknown>(options: UseObjectOptions): UseObjectResult<T> {\n const [object, setObject] = useState<DeepPartial<T> | undefined>(undefined);\n const [isLoading, setLoading] = useState(false);\n const [error, setError] = useState<Error | undefined>(undefined);\n const abortRef = useRef<AbortController | null>(null);\n\n // Coalescing plumbing (same trailing-edge shape as `useChat`, one value wide).\n const throttleMs = options.throttleMs ?? 0;\n const latestRef = useRef<DeepPartial<T> | undefined>(undefined);\n const timerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const dirtyRef = useRef(false);\n\n const publish = useCallback((): void => {\n timerRef.current = undefined;\n dirtyRef.current = false;\n setObject(latestRef.current);\n }, []);\n\n const commit = useCallback(\n (next: DeepPartial<T> | undefined): void => {\n latestRef.current = next;\n if (throttleMs <= 0) {\n publish();\n return;\n }\n dirtyRef.current = true;\n if (timerRef.current === undefined) timerRef.current = setTimeout(publish, throttleMs);\n },\n [throttleMs, publish],\n );\n\n const flush = useCallback((): void => {\n if (timerRef.current !== undefined) {\n clearTimeout(timerRef.current);\n timerRef.current = undefined;\n }\n if (dirtyRef.current) publish();\n }, [publish]);\n\n /** A coalesced frame must not fire into an unmounted tree. */\n useEffect(\n () => () => {\n if (timerRef.current !== undefined) clearTimeout(timerRef.current);\n },\n [],\n );\n\n const stop = useCallback((): void => {\n abortRef.current?.abort();\n }, []);\n\n const submit = useCallback(\n async (input: unknown): Promise<void> => {\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n setLoading(true);\n setError(undefined);\n commit(undefined);\n flush(); // clearing the previous object is immediate, never coalesced\n try {\n const doFetch = options.fetch ?? fetch;\n const res = await doFetch(options.api, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...options.headers },\n body: JSON.stringify({ input }),\n signal: controller.signal,\n });\n for await (const part of readDeuzStream(res, {\n ...(options.onHttpError ? { onHttpError: options.onHttpError } : {}),\n })) {\n if (part.type === 'object-delta') {\n commit(part.object as DeepPartial<T>);\n } else if (part.type === 'error') {\n setError(new Error(part.message));\n break;\n }\n }\n } catch (err) {\n if (!controller.signal.aborted) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n } finally {\n setLoading(false);\n flush(); // the completed object is never lost to a throttle window\n }\n },\n [options.api, options.fetch, options.headers, options.onHttpError, commit, flush],\n );\n\n return { object, isLoading, error, submit, stop };\n}\n","/**\n * Headless chat components — zero styling, zero business logic. They only\n * wire core types (`ToolApprovalRequest`/`ToolApprovalResponse`, the useChat\n * cost state) to DOM events; presentation is overridable via render props.\n */\nimport type { ReactNode } from 'react';\nimport type { ToolApprovalRequest, ToolApprovalResponse } from '@deuz-sdk/core';\nimport type { UseChatCost } from './use-chat';\n\nexport interface ToolApprovalCardProps {\n approval: ToolApprovalRequest;\n /** Feed this straight into `useChat().addToolApprovalResponse`. */\n onRespond: (response: ToolApprovalResponse) => void;\n /** Override presentation; the component supplies the wired callbacks. */\n render?: (ctx: {\n approval: ToolApprovalRequest;\n approve: () => void;\n deny: (reason?: string) => void;\n }) => ReactNode;\n}\n\n/**\n * One pending tool approval. The verdict always carries the request's signed\n * `token` (D4) — callers never have to thread it themselves.\n */\nexport function ToolApprovalCard({ approval, onRespond, render }: ToolApprovalCardProps) {\n const respond = (approved: boolean, reason?: string): void =>\n onRespond({\n approvalId: approval.approvalId,\n approved,\n ...(reason !== undefined ? { reason } : {}),\n ...(approval.token !== undefined ? { token: approval.token } : {}),\n });\n const approve = (): void => respond(true);\n const deny = (reason?: string): void => respond(false, reason);\n\n if (render) return <>{render({ approval, approve, deny })}</>;\n return (\n <div data-deuz=\"tool-approval\">\n <span data-deuz=\"tool-approval-name\">{approval.toolName}</span>\n <pre data-deuz=\"tool-approval-input\">{JSON.stringify(approval.input, null, 2)}</pre>\n <button type=\"button\" onClick={approve}>\n Approve\n </button>\n <button type=\"button\" onClick={() => deny()}>\n Deny\n </button>\n </div>\n );\n}\n\nexport interface CostBadgeProps {\n /** The `useChat` cost state (undefined until the first `cost` part arrives). */\n cost: UseChatCost | undefined;\n /** Override presentation. */\n format?: (cost: UseChatCost) => ReactNode;\n}\n\n/** Live cost readout: `$X.XXXX`, plus ` (saved $Y.YYYY)` when caching saved money. */\nexport function CostBadge({ cost, format }: CostBadgeProps) {\n if (cost === undefined) return null;\n if (format) return <>{format(cost)}</>;\n const saved =\n cost.cacheSavingsUsd !== undefined && cost.cacheSavingsUsd > 0\n ? ` (saved $${cost.cacheSavingsUsd.toFixed(4)})`\n : '';\n return <span data-deuz=\"cost-badge\">{`$${cost.costUsd.toFixed(4)}${saved}`}</span>;\n}\n"]}