@assistant-ui/react-ag-ui 0.0.40 → 0.0.41
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.
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { AG_UI_METADATA_NAMESPACE, RunAggregator, tryParseJSON } from "./adapter/run-aggregator.js";
|
|
3
3
|
import { fromAgUiMessages, toAgUiMessages, toAgUiTools } from "./adapter/conversions.js";
|
|
4
4
|
import { createAgUiSubscriber } from "./adapter/subscriber.js";
|
|
5
|
-
import { fromThreadMessageLike, generateId } from "@assistant-ui/core
|
|
5
|
+
import { fromThreadMessageLike, generateId } from "@assistant-ui/core";
|
|
6
6
|
import jsonpatch from "fast-json-patch";
|
|
7
7
|
//#region src/runtime/AgUiThreadRuntimeCore.ts
|
|
8
8
|
const optimisticPrefix = "__optimistic__";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgUiThreadRuntimeCore.js","names":[],"sources":["../../src/runtime/AgUiThreadRuntimeCore.ts"],"sourcesContent":["\"use client\";\n\nimport { generateId, fromThreadMessageLike } from \"@assistant-ui/core/internal\";\nimport type {\n AddToolResultOptions,\n AppendMessage,\n AssistantRuntime,\n ChatModelRunOptions,\n ChatModelRunResult,\n MessageStatus,\n ThreadAssistantMessage,\n ThreadHistoryAdapter,\n ThreadMessage,\n ToolCallMessagePart,\n} from \"@assistant-ui/core\";\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport jsonpatch, { type Operation } from \"fast-json-patch\";\nimport type { Logger } from \"./logger\";\nimport type { AgUiEvent, AgUiInterrupt, AgUiResumeEntry } from \"./types\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport {\n AG_UI_METADATA_NAMESPACE,\n type AgUiCustomMetadata,\n RunAggregator,\n tryParseJSON,\n} from \"./adapter/run-aggregator\";\nimport {\n fromAgUiMessages,\n toAgUiMessages,\n toAgUiTools,\n} from \"./adapter/conversions\";\nimport { createAgUiSubscriber } from \"./adapter/subscriber\";\n\nconst optimisticPrefix = \"__optimistic__\";\nconst generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;\nconst isOptimisticId = (id: string) => id.startsWith(optimisticPrefix);\n\nconst symbolResumeShim = Symbol(\"agui-resume-shim\");\n\ntype RunConfig = NonNullable<AppendMessage[\"runConfig\"]>;\ntype ResumeStream = (\n options: ChatModelRunOptions,\n) => AsyncGenerator<ChatModelRunResult, void, unknown>;\ntype ResumeRunConfig = {\n parentId: string | null;\n sourceId: string | null;\n runConfig: RunConfig;\n stream?: ResumeStream;\n};\n\ntype CoreOptions = {\n agent: AbstractAgent;\n logger: Logger;\n showThinking: boolean;\n onError?: (error: Error) => void;\n onCancel?: () => void;\n history?: ThreadHistoryAdapter;\n notifyUpdate: () => void;\n};\n\nconst FALLBACK_USER_STATUS = { type: \"complete\", reason: \"unknown\" } as const;\n\nexport class AgUiThreadRuntimeCore {\n private agent: AbstractAgent;\n private logger: Logger;\n private showThinking: boolean;\n private onError: ((error: Error) => void) | undefined;\n private onCancel: (() => void) | undefined;\n private readonly notifyUpdate: () => void;\n\n private runtime: AssistantRuntime | undefined;\n private messages: ThreadMessage[] = [];\n private isRunningFlag = false;\n private abortController: AbortController | null = null;\n private stateSnapshot: ReadonlyJSONValue | undefined;\n private pendingError: Error | null = null;\n private history: ThreadHistoryAdapter | undefined;\n private lastRunConfig: RunConfig | undefined;\n private readonly assistantHistoryParents = new Map<string, string | null>();\n private readonly recordedHistoryIds = new Set<string>();\n private _isLoading = false;\n private _loadPromise: Promise<void> | undefined;\n private pendingResumeMessageId: string | null = null;\n\n constructor(options: CoreOptions) {\n this.agent = options.agent;\n this.logger = options.logger;\n this.showThinking = options.showThinking;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n this.history = options.history;\n this.notifyUpdate = options.notifyUpdate;\n this.installResumeShim();\n }\n\n updateOptions(options: Omit<CoreOptions, \"notifyUpdate\">) {\n this.agent = options.agent;\n this.logger = options.logger;\n this.showThinking = options.showThinking;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n this.history = options.history;\n this.installResumeShim();\n }\n\n attachRuntime(runtime: AssistantRuntime) {\n this.runtime = runtime;\n }\n\n detachRuntime() {\n this.runtime = undefined;\n }\n\n getMessages(): readonly ThreadMessage[] {\n return this.messages;\n }\n\n getState(): ReadonlyJSONValue | undefined {\n return this.stateSnapshot;\n }\n\n isRunning(): boolean {\n return this.isRunningFlag;\n }\n\n get isLoading(): boolean {\n return this._isLoading;\n }\n\n __internal_load(): Promise<void> {\n if (this._loadPromise) return this._loadPromise;\n\n const promise = this.history?.load() ?? Promise.resolve(null);\n\n this._isLoading = true;\n\n this._loadPromise = promise\n .then(async (repo) => {\n if (!repo) return;\n\n const messages = repo.messages.map((item) => item.message);\n this.applyExternalMessages(messages);\n\n if (repo.unstable_resume) {\n const parentId = repo.headId ?? messages.at(-1)?.id ?? null;\n const resumeStream = this.history?.resume?.bind(this.history);\n await this.startRun(\n parentId,\n this.lastRunConfig,\n undefined,\n resumeStream,\n );\n }\n })\n .catch((error) => {\n this.logger.error?.(\"[agui] failed to load history\", error);\n this.onError?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n })\n .finally(() => {\n this._isLoading = false;\n this.notifyUpdate();\n });\n\n this.notifyUpdate();\n return this._loadPromise;\n }\n\n async append(message: AppendMessage): Promise<void> {\n const startRun = message.startRun ?? message.role === \"user\";\n if (startRun) this.assertNoPendingInterrupts();\n if (message.sourceId) {\n this.messages = this.messages.filter(\n (entry) => entry.id !== message.sourceId,\n );\n }\n this.resetHead(message.parentId);\n\n const threadMessage = this.toThreadMessage(message);\n this.messages = [...this.messages, threadMessage];\n this.notifyUpdate();\n this.recordHistoryEntry(message.parentId ?? null, threadMessage);\n\n if (!startRun) return;\n await this.startRun(threadMessage.id, message.runConfig);\n }\n\n async edit(message: AppendMessage): Promise<void> {\n await this.append(message);\n }\n\n async reload(\n parentId: string | null,\n config: { runConfig?: RunConfig } = {},\n ): Promise<void> {\n this.assertNoPendingInterrupts();\n this.resetHead(parentId);\n this.notifyUpdate();\n await this.startRun(parentId, config.runConfig);\n }\n\n async cancel(): Promise<void> {\n if (!this.abortController) return;\n this.abortController.abort();\n }\n\n async resume(config: ResumeRunConfig): Promise<void> {\n this.assertNoPendingInterrupts();\n await this.startRun(\n config.parentId,\n config.runConfig ?? this.lastRunConfig,\n undefined,\n config.stream,\n );\n }\n\n async resumeInFlightRun(messages: readonly ThreadMessage[]): Promise<void> {\n // Without a resume stream startRun would re-run the agent from scratch.\n const resumeStream = this.history?.resume?.bind(this.history);\n if (!resumeStream) {\n const error = new Error(\n \"[agui] unstable_resume requires a ThreadHistoryAdapter with a resume() method; skipping resume after thread switch\",\n );\n this.logger.error?.(error.message);\n this.onError?.(error);\n return;\n }\n const parentId = messages.at(-1)?.id ?? null;\n try {\n await this.startRun(\n parentId,\n this.lastRunConfig,\n undefined,\n resumeStream,\n );\n } catch {\n // startRun already reported via onError; don't reject the switch.\n }\n }\n\n private assertNoPendingInterrupts(): void {\n if (!this.getPendingInterrupts()) return;\n throw new Error(\n \"[agui] cannot start a new run while interrupts are pending; resolve them with submitInterruptResponses()\",\n );\n }\n\n getPendingInterrupts(): {\n messageId: string;\n interrupts: readonly AgUiInterrupt[];\n } | null {\n const assistant = this.messages.findLast((m) => m.role === \"assistant\") as\n | ThreadAssistantMessage\n | undefined;\n if (\n !assistant ||\n assistant.status?.type !== \"requires-action\" ||\n assistant.status.reason !== \"interrupt\"\n ) {\n return null;\n }\n const stored = (\n assistant.metadata.custom[AG_UI_METADATA_NAMESPACE] as\n | AgUiCustomMetadata\n | undefined\n )?.interrupts;\n if (!stored?.length) return null;\n return { messageId: assistant.id, interrupts: stored };\n }\n\n async submitInterruptResponses(\n responses: readonly AgUiResumeEntry[],\n ): Promise<void> {\n const pending = this.getPendingInterrupts();\n if (!pending) {\n throw new Error(\n \"[agui] submitInterruptResponses: no pending interrupts on this thread\",\n );\n }\n\n const responsesById = new Map<string, AgUiResumeEntry>();\n for (const entry of responses) {\n if (!entry || typeof entry.interruptId !== \"string\") {\n throw new Error(\n \"[agui] submitInterruptResponses: every entry must have an interruptId\",\n );\n }\n if (entry.status !== \"resolved\" && entry.status !== \"cancelled\") {\n throw new Error(\n `[agui] submitInterruptResponses: invalid status \"${entry.status}\" for interrupt ${entry.interruptId}`,\n );\n }\n if (responsesById.has(entry.interruptId)) {\n throw new Error(\n `[agui] submitInterruptResponses: duplicate response for interrupt ${entry.interruptId}`,\n );\n }\n responsesById.set(entry.interruptId, entry);\n }\n\n const openIds = pending.interrupts.map((i) => i.id);\n const missing = openIds.filter((id) => !responsesById.has(id));\n if (missing.length > 0) {\n throw new Error(\n `[agui] submitInterruptResponses: missing responses for open interrupts: ${missing.join(\", \")}`,\n );\n }\n const known = new Set(openIds);\n const unknownIds = [...responsesById.keys()].filter((id) => !known.has(id));\n if (unknownIds.length > 0) {\n throw new Error(\n `[agui] submitInterruptResponses: unknown interrupt ids: ${unknownIds.join(\", \")}`,\n );\n }\n\n const now = Date.now();\n for (const interrupt of pending.interrupts) {\n if (!interrupt.expiresAt) continue;\n const expiry = new Date(interrupt.expiresAt).getTime();\n if (Number.isNaN(expiry)) {\n throw new Error(\n `[agui] submitInterruptResponses: interrupt ${interrupt.id} has malformed expiresAt \"${interrupt.expiresAt}\"`,\n );\n }\n if (expiry <= now) {\n throw new Error(\n `[agui] submitInterruptResponses: interrupt ${interrupt.id} expired at ${interrupt.expiresAt}`,\n );\n }\n }\n\n const resume: AgUiResumeEntry[] = openIds.map(\n (id) => responsesById.get(id)!,\n );\n\n if (this.isRunningFlag) {\n throw new Error(\n \"[agui] submitInterruptResponses: a run is already in progress\",\n );\n }\n\n this.clearPendingInterrupts(pending.messageId);\n await this.startRun(pending.messageId, this.lastRunConfig, resume);\n }\n\n private clearPendingInterrupts(messageId: string): void {\n let touched = false;\n this.messages = this.messages.map((message) => {\n if (message.id !== messageId || message.role !== \"assistant\")\n return message;\n const assistant = message as ThreadAssistantMessage;\n if (\n assistant.status?.type !== \"requires-action\" ||\n assistant.status.reason !== \"interrupt\"\n ) {\n return assistant;\n }\n touched = true;\n const aguiMeta = assistant.metadata.custom[AG_UI_METADATA_NAMESPACE] as\n | AgUiCustomMetadata\n | undefined;\n const { interrupts: _drop, ...restAgui } = aguiMeta ?? {};\n const newCustom = { ...assistant.metadata.custom };\n if (Object.keys(restAgui).length > 0) {\n newCustom[AG_UI_METADATA_NAMESPACE] = restAgui;\n } else {\n delete newCustom[AG_UI_METADATA_NAMESPACE];\n }\n return {\n ...assistant,\n status: { type: \"complete\" as const, reason: \"unknown\" as const },\n metadata: { ...assistant.metadata, custom: newCustom },\n };\n });\n if (touched) this.notifyUpdate();\n }\n\n findMessageIdForToolCall(toolCallId: string): string | undefined {\n let fallbackMessageId: string | undefined;\n for (let index = this.messages.length - 1; index >= 0; index--) {\n const message = this.messages[index];\n if (!message || message.role !== \"assistant\") continue;\n for (const part of message.content) {\n if (part.type !== \"tool-call\" || part.toolCallId !== toolCallId)\n continue;\n if (!(\"result\" in part) || part.result === undefined) {\n return message.id;\n }\n fallbackMessageId ??= message.id;\n }\n }\n return fallbackMessageId;\n }\n\n addToolResult(options: AddToolResultOptions): void {\n let updated = false;\n this.messages = this.messages.map((message) => {\n if (message.id !== options.messageId || message.role !== \"assistant\")\n return message;\n const assistant = message as ThreadAssistantMessage;\n let matchedToolCall = false;\n const content = assistant.content.map((part) => {\n if (part.type !== \"tool-call\" || part.toolCallId !== options.toolCallId)\n return part;\n matchedToolCall = true;\n return {\n ...part,\n result: options.result,\n artifact: options.artifact,\n isError: options.isError,\n };\n });\n if (!matchedToolCall) return message;\n updated = true;\n return { ...assistant, content };\n });\n\n if (!updated) return;\n this.notifyUpdate();\n this.maybeResumeAfterToolResults(options.messageId);\n }\n\n // The continuation fires whether the frontend result lands before\n // RUN_FINISHED (the status flips to requires-action only later, while the\n // run is still draining) or after it.\n private maybeResumeAfterToolResults(messageId: string): void {\n if (!this.maybeCompleteAfterToolResults(messageId)) return;\n\n if (this.isRunningFlag) {\n // A run is still draining (RUN_FINISHED arrived but the stream has not\n // closed). Defer until startRun's tail so we never start two runs.\n this.pendingResumeMessageId = messageId;\n return;\n }\n this.startResumeRun(messageId);\n }\n\n private maybeCompleteAfterToolResults(messageId: string): boolean {\n const message = this.messages.find((m) => m.id === messageId);\n if (!message || message.role !== \"assistant\") return false;\n const assistant = message as ThreadAssistantMessage;\n if (\n assistant.status?.type !== \"requires-action\" ||\n assistant.status.reason !== \"tool-calls\"\n ) {\n return false;\n }\n const allResolved = assistant.content.every(\n (part) =>\n part.type !== \"tool-call\" ||\n (\"result\" in part && part.result !== undefined),\n );\n if (!allResolved) return false;\n\n this.messages = this.messages.map((m) =>\n m.id === messageId && m.role === \"assistant\"\n ? {\n ...(m as ThreadAssistantMessage),\n status: { type: \"complete\" as const, reason: \"unknown\" as const },\n }\n : m,\n );\n this.notifyUpdate();\n this.persistAssistantHistory(messageId);\n return true;\n }\n\n private startResumeRun(messageId: string): void {\n void this.startRun(messageId, this.lastRunConfig).catch((error) => {\n this.onError?.(error instanceof Error ? error : new Error(String(error)));\n });\n }\n\n applyExternalMessages(messages: readonly ThreadMessage[]): void {\n this.assistantHistoryParents.clear();\n this.messages = [...messages];\n this.recordedHistoryIds.clear();\n for (const message of this.messages) {\n this.recordedHistoryIds.add(message.id);\n }\n this.notifyUpdate();\n }\n\n loadExternalState(state: ReadonlyJSONValue): void {\n this.stateSnapshot = state;\n this.notifyUpdate();\n }\n\n private async startRun(\n parentId: string | null,\n runConfig?: RunConfig,\n resume?: AgUiResumeEntry[],\n resumeStream?: ResumeStream,\n ): Promise<void> {\n const normalizedRunConfig = runConfig ?? {};\n this.lastRunConfig = normalizedRunConfig;\n this.resetHead(parentId);\n const historicalMessages = [...this.messages];\n\n this.pendingError = null;\n const assistantParentId = parentId ?? this.messages.at(-1)?.id ?? null;\n let assistantMessageId: string | undefined;\n const ensureAssistant = () => {\n if (assistantMessageId) return assistantMessageId;\n const created = this.insertAssistantPlaceholder();\n assistantMessageId = created;\n this.markPendingAssistantHistory(created, assistantParentId ?? null);\n return created;\n };\n\n const applyUpdate = (update: ChatModelRunResult) => {\n const resolved = this.updateAssistantMessage(ensureAssistant(), update);\n if (resolved !== assistantMessageId) {\n assistantMessageId = resolved;\n }\n };\n\n const aggregator = new RunAggregator({\n showThinking: this.showThinking,\n logger: this.logger,\n emit: applyUpdate,\n onServerMessageId: (serverId) => {\n const placeholder = ensureAssistant();\n if (placeholder === serverId) return;\n this.reassignAssistantId(placeholder, serverId);\n assistantMessageId = serverId;\n },\n });\n const dispatch = (event: AgUiEvent) => this.handleEvent(aggregator, event);\n\n const abortController = new AbortController();\n const abortSignal = abortController.signal;\n this.abortController = abortController;\n\n let cancelRun = () => dispatch({ type: \"RUN_CANCELLED\" });\n abortSignal.addEventListener(\n \"abort\",\n () => {\n cancelRun();\n this.finishRun(abortController);\n this.onCancel?.();\n },\n { once: true },\n );\n\n this.setRunning(true);\n\n try {\n if (resumeStream) {\n // Cancel flips only the status; an aggregator RUN_CANCELLED would emit an empty snapshot and wipe the replayed content.\n cancelRun = () =>\n applyUpdate({ status: { type: \"incomplete\", reason: \"cancelled\" } });\n await this.consumeResumeStream(resumeStream, {\n runConfig: normalizedRunConfig,\n threadId: this.agent.threadId || \"main\",\n parentId: assistantParentId,\n historicalMessages,\n abortSignal,\n ensureAssistant,\n applyUpdate,\n getAssistantMessageId: () => assistantMessageId,\n });\n } else {\n const runId = generateId();\n aggregator.handle({ type: \"RUN_STARTED\", runId });\n const input = this.buildRunInput(\n runId,\n normalizedRunConfig,\n historicalMessages,\n resume,\n );\n const subscriber = createAgUiSubscriber({\n dispatch,\n runId,\n logger: this.logger,\n onRunFailed: (error) => {\n this.pendingError = error;\n this.onError?.(error);\n },\n });\n try {\n (this.agent as any).messages = input.messages;\n (this.agent as any).threadId = input.threadId;\n (this.agent as any).state = input.state ?? null;\n } catch {\n // ignore\n }\n await (this.agent as any).runAgent(input, subscriber, {\n signal: abortSignal,\n });\n }\n } catch (error) {\n if (!abortSignal.aborted) {\n const err = error instanceof Error ? error : new Error(String(error));\n dispatch({ type: \"RUN_ERROR\", message: err.message });\n this.onError?.(err);\n this.pendingError = this.pendingError ?? err;\n }\n } finally {\n this.finishRun(abortController);\n }\n\n if (this.pendingError) {\n const err = this.pendingError;\n this.pendingError = null;\n this.pendingResumeMessageId = null;\n throw err;\n }\n\n // A tool result that landed before the run settled deferred its\n // continuation here so a second run never overlaps the first.\n if (this.pendingResumeMessageId !== null) {\n const resumeMessageId = this.pendingResumeMessageId;\n this.pendingResumeMessageId = null;\n if (!abortSignal.aborted) {\n this.startResumeRun(resumeMessageId);\n }\n }\n }\n\n // Replays a persisted run's snapshots into the existing assistant message, bypassing agent.runAgent so it is not re-invoked.\n private async consumeResumeStream(\n stream: ResumeStream,\n ctx: {\n runConfig: RunConfig;\n threadId: string;\n parentId: string | null;\n historicalMessages: readonly ThreadMessage[];\n abortSignal: AbortSignal;\n ensureAssistant: () => string;\n applyUpdate: (update: ChatModelRunResult) => void;\n getAssistantMessageId: () => string | undefined;\n },\n ): Promise<void> {\n const assistantId = ctx.ensureAssistant();\n const currentId = () => ctx.getAssistantMessageId() ?? assistantId;\n const options: ChatModelRunOptions = {\n messages: ctx.historicalMessages,\n runConfig: ctx.runConfig,\n abortSignal: ctx.abortSignal,\n context: this.runtime?.thread.getModelContext() ?? {},\n unstable_assistantMessageId: assistantId,\n unstable_threadId: ctx.threadId,\n unstable_parentId: ctx.parentId,\n unstable_getMessage: () => {\n const message = this.messages.find((m) => m.id === currentId());\n if (!message) {\n throw new Error(\n \"[agui] resume stream requested the assistant message before it existed\",\n );\n }\n return message;\n },\n };\n\n try {\n for await (const result of stream(options)) {\n if (ctx.abortSignal.aborted) return;\n ctx.applyUpdate(result);\n }\n } catch (error) {\n if (ctx.abortSignal.aborted) return;\n const err = error instanceof Error ? error : new Error(String(error));\n ctx.applyUpdate({\n status: { type: \"incomplete\", reason: \"error\", error: err.message },\n });\n this.onError?.(err);\n this.pendingError = this.pendingError ?? err;\n return;\n }\n\n if (ctx.abortSignal.aborted) return;\n const current = this.messages.find((m) => m.id === currentId());\n if (!current || current.status?.type === \"running\") {\n ctx.applyUpdate({ status: { type: \"complete\", reason: \"unknown\" } });\n }\n }\n\n private buildRunInput(\n runId: string,\n runConfig: RunConfig | undefined,\n historyMessages: readonly ThreadMessage[] | undefined,\n resume?: AgUiResumeEntry[],\n ) {\n const threadId = this.agent.threadId || \"main\";\n const messages = toAgUiMessages(historyMessages ?? this.messages);\n const context = this.runtime?.thread.getModelContext();\n return {\n threadId,\n runId,\n state: this.stateSnapshot ?? null,\n messages,\n tools: toAgUiTools(context?.tools),\n context: context?.system\n ? [{ description: \"system\", value: context.system }]\n : [],\n forwardedProps: {\n ...(context?.callSettings ?? {}),\n ...(context?.config ?? {}),\n ...(runConfig?.custom ? { runConfig: runConfig.custom } : {}),\n },\n ...(resume !== undefined ? { resume } : {}),\n };\n }\n\n private installResumeShim(): void {\n const agent = this.agent as any;\n if (agent[symbolResumeShim]) return;\n agent[symbolResumeShim] = true;\n const onInstance = Object.hasOwn(agent, \"prepareRunAgentInput\");\n const original = onInstance\n ? agent.prepareRunAgentInput\n : Object.getPrototypeOf(agent)?.prepareRunAgentInput;\n if (typeof original !== \"function\") return;\n agent.prepareRunAgentInput = function (\n this: unknown,\n params: { resume?: unknown } | undefined,\n ) {\n const input = original.call(this, params);\n if (params?.resume !== undefined && input && typeof input === \"object\") {\n return { ...(input as object), resume: params.resume };\n }\n return input;\n };\n }\n\n private setRunning(running: boolean) {\n this.isRunningFlag = running;\n this.notifyUpdate();\n }\n\n private finishRun(controller: AbortController | null) {\n if (this.abortController === controller) {\n this.abortController = null;\n }\n this.setRunning(false);\n }\n\n private insertAssistantPlaceholder(): string {\n const id = generateOptimisticId();\n const assistant: ThreadAssistantMessage = {\n id,\n role: \"assistant\",\n createdAt: new Date(),\n status: { type: \"running\" },\n content: [],\n metadata: {\n unstable_state: this.stateSnapshot ?? null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n isOptimistic: true,\n custom: {},\n },\n };\n this.messages = [...this.messages, assistant];\n this.notifyUpdate();\n return id;\n }\n\n private reassignAssistantId(oldId: string, newId: string): void {\n if (oldId === newId) return;\n\n const collidesWithExisting = this.messages.some((m) => m.id === newId);\n\n if (collidesWithExisting) {\n this.logger.debug?.(\n \"[agui] reassignAssistantId: server id already present in messages, dropping placeholder\",\n { oldId, newId },\n );\n this.messages = this.messages.filter((m) => m.id !== oldId);\n } else {\n this.messages = this.messages.map((m) => {\n if (m.id !== oldId) return m;\n const { isOptimistic: _, ...metadata } = m.metadata;\n return { ...m, id: newId, metadata } as ThreadMessage;\n });\n }\n\n const pendingParent = this.assistantHistoryParents.get(oldId);\n if (pendingParent !== undefined) {\n this.assistantHistoryParents.delete(oldId);\n if (!this.assistantHistoryParents.has(newId)) {\n this.assistantHistoryParents.set(newId, pendingParent);\n }\n }\n\n if (this.recordedHistoryIds.has(oldId)) {\n this.recordedHistoryIds.delete(oldId);\n this.recordedHistoryIds.add(newId);\n }\n\n this.notifyUpdate();\n }\n\n private updateAssistantMessage(\n messageId: string,\n update: ChatModelRunResult,\n ): string {\n let touched = false;\n let latestStatus: MessageStatus | undefined;\n this.messages = this.messages.map((message) => {\n if (message.id !== messageId || message.role !== \"assistant\")\n return message;\n touched = true;\n const assistant = message as ThreadAssistantMessage;\n const metadata = update.metadata\n ? this.mergeAssistantMetadata(assistant.metadata, update.metadata)\n : assistant.metadata;\n latestStatus = update.status ?? assistant.status;\n const content =\n update.content !== undefined\n ? this.preserveToolResults(\n assistant.content,\n update.content as ThreadAssistantMessage[\"content\"],\n )\n : assistant.content;\n return {\n ...assistant,\n content,\n status: latestStatus,\n metadata,\n };\n });\n if (!touched) return messageId;\n\n let resolvedMessageId = messageId;\n const isSettled =\n latestStatus !== undefined && latestStatus.type !== \"running\";\n if (isSettled && isOptimisticId(messageId)) {\n const stableId = generateId();\n this.reassignAssistantId(messageId, stableId);\n resolvedMessageId = stableId;\n } else {\n this.notifyUpdate();\n }\n if (this.isPersistableStatus(latestStatus)) {\n this.persistAssistantHistory(resolvedMessageId);\n }\n this.maybeResumeAfterToolResults(resolvedMessageId);\n return resolvedMessageId;\n }\n\n // The RunAggregator rebuilds the assistant content from stream events only,\n // so a fresh snapshot omits results injected via addToolResult (frontend tool\n // execution). Carry those results forward so the aggregator never clobbers\n // them. Results are only ever added in this flow, so preserving is safe.\n private preserveToolResults(\n previous: ThreadAssistantMessage[\"content\"],\n next: ThreadAssistantMessage[\"content\"],\n ): ThreadAssistantMessage[\"content\"] {\n const resolved = new Map<string, ToolCallMessagePart>();\n for (const part of previous) {\n if (\n part.type === \"tool-call\" &&\n \"result\" in part &&\n part.result !== undefined\n ) {\n resolved.set(part.toolCallId, part);\n }\n }\n if (resolved.size === 0) return next;\n\n let changed = false;\n const merged = next.map((part) => {\n if (part.type !== \"tool-call\") return part;\n if (\"result\" in part && part.result !== undefined) return part;\n const prior = resolved.get(part.toolCallId);\n if (!prior) return part;\n changed = true;\n return {\n ...part,\n result: prior.result,\n ...(prior.artifact !== undefined ? { artifact: prior.artifact } : {}),\n ...(prior.isError !== undefined ? { isError: prior.isError } : {}),\n };\n });\n return changed ? (merged as ThreadAssistantMessage[\"content\"]) : next;\n }\n\n private mergeAssistantMetadata(\n current: ThreadAssistantMessage[\"metadata\"],\n incoming: NonNullable<ChatModelRunResult[\"metadata\"]>,\n ): ThreadAssistantMessage[\"metadata\"] {\n const annotations = incoming.unstable_annotations\n ? [...current.unstable_annotations, ...incoming.unstable_annotations]\n : current.unstable_annotations;\n const data = incoming.unstable_data\n ? [...current.unstable_data, ...incoming.unstable_data]\n : current.unstable_data;\n const steps = incoming.steps\n ? [...current.steps, ...incoming.steps]\n : current.steps;\n return {\n unstable_state:\n incoming.unstable_state !== undefined\n ? incoming.unstable_state\n : current.unstable_state,\n unstable_annotations: annotations,\n unstable_data: data,\n steps,\n ...(current.isOptimistic ? { isOptimistic: true } : {}),\n ...(incoming.timing ? { timing: incoming.timing } : {}),\n custom: incoming.custom\n ? { ...current.custom, ...incoming.custom }\n : current.custom,\n };\n }\n\n private handleEvent(aggregator: RunAggregator, event: AgUiEvent) {\n switch (event.type) {\n case \"STATE_SNAPSHOT\": {\n this.stateSnapshot = event.snapshot as ReadonlyJSONValue;\n this.notifyUpdate();\n return;\n }\n case \"STATE_DELTA\": {\n if (event.delta.length === 0) return;\n try {\n const state = this.stateSnapshot ?? {};\n const result = jsonpatch.applyPatch(\n state,\n event.delta as Operation[],\n /* validateOperation */ true,\n /* mutateDocument */ false,\n );\n this.stateSnapshot = result.newDocument as ReadonlyJSONValue;\n this.notifyUpdate();\n } catch (error) {\n this.logger.error?.(\"[agui] failed to apply state delta\", error);\n }\n return;\n }\n case \"MESSAGES_SNAPSHOT\": {\n this.importMessagesSnapshot(event.messages);\n return;\n }\n case \"TOOL_CALL_RESULT\": {\n if (!aggregator.hasToolCall(event.toolCallId)) {\n const messageId = this.findMessageIdForToolCall(event.toolCallId);\n if (messageId !== undefined) {\n this.applyCrossRunToolResult(messageId, event);\n return;\n }\n }\n aggregator.handle(event);\n return;\n }\n default:\n aggregator.handle(event);\n }\n }\n\n private applyCrossRunToolResult(\n messageId: string,\n event: Extract<AgUiEvent, { type: \"TOOL_CALL_RESULT\" }>,\n ): void {\n let updated = false;\n this.messages = this.messages.map((message) => {\n if (message.id !== messageId || message.role !== \"assistant\")\n return message;\n const assistant = message as ThreadAssistantMessage;\n let matchedToolCall = false;\n const content = assistant.content.map((part) => {\n if (part.type !== \"tool-call\" || part.toolCallId !== event.toolCallId)\n return part;\n matchedToolCall = true;\n return {\n ...part,\n result: tryParseJSON(event.content ?? \"\") as ReadonlyJSONValue,\n ...(event.role === \"tool\" ? { isError: false } : {}),\n ...(event.messageId\n ? { unstable_toolMessageId: event.messageId }\n : {}),\n };\n });\n if (!matchedToolCall) return message;\n updated = true;\n return { ...assistant, content };\n });\n\n if (!updated) return;\n this.notifyUpdate();\n // Not maybeResumeAfterToolResults: the delivering run is already in\n // flight, and a resume from the owner would reset the head past it.\n this.maybeCompleteAfterToolResults(messageId);\n }\n\n private importMessagesSnapshot(rawMessages: readonly unknown[]) {\n try {\n const normalized = fromAgUiMessages(rawMessages, {\n showThinking: this.showThinking,\n });\n const converted: ThreadMessage[] = [];\n for (const message of normalized) {\n try {\n converted.push(\n fromThreadMessageLike(message, generateId(), FALLBACK_USER_STATUS),\n );\n } catch (error) {\n this.logger.error?.(\n \"[agui] failed to import message from snapshot\",\n error,\n );\n }\n }\n this.applyExternalMessages(converted);\n } catch (error) {\n this.logger.error?.(\"[agui] failed to import messages snapshot\", error);\n }\n }\n\n private toThreadMessage(message: AppendMessage): ThreadMessage {\n return fromThreadMessageLike(\n message as any,\n generateId(),\n FALLBACK_USER_STATUS,\n );\n }\n\n private resetHead(parentId: string | null | undefined) {\n if (!parentId) {\n if (this.messages.length) {\n this.messages = [];\n }\n return;\n }\n const idx = this.messages.findIndex((message) => message.id === parentId);\n if (idx === -1) return;\n this.messages = this.messages.slice(0, idx + 1);\n }\n\n private isTerminalStatus(status?: MessageStatus): boolean {\n return status?.type === \"complete\" || status?.type === \"incomplete\";\n }\n\n private isPersistableStatus(status?: MessageStatus): boolean {\n if (this.isTerminalStatus(status)) return true;\n return status?.type === \"requires-action\" && status.reason === \"interrupt\";\n }\n\n private recordHistoryEntry(parentId: string | null, message: ThreadMessage) {\n this.appendHistoryItem(parentId, message);\n }\n\n private markPendingAssistantHistory(\n messageId: string,\n parentId: string | null,\n ) {\n if (!this.history) return;\n this.assistantHistoryParents.set(messageId, parentId);\n }\n\n private persistAssistantHistory(messageId: string) {\n if (!this.history) return;\n const parentId = this.assistantHistoryParents.get(messageId);\n if (parentId === undefined) return;\n const message = this.messages.find((m) => m.id === messageId);\n if (!message || message.role !== \"assistant\") return;\n if (!this.isPersistableStatus(message.status)) return;\n this.assistantHistoryParents.delete(messageId);\n this.appendHistoryItem(parentId, message);\n }\n\n private appendHistoryItem(parentId: string | null, message: ThreadMessage) {\n if (!this.history || this.recordedHistoryIds.has(message.id)) return;\n this.recordedHistoryIds.add(message.id);\n void this.history.append({ parentId, message }).catch((error) => {\n this.recordedHistoryIds.delete(message.id);\n this.logger.error?.(\"[agui] failed to append history entry\", error);\n });\n }\n}\n"],"mappings":";;;;;;;AAiCA,MAAM,mBAAmB;AACzB,MAAM,6BAA6B,GAAG,mBAAmB,WAAW;AACpE,MAAM,kBAAkB,OAAe,GAAG,WAAW,gBAAgB;AAErE,MAAM,mBAAmB,OAAO,kBAAkB;AAuBlD,MAAM,uBAAuB;CAAE,MAAM;CAAY,QAAQ;AAAU;AAEnE,IAAa,wBAAb,MAAmC;CACjC;CACA;CACA;CACA;CACA;CACA;CAEA;CACA,WAAoC,CAAC;CACrC,gBAAwB;CACxB,kBAAkD;CAClD;CACA,eAAqC;CACrC;CACA;CACA,0CAA2C,IAAI,IAA2B;CAC1E,qCAAsC,IAAI,IAAY;CACtD,aAAqB;CACrB;CACA,yBAAgD;CAEhD,YAAY,SAAsB;EAChC,KAAK,QAAQ,QAAQ;EACrB,KAAK,SAAS,QAAQ;EACtB,KAAK,eAAe,QAAQ;EAC5B,KAAK,UAAU,QAAQ;EACvB,KAAK,WAAW,QAAQ;EACxB,KAAK,UAAU,QAAQ;EACvB,KAAK,eAAe,QAAQ;EAC5B,KAAK,kBAAkB;CACzB;CAEA,cAAc,SAA4C;EACxD,KAAK,QAAQ,QAAQ;EACrB,KAAK,SAAS,QAAQ;EACtB,KAAK,eAAe,QAAQ;EAC5B,KAAK,UAAU,QAAQ;EACvB,KAAK,WAAW,QAAQ;EACxB,KAAK,UAAU,QAAQ;EACvB,KAAK,kBAAkB;CACzB;CAEA,cAAc,SAA2B;EACvC,KAAK,UAAU;CACjB;CAEA,gBAAgB;EACd,KAAK,UAAU,KAAA;CACjB;CAEA,cAAwC;EACtC,OAAO,KAAK;CACd;CAEA,WAA0C;EACxC,OAAO,KAAK;CACd;CAEA,YAAqB;EACnB,OAAO,KAAK;CACd;CAEA,IAAI,YAAqB;EACvB,OAAO,KAAK;CACd;CAEA,kBAAiC;EAC/B,IAAI,KAAK,cAAc,OAAO,KAAK;EAEnC,MAAM,UAAU,KAAK,SAAS,KAAK,KAAK,QAAQ,QAAQ,IAAI;EAE5D,KAAK,aAAa;EAElB,KAAK,eAAe,QACjB,KAAK,OAAO,SAAS;GACpB,IAAI,CAAC,MAAM;GAEX,MAAM,WAAW,KAAK,SAAS,KAAK,SAAS,KAAK,OAAO;GACzD,KAAK,sBAAsB,QAAQ;GAEnC,IAAI,KAAK,iBAAiB;IACxB,MAAM,WAAW,KAAK,UAAU,SAAS,GAAG,EAAE,CAAC,EAAE,MAAM;IACvD,MAAM,eAAe,KAAK,SAAS,QAAQ,KAAK,KAAK,OAAO;IAC5D,MAAM,KAAK,SACT,UACA,KAAK,eACL,KAAA,GACA,YACF;GACF;EACF,CAAC,CAAC,CACD,OAAO,UAAU;GAChB,KAAK,OAAO,QAAQ,iCAAiC,KAAK;GAC1D,KAAK,UACH,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAC1D;EACF,CAAC,CAAC,CACD,cAAc;GACb,KAAK,aAAa;GAClB,KAAK,aAAa;EACpB,CAAC;EAEH,KAAK,aAAa;EAClB,OAAO,KAAK;CACd;CAEA,MAAM,OAAO,SAAuC;EAClD,MAAM,WAAW,QAAQ,YAAY,QAAQ,SAAS;EACtD,IAAI,UAAU,KAAK,0BAA0B;EAC7C,IAAI,QAAQ,UACV,KAAK,WAAW,KAAK,SAAS,QAC3B,UAAU,MAAM,OAAO,QAAQ,QAClC;EAEF,KAAK,UAAU,QAAQ,QAAQ;EAE/B,MAAM,gBAAgB,KAAK,gBAAgB,OAAO;EAClD,KAAK,WAAW,CAAC,GAAG,KAAK,UAAU,aAAa;EAChD,KAAK,aAAa;EAClB,KAAK,mBAAmB,QAAQ,YAAY,MAAM,aAAa;EAE/D,IAAI,CAAC,UAAU;EACf,MAAM,KAAK,SAAS,cAAc,IAAI,QAAQ,SAAS;CACzD;CAEA,MAAM,KAAK,SAAuC;EAChD,MAAM,KAAK,OAAO,OAAO;CAC3B;CAEA,MAAM,OACJ,UACA,SAAoC,CAAC,GACtB;EACf,KAAK,0BAA0B;EAC/B,KAAK,UAAU,QAAQ;EACvB,KAAK,aAAa;EAClB,MAAM,KAAK,SAAS,UAAU,OAAO,SAAS;CAChD;CAEA,MAAM,SAAwB;EAC5B,IAAI,CAAC,KAAK,iBAAiB;EAC3B,KAAK,gBAAgB,MAAM;CAC7B;CAEA,MAAM,OAAO,QAAwC;EACnD,KAAK,0BAA0B;EAC/B,MAAM,KAAK,SACT,OAAO,UACP,OAAO,aAAa,KAAK,eACzB,KAAA,GACA,OAAO,MACT;CACF;CAEA,MAAM,kBAAkB,UAAmD;EAEzE,MAAM,eAAe,KAAK,SAAS,QAAQ,KAAK,KAAK,OAAO;EAC5D,IAAI,CAAC,cAAc;GACjB,MAAM,wBAAQ,IAAI,MAChB,oHACF;GACA,KAAK,OAAO,QAAQ,MAAM,OAAO;GACjC,KAAK,UAAU,KAAK;GACpB;EACF;EACA,MAAM,WAAW,SAAS,GAAG,EAAE,CAAC,EAAE,MAAM;EACxC,IAAI;GACF,MAAM,KAAK,SACT,UACA,KAAK,eACL,KAAA,GACA,YACF;EACF,QAAQ,CAER;CACF;CAEA,4BAA0C;EACxC,IAAI,CAAC,KAAK,qBAAqB,GAAG;EAClC,MAAM,IAAI,MACR,0GACF;CACF;CAEA,uBAGS;EACP,MAAM,YAAY,KAAK,SAAS,UAAU,MAAM,EAAE,SAAS,WAAW;EAGtE,IACE,CAAC,aACD,UAAU,QAAQ,SAAS,qBAC3B,UAAU,OAAO,WAAW,aAE5B,OAAO;EAET,MAAM,SACJ,UAAU,SAAS,OAAO,yBAAyB,EAGlD;EACH,IAAI,CAAC,QAAQ,QAAQ,OAAO;EAC5B,OAAO;GAAE,WAAW,UAAU;GAAI,YAAY;EAAO;CACvD;CAEA,MAAM,yBACJ,WACe;EACf,MAAM,UAAU,KAAK,qBAAqB;EAC1C,IAAI,CAAC,SACH,MAAM,IAAI,MACR,uEACF;EAGF,MAAM,gCAAgB,IAAI,IAA6B;EACvD,KAAK,MAAM,SAAS,WAAW;GAC7B,IAAI,CAAC,SAAS,OAAO,MAAM,gBAAgB,UACzC,MAAM,IAAI,MACR,uEACF;GAEF,IAAI,MAAM,WAAW,cAAc,MAAM,WAAW,aAClD,MAAM,IAAI,MACR,oDAAoD,MAAM,OAAO,kBAAkB,MAAM,aAC3F;GAEF,IAAI,cAAc,IAAI,MAAM,WAAW,GACrC,MAAM,IAAI,MACR,qEAAqE,MAAM,aAC7E;GAEF,cAAc,IAAI,MAAM,aAAa,KAAK;EAC5C;EAEA,MAAM,UAAU,QAAQ,WAAW,KAAK,MAAM,EAAE,EAAE;EAClD,MAAM,UAAU,QAAQ,QAAQ,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC;EAC7D,IAAI,QAAQ,SAAS,GACnB,MAAM,IAAI,MACR,2EAA2E,QAAQ,KAAK,IAAI,GAC9F;EAEF,MAAM,QAAQ,IAAI,IAAI,OAAO;EAC7B,MAAM,aAAa,CAAC,GAAG,cAAc,KAAK,CAAC,CAAC,CAAC,QAAQ,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;EAC1E,IAAI,WAAW,SAAS,GACtB,MAAM,IAAI,MACR,2DAA2D,WAAW,KAAK,IAAI,GACjF;EAGF,MAAM,MAAM,KAAK,IAAI;EACrB,KAAK,MAAM,aAAa,QAAQ,YAAY;GAC1C,IAAI,CAAC,UAAU,WAAW;GAC1B,MAAM,SAAS,IAAI,KAAK,UAAU,SAAS,CAAC,CAAC,QAAQ;GACrD,IAAI,OAAO,MAAM,MAAM,GACrB,MAAM,IAAI,MACR,8CAA8C,UAAU,GAAG,4BAA4B,UAAU,UAAU,EAC7G;GAEF,IAAI,UAAU,KACZ,MAAM,IAAI,MACR,8CAA8C,UAAU,GAAG,cAAc,UAAU,WACrF;EAEJ;EAEA,MAAM,SAA4B,QAAQ,KACvC,OAAO,cAAc,IAAI,EAAE,CAC9B;EAEA,IAAI,KAAK,eACP,MAAM,IAAI,MACR,+DACF;EAGF,KAAK,uBAAuB,QAAQ,SAAS;EAC7C,MAAM,KAAK,SAAS,QAAQ,WAAW,KAAK,eAAe,MAAM;CACnE;CAEA,uBAA+B,WAAyB;EACtD,IAAI,UAAU;EACd,KAAK,WAAW,KAAK,SAAS,KAAK,YAAY;GAC7C,IAAI,QAAQ,OAAO,aAAa,QAAQ,SAAS,aAC/C,OAAO;GACT,MAAM,YAAY;GAClB,IACE,UAAU,QAAQ,SAAS,qBAC3B,UAAU,OAAO,WAAW,aAE5B,OAAO;GAET,UAAU;GAIV,MAAM,EAAE,YAAY,OAAO,GAAG,aAHb,UAAU,SAAS,OAAA,WAGmB,CAAC;GACxD,MAAM,YAAY,EAAE,GAAG,UAAU,SAAS,OAAO;GACjD,IAAI,OAAO,KAAK,QAAQ,CAAC,CAAC,SAAS,GACjC,UAAU,4BAA4B;QAEtC,OAAO,UAAU;GAEnB,OAAO;IACL,GAAG;IACH,QAAQ;KAAE,MAAM;KAAqB,QAAQ;IAAmB;IAChE,UAAU;KAAE,GAAG,UAAU;KAAU,QAAQ;IAAU;GACvD;EACF,CAAC;EACD,IAAI,SAAS,KAAK,aAAa;CACjC;CAEA,yBAAyB,YAAwC;EAC/D,IAAI;EACJ,KAAK,IAAI,QAAQ,KAAK,SAAS,SAAS,GAAG,SAAS,GAAG,SAAS;GAC9D,MAAM,UAAU,KAAK,SAAS;GAC9B,IAAI,CAAC,WAAW,QAAQ,SAAS,aAAa;GAC9C,KAAK,MAAM,QAAQ,QAAQ,SAAS;IAClC,IAAI,KAAK,SAAS,eAAe,KAAK,eAAe,YACnD;IACF,IAAI,EAAE,YAAY,SAAS,KAAK,WAAW,KAAA,GACzC,OAAO,QAAQ;IAEjB,sBAAsB,QAAQ;GAChC;EACF;EACA,OAAO;CACT;CAEA,cAAc,SAAqC;EACjD,IAAI,UAAU;EACd,KAAK,WAAW,KAAK,SAAS,KAAK,YAAY;GAC7C,IAAI,QAAQ,OAAO,QAAQ,aAAa,QAAQ,SAAS,aACvD,OAAO;GACT,MAAM,YAAY;GAClB,IAAI,kBAAkB;GACtB,MAAM,UAAU,UAAU,QAAQ,KAAK,SAAS;IAC9C,IAAI,KAAK,SAAS,eAAe,KAAK,eAAe,QAAQ,YAC3D,OAAO;IACT,kBAAkB;IAClB,OAAO;KACL,GAAG;KACH,QAAQ,QAAQ;KAChB,UAAU,QAAQ;KAClB,SAAS,QAAQ;IACnB;GACF,CAAC;GACD,IAAI,CAAC,iBAAiB,OAAO;GAC7B,UAAU;GACV,OAAO;IAAE,GAAG;IAAW;GAAQ;EACjC,CAAC;EAED,IAAI,CAAC,SAAS;EACd,KAAK,aAAa;EAClB,KAAK,4BAA4B,QAAQ,SAAS;CACpD;CAKA,4BAAoC,WAAyB;EAC3D,IAAI,CAAC,KAAK,8BAA8B,SAAS,GAAG;EAEpD,IAAI,KAAK,eAAe;GAGtB,KAAK,yBAAyB;GAC9B;EACF;EACA,KAAK,eAAe,SAAS;CAC/B;CAEA,8BAAsC,WAA4B;EAChE,MAAM,UAAU,KAAK,SAAS,MAAM,MAAM,EAAE,OAAO,SAAS;EAC5D,IAAI,CAAC,WAAW,QAAQ,SAAS,aAAa,OAAO;EACrD,MAAM,YAAY;EAClB,IACE,UAAU,QAAQ,SAAS,qBAC3B,UAAU,OAAO,WAAW,cAE5B,OAAO;EAOT,IAAI,CALgB,UAAU,QAAQ,OACnC,SACC,KAAK,SAAS,eACb,YAAY,QAAQ,KAAK,WAAW,KAAA,CAE1B,GAAG,OAAO;EAEzB,KAAK,WAAW,KAAK,SAAS,KAAK,MACjC,EAAE,OAAO,aAAa,EAAE,SAAS,cAC7B;GACE,GAAI;GACJ,QAAQ;IAAE,MAAM;IAAqB,QAAQ;GAAmB;EAClE,IACA,CACN;EACA,KAAK,aAAa;EAClB,KAAK,wBAAwB,SAAS;EACtC,OAAO;CACT;CAEA,eAAuB,WAAyB;EAC9C,KAAU,SAAS,WAAW,KAAK,aAAa,CAAC,CAAC,OAAO,UAAU;GACjE,KAAK,UAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;EAC1E,CAAC;CACH;CAEA,sBAAsB,UAA0C;EAC9D,KAAK,wBAAwB,MAAM;EACnC,KAAK,WAAW,CAAC,GAAG,QAAQ;EAC5B,KAAK,mBAAmB,MAAM;EAC9B,KAAK,MAAM,WAAW,KAAK,UACzB,KAAK,mBAAmB,IAAI,QAAQ,EAAE;EAExC,KAAK,aAAa;CACpB;CAEA,kBAAkB,OAAgC;EAChD,KAAK,gBAAgB;EACrB,KAAK,aAAa;CACpB;CAEA,MAAc,SACZ,UACA,WACA,QACA,cACe;EACf,MAAM,sBAAsB,aAAa,CAAC;EAC1C,KAAK,gBAAgB;EACrB,KAAK,UAAU,QAAQ;EACvB,MAAM,qBAAqB,CAAC,GAAG,KAAK,QAAQ;EAE5C,KAAK,eAAe;EACpB,MAAM,oBAAoB,YAAY,KAAK,SAAS,GAAG,EAAE,CAAC,EAAE,MAAM;EAClE,IAAI;EACJ,MAAM,wBAAwB;GAC5B,IAAI,oBAAoB,OAAO;GAC/B,MAAM,UAAU,KAAK,2BAA2B;GAChD,qBAAqB;GACrB,KAAK,4BAA4B,SAAS,qBAAqB,IAAI;GACnE,OAAO;EACT;EAEA,MAAM,eAAe,WAA+B;GAClD,MAAM,WAAW,KAAK,uBAAuB,gBAAgB,GAAG,MAAM;GACtE,IAAI,aAAa,oBACf,qBAAqB;EAEzB;EAEA,MAAM,aAAa,IAAI,cAAc;GACnC,cAAc,KAAK;GACnB,QAAQ,KAAK;GACb,MAAM;GACN,oBAAoB,aAAa;IAC/B,MAAM,cAAc,gBAAgB;IACpC,IAAI,gBAAgB,UAAU;IAC9B,KAAK,oBAAoB,aAAa,QAAQ;IAC9C,qBAAqB;GACvB;EACF,CAAC;EACD,MAAM,YAAY,UAAqB,KAAK,YAAY,YAAY,KAAK;EAEzE,MAAM,kBAAkB,IAAI,gBAAgB;EAC5C,MAAM,cAAc,gBAAgB;EACpC,KAAK,kBAAkB;EAEvB,IAAI,kBAAkB,SAAS,EAAE,MAAM,gBAAgB,CAAC;EACxD,YAAY,iBACV,eACM;GACJ,UAAU;GACV,KAAK,UAAU,eAAe;GAC9B,KAAK,WAAW;EAClB,GACA,EAAE,MAAM,KAAK,CACf;EAEA,KAAK,WAAW,IAAI;EAEpB,IAAI;GACF,IAAI,cAAc;IAEhB,kBACE,YAAY,EAAE,QAAQ;KAAE,MAAM;KAAc,QAAQ;IAAY,EAAE,CAAC;IACrE,MAAM,KAAK,oBAAoB,cAAc;KAC3C,WAAW;KACX,UAAU,KAAK,MAAM,YAAY;KACjC,UAAU;KACV;KACA;KACA;KACA;KACA,6BAA6B;IAC/B,CAAC;GACH,OAAO;IACL,MAAM,QAAQ,WAAW;IACzB,WAAW,OAAO;KAAE,MAAM;KAAe;IAAM,CAAC;IAChD,MAAM,QAAQ,KAAK,cACjB,OACA,qBACA,oBACA,MACF;IACA,MAAM,aAAa,qBAAqB;KACtC;KACA;KACA,QAAQ,KAAK;KACb,cAAc,UAAU;MACtB,KAAK,eAAe;MACpB,KAAK,UAAU,KAAK;KACtB;IACF,CAAC;IACD,IAAI;KACF,KAAM,MAAc,WAAW,MAAM;KACrC,KAAM,MAAc,WAAW,MAAM;KACrC,KAAM,MAAc,QAAQ,MAAM,SAAS;IAC7C,QAAQ,CAER;IACA,MAAO,KAAK,MAAc,SAAS,OAAO,YAAY,EACpD,QAAQ,YACV,CAAC;GACH;EACF,SAAS,OAAO;GACd,IAAI,CAAC,YAAY,SAAS;IACxB,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;IACpE,SAAS;KAAE,MAAM;KAAa,SAAS,IAAI;IAAQ,CAAC;IACpD,KAAK,UAAU,GAAG;IAClB,KAAK,eAAe,KAAK,gBAAgB;GAC3C;EACF,UAAU;GACR,KAAK,UAAU,eAAe;EAChC;EAEA,IAAI,KAAK,cAAc;GACrB,MAAM,MAAM,KAAK;GACjB,KAAK,eAAe;GACpB,KAAK,yBAAyB;GAC9B,MAAM;EACR;EAIA,IAAI,KAAK,2BAA2B,MAAM;GACxC,MAAM,kBAAkB,KAAK;GAC7B,KAAK,yBAAyB;GAC9B,IAAI,CAAC,YAAY,SACf,KAAK,eAAe,eAAe;EAEvC;CACF;CAGA,MAAc,oBACZ,QACA,KAUe;EACf,MAAM,cAAc,IAAI,gBAAgB;EACxC,MAAM,kBAAkB,IAAI,sBAAsB,KAAK;EACvD,MAAM,UAA+B;GACnC,UAAU,IAAI;GACd,WAAW,IAAI;GACf,aAAa,IAAI;GACjB,SAAS,KAAK,SAAS,OAAO,gBAAgB,KAAK,CAAC;GACpD,6BAA6B;GAC7B,mBAAmB,IAAI;GACvB,mBAAmB,IAAI;GACvB,2BAA2B;IACzB,MAAM,UAAU,KAAK,SAAS,MAAM,MAAM,EAAE,OAAO,UAAU,CAAC;IAC9D,IAAI,CAAC,SACH,MAAM,IAAI,MACR,wEACF;IAEF,OAAO;GACT;EACF;EAEA,IAAI;GACF,WAAW,MAAM,UAAU,OAAO,OAAO,GAAG;IAC1C,IAAI,IAAI,YAAY,SAAS;IAC7B,IAAI,YAAY,MAAM;GACxB;EACF,SAAS,OAAO;GACd,IAAI,IAAI,YAAY,SAAS;GAC7B,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;GACpE,IAAI,YAAY,EACd,QAAQ;IAAE,MAAM;IAAc,QAAQ;IAAS,OAAO,IAAI;GAAQ,EACpE,CAAC;GACD,KAAK,UAAU,GAAG;GAClB,KAAK,eAAe,KAAK,gBAAgB;GACzC;EACF;EAEA,IAAI,IAAI,YAAY,SAAS;EAC7B,MAAM,UAAU,KAAK,SAAS,MAAM,MAAM,EAAE,OAAO,UAAU,CAAC;EAC9D,IAAI,CAAC,WAAW,QAAQ,QAAQ,SAAS,WACvC,IAAI,YAAY,EAAE,QAAQ;GAAE,MAAM;GAAY,QAAQ;EAAU,EAAE,CAAC;CAEvE;CAEA,cACE,OACA,WACA,iBACA,QACA;EACA,MAAM,WAAW,KAAK,MAAM,YAAY;EACxC,MAAM,WAAW,eAAe,mBAAmB,KAAK,QAAQ;EAChE,MAAM,UAAU,KAAK,SAAS,OAAO,gBAAgB;EACrD,OAAO;GACL;GACA;GACA,OAAO,KAAK,iBAAiB;GAC7B;GACA,OAAO,YAAY,SAAS,KAAK;GACjC,SAAS,SAAS,SACd,CAAC;IAAE,aAAa;IAAU,OAAO,QAAQ;GAAO,CAAC,IACjD,CAAC;GACL,gBAAgB;IACd,GAAI,SAAS,gBAAgB,CAAC;IAC9B,GAAI,SAAS,UAAU,CAAC;IACxB,GAAI,WAAW,SAAS,EAAE,WAAW,UAAU,OAAO,IAAI,CAAC;GAC7D;GACA,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;EAC3C;CACF;CAEA,oBAAkC;EAChC,MAAM,QAAQ,KAAK;EACnB,IAAI,MAAM,mBAAmB;EAC7B,MAAM,oBAAoB;EAE1B,MAAM,WADa,OAAO,OAAO,OAAO,sBACd,IACtB,MAAM,uBACN,OAAO,eAAe,KAAK,CAAC,EAAE;EAClC,IAAI,OAAO,aAAa,YAAY;EACpC,MAAM,uBAAuB,SAE3B,QACA;GACA,MAAM,QAAQ,SAAS,KAAK,MAAM,MAAM;GACxC,IAAI,QAAQ,WAAW,KAAA,KAAa,SAAS,OAAO,UAAU,UAC5D,OAAO;IAAE,GAAI;IAAkB,QAAQ,OAAO;GAAO;GAEvD,OAAO;EACT;CACF;CAEA,WAAmB,SAAkB;EACnC,KAAK,gBAAgB;EACrB,KAAK,aAAa;CACpB;CAEA,UAAkB,YAAoC;EACpD,IAAI,KAAK,oBAAoB,YAC3B,KAAK,kBAAkB;EAEzB,KAAK,WAAW,KAAK;CACvB;CAEA,6BAA6C;EAC3C,MAAM,KAAK,qBAAqB;EAChC,MAAM,YAAoC;GACxC;GACA,MAAM;GACN,2BAAW,IAAI,KAAK;GACpB,QAAQ,EAAE,MAAM,UAAU;GAC1B,SAAS,CAAC;GACV,UAAU;IACR,gBAAgB,KAAK,iBAAiB;IACtC,sBAAsB,CAAC;IACvB,eAAe,CAAC;IAChB,OAAO,CAAC;IACR,cAAc;IACd,QAAQ,CAAC;GACX;EACF;EACA,KAAK,WAAW,CAAC,GAAG,KAAK,UAAU,SAAS;EAC5C,KAAK,aAAa;EAClB,OAAO;CACT;CAEA,oBAA4B,OAAe,OAAqB;EAC9D,IAAI,UAAU,OAAO;EAIrB,IAF6B,KAAK,SAAS,MAAM,MAAM,EAAE,OAAO,KAEzC,GAAG;GACxB,KAAK,OAAO,QACV,2FACA;IAAE;IAAO;GAAM,CACjB;GACA,KAAK,WAAW,KAAK,SAAS,QAAQ,MAAM,EAAE,OAAO,KAAK;EAC5D,OACE,KAAK,WAAW,KAAK,SAAS,KAAK,MAAM;GACvC,IAAI,EAAE,OAAO,OAAO,OAAO;GAC3B,MAAM,EAAE,cAAc,GAAG,GAAG,aAAa,EAAE;GAC3C,OAAO;IAAE,GAAG;IAAG,IAAI;IAAO;GAAS;EACrC,CAAC;EAGH,MAAM,gBAAgB,KAAK,wBAAwB,IAAI,KAAK;EAC5D,IAAI,kBAAkB,KAAA,GAAW;GAC/B,KAAK,wBAAwB,OAAO,KAAK;GACzC,IAAI,CAAC,KAAK,wBAAwB,IAAI,KAAK,GACzC,KAAK,wBAAwB,IAAI,OAAO,aAAa;EAEzD;EAEA,IAAI,KAAK,mBAAmB,IAAI,KAAK,GAAG;GACtC,KAAK,mBAAmB,OAAO,KAAK;GACpC,KAAK,mBAAmB,IAAI,KAAK;EACnC;EAEA,KAAK,aAAa;CACpB;CAEA,uBACE,WACA,QACQ;EACR,IAAI,UAAU;EACd,IAAI;EACJ,KAAK,WAAW,KAAK,SAAS,KAAK,YAAY;GAC7C,IAAI,QAAQ,OAAO,aAAa,QAAQ,SAAS,aAC/C,OAAO;GACT,UAAU;GACV,MAAM,YAAY;GAClB,MAAM,WAAW,OAAO,WACpB,KAAK,uBAAuB,UAAU,UAAU,OAAO,QAAQ,IAC/D,UAAU;GACd,eAAe,OAAO,UAAU,UAAU;GAC1C,MAAM,UACJ,OAAO,YAAY,KAAA,IACf,KAAK,oBACH,UAAU,SACV,OAAO,OACT,IACA,UAAU;GAChB,OAAO;IACL,GAAG;IACH;IACA,QAAQ;IACR;GACF;EACF,CAAC;EACD,IAAI,CAAC,SAAS,OAAO;EAErB,IAAI,oBAAoB;EAGxB,IADE,iBAAiB,KAAA,KAAa,aAAa,SAAS,aACrC,eAAe,SAAS,GAAG;GAC1C,MAAM,WAAW,WAAW;GAC5B,KAAK,oBAAoB,WAAW,QAAQ;GAC5C,oBAAoB;EACtB,OACE,KAAK,aAAa;EAEpB,IAAI,KAAK,oBAAoB,YAAY,GACvC,KAAK,wBAAwB,iBAAiB;EAEhD,KAAK,4BAA4B,iBAAiB;EAClD,OAAO;CACT;CAMA,oBACE,UACA,MACmC;EACnC,MAAM,2BAAW,IAAI,IAAiC;EACtD,KAAK,MAAM,QAAQ,UACjB,IACE,KAAK,SAAS,eACd,YAAY,QACZ,KAAK,WAAW,KAAA,GAEhB,SAAS,IAAI,KAAK,YAAY,IAAI;EAGtC,IAAI,SAAS,SAAS,GAAG,OAAO;EAEhC,IAAI,UAAU;EACd,MAAM,SAAS,KAAK,KAAK,SAAS;GAChC,IAAI,KAAK,SAAS,aAAa,OAAO;GACtC,IAAI,YAAY,QAAQ,KAAK,WAAW,KAAA,GAAW,OAAO;GAC1D,MAAM,QAAQ,SAAS,IAAI,KAAK,UAAU;GAC1C,IAAI,CAAC,OAAO,OAAO;GACnB,UAAU;GACV,OAAO;IACL,GAAG;IACH,QAAQ,MAAM;IACd,GAAI,MAAM,aAAa,KAAA,IAAY,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;IACnE,GAAI,MAAM,YAAY,KAAA,IAAY,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;GAClE;EACF,CAAC;EACD,OAAO,UAAW,SAA+C;CACnE;CAEA,uBACE,SACA,UACoC;EACpC,MAAM,cAAc,SAAS,uBACzB,CAAC,GAAG,QAAQ,sBAAsB,GAAG,SAAS,oBAAoB,IAClE,QAAQ;EACZ,MAAM,OAAO,SAAS,gBAClB,CAAC,GAAG,QAAQ,eAAe,GAAG,SAAS,aAAa,IACpD,QAAQ;EACZ,MAAM,QAAQ,SAAS,QACnB,CAAC,GAAG,QAAQ,OAAO,GAAG,SAAS,KAAK,IACpC,QAAQ;EACZ,OAAO;GACL,gBACE,SAAS,mBAAmB,KAAA,IACxB,SAAS,iBACT,QAAQ;GACd,sBAAsB;GACtB,eAAe;GACf;GACA,GAAI,QAAQ,eAAe,EAAE,cAAc,KAAK,IAAI,CAAC;GACrD,GAAI,SAAS,SAAS,EAAE,QAAQ,SAAS,OAAO,IAAI,CAAC;GACrD,QAAQ,SAAS,SACb;IAAE,GAAG,QAAQ;IAAQ,GAAG,SAAS;GAAO,IACxC,QAAQ;EACd;CACF;CAEA,YAAoB,YAA2B,OAAkB;EAC/D,QAAQ,MAAM,MAAd;GACE,KAAK;IACH,KAAK,gBAAgB,MAAM;IAC3B,KAAK,aAAa;IAClB;GAEF,KAAK;IACH,IAAI,MAAM,MAAM,WAAW,GAAG;IAC9B,IAAI;KACF,MAAM,QAAQ,KAAK,iBAAiB,CAAC;KACrC,MAAM,SAAS,UAAU,WACvB,OACA,MAAM,OACkB,MACH,KACvB;KACA,KAAK,gBAAgB,OAAO;KAC5B,KAAK,aAAa;IACpB,SAAS,OAAO;KACd,KAAK,OAAO,QAAQ,sCAAsC,KAAK;IACjE;IACA;GAEF,KAAK;IACH,KAAK,uBAAuB,MAAM,QAAQ;IAC1C;GAEF,KAAK;IACH,IAAI,CAAC,WAAW,YAAY,MAAM,UAAU,GAAG;KAC7C,MAAM,YAAY,KAAK,yBAAyB,MAAM,UAAU;KAChE,IAAI,cAAc,KAAA,GAAW;MAC3B,KAAK,wBAAwB,WAAW,KAAK;MAC7C;KACF;IACF;IACA,WAAW,OAAO,KAAK;IACvB;GAEF,SACE,WAAW,OAAO,KAAK;EAC3B;CACF;CAEA,wBACE,WACA,OACM;EACN,IAAI,UAAU;EACd,KAAK,WAAW,KAAK,SAAS,KAAK,YAAY;GAC7C,IAAI,QAAQ,OAAO,aAAa,QAAQ,SAAS,aAC/C,OAAO;GACT,MAAM,YAAY;GAClB,IAAI,kBAAkB;GACtB,MAAM,UAAU,UAAU,QAAQ,KAAK,SAAS;IAC9C,IAAI,KAAK,SAAS,eAAe,KAAK,eAAe,MAAM,YACzD,OAAO;IACT,kBAAkB;IAClB,OAAO;KACL,GAAG;KACH,QAAQ,aAAa,MAAM,WAAW,EAAE;KACxC,GAAI,MAAM,SAAS,SAAS,EAAE,SAAS,MAAM,IAAI,CAAC;KAClD,GAAI,MAAM,YACN,EAAE,wBAAwB,MAAM,UAAU,IAC1C,CAAC;IACP;GACF,CAAC;GACD,IAAI,CAAC,iBAAiB,OAAO;GAC7B,UAAU;GACV,OAAO;IAAE,GAAG;IAAW;GAAQ;EACjC,CAAC;EAED,IAAI,CAAC,SAAS;EACd,KAAK,aAAa;EAGlB,KAAK,8BAA8B,SAAS;CAC9C;CAEA,uBAA+B,aAAiC;EAC9D,IAAI;GACF,MAAM,aAAa,iBAAiB,aAAa,EAC/C,cAAc,KAAK,aACrB,CAAC;GACD,MAAM,YAA6B,CAAC;GACpC,KAAK,MAAM,WAAW,YACpB,IAAI;IACF,UAAU,KACR,sBAAsB,SAAS,WAAW,GAAG,oBAAoB,CACnE;GACF,SAAS,OAAO;IACd,KAAK,OAAO,QACV,iDACA,KACF;GACF;GAEF,KAAK,sBAAsB,SAAS;EACtC,SAAS,OAAO;GACd,KAAK,OAAO,QAAQ,6CAA6C,KAAK;EACxE;CACF;CAEA,gBAAwB,SAAuC;EAC7D,OAAO,sBACL,SACA,WAAW,GACX,oBACF;CACF;CAEA,UAAkB,UAAqC;EACrD,IAAI,CAAC,UAAU;GACb,IAAI,KAAK,SAAS,QAChB,KAAK,WAAW,CAAC;GAEnB;EACF;EACA,MAAM,MAAM,KAAK,SAAS,WAAW,YAAY,QAAQ,OAAO,QAAQ;EACxE,IAAI,QAAQ,IAAI;EAChB,KAAK,WAAW,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC;CAChD;CAEA,iBAAyB,QAAiC;EACxD,OAAO,QAAQ,SAAS,cAAc,QAAQ,SAAS;CACzD;CAEA,oBAA4B,QAAiC;EAC3D,IAAI,KAAK,iBAAiB,MAAM,GAAG,OAAO;EAC1C,OAAO,QAAQ,SAAS,qBAAqB,OAAO,WAAW;CACjE;CAEA,mBAA2B,UAAyB,SAAwB;EAC1E,KAAK,kBAAkB,UAAU,OAAO;CAC1C;CAEA,4BACE,WACA,UACA;EACA,IAAI,CAAC,KAAK,SAAS;EACnB,KAAK,wBAAwB,IAAI,WAAW,QAAQ;CACtD;CAEA,wBAAgC,WAAmB;EACjD,IAAI,CAAC,KAAK,SAAS;EACnB,MAAM,WAAW,KAAK,wBAAwB,IAAI,SAAS;EAC3D,IAAI,aAAa,KAAA,GAAW;EAC5B,MAAM,UAAU,KAAK,SAAS,MAAM,MAAM,EAAE,OAAO,SAAS;EAC5D,IAAI,CAAC,WAAW,QAAQ,SAAS,aAAa;EAC9C,IAAI,CAAC,KAAK,oBAAoB,QAAQ,MAAM,GAAG;EAC/C,KAAK,wBAAwB,OAAO,SAAS;EAC7C,KAAK,kBAAkB,UAAU,OAAO;CAC1C;CAEA,kBAA0B,UAAyB,SAAwB;EACzE,IAAI,CAAC,KAAK,WAAW,KAAK,mBAAmB,IAAI,QAAQ,EAAE,GAAG;EAC9D,KAAK,mBAAmB,IAAI,QAAQ,EAAE;EACtC,KAAU,QAAQ,OAAO;GAAE;GAAU;EAAQ,CAAC,CAAC,CAAC,OAAO,UAAU;GAC/D,KAAK,mBAAmB,OAAO,QAAQ,EAAE;GACzC,KAAK,OAAO,QAAQ,yCAAyC,KAAK;EACpE,CAAC;CACH;AACF"}
|
|
1
|
+
{"version":3,"file":"AgUiThreadRuntimeCore.js","names":[],"sources":["../../src/runtime/AgUiThreadRuntimeCore.ts"],"sourcesContent":["\"use client\";\n\nimport { generateId, fromThreadMessageLike } from \"@assistant-ui/core\";\nimport type {\n AddToolResultOptions,\n AppendMessage,\n AssistantRuntime,\n ChatModelRunOptions,\n ChatModelRunResult,\n MessageStatus,\n ThreadAssistantMessage,\n ThreadHistoryAdapter,\n ThreadMessage,\n ToolCallMessagePart,\n} from \"@assistant-ui/core\";\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport jsonpatch, { type Operation } from \"fast-json-patch\";\nimport type { Logger } from \"./logger\";\nimport type { AgUiEvent, AgUiInterrupt, AgUiResumeEntry } from \"./types\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport {\n AG_UI_METADATA_NAMESPACE,\n type AgUiCustomMetadata,\n RunAggregator,\n tryParseJSON,\n} from \"./adapter/run-aggregator\";\nimport {\n fromAgUiMessages,\n toAgUiMessages,\n toAgUiTools,\n} from \"./adapter/conversions\";\nimport { createAgUiSubscriber } from \"./adapter/subscriber\";\n\nconst optimisticPrefix = \"__optimistic__\";\nconst generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;\nconst isOptimisticId = (id: string) => id.startsWith(optimisticPrefix);\n\nconst symbolResumeShim = Symbol(\"agui-resume-shim\");\n\ntype RunConfig = NonNullable<AppendMessage[\"runConfig\"]>;\ntype ResumeStream = (\n options: ChatModelRunOptions,\n) => AsyncGenerator<ChatModelRunResult, void, unknown>;\ntype ResumeRunConfig = {\n parentId: string | null;\n sourceId: string | null;\n runConfig: RunConfig;\n stream?: ResumeStream;\n};\n\ntype CoreOptions = {\n agent: AbstractAgent;\n logger: Logger;\n showThinking: boolean;\n onError?: (error: Error) => void;\n onCancel?: () => void;\n history?: ThreadHistoryAdapter;\n notifyUpdate: () => void;\n};\n\nconst FALLBACK_USER_STATUS = { type: \"complete\", reason: \"unknown\" } as const;\n\nexport class AgUiThreadRuntimeCore {\n private agent: AbstractAgent;\n private logger: Logger;\n private showThinking: boolean;\n private onError: ((error: Error) => void) | undefined;\n private onCancel: (() => void) | undefined;\n private readonly notifyUpdate: () => void;\n\n private runtime: AssistantRuntime | undefined;\n private messages: ThreadMessage[] = [];\n private isRunningFlag = false;\n private abortController: AbortController | null = null;\n private stateSnapshot: ReadonlyJSONValue | undefined;\n private pendingError: Error | null = null;\n private history: ThreadHistoryAdapter | undefined;\n private lastRunConfig: RunConfig | undefined;\n private readonly assistantHistoryParents = new Map<string, string | null>();\n private readonly recordedHistoryIds = new Set<string>();\n private _isLoading = false;\n private _loadPromise: Promise<void> | undefined;\n private pendingResumeMessageId: string | null = null;\n\n constructor(options: CoreOptions) {\n this.agent = options.agent;\n this.logger = options.logger;\n this.showThinking = options.showThinking;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n this.history = options.history;\n this.notifyUpdate = options.notifyUpdate;\n this.installResumeShim();\n }\n\n updateOptions(options: Omit<CoreOptions, \"notifyUpdate\">) {\n this.agent = options.agent;\n this.logger = options.logger;\n this.showThinking = options.showThinking;\n this.onError = options.onError;\n this.onCancel = options.onCancel;\n this.history = options.history;\n this.installResumeShim();\n }\n\n attachRuntime(runtime: AssistantRuntime) {\n this.runtime = runtime;\n }\n\n detachRuntime() {\n this.runtime = undefined;\n }\n\n getMessages(): readonly ThreadMessage[] {\n return this.messages;\n }\n\n getState(): ReadonlyJSONValue | undefined {\n return this.stateSnapshot;\n }\n\n isRunning(): boolean {\n return this.isRunningFlag;\n }\n\n get isLoading(): boolean {\n return this._isLoading;\n }\n\n __internal_load(): Promise<void> {\n if (this._loadPromise) return this._loadPromise;\n\n const promise = this.history?.load() ?? Promise.resolve(null);\n\n this._isLoading = true;\n\n this._loadPromise = promise\n .then(async (repo) => {\n if (!repo) return;\n\n const messages = repo.messages.map((item) => item.message);\n this.applyExternalMessages(messages);\n\n if (repo.unstable_resume) {\n const parentId = repo.headId ?? messages.at(-1)?.id ?? null;\n const resumeStream = this.history?.resume?.bind(this.history);\n await this.startRun(\n parentId,\n this.lastRunConfig,\n undefined,\n resumeStream,\n );\n }\n })\n .catch((error) => {\n this.logger.error?.(\"[agui] failed to load history\", error);\n this.onError?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n })\n .finally(() => {\n this._isLoading = false;\n this.notifyUpdate();\n });\n\n this.notifyUpdate();\n return this._loadPromise;\n }\n\n async append(message: AppendMessage): Promise<void> {\n const startRun = message.startRun ?? message.role === \"user\";\n if (startRun) this.assertNoPendingInterrupts();\n if (message.sourceId) {\n this.messages = this.messages.filter(\n (entry) => entry.id !== message.sourceId,\n );\n }\n this.resetHead(message.parentId);\n\n const threadMessage = this.toThreadMessage(message);\n this.messages = [...this.messages, threadMessage];\n this.notifyUpdate();\n this.recordHistoryEntry(message.parentId ?? null, threadMessage);\n\n if (!startRun) return;\n await this.startRun(threadMessage.id, message.runConfig);\n }\n\n async edit(message: AppendMessage): Promise<void> {\n await this.append(message);\n }\n\n async reload(\n parentId: string | null,\n config: { runConfig?: RunConfig } = {},\n ): Promise<void> {\n this.assertNoPendingInterrupts();\n this.resetHead(parentId);\n this.notifyUpdate();\n await this.startRun(parentId, config.runConfig);\n }\n\n async cancel(): Promise<void> {\n if (!this.abortController) return;\n this.abortController.abort();\n }\n\n async resume(config: ResumeRunConfig): Promise<void> {\n this.assertNoPendingInterrupts();\n await this.startRun(\n config.parentId,\n config.runConfig ?? this.lastRunConfig,\n undefined,\n config.stream,\n );\n }\n\n async resumeInFlightRun(messages: readonly ThreadMessage[]): Promise<void> {\n // Without a resume stream startRun would re-run the agent from scratch.\n const resumeStream = this.history?.resume?.bind(this.history);\n if (!resumeStream) {\n const error = new Error(\n \"[agui] unstable_resume requires a ThreadHistoryAdapter with a resume() method; skipping resume after thread switch\",\n );\n this.logger.error?.(error.message);\n this.onError?.(error);\n return;\n }\n const parentId = messages.at(-1)?.id ?? null;\n try {\n await this.startRun(\n parentId,\n this.lastRunConfig,\n undefined,\n resumeStream,\n );\n } catch {\n // startRun already reported via onError; don't reject the switch.\n }\n }\n\n private assertNoPendingInterrupts(): void {\n if (!this.getPendingInterrupts()) return;\n throw new Error(\n \"[agui] cannot start a new run while interrupts are pending; resolve them with submitInterruptResponses()\",\n );\n }\n\n getPendingInterrupts(): {\n messageId: string;\n interrupts: readonly AgUiInterrupt[];\n } | null {\n const assistant = this.messages.findLast((m) => m.role === \"assistant\") as\n | ThreadAssistantMessage\n | undefined;\n if (\n !assistant ||\n assistant.status?.type !== \"requires-action\" ||\n assistant.status.reason !== \"interrupt\"\n ) {\n return null;\n }\n const stored = (\n assistant.metadata.custom[AG_UI_METADATA_NAMESPACE] as\n | AgUiCustomMetadata\n | undefined\n )?.interrupts;\n if (!stored?.length) return null;\n return { messageId: assistant.id, interrupts: stored };\n }\n\n async submitInterruptResponses(\n responses: readonly AgUiResumeEntry[],\n ): Promise<void> {\n const pending = this.getPendingInterrupts();\n if (!pending) {\n throw new Error(\n \"[agui] submitInterruptResponses: no pending interrupts on this thread\",\n );\n }\n\n const responsesById = new Map<string, AgUiResumeEntry>();\n for (const entry of responses) {\n if (!entry || typeof entry.interruptId !== \"string\") {\n throw new Error(\n \"[agui] submitInterruptResponses: every entry must have an interruptId\",\n );\n }\n if (entry.status !== \"resolved\" && entry.status !== \"cancelled\") {\n throw new Error(\n `[agui] submitInterruptResponses: invalid status \"${entry.status}\" for interrupt ${entry.interruptId}`,\n );\n }\n if (responsesById.has(entry.interruptId)) {\n throw new Error(\n `[agui] submitInterruptResponses: duplicate response for interrupt ${entry.interruptId}`,\n );\n }\n responsesById.set(entry.interruptId, entry);\n }\n\n const openIds = pending.interrupts.map((i) => i.id);\n const missing = openIds.filter((id) => !responsesById.has(id));\n if (missing.length > 0) {\n throw new Error(\n `[agui] submitInterruptResponses: missing responses for open interrupts: ${missing.join(\", \")}`,\n );\n }\n const known = new Set(openIds);\n const unknownIds = [...responsesById.keys()].filter((id) => !known.has(id));\n if (unknownIds.length > 0) {\n throw new Error(\n `[agui] submitInterruptResponses: unknown interrupt ids: ${unknownIds.join(\", \")}`,\n );\n }\n\n const now = Date.now();\n for (const interrupt of pending.interrupts) {\n if (!interrupt.expiresAt) continue;\n const expiry = new Date(interrupt.expiresAt).getTime();\n if (Number.isNaN(expiry)) {\n throw new Error(\n `[agui] submitInterruptResponses: interrupt ${interrupt.id} has malformed expiresAt \"${interrupt.expiresAt}\"`,\n );\n }\n if (expiry <= now) {\n throw new Error(\n `[agui] submitInterruptResponses: interrupt ${interrupt.id} expired at ${interrupt.expiresAt}`,\n );\n }\n }\n\n const resume: AgUiResumeEntry[] = openIds.map(\n (id) => responsesById.get(id)!,\n );\n\n if (this.isRunningFlag) {\n throw new Error(\n \"[agui] submitInterruptResponses: a run is already in progress\",\n );\n }\n\n this.clearPendingInterrupts(pending.messageId);\n await this.startRun(pending.messageId, this.lastRunConfig, resume);\n }\n\n private clearPendingInterrupts(messageId: string): void {\n let touched = false;\n this.messages = this.messages.map((message) => {\n if (message.id !== messageId || message.role !== \"assistant\")\n return message;\n const assistant = message as ThreadAssistantMessage;\n if (\n assistant.status?.type !== \"requires-action\" ||\n assistant.status.reason !== \"interrupt\"\n ) {\n return assistant;\n }\n touched = true;\n const aguiMeta = assistant.metadata.custom[AG_UI_METADATA_NAMESPACE] as\n | AgUiCustomMetadata\n | undefined;\n const { interrupts: _drop, ...restAgui } = aguiMeta ?? {};\n const newCustom = { ...assistant.metadata.custom };\n if (Object.keys(restAgui).length > 0) {\n newCustom[AG_UI_METADATA_NAMESPACE] = restAgui;\n } else {\n delete newCustom[AG_UI_METADATA_NAMESPACE];\n }\n return {\n ...assistant,\n status: { type: \"complete\" as const, reason: \"unknown\" as const },\n metadata: { ...assistant.metadata, custom: newCustom },\n };\n });\n if (touched) this.notifyUpdate();\n }\n\n findMessageIdForToolCall(toolCallId: string): string | undefined {\n let fallbackMessageId: string | undefined;\n for (let index = this.messages.length - 1; index >= 0; index--) {\n const message = this.messages[index];\n if (!message || message.role !== \"assistant\") continue;\n for (const part of message.content) {\n if (part.type !== \"tool-call\" || part.toolCallId !== toolCallId)\n continue;\n if (!(\"result\" in part) || part.result === undefined) {\n return message.id;\n }\n fallbackMessageId ??= message.id;\n }\n }\n return fallbackMessageId;\n }\n\n addToolResult(options: AddToolResultOptions): void {\n let updated = false;\n this.messages = this.messages.map((message) => {\n if (message.id !== options.messageId || message.role !== \"assistant\")\n return message;\n const assistant = message as ThreadAssistantMessage;\n let matchedToolCall = false;\n const content = assistant.content.map((part) => {\n if (part.type !== \"tool-call\" || part.toolCallId !== options.toolCallId)\n return part;\n matchedToolCall = true;\n return {\n ...part,\n result: options.result,\n artifact: options.artifact,\n isError: options.isError,\n };\n });\n if (!matchedToolCall) return message;\n updated = true;\n return { ...assistant, content };\n });\n\n if (!updated) return;\n this.notifyUpdate();\n this.maybeResumeAfterToolResults(options.messageId);\n }\n\n // The continuation fires whether the frontend result lands before\n // RUN_FINISHED (the status flips to requires-action only later, while the\n // run is still draining) or after it.\n private maybeResumeAfterToolResults(messageId: string): void {\n if (!this.maybeCompleteAfterToolResults(messageId)) return;\n\n if (this.isRunningFlag) {\n // A run is still draining (RUN_FINISHED arrived but the stream has not\n // closed). Defer until startRun's tail so we never start two runs.\n this.pendingResumeMessageId = messageId;\n return;\n }\n this.startResumeRun(messageId);\n }\n\n private maybeCompleteAfterToolResults(messageId: string): boolean {\n const message = this.messages.find((m) => m.id === messageId);\n if (!message || message.role !== \"assistant\") return false;\n const assistant = message as ThreadAssistantMessage;\n if (\n assistant.status?.type !== \"requires-action\" ||\n assistant.status.reason !== \"tool-calls\"\n ) {\n return false;\n }\n const allResolved = assistant.content.every(\n (part) =>\n part.type !== \"tool-call\" ||\n (\"result\" in part && part.result !== undefined),\n );\n if (!allResolved) return false;\n\n this.messages = this.messages.map((m) =>\n m.id === messageId && m.role === \"assistant\"\n ? {\n ...(m as ThreadAssistantMessage),\n status: { type: \"complete\" as const, reason: \"unknown\" as const },\n }\n : m,\n );\n this.notifyUpdate();\n this.persistAssistantHistory(messageId);\n return true;\n }\n\n private startResumeRun(messageId: string): void {\n void this.startRun(messageId, this.lastRunConfig).catch((error) => {\n this.onError?.(error instanceof Error ? error : new Error(String(error)));\n });\n }\n\n applyExternalMessages(messages: readonly ThreadMessage[]): void {\n this.assistantHistoryParents.clear();\n this.messages = [...messages];\n this.recordedHistoryIds.clear();\n for (const message of this.messages) {\n this.recordedHistoryIds.add(message.id);\n }\n this.notifyUpdate();\n }\n\n loadExternalState(state: ReadonlyJSONValue): void {\n this.stateSnapshot = state;\n this.notifyUpdate();\n }\n\n private async startRun(\n parentId: string | null,\n runConfig?: RunConfig,\n resume?: AgUiResumeEntry[],\n resumeStream?: ResumeStream,\n ): Promise<void> {\n const normalizedRunConfig = runConfig ?? {};\n this.lastRunConfig = normalizedRunConfig;\n this.resetHead(parentId);\n const historicalMessages = [...this.messages];\n\n this.pendingError = null;\n const assistantParentId = parentId ?? this.messages.at(-1)?.id ?? null;\n let assistantMessageId: string | undefined;\n const ensureAssistant = () => {\n if (assistantMessageId) return assistantMessageId;\n const created = this.insertAssistantPlaceholder();\n assistantMessageId = created;\n this.markPendingAssistantHistory(created, assistantParentId ?? null);\n return created;\n };\n\n const applyUpdate = (update: ChatModelRunResult) => {\n const resolved = this.updateAssistantMessage(ensureAssistant(), update);\n if (resolved !== assistantMessageId) {\n assistantMessageId = resolved;\n }\n };\n\n const aggregator = new RunAggregator({\n showThinking: this.showThinking,\n logger: this.logger,\n emit: applyUpdate,\n onServerMessageId: (serverId) => {\n const placeholder = ensureAssistant();\n if (placeholder === serverId) return;\n this.reassignAssistantId(placeholder, serverId);\n assistantMessageId = serverId;\n },\n });\n const dispatch = (event: AgUiEvent) => this.handleEvent(aggregator, event);\n\n const abortController = new AbortController();\n const abortSignal = abortController.signal;\n this.abortController = abortController;\n\n let cancelRun = () => dispatch({ type: \"RUN_CANCELLED\" });\n abortSignal.addEventListener(\n \"abort\",\n () => {\n cancelRun();\n this.finishRun(abortController);\n this.onCancel?.();\n },\n { once: true },\n );\n\n this.setRunning(true);\n\n try {\n if (resumeStream) {\n // Cancel flips only the status; an aggregator RUN_CANCELLED would emit an empty snapshot and wipe the replayed content.\n cancelRun = () =>\n applyUpdate({ status: { type: \"incomplete\", reason: \"cancelled\" } });\n await this.consumeResumeStream(resumeStream, {\n runConfig: normalizedRunConfig,\n threadId: this.agent.threadId || \"main\",\n parentId: assistantParentId,\n historicalMessages,\n abortSignal,\n ensureAssistant,\n applyUpdate,\n getAssistantMessageId: () => assistantMessageId,\n });\n } else {\n const runId = generateId();\n aggregator.handle({ type: \"RUN_STARTED\", runId });\n const input = this.buildRunInput(\n runId,\n normalizedRunConfig,\n historicalMessages,\n resume,\n );\n const subscriber = createAgUiSubscriber({\n dispatch,\n runId,\n logger: this.logger,\n onRunFailed: (error) => {\n this.pendingError = error;\n this.onError?.(error);\n },\n });\n try {\n (this.agent as any).messages = input.messages;\n (this.agent as any).threadId = input.threadId;\n (this.agent as any).state = input.state ?? null;\n } catch {\n // ignore\n }\n await (this.agent as any).runAgent(input, subscriber, {\n signal: abortSignal,\n });\n }\n } catch (error) {\n if (!abortSignal.aborted) {\n const err = error instanceof Error ? error : new Error(String(error));\n dispatch({ type: \"RUN_ERROR\", message: err.message });\n this.onError?.(err);\n this.pendingError = this.pendingError ?? err;\n }\n } finally {\n this.finishRun(abortController);\n }\n\n if (this.pendingError) {\n const err = this.pendingError;\n this.pendingError = null;\n this.pendingResumeMessageId = null;\n throw err;\n }\n\n // A tool result that landed before the run settled deferred its\n // continuation here so a second run never overlaps the first.\n if (this.pendingResumeMessageId !== null) {\n const resumeMessageId = this.pendingResumeMessageId;\n this.pendingResumeMessageId = null;\n if (!abortSignal.aborted) {\n this.startResumeRun(resumeMessageId);\n }\n }\n }\n\n // Replays a persisted run's snapshots into the existing assistant message, bypassing agent.runAgent so it is not re-invoked.\n private async consumeResumeStream(\n stream: ResumeStream,\n ctx: {\n runConfig: RunConfig;\n threadId: string;\n parentId: string | null;\n historicalMessages: readonly ThreadMessage[];\n abortSignal: AbortSignal;\n ensureAssistant: () => string;\n applyUpdate: (update: ChatModelRunResult) => void;\n getAssistantMessageId: () => string | undefined;\n },\n ): Promise<void> {\n const assistantId = ctx.ensureAssistant();\n const currentId = () => ctx.getAssistantMessageId() ?? assistantId;\n const options: ChatModelRunOptions = {\n messages: ctx.historicalMessages,\n runConfig: ctx.runConfig,\n abortSignal: ctx.abortSignal,\n context: this.runtime?.thread.getModelContext() ?? {},\n unstable_assistantMessageId: assistantId,\n unstable_threadId: ctx.threadId,\n unstable_parentId: ctx.parentId,\n unstable_getMessage: () => {\n const message = this.messages.find((m) => m.id === currentId());\n if (!message) {\n throw new Error(\n \"[agui] resume stream requested the assistant message before it existed\",\n );\n }\n return message;\n },\n };\n\n try {\n for await (const result of stream(options)) {\n if (ctx.abortSignal.aborted) return;\n ctx.applyUpdate(result);\n }\n } catch (error) {\n if (ctx.abortSignal.aborted) return;\n const err = error instanceof Error ? error : new Error(String(error));\n ctx.applyUpdate({\n status: { type: \"incomplete\", reason: \"error\", error: err.message },\n });\n this.onError?.(err);\n this.pendingError = this.pendingError ?? err;\n return;\n }\n\n if (ctx.abortSignal.aborted) return;\n const current = this.messages.find((m) => m.id === currentId());\n if (!current || current.status?.type === \"running\") {\n ctx.applyUpdate({ status: { type: \"complete\", reason: \"unknown\" } });\n }\n }\n\n private buildRunInput(\n runId: string,\n runConfig: RunConfig | undefined,\n historyMessages: readonly ThreadMessage[] | undefined,\n resume?: AgUiResumeEntry[],\n ) {\n const threadId = this.agent.threadId || \"main\";\n const messages = toAgUiMessages(historyMessages ?? this.messages);\n const context = this.runtime?.thread.getModelContext();\n return {\n threadId,\n runId,\n state: this.stateSnapshot ?? null,\n messages,\n tools: toAgUiTools(context?.tools),\n context: context?.system\n ? [{ description: \"system\", value: context.system }]\n : [],\n forwardedProps: {\n ...(context?.callSettings ?? {}),\n ...(context?.config ?? {}),\n ...(runConfig?.custom ? { runConfig: runConfig.custom } : {}),\n },\n ...(resume !== undefined ? { resume } : {}),\n };\n }\n\n private installResumeShim(): void {\n const agent = this.agent as any;\n if (agent[symbolResumeShim]) return;\n agent[symbolResumeShim] = true;\n const onInstance = Object.hasOwn(agent, \"prepareRunAgentInput\");\n const original = onInstance\n ? agent.prepareRunAgentInput\n : Object.getPrototypeOf(agent)?.prepareRunAgentInput;\n if (typeof original !== \"function\") return;\n agent.prepareRunAgentInput = function (\n this: unknown,\n params: { resume?: unknown } | undefined,\n ) {\n const input = original.call(this, params);\n if (params?.resume !== undefined && input && typeof input === \"object\") {\n return { ...(input as object), resume: params.resume };\n }\n return input;\n };\n }\n\n private setRunning(running: boolean) {\n this.isRunningFlag = running;\n this.notifyUpdate();\n }\n\n private finishRun(controller: AbortController | null) {\n if (this.abortController === controller) {\n this.abortController = null;\n }\n this.setRunning(false);\n }\n\n private insertAssistantPlaceholder(): string {\n const id = generateOptimisticId();\n const assistant: ThreadAssistantMessage = {\n id,\n role: \"assistant\",\n createdAt: new Date(),\n status: { type: \"running\" },\n content: [],\n metadata: {\n unstable_state: this.stateSnapshot ?? null,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n isOptimistic: true,\n custom: {},\n },\n };\n this.messages = [...this.messages, assistant];\n this.notifyUpdate();\n return id;\n }\n\n private reassignAssistantId(oldId: string, newId: string): void {\n if (oldId === newId) return;\n\n const collidesWithExisting = this.messages.some((m) => m.id === newId);\n\n if (collidesWithExisting) {\n this.logger.debug?.(\n \"[agui] reassignAssistantId: server id already present in messages, dropping placeholder\",\n { oldId, newId },\n );\n this.messages = this.messages.filter((m) => m.id !== oldId);\n } else {\n this.messages = this.messages.map((m) => {\n if (m.id !== oldId) return m;\n const { isOptimistic: _, ...metadata } = m.metadata;\n return { ...m, id: newId, metadata } as ThreadMessage;\n });\n }\n\n const pendingParent = this.assistantHistoryParents.get(oldId);\n if (pendingParent !== undefined) {\n this.assistantHistoryParents.delete(oldId);\n if (!this.assistantHistoryParents.has(newId)) {\n this.assistantHistoryParents.set(newId, pendingParent);\n }\n }\n\n if (this.recordedHistoryIds.has(oldId)) {\n this.recordedHistoryIds.delete(oldId);\n this.recordedHistoryIds.add(newId);\n }\n\n this.notifyUpdate();\n }\n\n private updateAssistantMessage(\n messageId: string,\n update: ChatModelRunResult,\n ): string {\n let touched = false;\n let latestStatus: MessageStatus | undefined;\n this.messages = this.messages.map((message) => {\n if (message.id !== messageId || message.role !== \"assistant\")\n return message;\n touched = true;\n const assistant = message as ThreadAssistantMessage;\n const metadata = update.metadata\n ? this.mergeAssistantMetadata(assistant.metadata, update.metadata)\n : assistant.metadata;\n latestStatus = update.status ?? assistant.status;\n const content =\n update.content !== undefined\n ? this.preserveToolResults(\n assistant.content,\n update.content as ThreadAssistantMessage[\"content\"],\n )\n : assistant.content;\n return {\n ...assistant,\n content,\n status: latestStatus,\n metadata,\n };\n });\n if (!touched) return messageId;\n\n let resolvedMessageId = messageId;\n const isSettled =\n latestStatus !== undefined && latestStatus.type !== \"running\";\n if (isSettled && isOptimisticId(messageId)) {\n const stableId = generateId();\n this.reassignAssistantId(messageId, stableId);\n resolvedMessageId = stableId;\n } else {\n this.notifyUpdate();\n }\n if (this.isPersistableStatus(latestStatus)) {\n this.persistAssistantHistory(resolvedMessageId);\n }\n this.maybeResumeAfterToolResults(resolvedMessageId);\n return resolvedMessageId;\n }\n\n // The RunAggregator rebuilds the assistant content from stream events only,\n // so a fresh snapshot omits results injected via addToolResult (frontend tool\n // execution). Carry those results forward so the aggregator never clobbers\n // them. Results are only ever added in this flow, so preserving is safe.\n private preserveToolResults(\n previous: ThreadAssistantMessage[\"content\"],\n next: ThreadAssistantMessage[\"content\"],\n ): ThreadAssistantMessage[\"content\"] {\n const resolved = new Map<string, ToolCallMessagePart>();\n for (const part of previous) {\n if (\n part.type === \"tool-call\" &&\n \"result\" in part &&\n part.result !== undefined\n ) {\n resolved.set(part.toolCallId, part);\n }\n }\n if (resolved.size === 0) return next;\n\n let changed = false;\n const merged = next.map((part) => {\n if (part.type !== \"tool-call\") return part;\n if (\"result\" in part && part.result !== undefined) return part;\n const prior = resolved.get(part.toolCallId);\n if (!prior) return part;\n changed = true;\n return {\n ...part,\n result: prior.result,\n ...(prior.artifact !== undefined ? { artifact: prior.artifact } : {}),\n ...(prior.isError !== undefined ? { isError: prior.isError } : {}),\n };\n });\n return changed ? (merged as ThreadAssistantMessage[\"content\"]) : next;\n }\n\n private mergeAssistantMetadata(\n current: ThreadAssistantMessage[\"metadata\"],\n incoming: NonNullable<ChatModelRunResult[\"metadata\"]>,\n ): ThreadAssistantMessage[\"metadata\"] {\n const annotations = incoming.unstable_annotations\n ? [...current.unstable_annotations, ...incoming.unstable_annotations]\n : current.unstable_annotations;\n const data = incoming.unstable_data\n ? [...current.unstable_data, ...incoming.unstable_data]\n : current.unstable_data;\n const steps = incoming.steps\n ? [...current.steps, ...incoming.steps]\n : current.steps;\n return {\n unstable_state:\n incoming.unstable_state !== undefined\n ? incoming.unstable_state\n : current.unstable_state,\n unstable_annotations: annotations,\n unstable_data: data,\n steps,\n ...(current.isOptimistic ? { isOptimistic: true } : {}),\n ...(incoming.timing ? { timing: incoming.timing } : {}),\n custom: incoming.custom\n ? { ...current.custom, ...incoming.custom }\n : current.custom,\n };\n }\n\n private handleEvent(aggregator: RunAggregator, event: AgUiEvent) {\n switch (event.type) {\n case \"STATE_SNAPSHOT\": {\n this.stateSnapshot = event.snapshot as ReadonlyJSONValue;\n this.notifyUpdate();\n return;\n }\n case \"STATE_DELTA\": {\n if (event.delta.length === 0) return;\n try {\n const state = this.stateSnapshot ?? {};\n const result = jsonpatch.applyPatch(\n state,\n event.delta as Operation[],\n /* validateOperation */ true,\n /* mutateDocument */ false,\n );\n this.stateSnapshot = result.newDocument as ReadonlyJSONValue;\n this.notifyUpdate();\n } catch (error) {\n this.logger.error?.(\"[agui] failed to apply state delta\", error);\n }\n return;\n }\n case \"MESSAGES_SNAPSHOT\": {\n this.importMessagesSnapshot(event.messages);\n return;\n }\n case \"TOOL_CALL_RESULT\": {\n if (!aggregator.hasToolCall(event.toolCallId)) {\n const messageId = this.findMessageIdForToolCall(event.toolCallId);\n if (messageId !== undefined) {\n this.applyCrossRunToolResult(messageId, event);\n return;\n }\n }\n aggregator.handle(event);\n return;\n }\n default:\n aggregator.handle(event);\n }\n }\n\n private applyCrossRunToolResult(\n messageId: string,\n event: Extract<AgUiEvent, { type: \"TOOL_CALL_RESULT\" }>,\n ): void {\n let updated = false;\n this.messages = this.messages.map((message) => {\n if (message.id !== messageId || message.role !== \"assistant\")\n return message;\n const assistant = message as ThreadAssistantMessage;\n let matchedToolCall = false;\n const content = assistant.content.map((part) => {\n if (part.type !== \"tool-call\" || part.toolCallId !== event.toolCallId)\n return part;\n matchedToolCall = true;\n return {\n ...part,\n result: tryParseJSON(event.content ?? \"\") as ReadonlyJSONValue,\n ...(event.role === \"tool\" ? { isError: false } : {}),\n ...(event.messageId\n ? { unstable_toolMessageId: event.messageId }\n : {}),\n };\n });\n if (!matchedToolCall) return message;\n updated = true;\n return { ...assistant, content };\n });\n\n if (!updated) return;\n this.notifyUpdate();\n // Not maybeResumeAfterToolResults: the delivering run is already in\n // flight, and a resume from the owner would reset the head past it.\n this.maybeCompleteAfterToolResults(messageId);\n }\n\n private importMessagesSnapshot(rawMessages: readonly unknown[]) {\n try {\n const normalized = fromAgUiMessages(rawMessages, {\n showThinking: this.showThinking,\n });\n const converted: ThreadMessage[] = [];\n for (const message of normalized) {\n try {\n converted.push(\n fromThreadMessageLike(message, generateId(), FALLBACK_USER_STATUS),\n );\n } catch (error) {\n this.logger.error?.(\n \"[agui] failed to import message from snapshot\",\n error,\n );\n }\n }\n this.applyExternalMessages(converted);\n } catch (error) {\n this.logger.error?.(\"[agui] failed to import messages snapshot\", error);\n }\n }\n\n private toThreadMessage(message: AppendMessage): ThreadMessage {\n return fromThreadMessageLike(\n message as any,\n generateId(),\n FALLBACK_USER_STATUS,\n );\n }\n\n private resetHead(parentId: string | null | undefined) {\n if (!parentId) {\n if (this.messages.length) {\n this.messages = [];\n }\n return;\n }\n const idx = this.messages.findIndex((message) => message.id === parentId);\n if (idx === -1) return;\n this.messages = this.messages.slice(0, idx + 1);\n }\n\n private isTerminalStatus(status?: MessageStatus): boolean {\n return status?.type === \"complete\" || status?.type === \"incomplete\";\n }\n\n private isPersistableStatus(status?: MessageStatus): boolean {\n if (this.isTerminalStatus(status)) return true;\n return status?.type === \"requires-action\" && status.reason === \"interrupt\";\n }\n\n private recordHistoryEntry(parentId: string | null, message: ThreadMessage) {\n this.appendHistoryItem(parentId, message);\n }\n\n private markPendingAssistantHistory(\n messageId: string,\n parentId: string | null,\n ) {\n if (!this.history) return;\n this.assistantHistoryParents.set(messageId, parentId);\n }\n\n private persistAssistantHistory(messageId: string) {\n if (!this.history) return;\n const parentId = this.assistantHistoryParents.get(messageId);\n if (parentId === undefined) return;\n const message = this.messages.find((m) => m.id === messageId);\n if (!message || message.role !== \"assistant\") return;\n if (!this.isPersistableStatus(message.status)) return;\n this.assistantHistoryParents.delete(messageId);\n this.appendHistoryItem(parentId, message);\n }\n\n private appendHistoryItem(parentId: string | null, message: ThreadMessage) {\n if (!this.history || this.recordedHistoryIds.has(message.id)) return;\n this.recordedHistoryIds.add(message.id);\n void this.history.append({ parentId, message }).catch((error) => {\n this.recordedHistoryIds.delete(message.id);\n this.logger.error?.(\"[agui] failed to append history entry\", error);\n });\n }\n}\n"],"mappings":";;;;;;;AAiCA,MAAM,mBAAmB;AACzB,MAAM,6BAA6B,GAAG,mBAAmB,WAAW;AACpE,MAAM,kBAAkB,OAAe,GAAG,WAAW,gBAAgB;AAErE,MAAM,mBAAmB,OAAO,kBAAkB;AAuBlD,MAAM,uBAAuB;CAAE,MAAM;CAAY,QAAQ;AAAU;AAEnE,IAAa,wBAAb,MAAmC;CACjC;CACA;CACA;CACA;CACA;CACA;CAEA;CACA,WAAoC,CAAC;CACrC,gBAAwB;CACxB,kBAAkD;CAClD;CACA,eAAqC;CACrC;CACA;CACA,0CAA2C,IAAI,IAA2B;CAC1E,qCAAsC,IAAI,IAAY;CACtD,aAAqB;CACrB;CACA,yBAAgD;CAEhD,YAAY,SAAsB;EAChC,KAAK,QAAQ,QAAQ;EACrB,KAAK,SAAS,QAAQ;EACtB,KAAK,eAAe,QAAQ;EAC5B,KAAK,UAAU,QAAQ;EACvB,KAAK,WAAW,QAAQ;EACxB,KAAK,UAAU,QAAQ;EACvB,KAAK,eAAe,QAAQ;EAC5B,KAAK,kBAAkB;CACzB;CAEA,cAAc,SAA4C;EACxD,KAAK,QAAQ,QAAQ;EACrB,KAAK,SAAS,QAAQ;EACtB,KAAK,eAAe,QAAQ;EAC5B,KAAK,UAAU,QAAQ;EACvB,KAAK,WAAW,QAAQ;EACxB,KAAK,UAAU,QAAQ;EACvB,KAAK,kBAAkB;CACzB;CAEA,cAAc,SAA2B;EACvC,KAAK,UAAU;CACjB;CAEA,gBAAgB;EACd,KAAK,UAAU,KAAA;CACjB;CAEA,cAAwC;EACtC,OAAO,KAAK;CACd;CAEA,WAA0C;EACxC,OAAO,KAAK;CACd;CAEA,YAAqB;EACnB,OAAO,KAAK;CACd;CAEA,IAAI,YAAqB;EACvB,OAAO,KAAK;CACd;CAEA,kBAAiC;EAC/B,IAAI,KAAK,cAAc,OAAO,KAAK;EAEnC,MAAM,UAAU,KAAK,SAAS,KAAK,KAAK,QAAQ,QAAQ,IAAI;EAE5D,KAAK,aAAa;EAElB,KAAK,eAAe,QACjB,KAAK,OAAO,SAAS;GACpB,IAAI,CAAC,MAAM;GAEX,MAAM,WAAW,KAAK,SAAS,KAAK,SAAS,KAAK,OAAO;GACzD,KAAK,sBAAsB,QAAQ;GAEnC,IAAI,KAAK,iBAAiB;IACxB,MAAM,WAAW,KAAK,UAAU,SAAS,GAAG,EAAE,CAAC,EAAE,MAAM;IACvD,MAAM,eAAe,KAAK,SAAS,QAAQ,KAAK,KAAK,OAAO;IAC5D,MAAM,KAAK,SACT,UACA,KAAK,eACL,KAAA,GACA,YACF;GACF;EACF,CAAC,CAAC,CACD,OAAO,UAAU;GAChB,KAAK,OAAO,QAAQ,iCAAiC,KAAK;GAC1D,KAAK,UACH,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAC1D;EACF,CAAC,CAAC,CACD,cAAc;GACb,KAAK,aAAa;GAClB,KAAK,aAAa;EACpB,CAAC;EAEH,KAAK,aAAa;EAClB,OAAO,KAAK;CACd;CAEA,MAAM,OAAO,SAAuC;EAClD,MAAM,WAAW,QAAQ,YAAY,QAAQ,SAAS;EACtD,IAAI,UAAU,KAAK,0BAA0B;EAC7C,IAAI,QAAQ,UACV,KAAK,WAAW,KAAK,SAAS,QAC3B,UAAU,MAAM,OAAO,QAAQ,QAClC;EAEF,KAAK,UAAU,QAAQ,QAAQ;EAE/B,MAAM,gBAAgB,KAAK,gBAAgB,OAAO;EAClD,KAAK,WAAW,CAAC,GAAG,KAAK,UAAU,aAAa;EAChD,KAAK,aAAa;EAClB,KAAK,mBAAmB,QAAQ,YAAY,MAAM,aAAa;EAE/D,IAAI,CAAC,UAAU;EACf,MAAM,KAAK,SAAS,cAAc,IAAI,QAAQ,SAAS;CACzD;CAEA,MAAM,KAAK,SAAuC;EAChD,MAAM,KAAK,OAAO,OAAO;CAC3B;CAEA,MAAM,OACJ,UACA,SAAoC,CAAC,GACtB;EACf,KAAK,0BAA0B;EAC/B,KAAK,UAAU,QAAQ;EACvB,KAAK,aAAa;EAClB,MAAM,KAAK,SAAS,UAAU,OAAO,SAAS;CAChD;CAEA,MAAM,SAAwB;EAC5B,IAAI,CAAC,KAAK,iBAAiB;EAC3B,KAAK,gBAAgB,MAAM;CAC7B;CAEA,MAAM,OAAO,QAAwC;EACnD,KAAK,0BAA0B;EAC/B,MAAM,KAAK,SACT,OAAO,UACP,OAAO,aAAa,KAAK,eACzB,KAAA,GACA,OAAO,MACT;CACF;CAEA,MAAM,kBAAkB,UAAmD;EAEzE,MAAM,eAAe,KAAK,SAAS,QAAQ,KAAK,KAAK,OAAO;EAC5D,IAAI,CAAC,cAAc;GACjB,MAAM,wBAAQ,IAAI,MAChB,oHACF;GACA,KAAK,OAAO,QAAQ,MAAM,OAAO;GACjC,KAAK,UAAU,KAAK;GACpB;EACF;EACA,MAAM,WAAW,SAAS,GAAG,EAAE,CAAC,EAAE,MAAM;EACxC,IAAI;GACF,MAAM,KAAK,SACT,UACA,KAAK,eACL,KAAA,GACA,YACF;EACF,QAAQ,CAER;CACF;CAEA,4BAA0C;EACxC,IAAI,CAAC,KAAK,qBAAqB,GAAG;EAClC,MAAM,IAAI,MACR,0GACF;CACF;CAEA,uBAGS;EACP,MAAM,YAAY,KAAK,SAAS,UAAU,MAAM,EAAE,SAAS,WAAW;EAGtE,IACE,CAAC,aACD,UAAU,QAAQ,SAAS,qBAC3B,UAAU,OAAO,WAAW,aAE5B,OAAO;EAET,MAAM,SACJ,UAAU,SAAS,OAAO,yBAAyB,EAGlD;EACH,IAAI,CAAC,QAAQ,QAAQ,OAAO;EAC5B,OAAO;GAAE,WAAW,UAAU;GAAI,YAAY;EAAO;CACvD;CAEA,MAAM,yBACJ,WACe;EACf,MAAM,UAAU,KAAK,qBAAqB;EAC1C,IAAI,CAAC,SACH,MAAM,IAAI,MACR,uEACF;EAGF,MAAM,gCAAgB,IAAI,IAA6B;EACvD,KAAK,MAAM,SAAS,WAAW;GAC7B,IAAI,CAAC,SAAS,OAAO,MAAM,gBAAgB,UACzC,MAAM,IAAI,MACR,uEACF;GAEF,IAAI,MAAM,WAAW,cAAc,MAAM,WAAW,aAClD,MAAM,IAAI,MACR,oDAAoD,MAAM,OAAO,kBAAkB,MAAM,aAC3F;GAEF,IAAI,cAAc,IAAI,MAAM,WAAW,GACrC,MAAM,IAAI,MACR,qEAAqE,MAAM,aAC7E;GAEF,cAAc,IAAI,MAAM,aAAa,KAAK;EAC5C;EAEA,MAAM,UAAU,QAAQ,WAAW,KAAK,MAAM,EAAE,EAAE;EAClD,MAAM,UAAU,QAAQ,QAAQ,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC;EAC7D,IAAI,QAAQ,SAAS,GACnB,MAAM,IAAI,MACR,2EAA2E,QAAQ,KAAK,IAAI,GAC9F;EAEF,MAAM,QAAQ,IAAI,IAAI,OAAO;EAC7B,MAAM,aAAa,CAAC,GAAG,cAAc,KAAK,CAAC,CAAC,CAAC,QAAQ,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;EAC1E,IAAI,WAAW,SAAS,GACtB,MAAM,IAAI,MACR,2DAA2D,WAAW,KAAK,IAAI,GACjF;EAGF,MAAM,MAAM,KAAK,IAAI;EACrB,KAAK,MAAM,aAAa,QAAQ,YAAY;GAC1C,IAAI,CAAC,UAAU,WAAW;GAC1B,MAAM,SAAS,IAAI,KAAK,UAAU,SAAS,CAAC,CAAC,QAAQ;GACrD,IAAI,OAAO,MAAM,MAAM,GACrB,MAAM,IAAI,MACR,8CAA8C,UAAU,GAAG,4BAA4B,UAAU,UAAU,EAC7G;GAEF,IAAI,UAAU,KACZ,MAAM,IAAI,MACR,8CAA8C,UAAU,GAAG,cAAc,UAAU,WACrF;EAEJ;EAEA,MAAM,SAA4B,QAAQ,KACvC,OAAO,cAAc,IAAI,EAAE,CAC9B;EAEA,IAAI,KAAK,eACP,MAAM,IAAI,MACR,+DACF;EAGF,KAAK,uBAAuB,QAAQ,SAAS;EAC7C,MAAM,KAAK,SAAS,QAAQ,WAAW,KAAK,eAAe,MAAM;CACnE;CAEA,uBAA+B,WAAyB;EACtD,IAAI,UAAU;EACd,KAAK,WAAW,KAAK,SAAS,KAAK,YAAY;GAC7C,IAAI,QAAQ,OAAO,aAAa,QAAQ,SAAS,aAC/C,OAAO;GACT,MAAM,YAAY;GAClB,IACE,UAAU,QAAQ,SAAS,qBAC3B,UAAU,OAAO,WAAW,aAE5B,OAAO;GAET,UAAU;GAIV,MAAM,EAAE,YAAY,OAAO,GAAG,aAHb,UAAU,SAAS,OAAA,WAGmB,CAAC;GACxD,MAAM,YAAY,EAAE,GAAG,UAAU,SAAS,OAAO;GACjD,IAAI,OAAO,KAAK,QAAQ,CAAC,CAAC,SAAS,GACjC,UAAU,4BAA4B;QAEtC,OAAO,UAAU;GAEnB,OAAO;IACL,GAAG;IACH,QAAQ;KAAE,MAAM;KAAqB,QAAQ;IAAmB;IAChE,UAAU;KAAE,GAAG,UAAU;KAAU,QAAQ;IAAU;GACvD;EACF,CAAC;EACD,IAAI,SAAS,KAAK,aAAa;CACjC;CAEA,yBAAyB,YAAwC;EAC/D,IAAI;EACJ,KAAK,IAAI,QAAQ,KAAK,SAAS,SAAS,GAAG,SAAS,GAAG,SAAS;GAC9D,MAAM,UAAU,KAAK,SAAS;GAC9B,IAAI,CAAC,WAAW,QAAQ,SAAS,aAAa;GAC9C,KAAK,MAAM,QAAQ,QAAQ,SAAS;IAClC,IAAI,KAAK,SAAS,eAAe,KAAK,eAAe,YACnD;IACF,IAAI,EAAE,YAAY,SAAS,KAAK,WAAW,KAAA,GACzC,OAAO,QAAQ;IAEjB,sBAAsB,QAAQ;GAChC;EACF;EACA,OAAO;CACT;CAEA,cAAc,SAAqC;EACjD,IAAI,UAAU;EACd,KAAK,WAAW,KAAK,SAAS,KAAK,YAAY;GAC7C,IAAI,QAAQ,OAAO,QAAQ,aAAa,QAAQ,SAAS,aACvD,OAAO;GACT,MAAM,YAAY;GAClB,IAAI,kBAAkB;GACtB,MAAM,UAAU,UAAU,QAAQ,KAAK,SAAS;IAC9C,IAAI,KAAK,SAAS,eAAe,KAAK,eAAe,QAAQ,YAC3D,OAAO;IACT,kBAAkB;IAClB,OAAO;KACL,GAAG;KACH,QAAQ,QAAQ;KAChB,UAAU,QAAQ;KAClB,SAAS,QAAQ;IACnB;GACF,CAAC;GACD,IAAI,CAAC,iBAAiB,OAAO;GAC7B,UAAU;GACV,OAAO;IAAE,GAAG;IAAW;GAAQ;EACjC,CAAC;EAED,IAAI,CAAC,SAAS;EACd,KAAK,aAAa;EAClB,KAAK,4BAA4B,QAAQ,SAAS;CACpD;CAKA,4BAAoC,WAAyB;EAC3D,IAAI,CAAC,KAAK,8BAA8B,SAAS,GAAG;EAEpD,IAAI,KAAK,eAAe;GAGtB,KAAK,yBAAyB;GAC9B;EACF;EACA,KAAK,eAAe,SAAS;CAC/B;CAEA,8BAAsC,WAA4B;EAChE,MAAM,UAAU,KAAK,SAAS,MAAM,MAAM,EAAE,OAAO,SAAS;EAC5D,IAAI,CAAC,WAAW,QAAQ,SAAS,aAAa,OAAO;EACrD,MAAM,YAAY;EAClB,IACE,UAAU,QAAQ,SAAS,qBAC3B,UAAU,OAAO,WAAW,cAE5B,OAAO;EAOT,IAAI,CALgB,UAAU,QAAQ,OACnC,SACC,KAAK,SAAS,eACb,YAAY,QAAQ,KAAK,WAAW,KAAA,CAE1B,GAAG,OAAO;EAEzB,KAAK,WAAW,KAAK,SAAS,KAAK,MACjC,EAAE,OAAO,aAAa,EAAE,SAAS,cAC7B;GACE,GAAI;GACJ,QAAQ;IAAE,MAAM;IAAqB,QAAQ;GAAmB;EAClE,IACA,CACN;EACA,KAAK,aAAa;EAClB,KAAK,wBAAwB,SAAS;EACtC,OAAO;CACT;CAEA,eAAuB,WAAyB;EAC9C,KAAU,SAAS,WAAW,KAAK,aAAa,CAAC,CAAC,OAAO,UAAU;GACjE,KAAK,UAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;EAC1E,CAAC;CACH;CAEA,sBAAsB,UAA0C;EAC9D,KAAK,wBAAwB,MAAM;EACnC,KAAK,WAAW,CAAC,GAAG,QAAQ;EAC5B,KAAK,mBAAmB,MAAM;EAC9B,KAAK,MAAM,WAAW,KAAK,UACzB,KAAK,mBAAmB,IAAI,QAAQ,EAAE;EAExC,KAAK,aAAa;CACpB;CAEA,kBAAkB,OAAgC;EAChD,KAAK,gBAAgB;EACrB,KAAK,aAAa;CACpB;CAEA,MAAc,SACZ,UACA,WACA,QACA,cACe;EACf,MAAM,sBAAsB,aAAa,CAAC;EAC1C,KAAK,gBAAgB;EACrB,KAAK,UAAU,QAAQ;EACvB,MAAM,qBAAqB,CAAC,GAAG,KAAK,QAAQ;EAE5C,KAAK,eAAe;EACpB,MAAM,oBAAoB,YAAY,KAAK,SAAS,GAAG,EAAE,CAAC,EAAE,MAAM;EAClE,IAAI;EACJ,MAAM,wBAAwB;GAC5B,IAAI,oBAAoB,OAAO;GAC/B,MAAM,UAAU,KAAK,2BAA2B;GAChD,qBAAqB;GACrB,KAAK,4BAA4B,SAAS,qBAAqB,IAAI;GACnE,OAAO;EACT;EAEA,MAAM,eAAe,WAA+B;GAClD,MAAM,WAAW,KAAK,uBAAuB,gBAAgB,GAAG,MAAM;GACtE,IAAI,aAAa,oBACf,qBAAqB;EAEzB;EAEA,MAAM,aAAa,IAAI,cAAc;GACnC,cAAc,KAAK;GACnB,QAAQ,KAAK;GACb,MAAM;GACN,oBAAoB,aAAa;IAC/B,MAAM,cAAc,gBAAgB;IACpC,IAAI,gBAAgB,UAAU;IAC9B,KAAK,oBAAoB,aAAa,QAAQ;IAC9C,qBAAqB;GACvB;EACF,CAAC;EACD,MAAM,YAAY,UAAqB,KAAK,YAAY,YAAY,KAAK;EAEzE,MAAM,kBAAkB,IAAI,gBAAgB;EAC5C,MAAM,cAAc,gBAAgB;EACpC,KAAK,kBAAkB;EAEvB,IAAI,kBAAkB,SAAS,EAAE,MAAM,gBAAgB,CAAC;EACxD,YAAY,iBACV,eACM;GACJ,UAAU;GACV,KAAK,UAAU,eAAe;GAC9B,KAAK,WAAW;EAClB,GACA,EAAE,MAAM,KAAK,CACf;EAEA,KAAK,WAAW,IAAI;EAEpB,IAAI;GACF,IAAI,cAAc;IAEhB,kBACE,YAAY,EAAE,QAAQ;KAAE,MAAM;KAAc,QAAQ;IAAY,EAAE,CAAC;IACrE,MAAM,KAAK,oBAAoB,cAAc;KAC3C,WAAW;KACX,UAAU,KAAK,MAAM,YAAY;KACjC,UAAU;KACV;KACA;KACA;KACA;KACA,6BAA6B;IAC/B,CAAC;GACH,OAAO;IACL,MAAM,QAAQ,WAAW;IACzB,WAAW,OAAO;KAAE,MAAM;KAAe;IAAM,CAAC;IAChD,MAAM,QAAQ,KAAK,cACjB,OACA,qBACA,oBACA,MACF;IACA,MAAM,aAAa,qBAAqB;KACtC;KACA;KACA,QAAQ,KAAK;KACb,cAAc,UAAU;MACtB,KAAK,eAAe;MACpB,KAAK,UAAU,KAAK;KACtB;IACF,CAAC;IACD,IAAI;KACF,KAAM,MAAc,WAAW,MAAM;KACrC,KAAM,MAAc,WAAW,MAAM;KACrC,KAAM,MAAc,QAAQ,MAAM,SAAS;IAC7C,QAAQ,CAER;IACA,MAAO,KAAK,MAAc,SAAS,OAAO,YAAY,EACpD,QAAQ,YACV,CAAC;GACH;EACF,SAAS,OAAO;GACd,IAAI,CAAC,YAAY,SAAS;IACxB,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;IACpE,SAAS;KAAE,MAAM;KAAa,SAAS,IAAI;IAAQ,CAAC;IACpD,KAAK,UAAU,GAAG;IAClB,KAAK,eAAe,KAAK,gBAAgB;GAC3C;EACF,UAAU;GACR,KAAK,UAAU,eAAe;EAChC;EAEA,IAAI,KAAK,cAAc;GACrB,MAAM,MAAM,KAAK;GACjB,KAAK,eAAe;GACpB,KAAK,yBAAyB;GAC9B,MAAM;EACR;EAIA,IAAI,KAAK,2BAA2B,MAAM;GACxC,MAAM,kBAAkB,KAAK;GAC7B,KAAK,yBAAyB;GAC9B,IAAI,CAAC,YAAY,SACf,KAAK,eAAe,eAAe;EAEvC;CACF;CAGA,MAAc,oBACZ,QACA,KAUe;EACf,MAAM,cAAc,IAAI,gBAAgB;EACxC,MAAM,kBAAkB,IAAI,sBAAsB,KAAK;EACvD,MAAM,UAA+B;GACnC,UAAU,IAAI;GACd,WAAW,IAAI;GACf,aAAa,IAAI;GACjB,SAAS,KAAK,SAAS,OAAO,gBAAgB,KAAK,CAAC;GACpD,6BAA6B;GAC7B,mBAAmB,IAAI;GACvB,mBAAmB,IAAI;GACvB,2BAA2B;IACzB,MAAM,UAAU,KAAK,SAAS,MAAM,MAAM,EAAE,OAAO,UAAU,CAAC;IAC9D,IAAI,CAAC,SACH,MAAM,IAAI,MACR,wEACF;IAEF,OAAO;GACT;EACF;EAEA,IAAI;GACF,WAAW,MAAM,UAAU,OAAO,OAAO,GAAG;IAC1C,IAAI,IAAI,YAAY,SAAS;IAC7B,IAAI,YAAY,MAAM;GACxB;EACF,SAAS,OAAO;GACd,IAAI,IAAI,YAAY,SAAS;GAC7B,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;GACpE,IAAI,YAAY,EACd,QAAQ;IAAE,MAAM;IAAc,QAAQ;IAAS,OAAO,IAAI;GAAQ,EACpE,CAAC;GACD,KAAK,UAAU,GAAG;GAClB,KAAK,eAAe,KAAK,gBAAgB;GACzC;EACF;EAEA,IAAI,IAAI,YAAY,SAAS;EAC7B,MAAM,UAAU,KAAK,SAAS,MAAM,MAAM,EAAE,OAAO,UAAU,CAAC;EAC9D,IAAI,CAAC,WAAW,QAAQ,QAAQ,SAAS,WACvC,IAAI,YAAY,EAAE,QAAQ;GAAE,MAAM;GAAY,QAAQ;EAAU,EAAE,CAAC;CAEvE;CAEA,cACE,OACA,WACA,iBACA,QACA;EACA,MAAM,WAAW,KAAK,MAAM,YAAY;EACxC,MAAM,WAAW,eAAe,mBAAmB,KAAK,QAAQ;EAChE,MAAM,UAAU,KAAK,SAAS,OAAO,gBAAgB;EACrD,OAAO;GACL;GACA;GACA,OAAO,KAAK,iBAAiB;GAC7B;GACA,OAAO,YAAY,SAAS,KAAK;GACjC,SAAS,SAAS,SACd,CAAC;IAAE,aAAa;IAAU,OAAO,QAAQ;GAAO,CAAC,IACjD,CAAC;GACL,gBAAgB;IACd,GAAI,SAAS,gBAAgB,CAAC;IAC9B,GAAI,SAAS,UAAU,CAAC;IACxB,GAAI,WAAW,SAAS,EAAE,WAAW,UAAU,OAAO,IAAI,CAAC;GAC7D;GACA,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;EAC3C;CACF;CAEA,oBAAkC;EAChC,MAAM,QAAQ,KAAK;EACnB,IAAI,MAAM,mBAAmB;EAC7B,MAAM,oBAAoB;EAE1B,MAAM,WADa,OAAO,OAAO,OAAO,sBACd,IACtB,MAAM,uBACN,OAAO,eAAe,KAAK,CAAC,EAAE;EAClC,IAAI,OAAO,aAAa,YAAY;EACpC,MAAM,uBAAuB,SAE3B,QACA;GACA,MAAM,QAAQ,SAAS,KAAK,MAAM,MAAM;GACxC,IAAI,QAAQ,WAAW,KAAA,KAAa,SAAS,OAAO,UAAU,UAC5D,OAAO;IAAE,GAAI;IAAkB,QAAQ,OAAO;GAAO;GAEvD,OAAO;EACT;CACF;CAEA,WAAmB,SAAkB;EACnC,KAAK,gBAAgB;EACrB,KAAK,aAAa;CACpB;CAEA,UAAkB,YAAoC;EACpD,IAAI,KAAK,oBAAoB,YAC3B,KAAK,kBAAkB;EAEzB,KAAK,WAAW,KAAK;CACvB;CAEA,6BAA6C;EAC3C,MAAM,KAAK,qBAAqB;EAChC,MAAM,YAAoC;GACxC;GACA,MAAM;GACN,2BAAW,IAAI,KAAK;GACpB,QAAQ,EAAE,MAAM,UAAU;GAC1B,SAAS,CAAC;GACV,UAAU;IACR,gBAAgB,KAAK,iBAAiB;IACtC,sBAAsB,CAAC;IACvB,eAAe,CAAC;IAChB,OAAO,CAAC;IACR,cAAc;IACd,QAAQ,CAAC;GACX;EACF;EACA,KAAK,WAAW,CAAC,GAAG,KAAK,UAAU,SAAS;EAC5C,KAAK,aAAa;EAClB,OAAO;CACT;CAEA,oBAA4B,OAAe,OAAqB;EAC9D,IAAI,UAAU,OAAO;EAIrB,IAF6B,KAAK,SAAS,MAAM,MAAM,EAAE,OAAO,KAEzC,GAAG;GACxB,KAAK,OAAO,QACV,2FACA;IAAE;IAAO;GAAM,CACjB;GACA,KAAK,WAAW,KAAK,SAAS,QAAQ,MAAM,EAAE,OAAO,KAAK;EAC5D,OACE,KAAK,WAAW,KAAK,SAAS,KAAK,MAAM;GACvC,IAAI,EAAE,OAAO,OAAO,OAAO;GAC3B,MAAM,EAAE,cAAc,GAAG,GAAG,aAAa,EAAE;GAC3C,OAAO;IAAE,GAAG;IAAG,IAAI;IAAO;GAAS;EACrC,CAAC;EAGH,MAAM,gBAAgB,KAAK,wBAAwB,IAAI,KAAK;EAC5D,IAAI,kBAAkB,KAAA,GAAW;GAC/B,KAAK,wBAAwB,OAAO,KAAK;GACzC,IAAI,CAAC,KAAK,wBAAwB,IAAI,KAAK,GACzC,KAAK,wBAAwB,IAAI,OAAO,aAAa;EAEzD;EAEA,IAAI,KAAK,mBAAmB,IAAI,KAAK,GAAG;GACtC,KAAK,mBAAmB,OAAO,KAAK;GACpC,KAAK,mBAAmB,IAAI,KAAK;EACnC;EAEA,KAAK,aAAa;CACpB;CAEA,uBACE,WACA,QACQ;EACR,IAAI,UAAU;EACd,IAAI;EACJ,KAAK,WAAW,KAAK,SAAS,KAAK,YAAY;GAC7C,IAAI,QAAQ,OAAO,aAAa,QAAQ,SAAS,aAC/C,OAAO;GACT,UAAU;GACV,MAAM,YAAY;GAClB,MAAM,WAAW,OAAO,WACpB,KAAK,uBAAuB,UAAU,UAAU,OAAO,QAAQ,IAC/D,UAAU;GACd,eAAe,OAAO,UAAU,UAAU;GAC1C,MAAM,UACJ,OAAO,YAAY,KAAA,IACf,KAAK,oBACH,UAAU,SACV,OAAO,OACT,IACA,UAAU;GAChB,OAAO;IACL,GAAG;IACH;IACA,QAAQ;IACR;GACF;EACF,CAAC;EACD,IAAI,CAAC,SAAS,OAAO;EAErB,IAAI,oBAAoB;EAGxB,IADE,iBAAiB,KAAA,KAAa,aAAa,SAAS,aACrC,eAAe,SAAS,GAAG;GAC1C,MAAM,WAAW,WAAW;GAC5B,KAAK,oBAAoB,WAAW,QAAQ;GAC5C,oBAAoB;EACtB,OACE,KAAK,aAAa;EAEpB,IAAI,KAAK,oBAAoB,YAAY,GACvC,KAAK,wBAAwB,iBAAiB;EAEhD,KAAK,4BAA4B,iBAAiB;EAClD,OAAO;CACT;CAMA,oBACE,UACA,MACmC;EACnC,MAAM,2BAAW,IAAI,IAAiC;EACtD,KAAK,MAAM,QAAQ,UACjB,IACE,KAAK,SAAS,eACd,YAAY,QACZ,KAAK,WAAW,KAAA,GAEhB,SAAS,IAAI,KAAK,YAAY,IAAI;EAGtC,IAAI,SAAS,SAAS,GAAG,OAAO;EAEhC,IAAI,UAAU;EACd,MAAM,SAAS,KAAK,KAAK,SAAS;GAChC,IAAI,KAAK,SAAS,aAAa,OAAO;GACtC,IAAI,YAAY,QAAQ,KAAK,WAAW,KAAA,GAAW,OAAO;GAC1D,MAAM,QAAQ,SAAS,IAAI,KAAK,UAAU;GAC1C,IAAI,CAAC,OAAO,OAAO;GACnB,UAAU;GACV,OAAO;IACL,GAAG;IACH,QAAQ,MAAM;IACd,GAAI,MAAM,aAAa,KAAA,IAAY,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;IACnE,GAAI,MAAM,YAAY,KAAA,IAAY,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;GAClE;EACF,CAAC;EACD,OAAO,UAAW,SAA+C;CACnE;CAEA,uBACE,SACA,UACoC;EACpC,MAAM,cAAc,SAAS,uBACzB,CAAC,GAAG,QAAQ,sBAAsB,GAAG,SAAS,oBAAoB,IAClE,QAAQ;EACZ,MAAM,OAAO,SAAS,gBAClB,CAAC,GAAG,QAAQ,eAAe,GAAG,SAAS,aAAa,IACpD,QAAQ;EACZ,MAAM,QAAQ,SAAS,QACnB,CAAC,GAAG,QAAQ,OAAO,GAAG,SAAS,KAAK,IACpC,QAAQ;EACZ,OAAO;GACL,gBACE,SAAS,mBAAmB,KAAA,IACxB,SAAS,iBACT,QAAQ;GACd,sBAAsB;GACtB,eAAe;GACf;GACA,GAAI,QAAQ,eAAe,EAAE,cAAc,KAAK,IAAI,CAAC;GACrD,GAAI,SAAS,SAAS,EAAE,QAAQ,SAAS,OAAO,IAAI,CAAC;GACrD,QAAQ,SAAS,SACb;IAAE,GAAG,QAAQ;IAAQ,GAAG,SAAS;GAAO,IACxC,QAAQ;EACd;CACF;CAEA,YAAoB,YAA2B,OAAkB;EAC/D,QAAQ,MAAM,MAAd;GACE,KAAK;IACH,KAAK,gBAAgB,MAAM;IAC3B,KAAK,aAAa;IAClB;GAEF,KAAK;IACH,IAAI,MAAM,MAAM,WAAW,GAAG;IAC9B,IAAI;KACF,MAAM,QAAQ,KAAK,iBAAiB,CAAC;KACrC,MAAM,SAAS,UAAU,WACvB,OACA,MAAM,OACkB,MACH,KACvB;KACA,KAAK,gBAAgB,OAAO;KAC5B,KAAK,aAAa;IACpB,SAAS,OAAO;KACd,KAAK,OAAO,QAAQ,sCAAsC,KAAK;IACjE;IACA;GAEF,KAAK;IACH,KAAK,uBAAuB,MAAM,QAAQ;IAC1C;GAEF,KAAK;IACH,IAAI,CAAC,WAAW,YAAY,MAAM,UAAU,GAAG;KAC7C,MAAM,YAAY,KAAK,yBAAyB,MAAM,UAAU;KAChE,IAAI,cAAc,KAAA,GAAW;MAC3B,KAAK,wBAAwB,WAAW,KAAK;MAC7C;KACF;IACF;IACA,WAAW,OAAO,KAAK;IACvB;GAEF,SACE,WAAW,OAAO,KAAK;EAC3B;CACF;CAEA,wBACE,WACA,OACM;EACN,IAAI,UAAU;EACd,KAAK,WAAW,KAAK,SAAS,KAAK,YAAY;GAC7C,IAAI,QAAQ,OAAO,aAAa,QAAQ,SAAS,aAC/C,OAAO;GACT,MAAM,YAAY;GAClB,IAAI,kBAAkB;GACtB,MAAM,UAAU,UAAU,QAAQ,KAAK,SAAS;IAC9C,IAAI,KAAK,SAAS,eAAe,KAAK,eAAe,MAAM,YACzD,OAAO;IACT,kBAAkB;IAClB,OAAO;KACL,GAAG;KACH,QAAQ,aAAa,MAAM,WAAW,EAAE;KACxC,GAAI,MAAM,SAAS,SAAS,EAAE,SAAS,MAAM,IAAI,CAAC;KAClD,GAAI,MAAM,YACN,EAAE,wBAAwB,MAAM,UAAU,IAC1C,CAAC;IACP;GACF,CAAC;GACD,IAAI,CAAC,iBAAiB,OAAO;GAC7B,UAAU;GACV,OAAO;IAAE,GAAG;IAAW;GAAQ;EACjC,CAAC;EAED,IAAI,CAAC,SAAS;EACd,KAAK,aAAa;EAGlB,KAAK,8BAA8B,SAAS;CAC9C;CAEA,uBAA+B,aAAiC;EAC9D,IAAI;GACF,MAAM,aAAa,iBAAiB,aAAa,EAC/C,cAAc,KAAK,aACrB,CAAC;GACD,MAAM,YAA6B,CAAC;GACpC,KAAK,MAAM,WAAW,YACpB,IAAI;IACF,UAAU,KACR,sBAAsB,SAAS,WAAW,GAAG,oBAAoB,CACnE;GACF,SAAS,OAAO;IACd,KAAK,OAAO,QACV,iDACA,KACF;GACF;GAEF,KAAK,sBAAsB,SAAS;EACtC,SAAS,OAAO;GACd,KAAK,OAAO,QAAQ,6CAA6C,KAAK;EACxE;CACF;CAEA,gBAAwB,SAAuC;EAC7D,OAAO,sBACL,SACA,WAAW,GACX,oBACF;CACF;CAEA,UAAkB,UAAqC;EACrD,IAAI,CAAC,UAAU;GACb,IAAI,KAAK,SAAS,QAChB,KAAK,WAAW,CAAC;GAEnB;EACF;EACA,MAAM,MAAM,KAAK,SAAS,WAAW,YAAY,QAAQ,OAAO,QAAQ;EACxE,IAAI,QAAQ,IAAI;EAChB,KAAK,WAAW,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC;CAChD;CAEA,iBAAyB,QAAiC;EACxD,OAAO,QAAQ,SAAS,cAAc,QAAQ,SAAS;CACzD;CAEA,oBAA4B,QAAiC;EAC3D,IAAI,KAAK,iBAAiB,MAAM,GAAG,OAAO;EAC1C,OAAO,QAAQ,SAAS,qBAAqB,OAAO,WAAW;CACjE;CAEA,mBAA2B,UAAyB,SAAwB;EAC1E,KAAK,kBAAkB,UAAU,OAAO;CAC1C;CAEA,4BACE,WACA,UACA;EACA,IAAI,CAAC,KAAK,SAAS;EACnB,KAAK,wBAAwB,IAAI,WAAW,QAAQ;CACtD;CAEA,wBAAgC,WAAmB;EACjD,IAAI,CAAC,KAAK,SAAS;EACnB,MAAM,WAAW,KAAK,wBAAwB,IAAI,SAAS;EAC3D,IAAI,aAAa,KAAA,GAAW;EAC5B,MAAM,UAAU,KAAK,SAAS,MAAM,MAAM,EAAE,OAAO,SAAS;EAC5D,IAAI,CAAC,WAAW,QAAQ,SAAS,aAAa;EAC9C,IAAI,CAAC,KAAK,oBAAoB,QAAQ,MAAM,GAAG;EAC/C,KAAK,wBAAwB,OAAO,SAAS;EAC7C,KAAK,kBAAkB,UAAU,OAAO;CAC1C;CAEA,kBAA0B,UAAyB,SAAwB;EACzE,IAAI,CAAC,KAAK,WAAW,KAAK,mBAAmB,IAAI,QAAQ,EAAE,GAAG;EAC9D,KAAK,mBAAmB,IAAI,QAAQ,EAAE;EACtC,KAAU,QAAQ,OAAO;GAAE;GAAU;EAAQ,CAAC,CAAC,CAAC,OAAO,UAAU;GAC/D,KAAK,mBAAmB,OAAO,QAAQ,EAAE;GACzC,KAAK,OAAO,QAAQ,yCAAyC,KAAK;EACpE,CAAC;CACH;AACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/react-ag-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.41",
|
|
4
4
|
"description": "AG-UI protocol adapter for assistant-ui",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ag-ui",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"sideEffects": false,
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@ag-ui/client": "^0.0.57",
|
|
33
|
-
"@assistant-ui/core": "^0.2.
|
|
33
|
+
"@assistant-ui/core": "^0.2.17",
|
|
34
34
|
"assistant-stream": "^0.3.23",
|
|
35
35
|
"fast-json-patch": "^3.1.1"
|
|
36
36
|
},
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"react": "^19.2.7",
|
|
49
49
|
"vitest": "^4.1.8",
|
|
50
50
|
"zod": "^4.4.3",
|
|
51
|
-
"@assistant-ui/x-buildutils": "0.0.
|
|
51
|
+
"@assistant-ui/x-buildutils": "0.0.15"
|
|
52
52
|
},
|
|
53
53
|
"publishConfig": {
|
|
54
54
|
"access": "public",
|