@assistant-ui/core 0.3.8 → 0.3.10

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.
Files changed (37) hide show
  1. package/dist/model-context/frame/provider.js +1 -3
  2. package/dist/model-context/frame/provider.js.map +1 -1
  3. package/dist/model-context/types.js +4 -2
  4. package/dist/model-context/types.js.map +1 -1
  5. package/dist/react/AssistantProvider.js +5 -4
  6. package/dist/react/AssistantProvider.js.map +1 -1
  7. package/dist/react/adapters/LocalStorageThreadListAdapter.js +2 -1
  8. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  9. package/dist/react/client/Interactables.js +12 -10
  10. package/dist/react/client/Interactables.js.map +1 -1
  11. package/dist/react/model-context/useInteractable.js.map +1 -1
  12. package/dist/react/primitives/message/MessageGroupedParts.js +11 -8
  13. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  14. package/dist/react/primitives/message/MessageParts.js +27 -22
  15. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  16. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +5 -4
  17. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  18. package/dist/react/runtimes/external-message-converter.js +3 -1
  19. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  20. package/dist/react/runtimes/useLocalRuntime.js +2 -1
  21. package/dist/react/runtimes/useLocalRuntime.js.map +1 -1
  22. package/dist/runtime/api/message-runtime.js +4 -2
  23. package/dist/runtime/api/message-runtime.js.map +1 -1
  24. package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -1
  25. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  26. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +9 -5
  27. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  28. package/dist/runtimes/local/local-thread-runtime-core.js +9 -6
  29. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  30. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +31 -28
  31. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  32. package/dist/subscribable/subscribable.js +6 -4
  33. package/dist/subscribable/subscribable.js.map +1 -1
  34. package/package.json +10 -10
  35. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +5 -1
  36. package/src/runtimes/local/local-thread-runtime-core.test.ts +18 -22
  37. package/src/tests/external-store-thread-runtime-core.test.ts +36 -0
@@ -1 +1 @@
1
- {"version":3,"file":"external-message-converter.js","names":["c","_c","useMemo","useState","ThreadMessageConverter","getExternalStoreMessages","symbolInnerMessage","bindExternalStoreMessage","fromThreadMessageLike","ThreadMessageLike","getAutoStatus","isAutoStatus","ToolExecutionStatus","ReadonlyJSONValue","generateErrorMessageId","ThreadAssistantMessage","ThreadMessage","ToolCallMessagePart","MessageTiming","JoinStrategy","ThreadMessageLikeContentItem","Exclude","isPendingToolCall","type","result","undefined","isInterruptedToolCall","interrupt","approval","approved","resolution","useExternalMessageConverter","Message","convertConfig","joinStrategy","role","toolCallId","toolName","artifact","isError","messages","Metadata","toolStatuses","Record","error","messageTiming","Callback","message","T","metadata","CallbackResult","input","outputs","CallbackCacheEntry","callback","ChunkResult","inputs","Mutable","P","mergeInnerMessages","existing","incoming","joinExternalMessages","assistantMessage","Omit","content","output","toolCallIdx","findIndex","toolCall","Error","const","text","map","length","id","createdAt","status","attachments","unstable_state","unstable_annotations","unstable_data","steps","custom","timing","submittedFeedback","isOptimistic","part","existingIdx","parentId","push","unsupportedRole","chunkExternalMessages","callbackResults","results","isAssistant","pendingNone","flush","callbackResult","at","createErrorAssistantMessage","msg","reason","Date","convertExternalMessages","WeakKey","isRunning","Array","isArray","chunks","idx","isLast","joined","hasInterruptedToolCalls","some","hasPendingToolCalls","autoStatus","newMessage","toString","lastMessage","t0","$","caches","_temp","t1","t2","state","threadMessages","callbackCache","get","set","t3","chunkCache","m","key","cached","shallowArrayEqual","converterCache","convertMessages","cache","message_0","a","b","i","WeakMap"],"sources":["../../../src/react/runtimes/external-message-converter.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport { ThreadMessageConverter } from \"../../runtimes/external-store/thread-message-converter\";\nimport {\n getExternalStoreMessages,\n symbolInnerMessage,\n bindExternalStoreMessage,\n} from \"../../runtime/utils/external-store-message\";\nimport {\n fromThreadMessageLike,\n type ThreadMessageLike,\n} from \"../../runtime/utils/thread-message-like\";\nimport { getAutoStatus, isAutoStatus } from \"../../runtime/utils/auto-status\";\nimport type { ToolExecutionStatus } from \"../../runtimes/tool-invocations/ToolInvocationTracker\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { generateErrorMessageId } from \"../../utils/id\";\nimport type {\n ThreadAssistantMessage,\n ThreadMessage,\n ToolCallMessagePart,\n} from \"../../types/message\";\nimport type { MessageTiming } from \"../../types/message\";\n\nexport type JoinStrategy = \"concat-content\" | \"none\";\n\ntype ThreadMessageLikeContentItem = Exclude<\n ThreadMessageLike[\"content\"],\n string\n>[number];\n\nconst isPendingToolCall = (c: ThreadMessageLikeContentItem): boolean =>\n c.type === \"tool-call\" && c.result === undefined;\n\nconst isInterruptedToolCall = (c: ThreadMessageLikeContentItem): boolean => {\n if (c.type !== \"tool-call\" || c.result !== undefined) return false;\n return (\n c.interrupt != null ||\n (c.approval != null &&\n c.approval.approved === undefined &&\n c.approval.resolution === undefined)\n );\n};\n\nexport namespace useExternalMessageConverter {\n export type Message =\n | (ThreadMessageLike & {\n readonly convertConfig?: {\n readonly joinStrategy?: JoinStrategy;\n };\n })\n | {\n role: \"tool\";\n toolCallId: string;\n toolName?: string | undefined;\n result: any;\n artifact?: any;\n isError?: boolean;\n messages?: readonly ThreadMessage[];\n };\n\n export type Metadata = {\n readonly toolStatuses?: Record<string, ToolExecutionStatus>;\n readonly error?: ReadonlyJSONValue;\n readonly messageTiming?: Record<string, MessageTiming>;\n };\n\n export type Callback<T> = (\n message: T,\n metadata: Metadata,\n ) => Message | Message[];\n}\n\ntype CallbackResult<T> = {\n input: T;\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype CallbackCacheEntry<T> = CallbackResult<T> & {\n metadata: useExternalMessageConverter.Metadata;\n callback: useExternalMessageConverter.Callback<T>;\n};\n\ntype ChunkResult<T> = {\n inputs: T[];\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nconst mergeInnerMessages = (existing: object, incoming: object) => ({\n [symbolInnerMessage]: [\n ...((existing as any)[symbolInnerMessage] ?? []),\n ...((incoming as any)[symbolInnerMessage] ?? []),\n ],\n});\n\nconst joinExternalMessages = (\n messages: readonly useExternalMessageConverter.Message[],\n): ThreadMessageLike => {\n const assistantMessage: Mutable<Omit<ThreadMessageLike, \"metadata\">> & {\n content: Exclude<ThreadMessageLike[\"content\"][0], string>[];\n metadata?: Mutable<ThreadMessageLike[\"metadata\"]>;\n } = {\n role: \"assistant\",\n content: [],\n };\n for (const output of messages) {\n if (output.role === \"tool\") {\n const toolCallIdx = assistantMessage.content.findIndex(\n (c) => c.type === \"tool-call\" && c.toolCallId === output.toolCallId,\n );\n // Ignore orphaned tool results so one bad tool message does not\n // prevent rendering the rest of the conversation.\n if (toolCallIdx !== -1) {\n const toolCall = assistantMessage.content[\n toolCallIdx\n ]! as ToolCallMessagePart;\n if (output.toolName != null) {\n if (toolCall.toolName !== output.toolName)\n throw new Error(\n `Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`,\n );\n }\n assistantMessage.content[toolCallIdx] = {\n ...toolCall,\n ...{\n [symbolInnerMessage]: [\n ...((toolCall as any)[symbolInnerMessage] ?? []),\n output,\n ],\n },\n result: output.result,\n artifact: output.artifact,\n isError: output.isError,\n messages: output.messages,\n };\n }\n } else {\n const role = output.role;\n const content = (\n typeof output.content === \"string\"\n ? [{ type: \"text\" as const, text: output.content }]\n : output.content\n ).map((c) => ({\n ...c,\n ...{ [symbolInnerMessage]: [output] },\n }));\n switch (role) {\n case \"system\":\n case \"user\":\n return {\n ...output,\n content,\n };\n case \"assistant\":\n if (assistantMessage.content.length === 0) {\n assistantMessage.id = output.id;\n assistantMessage.createdAt ??= output.createdAt;\n assistantMessage.status ??= output.status;\n\n if (output.attachments) {\n assistantMessage.attachments = [\n ...(assistantMessage.attachments ?? []),\n ...output.attachments,\n ];\n }\n\n if (output.metadata) {\n assistantMessage.metadata ??= {};\n if (output.metadata.unstable_state !== undefined) {\n assistantMessage.metadata.unstable_state =\n output.metadata.unstable_state;\n }\n if (output.metadata.unstable_annotations) {\n assistantMessage.metadata.unstable_annotations = [\n ...(assistantMessage.metadata.unstable_annotations ?? []),\n ...output.metadata.unstable_annotations,\n ];\n }\n if (output.metadata.unstable_data) {\n assistantMessage.metadata.unstable_data = [\n ...(assistantMessage.metadata.unstable_data ?? []),\n ...output.metadata.unstable_data,\n ];\n }\n if (output.metadata.steps) {\n assistantMessage.metadata.steps = [\n ...(assistantMessage.metadata.steps ?? []),\n ...output.metadata.steps,\n ];\n }\n if (output.metadata.custom) {\n assistantMessage.metadata.custom = {\n ...(assistantMessage.metadata.custom ?? {}),\n ...output.metadata.custom,\n };\n }\n\n if (output.metadata.timing) {\n assistantMessage.metadata.timing = output.metadata.timing;\n }\n\n if (output.metadata.submittedFeedback) {\n assistantMessage.metadata.submittedFeedback =\n output.metadata.submittedFeedback;\n }\n\n if (output.metadata.isOptimistic) {\n assistantMessage.metadata.isOptimistic = true;\n }\n }\n // TODO keep this in sync\n }\n\n // Add content parts, merging reasoning parts with same parentId\n for (const part of content) {\n if (part.type === \"tool-call\") {\n const existingIdx = assistantMessage.content.findIndex(\n (c) =>\n c.type === \"tool-call\" && c.toolCallId === part.toolCallId,\n );\n if (existingIdx !== -1) {\n const existing = assistantMessage.content[\n existingIdx\n ] as typeof part;\n assistantMessage.content[existingIdx] = {\n ...existing,\n ...part,\n ...mergeInnerMessages(existing, part),\n };\n continue;\n }\n }\n\n if (\n part.type === \"reasoning\" &&\n \"parentId\" in part &&\n part.parentId\n ) {\n const existingIdx = assistantMessage.content.findIndex(\n (c) =>\n c.type === \"reasoning\" &&\n \"parentId\" in c &&\n c.parentId === part.parentId,\n );\n if (existingIdx !== -1) {\n const existing = assistantMessage.content[\n existingIdx\n ] as typeof part;\n assistantMessage.content[existingIdx] = {\n ...existing,\n text: `${existing.text}\\n\\n${part.text}`,\n ...mergeInnerMessages(existing, part),\n };\n continue;\n }\n }\n assistantMessage.content.push(part);\n }\n break;\n default: {\n const unsupportedRole: never = role;\n throw new Error(`Unknown message role: ${unsupportedRole}`);\n }\n }\n }\n }\n return assistantMessage;\n};\n\nconst chunkExternalMessages = <T>(\n callbackResults: CallbackResult<T>[],\n joinStrategy?: JoinStrategy,\n) => {\n const results: ChunkResult<T>[] = [];\n let isAssistant = false;\n let pendingNone = false; // true if the previous assistant message had joinStrategy \"none\"\n let inputs: T[] = [];\n let outputs: useExternalMessageConverter.Message[] = [];\n\n const flush = () => {\n if (outputs.length) {\n results.push({\n inputs,\n outputs,\n });\n }\n inputs = [];\n outputs = [];\n isAssistant = false;\n pendingNone = false;\n };\n\n for (const callbackResult of callbackResults) {\n for (const output of callbackResult.outputs) {\n if (\n (pendingNone && output.role !== \"tool\") ||\n !isAssistant ||\n output.role === \"user\" ||\n output.role === \"system\"\n ) {\n flush();\n }\n isAssistant = output.role === \"assistant\" || output.role === \"tool\";\n\n if (inputs.at(-1) !== callbackResult.input) {\n inputs.push(callbackResult.input);\n }\n outputs.push(output);\n\n if (\n output.role === \"assistant\" &&\n (output.convertConfig?.joinStrategy === \"none\" ||\n joinStrategy === \"none\")\n ) {\n pendingNone = true;\n }\n }\n }\n flush();\n return results;\n};\n\nfunction createErrorAssistantMessage(\n error: ReadonlyJSONValue,\n): ThreadAssistantMessage {\n const msg: ThreadAssistantMessage = {\n id: generateErrorMessageId(),\n role: \"assistant\",\n content: [],\n status: { type: \"incomplete\", reason: \"error\", error },\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n custom: {},\n steps: [],\n },\n };\n bindExternalStoreMessage(msg, []);\n return msg;\n}\n\nexport const convertExternalMessages = <T extends WeakKey>(\n messages: T[],\n callback: useExternalMessageConverter.Callback<T>,\n isRunning: boolean,\n metadata: useExternalMessageConverter.Metadata,\n) => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n const output = callback(message, metadata);\n const outputs = Array.isArray(output) ? output : [output];\n const result = { input: message, outputs };\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults);\n\n const result = chunks.map((message, idx) => {\n const isLast = idx === chunks.length - 1;\n const joined = joinExternalMessages(message.outputs);\n const hasInterruptedToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isInterruptedToolCall);\n const hasPendingToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isPendingToolCall);\n const autoStatus = getAutoStatus(\n isLast,\n isRunning,\n hasInterruptedToolCalls,\n hasPendingToolCalls,\n isLast ? metadata.error : undefined,\n );\n const newMessage = fromThreadMessageLike(\n joined,\n idx.toString(),\n autoStatus,\n );\n bindExternalStoreMessage(newMessage, message.inputs);\n return newMessage;\n });\n\n if (metadata.error) {\n const lastMessage = result.at(-1);\n if (!lastMessage || lastMessage.role !== \"assistant\") {\n result.push(createErrorAssistantMessage(metadata.error));\n }\n }\n\n return result;\n};\n\nexport const useExternalMessageConverter = <T extends WeakKey>({\n callback,\n messages,\n isRunning,\n joinStrategy,\n metadata,\n}: {\n callback: useExternalMessageConverter.Callback<T>;\n messages: T[];\n isRunning: boolean;\n joinStrategy?: JoinStrategy | undefined;\n metadata?: useExternalMessageConverter.Metadata | undefined;\n}) => {\n // The caches live for the component lifetime; React Compiler hoists\n // allocations without reactive dependencies out of useMemo, so re-creating\n // them on dependency change would not survive compilation. Staleness is\n // instead tracked per entry via the metadata/callback that produced it,\n // keeping correctness independent of memoization (which React treats as\n // droppable). A \"use no memo\" opt-out would restore the useMemo semantics\n // but leave cache flushing coupled to memo firing.\n const [caches] = useState(() => ({\n callbackCache: new WeakMap<T, CallbackCacheEntry<T>>(),\n chunkCache: new WeakMap<\n useExternalMessageConverter.Message,\n ChunkResult<T>\n >(),\n converterCache: new ThreadMessageConverter(),\n }));\n\n const state = useMemo(\n () => ({\n metadata: metadata ?? {},\n callback,\n ...caches,\n }),\n [callback, metadata, caches],\n );\n\n return useMemo(() => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n let result = state.callbackCache.get(message);\n if (\n !result ||\n result.metadata !== state.metadata ||\n result.callback !== state.callback\n ) {\n const output = state.callback(message, state.metadata);\n const outputs = Array.isArray(output) ? output : [output];\n result = {\n input: message,\n outputs,\n metadata: state.metadata,\n callback: state.callback,\n };\n state.callbackCache.set(message, result);\n }\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults, joinStrategy).map(\n (m) => {\n const key = m.outputs[0];\n if (!key) return m;\n\n const cached = state.chunkCache.get(key);\n if (cached && shallowArrayEqual(cached.outputs, m.outputs))\n return cached;\n state.chunkCache.set(key, m);\n return m;\n },\n );\n\n const threadMessages = state.converterCache.convertMessages(\n chunks,\n (cache, message, idx) => {\n const isLast = idx === chunks.length - 1;\n\n const joined = joinExternalMessages(message.outputs);\n const hasInterruptedToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isInterruptedToolCall);\n const hasPendingToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isPendingToolCall);\n const autoStatus = getAutoStatus(\n isLast,\n isRunning,\n hasInterruptedToolCalls,\n hasPendingToolCalls,\n isLast ? state.metadata.error : undefined,\n );\n\n if (\n cache &&\n (cache.role !== \"assistant\" ||\n !isAutoStatus(cache.status) ||\n cache.status === autoStatus)\n ) {\n const inputs = getExternalStoreMessages<T>(cache);\n if (shallowArrayEqual(inputs, message.inputs)) {\n return cache;\n }\n }\n\n const newMessage = fromThreadMessageLike(\n joined,\n idx.toString(),\n autoStatus,\n );\n bindExternalStoreMessage(newMessage, message.inputs);\n return newMessage;\n },\n );\n\n bindExternalStoreMessage(threadMessages, messages);\n\n if (state.metadata.error) {\n const lastMessage = threadMessages.at(-1);\n if (!lastMessage || lastMessage.role !== \"assistant\") {\n threadMessages.push(createErrorAssistantMessage(state.metadata.error));\n }\n }\n\n return threadMessages;\n }, [state, messages, isRunning, joinStrategy]);\n};\n\nconst shallowArrayEqual = (a: unknown[], b: unknown[]) => {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"external-message-converter.js","names":["c","_c","useMemo","useState","ThreadMessageConverter","getExternalStoreMessages","symbolInnerMessage","bindExternalStoreMessage","fromThreadMessageLike","ThreadMessageLike","getAutoStatus","isAutoStatus","ToolExecutionStatus","ReadonlyJSONValue","generateErrorMessageId","ThreadAssistantMessage","ThreadMessage","ToolCallMessagePart","MessageTiming","JoinStrategy","ThreadMessageLikeContentItem","Exclude","isPendingToolCall","type","result","undefined","isInterruptedToolCall","interrupt","approval","approved","resolution","useExternalMessageConverter","Message","convertConfig","joinStrategy","role","toolCallId","toolName","artifact","isError","messages","Metadata","toolStatuses","Record","error","messageTiming","Callback","message","T","metadata","CallbackResult","input","outputs","CallbackCacheEntry","callback","ChunkResult","inputs","Mutable","P","mergeInnerMessages","existing","incoming","joinExternalMessages","assistantMessage","Omit","content","output","toolCallIdx","findIndex","toolCall","Error","const","text","map","length","id","createdAt","status","attachments","unstable_state","unstable_annotations","unstable_data","steps","custom","timing","submittedFeedback","isOptimistic","part","existingIdx","parentId","push","unsupportedRole","chunkExternalMessages","callbackResults","results","isAssistant","pendingNone","flush","callbackResult","at","createErrorAssistantMessage","msg","reason","Date","convertExternalMessages","WeakKey","isRunning","Array","isArray","chunks","idx","isLast","joined","hasInterruptedToolCalls","some","hasPendingToolCalls","autoStatus","newMessage","toString","lastMessage","t0","$","caches","_temp","t1","t2","state","threadMessages","callbackCache","get","set","t3","chunkCache","m","key","cached","shallowArrayEqual","converterCache","convertMessages","cache","message_0","a","b","i","WeakMap"],"sources":["../../../src/react/runtimes/external-message-converter.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport { ThreadMessageConverter } from \"../../runtimes/external-store/thread-message-converter\";\nimport {\n getExternalStoreMessages,\n symbolInnerMessage,\n bindExternalStoreMessage,\n} from \"../../runtime/utils/external-store-message\";\nimport {\n fromThreadMessageLike,\n type ThreadMessageLike,\n} from \"../../runtime/utils/thread-message-like\";\nimport { getAutoStatus, isAutoStatus } from \"../../runtime/utils/auto-status\";\nimport type { ToolExecutionStatus } from \"../../runtimes/tool-invocations/ToolInvocationTracker\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { generateErrorMessageId } from \"../../utils/id\";\nimport type {\n ThreadAssistantMessage,\n ThreadMessage,\n ToolCallMessagePart,\n} from \"../../types/message\";\nimport type { MessageTiming } from \"../../types/message\";\n\nexport type JoinStrategy = \"concat-content\" | \"none\";\n\ntype ThreadMessageLikeContentItem = Exclude<\n ThreadMessageLike[\"content\"],\n string\n>[number];\n\nconst isPendingToolCall = (c: ThreadMessageLikeContentItem): boolean =>\n c.type === \"tool-call\" && c.result === undefined;\n\nconst isInterruptedToolCall = (c: ThreadMessageLikeContentItem): boolean => {\n if (c.type !== \"tool-call\" || c.result !== undefined) return false;\n return (\n c.interrupt != null ||\n (c.approval != null &&\n c.approval.approved === undefined &&\n c.approval.resolution === undefined)\n );\n};\n\nexport namespace useExternalMessageConverter {\n export type Message =\n | (ThreadMessageLike & {\n readonly convertConfig?: {\n readonly joinStrategy?: JoinStrategy;\n };\n })\n | {\n role: \"tool\";\n toolCallId: string;\n toolName?: string | undefined;\n result: any;\n artifact?: any;\n isError?: boolean;\n messages?: readonly ThreadMessage[];\n };\n\n export type Metadata = {\n readonly toolStatuses?: Record<string, ToolExecutionStatus>;\n readonly error?: ReadonlyJSONValue;\n readonly messageTiming?: Record<string, MessageTiming>;\n };\n\n export type Callback<T> = (\n message: T,\n metadata: Metadata,\n ) => Message | Message[];\n}\n\ntype CallbackResult<T> = {\n input: T;\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype CallbackCacheEntry<T> = CallbackResult<T> & {\n metadata: useExternalMessageConverter.Metadata;\n callback: useExternalMessageConverter.Callback<T>;\n};\n\ntype ChunkResult<T> = {\n inputs: T[];\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nconst mergeInnerMessages = (existing: object, incoming: object) => ({\n [symbolInnerMessage]: [\n ...((existing as any)[symbolInnerMessage] ?? []),\n ...((incoming as any)[symbolInnerMessage] ?? []),\n ],\n});\n\nconst joinExternalMessages = (\n messages: readonly useExternalMessageConverter.Message[],\n): ThreadMessageLike => {\n const assistantMessage: Mutable<Omit<ThreadMessageLike, \"metadata\">> & {\n content: Exclude<ThreadMessageLike[\"content\"][0], string>[];\n metadata?: Mutable<ThreadMessageLike[\"metadata\"]>;\n } = {\n role: \"assistant\",\n content: [],\n };\n for (const output of messages) {\n if (output.role === \"tool\") {\n const toolCallIdx = assistantMessage.content.findIndex(\n (c) => c.type === \"tool-call\" && c.toolCallId === output.toolCallId,\n );\n // Ignore orphaned tool results so one bad tool message does not\n // prevent rendering the rest of the conversation.\n if (toolCallIdx !== -1) {\n const toolCall = assistantMessage.content[\n toolCallIdx\n ]! as ToolCallMessagePart;\n if (output.toolName != null) {\n if (toolCall.toolName !== output.toolName)\n throw new Error(\n `Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`,\n );\n }\n assistantMessage.content[toolCallIdx] = {\n ...toolCall,\n ...{\n [symbolInnerMessage]: [\n ...((toolCall as any)[symbolInnerMessage] ?? []),\n output,\n ],\n },\n result: output.result,\n artifact: output.artifact,\n isError: output.isError,\n messages: output.messages,\n };\n }\n } else {\n const role = output.role;\n const content = (\n typeof output.content === \"string\"\n ? [{ type: \"text\" as const, text: output.content }]\n : output.content\n ).map((c) => ({\n ...c,\n ...{ [symbolInnerMessage]: [output] },\n }));\n switch (role) {\n case \"system\":\n case \"user\":\n return {\n ...output,\n content,\n };\n case \"assistant\":\n if (assistantMessage.content.length === 0) {\n assistantMessage.id = output.id;\n assistantMessage.createdAt ??= output.createdAt;\n assistantMessage.status ??= output.status;\n\n if (output.attachments) {\n assistantMessage.attachments = [\n ...(assistantMessage.attachments ?? []),\n ...output.attachments,\n ];\n }\n\n if (output.metadata) {\n assistantMessage.metadata ??= {};\n if (output.metadata.unstable_state !== undefined) {\n assistantMessage.metadata.unstable_state =\n output.metadata.unstable_state;\n }\n if (output.metadata.unstable_annotations) {\n assistantMessage.metadata.unstable_annotations = [\n ...(assistantMessage.metadata.unstable_annotations ?? []),\n ...output.metadata.unstable_annotations,\n ];\n }\n if (output.metadata.unstable_data) {\n assistantMessage.metadata.unstable_data = [\n ...(assistantMessage.metadata.unstable_data ?? []),\n ...output.metadata.unstable_data,\n ];\n }\n if (output.metadata.steps) {\n assistantMessage.metadata.steps = [\n ...(assistantMessage.metadata.steps ?? []),\n ...output.metadata.steps,\n ];\n }\n if (output.metadata.custom) {\n assistantMessage.metadata.custom = {\n ...(assistantMessage.metadata.custom ?? {}),\n ...output.metadata.custom,\n };\n }\n\n if (output.metadata.timing) {\n assistantMessage.metadata.timing = output.metadata.timing;\n }\n\n if (output.metadata.submittedFeedback) {\n assistantMessage.metadata.submittedFeedback =\n output.metadata.submittedFeedback;\n }\n\n if (output.metadata.isOptimistic) {\n assistantMessage.metadata.isOptimistic = true;\n }\n }\n // TODO keep this in sync\n }\n\n // Add content parts, merging reasoning parts with same parentId\n for (const part of content) {\n if (part.type === \"tool-call\") {\n const existingIdx = assistantMessage.content.findIndex(\n (c) =>\n c.type === \"tool-call\" && c.toolCallId === part.toolCallId,\n );\n if (existingIdx !== -1) {\n const existing = assistantMessage.content[\n existingIdx\n ] as typeof part;\n assistantMessage.content[existingIdx] = {\n ...existing,\n ...part,\n ...mergeInnerMessages(existing, part),\n };\n continue;\n }\n }\n\n if (\n part.type === \"reasoning\" &&\n \"parentId\" in part &&\n part.parentId\n ) {\n const existingIdx = assistantMessage.content.findIndex(\n (c) =>\n c.type === \"reasoning\" &&\n \"parentId\" in c &&\n c.parentId === part.parentId,\n );\n if (existingIdx !== -1) {\n const existing = assistantMessage.content[\n existingIdx\n ] as typeof part;\n assistantMessage.content[existingIdx] = {\n ...existing,\n text: `${existing.text}\\n\\n${part.text}`,\n ...mergeInnerMessages(existing, part),\n };\n continue;\n }\n }\n assistantMessage.content.push(part);\n }\n break;\n default: {\n const unsupportedRole: never = role;\n throw new Error(`Unknown message role: ${unsupportedRole}`);\n }\n }\n }\n }\n return assistantMessage;\n};\n\nconst chunkExternalMessages = <T>(\n callbackResults: CallbackResult<T>[],\n joinStrategy?: JoinStrategy,\n) => {\n const results: ChunkResult<T>[] = [];\n let isAssistant = false;\n let pendingNone = false; // true if the previous assistant message had joinStrategy \"none\"\n let inputs: T[] = [];\n let outputs: useExternalMessageConverter.Message[] = [];\n\n const flush = () => {\n if (outputs.length) {\n results.push({\n inputs,\n outputs,\n });\n }\n inputs = [];\n outputs = [];\n isAssistant = false;\n pendingNone = false;\n };\n\n for (const callbackResult of callbackResults) {\n for (const output of callbackResult.outputs) {\n if (\n (pendingNone && output.role !== \"tool\") ||\n !isAssistant ||\n output.role === \"user\" ||\n output.role === \"system\"\n ) {\n flush();\n }\n isAssistant = output.role === \"assistant\" || output.role === \"tool\";\n\n if (inputs.at(-1) !== callbackResult.input) {\n inputs.push(callbackResult.input);\n }\n outputs.push(output);\n\n if (\n output.role === \"assistant\" &&\n (output.convertConfig?.joinStrategy === \"none\" ||\n joinStrategy === \"none\")\n ) {\n pendingNone = true;\n }\n }\n }\n flush();\n return results;\n};\n\nfunction createErrorAssistantMessage(\n error: ReadonlyJSONValue,\n): ThreadAssistantMessage {\n const msg: ThreadAssistantMessage = {\n id: generateErrorMessageId(),\n role: \"assistant\",\n content: [],\n status: { type: \"incomplete\", reason: \"error\", error },\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n custom: {},\n steps: [],\n },\n };\n bindExternalStoreMessage(msg, []);\n return msg;\n}\n\nexport const convertExternalMessages = <T extends WeakKey>(\n messages: T[],\n callback: useExternalMessageConverter.Callback<T>,\n isRunning: boolean,\n metadata: useExternalMessageConverter.Metadata,\n) => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n const output = callback(message, metadata);\n const outputs = Array.isArray(output) ? output : [output];\n const result = { input: message, outputs };\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults);\n\n const result = chunks.map((message, idx) => {\n const isLast = idx === chunks.length - 1;\n const joined = joinExternalMessages(message.outputs);\n const hasInterruptedToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isInterruptedToolCall);\n const hasPendingToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isPendingToolCall);\n const autoStatus = getAutoStatus(\n isLast,\n isRunning,\n hasInterruptedToolCalls,\n hasPendingToolCalls,\n isLast ? metadata.error : undefined,\n );\n const newMessage = fromThreadMessageLike(\n joined,\n idx.toString(),\n autoStatus,\n );\n bindExternalStoreMessage(newMessage, message.inputs);\n return newMessage;\n });\n\n if (metadata.error) {\n const lastMessage = result.at(-1);\n if (!lastMessage || lastMessage.role !== \"assistant\") {\n result.push(createErrorAssistantMessage(metadata.error));\n }\n }\n\n return result;\n};\n\nexport const useExternalMessageConverter = <T extends WeakKey>({\n callback,\n messages,\n isRunning,\n joinStrategy,\n metadata,\n}: {\n callback: useExternalMessageConverter.Callback<T>;\n messages: T[];\n isRunning: boolean;\n joinStrategy?: JoinStrategy | undefined;\n metadata?: useExternalMessageConverter.Metadata | undefined;\n}) => {\n // The caches live for the component lifetime; React Compiler hoists\n // allocations without reactive dependencies out of useMemo, so re-creating\n // them on dependency change would not survive compilation. Staleness is\n // instead tracked per entry via the metadata/callback that produced it,\n // keeping correctness independent of memoization (which React treats as\n // droppable). A \"use no memo\" opt-out would restore the useMemo semantics\n // but leave cache flushing coupled to memo firing.\n const [caches] = useState(() => ({\n callbackCache: new WeakMap<T, CallbackCacheEntry<T>>(),\n chunkCache: new WeakMap<\n useExternalMessageConverter.Message,\n ChunkResult<T>\n >(),\n converterCache: new ThreadMessageConverter(),\n }));\n\n const state = useMemo(\n () => ({\n metadata: metadata ?? {},\n callback,\n ...caches,\n }),\n [callback, metadata, caches],\n );\n\n return useMemo(() => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n let result = state.callbackCache.get(message);\n if (\n !result ||\n result.metadata !== state.metadata ||\n result.callback !== state.callback\n ) {\n const output = state.callback(message, state.metadata);\n const outputs = Array.isArray(output) ? output : [output];\n result = {\n input: message,\n outputs,\n metadata: state.metadata,\n callback: state.callback,\n };\n state.callbackCache.set(message, result);\n }\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults, joinStrategy).map(\n (m) => {\n const key = m.outputs[0];\n if (!key) return m;\n\n const cached = state.chunkCache.get(key);\n if (cached && shallowArrayEqual(cached.outputs, m.outputs))\n return cached;\n state.chunkCache.set(key, m);\n return m;\n },\n );\n\n const threadMessages = state.converterCache.convertMessages(\n chunks,\n (cache, message, idx) => {\n const isLast = idx === chunks.length - 1;\n\n const joined = joinExternalMessages(message.outputs);\n const hasInterruptedToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isInterruptedToolCall);\n const hasPendingToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isPendingToolCall);\n const autoStatus = getAutoStatus(\n isLast,\n isRunning,\n hasInterruptedToolCalls,\n hasPendingToolCalls,\n isLast ? state.metadata.error : undefined,\n );\n\n if (\n cache &&\n (cache.role !== \"assistant\" ||\n !isAutoStatus(cache.status) ||\n cache.status === autoStatus)\n ) {\n const inputs = getExternalStoreMessages<T>(cache);\n if (shallowArrayEqual(inputs, message.inputs)) {\n return cache;\n }\n }\n\n const newMessage = fromThreadMessageLike(\n joined,\n idx.toString(),\n autoStatus,\n );\n bindExternalStoreMessage(newMessage, message.inputs);\n return newMessage;\n },\n );\n\n bindExternalStoreMessage(threadMessages, messages);\n\n if (state.metadata.error) {\n const lastMessage = threadMessages.at(-1);\n if (!lastMessage || lastMessage.role !== \"assistant\") {\n threadMessages.push(createErrorAssistantMessage(state.metadata.error));\n }\n }\n\n return threadMessages;\n }, [state, messages, isRunning, joinStrategy]);\n};\n\nconst shallowArrayEqual = (a: unknown[], b: unknown[]) => {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n"],"mappings":"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"}
@@ -62,11 +62,12 @@ const splitLocalRuntimeOptions = (options) => {
62
62
  };
63
63
  };
64
64
  const useLocalRuntime = (chatModel, { cloud, ...options } = {}) => {
65
+ const cloudAdapter = useCloudThreadListAdapter({ cloud });
65
66
  return useRemoteThreadListRuntime({
66
67
  runtimeHook: function RuntimeHook() {
67
68
  return useLocalThreadRuntime(chatModel, options);
68
69
  },
69
- adapter: useCloudThreadListAdapter({ cloud }),
70
+ adapter: cloudAdapter,
70
71
  allowNesting: true
71
72
  });
72
73
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useLocalRuntime.js","names":["useEffect","useMemo","useRef","useState","AssistantRuntime","ChatModelAdapter","ThreadMessageLike","LocalRuntimeOptionsBase","AssistantRuntimeImpl","LocalRuntimeCore","useAuiState","useRemoteThreadListRuntime","useCloudThreadListAdapter","useRuntimeAdapters","AssistantCloud","LocalRuntimeOptions","Omit","cloud","initialMessages","adapters","useLocalThreadRuntime","chatModel","options","modelContext","threadListAdapters","opt","runtime","threadIdRef","undefined","historyLoadPromiseRef","Promise","current","s","threadListItem","remoteId","threads","getMainThreadRuntimeCore","__internal_setGetThreadId","detach","__internal_setOptions","loadPromise","__internal_load","catch","error","console","registerModelContextProvider","splitLocalRuntimeOptions","T","maxSteps","unstable_humanToolNames","unstable_enableMessageQueue","unstable_queueClearOnRewind","unstable_queueClearOnCancel","rest","localRuntimeOptions","otherOptions","useLocalRuntime","cloudAdapter","runtimeHook","RuntimeHook","adapter","allowNesting"],"sources":["../../../src/react/runtimes/useLocalRuntime.ts"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n AssistantRuntime,\n ChatModelAdapter,\n ThreadMessageLike,\n} from \"../../index\";\nimport type { LocalRuntimeOptionsBase } from \"../../runtimes/local/local-runtime-options\";\nimport { AssistantRuntimeImpl, LocalRuntimeCore } from \"../../internal\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport { useRemoteThreadListRuntime } from \"./useRemoteThreadListRuntime\";\nimport { useCloudThreadListAdapter } from \"./cloud/useCloudThreadListAdapter\";\nimport { useRuntimeAdapters } from \"./RuntimeAdapterProvider\";\nimport type { AssistantCloud } from \"assistant-cloud\";\n\nexport type LocalRuntimeOptions = Omit<LocalRuntimeOptionsBase, \"adapters\"> & {\n cloud?: AssistantCloud | undefined;\n initialMessages?: readonly ThreadMessageLike[] | undefined;\n adapters?: Omit<LocalRuntimeOptionsBase[\"adapters\"], \"chatModel\"> | undefined;\n};\n\nconst useLocalThreadRuntime = (\n chatModel: ChatModelAdapter,\n { initialMessages, ...options }: LocalRuntimeOptions,\n): AssistantRuntime => {\n const { modelContext, ...threadListAdapters } = useRuntimeAdapters() ?? {};\n const opt = {\n ...options,\n adapters: {\n ...threadListAdapters,\n ...options.adapters,\n chatModel,\n },\n };\n\n const [runtime] = useState(() => new LocalRuntimeCore(opt, initialMessages));\n\n const threadIdRef = useRef<string | undefined>(undefined);\n const historyLoadPromiseRef = useRef<Promise<void> | undefined>(undefined);\n threadIdRef.current = useAuiState((s) => s.threadListItem.remoteId);\n\n useEffect(() => {\n runtime.threads\n .getMainThreadRuntimeCore()\n .__internal_setGetThreadId(() => threadIdRef.current);\n }, [runtime]);\n\n useEffect(() => {\n return () => {\n runtime.threads.getMainThreadRuntimeCore().detach();\n };\n }, [runtime]);\n\n useEffect(() => {\n runtime.threads.getMainThreadRuntimeCore().__internal_setOptions(opt);\n });\n\n useEffect(() => {\n const loadPromise = runtime.threads\n .getMainThreadRuntimeCore()\n .__internal_load();\n if (historyLoadPromiseRef.current === loadPromise) return;\n\n historyLoadPromiseRef.current = loadPromise;\n void loadPromise.catch((error: unknown) => {\n console.error(\"[assistant-ui] local thread history load failed:\", error);\n });\n }, [runtime]);\n\n useEffect(() => {\n if (!modelContext) return undefined;\n return runtime.registerModelContextProvider(modelContext);\n }, [modelContext, runtime]);\n\n return useMemo(() => new AssistantRuntimeImpl(runtime), [runtime]);\n};\n\nexport const splitLocalRuntimeOptions = <T extends LocalRuntimeOptions>(\n options: T,\n) => {\n const {\n cloud,\n initialMessages,\n maxSteps,\n adapters,\n unstable_humanToolNames,\n unstable_enableMessageQueue,\n unstable_queueClearOnRewind,\n unstable_queueClearOnCancel,\n ...rest\n } = options;\n\n return {\n localRuntimeOptions: {\n cloud,\n initialMessages,\n maxSteps,\n adapters,\n unstable_humanToolNames,\n unstable_enableMessageQueue,\n unstable_queueClearOnRewind,\n unstable_queueClearOnCancel,\n },\n otherOptions: rest,\n };\n};\n\nexport const useLocalRuntime = (\n chatModel: ChatModelAdapter,\n { cloud, ...options }: LocalRuntimeOptions = {},\n): AssistantRuntime => {\n const cloudAdapter = useCloudThreadListAdapter({ cloud });\n return useRemoteThreadListRuntime({\n runtimeHook: function RuntimeHook() {\n return useLocalThreadRuntime(chatModel, options);\n },\n adapter: cloudAdapter,\n allowNesting: true,\n });\n};\n"],"mappings":";;;;;;;;AAoBA,MAAMoB,yBACJC,WACA,EAAEH,iBAAiB,GAAGI,cACD;CACrB,MAAM,EAAEC,cAAc,GAAGC,uBAAuBX,mBAAmB,KAAK,CAAC;CACzE,MAAMY,MAAM;EACV,GAAGH;EACHH,UAAU;GACR,GAAGK;GACH,GAAGF,QAAQH;GACXE;EACF;CACF;CAEA,MAAM,CAACK,WAAWvB,eAAe,IAAIM,iBAAiBgB,KAAKP,eAAe,CAAC;CAE3E,MAAMS,cAAczB,OAA2B0B,KAAAA,CAAS;CACxD,MAAMC,wBAAwB3B,OAAkC0B,KAAAA,CAAS;CACzED,YAAYI,UAAUrB,aAAasB,MAAMA,EAAEC,eAAeC,QAAQ;CAElElC,gBAAgB;EACd0B,QAAQS,QACLC,yBAAyB,CAAC,CAC1BC,gCAAgCV,YAAYI,OAAO;CACxD,GAAG,CAACL,OAAO,CAAC;CAEZ1B,gBAAgB;EACd,aAAa;GACX0B,QAAQS,QAAQC,yBAAyB,CAAC,CAACE,OAAO;EACpD;CACF,GAAG,CAACZ,OAAO,CAAC;CAEZ1B,gBAAgB;EACd0B,QAAQS,QAAQC,yBAAyB,CAAC,CAACG,sBAAsBd,GAAG;CACtE,CAAC;CAEDzB,gBAAgB;EACd,MAAMwC,cAAcd,QAAQS,QACzBC,yBAAyB,CAAC,CAC1BK,gBAAgB;EACnB,IAAIZ,sBAAsBE,YAAYS,aAAa;EAEnDX,sBAAsBE,UAAUS;EAChC,YAAiBE,OAAOC,UAAmB;GACzCC,QAAQD,MAAM,oDAAoDA,KAAK;EACzE,CAAC;CACH,GAAG,CAACjB,OAAO,CAAC;CAEZ1B,gBAAgB;EACd,IAAI,CAACuB,cAAc,OAAOK,KAAAA;EAC1B,OAAOF,QAAQmB,6BAA6BtB,YAAY;CAC1D,GAAG,CAACA,cAAcG,OAAO,CAAC;CAE1B,OAAOzB,cAAc,IAAIO,qBAAqBkB,OAAO,GAAG,CAACA,OAAO,CAAC;AACnE;AAEA,MAAaoB,4BACXxB,YACG;CACH,MAAM,EACJL,OACAC,iBACA8B,UACA7B,UACA8B,yBACAC,6BACAC,6BACAC,6BACA,GAAGC,SACD/B;CAEJ,OAAO;EACLgC,qBAAqB;GACnBrC;GACAC;GACA8B;GACA7B;GACA8B;GACAC;GACAC;GACAC;EACF;EACAG,cAAcF;CAChB;AACF;AAEA,MAAaG,mBACXnC,WACA,EAAEJ,OAAO,GAAGK,YAAiC,CAAC,MACzB;CAErB,OAAOX,2BAA2B;EAChC+C,aAAa,SAASC,cAAc;GAClC,OAAOvC,sBAAsBC,WAAWC,OAAO;EACjD;EACAsC,SALmBhD,0BAA0B,EAAEK,MAAM,CAK5CwC;EACTI,cAAc;CAChB,CAAC;AACH"}
1
+ {"version":3,"file":"useLocalRuntime.js","names":["useEffect","useMemo","useRef","useState","AssistantRuntime","ChatModelAdapter","ThreadMessageLike","LocalRuntimeOptionsBase","AssistantRuntimeImpl","LocalRuntimeCore","useAuiState","useRemoteThreadListRuntime","useCloudThreadListAdapter","useRuntimeAdapters","AssistantCloud","LocalRuntimeOptions","Omit","cloud","initialMessages","adapters","useLocalThreadRuntime","chatModel","options","modelContext","threadListAdapters","opt","runtime","threadIdRef","undefined","historyLoadPromiseRef","Promise","current","s","threadListItem","remoteId","threads","getMainThreadRuntimeCore","__internal_setGetThreadId","detach","__internal_setOptions","loadPromise","__internal_load","catch","error","console","registerModelContextProvider","splitLocalRuntimeOptions","T","maxSteps","unstable_humanToolNames","unstable_enableMessageQueue","unstable_queueClearOnRewind","unstable_queueClearOnCancel","rest","localRuntimeOptions","otherOptions","useLocalRuntime","cloudAdapter","runtimeHook","RuntimeHook","adapter","allowNesting"],"sources":["../../../src/react/runtimes/useLocalRuntime.ts"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n AssistantRuntime,\n ChatModelAdapter,\n ThreadMessageLike,\n} from \"../../index\";\nimport type { LocalRuntimeOptionsBase } from \"../../runtimes/local/local-runtime-options\";\nimport { AssistantRuntimeImpl, LocalRuntimeCore } from \"../../internal\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport { useRemoteThreadListRuntime } from \"./useRemoteThreadListRuntime\";\nimport { useCloudThreadListAdapter } from \"./cloud/useCloudThreadListAdapter\";\nimport { useRuntimeAdapters } from \"./RuntimeAdapterProvider\";\nimport type { AssistantCloud } from \"assistant-cloud\";\n\nexport type LocalRuntimeOptions = Omit<LocalRuntimeOptionsBase, \"adapters\"> & {\n cloud?: AssistantCloud | undefined;\n initialMessages?: readonly ThreadMessageLike[] | undefined;\n adapters?: Omit<LocalRuntimeOptionsBase[\"adapters\"], \"chatModel\"> | undefined;\n};\n\nconst useLocalThreadRuntime = (\n chatModel: ChatModelAdapter,\n { initialMessages, ...options }: LocalRuntimeOptions,\n): AssistantRuntime => {\n const { modelContext, ...threadListAdapters } = useRuntimeAdapters() ?? {};\n const opt = {\n ...options,\n adapters: {\n ...threadListAdapters,\n ...options.adapters,\n chatModel,\n },\n };\n\n const [runtime] = useState(() => new LocalRuntimeCore(opt, initialMessages));\n\n const threadIdRef = useRef<string | undefined>(undefined);\n const historyLoadPromiseRef = useRef<Promise<void> | undefined>(undefined);\n threadIdRef.current = useAuiState((s) => s.threadListItem.remoteId);\n\n useEffect(() => {\n runtime.threads\n .getMainThreadRuntimeCore()\n .__internal_setGetThreadId(() => threadIdRef.current);\n }, [runtime]);\n\n useEffect(() => {\n return () => {\n runtime.threads.getMainThreadRuntimeCore().detach();\n };\n }, [runtime]);\n\n useEffect(() => {\n runtime.threads.getMainThreadRuntimeCore().__internal_setOptions(opt);\n });\n\n useEffect(() => {\n const loadPromise = runtime.threads\n .getMainThreadRuntimeCore()\n .__internal_load();\n if (historyLoadPromiseRef.current === loadPromise) return;\n\n historyLoadPromiseRef.current = loadPromise;\n void loadPromise.catch((error: unknown) => {\n console.error(\"[assistant-ui] local thread history load failed:\", error);\n });\n }, [runtime]);\n\n useEffect(() => {\n if (!modelContext) return undefined;\n return runtime.registerModelContextProvider(modelContext);\n }, [modelContext, runtime]);\n\n return useMemo(() => new AssistantRuntimeImpl(runtime), [runtime]);\n};\n\nexport const splitLocalRuntimeOptions = <T extends LocalRuntimeOptions>(\n options: T,\n) => {\n const {\n cloud,\n initialMessages,\n maxSteps,\n adapters,\n unstable_humanToolNames,\n unstable_enableMessageQueue,\n unstable_queueClearOnRewind,\n unstable_queueClearOnCancel,\n ...rest\n } = options;\n\n return {\n localRuntimeOptions: {\n cloud,\n initialMessages,\n maxSteps,\n adapters,\n unstable_humanToolNames,\n unstable_enableMessageQueue,\n unstable_queueClearOnRewind,\n unstable_queueClearOnCancel,\n },\n otherOptions: rest,\n };\n};\n\nexport const useLocalRuntime = (\n chatModel: ChatModelAdapter,\n { cloud, ...options }: LocalRuntimeOptions = {},\n): AssistantRuntime => {\n const cloudAdapter = useCloudThreadListAdapter({ cloud });\n return useRemoteThreadListRuntime({\n runtimeHook: function RuntimeHook() {\n return useLocalThreadRuntime(chatModel, options);\n },\n adapter: cloudAdapter,\n allowNesting: true,\n });\n};\n"],"mappings":";;;;;;;;AAoBA,MAAMoB,yBACJC,WACA,EAAEH,iBAAiB,GAAGI,cACD;CACrB,MAAM,EAAEC,cAAc,GAAGC,uBAAuBX,mBAAmB,KAAK,CAAC;CACzE,MAAMY,MAAM;EACV,GAAGH;EACHH,UAAU;GACR,GAAGK;GACH,GAAGF,QAAQH;GACXE;EACF;CACF;CAEA,MAAM,CAACK,WAAWvB,eAAe,IAAIM,iBAAiBgB,KAAKP,eAAe,CAAC;CAE3E,MAAMS,cAAczB,OAA2B0B,KAAAA,CAAS;CACxD,MAAMC,wBAAwB3B,OAAkC0B,KAAAA,CAAS;CACzED,YAAYI,UAAUrB,aAAasB,MAAMA,EAAEC,eAAeC,QAAQ;CAElElC,gBAAgB;EACd0B,QAAQS,QACLC,yBAAyB,CAAC,CAC1BC,gCAAgCV,YAAYI,OAAO;CACxD,GAAG,CAACL,OAAO,CAAC;CAEZ1B,gBAAgB;EACd,aAAa;GACX0B,QAAQS,QAAQC,yBAAyB,CAAC,CAACE,OAAO;EACpD;CACF,GAAG,CAACZ,OAAO,CAAC;CAEZ1B,gBAAgB;EACd0B,QAAQS,QAAQC,yBAAyB,CAAC,CAACG,sBAAsBd,GAAG;CACtE,CAAC;CAEDzB,gBAAgB;EACd,MAAMwC,cAAcd,QAAQS,QACzBC,yBAAyB,CAAC,CAC1BK,gBAAgB;EACnB,IAAIZ,sBAAsBE,YAAYS,aAAa;EAEnDX,sBAAsBE,UAAUS;EAChC,YAAiBE,OAAOC,UAAmB;GACzCC,QAAQD,MAAM,oDAAoDA,KAAK;EACzE,CAAC;CACH,GAAG,CAACjB,OAAO,CAAC;CAEZ1B,gBAAgB;EACd,IAAI,CAACuB,cAAc,OAAOK,KAAAA;EAC1B,OAAOF,QAAQmB,6BAA6BtB,YAAY;CAC1D,GAAG,CAACA,cAAcG,OAAO,CAAC;CAE1B,OAAOzB,cAAc,IAAIO,qBAAqBkB,OAAO,GAAG,CAACA,OAAO,CAAC;AACnE;AAEA,MAAaoB,4BACXxB,YACG;CACH,MAAM,EACJL,OACAC,iBACA8B,UACA7B,UACA8B,yBACAC,6BACAC,6BACAC,6BACA,GAAGC,SACD/B;CAEJ,OAAO;EACLgC,qBAAqB;GACnBrC;GACAC;GACA8B;GACA7B;GACA8B;GACAC;GACAC;GACAC;EACF;EACAG,cAAcF;CAChB;AACF;AAEA,MAAaG,mBACXnC,WACA,EAAEJ,OAAO,GAAGK,YAAiC,CAAC,MACzB;CACrB,MAAMmC,eAAe7C,0BAA0B,EAAEK,MAAM,CAAC;CACxD,OAAON,2BAA2B;EAChC+C,aAAa,SAASC,cAAc;GAClC,OAAOvC,sBAAsBC,WAAWC,OAAO;EACjD;EACAsC,SAASH;EACTI,cAAc;CAChB,CAAC;AACH"}
@@ -8,8 +8,10 @@ import { MessagePartRuntimeImpl } from "./message-part-runtime.js";
8
8
  //#region src/runtime/api/message-runtime.ts
9
9
  const toMessagePartStatus = (message, partIndex, part) => {
10
10
  if (message.role !== "assistant") return COMPLETE_STATUS;
11
- if (part.type === "tool-call") if (part.result === void 0) return message.status;
12
- else return COMPLETE_STATUS;
11
+ if (part.type === "tool-call") {
12
+ if (part.result === void 0) return message.status;
13
+ else return COMPLETE_STATUS;
14
+ }
13
15
  if (message.status.type === "running") {
14
16
  const status = normalizePartStatus(part);
15
17
  if (status) return status;
@@ -1 +1 @@
1
- {"version":3,"file":"message-runtime.js","names":["SpeechState","symbolInnerMessage","ToolCallMessagePartStatus","ThreadMessage","ThreadAssistantMessagePart","ThreadUserMessagePart","Unsubscribe","MessagePartStatus","RunConfig","COMPLETE_STATUS","normalizePartStatus","getThreadMessageText","NestedSubscriptionSubject","SKIP_UPDATE","ShallowMemoizeSubject","AttachmentRuntime","AttachmentState","MessageAttachmentRuntimeImpl","EditComposerRuntime","EditComposerRuntimeImpl","MessagePartRuntime","MessagePartRuntimeImpl","MessagePartState","MessageRuntimePath","ThreadRuntimeCoreBinding","MessageStateBinding","toMessagePartStatus","message","partIndex","part","role","type","result","undefined","status","isLastPart","Math","max","content","length","getMessagePartState","MessageState","Object","freeze","parentId","index","isLast","branchNumber","branchCount","speech","ReloadConfig","runConfig","MessageRuntime","path","composer","getState","delete","Promise","reload","config","speak","stopSpeaking","submitFeedback","switchToBranch","position","branchId","unstable_getCopyText","subscribe","callback","getMessagePartByIndex","idx","getMessagePartByToolCallId","toolCallId","getAttachmentByIndex","source","MessageRuntimeImpl","_core","_threadBinding","constructor","ref","composerSource","_getEditComposerRuntimeCore","beginEdit","id","__internal_bindMethods","bind","getEditComposer","state","deleteMessage","reloadConfig","editComposerRuntimeCore","composerRuntimeCore","Error","startRun","sourceId","thread","messageId","branches","getBranches","targetBranch","messagePartSelector","JSON","stringify","findIndex","attachmentSource","attachmentSelector","attachments","attachment"],"sources":["../../../src/runtime/api/message-runtime.ts"],"sourcesContent":["import type { SpeechState } from \"../interfaces/thread-runtime-core\";\nimport { symbolInnerMessage } from \"../utils/external-store-message\";\nimport type {\n ToolCallMessagePartStatus,\n ThreadMessage,\n ThreadAssistantMessagePart,\n ThreadUserMessagePart,\n} from \"../../types/message\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { MessagePartStatus, RunConfig } from \"../../types/message\";\nimport {\n COMPLETE_STATUS,\n normalizePartStatus,\n} from \"../../utils/normalizePartStatus\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport { NestedSubscriptionSubject } from \"../../subscribable/subscribable\";\nimport {\n SKIP_UPDATE,\n ShallowMemoizeSubject,\n} from \"../../subscribable/subscribable\";\nimport {\n type AttachmentRuntime,\n type AttachmentState,\n MessageAttachmentRuntimeImpl,\n} from \"./attachment-runtime\";\nimport {\n type EditComposerRuntime,\n EditComposerRuntimeImpl,\n} from \"./composer-runtime\";\nimport {\n type MessagePartRuntime,\n MessagePartRuntimeImpl,\n type MessagePartState,\n} from \"./message-part-runtime\";\nimport type { MessageRuntimePath } from \"./paths\";\nimport type { ThreadRuntimeCoreBinding } from \"./thread-runtime\";\nimport type { MessageStateBinding } from \"./bindings\";\n\nexport const toMessagePartStatus = (\n message: ThreadMessage,\n partIndex: number,\n part: ThreadUserMessagePart | ThreadAssistantMessagePart,\n): ToolCallMessagePartStatus => {\n if (message.role !== \"assistant\") return COMPLETE_STATUS;\n\n if (part.type === \"tool-call\") {\n if (part.result === undefined) {\n return message.status as ToolCallMessagePartStatus;\n } else {\n return COMPLETE_STATUS;\n }\n }\n\n if (message.status.type === \"running\") {\n const status = normalizePartStatus(part);\n if (status) return status;\n }\n\n const isLastPart = partIndex === Math.max(0, message.content.length - 1);\n if (message.status.type === \"requires-action\") return COMPLETE_STATUS;\n return isLastPart ? (message.status as MessagePartStatus) : COMPLETE_STATUS;\n};\n\nconst getMessagePartState = (\n message: MessageState,\n partIndex: number,\n): MessagePartState | SKIP_UPDATE => {\n const part = message.content[partIndex];\n if (!part) {\n return SKIP_UPDATE;\n }\n\n // if the message part is the same, don't update\n const status = toMessagePartStatus(message, partIndex, part);\n return Object.freeze({\n ...part,\n ...{ [symbolInnerMessage]: (part as any)[symbolInnerMessage] },\n status: status as MessagePartStatus,\n });\n};\n\nexport type MessageState = ThreadMessage & {\n readonly parentId: string | null;\n /** The position of this message in the thread (0 for first message) */\n readonly index: number;\n readonly isLast: boolean;\n\n readonly branchNumber: number;\n readonly branchCount: number;\n\n /**\n * @deprecated This API is still under active development and might change without notice.\n */\n readonly speech: SpeechState | undefined;\n};\n\nexport type { MessageStateBinding } from \"./bindings\";\n\ntype ReloadConfig = {\n runConfig?: RunConfig;\n};\n\nexport type MessageRuntime = {\n readonly path: MessageRuntimePath;\n\n readonly composer: EditComposerRuntime;\n\n getState(): MessageState;\n delete(): void | Promise<void>;\n reload(config?: ReloadConfig): void;\n /**\n * @deprecated This API is still under active development and might change without notice.\n */\n speak(): void;\n /**\n * @deprecated This API is still under active development and might change without notice.\n */\n stopSpeaking(): void;\n submitFeedback({ type }: { type: \"positive\" | \"negative\" }): void;\n switchToBranch({\n position,\n branchId,\n }: {\n position?: \"previous\" | \"next\" | undefined;\n branchId?: string | undefined;\n }): void;\n unstable_getCopyText(): string;\n\n subscribe(callback: () => void): Unsubscribe;\n\n getMessagePartByIndex(idx: number): MessagePartRuntime;\n getMessagePartByToolCallId(toolCallId: string): MessagePartRuntime;\n\n getAttachmentByIndex(idx: number): AttachmentRuntime & { source: \"message\" };\n};\n\nexport class MessageRuntimeImpl implements MessageRuntime {\n public get path() {\n return this._core.path;\n }\n\n private _core: MessageStateBinding;\n private _threadBinding: ThreadRuntimeCoreBinding;\n\n constructor(\n _core: MessageStateBinding,\n _threadBinding: ThreadRuntimeCoreBinding,\n ) {\n this._core = _core;\n this._threadBinding = _threadBinding;\n this.composer = new EditComposerRuntimeImpl(\n new NestedSubscriptionSubject({\n path: {\n ...this.path,\n ref: `${this.path.ref}.composer`,\n composerSource: \"edit\",\n },\n getState: this._getEditComposerRuntimeCore,\n subscribe: (callback) => this._threadBinding.subscribe(callback),\n }),\n () => this._threadBinding.getState().beginEdit(this._core.getState().id),\n );\n\n this.__internal_bindMethods();\n }\n\n protected __internal_bindMethods() {\n this.reload = this.reload.bind(this);\n this.delete = this.delete.bind(this);\n this.getState = this.getState.bind(this);\n this.subscribe = this.subscribe.bind(this);\n this.getMessagePartByIndex = this.getMessagePartByIndex.bind(this);\n this.getMessagePartByToolCallId =\n this.getMessagePartByToolCallId.bind(this);\n this.getAttachmentByIndex = this.getAttachmentByIndex.bind(this);\n this.unstable_getCopyText = this.unstable_getCopyText.bind(this);\n this.speak = this.speak.bind(this);\n this.stopSpeaking = this.stopSpeaking.bind(this);\n this.submitFeedback = this.submitFeedback.bind(this);\n this.switchToBranch = this.switchToBranch.bind(this);\n }\n\n public readonly composer;\n\n private _getEditComposerRuntimeCore = () => {\n return this._threadBinding\n .getState()\n .getEditComposer(this._core.getState().id);\n };\n\n public getState() {\n return this._core.getState();\n }\n\n public delete() {\n const state = this._core.getState();\n return this._threadBinding.getState().deleteMessage(state.id);\n }\n\n public reload(reloadConfig: ReloadConfig = {}) {\n const editComposerRuntimeCore = this._getEditComposerRuntimeCore();\n const composerRuntimeCore =\n editComposerRuntimeCore ?? this._threadBinding.getState().composer;\n const composer = editComposerRuntimeCore ?? composerRuntimeCore;\n\n const { runConfig = composer.runConfig } = reloadConfig;\n const state = this._core.getState();\n if (state.role !== \"assistant\")\n throw new Error(\"Can only reload assistant messages\");\n\n this._threadBinding.getState().startRun({\n parentId: state.parentId,\n sourceId: state.id,\n runConfig,\n });\n }\n\n public speak() {\n const state = this._core.getState();\n return this._threadBinding.getState().speak(state.id);\n }\n\n public stopSpeaking() {\n const state = this._core.getState();\n const thread = this._threadBinding.getState();\n if (thread.speech?.messageId === state.id) {\n this._threadBinding.getState().stopSpeaking();\n } else {\n throw new Error(\"Message is not being spoken\");\n }\n }\n\n public submitFeedback({ type }: { type: \"positive\" | \"negative\" }) {\n const state = this._core.getState();\n this._threadBinding.getState().submitFeedback({\n messageId: state.id,\n type,\n });\n }\n\n public switchToBranch({\n position,\n branchId,\n }: {\n position?: \"previous\" | \"next\" | undefined;\n branchId?: string | undefined;\n }) {\n const state = this._core.getState();\n if (branchId && position) {\n throw new Error(\"May not specify both branchId and position\");\n } else if (!branchId && !position) {\n throw new Error(\"Must specify either branchId or position\");\n }\n\n const thread = this._threadBinding.getState();\n const branches = thread.getBranches(state.id);\n let targetBranch = branchId;\n if (position === \"previous\") {\n targetBranch = branches[state.branchNumber - 2];\n } else if (position === \"next\") {\n targetBranch = branches[state.branchNumber];\n }\n if (!targetBranch) throw new Error(\"Branch not found\");\n\n this._threadBinding.getState().switchToBranch(targetBranch);\n }\n\n public unstable_getCopyText() {\n return getThreadMessageText(this.getState());\n }\n\n public subscribe(callback: () => void) {\n return this._core.subscribe(callback);\n }\n\n public getMessagePartByIndex(idx: number) {\n if (idx < 0) throw new Error(\"Message part index must be >= 0\");\n return new MessagePartRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ...this.path,\n ref: `${this.path.ref}.content[${idx}]`,\n messagePartSelector: { type: \"index\", index: idx },\n },\n getState: () => {\n return getMessagePartState(this.getState(), idx);\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this._core,\n this._threadBinding,\n );\n }\n\n public getMessagePartByToolCallId(toolCallId: string) {\n return new MessagePartRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ...this.path,\n ref: `${this.path.ref}.content[toolCallId=${JSON.stringify(toolCallId)}]`,\n messagePartSelector: { type: \"toolCallId\", toolCallId },\n },\n getState: () => {\n const state = this._core.getState();\n const idx = state.content.findIndex(\n (part) =>\n part.type === \"tool-call\" && part.toolCallId === toolCallId,\n );\n if (idx === -1) return SKIP_UPDATE;\n return getMessagePartState(state, idx);\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this._core,\n this._threadBinding,\n );\n }\n\n public getAttachmentByIndex(idx: number) {\n return new MessageAttachmentRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ...this.path,\n ref: `${this.path.ref}.attachments[${idx}]`,\n attachmentSource: \"message\",\n attachmentSelector: { type: \"index\", index: idx },\n },\n getState: () => {\n const attachments = this.getState().attachments;\n const attachment = attachments?.[idx];\n if (!attachment) return SKIP_UPDATE;\n\n return {\n ...attachment,\n source: \"message\",\n } satisfies AttachmentState & { source: \"message\" };\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"message-runtime.js","names":["SpeechState","symbolInnerMessage","ToolCallMessagePartStatus","ThreadMessage","ThreadAssistantMessagePart","ThreadUserMessagePart","Unsubscribe","MessagePartStatus","RunConfig","COMPLETE_STATUS","normalizePartStatus","getThreadMessageText","NestedSubscriptionSubject","SKIP_UPDATE","ShallowMemoizeSubject","AttachmentRuntime","AttachmentState","MessageAttachmentRuntimeImpl","EditComposerRuntime","EditComposerRuntimeImpl","MessagePartRuntime","MessagePartRuntimeImpl","MessagePartState","MessageRuntimePath","ThreadRuntimeCoreBinding","MessageStateBinding","toMessagePartStatus","message","partIndex","part","role","type","result","undefined","status","isLastPart","Math","max","content","length","getMessagePartState","MessageState","Object","freeze","parentId","index","isLast","branchNumber","branchCount","speech","ReloadConfig","runConfig","MessageRuntime","path","composer","getState","delete","Promise","reload","config","speak","stopSpeaking","submitFeedback","switchToBranch","position","branchId","unstable_getCopyText","subscribe","callback","getMessagePartByIndex","idx","getMessagePartByToolCallId","toolCallId","getAttachmentByIndex","source","MessageRuntimeImpl","_core","_threadBinding","constructor","ref","composerSource","_getEditComposerRuntimeCore","beginEdit","id","__internal_bindMethods","bind","getEditComposer","state","deleteMessage","reloadConfig","editComposerRuntimeCore","composerRuntimeCore","Error","startRun","sourceId","thread","messageId","branches","getBranches","targetBranch","messagePartSelector","JSON","stringify","findIndex","attachmentSource","attachmentSelector","attachments","attachment"],"sources":["../../../src/runtime/api/message-runtime.ts"],"sourcesContent":["import type { SpeechState } from \"../interfaces/thread-runtime-core\";\nimport { symbolInnerMessage } from \"../utils/external-store-message\";\nimport type {\n ToolCallMessagePartStatus,\n ThreadMessage,\n ThreadAssistantMessagePart,\n ThreadUserMessagePart,\n} from \"../../types/message\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { MessagePartStatus, RunConfig } from \"../../types/message\";\nimport {\n COMPLETE_STATUS,\n normalizePartStatus,\n} from \"../../utils/normalizePartStatus\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport { NestedSubscriptionSubject } from \"../../subscribable/subscribable\";\nimport {\n SKIP_UPDATE,\n ShallowMemoizeSubject,\n} from \"../../subscribable/subscribable\";\nimport {\n type AttachmentRuntime,\n type AttachmentState,\n MessageAttachmentRuntimeImpl,\n} from \"./attachment-runtime\";\nimport {\n type EditComposerRuntime,\n EditComposerRuntimeImpl,\n} from \"./composer-runtime\";\nimport {\n type MessagePartRuntime,\n MessagePartRuntimeImpl,\n type MessagePartState,\n} from \"./message-part-runtime\";\nimport type { MessageRuntimePath } from \"./paths\";\nimport type { ThreadRuntimeCoreBinding } from \"./thread-runtime\";\nimport type { MessageStateBinding } from \"./bindings\";\n\nexport const toMessagePartStatus = (\n message: ThreadMessage,\n partIndex: number,\n part: ThreadUserMessagePart | ThreadAssistantMessagePart,\n): ToolCallMessagePartStatus => {\n if (message.role !== \"assistant\") return COMPLETE_STATUS;\n\n if (part.type === \"tool-call\") {\n if (part.result === undefined) {\n return message.status as ToolCallMessagePartStatus;\n } else {\n return COMPLETE_STATUS;\n }\n }\n\n if (message.status.type === \"running\") {\n const status = normalizePartStatus(part);\n if (status) return status;\n }\n\n const isLastPart = partIndex === Math.max(0, message.content.length - 1);\n if (message.status.type === \"requires-action\") return COMPLETE_STATUS;\n return isLastPart ? (message.status as MessagePartStatus) : COMPLETE_STATUS;\n};\n\nconst getMessagePartState = (\n message: MessageState,\n partIndex: number,\n): MessagePartState | SKIP_UPDATE => {\n const part = message.content[partIndex];\n if (!part) {\n return SKIP_UPDATE;\n }\n\n // if the message part is the same, don't update\n const status = toMessagePartStatus(message, partIndex, part);\n return Object.freeze({\n ...part,\n ...{ [symbolInnerMessage]: (part as any)[symbolInnerMessage] },\n status: status as MessagePartStatus,\n });\n};\n\nexport type MessageState = ThreadMessage & {\n readonly parentId: string | null;\n /** The position of this message in the thread (0 for first message) */\n readonly index: number;\n readonly isLast: boolean;\n\n readonly branchNumber: number;\n readonly branchCount: number;\n\n /**\n * @deprecated This API is still under active development and might change without notice.\n */\n readonly speech: SpeechState | undefined;\n};\n\nexport type { MessageStateBinding } from \"./bindings\";\n\ntype ReloadConfig = {\n runConfig?: RunConfig;\n};\n\nexport type MessageRuntime = {\n readonly path: MessageRuntimePath;\n\n readonly composer: EditComposerRuntime;\n\n getState(): MessageState;\n delete(): void | Promise<void>;\n reload(config?: ReloadConfig): void;\n /**\n * @deprecated This API is still under active development and might change without notice.\n */\n speak(): void;\n /**\n * @deprecated This API is still under active development and might change without notice.\n */\n stopSpeaking(): void;\n submitFeedback({ type }: { type: \"positive\" | \"negative\" }): void;\n switchToBranch({\n position,\n branchId,\n }: {\n position?: \"previous\" | \"next\" | undefined;\n branchId?: string | undefined;\n }): void;\n unstable_getCopyText(): string;\n\n subscribe(callback: () => void): Unsubscribe;\n\n getMessagePartByIndex(idx: number): MessagePartRuntime;\n getMessagePartByToolCallId(toolCallId: string): MessagePartRuntime;\n\n getAttachmentByIndex(idx: number): AttachmentRuntime & { source: \"message\" };\n};\n\nexport class MessageRuntimeImpl implements MessageRuntime {\n public get path() {\n return this._core.path;\n }\n\n private _core: MessageStateBinding;\n private _threadBinding: ThreadRuntimeCoreBinding;\n\n constructor(\n _core: MessageStateBinding,\n _threadBinding: ThreadRuntimeCoreBinding,\n ) {\n this._core = _core;\n this._threadBinding = _threadBinding;\n this.composer = new EditComposerRuntimeImpl(\n new NestedSubscriptionSubject({\n path: {\n ...this.path,\n ref: `${this.path.ref}.composer`,\n composerSource: \"edit\",\n },\n getState: this._getEditComposerRuntimeCore,\n subscribe: (callback) => this._threadBinding.subscribe(callback),\n }),\n () => this._threadBinding.getState().beginEdit(this._core.getState().id),\n );\n\n this.__internal_bindMethods();\n }\n\n protected __internal_bindMethods() {\n this.reload = this.reload.bind(this);\n this.delete = this.delete.bind(this);\n this.getState = this.getState.bind(this);\n this.subscribe = this.subscribe.bind(this);\n this.getMessagePartByIndex = this.getMessagePartByIndex.bind(this);\n this.getMessagePartByToolCallId =\n this.getMessagePartByToolCallId.bind(this);\n this.getAttachmentByIndex = this.getAttachmentByIndex.bind(this);\n this.unstable_getCopyText = this.unstable_getCopyText.bind(this);\n this.speak = this.speak.bind(this);\n this.stopSpeaking = this.stopSpeaking.bind(this);\n this.submitFeedback = this.submitFeedback.bind(this);\n this.switchToBranch = this.switchToBranch.bind(this);\n }\n\n public readonly composer;\n\n private _getEditComposerRuntimeCore = () => {\n return this._threadBinding\n .getState()\n .getEditComposer(this._core.getState().id);\n };\n\n public getState() {\n return this._core.getState();\n }\n\n public delete() {\n const state = this._core.getState();\n return this._threadBinding.getState().deleteMessage(state.id);\n }\n\n public reload(reloadConfig: ReloadConfig = {}) {\n const editComposerRuntimeCore = this._getEditComposerRuntimeCore();\n const composerRuntimeCore =\n editComposerRuntimeCore ?? this._threadBinding.getState().composer;\n const composer = editComposerRuntimeCore ?? composerRuntimeCore;\n\n const { runConfig = composer.runConfig } = reloadConfig;\n const state = this._core.getState();\n if (state.role !== \"assistant\")\n throw new Error(\"Can only reload assistant messages\");\n\n this._threadBinding.getState().startRun({\n parentId: state.parentId,\n sourceId: state.id,\n runConfig,\n });\n }\n\n public speak() {\n const state = this._core.getState();\n return this._threadBinding.getState().speak(state.id);\n }\n\n public stopSpeaking() {\n const state = this._core.getState();\n const thread = this._threadBinding.getState();\n if (thread.speech?.messageId === state.id) {\n this._threadBinding.getState().stopSpeaking();\n } else {\n throw new Error(\"Message is not being spoken\");\n }\n }\n\n public submitFeedback({ type }: { type: \"positive\" | \"negative\" }) {\n const state = this._core.getState();\n this._threadBinding.getState().submitFeedback({\n messageId: state.id,\n type,\n });\n }\n\n public switchToBranch({\n position,\n branchId,\n }: {\n position?: \"previous\" | \"next\" | undefined;\n branchId?: string | undefined;\n }) {\n const state = this._core.getState();\n if (branchId && position) {\n throw new Error(\"May not specify both branchId and position\");\n } else if (!branchId && !position) {\n throw new Error(\"Must specify either branchId or position\");\n }\n\n const thread = this._threadBinding.getState();\n const branches = thread.getBranches(state.id);\n let targetBranch = branchId;\n if (position === \"previous\") {\n targetBranch = branches[state.branchNumber - 2];\n } else if (position === \"next\") {\n targetBranch = branches[state.branchNumber];\n }\n if (!targetBranch) throw new Error(\"Branch not found\");\n\n this._threadBinding.getState().switchToBranch(targetBranch);\n }\n\n public unstable_getCopyText() {\n return getThreadMessageText(this.getState());\n }\n\n public subscribe(callback: () => void) {\n return this._core.subscribe(callback);\n }\n\n public getMessagePartByIndex(idx: number) {\n if (idx < 0) throw new Error(\"Message part index must be >= 0\");\n return new MessagePartRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ...this.path,\n ref: `${this.path.ref}.content[${idx}]`,\n messagePartSelector: { type: \"index\", index: idx },\n },\n getState: () => {\n return getMessagePartState(this.getState(), idx);\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this._core,\n this._threadBinding,\n );\n }\n\n public getMessagePartByToolCallId(toolCallId: string) {\n return new MessagePartRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ...this.path,\n ref: `${this.path.ref}.content[toolCallId=${JSON.stringify(toolCallId)}]`,\n messagePartSelector: { type: \"toolCallId\", toolCallId },\n },\n getState: () => {\n const state = this._core.getState();\n const idx = state.content.findIndex(\n (part) =>\n part.type === \"tool-call\" && part.toolCallId === toolCallId,\n );\n if (idx === -1) return SKIP_UPDATE;\n return getMessagePartState(state, idx);\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this._core,\n this._threadBinding,\n );\n }\n\n public getAttachmentByIndex(idx: number) {\n return new MessageAttachmentRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ...this.path,\n ref: `${this.path.ref}.attachments[${idx}]`,\n attachmentSource: \"message\",\n attachmentSelector: { type: \"index\", index: idx },\n },\n getState: () => {\n const attachments = this.getState().attachments;\n const attachment = attachments?.[idx];\n if (!attachment) return SKIP_UPDATE;\n\n return {\n ...attachment,\n source: \"message\",\n } satisfies AttachmentState & { source: \"message\" };\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n );\n }\n}\n"],"mappings":"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"}
@@ -27,7 +27,7 @@ declare abstract class BaseComposerRuntimeCore extends BaseSubscribable implemen
27
27
  private _text;
28
28
  get text(): string;
29
29
  private _role;
30
- get role(): "assistant" | "system" | "user";
30
+ get role(): "system" | "user" | "assistant";
31
31
  private _runConfig;
32
32
  get runConfig(): RunConfig;
33
33
  private _quote;
@@ -1 +1 @@
1
- {"version":3,"file":"external-store-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtimes/external-store/external-store-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;;;cAmDa,qBACX,oBACA,mBAAmB;cAKR,uCACH,iCACG;UAEH;MAiBG,gBAAY;UAIf;EACD;EACA;MACI;MAIA;YAIQ,6BAA6B;MAI5B,sEAAK,sDAAA;MAId;kBARqC;;;;;;;MAarC,iCAAiC;EAKrC,sBAAsB;EACtB;UAEC;UAEA;;;;;UAMA;EAEQ,UAAU;EAQxB,YAAA,iBAAiB,sBACjB,OAAO;EAMF,sBAAsB,OAAO;;;;;;;UA8L5B;;;;;UAmEA;UACA;;;;;;;UAQA;EAmBQ,eAAe;;;;;;;;;UA6BvB;EAaK,OAAO,SAAS,gBAAgB;EA+BhC,cAAc,oBAAoB;EAoBxC,0BApBwC;EA0BxC,+BANa;EAUb,cAAc,qBAAqB,WAAW;EAI9C,gBAAgB;EAIV,SAAS,QAAQ,iBAAiB;EAYlC,UAAU,QAAQ,kBAAkB;EAO1C;EAOA,oBAAoB;EAmBpB;EAwCA,cAAc,SAAS;EAMvB,eAAe,SAAS;EAoBxB,sBAAsB,SAAS;EAMtB,MAAM,2BAA2B;EAMjC,OAAO,MAAM;UAQrB"}
1
+ {"version":3,"file":"external-store-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtimes/external-store/external-store-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;;;cAmDa,qBACX,oBACA,mBAAmB;cAKR,uCACH,iCACG;UAEH;MAiBG,gBAAY;UAIf;EACD;EACA;MACI;MAIA;YAIQ,6BAA6B;MAI5B,sEAAK,sDAAA;MAId;kBARqC;;;;;;;MAarC,iCAAiC;EAKrC,sBAAsB;EACtB;UAEC;UAEA;;;;;UAMA;EAEQ,UAAU;EAQxB,YAAA,iBAAiB,sBACjB,OAAO;EAMF,sBAAsB,OAAO;;;;;;;UA8L5B;;;;;UAmEA;UACA;;;;;;;UAQA;EAmBQ,eAAe;;;;;;;;;UA6BvB;EAaK,OAAO,SAAS,gBAAgB;EAmChC,cAAc,oBAAoB;EAoBxC,0BApBwC;EA0BxC,+BANa;EAUb,cAAc,qBAAqB,WAAW;EAI9C,gBAAgB;EAIV,SAAS,QAAQ,iBAAiB;EAYlC,UAAU,QAAQ,kBAAkB;EAO1C;EAOA,oBAAoB;EAmBpB;EAwCA,cAAc,SAAS;EAMvB,eAAe,SAAS;EAoBxB,sBAAsB,SAAS;EAMtB,MAAM,2BAA2B;EAMjC,OAAO,MAAM;UAQrB"}
@@ -133,9 +133,11 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
133
133
  }
134
134
  messages = !store.convertMessage ? store.messages : this._converter.convertMessages(store.messages, (cache, m, idx) => {
135
135
  if (!store.convertMessage) return m;
136
- const autoStatus = getAutoStatus(idx === (store.messages?.length ?? 0) - 1, isRunning, false, false, void 0);
136
+ const isLast = idx === (store.messages?.length ?? 0) - 1;
137
+ const autoStatus = getAutoStatus(isLast, isRunning, false, false, void 0);
137
138
  if (cache && (cache.role !== "assistant" || !isAutoStatus(cache.status) || cache.status === autoStatus)) return cache;
138
- const newMessage = fromThreadMessageLike(store.convertMessage(m, idx), idx.toString(), autoStatus);
139
+ const messageLike = store.convertMessage(m, idx);
140
+ const newMessage = fromThreadMessageLike(messageLike, idx.toString(), autoStatus);
139
141
  bindExternalStoreMessage(newMessage, m);
140
142
  return newMessage;
141
143
  });
@@ -158,8 +160,10 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
158
160
  }
159
161
  } else throw new Error("ExternalStoreAdapter must provide either 'messages' or 'messageRepository'");
160
162
  if (messages.length > 0) this.ensureInitialized();
161
- if ((oldStore?.isRunning ?? false) !== (store.isRunning ?? false)) if (store.isRunning) this._notifyEventSubscribers("runStart", {});
162
- else this._notifyEventSubscribers("runEnd", {});
163
+ if ((oldStore?.isRunning ?? false) !== (store.isRunning ?? false)) {
164
+ if (store.isRunning) this._notifyEventSubscribers("runStart", {});
165
+ else this._notifyEventSubscribers("runEnd", {});
166
+ }
163
167
  let optimisticId = null;
164
168
  if (hasUpcomingMessage(isRunning, messages)) {
165
169
  optimisticId = generateId();
@@ -273,7 +277,7 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
273
277
  });
274
278
  }
275
279
  async append(message) {
276
- const isEdit = message.parentId !== (this.messages.at(-1)?.id ?? null);
280
+ const isEdit = message.sourceId != null || message.parentId !== (this.messages.at(-1)?.id ?? null);
277
281
  if (!isEdit && this._store.queue) {
278
282
  if (message.steer ?? this._store.isRunning ?? false) this._store.queue.steer(message);
279
283
  else this._store.queue.enqueue(message);
@@ -1 +1 @@
1
- {"version":3,"file":"external-store-thread-runtime-core.js","names":["AppendMessage","ThreadMessage","AddToolResultOptions","ResumeRunConfig","ResumeToolCallOptions","RespondToToolApprovalOptions","StartRunConfig","ThreadSuggestion","ExternalStoreAdapter","ExternalStoreBranchChange","getExternalStoreMessages","bindExternalStoreMessage","ThreadMessageConverter","getAutoStatus","isAutoStatus","fromThreadMessageLike","ThreadMessageLike","getThreadMessageText","RuntimeCapabilities","ThreadRuntimeCore","QueuePlacement","BaseThreadRuntimeCore","ModelContextProvider","ExportedMessageRepository","MessageRepository","generateId","ToolInvocationTracker","EMPTY_QUEUE_ITEMS","EMPTY_ARRAY","Object","freeze","shallowEqual","a","b","aKeys","keys","length","key","hasUpcomingMessage","isRunning","messages","role","ExternalStoreThreadRuntimeCore","_capabilities","switchToBranch","switchBranchDuringRun","edit","delete","reload","refetchThread","cancel","unstable_copy","speech","dictation","voice","attachments","feedback","queue","capabilities","_messages","isDisabled","isSendDisabled","isLoading","_store","_getBaseMessages","state","adapters","unstable_refetchThread","Promise","onRefetchThread","undefined","suggestions","extras","_converter","_toolInvocations","beginEdit","messageId","onEdit","Error","constructor","contextProvider","store","__internal_setAdapter","oldStore","newSuggestions","newCapabilities","setMessages","onDelete","onReload","onCancel","unstable_capabilities","copy","messageRepository","_notifySubscribers","incoming","headId","at","message","id","repository","resetHead","getMessages","incomingIds","Set","map","parentId","addOrUpdateMessage","export","has","deleteMessage","convertMessage","convertMessages","cache","m","idx","isLast","autoStatus","status","messageLike","newMessage","toString","seenIds","deduped","i","console","warn","add","push","reverse","parent","ensureInitialized","_notifyEventSubscribers","optimisticId","content","metadata","isOptimistic","type","_driveToolInvocations","unstable_enableToolInvocations","reset","setToolStatuses","getModelContext","tools","onResult","command","_findMessageIdForToolCall","toolCallId","onAddToolResult","toolName","result","isError","artifact","modelContent","err","error","onStatusesChange","statuses","fromEntries","setState","_toolCallToMessageId","Map","_messagesForToolCallIndex","clear","visit","Array","isArray","part","set","get","branchId","onBranchChange","unstable_onBranchChange","previousHeadId","canonicalHeadId","updateMessages","_notifyBranchChange","event","visibleMessageIds","append","isEdit","steer","enqueue","startRun","abort","onNew","messageIndex","findIndex","filter","getQueueItems","items","getSteerQueueItems","steerItems","moveQueueItem","queueItemId","placement","move","removeQueueItem","remove","config","resumeRun","onResume","exportExternalState","onExportExternalState","importExternalState","onLoadExternalState","cancelRun","head","previousMessage","composer","text","trim","setText","setTimeout","addToolResult","options","resumeToolCall","handled","resume","payload","onResumeToolCall","respondToToolApproval","onRespondToToolApproval","initialMessages","repo","import","fromArray","data","onImport","hasConverter","flatMap"],"sources":["../../../src/runtimes/external-store/external-store-thread-runtime-core.ts"],"sourcesContent":["import type { AppendMessage, ThreadMessage } from \"../../types/message\";\nimport type {\n AddToolResultOptions,\n ResumeRunConfig,\n ResumeToolCallOptions,\n RespondToToolApprovalOptions,\n StartRunConfig,\n ThreadSuggestion,\n} from \"../../runtime/interfaces/thread-runtime-core\";\n\nimport type {\n ExternalStoreAdapter,\n ExternalStoreBranchChange,\n} from \"./external-store-adapter\";\nimport {\n getExternalStoreMessages,\n bindExternalStoreMessage,\n} from \"../../runtime/utils/external-store-message\";\nimport { ThreadMessageConverter } from \"./thread-message-converter\";\nimport { getAutoStatus, isAutoStatus } from \"../../runtime/utils/auto-status\";\nimport {\n fromThreadMessageLike,\n type ThreadMessageLike,\n} from \"../../runtime/utils/thread-message-like\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport type {\n RuntimeCapabilities,\n ThreadRuntimeCore,\n} from \"../../runtime/interfaces/thread-runtime-core\";\nimport type { QueuePlacement } from \"../../runtime/queue/external-thread-queue-adapter\";\nimport { BaseThreadRuntimeCore } from \"../../runtime/base/base-thread-runtime-core\";\nimport type { ModelContextProvider } from \"../../model-context/types\";\nimport {\n ExportedMessageRepository,\n MessageRepository,\n} from \"../../runtime/utils/message-repository\";\nimport { generateId } from \"../../utils/id\";\nimport { ToolInvocationTracker } from \"../tool-invocations/ToolInvocationTracker\";\nimport { EMPTY_QUEUE_ITEMS } from \"../../store/scopes/queue-item\";\n\nconst EMPTY_ARRAY: readonly ThreadSuggestion[] = Object.freeze([]);\n\nconst shallowEqual = (a: object, b: object): boolean => {\n const aKeys = Object.keys(a);\n if (aKeys.length !== Object.keys(b).length) return false;\n for (const key of aKeys) {\n if ((a as any)[key] !== (b as any)[key]) return false;\n }\n return true;\n};\n\nexport const hasUpcomingMessage = (\n isRunning: boolean,\n messages: readonly ThreadMessage[],\n) => {\n return isRunning && messages[messages.length - 1]?.role !== \"assistant\";\n};\n\nexport class ExternalStoreThreadRuntimeCore\n extends BaseThreadRuntimeCore\n implements ThreadRuntimeCore\n{\n private _capabilities: RuntimeCapabilities = {\n switchToBranch: false,\n switchBranchDuringRun: false,\n edit: false,\n delete: false,\n reload: false,\n refetchThread: false,\n cancel: false,\n unstable_copy: false,\n speech: false,\n dictation: false,\n voice: false,\n attachments: false,\n feedback: false,\n queue: false,\n };\n\n public get capabilities() {\n return this._capabilities;\n }\n\n private _messages!: readonly ThreadMessage[];\n public isDisabled!: boolean;\n public isSendDisabled!: boolean;\n public get isLoading() {\n return this._store.isLoading ?? false;\n }\n // Unlike `isLoading`: pass `undefined` through to preserve the `getThreadState` fallback.\n public get isRunning(): boolean | undefined {\n return this._store.isRunning;\n }\n\n protected override _getBaseMessages(): readonly ThreadMessage[] {\n return this._messages;\n }\n\n public override get state() {\n return this._store.state ?? super.state;\n }\n\n public get adapters() {\n return this._store.adapters;\n }\n\n // A getter, not a method, so its presence tracks the adapter.\n public get unstable_refetchThread(): (() => Promise<void>) | undefined {\n if (!this._store.onRefetchThread) return undefined;\n return () => this._store.onRefetchThread!();\n }\n\n public suggestions: readonly ThreadSuggestion[] = [];\n public extras: unknown = undefined;\n\n private _converter = new ThreadMessageConverter();\n\n private _store!: ExternalStoreAdapter<any>;\n\n /**\n * Client-side tool-invocations pipeline. Constructed lazily on first\n * snapshot — only when `adapter.unstable_enableToolInvocations === true`.\n */\n private _toolInvocations: ToolInvocationTracker | null = null;\n\n public override beginEdit(messageId: string) {\n if (!this._store.onEdit)\n throw new Error(\"Runtime does not support editing.\");\n\n super.beginEdit(messageId);\n }\n\n constructor(\n contextProvider: ModelContextProvider,\n store: ExternalStoreAdapter<any>,\n ) {\n super(contextProvider);\n this.__internal_setAdapter(store);\n }\n\n public __internal_setAdapter(store: ExternalStoreAdapter<any>) {\n if (this._store === store) return;\n\n const isRunning = store.isRunning ?? false;\n this.isDisabled = store.isDisabled ?? false;\n this.isSendDisabled = store.isSendDisabled ?? false;\n\n const oldStore = this._store as ExternalStoreAdapter<any> | undefined;\n this._store = store;\n if (this.extras !== store.extras) {\n this.extras = store.extras;\n }\n\n const newSuggestions = store.suggestions ?? EMPTY_ARRAY;\n if (!shallowEqual(this.suggestions, newSuggestions)) {\n this.suggestions = newSuggestions;\n }\n\n const newCapabilities: RuntimeCapabilities = {\n switchToBranch: this._store.setMessages !== undefined,\n switchBranchDuringRun: false,\n edit: this._store.onEdit !== undefined,\n delete:\n this._store.onDelete !== undefined ||\n this._store.setMessages !== undefined,\n reload: this._store.onReload !== undefined,\n refetchThread: this._store.onRefetchThread !== undefined,\n cancel: this._store.onCancel !== undefined,\n speech: this._store.adapters?.speech !== undefined,\n dictation: this._store.adapters?.dictation !== undefined,\n voice: this._store.adapters?.voice !== undefined,\n unstable_copy: this._store.unstable_capabilities?.copy !== false,\n attachments: !!this._store.adapters?.attachments,\n feedback: !!this._store.adapters?.feedback,\n queue: this._store.queue !== undefined,\n };\n if (!shallowEqual(this._capabilities, newCapabilities)) {\n this._capabilities = newCapabilities;\n }\n\n let messages: readonly ThreadMessage[];\n\n if (store.messageRepository) {\n // Handle messageRepository\n if (\n oldStore &&\n oldStore.isRunning === store.isRunning &&\n oldStore.messageRepository === store.messageRepository\n ) {\n this._notifySubscribers();\n return;\n }\n\n const incoming = store.messageRepository.messages;\n const headId =\n store.messageRepository.headId ?? incoming.at(-1)?.message.id ?? null;\n\n if (oldStore && oldStore.messageRepository === store.messageRepository) {\n this.repository.resetHead(headId);\n messages = this.repository.getMessages();\n } else {\n const incomingIds = new Set(incoming.map(({ message }) => message.id));\n for (const { message, parentId } of incoming) {\n this.repository.addOrUpdateMessage(parentId, message);\n }\n for (const { message } of this.repository.export().messages) {\n if (!incomingIds.has(message.id)) {\n this.repository.deleteMessage(message.id);\n }\n }\n this.repository.resetHead(headId);\n messages = this.repository.getMessages();\n }\n } else if (store.messages) {\n // Handle messages array\n\n if (oldStore) {\n // flush the converter cache when the convertMessage prop changes\n if (oldStore.convertMessage !== store.convertMessage) {\n this._converter = new ThreadMessageConverter();\n } else if (\n oldStore.isRunning === store.isRunning &&\n oldStore.messages === store.messages\n ) {\n this._notifySubscribers();\n // no conversion update\n return;\n }\n }\n\n messages = !store.convertMessage\n ? store.messages\n : this._converter.convertMessages(store.messages, (cache, m, idx) => {\n if (!store.convertMessage) return m;\n\n const isLast = idx === (store.messages?.length ?? 0) - 1;\n const autoStatus = getAutoStatus(\n isLast,\n isRunning,\n false,\n false,\n undefined,\n );\n\n if (\n cache &&\n (cache.role !== \"assistant\" ||\n !isAutoStatus(cache.status) ||\n cache.status === autoStatus)\n )\n return cache;\n\n const messageLike = store.convertMessage(m, idx);\n const newMessage = fromThreadMessageLike(\n messageLike,\n idx.toString(),\n autoStatus,\n );\n bindExternalStoreMessage(newMessage, m);\n return newMessage;\n });\n\n const seenIds = new Set<string>();\n const deduped: ThreadMessage[] = [];\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]!;\n if (seenIds.has(message.id)) {\n console.warn(\n `ExternalStoreThreadRuntimeCore: duplicate message id \"${message.id}\" in the provided messages array; keeping the last occurrence.`,\n );\n continue;\n }\n seenIds.add(message.id);\n deduped.push(message);\n }\n if (deduped.length !== messages.length) messages = deduped.reverse();\n\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i]!;\n const parent = messages[i - 1];\n this.repository.addOrUpdateMessage(parent?.id ?? null, message);\n }\n } else {\n throw new Error(\n \"ExternalStoreAdapter must provide either 'messages' or 'messageRepository'\",\n );\n }\n\n // Common logic for both paths\n if (messages.length > 0) this.ensureInitialized();\n\n if ((oldStore?.isRunning ?? false) !== (store.isRunning ?? false)) {\n if (store.isRunning) {\n this._notifyEventSubscribers(\"runStart\", {});\n } else {\n this._notifyEventSubscribers(\"runEnd\", {});\n }\n }\n\n // Append an optimistic placeholder while running but before a trailing\n // assistant message exists. resetHead evicts off-branch optimistic messages\n // (prior placeholders, mid-run id-swap siblings); export() never persists them.\n let optimisticId: string | null = null;\n if (hasUpcomingMessage(isRunning, messages)) {\n optimisticId = generateId();\n this.repository.addOrUpdateMessage(\n messages.at(-1)?.id ?? null,\n fromThreadMessageLike(\n { role: \"assistant\", content: [], metadata: { isOptimistic: true } },\n optimisticId,\n { type: \"running\" },\n ),\n );\n }\n\n this.repository.resetHead(optimisticId ?? messages.at(-1)?.id ?? null);\n\n this._messages = this.repository.getMessages();\n\n this._driveToolInvocations();\n\n this._notifySubscribers();\n }\n\n /**\n * Feed the current message snapshot into the tool-invocations tracker.\n * Opt-in via `adapter.unstable_enableToolInvocations: true`. The tracker\n * itself is fail-silent — see ToolInvocationTracker for the\n * state-transition contract.\n */\n private _driveToolInvocations(): void {\n if (!this._store.unstable_enableToolInvocations) {\n // Adapter did not opt in (default). If a tracker was previously\n // constructed (e.g. the adapter just toggled the flag off via a\n // dynamic swap), drop it so subsequent snapshots are no-ops.\n if (this._toolInvocations) {\n this._toolInvocations.reset();\n this._toolInvocations = null;\n this._store.setToolStatuses?.({});\n }\n return;\n }\n\n if (!this._toolInvocations) {\n this._toolInvocations = new ToolInvocationTracker(\n () => this.getModelContext().tools,\n {\n onResult: (command) => {\n try {\n const messageId = this._findMessageIdForToolCall(\n command.toolCallId,\n );\n if (messageId === undefined) {\n // The tool call no longer exists in the snapshot (e.g.\n // rolled back). Drop the result.\n return;\n }\n this._store.onAddToolResult?.({\n messageId,\n toolCallId: command.toolCallId,\n toolName: command.toolName,\n result: command.result,\n isError: command.isError,\n ...(command.artifact !== undefined && {\n artifact: command.artifact,\n }),\n ...(command.modelContent !== undefined && {\n modelContent: command.modelContent,\n }),\n });\n } catch (err) {\n console.error(\n \"[ExternalStoreThreadRuntimeCore] onAddToolResult dispatch failed\",\n err,\n );\n }\n },\n onStatusesChange: (statuses) => {\n this._store.setToolStatuses?.(Object.fromEntries(statuses));\n },\n },\n );\n }\n\n this._toolInvocations.setState({\n messages: this._messages,\n isRunning: this._store.isRunning ?? false,\n ...(this._store.isLoading !== undefined && {\n isLoading: this._store.isLoading,\n }),\n });\n }\n\n /**\n * Lookup table from `toolCallId` to the owning assistant message's `id`,\n * rebuilt lazily when `_messages` changes (see `_messagesForToolCallIndex`).\n */\n private _toolCallToMessageId = new Map<string, string>();\n private _messagesForToolCallIndex: readonly ThreadMessage[] | null = null;\n\n /**\n * Look up the assistant message that owns a tool-call part. Lazily builds\n * (and caches) a `toolCallId → messageId` map keyed off the current\n * `_messages` reference, so onResult dispatches stay O(1) instead of\n * walking the full thread on every result.\n */\n private _findMessageIdForToolCall(toolCallId: string): string | undefined {\n if (this._messagesForToolCallIndex !== this._messages) {\n this._toolCallToMessageId.clear();\n const visit = (messages: readonly ThreadMessage[]): void => {\n for (const message of messages) {\n if (!Array.isArray(message.content)) continue;\n for (const part of message.content) {\n if (!part || part.type !== \"tool-call\") continue;\n this._toolCallToMessageId.set(part.toolCallId, message.id);\n if (part.messages) visit(part.messages);\n }\n }\n };\n visit(this._messages);\n this._messagesForToolCallIndex = this._messages;\n }\n return this._toolCallToMessageId.get(toolCallId);\n }\n\n public override switchToBranch(branchId: string): void {\n if (!this._store.setMessages)\n throw new Error(\"Runtime does not support switching branches.\");\n\n // Silently ignore branch switches while running\n if (this._store.isRunning) {\n return;\n }\n\n const onBranchChange = this._store.unstable_onBranchChange;\n const previousHeadId = onBranchChange\n ? this.repository.canonicalHeadId\n : null;\n\n this.repository.switchToBranch(branchId);\n this.updateMessages(this.repository.getMessages());\n if (onBranchChange) {\n this._notifyBranchChange(previousHeadId, onBranchChange);\n }\n }\n\n /**\n * Emit `unstable_onBranchChange` for an explicit branch switch. Reads the\n * canonical head from the repository (which skips optimistic/transient\n * messages) and de-dupes switches that leave the canonical head unchanged.\n * Comparing against the head observed just before the switch — rather than the\n * last emitted head — keeps a switch firing after an adapter resync moved the\n * head elsewhere in the meantime.\n */\n private _notifyBranchChange(\n previousHeadId: string | null,\n onBranchChange: (event: ExternalStoreBranchChange) => void,\n ): void {\n const headId = this.repository.canonicalHeadId;\n if (headId === previousHeadId) return;\n\n onBranchChange({\n headId,\n visibleMessageIds: this.repository.getMessages().map((m) => m.id),\n });\n }\n\n public async append(message: AppendMessage): Promise<void> {\n const isEdit = message.parentId !== (this.messages.at(-1)?.id ?? null);\n\n // Buffering does not start a run, so the tool-abort below must wait until\n // the queue flushes. By then the prior run (and its tools) has settled.\n if (!isEdit && this._store.queue) {\n if (message.steer ?? this._store.isRunning ?? false)\n this._store.queue.steer(message);\n else this._store.queue.enqueue(message);\n return;\n }\n\n // Auto-abort in-flight client-side tool executions when a new run is\n // about to start. Without this, a tool that finishes after the new turn\n // begins would feed a stale result into `onAddToolResult`, racing with\n // the new turn the user just initiated. `startRun` defaults to true for\n // user messages — matches the satellites' historical opt-in cancel\n // behavior, which is now built in.\n if (message.startRun ?? message.role === \"user\") {\n await this._toolInvocations?.abort();\n }\n\n if (isEdit) {\n if (!this._store.onEdit)\n throw new Error(\"Runtime does not support editing messages.\");\n await this._store.onEdit(message);\n } else {\n await this._store.onNew(message);\n }\n }\n\n public async deleteMessage(messageId: string): Promise<void> {\n if (this._store.onDelete) {\n await this._store.onDelete(messageId);\n return;\n }\n\n if (!this._store.setMessages)\n throw new Error(\"Runtime does not support deleting messages.\");\n\n if (this._store.isRunning) {\n await this._toolInvocations?.abort();\n }\n\n const messages = this.repository.getMessages();\n const messageIndex = messages.findIndex((m) => m.id === messageId);\n if (messageIndex === -1) throw new Error(\"Message not found.\");\n\n this.updateMessages(messages.filter((message) => message.id !== messageId));\n }\n\n public getQueueItems() {\n // The composer reads this during base-thread construction, before the\n // constructor assigns `_store`, so guard against the unset field.\n return this._store?.queue?.items ?? EMPTY_QUEUE_ITEMS;\n }\n\n public getSteerQueueItems() {\n return this._store?.queue?.steerItems ?? EMPTY_QUEUE_ITEMS;\n }\n\n public moveQueueItem(queueItemId: string, placement: QueuePlacement) {\n this._store?.queue?.move(queueItemId, placement);\n }\n\n public removeQueueItem(queueItemId: string) {\n this._store?.queue?.remove(queueItemId);\n }\n\n public async startRun(config: StartRunConfig): Promise<void> {\n if (!this._store.onReload)\n throw new Error(\"Runtime does not support reloading messages.\");\n\n // Auto-abort in-flight client-side tool executions when a run reloads;\n // any results that land afterward would target a turn that no longer\n // exists. See `append` above for full rationale.\n await this._toolInvocations?.abort();\n\n await this._store.onReload(config.parentId, config);\n }\n\n public async resumeRun(config: ResumeRunConfig): Promise<void> {\n if (!this._store.onResume)\n throw new Error(\"Runtime does not support resuming runs.\");\n\n await this._store.onResume(config);\n }\n\n public exportExternalState(): any {\n if (!this._store.onExportExternalState)\n throw new Error(\"Runtime does not support exporting external states.\");\n\n return this._store.onExportExternalState();\n }\n\n public importExternalState(state: any): void {\n if (!this._store.onLoadExternalState)\n throw new Error(\"Runtime does not support importing external states.\");\n\n // Re-arm the tracker so the next adapter snapshot (containing the\n // imported state) is treated as historical — no streamCall/execute\n // fires for the loaded tool calls. The adapter is expected to update\n // its messages in response to onLoadExternalState; that update flows\n // back here via __internal_setAdapter. We only clear adapter-side\n // tool statuses when the tracker is the source of truth — otherwise\n // we'd wipe statuses the adapter is managing on its own.\n if (this._toolInvocations) {\n this._toolInvocations.reset();\n this._store.setToolStatuses?.({});\n }\n\n this._store.onLoadExternalState(state);\n }\n\n public cancelRun(): void {\n if (!this._store.onCancel)\n throw new Error(\"Runtime does not support cancelling runs.\");\n\n // Abort any in-flight client-side tool executions. Fire-and-forget —\n // the abort resolves once executions settle, but we don't gate the\n // cancel on it.\n void this._toolInvocations?.abort();\n\n this._store.onCancel();\n\n // Drop an empty optimistic head (placeholder or pre-stream message); a\n // partially-streamed one is kept and re-supplied by the store on resync.\n const head = this.repository.getMessages().at(-1);\n if (head && head.metadata.isOptimistic && head.content.length === 0) {\n this.repository.deleteMessage(head.id);\n }\n\n let messages = this.repository.getMessages();\n const previousMessage = messages[messages.length - 1];\n if (\n previousMessage?.role === \"user\" &&\n previousMessage.id === messages.at(-1)?.id // ensure the previous message is a leaf node\n ) {\n this.repository.deleteMessage(previousMessage.id);\n if (!this.composer.text.trim()) {\n this.composer.setText(getThreadMessageText(previousMessage));\n }\n\n messages = this.repository.getMessages();\n } else {\n this._notifySubscribers();\n }\n\n // resync messages (for reloading, to restore the previous branch)\n setTimeout(() => {\n this.updateMessages(messages);\n }, 0);\n }\n\n public addToolResult(options: AddToolResultOptions) {\n if (!this._store.onAddToolResult)\n throw new Error(\"Runtime does not support tool results.\");\n this._store.onAddToolResult?.(options);\n }\n\n public resumeToolCall(options: ResumeToolCallOptions) {\n // Tracker owns its own human-input handlers — let it resume in-process\n // tool calls without round-tripping through the adapter. Falls back to\n // the adapter's onResumeToolCall (if any) for tool calls the tracker\n // doesn't know about.\n const handled =\n this._toolInvocations?.resume(options.toolCallId, options.payload) ??\n false;\n if (handled) return;\n\n if (this._store.onResumeToolCall) {\n this._store.onResumeToolCall(options);\n return;\n }\n\n throw new Error(\n `Tool call ${options.toolCallId} is not waiting for resume.`,\n );\n }\n\n public respondToToolApproval(options: RespondToToolApprovalOptions) {\n if (!this._store.onRespondToToolApproval)\n throw new Error(\"Runtime does not support tool approvals.\");\n this._store.onRespondToToolApproval(options);\n }\n\n public override reset(initialMessages?: readonly ThreadMessageLike[]) {\n const repo = new MessageRepository();\n repo.import(ExportedMessageRepository.fromArray(initialMessages ?? []));\n this.updateMessages(repo.getMessages());\n }\n\n public override import(data: ExportedMessageRepository) {\n super.import(data);\n\n if (this._store.onImport) {\n this._store.onImport(this.repository.getMessages());\n }\n }\n\n private updateMessages = (messages: readonly ThreadMessage[]) => {\n const hasConverter = this._store.convertMessage !== undefined;\n if (hasConverter) {\n this._store.setMessages?.(messages.flatMap(getExternalStoreMessages));\n } else {\n // TODO mark this as readonly in v0.12.0\n this._store.setMessages?.(messages as ThreadMessage[]);\n }\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"external-store-thread-runtime-core.js","names":["AppendMessage","ThreadMessage","AddToolResultOptions","ResumeRunConfig","ResumeToolCallOptions","RespondToToolApprovalOptions","StartRunConfig","ThreadSuggestion","ExternalStoreAdapter","ExternalStoreBranchChange","getExternalStoreMessages","bindExternalStoreMessage","ThreadMessageConverter","getAutoStatus","isAutoStatus","fromThreadMessageLike","ThreadMessageLike","getThreadMessageText","RuntimeCapabilities","ThreadRuntimeCore","QueuePlacement","BaseThreadRuntimeCore","ModelContextProvider","ExportedMessageRepository","MessageRepository","generateId","ToolInvocationTracker","EMPTY_QUEUE_ITEMS","EMPTY_ARRAY","Object","freeze","shallowEqual","a","b","aKeys","keys","length","key","hasUpcomingMessage","isRunning","messages","role","ExternalStoreThreadRuntimeCore","_capabilities","switchToBranch","switchBranchDuringRun","edit","delete","reload","refetchThread","cancel","unstable_copy","speech","dictation","voice","attachments","feedback","queue","capabilities","_messages","isDisabled","isSendDisabled","isLoading","_store","_getBaseMessages","state","adapters","unstable_refetchThread","Promise","onRefetchThread","undefined","suggestions","extras","_converter","_toolInvocations","beginEdit","messageId","onEdit","Error","constructor","contextProvider","store","__internal_setAdapter","oldStore","newSuggestions","newCapabilities","setMessages","onDelete","onReload","onCancel","unstable_capabilities","copy","messageRepository","_notifySubscribers","incoming","headId","at","message","id","repository","resetHead","getMessages","incomingIds","Set","map","parentId","addOrUpdateMessage","export","has","deleteMessage","convertMessage","convertMessages","cache","m","idx","isLast","autoStatus","status","messageLike","newMessage","toString","seenIds","deduped","i","console","warn","add","push","reverse","parent","ensureInitialized","_notifyEventSubscribers","optimisticId","content","metadata","isOptimistic","type","_driveToolInvocations","unstable_enableToolInvocations","reset","setToolStatuses","getModelContext","tools","onResult","command","_findMessageIdForToolCall","toolCallId","onAddToolResult","toolName","result","isError","artifact","modelContent","err","error","onStatusesChange","statuses","fromEntries","setState","_toolCallToMessageId","Map","_messagesForToolCallIndex","clear","visit","Array","isArray","part","set","get","branchId","onBranchChange","unstable_onBranchChange","previousHeadId","canonicalHeadId","updateMessages","_notifyBranchChange","event","visibleMessageIds","append","isEdit","sourceId","steer","enqueue","startRun","abort","onNew","messageIndex","findIndex","filter","getQueueItems","items","getSteerQueueItems","steerItems","moveQueueItem","queueItemId","placement","move","removeQueueItem","remove","config","resumeRun","onResume","exportExternalState","onExportExternalState","importExternalState","onLoadExternalState","cancelRun","head","previousMessage","composer","text","trim","setText","setTimeout","addToolResult","options","resumeToolCall","handled","resume","payload","onResumeToolCall","respondToToolApproval","onRespondToToolApproval","initialMessages","repo","import","fromArray","data","onImport","hasConverter","flatMap"],"sources":["../../../src/runtimes/external-store/external-store-thread-runtime-core.ts"],"sourcesContent":["import type { AppendMessage, ThreadMessage } from \"../../types/message\";\nimport type {\n AddToolResultOptions,\n ResumeRunConfig,\n ResumeToolCallOptions,\n RespondToToolApprovalOptions,\n StartRunConfig,\n ThreadSuggestion,\n} from \"../../runtime/interfaces/thread-runtime-core\";\n\nimport type {\n ExternalStoreAdapter,\n ExternalStoreBranchChange,\n} from \"./external-store-adapter\";\nimport {\n getExternalStoreMessages,\n bindExternalStoreMessage,\n} from \"../../runtime/utils/external-store-message\";\nimport { ThreadMessageConverter } from \"./thread-message-converter\";\nimport { getAutoStatus, isAutoStatus } from \"../../runtime/utils/auto-status\";\nimport {\n fromThreadMessageLike,\n type ThreadMessageLike,\n} from \"../../runtime/utils/thread-message-like\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport type {\n RuntimeCapabilities,\n ThreadRuntimeCore,\n} from \"../../runtime/interfaces/thread-runtime-core\";\nimport type { QueuePlacement } from \"../../runtime/queue/external-thread-queue-adapter\";\nimport { BaseThreadRuntimeCore } from \"../../runtime/base/base-thread-runtime-core\";\nimport type { ModelContextProvider } from \"../../model-context/types\";\nimport {\n ExportedMessageRepository,\n MessageRepository,\n} from \"../../runtime/utils/message-repository\";\nimport { generateId } from \"../../utils/id\";\nimport { ToolInvocationTracker } from \"../tool-invocations/ToolInvocationTracker\";\nimport { EMPTY_QUEUE_ITEMS } from \"../../store/scopes/queue-item\";\n\nconst EMPTY_ARRAY: readonly ThreadSuggestion[] = Object.freeze([]);\n\nconst shallowEqual = (a: object, b: object): boolean => {\n const aKeys = Object.keys(a);\n if (aKeys.length !== Object.keys(b).length) return false;\n for (const key of aKeys) {\n if ((a as any)[key] !== (b as any)[key]) return false;\n }\n return true;\n};\n\nexport const hasUpcomingMessage = (\n isRunning: boolean,\n messages: readonly ThreadMessage[],\n) => {\n return isRunning && messages[messages.length - 1]?.role !== \"assistant\";\n};\n\nexport class ExternalStoreThreadRuntimeCore\n extends BaseThreadRuntimeCore\n implements ThreadRuntimeCore\n{\n private _capabilities: RuntimeCapabilities = {\n switchToBranch: false,\n switchBranchDuringRun: false,\n edit: false,\n delete: false,\n reload: false,\n refetchThread: false,\n cancel: false,\n unstable_copy: false,\n speech: false,\n dictation: false,\n voice: false,\n attachments: false,\n feedback: false,\n queue: false,\n };\n\n public get capabilities() {\n return this._capabilities;\n }\n\n private _messages!: readonly ThreadMessage[];\n public isDisabled!: boolean;\n public isSendDisabled!: boolean;\n public get isLoading() {\n return this._store.isLoading ?? false;\n }\n // Unlike `isLoading`: pass `undefined` through to preserve the `getThreadState` fallback.\n public get isRunning(): boolean | undefined {\n return this._store.isRunning;\n }\n\n protected override _getBaseMessages(): readonly ThreadMessage[] {\n return this._messages;\n }\n\n public override get state() {\n return this._store.state ?? super.state;\n }\n\n public get adapters() {\n return this._store.adapters;\n }\n\n // A getter, not a method, so its presence tracks the adapter.\n public get unstable_refetchThread(): (() => Promise<void>) | undefined {\n if (!this._store.onRefetchThread) return undefined;\n return () => this._store.onRefetchThread!();\n }\n\n public suggestions: readonly ThreadSuggestion[] = [];\n public extras: unknown = undefined;\n\n private _converter = new ThreadMessageConverter();\n\n private _store!: ExternalStoreAdapter<any>;\n\n /**\n * Client-side tool-invocations pipeline. Constructed lazily on first\n * snapshot — only when `adapter.unstable_enableToolInvocations === true`.\n */\n private _toolInvocations: ToolInvocationTracker | null = null;\n\n public override beginEdit(messageId: string) {\n if (!this._store.onEdit)\n throw new Error(\"Runtime does not support editing.\");\n\n super.beginEdit(messageId);\n }\n\n constructor(\n contextProvider: ModelContextProvider,\n store: ExternalStoreAdapter<any>,\n ) {\n super(contextProvider);\n this.__internal_setAdapter(store);\n }\n\n public __internal_setAdapter(store: ExternalStoreAdapter<any>) {\n if (this._store === store) return;\n\n const isRunning = store.isRunning ?? false;\n this.isDisabled = store.isDisabled ?? false;\n this.isSendDisabled = store.isSendDisabled ?? false;\n\n const oldStore = this._store as ExternalStoreAdapter<any> | undefined;\n this._store = store;\n if (this.extras !== store.extras) {\n this.extras = store.extras;\n }\n\n const newSuggestions = store.suggestions ?? EMPTY_ARRAY;\n if (!shallowEqual(this.suggestions, newSuggestions)) {\n this.suggestions = newSuggestions;\n }\n\n const newCapabilities: RuntimeCapabilities = {\n switchToBranch: this._store.setMessages !== undefined,\n switchBranchDuringRun: false,\n edit: this._store.onEdit !== undefined,\n delete:\n this._store.onDelete !== undefined ||\n this._store.setMessages !== undefined,\n reload: this._store.onReload !== undefined,\n refetchThread: this._store.onRefetchThread !== undefined,\n cancel: this._store.onCancel !== undefined,\n speech: this._store.adapters?.speech !== undefined,\n dictation: this._store.adapters?.dictation !== undefined,\n voice: this._store.adapters?.voice !== undefined,\n unstable_copy: this._store.unstable_capabilities?.copy !== false,\n attachments: !!this._store.adapters?.attachments,\n feedback: !!this._store.adapters?.feedback,\n queue: this._store.queue !== undefined,\n };\n if (!shallowEqual(this._capabilities, newCapabilities)) {\n this._capabilities = newCapabilities;\n }\n\n let messages: readonly ThreadMessage[];\n\n if (store.messageRepository) {\n // Handle messageRepository\n if (\n oldStore &&\n oldStore.isRunning === store.isRunning &&\n oldStore.messageRepository === store.messageRepository\n ) {\n this._notifySubscribers();\n return;\n }\n\n const incoming = store.messageRepository.messages;\n const headId =\n store.messageRepository.headId ?? incoming.at(-1)?.message.id ?? null;\n\n if (oldStore && oldStore.messageRepository === store.messageRepository) {\n this.repository.resetHead(headId);\n messages = this.repository.getMessages();\n } else {\n const incomingIds = new Set(incoming.map(({ message }) => message.id));\n for (const { message, parentId } of incoming) {\n this.repository.addOrUpdateMessage(parentId, message);\n }\n for (const { message } of this.repository.export().messages) {\n if (!incomingIds.has(message.id)) {\n this.repository.deleteMessage(message.id);\n }\n }\n this.repository.resetHead(headId);\n messages = this.repository.getMessages();\n }\n } else if (store.messages) {\n // Handle messages array\n\n if (oldStore) {\n // flush the converter cache when the convertMessage prop changes\n if (oldStore.convertMessage !== store.convertMessage) {\n this._converter = new ThreadMessageConverter();\n } else if (\n oldStore.isRunning === store.isRunning &&\n oldStore.messages === store.messages\n ) {\n this._notifySubscribers();\n // no conversion update\n return;\n }\n }\n\n messages = !store.convertMessage\n ? store.messages\n : this._converter.convertMessages(store.messages, (cache, m, idx) => {\n if (!store.convertMessage) return m;\n\n const isLast = idx === (store.messages?.length ?? 0) - 1;\n const autoStatus = getAutoStatus(\n isLast,\n isRunning,\n false,\n false,\n undefined,\n );\n\n if (\n cache &&\n (cache.role !== \"assistant\" ||\n !isAutoStatus(cache.status) ||\n cache.status === autoStatus)\n )\n return cache;\n\n const messageLike = store.convertMessage(m, idx);\n const newMessage = fromThreadMessageLike(\n messageLike,\n idx.toString(),\n autoStatus,\n );\n bindExternalStoreMessage(newMessage, m);\n return newMessage;\n });\n\n const seenIds = new Set<string>();\n const deduped: ThreadMessage[] = [];\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]!;\n if (seenIds.has(message.id)) {\n console.warn(\n `ExternalStoreThreadRuntimeCore: duplicate message id \"${message.id}\" in the provided messages array; keeping the last occurrence.`,\n );\n continue;\n }\n seenIds.add(message.id);\n deduped.push(message);\n }\n if (deduped.length !== messages.length) messages = deduped.reverse();\n\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i]!;\n const parent = messages[i - 1];\n this.repository.addOrUpdateMessage(parent?.id ?? null, message);\n }\n } else {\n throw new Error(\n \"ExternalStoreAdapter must provide either 'messages' or 'messageRepository'\",\n );\n }\n\n // Common logic for both paths\n if (messages.length > 0) this.ensureInitialized();\n\n if ((oldStore?.isRunning ?? false) !== (store.isRunning ?? false)) {\n if (store.isRunning) {\n this._notifyEventSubscribers(\"runStart\", {});\n } else {\n this._notifyEventSubscribers(\"runEnd\", {});\n }\n }\n\n // Append an optimistic placeholder while running but before a trailing\n // assistant message exists. resetHead evicts off-branch optimistic messages\n // (prior placeholders, mid-run id-swap siblings); export() never persists them.\n let optimisticId: string | null = null;\n if (hasUpcomingMessage(isRunning, messages)) {\n optimisticId = generateId();\n this.repository.addOrUpdateMessage(\n messages.at(-1)?.id ?? null,\n fromThreadMessageLike(\n { role: \"assistant\", content: [], metadata: { isOptimistic: true } },\n optimisticId,\n { type: \"running\" },\n ),\n );\n }\n\n this.repository.resetHead(optimisticId ?? messages.at(-1)?.id ?? null);\n\n this._messages = this.repository.getMessages();\n\n this._driveToolInvocations();\n\n this._notifySubscribers();\n }\n\n /**\n * Feed the current message snapshot into the tool-invocations tracker.\n * Opt-in via `adapter.unstable_enableToolInvocations: true`. The tracker\n * itself is fail-silent — see ToolInvocationTracker for the\n * state-transition contract.\n */\n private _driveToolInvocations(): void {\n if (!this._store.unstable_enableToolInvocations) {\n // Adapter did not opt in (default). If a tracker was previously\n // constructed (e.g. the adapter just toggled the flag off via a\n // dynamic swap), drop it so subsequent snapshots are no-ops.\n if (this._toolInvocations) {\n this._toolInvocations.reset();\n this._toolInvocations = null;\n this._store.setToolStatuses?.({});\n }\n return;\n }\n\n if (!this._toolInvocations) {\n this._toolInvocations = new ToolInvocationTracker(\n () => this.getModelContext().tools,\n {\n onResult: (command) => {\n try {\n const messageId = this._findMessageIdForToolCall(\n command.toolCallId,\n );\n if (messageId === undefined) {\n // The tool call no longer exists in the snapshot (e.g.\n // rolled back). Drop the result.\n return;\n }\n this._store.onAddToolResult?.({\n messageId,\n toolCallId: command.toolCallId,\n toolName: command.toolName,\n result: command.result,\n isError: command.isError,\n ...(command.artifact !== undefined && {\n artifact: command.artifact,\n }),\n ...(command.modelContent !== undefined && {\n modelContent: command.modelContent,\n }),\n });\n } catch (err) {\n console.error(\n \"[ExternalStoreThreadRuntimeCore] onAddToolResult dispatch failed\",\n err,\n );\n }\n },\n onStatusesChange: (statuses) => {\n this._store.setToolStatuses?.(Object.fromEntries(statuses));\n },\n },\n );\n }\n\n this._toolInvocations.setState({\n messages: this._messages,\n isRunning: this._store.isRunning ?? false,\n ...(this._store.isLoading !== undefined && {\n isLoading: this._store.isLoading,\n }),\n });\n }\n\n /**\n * Lookup table from `toolCallId` to the owning assistant message's `id`,\n * rebuilt lazily when `_messages` changes (see `_messagesForToolCallIndex`).\n */\n private _toolCallToMessageId = new Map<string, string>();\n private _messagesForToolCallIndex: readonly ThreadMessage[] | null = null;\n\n /**\n * Look up the assistant message that owns a tool-call part. Lazily builds\n * (and caches) a `toolCallId → messageId` map keyed off the current\n * `_messages` reference, so onResult dispatches stay O(1) instead of\n * walking the full thread on every result.\n */\n private _findMessageIdForToolCall(toolCallId: string): string | undefined {\n if (this._messagesForToolCallIndex !== this._messages) {\n this._toolCallToMessageId.clear();\n const visit = (messages: readonly ThreadMessage[]): void => {\n for (const message of messages) {\n if (!Array.isArray(message.content)) continue;\n for (const part of message.content) {\n if (!part || part.type !== \"tool-call\") continue;\n this._toolCallToMessageId.set(part.toolCallId, message.id);\n if (part.messages) visit(part.messages);\n }\n }\n };\n visit(this._messages);\n this._messagesForToolCallIndex = this._messages;\n }\n return this._toolCallToMessageId.get(toolCallId);\n }\n\n public override switchToBranch(branchId: string): void {\n if (!this._store.setMessages)\n throw new Error(\"Runtime does not support switching branches.\");\n\n // Silently ignore branch switches while running\n if (this._store.isRunning) {\n return;\n }\n\n const onBranchChange = this._store.unstable_onBranchChange;\n const previousHeadId = onBranchChange\n ? this.repository.canonicalHeadId\n : null;\n\n this.repository.switchToBranch(branchId);\n this.updateMessages(this.repository.getMessages());\n if (onBranchChange) {\n this._notifyBranchChange(previousHeadId, onBranchChange);\n }\n }\n\n /**\n * Emit `unstable_onBranchChange` for an explicit branch switch. Reads the\n * canonical head from the repository (which skips optimistic/transient\n * messages) and de-dupes switches that leave the canonical head unchanged.\n * Comparing against the head observed just before the switch — rather than the\n * last emitted head — keeps a switch firing after an adapter resync moved the\n * head elsewhere in the meantime.\n */\n private _notifyBranchChange(\n previousHeadId: string | null,\n onBranchChange: (event: ExternalStoreBranchChange) => void,\n ): void {\n const headId = this.repository.canonicalHeadId;\n if (headId === previousHeadId) return;\n\n onBranchChange({\n headId,\n visibleMessageIds: this.repository.getMessages().map((m) => m.id),\n });\n }\n\n public async append(message: AppendMessage): Promise<void> {\n // sourceId marks an edit send; the parent may coincide with the head\n // after a resync (e.g. cancelRun dropped the edited message).\n const isEdit =\n message.sourceId != null ||\n message.parentId !== (this.messages.at(-1)?.id ?? null);\n\n // Buffering does not start a run, so the tool-abort below must wait until\n // the queue flushes. By then the prior run (and its tools) has settled.\n if (!isEdit && this._store.queue) {\n if (message.steer ?? this._store.isRunning ?? false)\n this._store.queue.steer(message);\n else this._store.queue.enqueue(message);\n return;\n }\n\n // Auto-abort in-flight client-side tool executions when a new run is\n // about to start. Without this, a tool that finishes after the new turn\n // begins would feed a stale result into `onAddToolResult`, racing with\n // the new turn the user just initiated. `startRun` defaults to true for\n // user messages — matches the satellites' historical opt-in cancel\n // behavior, which is now built in.\n if (message.startRun ?? message.role === \"user\") {\n await this._toolInvocations?.abort();\n }\n\n if (isEdit) {\n if (!this._store.onEdit)\n throw new Error(\"Runtime does not support editing messages.\");\n await this._store.onEdit(message);\n } else {\n await this._store.onNew(message);\n }\n }\n\n public async deleteMessage(messageId: string): Promise<void> {\n if (this._store.onDelete) {\n await this._store.onDelete(messageId);\n return;\n }\n\n if (!this._store.setMessages)\n throw new Error(\"Runtime does not support deleting messages.\");\n\n if (this._store.isRunning) {\n await this._toolInvocations?.abort();\n }\n\n const messages = this.repository.getMessages();\n const messageIndex = messages.findIndex((m) => m.id === messageId);\n if (messageIndex === -1) throw new Error(\"Message not found.\");\n\n this.updateMessages(messages.filter((message) => message.id !== messageId));\n }\n\n public getQueueItems() {\n // The composer reads this during base-thread construction, before the\n // constructor assigns `_store`, so guard against the unset field.\n return this._store?.queue?.items ?? EMPTY_QUEUE_ITEMS;\n }\n\n public getSteerQueueItems() {\n return this._store?.queue?.steerItems ?? EMPTY_QUEUE_ITEMS;\n }\n\n public moveQueueItem(queueItemId: string, placement: QueuePlacement) {\n this._store?.queue?.move(queueItemId, placement);\n }\n\n public removeQueueItem(queueItemId: string) {\n this._store?.queue?.remove(queueItemId);\n }\n\n public async startRun(config: StartRunConfig): Promise<void> {\n if (!this._store.onReload)\n throw new Error(\"Runtime does not support reloading messages.\");\n\n // Auto-abort in-flight client-side tool executions when a run reloads;\n // any results that land afterward would target a turn that no longer\n // exists. See `append` above for full rationale.\n await this._toolInvocations?.abort();\n\n await this._store.onReload(config.parentId, config);\n }\n\n public async resumeRun(config: ResumeRunConfig): Promise<void> {\n if (!this._store.onResume)\n throw new Error(\"Runtime does not support resuming runs.\");\n\n await this._store.onResume(config);\n }\n\n public exportExternalState(): any {\n if (!this._store.onExportExternalState)\n throw new Error(\"Runtime does not support exporting external states.\");\n\n return this._store.onExportExternalState();\n }\n\n public importExternalState(state: any): void {\n if (!this._store.onLoadExternalState)\n throw new Error(\"Runtime does not support importing external states.\");\n\n // Re-arm the tracker so the next adapter snapshot (containing the\n // imported state) is treated as historical — no streamCall/execute\n // fires for the loaded tool calls. The adapter is expected to update\n // its messages in response to onLoadExternalState; that update flows\n // back here via __internal_setAdapter. We only clear adapter-side\n // tool statuses when the tracker is the source of truth — otherwise\n // we'd wipe statuses the adapter is managing on its own.\n if (this._toolInvocations) {\n this._toolInvocations.reset();\n this._store.setToolStatuses?.({});\n }\n\n this._store.onLoadExternalState(state);\n }\n\n public cancelRun(): void {\n if (!this._store.onCancel)\n throw new Error(\"Runtime does not support cancelling runs.\");\n\n // Abort any in-flight client-side tool executions. Fire-and-forget —\n // the abort resolves once executions settle, but we don't gate the\n // cancel on it.\n void this._toolInvocations?.abort();\n\n this._store.onCancel();\n\n // Drop an empty optimistic head (placeholder or pre-stream message); a\n // partially-streamed one is kept and re-supplied by the store on resync.\n const head = this.repository.getMessages().at(-1);\n if (head && head.metadata.isOptimistic && head.content.length === 0) {\n this.repository.deleteMessage(head.id);\n }\n\n let messages = this.repository.getMessages();\n const previousMessage = messages[messages.length - 1];\n if (\n previousMessage?.role === \"user\" &&\n previousMessage.id === messages.at(-1)?.id // ensure the previous message is a leaf node\n ) {\n this.repository.deleteMessage(previousMessage.id);\n if (!this.composer.text.trim()) {\n this.composer.setText(getThreadMessageText(previousMessage));\n }\n\n messages = this.repository.getMessages();\n } else {\n this._notifySubscribers();\n }\n\n // resync messages (for reloading, to restore the previous branch)\n setTimeout(() => {\n this.updateMessages(messages);\n }, 0);\n }\n\n public addToolResult(options: AddToolResultOptions) {\n if (!this._store.onAddToolResult)\n throw new Error(\"Runtime does not support tool results.\");\n this._store.onAddToolResult?.(options);\n }\n\n public resumeToolCall(options: ResumeToolCallOptions) {\n // Tracker owns its own human-input handlers — let it resume in-process\n // tool calls without round-tripping through the adapter. Falls back to\n // the adapter's onResumeToolCall (if any) for tool calls the tracker\n // doesn't know about.\n const handled =\n this._toolInvocations?.resume(options.toolCallId, options.payload) ??\n false;\n if (handled) return;\n\n if (this._store.onResumeToolCall) {\n this._store.onResumeToolCall(options);\n return;\n }\n\n throw new Error(\n `Tool call ${options.toolCallId} is not waiting for resume.`,\n );\n }\n\n public respondToToolApproval(options: RespondToToolApprovalOptions) {\n if (!this._store.onRespondToToolApproval)\n throw new Error(\"Runtime does not support tool approvals.\");\n this._store.onRespondToToolApproval(options);\n }\n\n public override reset(initialMessages?: readonly ThreadMessageLike[]) {\n const repo = new MessageRepository();\n repo.import(ExportedMessageRepository.fromArray(initialMessages ?? []));\n this.updateMessages(repo.getMessages());\n }\n\n public override import(data: ExportedMessageRepository) {\n super.import(data);\n\n if (this._store.onImport) {\n this._store.onImport(this.repository.getMessages());\n }\n }\n\n private updateMessages = (messages: readonly ThreadMessage[]) => {\n const hasConverter = this._store.convertMessage !== undefined;\n if (hasConverter) {\n this._store.setMessages?.(messages.flatMap(getExternalStoreMessages));\n } else {\n // TODO mark this as readonly in v0.12.0\n this._store.setMessages?.(messages as ThreadMessage[]);\n }\n };\n}\n"],"mappings":"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"}
@@ -284,10 +284,11 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
284
284
  const adapter = this.adapters.suggestion;
285
285
  (async () => {
286
286
  try {
287
- await consumeSuggestionResult(adapter.generate({
287
+ const promiseOrGenerator = adapter.generate({
288
288
  messages: this.messages,
289
289
  signal
290
- }), {
290
+ });
291
+ await consumeSuggestionResult(promiseOrGenerator, {
291
292
  signal,
292
293
  onUpdate: (r) => {
293
294
  this._suggestions = r;
@@ -425,10 +426,12 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
425
426
  this._suggestionsController = null;
426
427
  }
427
428
  cancelRun() {
428
- if (this._queue) if (this._options.unstable_queueClearOnCancel ?? true) this._queue.clear();
429
- else {
430
- this._queue.notifyCancelled();
431
- if (this._activeRun) this._activeRun.cancelled = true;
429
+ if (this._queue) {
430
+ if (this._options.unstable_queueClearOnCancel ?? true) this._queue.clear();
431
+ else {
432
+ this._queue.notifyCancelled();
433
+ if (this._activeRun) this._activeRun.cancelled = true;
434
+ }
432
435
  }
433
436
  const error = new AbortError(false);
434
437
  this.abortController?.abort(error);