@assistant-ui/react-ag-ui 0.0.33 → 0.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"AgUiThreadRuntimeCore.d.ts","names":[],"sources":["../../src/runtime/AgUiThreadRuntimeCore.ts"],"mappings":";;;;;;;KAoCK,SAAA,GAAY,WAAW,CAAC,aAAA;AAAA,KACxB,eAAA;EACH,QAAA;EACA,QAAA;EACA,SAAA,EAAW,SAAS;EACpB,MAAA;AAAA;AAAA,KAGG,WAAA;EACH,KAAA,EAAO,SAAA;EACP,MAAA,EAAQ,MAAA;EACR,YAAA;EACA,OAAA,IAAW,KAAA,EAAO,KAAA;EAClB,QAAA;EACA,OAAA,GAAU,oBAAA;EACV,YAAA;AAAA;AAAA,cAKW,qBAAA;EAAA,QACH,KAAA;EAAA,QACA,MAAA;EAAA,QACA,YAAA;EAAA,QACA,OAAA;EAAA,QACA,QAAA;EAAA,iBACS,YAAA;EAAA,QAET,OAAA;EAAA,QACA,QAAA;EAAA,QACA,aAAA;EAAA,QACA,eAAA;EAAA,QACA,aAAA;EAAA,QACA,YAAA;EAAA,QACA,OAAA;EAAA,QACA,aAAA;EAAA,iBACS,uBAAA;EAAA,iBACA,kBAAA;EAAA,QACT,UAAA;EAAA,QACA,YAAA;cAEI,OAAA,EAAS,WAAA;EAWrB,aAAA,CAAc,OAAA,EAAS,IAAA,CAAK,WAAA;EAU5B,aAAA,CAAc,OAAA,EAAS,gBAAA;EAIvB,aAAA,CAAA;EAIA,WAAA,CAAA,YAAwB,aAAA;EAIxB,QAAA,CAAA,GAAY,iBAAA;EAIZ,SAAA,CAAA;EAAA,IAII,SAAA,CAAA;EAIJ,eAAA,CAAA,GAAmB,OAAA;EAkCb,MAAA,CAAO,OAAA,EAAS,aAAA,GAAgB,OAAA;EAmBhC,IAAA,CAAK,OAAA,EAAS,aAAA,GAAgB,OAAA;EAI9B,MAAA,CACJ,QAAA,iBACA,MAAA;IAAU,SAAA,GAAY,SAAA;EAAA,IACrB,OAAA;EAOG,MAAA,CAAA,GAAU,OAAA;EAKV,MAAA,CAAO,MAAA,EAAQ,eAAA,GAAkB,OAAA;EAAA,QAa/B,yBAAA;EAOR,oBAAA,CAAA;IACE,SAAA;IACA,UAAA,WAAqB,aAAA;EAAA;EAqBjB,wBAAA,CACJ,SAAA,WAAoB,eAAA,KACnB,OAAA;EAAA,QAyEK,sBAAA;EAgCR,wBAAA,CAAyB,UAAA;EAiBzB,aAAA,CAAc,OAAA,EAAS,oBAAA;EAgEvB,qBAAA,CAAsB,QAAA,WAAmB,aAAA;EAUzC,iBAAA,CAAkB,KAAA,EAAO,iBAAA;EAAA,QAKX,QAAA;EAAA,QAsGN,aAAA;EAAA,QA2BA,iBAAA;EAAA,QAqBA,UAAA;EAAA,QAKA,SAAA;EAAA,QAOA,0BAAA;EAAA,QAqBA,mBAAA;EAAA,QAiCA,sBAAA;EAAA,QAyCA,sBAAA;EAAA,QA4BA,WAAA;EAAA,QAoBA,sBAAA;EAAA,QA0BA,eAAA;EAAA,QAQA,SAAA;EAAA,QAYA,gBAAA;EAAA,QAIA,mBAAA;EAAA,QAKA,kBAAA;EAAA,QAIA,2BAAA;EAAA,QAQA,uBAAA;EAAA,QAWA,iBAAA;AAAA"}
1
+ {"version":3,"file":"AgUiThreadRuntimeCore.d.ts","names":[],"sources":["../../src/runtime/AgUiThreadRuntimeCore.ts"],"mappings":";;;;;;;KAmCK,SAAA,GAAY,WAAW,CAAC,aAAA;AAAA,KACxB,eAAA;EACH,QAAA;EACA,QAAA;EACA,SAAA,EAAW,SAAS;EACpB,MAAA;AAAA;AAAA,KAGG,WAAA;EACH,KAAA,EAAO,SAAA;EACP,MAAA,EAAQ,MAAA;EACR,YAAA;EACA,OAAA,IAAW,KAAA,EAAO,KAAA;EAClB,QAAA;EACA,OAAA,GAAU,oBAAA;EACV,YAAA;AAAA;AAAA,cAKW,qBAAA;EAAA,QACH,KAAA;EAAA,QACA,MAAA;EAAA,QACA,YAAA;EAAA,QACA,OAAA;EAAA,QACA,QAAA;EAAA,iBACS,YAAA;EAAA,QAET,OAAA;EAAA,QACA,QAAA;EAAA,QACA,aAAA;EAAA,QACA,eAAA;EAAA,QACA,aAAA;EAAA,QACA,YAAA;EAAA,QACA,OAAA;EAAA,QACA,aAAA;EAAA,iBACS,uBAAA;EAAA,iBACA,kBAAA;EAAA,QACT,UAAA;EAAA,QACA,YAAA;cAEI,OAAA,EAAS,WAAA;EAWrB,aAAA,CAAc,OAAA,EAAS,IAAA,CAAK,WAAA;EAU5B,aAAA,CAAc,OAAA,EAAS,gBAAA;EAIvB,aAAA;EAIA,WAAA,aAAwB,aAAA;EAIxB,QAAA,IAAY,iBAAA;EAIZ,SAAA;EAAA,IAII,SAAA;EAIJ,eAAA,IAAmB,OAAA;EAkCb,MAAA,CAAO,OAAA,EAAS,aAAA,GAAgB,OAAA;EAmBhC,IAAA,CAAK,OAAA,EAAS,aAAA,GAAgB,OAAA;EAI9B,MAAA,CACJ,QAAA,iBACA,MAAA;IAAU,SAAA,GAAY,SAAA;EAAA,IACrB,OAAA;EAOG,MAAA,IAAU,OAAA;EAKV,MAAA,CAAO,MAAA,EAAQ,eAAA,GAAkB,OAAA;EAAA,QAa/B,yBAAA;EAOR,oBAAA;IACE,SAAA;IACA,UAAA,WAAqB,aAAA;EAAA;EAqBjB,wBAAA,CACJ,SAAA,WAAoB,eAAA,KACnB,OAAA;EAAA,QAyEK,sBAAA;EAgCR,wBAAA,CAAyB,UAAA;EAiBzB,aAAA,CAAc,OAAA,EAAS,oBAAA;EAgEvB,qBAAA,CAAsB,QAAA,WAAmB,aAAA;EAUzC,iBAAA,CAAkB,KAAA,EAAO,iBAAA;EAAA,QAKX,QAAA;EAAA,QAsGN,aAAA;EAAA,QA2BA,iBAAA;EAAA,QAqBA,UAAA;EAAA,QAKA,SAAA;EAAA,QAOA,0BAAA;EAAA,QAqBA,mBAAA;EAAA,QAiCA,sBAAA;EAAA,QAyCA,sBAAA;EAAA,QA4BA,WAAA;EAAA,QAoBA,sBAAA;EAAA,QA0BA,eAAA;EAAA,QAQA,SAAA;EAAA,QAYA,gBAAA;EAAA,QAIA,mBAAA;EAAA,QAKA,kBAAA;EAAA,QAIA,2BAAA;EAAA,QAQA,uBAAA;EAAA,QAWA,iBAAA;AAAA"}
@@ -2,8 +2,11 @@
2
2
  import { AG_UI_METADATA_NAMESPACE, RunAggregator } 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, generateOptimisticId, isOptimisticId } from "@assistant-ui/core/internal";
5
+ import { fromThreadMessageLike, generateId } from "@assistant-ui/core/internal";
6
6
  //#region src/runtime/AgUiThreadRuntimeCore.ts
7
+ const optimisticPrefix = "__optimistic__";
8
+ const generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
9
+ const isOptimisticId = (id) => id.startsWith(optimisticPrefix);
7
10
  const symbolResumeShim = Symbol("agui-resume-shim");
8
11
  const FALLBACK_USER_STATUS = {
9
12
  type: "complete",
@@ -1 +1 @@
1
- {"version":3,"file":"AgUiThreadRuntimeCore.js","names":[],"sources":["../../src/runtime/AgUiThreadRuntimeCore.ts"],"sourcesContent":["\"use client\";\n\nimport {\n generateId,\n generateOptimisticId,\n isOptimisticId,\n fromThreadMessageLike,\n} from \"@assistant-ui/core/internal\";\nimport type {\n AddToolResultOptions,\n AppendMessage,\n AssistantRuntime,\n ChatModelRunResult,\n MessageStatus,\n ThreadAssistantMessage,\n ThreadHistoryAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type { HttpAgent } from \"@ag-ui/client\";\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} from \"./adapter/run-aggregator\";\nimport {\n fromAgUiMessages,\n toAgUiMessages,\n toAgUiTools,\n} from \"./adapter/conversions\";\nimport { createAgUiSubscriber } from \"./adapter/subscriber\";\n\nconst symbolResumeShim = Symbol(\"agui-resume-shim\");\n\ntype RunConfig = NonNullable<AppendMessage[\"runConfig\"]>;\ntype ResumeRunConfig = {\n parentId: string | null;\n sourceId: string | null;\n runConfig: RunConfig;\n stream?: unknown;\n};\n\ntype CoreOptions = {\n agent: HttpAgent;\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: HttpAgent;\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\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 await this.startRun(parentId, this.lastRunConfig);\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 if (config.stream) {\n this.logger.debug?.(\n \"[agui] resume stream is not supported, falling back to regular run\",\n );\n }\n await this.startRun(\n config.parentId,\n config.runConfig ?? this.lastRunConfig,\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 let shouldResume = 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\n if (\n assistant.status?.type === \"requires-action\" &&\n assistant.status.reason === \"tool-calls\" &&\n content.every(\n (part) =>\n part.type !== \"tool-call\" ||\n (\"result\" in part && part.result !== undefined),\n )\n ) {\n shouldResume = true;\n return {\n ...assistant,\n content,\n status: { type: \"complete\" as const, reason: \"unknown\" as const },\n };\n }\n\n return {\n ...assistant,\n content,\n };\n });\n\n if (updated) {\n this.notifyUpdate();\n\n if (shouldResume) {\n this.persistAssistantHistory(options.messageId);\n\n if (!this.isRunningFlag) {\n void this.startRun(options.messageId, this.lastRunConfig).catch(\n (error) => {\n this.onError?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n },\n );\n }\n }\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 ): Promise<void> {\n const normalizedRunConfig = runConfig ?? {};\n this.lastRunConfig = normalizedRunConfig;\n this.resetHead(parentId);\n const historicalMessages = [...this.messages];\n\n const runId = generateId();\n this.pendingError = null;\n const input = this.buildRunInput(\n runId,\n normalizedRunConfig,\n historicalMessages,\n resume,\n );\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 aggregator = new RunAggregator({\n showThinking: this.showThinking,\n logger: this.logger,\n emit: (update) => {\n const resolved = this.updateAssistantMessage(ensureAssistant(), update);\n if (resolved !== assistantMessageId) {\n assistantMessageId = resolved;\n }\n },\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 abortSignal.addEventListener(\n \"abort\",\n () => {\n dispatch({ type: \"RUN_CANCELLED\" });\n this.finishRun(abortController);\n this.onCancel?.();\n },\n { once: true },\n );\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\n aggregator.handle({ type: \"RUN_STARTED\", runId });\n this.setRunning(true);\n\n try {\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 } 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 throw err;\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 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 m.id === oldId ? { ...m, id: newId } : m,\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 return {\n ...assistant,\n content: (update.content ??\n assistant.content) as ThreadAssistantMessage[\"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 return resolvedMessageId;\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 ...(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 this.logger.debug?.(\"[agui] state delta event ignored\", event.delta);\n return;\n }\n case \"MESSAGES_SNAPSHOT\": {\n this.importMessagesSnapshot(event.messages);\n return;\n }\n default:\n aggregator.handle(event);\n }\n }\n\n private importMessagesSnapshot(rawMessages: readonly unknown[]) {\n try {\n const normalized = fromAgUiMessages(rawMessages);\n const converted: ThreadMessage[] = [];\n for (const message of normalized) {\n try {\n converted.push(\n fromThreadMessageLike(\n message as any,\n generateId(),\n FALLBACK_USER_STATUS,\n ),\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":"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"}
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 ChatModelRunResult,\n MessageStatus,\n ThreadAssistantMessage,\n ThreadHistoryAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type { HttpAgent } from \"@ag-ui/client\";\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} 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 ResumeRunConfig = {\n parentId: string | null;\n sourceId: string | null;\n runConfig: RunConfig;\n stream?: unknown;\n};\n\ntype CoreOptions = {\n agent: HttpAgent;\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: HttpAgent;\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\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 await this.startRun(parentId, this.lastRunConfig);\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 if (config.stream) {\n this.logger.debug?.(\n \"[agui] resume stream is not supported, falling back to regular run\",\n );\n }\n await this.startRun(\n config.parentId,\n config.runConfig ?? this.lastRunConfig,\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 let shouldResume = 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\n if (\n assistant.status?.type === \"requires-action\" &&\n assistant.status.reason === \"tool-calls\" &&\n content.every(\n (part) =>\n part.type !== \"tool-call\" ||\n (\"result\" in part && part.result !== undefined),\n )\n ) {\n shouldResume = true;\n return {\n ...assistant,\n content,\n status: { type: \"complete\" as const, reason: \"unknown\" as const },\n };\n }\n\n return {\n ...assistant,\n content,\n };\n });\n\n if (updated) {\n this.notifyUpdate();\n\n if (shouldResume) {\n this.persistAssistantHistory(options.messageId);\n\n if (!this.isRunningFlag) {\n void this.startRun(options.messageId, this.lastRunConfig).catch(\n (error) => {\n this.onError?.(\n error instanceof Error ? error : new Error(String(error)),\n );\n },\n );\n }\n }\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 ): Promise<void> {\n const normalizedRunConfig = runConfig ?? {};\n this.lastRunConfig = normalizedRunConfig;\n this.resetHead(parentId);\n const historicalMessages = [...this.messages];\n\n const runId = generateId();\n this.pendingError = null;\n const input = this.buildRunInput(\n runId,\n normalizedRunConfig,\n historicalMessages,\n resume,\n );\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 aggregator = new RunAggregator({\n showThinking: this.showThinking,\n logger: this.logger,\n emit: (update) => {\n const resolved = this.updateAssistantMessage(ensureAssistant(), update);\n if (resolved !== assistantMessageId) {\n assistantMessageId = resolved;\n }\n },\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 abortSignal.addEventListener(\n \"abort\",\n () => {\n dispatch({ type: \"RUN_CANCELLED\" });\n this.finishRun(abortController);\n this.onCancel?.();\n },\n { once: true },\n );\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\n aggregator.handle({ type: \"RUN_STARTED\", runId });\n this.setRunning(true);\n\n try {\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 } 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 throw err;\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 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 m.id === oldId ? { ...m, id: newId } : m,\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 return {\n ...assistant,\n content: (update.content ??\n assistant.content) as ThreadAssistantMessage[\"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 return resolvedMessageId;\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 ...(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 this.logger.debug?.(\"[agui] state delta event ignored\", event.delta);\n return;\n }\n case \"MESSAGES_SNAPSHOT\": {\n this.importMessagesSnapshot(event.messages);\n return;\n }\n default:\n aggregator.handle(event);\n }\n }\n\n private importMessagesSnapshot(rawMessages: readonly unknown[]) {\n try {\n const normalized = fromAgUiMessages(rawMessages);\n const converted: ThreadMessage[] = [];\n for (const message of normalized) {\n try {\n converted.push(\n fromThreadMessageLike(\n message as any,\n generateId(),\n FALLBACK_USER_STATUS,\n ),\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":"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"}
@@ -1,5 +1,5 @@
1
1
  import { Logger } from "./logger.js";
2
- import { AttachmentAdapter, DictationAdapter, FeedbackAdapter, SpeechSynthesisAdapter, ThreadHistoryAdapter, ThreadMessage } from "@assistant-ui/core";
2
+ import { AttachmentAdapter, DictationAdapter, ExternalStoreSharedOptions, FeedbackAdapter, RealtimeVoiceAdapter, SpeechSynthesisAdapter, ThreadHistoryAdapter, ThreadMessage } from "@assistant-ui/core";
3
3
  import { HttpAgent } from "@ag-ui/client";
4
4
  import { ReadonlyJSONValue } from "assistant-stream/utils";
5
5
 
@@ -22,6 +22,7 @@ type UseAgUiRuntimeAdapters = {
22
22
  attachments?: AttachmentAdapter;
23
23
  speech?: SpeechSynthesisAdapter;
24
24
  dictation?: DictationAdapter;
25
+ voice?: RealtimeVoiceAdapter;
25
26
  feedback?: FeedbackAdapter;
26
27
  history?: ThreadHistoryAdapter;
27
28
  /**
@@ -29,7 +30,7 @@ type UseAgUiRuntimeAdapters = {
29
30
  */
30
31
  threadList?: UseAgUiThreadListAdapter;
31
32
  };
32
- type UseAgUiRuntimeOptions = {
33
+ type UseAgUiRuntimeOptions = ExternalStoreSharedOptions & {
33
34
  agent: HttpAgent;
34
35
  logger?: Partial<Logger>;
35
36
  showThinking?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/runtime/types.ts"],"mappings":";;;;;;;;AAeA;KAAY,wBAAA;EACV,QAAA;EACA,mBAAA,UAA6B,OAAA;EAC7B,gBAAA,KACM,QAAA,aACE,OAAA;IACE,QAAA,WAAmB,aAAA;IACnB,KAAA,GAAQ,iBAAA;EAAA;IAER,QAAA,WAAmB,aAAA;IAAiB,KAAA,GAAQ,iBAAA;EAAA;AAAA;AAAA,KAI5C,sBAAA;EACV,WAAA,GAAc,iBAAA;EACd,MAAA,GAAS,sBAAA;EACT,SAAA,GAAY,gBAAA;EACZ,QAAA,GAAW,eAAA;EACX,OAAA,GAAU,oBAAA;EAZmB;;;EAgB7B,UAAA,GAAa,wBAAA;AAAA;AAAA,KAGH,qBAAA;EACV,KAAA,EAAO,SAAA;EACP,MAAA,GAAS,OAAA,CAAQ,MAAA;EACjB,YAAA;EACA,OAAA,IAAW,CAAA,EAAG,KAAA;EACd,QAAA;EACA,QAAA,GAAW,sBAAA;AAAA;AAAA,KAGD,mBAAA;AAAA,KAMA,aAAA;EACV,EAAA;EACA,MAAA,EAAQ,mBAAA;EACR,OAAA;EACA,UAAA;EACA,cAAA,GAAiB,MAAA;EACjB,SAAA;EACA,QAAA,GAAW,MAAA;AAAA;AAAA,KAGD,eAAA;EACV,WAAA;EACA,MAAA;EACA,OAAA;AAAA;AAAA,KAGU,sBAAA;EACN,IAAA;AAAA;EACA,IAAA;EAAmB,UAAA,EAAY,aAAa;AAAA;AAAA,KAEtC,SAAA;EACN,IAAA;EAAqB,KAAA;AAAA;EAErB,IAAA;EACA,KAAA;EACA,OAAA,GAAU,sBAAsB;AAAA;EAEhC,IAAA;EAAuB,KAAA;AAAA;EACvB,IAAA;EAAmB,OAAA;EAAkB,IAAA;AAAA;EACrC,IAAA;EAA4B,SAAA;AAAA;EAC5B,IAAA;EAA8B,SAAA;EAAoB,KAAA;AAAA;EAClD,IAAA;EAA0B,SAAA;AAAA;EAC1B,IAAA;EAA4B,KAAA;AAAA;EAC5B,IAAA;EAAwB,KAAA;AAAA;EACxB,IAAA;AAAA;EACA,IAAA;EAAuC,KAAA;AAAA;EACvC,IAAA;AAAA;EACA,IAAA;AAAA;EACA,IAAA;EAAyB,SAAA;AAAA;EACzB,IAAA;EAAiC,SAAA;AAAA;EACjC,IAAA;EAAmC,SAAA;EAAoB,KAAA;AAAA;EACvD,IAAA;EAA+B,SAAA;AAAA;EAC/B,IAAA;EAAuB,SAAA;AAAA;EAEvB,IAAA;EACA,UAAA;EACA,YAAA;EACA,eAAA;AAAA;EAEA,IAAA;EAAwB,UAAA;EAAoB,KAAA;AAAA;EAC5C,IAAA;EAAuB,UAAA;AAAA;EAEvB,IAAA;EACA,UAAA;EACA,YAAA;EACA,eAAA;EACA,KAAA;AAAA;EAGA,IAAA;EACA,SAAA;EACA,UAAA;EACA,OAAA;EACA,IAAA;AAAA;EAEA,IAAA;EAAa,KAAA;EAAY,MAAA;AAAA;EACzB,IAAA;EAAgB,IAAA;EAAc,KAAA;AAAA;EAC9B,IAAA;EAAwB,QAAA;AAAA;EACxB,IAAA;EAAqB,KAAA;AAAA;EACrB,IAAA;EAA2B,QAAA;AAAA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/runtime/types.ts"],"mappings":";;;;;;;;AAiBA;KAAY,wBAAA;EACV,QAAA;EACA,mBAAA,UAA6B,OAAA;EAC7B,gBAAA,KACM,QAAA,aACE,OAAA;IACE,QAAA,WAAmB,aAAA;IACnB,KAAA,GAAQ,iBAAA;EAAA;IAER,QAAA,WAAmB,aAAA;IAAiB,KAAA,GAAQ,iBAAA;EAAA;AAAA;AAAA,KAI5C,sBAAA;EACV,WAAA,GAAc,iBAAA;EACd,MAAA,GAAS,sBAAA;EACT,SAAA,GAAY,gBAAA;EACZ,KAAA,GAAQ,oBAAA;EACR,QAAA,GAAW,eAAA;EACX,OAAA,GAAU,oBAAA;EAZA;;;EAgBV,UAAA,GAAa,wBAAA;AAAA;AAAA,KAGH,qBAAA,GAAwB,0BAAA;EAClC,KAAA,EAAO,SAAA;EACP,MAAA,GAAS,OAAA,CAAQ,MAAA;EACjB,YAAA;EACA,OAAA,IAAW,CAAA,EAAG,KAAA;EACd,QAAA;EACA,QAAA,GAAW,sBAAA;AAAA;AAAA,KAGD,mBAAA;AAAA,KAMA,aAAA;EACV,EAAA;EACA,MAAA,EAAQ,mBAAA;EACR,OAAA;EACA,UAAA;EACA,cAAA,GAAiB,MAAA;EACjB,SAAA;EACA,QAAA,GAAW,MAAA;AAAA;AAAA,KAGD,eAAA;EACV,WAAA;EACA,MAAA;EACA,OAAA;AAAA;AAAA,KAGU,sBAAA;EACN,IAAA;AAAA;EACA,IAAA;EAAmB,UAAA,EAAY,aAAa;AAAA;AAAA,KAEtC,SAAA;EACN,IAAA;EAAqB,KAAA;AAAA;EAErB,IAAA;EACA,KAAA;EACA,OAAA,GAAU,sBAAsB;AAAA;EAEhC,IAAA;EAAuB,KAAA;AAAA;EACvB,IAAA;EAAmB,OAAA;EAAkB,IAAA;AAAA;EACrC,IAAA;EAA4B,SAAA;AAAA;EAC5B,IAAA;EAA8B,SAAA;EAAoB,KAAA;AAAA;EAClD,IAAA;EAA0B,SAAA;AAAA;EAC1B,IAAA;EAA4B,KAAA;AAAA;EAC5B,IAAA;EAAwB,KAAA;AAAA;EACxB,IAAA;AAAA;EACA,IAAA;EAAuC,KAAA;AAAA;EACvC,IAAA;AAAA;EACA,IAAA;AAAA;EACA,IAAA;EAAyB,SAAA;AAAA;EACzB,IAAA;EAAiC,SAAA;AAAA;EACjC,IAAA;EAAmC,SAAA;EAAoB,KAAA;AAAA;EACvD,IAAA;EAA+B,SAAA;AAAA;EAC/B,IAAA;EAAuB,SAAA;AAAA;EAEvB,IAAA;EACA,UAAA;EACA,YAAA;EACA,eAAA;AAAA;EAEA,IAAA;EAAwB,UAAA;EAAoB,KAAA;AAAA;EAC5C,IAAA;EAAuB,UAAA;AAAA;EAEvB,IAAA;EACA,UAAA;EACA,YAAA;EACA,eAAA;EACA,KAAA;AAAA;EAGA,IAAA;EACA,SAAA;EACA,UAAA;EACA,OAAA;EACA,IAAA;AAAA;EAEA,IAAA;EAAa,KAAA;EAAY,MAAA;AAAA;EACzB,IAAA;EAAgB,IAAA;EAAc,KAAA;AAAA;EAC9B,IAAA;EAAwB,QAAA;AAAA;EACxB,IAAA;EAAqB,KAAA;AAAA;EACrB,IAAA;EAA2B,QAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAgUiRuntime.d.ts","names":[],"sources":["../src/useAgUiRuntime.ts"],"mappings":";;;;KAuBY,oBAAA,GAAuB,gBAAA;EACjC,6BAAA,iBAA8C,aAAA;EAC9C,iCAAA,GACE,SAAA,WAAoB,eAAA,OACjB,OAAA;AAAA;AAAA,iBAGS,cAAA,CACd,OAAA,EAAS,qBAAA,GACR,oBAAoB"}
1
+ {"version":3,"file":"useAgUiRuntime.d.ts","names":[],"sources":["../src/useAgUiRuntime.ts"],"mappings":";;;;KAwBY,oBAAA,GAAuB,gBAAA;EACjC,6BAAA,iBAA8C,aAAA;EAC9C,iCAAA,GACE,SAAA,WAAoB,eAAA,OACjB,OAAA;AAAA;AAAA,iBAGS,cAAA,CACd,OAAA,EAAS,qBAAA,GACR,oBAAoB"}
@@ -2,7 +2,7 @@
2
2
  import { makeLogger } from "./runtime/logger.js";
3
3
  import { AgUiThreadRuntimeCore } from "./runtime/AgUiThreadRuntimeCore.js";
4
4
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
5
- import { useExternalStoreRuntime, useRuntimeAdapters } from "@assistant-ui/core/react";
5
+ import { useExternalStoreRuntime, useExternalStoreSharedOptions, useRuntimeAdapters } from "@assistant-ui/core/react";
6
6
  //#region src/useAgUiRuntime.ts
7
7
  function useAgUiRuntime(options) {
8
8
  const logger = useMemo(() => makeLogger(options.logger), [options.logger]);
@@ -53,6 +53,7 @@ function useAgUiRuntime(options) {
53
53
  attachments: adapters?.attachments ?? runtimeAdapters?.attachments,
54
54
  speech: adapters?.speech,
55
55
  dictation: adapters?.dictation,
56
+ voice: adapters?.voice,
56
57
  feedback: adapters?.feedback,
57
58
  threadList
58
59
  }), [
@@ -60,8 +61,10 @@ function useAgUiRuntime(options) {
60
61
  runtimeAdapters,
61
62
  threadList
62
63
  ]);
64
+ const shared = useExternalStoreSharedOptions(options);
63
65
  const baseRuntime = useExternalStoreRuntime(useMemo(() => {
64
66
  return {
67
+ ...shared,
65
68
  isLoading: core.isLoading,
66
69
  messages: core.getMessages(),
67
70
  state: core.getState(),
@@ -85,7 +88,8 @@ function useAgUiRuntime(options) {
85
88
  adapterAdapters,
86
89
  core,
87
90
  _version,
88
- hasExecutingTools
91
+ hasExecutingTools,
92
+ shared
89
93
  ]));
90
94
  const runtime = useMemo(() => {
91
95
  const wrapper = Object.create(baseRuntime);
@@ -1 +1 @@
1
- {"version":3,"file":"useAgUiRuntime.js","names":[],"sources":["../src/useAgUiRuntime.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useExternalStoreRuntime,\n useRuntimeAdapters,\n} from \"@assistant-ui/core/react\";\nimport type { ToolExecutionStatus } from \"@assistant-ui/core\";\nimport type {\n AssistantRuntime,\n AppendMessage,\n ExternalStoreAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { makeLogger } from \"./runtime/logger\";\nimport type {\n AgUiInterrupt,\n AgUiResumeEntry,\n UseAgUiRuntimeOptions,\n} from \"./runtime/types\";\nimport { AgUiThreadRuntimeCore } from \"./runtime/AgUiThreadRuntimeCore\";\n\nexport type AgUiAssistantRuntime = AssistantRuntime & {\n unstable_getPendingInterrupts: () => readonly AgUiInterrupt[];\n unstable_submitInterruptResponses: (\n responses: readonly AgUiResumeEntry[],\n ) => Promise<void>;\n};\n\nexport function useAgUiRuntime(\n options: UseAgUiRuntimeOptions,\n): AgUiAssistantRuntime {\n const logger = useMemo(() => makeLogger(options.logger), [options.logger]);\n const [_version, setVersion] = useState(0);\n const notifyUpdate = useCallback(() => setVersion((v) => v + 1), []);\n const coreRef = useRef<AgUiThreadRuntimeCore | null>(null);\n const runtimeAdapters = useRuntimeAdapters();\n\n const historyAdapter = options.adapters?.history ?? runtimeAdapters?.history;\n const threadListAdapter = options.adapters?.threadList;\n\n if (!coreRef.current) {\n coreRef.current = new AgUiThreadRuntimeCore({\n agent: options.agent,\n logger,\n showThinking: options.showThinking ?? true,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(historyAdapter && { history: historyAdapter }),\n notifyUpdate,\n });\n }\n\n const core = coreRef.current;\n core.updateOptions({\n agent: options.agent,\n logger,\n showThinking: options.showThinking ?? true,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(historyAdapter && { history: historyAdapter }),\n });\n\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n\n const hasExecutingTools = Object.values(toolStatuses).some(\n (s) => s?.type === \"executing\",\n );\n\n const threadList = useMemo(() => {\n if (!threadListAdapter) return undefined;\n\n const { onSwitchToNewThread, onSwitchToThread } = threadListAdapter;\n\n return {\n threadId: threadListAdapter.threadId,\n onSwitchToNewThread: onSwitchToNewThread\n ? async () => {\n await onSwitchToNewThread();\n core.applyExternalMessages([]);\n }\n : undefined,\n onSwitchToThread: onSwitchToThread\n ? async (threadId: string) => {\n const result = await onSwitchToThread(threadId);\n core.applyExternalMessages(result.messages);\n if (result.state) {\n core.loadExternalState(result.state);\n }\n }\n : undefined,\n };\n }, [threadListAdapter, core]);\n\n const adapters = options.adapters;\n const adapterAdapters = useMemo(\n () => ({\n attachments: adapters?.attachments ?? runtimeAdapters?.attachments,\n speech: adapters?.speech,\n dictation: adapters?.dictation,\n feedback: adapters?.feedback,\n threadList,\n }),\n [adapters, runtimeAdapters, threadList],\n );\n\n const store = useMemo(\n () => {\n void _version; // rerender on version change\n\n return {\n isLoading: core.isLoading,\n messages: core.getMessages(),\n state: core.getState(),\n isRunning: core.isRunning() || hasExecutingTools,\n unstable_enableToolInvocations: true,\n setToolStatuses,\n onNew: (message: AppendMessage) => core.append(message),\n onEdit: (message: AppendMessage) => core.edit(message),\n onReload: (parentId: string | null, config: { runConfig?: any }) =>\n core.reload(parentId, config),\n onCancel: async () => {\n core.cancel();\n },\n onAddToolResult: (options) => core.addToolResult(options),\n onResume: (config) => core.resume(config),\n setMessages: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onImport: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onLoadExternalState: (state: ReadonlyJSONValue) =>\n core.loadExternalState(state),\n adapters: adapterAdapters,\n } satisfies ExternalStoreAdapter<ThreadMessage>;\n },\n // _version is intentionally included to trigger re-computation when core state changes via notifyUpdate\n // toolInvocations intentionally excluded: abort/resume use refs internally and work with stale captures\n [adapterAdapters, core, _version, hasExecutingTools],\n );\n\n const baseRuntime = useExternalStoreRuntime(store);\n\n const runtime = useMemo<AgUiAssistantRuntime>(() => {\n const wrapper = Object.create(baseRuntime) as AgUiAssistantRuntime;\n wrapper.unstable_getPendingInterrupts = () =>\n core.getPendingInterrupts()?.interrupts ?? [];\n wrapper.unstable_submitInterruptResponses = (responses) =>\n core.submitInterruptResponses(responses);\n return wrapper;\n }, [baseRuntime, core]);\n\n useEffect(() => {\n core.attachRuntime(runtime);\n return () => {\n core.detachRuntime();\n };\n }, [core, runtime]);\n\n useEffect(() => {\n core.__internal_load();\n }, [core]);\n\n return runtime;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useAgUiRuntime.js","names":[],"sources":["../src/useAgUiRuntime.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n useExternalStoreRuntime,\n useExternalStoreSharedOptions,\n useRuntimeAdapters,\n} from \"@assistant-ui/core/react\";\nimport type { ToolExecutionStatus } from \"@assistant-ui/core\";\nimport type {\n AssistantRuntime,\n AppendMessage,\n ExternalStoreAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { makeLogger } from \"./runtime/logger\";\nimport type {\n AgUiInterrupt,\n AgUiResumeEntry,\n UseAgUiRuntimeOptions,\n} from \"./runtime/types\";\nimport { AgUiThreadRuntimeCore } from \"./runtime/AgUiThreadRuntimeCore\";\n\nexport type AgUiAssistantRuntime = AssistantRuntime & {\n unstable_getPendingInterrupts: () => readonly AgUiInterrupt[];\n unstable_submitInterruptResponses: (\n responses: readonly AgUiResumeEntry[],\n ) => Promise<void>;\n};\n\nexport function useAgUiRuntime(\n options: UseAgUiRuntimeOptions,\n): AgUiAssistantRuntime {\n const logger = useMemo(() => makeLogger(options.logger), [options.logger]);\n const [_version, setVersion] = useState(0);\n const notifyUpdate = useCallback(() => setVersion((v) => v + 1), []);\n const coreRef = useRef<AgUiThreadRuntimeCore | null>(null);\n const runtimeAdapters = useRuntimeAdapters();\n\n const historyAdapter = options.adapters?.history ?? runtimeAdapters?.history;\n const threadListAdapter = options.adapters?.threadList;\n\n if (!coreRef.current) {\n coreRef.current = new AgUiThreadRuntimeCore({\n agent: options.agent,\n logger,\n showThinking: options.showThinking ?? true,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(historyAdapter && { history: historyAdapter }),\n notifyUpdate,\n });\n }\n\n const core = coreRef.current;\n core.updateOptions({\n agent: options.agent,\n logger,\n showThinking: options.showThinking ?? true,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(historyAdapter && { history: historyAdapter }),\n });\n\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n\n const hasExecutingTools = Object.values(toolStatuses).some(\n (s) => s?.type === \"executing\",\n );\n\n const threadList = useMemo(() => {\n if (!threadListAdapter) return undefined;\n\n const { onSwitchToNewThread, onSwitchToThread } = threadListAdapter;\n\n return {\n threadId: threadListAdapter.threadId,\n onSwitchToNewThread: onSwitchToNewThread\n ? async () => {\n await onSwitchToNewThread();\n core.applyExternalMessages([]);\n }\n : undefined,\n onSwitchToThread: onSwitchToThread\n ? async (threadId: string) => {\n const result = await onSwitchToThread(threadId);\n core.applyExternalMessages(result.messages);\n if (result.state) {\n core.loadExternalState(result.state);\n }\n }\n : undefined,\n };\n }, [threadListAdapter, core]);\n\n const adapters = options.adapters;\n const adapterAdapters = useMemo(\n () => ({\n attachments: adapters?.attachments ?? runtimeAdapters?.attachments,\n speech: adapters?.speech,\n dictation: adapters?.dictation,\n voice: adapters?.voice,\n feedback: adapters?.feedback,\n threadList,\n }),\n [adapters, runtimeAdapters, threadList],\n );\n\n const shared = useExternalStoreSharedOptions(options);\n const store = useMemo(\n () => {\n void _version; // rerender on version change\n\n return {\n ...shared,\n isLoading: core.isLoading,\n messages: core.getMessages(),\n state: core.getState(),\n isRunning: core.isRunning() || hasExecutingTools,\n unstable_enableToolInvocations: true,\n setToolStatuses,\n onNew: (message: AppendMessage) => core.append(message),\n onEdit: (message: AppendMessage) => core.edit(message),\n onReload: (parentId: string | null, config: { runConfig?: any }) =>\n core.reload(parentId, config),\n onCancel: async () => {\n core.cancel();\n },\n onAddToolResult: (options) => core.addToolResult(options),\n onResume: (config) => core.resume(config),\n setMessages: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onImport: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onLoadExternalState: (state: ReadonlyJSONValue) =>\n core.loadExternalState(state),\n adapters: adapterAdapters,\n } satisfies ExternalStoreAdapter<ThreadMessage>;\n },\n // _version is intentionally included to trigger re-computation when core state changes via notifyUpdate\n // toolInvocations intentionally excluded: abort/resume use refs internally and work with stale captures\n [adapterAdapters, core, _version, hasExecutingTools, shared],\n );\n\n const baseRuntime = useExternalStoreRuntime(store);\n\n const runtime = useMemo<AgUiAssistantRuntime>(() => {\n const wrapper = Object.create(baseRuntime) as AgUiAssistantRuntime;\n wrapper.unstable_getPendingInterrupts = () =>\n core.getPendingInterrupts()?.interrupts ?? [];\n wrapper.unstable_submitInterruptResponses = (responses) =>\n core.submitInterruptResponses(responses);\n return wrapper;\n }, [baseRuntime, core]);\n\n useEffect(() => {\n core.attachRuntime(runtime);\n return () => {\n core.detachRuntime();\n };\n }, [core, runtime]);\n\n useEffect(() => {\n core.__internal_load();\n }, [core]);\n\n return runtime;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-ag-ui",
3
- "version": "0.0.33",
3
+ "version": "0.0.34",
4
4
  "description": "AG-UI protocol adapter for assistant-ui",
5
5
  "keywords": [
6
6
  "ag-ui",
@@ -29,9 +29,9 @@
29
29
  ],
30
30
  "sideEffects": false,
31
31
  "dependencies": {
32
- "@ag-ui/client": "^0.0.53",
33
- "@assistant-ui/core": "^0.2.5",
34
- "assistant-stream": "^0.3.16"
32
+ "@ag-ui/client": "^0.0.54",
33
+ "@assistant-ui/core": "^0.2.8",
34
+ "assistant-stream": "^0.3.18"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@types/react": "*",
@@ -47,7 +47,7 @@
47
47
  "react": "^19.2.6",
48
48
  "vitest": "^4.1.7",
49
49
  "zod": "^4.4.3",
50
- "@assistant-ui/x-buildutils": "0.0.9"
50
+ "@assistant-ui/x-buildutils": "0.0.10"
51
51
  },
52
52
  "publishConfig": {
53
53
  "access": "public",
@@ -1,11 +1,6 @@
1
1
  "use client";
2
2
 
3
- import {
4
- generateId,
5
- generateOptimisticId,
6
- isOptimisticId,
7
- fromThreadMessageLike,
8
- } from "@assistant-ui/core/internal";
3
+ import { generateId, fromThreadMessageLike } from "@assistant-ui/core/internal";
9
4
  import type {
10
5
  AddToolResultOptions,
11
6
  AppendMessage,
@@ -32,6 +27,10 @@ import {
32
27
  } from "./adapter/conversions";
33
28
  import { createAgUiSubscriber } from "./adapter/subscriber";
34
29
 
30
+ const optimisticPrefix = "__optimistic__";
31
+ const generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
32
+ const isOptimisticId = (id: string) => id.startsWith(optimisticPrefix);
33
+
35
34
  const symbolResumeShim = Symbol("agui-resume-shim");
36
35
 
37
36
  type RunConfig = NonNullable<AppendMessage["runConfig"]>;
@@ -1,7 +1,9 @@
1
1
  import type {
2
2
  AttachmentAdapter,
3
3
  DictationAdapter,
4
+ ExternalStoreSharedOptions,
4
5
  FeedbackAdapter,
6
+ RealtimeVoiceAdapter,
5
7
  SpeechSynthesisAdapter,
6
8
  ThreadHistoryAdapter,
7
9
  ThreadMessage,
@@ -30,6 +32,7 @@ export type UseAgUiRuntimeAdapters = {
30
32
  attachments?: AttachmentAdapter;
31
33
  speech?: SpeechSynthesisAdapter;
32
34
  dictation?: DictationAdapter;
35
+ voice?: RealtimeVoiceAdapter;
33
36
  feedback?: FeedbackAdapter;
34
37
  history?: ThreadHistoryAdapter;
35
38
  /**
@@ -38,7 +41,7 @@ export type UseAgUiRuntimeAdapters = {
38
41
  threadList?: UseAgUiThreadListAdapter;
39
42
  };
40
43
 
41
- export type UseAgUiRuntimeOptions = {
44
+ export type UseAgUiRuntimeOptions = ExternalStoreSharedOptions & {
42
45
  agent: HttpAgent;
43
46
  logger?: Partial<Logger>;
44
47
  showThinking?: boolean;
@@ -3,6 +3,7 @@
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
4
  import {
5
5
  useExternalStoreRuntime,
6
+ useExternalStoreSharedOptions,
6
7
  useRuntimeAdapters,
7
8
  } from "@assistant-ui/core/react";
8
9
  import type { ToolExecutionStatus } from "@assistant-ui/core";
@@ -101,17 +102,20 @@ export function useAgUiRuntime(
101
102
  attachments: adapters?.attachments ?? runtimeAdapters?.attachments,
102
103
  speech: adapters?.speech,
103
104
  dictation: adapters?.dictation,
105
+ voice: adapters?.voice,
104
106
  feedback: adapters?.feedback,
105
107
  threadList,
106
108
  }),
107
109
  [adapters, runtimeAdapters, threadList],
108
110
  );
109
111
 
112
+ const shared = useExternalStoreSharedOptions(options);
110
113
  const store = useMemo(
111
114
  () => {
112
115
  void _version; // rerender on version change
113
116
 
114
117
  return {
118
+ ...shared,
115
119
  isLoading: core.isLoading,
116
120
  messages: core.getMessages(),
117
121
  state: core.getState(),
@@ -138,7 +142,7 @@ export function useAgUiRuntime(
138
142
  },
139
143
  // _version is intentionally included to trigger re-computation when core state changes via notifyUpdate
140
144
  // toolInvocations intentionally excluded: abort/resume use refs internally and work with stale captures
141
- [adapterAdapters, core, _version, hasExecutingTools],
145
+ [adapterAdapters, core, _version, hasExecutingTools, shared],
142
146
  );
143
147
 
144
148
  const baseRuntime = useExternalStoreRuntime(store);