@x12i/ai 1.0.0 → 1.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/messages.ts","../src/thread-state.ts","../src/errors.ts","../src/stream.ts","../src/citations.ts","../src/format.ts","../src/markdown-safety.ts"],"sourcesContent":["import type {\n DataPart,\n FilePart,\n Message,\n ReasoningPart,\n SourcePart,\n TextPart,\n ToolPart,\n} from \"./types\";\n\n/** The text of a message: its text parts, joined. Reasoning and tool output are left out. */\nexport function messageText(message: Message): string {\n return message.parts\n .filter((part): part is TextPart => part.type === \"text\")\n .map((part) => part.text)\n .join(\"\");\n}\n\n/** The reasoning of a message, joined. Empty when the model produced none. */\nexport function messageReasoning(message: Message): string {\n return message.parts\n .filter((part): part is ReasoningPart => part.type === \"reasoning\")\n .map((part) => part.text)\n .join(\"\\n\\n\");\n}\n\n/** Tool calls that are waiting for a human decision. */\nexport function pendingApprovals(message: Message): ToolPart[] {\n return message.parts.filter(\n (part): part is ToolPart => part.type === \"tool\" && part.state === \"needs-approval\",\n );\n}\n\n/** Tool calls waiting for a human decision anywhere in a thread, oldest first. */\nexport function threadPendingApprovals(messages: readonly Message[]): ToolPart[] {\n return messages.flatMap(pendingApprovals);\n}\n\n/** The tool calls of a message, in order. */\nexport function messageToolCalls(message: Message): ToolPart[] {\n return message.parts.filter((part): part is ToolPart => part.type === \"tool\");\n}\n\n/** The sources of a message, in order. A citation `[n]` points at the n-th. */\nexport function messageSources(message: Message): SourcePart[] {\n return message.parts.filter((part): part is SourcePart => part.type === \"source\");\n}\n\n/** The files of a message, in order. */\nexport function messageFiles(message: Message): FilePart[] {\n return message.parts.filter((part): part is FilePart => part.type === \"file\");\n}\n\n/** The structured data parts of a message, in order. */\nexport function messageData(message: Message): DataPart[] {\n return message.parts.filter((part): part is DataPart => part.type === \"data\");\n}\n\n/** Finds a tool call by id anywhere in a list of messages, searching newest first. */\nexport function findToolCall(\n messages: readonly Message[],\n callId: string,\n): { message: Message; part: ToolPart } | undefined {\n for (let m = messages.length - 1; m >= 0; m -= 1) {\n const message = messages[m];\n if (!message) continue;\n for (let p = message.parts.length - 1; p >= 0; p -= 1) {\n const part = message.parts[p];\n if (part && part.type === \"tool\" && part.id === callId) return { message, part };\n }\n }\n return undefined;\n}\n\n/** True while a message is still being written. */\nexport function isStreaming(message: Message): boolean {\n return message.status === \"streaming\";\n}\n\n/** The last message with the given role, or undefined. */\nexport function lastMessageWithRole(\n messages: readonly Message[],\n role: Message[\"role\"],\n): Message | undefined {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (message && message.role === role) return message;\n }\n return undefined;\n}\n","import type {\n FilePart,\n FinishReason,\n Message,\n MessagePart,\n ReasoningPart,\n SourcePart,\n TextPart,\n ThreadError,\n ToolApproval,\n ToolPart,\n ToolState,\n Usage,\n} from \"./types\";\n\n/**\n * Thread state and its reducer.\n *\n * `threadReducer(state, action)` is a pure function: it never mutates `state`\n * or an action, it returns the same `state` object when an action changes\n * nothing, and it never reads a clock or generates a random id. Time comes in\n * through the optional `at` (epoch milliseconds) on actions, and ids come in\n * through the actions or, when a provider sends none, a deterministic counter.\n * That makes it safe in React, in tests and in server code.\n */\n\n/**\n * - `idle`: nothing in flight.\n * - `submitted`: a request was sent and nothing has come back yet.\n * - `streaming`: an assistant message is being written.\n * - `error`: the last request failed; `error` has the cause.\n */\nexport type ThreadStatus = \"idle\" | \"submitted\" | \"streaming\" | \"error\";\n\n/**\n * Versions of one place in the thread, made by editing a message with\n * `mode: \"branch\"`. `alternatives` holds the versions that are not showing,\n * each one a whole tail of the thread; the showing version is `messages`.\n */\nexport interface BranchPoint {\n /** The message the versions follow, or `\"\"` when the versions start the thread. */\n parentId: string;\n /** The versions that are not showing. */\n alternatives: Message[][];\n /** Where the showing version sits among all versions, from 0. */\n activeIndex: number;\n}\n\nexport interface ThreadState {\n /** The messages on the showing path, oldest first. */\n messages: Message[];\n status: ThreadStatus;\n error: ThreadError | null;\n /** The assistant message being written, or null. */\n activeMessageId: string | null;\n /** Branch points by `parentId`. */\n branches: Record<string, BranchPoint>;\n}\n\nexport interface BranchInfo {\n parentId: string;\n /** The showing version, from 0. */\n index: number;\n /** How many versions exist, including the showing one. */\n count: number;\n}\n\nexport interface ToolCallPatch {\n name?: string;\n input?: unknown;\n output?: unknown;\n state?: ToolState;\n error?: string;\n errorCode?: string;\n durationMs?: number;\n approval?: ToolApproval;\n}\n\nexport type ThreadAction =\n /** Replaces the whole thread, for example after loading from a store. */\n | { type: \"set-messages\"; messages: Message[] }\n /** Adds a ready-made message (system notes, restored history). A duplicate id is ignored. */\n | { type: \"add-message\"; message: Message }\n | {\n type: \"add-user-message\";\n id: string;\n text?: string;\n attachments?: FilePart[];\n parts?: MessagePart[];\n createdAt?: string;\n /** Defaults to `submitted`: the user message starts a request. */\n status?: ThreadStatus;\n }\n /** Starts an assistant message. With an existing id it reopens that message. */\n | { type: \"begin-assistant-message\"; id?: string; createdAt?: string; metadata?: Record<string, unknown> }\n | { type: \"append-text\"; delta: string; messageId?: string; at?: number }\n | { type: \"append-reasoning\"; delta: string; messageId?: string; at?: number }\n | { type: \"end-reasoning\"; messageId?: string; durationMs?: number; at?: number }\n | {\n type: \"start-tool-call\";\n callId: string;\n name: string;\n input?: unknown;\n state?: ToolState;\n requiresApproval?: boolean;\n approvalPrompt?: string;\n messageId?: string;\n at?: number;\n }\n | { type: \"update-tool-call\"; callId: string; patch: ToolCallPatch; messageId?: string; at?: number }\n | {\n type: \"finish-tool-call\";\n callId: string;\n name?: string;\n output?: unknown;\n error?: string;\n errorCode?: string;\n durationMs?: number;\n messageId?: string;\n at?: number;\n }\n /** A human decision on a tool call that needs approval. */\n | { type: \"tool-decision\"; callId: string; decision: \"approved\" | \"denied\"; reason?: string }\n | { type: \"add-source\"; source: Omit<SourcePart, \"type\">; messageId?: string }\n | { type: \"add-part\"; part: MessagePart; messageId?: string }\n | { type: \"attach-files\"; files: FilePart[]; messageId?: string }\n | {\n type: \"finish\";\n messageId?: string;\n usage?: Usage;\n finishReason?: FinishReason;\n at?: number;\n }\n | { type: \"error\"; error: ThreadError | string; messageId?: string; at?: number }\n /** The user stopped the response. Content so far is kept. */\n | { type: \"abort\"; messageId?: string; at?: number }\n /** Drops the assistant reply to the last user message and gets ready to ask again. */\n | { type: \"regenerate\" }\n | {\n type: \"edit-message\";\n messageId: string;\n text?: string;\n parts?: MessagePart[];\n /**\n * For user messages: `truncate` (default) replaces the message and drops\n * everything after it; `branch` keeps the old version reachable through\n * `switch-branch`. Other roles are edited in place.\n */\n mode?: \"truncate\" | \"branch\";\n /** Id of the new version in `branch` mode. Defaults to `<id>~<n>`. */\n newId?: string;\n createdAt?: string;\n }\n | { type: \"switch-branch\"; parentId: string; index: number }\n | { type: \"dismiss-error\" }\n | { type: \"clear\" }\n | { type: \"batch\"; actions: ThreadAction[] };\n\nconst TERMINAL_TOOL_STATES: ReadonlySet<ToolState> = new Set([\"succeeded\", \"failed\", \"denied\"]);\n\nexport function isTerminalToolState(state: ToolState): boolean {\n return TERMINAL_TOOL_STATES.has(state);\n}\n\nexport function isBusy(state: Pick<ThreadState, \"status\">): boolean {\n return state.status === \"submitted\" || state.status === \"streaming\";\n}\n\nexport function createThreadState(messages: readonly Message[] = []): ThreadState {\n return {\n messages: [...messages],\n status: \"idle\",\n error: null,\n activeMessageId: null,\n branches: {},\n };\n}\n\n// ---------------------------------------------------------------- helpers\n\n/** Drops keys whose value is undefined, so stored threads stay clean. */\nfunction defined<T extends object>(value: T): T {\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n if (entry !== undefined) result[key] = entry;\n }\n return result as T;\n}\n\nfunction shallowEqual(a: object, b: object): boolean {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) return false;\n const left = a as Record<string, unknown>;\n const right = b as Record<string, unknown>;\n return aKeys.every((key) => Object.is(left[key], right[key]));\n}\n\nfunction indexOfMessage(messages: readonly Message[], id: string): number {\n return messages.findIndex((message) => message.id === id);\n}\n\nfunction replaceAt<T>(items: readonly T[], index: number, item: T): T[] {\n const copy = items.slice();\n copy[index] = item;\n return copy;\n}\n\nfunction withMessage(state: ThreadState, index: number, message: Message): ThreadState {\n const current = state.messages[index];\n if (current === message) return state;\n return { ...state, messages: replaceAt(state.messages, index, message) };\n}\n\nfunction uniqueId(messages: readonly Message[], prefix: string, start: number): string {\n let n = start;\n while (messages.some((message) => message.id === `${prefix}${n}`)) n += 1;\n return `${prefix}${n}`;\n}\n\n/** Sets `durationMs` on the reasoning part that is still open at the end of `parts`. */\nfunction closeReasoning(parts: MessagePart[], at: number | undefined, durationMs?: number): MessagePart[] {\n const last = parts[parts.length - 1];\n if (!last || last.type !== \"reasoning\" || last.durationMs !== undefined) return parts;\n let duration = durationMs;\n if (duration === undefined && at !== undefined && last.startedAt !== undefined) {\n duration = Math.max(0, at - last.startedAt);\n }\n if (duration === undefined) return parts;\n return replaceAt(parts, parts.length - 1, { ...last, durationMs: duration });\n}\n\nfunction appendPart(parts: MessagePart[], part: MessagePart, at: number | undefined): MessagePart[] {\n return [...closeReasoning(parts, at), part];\n}\n\ninterface Target {\n state: ThreadState;\n index: number;\n message: Message;\n}\n\nfunction completeMessage(messages: Message[], id: string): Message[] {\n const index = indexOfMessage(messages, id);\n const message = messages[index];\n if (index < 0 || !message || message.status !== \"streaming\") return messages;\n return replaceAt(messages, index, { ...message, status: \"complete\" });\n}\n\nfunction beginAssistant(\n state: ThreadState,\n action: { id?: string | undefined; createdAt?: string | undefined; metadata?: Record<string, unknown> | undefined },\n): ThreadState {\n const id = action.id ?? uniqueId(state.messages, \"assistant-\", state.messages.length + 1);\n let messages = state.messages;\n\n // A new message ends the one that was being written.\n if (state.activeMessageId !== null && state.activeMessageId !== id) {\n messages = completeMessage(messages, state.activeMessageId);\n }\n\n const index = indexOfMessage(messages, id);\n if (index >= 0) {\n const existing = messages[index];\n if (!existing || existing.role !== \"assistant\") return state;\n if (\n existing.status === \"streaming\" &&\n state.activeMessageId === id &&\n state.status === \"streaming\" &&\n messages === state.messages\n ) {\n return state;\n }\n const reopened: Message = { ...existing, status: \"streaming\" };\n delete reopened.error;\n messages = replaceAt(messages, index, reopened);\n } else {\n messages = [\n ...messages,\n defined({\n id,\n role: \"assistant\" as const,\n parts: [] as MessagePart[],\n status: \"streaming\" as const,\n createdAt: action.createdAt,\n metadata: action.metadata,\n }),\n ];\n }\n\n return { ...state, messages, status: \"streaming\", error: null, activeMessageId: id };\n}\n\n/**\n * Finds the message a content action writes to. With no id it uses the active\n * message; when that does not exist either, it starts an assistant message, so\n * a delta that arrives before `begin-assistant-message` is not lost.\n */\nfunction resolveTarget(\n state: ThreadState,\n messageId: string | undefined,\n options: { anyRole?: boolean; createIfMissing?: boolean } = {},\n): Target | null {\n const id = messageId ?? state.activeMessageId ?? undefined;\n if (id !== undefined) {\n const index = indexOfMessage(state.messages, id);\n const message = state.messages[index];\n if (index >= 0 && message) {\n if (!options.anyRole) {\n if (message.role !== \"assistant\") return null;\n // A stopped or failed message does not take late content.\n if (message.status === \"stopped\" || message.status === \"error\") return null;\n }\n return { state, index, message };\n }\n }\n if (options.createIfMissing === false) return null;\n const created = beginAssistant(state, { id });\n // beginAssistant ignores an id that already belongs to a non-assistant message.\n if (created === state || created.activeMessageId === null) return null;\n const index = indexOfMessage(created.messages, created.activeMessageId);\n const message = created.messages[index];\n if (!message) return null;\n return { state: created, index, message };\n}\n\nfunction writeParts(target: Target, parts: MessagePart[]): ThreadState {\n if (parts === target.message.parts) return target.state;\n return withMessage(target.state, target.index, { ...target.message, parts });\n}\n\ninterface ToolLocation {\n messageIndex: number;\n partIndex: number;\n part: ToolPart;\n}\n\nfunction findToolLocation(messages: readonly Message[], callId: string): ToolLocation | null {\n for (let m = messages.length - 1; m >= 0; m -= 1) {\n const message = messages[m];\n if (!message) continue;\n for (let p = message.parts.length - 1; p >= 0; p -= 1) {\n const part = message.parts[p];\n if (part && part.type === \"tool\" && part.id === callId) {\n return { messageIndex: m, partIndex: p, part };\n }\n }\n }\n return null;\n}\n\nfunction writeToolPart(state: ThreadState, location: ToolLocation, next: ToolPart): ThreadState {\n if (next === location.part) return state;\n const message = state.messages[location.messageIndex];\n if (!message) return state;\n const parts = replaceAt(message.parts, location.partIndex, next);\n return withMessage(state, location.messageIndex, { ...message, parts });\n}\n\nfunction applyToolPatch(part: ToolPart, patch: ToolCallPatch, at: number | undefined): ToolPart {\n const next: ToolPart = { ...part };\n if (patch.name !== undefined) next.name = patch.name;\n if (patch.input !== undefined) next.input = patch.input;\n if (patch.output !== undefined) next.output = patch.output;\n if (patch.error !== undefined) next.error = patch.error;\n if (patch.errorCode !== undefined) next.errorCode = patch.errorCode;\n if (patch.durationMs !== undefined) next.durationMs = patch.durationMs;\n if (patch.approval !== undefined) next.approval = { ...part.approval, ...patch.approval };\n\n if (patch.state !== undefined) {\n // A finished call stays finished: a late \"running\" update cannot reopen it.\n const regressing = isTerminalToolState(part.state) && !isTerminalToolState(patch.state);\n if (!regressing) next.state = patch.state;\n }\n\n if (\n isTerminalToolState(next.state) &&\n next.durationMs === undefined &&\n next.startedAt !== undefined &&\n at !== undefined\n ) {\n next.durationMs = Math.max(0, at - next.startedAt);\n }\n\n return shallowEqual(next, part) ? part : next;\n}\n\nfunction newToolPart(\n callId: string,\n name: string,\n state: ToolState,\n at: number | undefined,\n): ToolPart {\n return defined({ type: \"tool\" as const, id: callId, name, state, startedAt: at });\n}\n\n// ------------------------------------------------------------- the actions\n\nfunction addUserMessage(\n state: ThreadState,\n action: Extract<ThreadAction, { type: \"add-user-message\" }>,\n): ThreadState {\n if (indexOfMessage(state.messages, action.id) >= 0) return state;\n\n const parts: MessagePart[] = [];\n if (action.parts) parts.push(...action.parts);\n if (action.text !== undefined && action.text !== \"\") parts.push({ type: \"text\", text: action.text });\n for (const file of action.attachments ?? []) parts.push(file);\n if (parts.length === 0) return state;\n\n let messages = state.messages;\n if (state.activeMessageId !== null) messages = completeMessage(messages, state.activeMessageId);\n\n const message: Message = defined({\n id: action.id,\n role: \"user\" as const,\n parts,\n createdAt: action.createdAt,\n });\n const status = action.status ?? \"submitted\";\n return {\n ...state,\n messages: [...messages, message],\n status,\n error: status === \"error\" ? state.error : null,\n activeMessageId: null,\n };\n}\n\nfunction appendText(state: ThreadState, action: Extract<ThreadAction, { type: \"append-text\" }>): ThreadState {\n if (action.delta === \"\") return state;\n const target = resolveTarget(state, action.messageId);\n if (!target) return state;\n const parts = closeReasoning(target.message.parts, action.at);\n const last = parts[parts.length - 1];\n const next: MessagePart[] =\n last && last.type === \"text\"\n ? replaceAt<MessagePart>(parts, parts.length - 1, { ...last, text: last.text + action.delta })\n : [...parts, { type: \"text\", text: action.delta } satisfies TextPart];\n return writeParts(target, next);\n}\n\nfunction appendReasoning(\n state: ThreadState,\n action: Extract<ThreadAction, { type: \"append-reasoning\" }>,\n): ThreadState {\n if (action.delta === \"\") return state;\n const target = resolveTarget(state, action.messageId);\n if (!target) return state;\n const parts = target.message.parts;\n const last = parts[parts.length - 1];\n if (last && last.type === \"reasoning\" && last.durationMs === undefined) {\n return writeParts(target, replaceAt<MessagePart>(parts, parts.length - 1, { ...last, text: last.text + action.delta }));\n }\n const part: ReasoningPart = defined({\n type: \"reasoning\" as const,\n text: action.delta,\n startedAt: action.at,\n });\n return writeParts(target, [...parts, part]);\n}\n\nfunction endReasoning(state: ThreadState, action: Extract<ThreadAction, { type: \"end-reasoning\" }>): ThreadState {\n const id = action.messageId ?? state.activeMessageId;\n if (id === null || id === undefined) return state;\n const index = indexOfMessage(state.messages, id);\n const message = state.messages[index];\n if (index < 0 || !message) return state;\n const parts = closeReasoning(message.parts, action.at, action.durationMs);\n if (parts === message.parts) return state;\n return withMessage(state, index, { ...message, parts });\n}\n\nfunction startToolCall(\n state: ThreadState,\n action: Extract<ThreadAction, { type: \"start-tool-call\" }>,\n): ThreadState {\n const wanted: ToolState = action.state ?? (action.requiresApproval ? \"needs-approval\" : \"running\");\n const existing = findToolLocation(state.messages, action.callId);\n\n if (existing) {\n // A repeated start (for example once the input has finished streaming) updates the call.\n const patch: ToolCallPatch = { name: action.name, state: wanted };\n if (action.input !== undefined) patch.input = action.input;\n if (action.approvalPrompt !== undefined) patch.approval = { prompt: action.approvalPrompt };\n return writeToolPart(state, existing, applyToolPatch(existing.part, patch, action.at));\n }\n\n const target = resolveTarget(state, action.messageId);\n if (!target) return state;\n const part = newToolPart(action.callId, action.name, wanted, action.at);\n if (action.input !== undefined) part.input = action.input;\n if (action.approvalPrompt !== undefined) part.approval = { prompt: action.approvalPrompt };\n return writeParts(target, appendPart(target.message.parts, part, action.at));\n}\n\nfunction updateToolCall(\n state: ThreadState,\n action: Extract<ThreadAction, { type: \"update-tool-call\" }>,\n): ThreadState {\n const existing = findToolLocation(state.messages, action.callId);\n if (existing) {\n return writeToolPart(state, existing, applyToolPatch(existing.part, action.patch, action.at));\n }\n // An update for a call we never saw creates it, so the data is not dropped.\n const target = resolveTarget(state, action.messageId);\n if (!target) return state;\n const created = applyToolPatch(\n newToolPart(action.callId, action.patch.name ?? action.callId, action.patch.state ?? \"running\", action.at),\n action.patch,\n action.at,\n );\n return writeParts(target, appendPart(target.message.parts, created, action.at));\n}\n\nfunction finishToolCall(\n state: ThreadState,\n action: Extract<ThreadAction, { type: \"finish-tool-call\" }>,\n): ThreadState {\n const failed = action.error !== undefined || action.errorCode !== undefined;\n const patch: ToolCallPatch = { state: failed ? \"failed\" : \"succeeded\" };\n if (action.output !== undefined) patch.output = action.output;\n if (action.error !== undefined) patch.error = action.error;\n if (action.errorCode !== undefined) patch.errorCode = action.errorCode;\n if (action.durationMs !== undefined) patch.durationMs = action.durationMs;\n\n const existing = findToolLocation(state.messages, action.callId);\n if (existing) {\n // A refused call has no result to record.\n if (existing.part.state === \"denied\") return state;\n return writeToolPart(state, existing, applyToolPatch(existing.part, patch, action.at));\n }\n\n // A result without a call creates the call, so the result is not lost.\n const target = resolveTarget(state, action.messageId);\n if (!target) return state;\n const created = applyToolPatch(\n newToolPart(action.callId, action.name ?? action.callId, \"running\", action.at),\n patch,\n action.at,\n );\n return writeParts(target, appendPart(target.message.parts, created, action.at));\n}\n\nfunction toolDecision(\n state: ThreadState,\n action: Extract<ThreadAction, { type: \"tool-decision\" }>,\n): ThreadState {\n const location = findToolLocation(state.messages, action.callId);\n if (!location || location.part.state !== \"needs-approval\") return state;\n const reason = action.reason?.trim();\n const approval: ToolApproval = { ...location.part.approval };\n if (reason) approval.reason = reason;\n const next: ToolPart = { ...location.part, state: action.decision, approval };\n if (Object.keys(approval).length === 0) delete next.approval;\n return writeToolPart(state, location, next);\n}\n\nfunction addSource(state: ThreadState, action: Extract<ThreadAction, { type: \"add-source\" }>): ThreadState {\n const target = resolveTarget(state, action.messageId);\n if (!target) return state;\n const parts = target.message.parts;\n const existingIndex = parts.findIndex((part) => part.type === \"source\" && part.id === action.source.id);\n const incoming: SourcePart = { type: \"source\", ...defined(action.source) };\n if (existingIndex >= 0) {\n const current = parts[existingIndex] as SourcePart;\n const merged: SourcePart = { ...current, ...incoming };\n return writeParts(target, shallowEqual(current, merged) ? parts : replaceAt<MessagePart>(parts, existingIndex, merged));\n }\n return writeParts(target, [...parts, incoming]);\n}\n\nfunction addPart(state: ThreadState, action: Extract<ThreadAction, { type: \"add-part\" }>): ThreadState {\n const { part } = action;\n if (part.type === \"source\") {\n return addSource(state, {\n type: \"add-source\",\n source: { id: part.id, title: part.title, url: part.url, snippet: part.snippet },\n ...(action.messageId ? { messageId: action.messageId } : {}),\n });\n }\n if (part.type === \"tool\" && findToolLocation(state.messages, part.id)) return state;\n const target = resolveTarget(state, action.messageId);\n if (!target) return state;\n return writeParts(target, appendPart(target.message.parts, part, undefined));\n}\n\nfunction attachFiles(state: ThreadState, action: Extract<ThreadAction, { type: \"attach-files\" }>): ThreadState {\n if (action.files.length === 0) return state;\n const fallback = state.messages[state.messages.length - 1]?.id;\n const id = action.messageId ?? state.activeMessageId ?? fallback;\n if (id === undefined || id === null) return state;\n const target = resolveTarget(state, id, { anyRole: true, createIfMissing: false });\n if (!target) return state;\n\n const known = new Set(\n target.message.parts.filter((part): part is FilePart => part.type === \"file\").map((part) => part.id ?? part.url),\n );\n const added = action.files.filter((file) => {\n const key = file.id ?? file.url;\n if (known.has(key)) return false;\n known.add(key);\n return true;\n });\n if (added.length === 0) return state;\n return writeParts(target, [...target.message.parts, ...added.map((file) => ({ ...file, type: \"file\" as const }))]);\n}\n\nfunction finishMessage(state: ThreadState, action: Extract<ThreadAction, { type: \"finish\" }>): ThreadState {\n const id = action.messageId ?? state.activeMessageId;\n let next = state;\n\n if (id !== null && id !== undefined) {\n const index = indexOfMessage(state.messages, id);\n const message = state.messages[index];\n if (index >= 0 && message) {\n const parts = closeReasoning(message.parts, action.at);\n const status = message.status === \"stopped\" || message.status === \"error\" ? message.status : \"complete\";\n const updated: Message = defined({\n ...message,\n parts,\n status,\n usage: action.usage ?? message.usage,\n finishReason: action.finishReason ?? message.finishReason,\n });\n next = shallowEqual(updated, message) ? state : withMessage(state, index, updated);\n }\n }\n\n const concernsActive = id === next.activeMessageId || next.activeMessageId === null;\n if (concernsActive && (next.status === \"streaming\" || next.status === \"submitted\")) {\n return { ...next, status: \"idle\", activeMessageId: null };\n }\n return next;\n}\n\nfunction toThreadErrorValue(error: ThreadError | string): ThreadError {\n return typeof error === \"string\" ? { message: error, kind: \"unknown\", retryable: true } : error;\n}\n\nfunction failMessage(state: ThreadState, action: Extract<ThreadAction, { type: \"error\" }>): ThreadState {\n const error = toThreadErrorValue(action.error);\n const id = action.messageId ?? state.activeMessageId;\n let messages = state.messages;\n\n if (id !== null && id !== undefined) {\n const index = indexOfMessage(messages, id);\n const message = messages[index];\n if (index >= 0 && message && message.role === \"assistant\") {\n if (message.status === \"streaming\" && message.parts.length === 0) {\n // Nothing was written: drop the empty bubble, the banner carries the error.\n messages = messages.filter((_, i) => i !== index);\n } else {\n messages = replaceAt(messages, index, {\n ...message,\n parts: closeReasoning(message.parts, action.at),\n status: \"error\",\n error,\n });\n }\n }\n }\n\n return { ...state, messages, status: \"error\", error, activeMessageId: null };\n}\n\nfunction abortMessage(state: ThreadState, action: Extract<ThreadAction, { type: \"abort\" }>): ThreadState {\n const id = action.messageId ?? state.activeMessageId;\n let messages = state.messages;\n\n if (id !== null && id !== undefined) {\n const index = indexOfMessage(messages, id);\n const message = messages[index];\n if (index >= 0 && message && message.role === \"assistant\" && message.status === \"streaming\") {\n if (message.parts.length === 0) {\n messages = messages.filter((_, i) => i !== index);\n } else {\n const parts = closeReasoning(message.parts, action.at).map((part): MessagePart => {\n if (part.type === \"tool\" && (part.state === \"running\" || part.state === \"queued\")) {\n return { ...part, state: \"failed\", errorCode: \"aborted\" };\n }\n return part;\n });\n messages = replaceAt(messages, index, { ...message, parts, status: \"stopped\" });\n }\n }\n }\n\n if (!isBusy(state) && messages === state.messages) return state;\n return {\n ...state,\n messages,\n status: isBusy(state) ? \"idle\" : state.status,\n activeMessageId: null,\n };\n}\n\nfunction regenerate(state: ThreadState): ThreadState {\n let end = state.messages.length;\n while (end > 0) {\n const last = state.messages[end - 1];\n if (last && (last.role === \"assistant\" || last.role === \"tool\")) end -= 1;\n else break;\n }\n const last = state.messages[end - 1];\n // Only a thread that ends with a user message can be asked again.\n if (!last || last.role !== \"user\") return state;\n const messages = state.messages.slice(0, end);\n return {\n ...state,\n messages,\n branches: pruneBranches(state.branches, messages),\n status: \"submitted\",\n error: null,\n activeMessageId: null,\n };\n}\n\nfunction editedParts(old: Message, action: Extract<ThreadAction, { type: \"edit-message\" }>): MessagePart[] {\n if (action.parts) return action.parts;\n const text = action.text ?? \"\";\n const parts: MessagePart[] = [];\n let placed = false;\n for (const part of old.parts) {\n if (part.type === \"text\") {\n if (!placed && text !== \"\") parts.push({ type: \"text\", text });\n placed = true;\n } else {\n parts.push(part);\n }\n }\n if (!placed && text !== \"\") parts.unshift({ type: \"text\", text });\n return parts;\n}\n\nfunction branchParentKey(messages: readonly Message[], index: number): string {\n return index <= 0 ? \"\" : (messages[index - 1]?.id ?? \"\");\n}\n\nfunction insertAt<T>(items: readonly T[], index: number, item: T): T[] {\n const copy = items.slice();\n copy.splice(Math.min(Math.max(index, 0), copy.length), 0, item);\n return copy;\n}\n\nfunction editMessage(state: ThreadState, action: Extract<ThreadAction, { type: \"edit-message\" }>): ThreadState {\n const index = indexOfMessage(state.messages, action.messageId);\n const old = state.messages[index];\n if (index < 0 || !old) return state;\n\n const parts = editedParts(old, action);\n if (parts.length === 0) return state;\n\n if (old.role !== \"user\") {\n const edited: Message = {\n ...old,\n parts,\n metadata: { ...old.metadata, edited: true },\n };\n return withMessage(state, index, edited);\n }\n\n const mode = action.mode ?? \"truncate\";\n const baseMetadata = { ...old.metadata, edited: true };\n\n if (mode === \"truncate\") {\n const edited: Message = defined({\n ...old,\n parts,\n metadata: baseMetadata,\n createdAt: action.createdAt ?? old.createdAt,\n });\n const messages = [...state.messages.slice(0, index), edited];\n return {\n ...state,\n messages,\n branches: pruneBranches(state.branches, messages),\n status: \"submitted\",\n error: null,\n activeMessageId: null,\n };\n }\n\n // Branch: keep the old version, show the new one.\n const newId =\n action.newId ?? uniqueId(state.messages, `${old.id}~`, (state.branches[branchParentKey(state.messages, index)]?.alternatives.length ?? 0) + 1);\n if (newId !== old.id && indexOfMessage(state.messages, newId) >= 0) return state;\n const parentKey = branchParentKey(state.messages, index);\n const currentTail = state.messages.slice(index);\n const edited: Message = defined({\n id: newId,\n role: \"user\" as const,\n parts,\n parentId: old.id,\n createdAt: action.createdAt,\n metadata: baseMetadata,\n });\n\n const existing = state.branches[parentKey];\n const all = existing ? insertAt(existing.alternatives, existing.activeIndex, currentTail) : [currentTail];\n const point: BranchPoint = { parentId: parentKey, alternatives: all, activeIndex: all.length };\n const messages = [...state.messages.slice(0, index), edited];\n return {\n ...state,\n messages,\n branches: pruneBranches({ ...state.branches, [parentKey]: point }, messages),\n status: \"submitted\",\n error: null,\n activeMessageId: null,\n };\n}\n\nfunction switchBranch(state: ThreadState, action: Extract<ThreadAction, { type: \"switch-branch\" }>): ThreadState {\n if (isBusy(state)) return state;\n const point = state.branches[action.parentId];\n if (!point) return state;\n const count = point.alternatives.length + 1;\n if (!Number.isInteger(action.index) || action.index < 0 || action.index >= count) return state;\n if (action.index === point.activeIndex) return state;\n\n let forkIndex = 0;\n if (action.parentId !== \"\") {\n const parentIndex = indexOfMessage(state.messages, action.parentId);\n if (parentIndex < 0) return state;\n forkIndex = parentIndex + 1;\n }\n\n const all = insertAt(point.alternatives, point.activeIndex, state.messages.slice(forkIndex));\n const nextTail = all[action.index];\n if (!nextTail) return state;\n const alternatives = all.filter((_, i) => i !== action.index);\n const messages = [...state.messages.slice(0, forkIndex), ...nextTail];\n return {\n ...state,\n messages,\n branches: { ...state.branches, [action.parentId]: { parentId: action.parentId, alternatives, activeIndex: action.index } },\n };\n}\n\n/** Drops branch points that can no longer be reached from the showing messages. */\nfunction pruneBranches(\n branches: Record<string, BranchPoint>,\n messages: readonly Message[],\n): Record<string, BranchPoint> {\n const keys = Object.keys(branches);\n if (keys.length === 0) return branches;\n\n const reachable = new Set<string>([\"\"]);\n for (const message of messages) reachable.add(message.id);\n\n const kept = new Set<string>();\n let changed = true;\n while (changed) {\n changed = false;\n for (const key of keys) {\n const point = branches[key];\n if (!point || kept.has(key) || !reachable.has(key)) continue;\n kept.add(key);\n changed = true;\n for (const tail of point.alternatives) for (const message of tail) reachable.add(message.id);\n }\n }\n\n if (kept.size === keys.length) return branches;\n const result: Record<string, BranchPoint> = {};\n for (const key of keys) {\n const point = branches[key];\n if (point && kept.has(key)) result[key] = point;\n }\n return result;\n}\n\n// ------------------------------------------------------------- the reducer\n\nexport function threadReducer(state: ThreadState, action: ThreadAction): ThreadState {\n switch (action.type) {\n case \"batch\": {\n let next = state;\n for (const inner of action.actions) next = threadReducer(next, inner);\n return next;\n }\n case \"set-messages\":\n return { ...createThreadState(action.messages) };\n case \"add-message\": {\n if (indexOfMessage(state.messages, action.message.id) >= 0) return state;\n return { ...state, messages: [...state.messages, action.message] };\n }\n case \"add-user-message\":\n return addUserMessage(state, action);\n case \"begin-assistant-message\":\n return beginAssistant(state, action);\n case \"append-text\":\n return appendText(state, action);\n case \"append-reasoning\":\n return appendReasoning(state, action);\n case \"end-reasoning\":\n return endReasoning(state, action);\n case \"start-tool-call\":\n return startToolCall(state, action);\n case \"update-tool-call\":\n return updateToolCall(state, action);\n case \"finish-tool-call\":\n return finishToolCall(state, action);\n case \"tool-decision\":\n return toolDecision(state, action);\n case \"add-source\":\n return addSource(state, action);\n case \"add-part\":\n return addPart(state, action);\n case \"attach-files\":\n return attachFiles(state, action);\n case \"finish\":\n return finishMessage(state, action);\n case \"error\":\n return failMessage(state, action);\n case \"abort\":\n return abortMessage(state, action);\n case \"regenerate\":\n return regenerate(state);\n case \"edit-message\":\n return editMessage(state, action);\n case \"switch-branch\":\n return switchBranch(state, action);\n case \"dismiss-error\": {\n if (state.error === null && state.status !== \"error\") return state;\n return { ...state, error: null, status: state.status === \"error\" ? \"idle\" : state.status };\n }\n case \"clear\": {\n if (\n state.messages.length === 0 &&\n state.status === \"idle\" &&\n state.error === null &&\n Object.keys(state.branches).length === 0\n ) {\n return state;\n }\n return createThreadState();\n }\n default:\n return state;\n }\n}\n\n// --------------------------------------------------------------- selectors\n\n/** The branch navigator data for a message, if it is where versions fork. */\nexport function getBranchInfo(state: ThreadState, messageId: string): BranchInfo | undefined {\n const index = indexOfMessage(state.messages, messageId);\n if (index < 0) return undefined;\n const parentId = branchParentKey(state.messages, index);\n const point = state.branches[parentId];\n if (!point) return undefined;\n return { parentId, index: point.activeIndex, count: point.alternatives.length + 1 };\n}\n\n/** All branch navigator data for the showing messages, by message id. */\nexport function getBranchInfoMap(state: ThreadState): Record<string, BranchInfo> {\n const result: Record<string, BranchInfo> = {};\n for (const message of state.messages) {\n const info = getBranchInfo(state, message.id);\n if (info) result[message.id] = info;\n }\n return result;\n}\n\n/** The last user message, which is what \"regenerate\" answers again. */\nexport function lastUserMessage(state: Pick<ThreadState, \"messages\">): Message | undefined {\n for (let i = state.messages.length - 1; i >= 0; i -= 1) {\n const message = state.messages[i];\n if (message && message.role === \"user\") return message;\n }\n return undefined;\n}\n","import type { ErrorKind, ThreadError } from \"./types\";\n\nfunction readNumber(source: unknown, key: string): number | undefined {\n if (typeof source !== \"object\" || source === null) return undefined;\n const value = (source as Record<string, unknown>)[key];\n return typeof value === \"number\" ? value : undefined;\n}\n\nfunction readString(source: unknown, key: string): string | undefined {\n if (typeof source !== \"object\" || source === null) return undefined;\n const value = (source as Record<string, unknown>)[key];\n return typeof value === \"string\" ? value : undefined;\n}\n\n/** True for the error `fetch` and `AbortController` produce when a request is cancelled. */\nexport function isAbortError(error: unknown): boolean {\n if (typeof error !== \"object\" || error === null) return false;\n const name = readString(error, \"name\");\n return name === \"AbortError\" || readString(error, \"code\") === \"ABORT_ERR\";\n}\n\n/** Retryable by default, except for moderation and auth, where retrying the same input will not help. */\nfunction defaultRetryable(kind: ErrorKind): boolean {\n return kind !== \"moderation\" && kind !== \"auth\";\n}\n\n/**\n * Turns anything a provider or `fetch` might throw into a `ThreadError` with a\n * `kind`, so the UI can show a distinct message for network failures, rate\n * limits and moderation blocks. It looks at the HTTP status (`status` or\n * `statusCode`), the error code and the message; it never reads secrets.\n */\nexport function toThreadError(error: unknown): ThreadError {\n if (typeof error === \"string\") {\n return { message: error, kind: \"unknown\", retryable: true };\n }\n\n const status = readNumber(error, \"status\") ?? readNumber(error, \"statusCode\");\n const code = readString(error, \"code\") ?? readString(error, \"type\");\n const message =\n readString(error, \"message\") ?? (error === undefined || error === null ? \"\" : String(error));\n const haystack = `${code ?? \"\"} ${message}`.toLowerCase();\n\n let kind: ErrorKind = \"unknown\";\n if (status === 429 || /rate[\\s_-]?limit|too many requests|quota/.test(haystack)) {\n kind = \"rate-limit\";\n } else if (\n status === 401 ||\n status === 403 ||\n /unauthori[sz]ed|invalid[\\s_-]?api[\\s_-]?key|authentication/.test(haystack)\n ) {\n kind = \"auth\";\n } else if (\n (typeof error === \"object\" && error !== null && readString(error, \"name\") === \"TypeError\") ||\n /failed to fetch|network|offline|econn\\w*|enotfound|etimedout|timeout|socket hang up|load failed/.test(\n haystack,\n )\n ) {\n kind = \"network\";\n } else if (/content[\\s_-]?(filter|policy)|moderation|safety|refusal|flagged/.test(haystack)) {\n kind = \"moderation\";\n } else if (status !== undefined && status >= 500) {\n kind = \"network\";\n }\n\n const result: ThreadError = { message, kind, retryable: defaultRetryable(kind) };\n if (code !== undefined) result.code = code;\n return result;\n}\n","import { toThreadError } from \"./errors\";\nimport { threadReducer, type ThreadAction, type ThreadState } from \"./thread-state\";\nimport type { FinishReason, ThreadError, ToolApproval, ToolState, Usage } from \"./types\";\n\n/**\n * Stream events: the one shape every provider is adapted to.\n *\n * A provider adapter is an async generator that yields these events. The\n * thread reducer (`applyStreamEvent`) turns each one into a state change, so\n * the UI never sees a provider SDK. Unknown event types are ignored, so an\n * adapter can pass extra events through without breaking older UIs.\n */\n\nexport interface StartEvent {\n type: \"start\";\n /** The assistant message id. Omit it and the hook or reducer makes one. */\n messageId?: string;\n createdAt?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface TextDeltaEvent {\n type: \"text-delta\";\n delta: string;\n messageId?: string;\n}\n\nexport interface ReasoningDeltaEvent {\n type: \"reasoning-delta\";\n delta: string;\n messageId?: string;\n}\n\n/** Ends the open reasoning block. Optional: the first text, tool call or finish also ends it. */\nexport interface ReasoningEndEvent {\n type: \"reasoning-end\";\n durationMs?: number;\n messageId?: string;\n}\n\nexport interface ToolCallEvent {\n type: \"tool-call\";\n callId: string;\n name: string;\n input?: unknown;\n /** Set when a human has to approve before the tool runs. */\n requiresApproval?: boolean;\n /** Why approval is needed. */\n approvalPrompt?: string;\n /** Overrides the starting state. Defaults to `running`, or `needs-approval`. */\n state?: ToolState;\n messageId?: string;\n}\n\nexport interface ToolUpdateEvent {\n type: \"tool-update\";\n callId: string;\n state?: ToolState;\n name?: string;\n input?: unknown;\n output?: unknown;\n error?: string;\n approval?: ToolApproval;\n messageId?: string;\n}\n\nexport interface ToolResultEvent {\n type: \"tool-result\";\n callId: string;\n output?: unknown;\n /** Present when the tool failed. */\n error?: string;\n durationMs?: number;\n /** Used only when this result arrives for a call that was never announced. */\n name?: string;\n messageId?: string;\n}\n\nexport interface SourceEvent {\n type: \"source\";\n id: string;\n title: string;\n url: string;\n snippet?: string;\n messageId?: string;\n}\n\nexport interface FileEvent {\n type: \"file\";\n id?: string;\n name: string;\n mediaType: string;\n url: string;\n size?: number;\n messageId?: string;\n}\n\nexport interface DataEvent {\n type: \"data\";\n kind: string;\n data: unknown;\n messageId?: string;\n}\n\nexport interface FinishEvent {\n type: \"finish\";\n usage?: Usage;\n finishReason?: FinishReason;\n messageId?: string;\n}\n\nexport interface ErrorEvent {\n type: \"error\";\n /** A message, or a full `ThreadError`. */\n error: string | ThreadError;\n messageId?: string;\n}\n\nexport interface AbortEvent {\n type: \"abort\";\n messageId?: string;\n}\n\nexport type StreamEvent =\n | StartEvent\n | TextDeltaEvent\n | ReasoningDeltaEvent\n | ReasoningEndEvent\n | ToolCallEvent\n | ToolUpdateEvent\n | ToolResultEvent\n | SourceEvent\n | FileEvent\n | DataEvent\n | FinishEvent\n | ErrorEvent\n | AbortEvent;\n\nexport interface StreamEventOptions {\n /**\n * The message to write to when an event names none and no message is being\n * written. `useThread` sets this to the id it made for the reply.\n */\n messageId?: string;\n /** Epoch milliseconds, for reasoning and tool durations. */\n at?: number;\n}\n\n/** Translates one stream event into a reducer action, or null when the event is unknown. */\nexport function streamEventToAction(\n state: Pick<ThreadState, \"activeMessageId\">,\n event: StreamEvent,\n options: StreamEventOptions = {},\n): ThreadAction | null {\n const messageId = event.messageId ?? state.activeMessageId ?? options.messageId;\n const at = options.at;\n // `exactOptionalPropertyTypes` is off, so these spreads only keep defined values.\n const withId = messageId === undefined ? {} : { messageId };\n const withAt = at === undefined ? {} : { at };\n\n switch (event.type) {\n case \"start\": {\n const id = event.messageId ?? options.messageId;\n return {\n type: \"begin-assistant-message\",\n ...(id === undefined ? {} : { id }),\n ...(event.createdAt === undefined ? {} : { createdAt: event.createdAt }),\n ...(event.metadata === undefined ? {} : { metadata: event.metadata }),\n };\n }\n case \"text-delta\":\n return { type: \"append-text\", delta: event.delta, ...withId, ...withAt };\n case \"reasoning-delta\":\n return { type: \"append-reasoning\", delta: event.delta, ...withId, ...withAt };\n case \"reasoning-end\":\n return {\n type: \"end-reasoning\",\n ...(event.durationMs === undefined ? {} : { durationMs: event.durationMs }),\n ...withId,\n ...withAt,\n };\n case \"tool-call\":\n return {\n type: \"start-tool-call\",\n callId: event.callId,\n name: event.name,\n ...(event.input === undefined ? {} : { input: event.input }),\n ...(event.state === undefined ? {} : { state: event.state }),\n ...(event.requiresApproval === undefined ? {} : { requiresApproval: event.requiresApproval }),\n ...(event.approvalPrompt === undefined ? {} : { approvalPrompt: event.approvalPrompt }),\n ...withId,\n ...withAt,\n };\n case \"tool-update\": {\n const patch: Extract<ThreadAction, { type: \"update-tool-call\" }>[\"patch\"] = {};\n if (event.state !== undefined) patch.state = event.state;\n if (event.name !== undefined) patch.name = event.name;\n if (event.input !== undefined) patch.input = event.input;\n if (event.output !== undefined) patch.output = event.output;\n if (event.error !== undefined) patch.error = event.error;\n if (event.approval !== undefined) patch.approval = event.approval;\n return { type: \"update-tool-call\", callId: event.callId, patch, ...withId, ...withAt };\n }\n case \"tool-result\":\n return {\n type: \"finish-tool-call\",\n callId: event.callId,\n ...(event.name === undefined ? {} : { name: event.name }),\n ...(event.output === undefined ? {} : { output: event.output }),\n ...(event.error === undefined ? {} : { error: event.error }),\n ...(event.durationMs === undefined ? {} : { durationMs: event.durationMs }),\n ...withId,\n ...withAt,\n };\n case \"source\":\n return {\n type: \"add-source\",\n source: {\n id: event.id,\n title: event.title,\n url: event.url,\n ...(event.snippet === undefined ? {} : { snippet: event.snippet }),\n },\n ...withId,\n };\n case \"file\":\n return {\n type: \"attach-files\",\n files: [\n {\n type: \"file\",\n ...(event.id === undefined ? {} : { id: event.id }),\n name: event.name,\n mediaType: event.mediaType,\n url: event.url,\n ...(event.size === undefined ? {} : { size: event.size }),\n },\n ],\n ...withId,\n };\n case \"data\":\n return { type: \"add-part\", part: { type: \"data\", kind: event.kind, data: event.data }, ...withId };\n case \"finish\":\n return {\n type: \"finish\",\n ...(event.usage === undefined ? {} : { usage: event.usage }),\n ...(event.finishReason === undefined ? {} : { finishReason: event.finishReason }),\n ...withId,\n ...withAt,\n };\n case \"error\":\n return { type: \"error\", error: event.error, ...withId, ...withAt };\n case \"abort\":\n return { type: \"abort\", ...withId, ...withAt };\n default:\n return null;\n }\n}\n\n/**\n * Applies one stream event to the thread state. Content that arrives before a\n * `start` event starts the assistant message itself, so a provider that never\n * sends `start` still works.\n */\nexport function applyStreamEvent(\n state: ThreadState,\n event: StreamEvent,\n options: StreamEventOptions = {},\n): ThreadState {\n const action = streamEventToAction(state, event, options);\n return action === null ? state : threadReducer(state, action);\n}\n\n/** Applies a list of stream events in order. Handy in tests and for replaying a recording. */\nexport function applyStreamEvents(\n state: ThreadState,\n events: readonly StreamEvent[],\n options: StreamEventOptions = {},\n): ThreadState {\n return events.reduce((current, event) => applyStreamEvent(current, event, options), state);\n}\n\n/** True for events that end a response, so a consumer can flush pending work. */\nexport function isTerminalStreamEvent(event: StreamEvent): boolean {\n return event.type === \"finish\" || event.type === \"error\" || event.type === \"abort\";\n}\n\n/**\n * Wraps a stream so it stops when `signal` aborts: iteration ends quietly,\n * and the source gets `return()` so a generator can clean up (close a socket,\n * cancel a request). Errors from the source are passed through, except the\n * abort error itself when the signal is aborted.\n */\nexport function createAbortableStream<T>(\n source: AsyncIterable<T>,\n signal: AbortSignal,\n): AsyncGenerator<T, void, undefined> {\n async function* run(): AsyncGenerator<T, void, undefined> {\n if (signal.aborted) return;\n const iterator = source[Symbol.asyncIterator]();\n let onAbort: (() => void) | undefined;\n const aborted = new Promise<{ aborted: true }>((resolve) => {\n onAbort = () => resolve({ aborted: true });\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n\n try {\n while (true) {\n let result: IteratorResult<T> | { aborted: true };\n try {\n result = await Promise.race([iterator.next(), aborted]);\n } catch (error) {\n if (signal.aborted) return;\n throw error;\n }\n if (\"aborted\" in result) return;\n if (result.done) return;\n yield result.value;\n if (signal.aborted) return;\n }\n } finally {\n if (onAbort) signal.removeEventListener(\"abort\", onAbort);\n // Let the source clean up, without waiting for it: a generator that is\n // still waiting on a request would only answer `return()` after that\n // request ends. Errors are ignored because we are already leaving.\n try {\n Promise.resolve(iterator.return?.()).catch(() => {});\n } catch {\n // ignored\n }\n }\n }\n return run();\n}\n\n/** Turns a thrown value into the `error` stream event, so a generator can `catch` and yield it. */\nexport function errorEvent(error: unknown): ErrorEvent {\n return { type: \"error\", error: toThreadError(error) };\n}\n","/**\n * Citation parsing. Models cite sources as bracketed numbers: `[1]`, `[2, 3]`,\n * `[1-3]`. A citation `[n]` points at the n-th source of the message (1-based,\n * in the order the source parts appear).\n */\n\nexport type CitationSegment =\n | { type: \"text\"; text: string }\n | {\n type: \"citation\";\n /** The source numbers the marker points at, in order and without repeats. */\n numbers: number[];\n /** The marker as written, for example `[1, 2]`. */\n raw: string;\n };\n\nexport interface ParseCitationsOptions {\n /**\n * The number of sources that exist. A marker that points past it, or at 0, is\n * left as plain text, so `[2024]` or `[0]` in prose is never mistaken for a\n * citation.\n */\n maxIndex?: number;\n}\n\n// `[1]`, `[1, 2]`, `[1-3]`, `[1–3]`. Not `[1](url)` (a link), `[1]: url` (a\n// reference definition), `[1][ref]`, `![1]` or `\\[1]` (escaped).\nconst MARKER = /(?<![\\\\\\]!])\\[(\\d{1,3}(?:\\s*[,–-]\\s*\\d{1,3})*)\\](?![([:])/g;\n\nfunction expand(list: string): number[] | null {\n const numbers: number[] = [];\n for (const piece of list.split(\",\")) {\n const range = piece.trim().split(/\\s*[–-]\\s*/);\n const first = Number(range[0]);\n const last = range.length > 1 ? Number(range[1]) : first;\n if (!Number.isInteger(first) || !Number.isInteger(last)) return null;\n if (last < first || last - first > 20) return null;\n for (let n = first; n <= last; n += 1) numbers.push(n);\n }\n return [...new Set(numbers)];\n}\n\n/** Splits text into plain text and citation markers. Joining every `text` and `raw` gives the input back. */\nexport function parseCitations(text: string, options: ParseCitationsOptions = {}): CitationSegment[] {\n const segments: CitationSegment[] = [];\n let cursor = 0;\n\n for (const match of text.matchAll(MARKER)) {\n const numbers = expand(match[1] ?? \"\");\n if (!numbers || numbers.length === 0) continue;\n if (options.maxIndex !== undefined && numbers.some((n) => n < 1 || n > (options.maxIndex ?? 0))) continue;\n\n if (match.index > cursor) segments.push({ type: \"text\", text: text.slice(cursor, match.index) });\n segments.push({ type: \"citation\", numbers, raw: match[0] });\n cursor = match.index + match[0].length;\n }\n\n if (cursor < text.length) segments.push({ type: \"text\", text: text.slice(cursor) });\n return segments;\n}\n\n/** Every source number cited in the text, sorted and without repeats. */\nexport function citedNumbers(text: string, options: ParseCitationsOptions = {}): number[] {\n const numbers = new Set<number>();\n for (const segment of parseCitations(text, options)) {\n if (segment.type === \"citation\") for (const n of segment.numbers) numbers.add(n);\n }\n return [...numbers].sort((a, b) => a - b);\n}\n","import type { Usage } from \"./types\";\n\n/**\n * Formatting helpers. They return numbers and units, never words: the words\n * around them (such as \"Thought for\") come from the `messages` catalog, so a\n * translation can reorder them.\n */\n\n/** The total of a usage record: `totalTokens`, or input plus output when it is missing. */\nexport function totalTokens(usage: Usage): number | undefined {\n if (usage.totalTokens !== undefined) return usage.totalTokens;\n if (usage.inputTokens === undefined && usage.outputTokens === undefined) return undefined;\n return (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0);\n}\n\n/** Adds two usage records field by field. Missing fields count as absent, not zero. */\nexport function mergeUsage(a: Usage | undefined, b: Usage | undefined): Usage | undefined {\n if (!a) return b;\n if (!b) return a;\n const result: Usage = {};\n const keys: Array<keyof Usage> = [\n \"inputTokens\",\n \"outputTokens\",\n \"totalTokens\",\n \"reasoningTokens\",\n \"cachedInputTokens\",\n ];\n for (const key of keys) {\n const left = a[key];\n const right = b[key];\n if (left === undefined && right === undefined) continue;\n result[key] = (left ?? 0) + (right ?? 0);\n }\n return result;\n}\n\n/** A compact, locale-aware count: `842`, `1.2K`, `3.4M`. */\nexport function formatTokenCount(count: number, locale?: string | string[]): string {\n if (!Number.isFinite(count)) return \"\";\n return new Intl.NumberFormat(locale, { notation: \"compact\", maximumFractionDigits: 1 }).format(count);\n}\n\nexport interface FormattedUsage {\n input?: string;\n output?: string;\n total?: string;\n reasoning?: string;\n cachedInput?: string;\n}\n\n/** Formats each field of a usage record with `formatTokenCount`. Absent fields stay absent. */\nexport function formatUsage(usage: Usage, locale?: string | string[]): FormattedUsage {\n const result: FormattedUsage = {};\n if (usage.inputTokens !== undefined) result.input = formatTokenCount(usage.inputTokens, locale);\n if (usage.outputTokens !== undefined) result.output = formatTokenCount(usage.outputTokens, locale);\n const total = totalTokens(usage);\n if (total !== undefined) result.total = formatTokenCount(total, locale);\n if (usage.reasoningTokens !== undefined) result.reasoning = formatTokenCount(usage.reasoningTokens, locale);\n if (usage.cachedInputTokens !== undefined) result.cachedInput = formatTokenCount(usage.cachedInputTokens, locale);\n return result;\n}\n\nfunction unitFormat(\n locale: string | string[] | undefined,\n unit: \"millisecond\" | \"second\" | \"minute\" | \"hour\",\n maximumFractionDigits = 0,\n): Intl.NumberFormat {\n return new Intl.NumberFormat(locale, { style: \"unit\", unit, unitDisplay: \"narrow\", maximumFractionDigits });\n}\n\n/**\n * A short, locale-aware duration: `240ms`, `4s`, `1.2s`, `1m 5s`, `2h 3m`.\n * Negative and non-finite values give an empty string.\n */\nexport function formatDuration(ms: number, locale?: string | string[]): string {\n if (!Number.isFinite(ms) || ms < 0) return \"\";\n if (ms < 1000) return unitFormat(locale, \"millisecond\").format(Math.round(ms));\n\n const totalSeconds = ms / 1000;\n if (totalSeconds < 10) return unitFormat(locale, \"second\", 1).format(Math.round(totalSeconds * 10) / 10);\n if (totalSeconds < 60) return unitFormat(locale, \"second\").format(Math.round(totalSeconds));\n\n const wholeSeconds = Math.round(totalSeconds);\n const hours = Math.floor(wholeSeconds / 3600);\n const minutes = Math.floor((wholeSeconds % 3600) / 60);\n const seconds = wholeSeconds % 60;\n const pieces: string[] = [];\n if (hours > 0) pieces.push(unitFormat(locale, \"hour\").format(hours));\n if (minutes > 0 || hours > 0) pieces.push(unitFormat(locale, \"minute\").format(minutes));\n if (hours === 0 && seconds > 0) pieces.push(unitFormat(locale, \"second\").format(seconds));\n return new Intl.ListFormat(locale, { type: \"unit\", style: \"narrow\" }).format(pieces);\n}\n\n/** A human-readable file size: `842 B`, `12.3 kB`, `4.5 MB`, in the user's locale. */\nexport function formatBytes(bytes: number, locale?: string | string[]): string {\n if (!Number.isFinite(bytes) || bytes < 0) return \"\";\n const units = [\"byte\", \"kilobyte\", \"megabyte\", \"gigabyte\"] as const;\n let value = bytes;\n let index = 0;\n while (value >= 1000 && index < units.length - 1) {\n value /= 1000;\n index += 1;\n }\n const unit = units[index] ?? \"byte\";\n return new Intl.NumberFormat(locale, {\n style: \"unit\",\n unit,\n unitDisplay: \"short\",\n maximumFractionDigits: index === 0 ? 0 : 1,\n }).format(value);\n}\n\n/**\n * Splits streamed text into the part that ends with a completed sentence or\n * line and the part still being written. Used to announce complete sentences\n * to assistive technology instead of every token.\n *\n * A sentence ends at `.`, `!`, `?`, `…`, `。`, `!` or `?` followed by\n * whitespace. The end of the text does not count, because the next token may\n * continue it (`3.` then `14`). A finished line, such as a list item or a\n * heading, also counts. Nothing inside a code fence ends one.\n */\nexport function splitCompletedSentences(text: string): { complete: string; rest: string } {\n let boundary = 0;\n let inFence = false;\n let offset = 0;\n const lines = text.split(\"\\n\");\n\n lines.forEach((line, index) => {\n const isLast = index === lines.length - 1;\n const start = offset;\n offset += line.length + 1;\n\n if (/^\\s{0,3}(```|~~~)/.test(line)) {\n inFence = !inFence;\n if (!inFence && !isLast) boundary = Math.max(boundary, offset - 1);\n return;\n }\n if (inFence) return;\n\n const stops = isLast ? /[.!?…。!?]+(?=\\s)/g : /[.!?…。!?]+(?=\\s|$)/g;\n for (const match of line.matchAll(stops)) {\n boundary = Math.max(boundary, start + match.index + match[0].length);\n }\n // A line that is followed by another one is finished.\n if (!isLast) boundary = Math.max(boundary, offset - 1);\n });\n\n return { complete: text.slice(0, boundary), rest: text.slice(boundary) };\n}\n\n/**\n * A rough plain-text reading of Markdown, for live announcements and previews:\n * links keep their text, images keep their alt text, citation markers such as\n * `[1]` and formatting marks (`**`, `#`, `>`, bullets, table bars) are dropped,\n * and fenced code keeps its content. It is not a Markdown parser, only close\n * enough that a screen reader does not read out punctuation.\n */\nexport function markdownToPlainText(markdown: string): string {\n return markdown\n .replace(/```[^\\n]*\\n([\\s\\S]*?)(?:```|$)/g, \"$1\")\n .replace(/!\\[([^\\]]*)\\]\\([^)]*\\)/g, \"$1\")\n .replace(/\\[([^\\]]+)\\]\\([^)]*\\)/g, \"$1\")\n .replace(/\\[\\d{1,3}(?:\\s*[,–-]\\s*\\d{1,3})*\\]/g, \"\")\n .replace(/^\\s{0,3}#{1,6}\\s+/gm, \"\")\n .replace(/^\\s{0,3}>\\s?/gm, \"\")\n .replace(/^\\s*[-*+]\\s+/gm, \"\")\n .replace(/^\\s*\\|?[\\s:|-]{3,}\\|?\\s*$/gm, \"\")\n .replace(/\\|/g, \" \")\n .replace(/(\\*\\*|__|~~|`)/g, \"\")\n .replace(/(^|[\\s(])[*_]([^\\s*_][^*_]*)[*_](?=$|[\\s).,!?:;])/g, \"$1$2\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n","/**\n * Markdown safety helpers. Model output is untrusted: a prompt-injected page\n * can make a model emit `[click](javascript:...)` or an image whose URL leaks\n * data. These functions decide which URLs may reach an `href` or `src`.\n *\n * They are pure string functions, so they also work on the server.\n */\n\n/** Protocols a link may use. Anything else (`javascript:`, `data:`, `vbscript:`, `file:`, `blob:`) is refused. */\nexport const SAFE_LINK_PROTOCOLS: readonly string[] = [\"http:\", \"https:\", \"mailto:\", \"tel:\"];\n\n/** Protocols an image may use. Images never use `mailto:` or `tel:`. */\nexport const SAFE_IMAGE_PROTOCOLS: readonly string[] = [\"http:\", \"https:\"];\n\nexport interface SanitizeUrlOptions {\n /** Allowed protocols, lower-case with the trailing colon. Defaults to `SAFE_LINK_PROTOCOLS`. */\n protocols?: readonly string[];\n /** Allow relative URLs such as `/docs`, `./a`, `?q=1` and `#top`. Defaults to true. */\n allowRelative?: boolean;\n}\n\n// Browsers ignore ASCII whitespace and control characters inside a scheme\n// (`java\\tscript:` runs as `javascript:`), so they are removed before checking.\n// eslint-disable-next-line no-control-regex\nconst IGNORED_IN_SCHEME = /[\\u0000-\\u0020\\u007f-\\u009f\\u00ad\\u200b-\\u200f\\u2028\\u2029\\ufeff]/g;\n\nconst SCHEME = /^([a-z][a-z0-9+.-]*):/i;\n\n/**\n * Returns the URL if it is safe to put in a link, or `null`.\n *\n * - Allowed: `http:`, `https:`, `mailto:`, `tel:` and relative URLs.\n * - Refused: `javascript:`, `data:`, `vbscript:`, `file:`, `blob:` and every\n * other scheme, including when disguised with whitespace, control\n * characters, mixed case or leading spaces.\n * - A colon after the first `/`, `?` or `#` is part of a path or query, so\n * `a/b:c` is a relative URL.\n */\nexport function sanitizeUrl(url: string | null | undefined, options: SanitizeUrlOptions = {}): string | null {\n if (typeof url !== \"string\") return null;\n const trimmed = url.trim();\n if (trimmed === \"\") return null;\n\n const protocols = options.protocols ?? SAFE_LINK_PROTOCOLS;\n const allowRelative = options.allowRelative ?? true;\n const probe = trimmed.replace(IGNORED_IN_SCHEME, \"\");\n\n const colon = probe.indexOf(\":\");\n const firstSeparator = probe.search(/[/?#]/);\n const hasScheme = colon !== -1 && (firstSeparator === -1 || colon < firstSeparator);\n\n if (!hasScheme) {\n // A backslash is a slash to browsers: `\\\\evil.example` is protocol-relative.\n // Both are fine for http(s) pages, but a disguised scheme is not.\n return allowRelative ? trimmed : null;\n }\n\n const scheme = SCHEME.exec(probe);\n if (!scheme) return null;\n const protocol = `${(scheme[1] ?? \"\").toLowerCase()}:`;\n return protocols.includes(protocol) ? trimmed : null;\n}\n\n/** True when `sanitizeUrl` accepts the URL. */\nexport function isSafeUrl(url: string | null | undefined, options: SanitizeUrlOptions = {}): boolean {\n return sanitizeUrl(url, options) !== null;\n}\n\nexport interface SanitizeImageUrlOptions {\n /**\n * Allow `data:image/png|jpeg|gif|webp|avif;base64,...` URLs. Off by default\n * for model output. Never allows `data:image/svg+xml`.\n */\n allowDataImages?: boolean;\n /** Allow `blob:` URLs, which a page makes itself (for example for a pasted file). Off by default. */\n allowBlob?: boolean;\n}\n\nconst DATA_IMAGE = /^data:image\\/(?:png|jpe?g|gif|webp|avif);base64,[a-z0-9+/=\\s]+$/i;\n\n/**\n * Returns the URL if it is safe to use as an image `src`, or `null`: `http:`,\n * `https:` and relative URLs, plus `blob:` and raster `data:` images when the\n * options allow them.\n */\nexport function sanitizeImageUrl(\n url: string | null | undefined,\n options: SanitizeImageUrlOptions = {},\n): string | null {\n if (typeof url !== \"string\") return null;\n const trimmed = url.trim();\n if (options.allowDataImages && DATA_IMAGE.test(trimmed)) return trimmed;\n if (options.allowBlob && /^blob:/i.test(trimmed)) return trimmed;\n return sanitizeUrl(trimmed, { protocols: SAFE_IMAGE_PROTOCOLS });\n}\n\n/** True for a URL that leaves the current site: `http(s):` or protocol-relative. */\nexport function isExternalUrl(url: string): boolean {\n return /^(?:https?:)?\\/\\//i.test(url.trim().replace(IGNORED_IN_SCHEME, \"\"));\n}\n\n/** The host of an `http(s)` URL without a leading `www.`, or `null`. */\nexport function getUrlHostname(url: string): string | null {\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") return null;\n return parsed.hostname.replace(/^www\\./i, \"\");\n } catch {\n return null;\n }\n}\n\n/**\n * Splits Markdown into top-level blocks so finished blocks can be rendered\n * once and only the last one re-parsed while text streams in.\n *\n * It splits only where that is safe: at blank lines outside a code fence,\n * after a block that is not a list, quote, indented block or HTML (those\n * can continue after a blank line). If the text uses reference-style links or\n * footnotes, which depend on definitions elsewhere in the text, it returns the\n * whole text as one block. Joining the blocks with `\"\"` always gives the input back.\n */\nexport function splitMarkdownBlocks(markdown: string): string[] {\n if (markdown === \"\") return [];\n // Definitions can appear after their use, so a split could break the link.\n if (/^ {0,3}\\[[^\\]\\n]+\\]:/m.test(markdown) || /\\[\\^[^\\]\\n]+\\]/.test(markdown)) return [markdown];\n\n type Kind = \"plain\" | \"list\" | \"quote\" | \"sticky\";\n const LIST_MARKER = /^ {0,3}(?:[-*+]|\\d{1,9}[.)])(?:\\s|$)/;\n\n const lines = markdown.split(\"\\n\");\n const blocks: string[] = [];\n let current = \"\";\n let kind: Kind | null = null;\n let fence: string | null = null;\n let afterBlank = false;\n\n const flush = () => {\n if (current !== \"\") blocks.push(current);\n current = \"\";\n kind = null;\n afterBlank = false;\n };\n\n /** True when a line after a blank line still belongs to the block that came before. */\n const continues = (line: string, previous: Kind | null): boolean => {\n if (previous === \"sticky\") return true;\n if (previous === \"list\") return LIST_MARKER.test(line) || /^(?: {2,}|\\t)/.test(line);\n if (previous === \"quote\") return /^ {0,3}>/.test(line);\n return false;\n };\n\n lines.forEach((line, index) => {\n const text = index === lines.length - 1 ? line : `${line}\\n`;\n const fenceMatch = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);\n\n if (fence !== null) {\n current += text;\n if (fenceMatch && fenceMatch[1] && fenceMatch[1][0] === fence[0] && fenceMatch[1].length >= fence.length && (fenceMatch[2] ?? \"\").trim() === \"\") {\n fence = null;\n }\n return;\n }\n\n if (line.trim() === \"\") {\n current += text;\n afterBlank = kind !== null;\n return;\n }\n\n // A line after a blank line starts a new block unless it continues the last one.\n if (afterBlank && !continues(line, kind)) flush();\n afterBlank = false;\n\n if (kind === null) {\n if (LIST_MARKER.test(line)) kind = \"list\";\n else if (/^ {0,3}>/.test(line)) kind = \"quote\";\n else if (/^(?:\\t| {4,}| {0,3}<)/.test(line)) kind = \"sticky\";\n else kind = \"plain\";\n }\n current += text;\n\n // An opening fence. A backtick fence cannot have backticks in its info string.\n const marker = fenceMatch?.[1];\n if (marker && !(marker[0] === \"`\" && (fenceMatch?.[2] ?? \"\").includes(\"`\"))) fence = marker;\n });\n\n flush();\n return blocks;\n}\n"],"mappings":"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","names":["index","message","last","edited","messages"]}
package/dist/index.d.ts CHANGED
@@ -1,87 +1,288 @@
1
+ import { M as Message, T as ToolPart, D as DataPart, F as FilePart, S as SourcePart, a as FinishReason, U as Usage, b as ThreadError } from './stream-C2tzoSII.js';
2
+ export { A as AbortEvent, B as BranchInfo, c as BranchPoint, d as DataEvent, E as ErrorEvent, e as ErrorKind, f as FileEvent, g as FinishEvent, h as MessageAdapter, i as MessagePart, j as MessagePartType, k as MessageRole, l as MessageStatus, m as MessagesAdapter, R as ReasoningDeltaEvent, n as ReasoningEndEvent, o as ReasoningPart, p as SourceEvent, q as StartEvent, r as StreamEvent, s as StreamEventOptions, t as TextDeltaEvent, u as TextPart, v as Thread, w as ThreadAction, x as ThreadState, y as ThreadStatus, z as ThreadStore, C as ToolApproval, G as ToolCallEvent, H as ToolCallPatch, I as ToolResultEvent, J as ToolState, K as ToolUpdateEvent, L as applyStreamEvent, N as applyStreamEvents, O as createAbortableStream, P as createThreadState, Q as errorEvent, V as getBranchInfo, W as getBranchInfoMap, X as isBusy, Y as isTerminalStreamEvent, Z as isTerminalToolState, _ as lastUserMessage, $ as streamEventToAction, a0 as threadReducer } from './stream-C2tzoSII.js';
3
+
4
+ /** The text of a message: its text parts, joined. Reasoning and tool output are left out. */
5
+ declare function messageText(message: Message): string;
6
+ /** The reasoning of a message, joined. Empty when the model produced none. */
7
+ declare function messageReasoning(message: Message): string;
8
+ /** Tool calls that are waiting for a human decision. */
9
+ declare function pendingApprovals(message: Message): ToolPart[];
10
+ /** Tool calls waiting for a human decision anywhere in a thread, oldest first. */
11
+ declare function threadPendingApprovals(messages: readonly Message[]): ToolPart[];
12
+ /** The tool calls of a message, in order. */
13
+ declare function messageToolCalls(message: Message): ToolPart[];
14
+ /** The sources of a message, in order. A citation `[n]` points at the n-th. */
15
+ declare function messageSources(message: Message): SourcePart[];
16
+ /** The files of a message, in order. */
17
+ declare function messageFiles(message: Message): FilePart[];
18
+ /** The structured data parts of a message, in order. */
19
+ declare function messageData(message: Message): DataPart[];
20
+ /** Finds a tool call by id anywhere in a list of messages, searching newest first. */
21
+ declare function findToolCall(messages: readonly Message[], callId: string): {
22
+ message: Message;
23
+ part: ToolPart;
24
+ } | undefined;
25
+ /** True while a message is still being written. */
26
+ declare function isStreaming(message: Message): boolean;
27
+ /** The last message with the given role, or undefined. */
28
+ declare function lastMessageWithRole(messages: readonly Message[], role: Message["role"]): Message | undefined;
29
+
30
+ interface AdapterOptions {
31
+ /** Prefix for ids made for messages that have none. Default `msg-`. */
32
+ idPrefix?: string;
33
+ }
1
34
  /**
2
- * The neutral message shape (spec section 6). Components read typed parts and
3
- * never import a provider SDK; adapters convert provider formats into this
4
- * shape.
35
+ * One part of a Vercel AI SDK `UIMessage` (v4 and v5 shapes). The adapter reads:
36
+ * `text`, `reasoning`, `tool-<name>` and `dynamic-tool` (with `toolCallId`,
37
+ * `state`, `input`, `output`, `errorText`), v4 `tool-invocation`, `source-url`,
38
+ * `source-document`, v4 `source`, `file` and `data-<name>`. `step-start` and
39
+ * unknown parts are skipped.
5
40
  */
6
- type MessageRole = "user" | "assistant" | "system";
7
- interface TextPart {
8
- type: "text";
9
- text: string;
41
+ interface AiSdkPart {
42
+ type: string;
43
+ [key: string]: unknown;
10
44
  }
11
- interface ReasoningPart {
12
- type: "reasoning";
13
- text: string;
14
- /** How long the model thought, for the "Thought for 4s" line. */
15
- durationMs?: number;
45
+ interface AiSdkMessage {
46
+ id?: string;
47
+ role: string;
48
+ /** The message parts. When absent, `content` (a string) is used. */
49
+ parts?: ReadonlyArray<AiSdkPart>;
50
+ content?: unknown;
51
+ createdAt?: Date | string | number;
52
+ metadata?: unknown;
16
53
  }
17
- type ToolState = "queued" | "running" | "succeeded" | "failed" | "needs-approval";
18
- interface ToolPart {
19
- type: "tool";
20
- id: string;
21
- name: string;
22
- state: ToolState;
23
- input?: unknown;
24
- output?: unknown;
25
- /** A human-readable cause when `state` is `failed`. */
26
- error?: string;
27
- durationMs?: number;
54
+ /**
55
+ * Converts Vercel AI SDK `UIMessage`s (the `messages` of `useChat`) into kit
56
+ * messages. Roles other than user, assistant and system are skipped.
57
+ */
58
+ declare function fromAiSdkMessages(messages: readonly AiSdkMessage[], options?: AdapterOptions): Message[];
59
+ /** A content part of an OpenAI chat message. */
60
+ interface OpenAIContentPart {
61
+ type: string;
62
+ text?: string;
63
+ image_url?: string | {
64
+ url: string;
65
+ };
66
+ file?: {
67
+ filename?: string;
68
+ file_data?: string;
69
+ };
70
+ [key: string]: unknown;
28
71
  }
29
- interface SourcePart {
30
- type: "source";
72
+ interface OpenAIToolCall {
31
73
  id: string;
32
- title: string;
33
- url: string;
34
- /** Shown in the source list next to the title and domain. */
35
- snippet?: string;
74
+ type?: string;
75
+ function?: {
76
+ name?: string;
77
+ arguments?: string;
78
+ };
36
79
  }
37
- interface FilePart {
38
- type: "file";
39
- name: string;
40
- mediaType: string;
41
- url: string;
42
- size?: number;
80
+ /**
81
+ * An OpenAI Chat Completions message. `developer` is treated as `system`.
82
+ * `tool` messages are merged into the assistant tool call they answer.
83
+ * `reasoning_content`, used by some OpenAI-compatible providers, becomes a
84
+ * reasoning part.
85
+ */
86
+ interface OpenAIChatMessage {
87
+ id?: string;
88
+ role: string;
89
+ content?: string | null | ReadonlyArray<OpenAIContentPart>;
90
+ name?: string;
91
+ tool_calls?: ReadonlyArray<OpenAIToolCall>;
92
+ tool_call_id?: string;
93
+ refusal?: string | null;
94
+ reasoning_content?: string | null;
43
95
  }
44
- /** Structured data a component can render, for example an artifact or a chart spec. */
45
- interface DataPart {
46
- type: "data";
47
- /** Identifies the shape of `data`, such as `chart` or `diagram`. */
48
- kind: string;
49
- data: unknown;
96
+ /**
97
+ * Converts OpenAI Chat Completions messages into kit messages.
98
+ *
99
+ * - An assistant `tool_calls` entry becomes a tool part, `running` until a
100
+ * `tool` message with the same `tool_call_id` finishes it as `succeeded` with
101
+ * the parsed JSON (or the raw string) as `output`.
102
+ * - A `tool` message that answers no known call becomes its own `tool` message.
103
+ */
104
+ declare function fromOpenAIChatMessages(messages: readonly OpenAIChatMessage[], options?: AdapterOptions): Message[];
105
+ /** A content block of an Anthropic Messages API message. */
106
+ interface AnthropicBlock {
107
+ type: string;
108
+ [key: string]: unknown;
50
109
  }
51
- type MessagePart = TextPart | ReasoningPart | ToolPart | SourcePart | FilePart | DataPart;
52
- type MessageStatus = "streaming" | "complete" | "error" | "stopped";
53
- interface Message {
54
- id: string;
55
- role: MessageRole;
56
- parts: MessagePart[];
57
- status?: MessageStatus;
58
- createdAt?: string;
59
- /** The message this one replaces or follows, for branches between versions. */
60
- parentId?: string;
61
- metadata?: Record<string, unknown>;
110
+ /**
111
+ * An Anthropic Messages API message. Reads `text` (with web-search
112
+ * `citations`), `thinking`, `tool_use`, `server_tool_use`, `tool_result`,
113
+ * `web_search_tool_result`, `image` and `document` blocks. A user message that
114
+ * holds only `tool_result` blocks is merged into the assistant tool calls
115
+ * they answer and produces no message of its own.
116
+ */
117
+ interface AnthropicMessage {
118
+ id?: string;
119
+ role: string;
120
+ content: string | ReadonlyArray<AnthropicBlock>;
62
121
  }
63
- interface Thread {
64
- id: string;
65
- title?: string;
66
- messages: Message[];
67
- updatedAt?: string;
122
+ interface AnthropicAdapterOptions extends AdapterOptions {
123
+ /** The request's top-level `system` prompt, shown as a system message first. */
124
+ system?: string | ReadonlyArray<{
125
+ type?: string;
126
+ text?: string;
127
+ }>;
128
+ }
129
+ /**
130
+ * Converts Anthropic Messages API messages into kit messages.
131
+ */
132
+ declare function fromAnthropicMessages(messages: readonly AnthropicMessage[], options?: AnthropicAdapterOptions): Message[];
133
+ /** Reads a `finish_reason` or `stop_reason` from any provider into the kit's vocabulary. */
134
+ declare function normalizeFinishReason(reason: unknown): FinishReason | undefined;
135
+ /** Reads token usage from OpenAI (`prompt_tokens`), Anthropic (`input_tokens`) or AI SDK (`inputTokens`) shapes. */
136
+ declare function normalizeUsage(usage: unknown): Usage | undefined;
137
+
138
+ /** True for the error `fetch` and `AbortController` produce when a request is cancelled. */
139
+ declare function isAbortError(error: unknown): boolean;
140
+ /**
141
+ * Turns anything a provider or `fetch` might throw into a `ThreadError` with a
142
+ * `kind`, so the UI can show a distinct message for network failures, rate
143
+ * limits and moderation blocks. It looks at the HTTP status (`status` or
144
+ * `statusCode`), the error code and the message; it never reads secrets.
145
+ */
146
+ declare function toThreadError(error: unknown): ThreadError;
147
+
148
+ /**
149
+ * Citation parsing. Models cite sources as bracketed numbers: `[1]`, `[2, 3]`,
150
+ * `[1-3]`. A citation `[n]` points at the n-th source of the message (1-based,
151
+ * in the order the source parts appear).
152
+ */
153
+ type CitationSegment = {
154
+ type: "text";
155
+ text: string;
156
+ } | {
157
+ type: "citation";
158
+ /** The source numbers the marker points at, in order and without repeats. */
159
+ numbers: number[];
160
+ /** The marker as written, for example `[1, 2]`. */
161
+ raw: string;
162
+ };
163
+ interface ParseCitationsOptions {
164
+ /**
165
+ * The number of sources that exist. A marker that points past it, or at 0, is
166
+ * left as plain text, so `[2024]` or `[0]` in prose is never mistaken for a
167
+ * citation.
168
+ */
169
+ maxIndex?: number;
68
170
  }
69
- /** Converts a provider's message format into the neutral shape. */
70
- type MessageAdapter<Input> = (input: Input) => Message;
171
+ /** Splits text into plain text and citation markers. Joining every `text` and `raw` gives the input back. */
172
+ declare function parseCitations(text: string, options?: ParseCitationsOptions): CitationSegment[];
173
+ /** Every source number cited in the text, sorted and without repeats. */
174
+ declare function citedNumbers(text: string, options?: ParseCitationsOptions): number[];
175
+
71
176
  /**
72
- * The thread component is stateless. Storage and history belong to the app,
73
- * through this small interface.
177
+ * Formatting helpers. They return numbers and units, never words: the words
178
+ * around them (such as "Thought for") come from the `messages` catalog, so a
179
+ * translation can reorder them.
74
180
  */
75
- interface ThreadStore {
76
- load(threadId: string): Promise<Thread | null>;
77
- save(thread: Thread): Promise<void>;
78
- list?(): Promise<Array<Pick<Thread, "id" | "title" | "updatedAt">>>;
79
- delete?(threadId: string): Promise<void>;
181
+ /** The total of a usage record: `totalTokens`, or input plus output when it is missing. */
182
+ declare function totalTokens(usage: Usage): number | undefined;
183
+ /** Adds two usage records field by field. Missing fields count as absent, not zero. */
184
+ declare function mergeUsage(a: Usage | undefined, b: Usage | undefined): Usage | undefined;
185
+ /** A compact, locale-aware count: `842`, `1.2K`, `3.4M`. */
186
+ declare function formatTokenCount(count: number, locale?: string | string[]): string;
187
+ interface FormattedUsage {
188
+ input?: string;
189
+ output?: string;
190
+ total?: string;
191
+ reasoning?: string;
192
+ cachedInput?: string;
80
193
  }
81
- /** The text of a message: its text parts, joined. Reasoning and tool output are left out. */
82
- declare function messageText(message: Message): string;
83
- /** Tool calls that are waiting for a human decision. */
84
- declare function pendingApprovals(message: Message): ToolPart[];
194
+ /** Formats each field of a usage record with `formatTokenCount`. Absent fields stay absent. */
195
+ declare function formatUsage(usage: Usage, locale?: string | string[]): FormattedUsage;
196
+ /**
197
+ * A short, locale-aware duration: `240ms`, `4s`, `1.2s`, `1m 5s`, `2h 3m`.
198
+ * Negative and non-finite values give an empty string.
199
+ */
200
+ declare function formatDuration(ms: number, locale?: string | string[]): string;
201
+ /** A human-readable file size: `842 B`, `12.3 kB`, `4.5 MB`, in the user's locale. */
202
+ declare function formatBytes(bytes: number, locale?: string | string[]): string;
203
+ /**
204
+ * Splits streamed text into the part that ends with a completed sentence or
205
+ * line and the part still being written. Used to announce complete sentences
206
+ * to assistive technology instead of every token.
207
+ *
208
+ * A sentence ends at `.`, `!`, `?`, `…`, `。`, `!` or `?` followed by
209
+ * whitespace. The end of the text does not count, because the next token may
210
+ * continue it (`3.` then `14`). A finished line, such as a list item or a
211
+ * heading, also counts. Nothing inside a code fence ends one.
212
+ */
213
+ declare function splitCompletedSentences(text: string): {
214
+ complete: string;
215
+ rest: string;
216
+ };
217
+ /**
218
+ * A rough plain-text reading of Markdown, for live announcements and previews:
219
+ * links keep their text, images keep their alt text, citation markers such as
220
+ * `[1]` and formatting marks (`**`, `#`, `>`, bullets, table bars) are dropped,
221
+ * and fenced code keeps its content. It is not a Markdown parser, only close
222
+ * enough that a screen reader does not read out punctuation.
223
+ */
224
+ declare function markdownToPlainText(markdown: string): string;
225
+
226
+ /**
227
+ * Markdown safety helpers. Model output is untrusted: a prompt-injected page
228
+ * can make a model emit `[click](javascript:...)` or an image whose URL leaks
229
+ * data. These functions decide which URLs may reach an `href` or `src`.
230
+ *
231
+ * They are pure string functions, so they also work on the server.
232
+ */
233
+ /** Protocols a link may use. Anything else (`javascript:`, `data:`, `vbscript:`, `file:`, `blob:`) is refused. */
234
+ declare const SAFE_LINK_PROTOCOLS: readonly string[];
235
+ /** Protocols an image may use. Images never use `mailto:` or `tel:`. */
236
+ declare const SAFE_IMAGE_PROTOCOLS: readonly string[];
237
+ interface SanitizeUrlOptions {
238
+ /** Allowed protocols, lower-case with the trailing colon. Defaults to `SAFE_LINK_PROTOCOLS`. */
239
+ protocols?: readonly string[];
240
+ /** Allow relative URLs such as `/docs`, `./a`, `?q=1` and `#top`. Defaults to true. */
241
+ allowRelative?: boolean;
242
+ }
243
+ /**
244
+ * Returns the URL if it is safe to put in a link, or `null`.
245
+ *
246
+ * - Allowed: `http:`, `https:`, `mailto:`, `tel:` and relative URLs.
247
+ * - Refused: `javascript:`, `data:`, `vbscript:`, `file:`, `blob:` and every
248
+ * other scheme, including when disguised with whitespace, control
249
+ * characters, mixed case or leading spaces.
250
+ * - A colon after the first `/`, `?` or `#` is part of a path or query, so
251
+ * `a/b:c` is a relative URL.
252
+ */
253
+ declare function sanitizeUrl(url: string | null | undefined, options?: SanitizeUrlOptions): string | null;
254
+ /** True when `sanitizeUrl` accepts the URL. */
255
+ declare function isSafeUrl(url: string | null | undefined, options?: SanitizeUrlOptions): boolean;
256
+ interface SanitizeImageUrlOptions {
257
+ /**
258
+ * Allow `data:image/png|jpeg|gif|webp|avif;base64,...` URLs. Off by default
259
+ * for model output. Never allows `data:image/svg+xml`.
260
+ */
261
+ allowDataImages?: boolean;
262
+ /** Allow `blob:` URLs, which a page makes itself (for example for a pasted file). Off by default. */
263
+ allowBlob?: boolean;
264
+ }
265
+ /**
266
+ * Returns the URL if it is safe to use as an image `src`, or `null`: `http:`,
267
+ * `https:` and relative URLs, plus `blob:` and raster `data:` images when the
268
+ * options allow them.
269
+ */
270
+ declare function sanitizeImageUrl(url: string | null | undefined, options?: SanitizeImageUrlOptions): string | null;
271
+ /** True for a URL that leaves the current site: `http(s):` or protocol-relative. */
272
+ declare function isExternalUrl(url: string): boolean;
273
+ /** The host of an `http(s)` URL without a leading `www.`, or `null`. */
274
+ declare function getUrlHostname(url: string): string | null;
275
+ /**
276
+ * Splits Markdown into top-level blocks so finished blocks can be rendered
277
+ * once and only the last one re-parsed while text streams in.
278
+ *
279
+ * It splits only where that is safe: at blank lines outside a code fence,
280
+ * after a block that is not a list, quote, indented block or HTML (those
281
+ * can continue after a blank line). If the text uses reference-style links or
282
+ * footnotes, which depend on definitions elsewhere in the text, it returns the
283
+ * whole text as one block. Joining the blocks with `""` always gives the input back.
284
+ */
285
+ declare function splitMarkdownBlocks(markdown: string): string[];
85
286
 
86
- export { messageText, pendingApprovals };
87
- export type { DataPart, FilePart, Message, MessageAdapter, MessagePart, MessageRole, MessageStatus, ReasoningPart, SourcePart, TextPart, Thread, ThreadStore, ToolPart, ToolState };
287
+ export { DataPart, FilePart, FinishReason, Message, SAFE_IMAGE_PROTOCOLS, SAFE_LINK_PROTOCOLS, SourcePart, ThreadError, ToolPart, Usage, citedNumbers, findToolCall, formatBytes, formatDuration, formatTokenCount, formatUsage, fromAiSdkMessages, fromAnthropicMessages, fromOpenAIChatMessages, getUrlHostname, isAbortError, isExternalUrl, isSafeUrl, isStreaming, lastMessageWithRole, markdownToPlainText, mergeUsage, messageData, messageFiles, messageReasoning, messageSources, messageText, messageToolCalls, normalizeFinishReason, normalizeUsage, parseCitations, pendingApprovals, sanitizeImageUrl, sanitizeUrl, splitCompletedSentences, splitMarkdownBlocks, threadPendingApprovals, toThreadError, totalTokens };
288
+ export type { AdapterOptions, AiSdkMessage, AiSdkPart, AnthropicAdapterOptions, AnthropicBlock, AnthropicMessage, CitationSegment, FormattedUsage, OpenAIChatMessage, OpenAIContentPart, OpenAIToolCall, ParseCitationsOptions, SanitizeImageUrlOptions, SanitizeUrlOptions };