@assistant-ui/ai-sdk 0.0.7 → 0.0.9

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 (115) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/dist/adapters/aiSDKFormatAdapter.d.ts +2 -2
  4. package/dist/adapters/aiSDKFormatAdapter.d.ts.map +1 -0
  5. package/dist/adapters/vercelAttachmentAdapter.d.ts +1 -3
  6. package/dist/adapters/vercelAttachmentAdapter.d.ts.map +1 -1
  7. package/dist/adapters/vercelAttachmentAdapter.js +3 -3
  8. package/dist/adapters/vercelAttachmentAdapter.js.map +1 -1
  9. package/dist/aiSDKExtras.d.ts +4 -6
  10. package/dist/aiSDKExtras.d.ts.map +1 -1
  11. package/dist/converters/convertMessage.d.ts +34 -24
  12. package/dist/converters/convertMessage.d.ts.map +1 -1
  13. package/dist/converters/convertMessage.js +56 -12
  14. package/dist/converters/convertMessage.js.map +1 -1
  15. package/dist/converters/modelContentEnvelope.d.ts +6 -7
  16. package/dist/converters/modelContentEnvelope.d.ts.map +1 -1
  17. package/dist/converters/toCreateMessage.d.ts +2 -4
  18. package/dist/converters/toCreateMessage.d.ts.map +1 -1
  19. package/dist/converters/toolOutputConversion.d.ts +20 -22
  20. package/dist/converters/toolOutputConversion.d.ts.map +1 -1
  21. package/dist/hooks.d.ts +2 -4
  22. package/dist/hooks.d.ts.map +1 -1
  23. package/dist/index.d.ts +17 -14
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.native.d.ts +15 -12
  26. package/dist/index.native.d.ts.map +1 -0
  27. package/dist/model-context/injectInteractableContext.d.ts +2 -4
  28. package/dist/model-context/injectInteractableContext.d.ts.map +1 -1
  29. package/dist/model-context/injectQuoteContext.d.ts +1 -3
  30. package/dist/model-context/injectQuoteContext.d.ts.map +1 -1
  31. package/dist/runtime/AISDKChat.d.ts +2 -4
  32. package/dist/runtime/AISDKChat.d.ts.map +1 -1
  33. package/dist/runtime/AISDKChat.js +1 -1
  34. package/dist/runtime/AISDKChat.js.map +1 -1
  35. package/dist/runtime/AISDKThreads.d.ts +29 -31
  36. package/dist/runtime/AISDKThreads.d.ts.map +1 -1
  37. package/dist/runtime/AISDKThreads.js +22 -23
  38. package/dist/runtime/AISDKThreads.js.map +1 -1
  39. package/dist/runtime/sdkIdentity.d.ts +1 -3
  40. package/dist/runtime/sdkIdentity.d.ts.map +1 -1
  41. package/dist/runtime/sdkIdentity.js +1 -1
  42. package/dist/runtime/useAISDKRuntime.d.ts +76 -70
  43. package/dist/runtime/useAISDKRuntime.d.ts.map +1 -1
  44. package/dist/runtime/useAISDKRuntime.js +311 -77
  45. package/dist/runtime/useAISDKRuntime.js.map +1 -1
  46. package/dist/runtime/useChatRuntime.d.ts +6 -8
  47. package/dist/runtime/useChatRuntime.d.ts.map +1 -1
  48. package/dist/runtime/useChatRuntime.js +14 -10
  49. package/dist/runtime/useChatRuntime.js.map +1 -1
  50. package/dist/runtime/useChatThread.d.ts +94 -89
  51. package/dist/runtime/useChatThread.d.ts.map +1 -1
  52. package/dist/runtime/useChatThread.js +44 -15
  53. package/dist/runtime/useChatThread.js.map +1 -1
  54. package/dist/runtime/useExternalHistory.d.ts +7 -7
  55. package/dist/runtime/useExternalHistory.d.ts.map +1 -1
  56. package/dist/runtime/useExternalHistory.js +231 -60
  57. package/dist/runtime/useExternalHistory.js.map +1 -1
  58. package/dist/runtime/useResourceCleanup.d.ts +1 -3
  59. package/dist/runtime/useResourceCleanup.d.ts.map +1 -1
  60. package/dist/runtime/useResourceCleanup.js +38 -14
  61. package/dist/runtime/useResourceCleanup.js.map +1 -1
  62. package/dist/runtime/useStreamingTiming.d.ts +3 -5
  63. package/dist/runtime/useStreamingTiming.d.ts.map +1 -1
  64. package/dist/runtime/useStreamingTiming.js +1 -1
  65. package/dist/tools/frontendTools.d.ts +21 -23
  66. package/dist/tools/frontendTools.d.ts.map +1 -1
  67. package/dist/tools/generativeTools.d.ts +24 -26
  68. package/dist/tools/generativeTools.d.ts.map +1 -1
  69. package/dist/tools/mcp-stdio.node.d.ts +2 -2
  70. package/dist/tools/mcp-stdio.node.d.ts.map +1 -0
  71. package/dist/tools/mcp-stdio.unsupported.d.ts +2 -4
  72. package/dist/tools/mcp-stdio.unsupported.d.ts.map +1 -1
  73. package/dist/transport/AssistantChatTransport.d.ts +14 -16
  74. package/dist/transport/AssistantChatTransport.d.ts.map +1 -1
  75. package/dist/transport/AssistantChatTransport.js +9 -2
  76. package/dist/transport/AssistantChatTransport.js.map +1 -1
  77. package/dist/transport/resumable.d.ts +25 -27
  78. package/dist/transport/resumable.d.ts.map +1 -1
  79. package/dist/usage.d.ts +8 -10
  80. package/dist/usage.d.ts.map +1 -1
  81. package/dist/usage.js.map +1 -1
  82. package/dist/utils/getVercelAIMessages.d.ts +2 -4
  83. package/dist/utils/getVercelAIMessages.d.ts.map +1 -1
  84. package/dist/utils/sliceMessagesUntil.d.ts +1 -3
  85. package/dist/utils/sliceMessagesUntil.d.ts.map +1 -1
  86. package/package.json +13 -9
  87. package/src/adapters/vercelAttachmentAdapter.test.ts +23 -0
  88. package/src/adapters/vercelAttachmentAdapter.ts +2 -2
  89. package/src/converters/convertMessage.test.ts +541 -3
  90. package/src/converters/convertMessage.ts +123 -15
  91. package/src/index.native.ts +1 -1
  92. package/src/index.ts +1 -1
  93. package/src/runtime/AISDKChat.ts +0 -4
  94. package/src/runtime/AISDKThreads.cloud.test.ts +60 -2
  95. package/src/runtime/AISDKThreads.test.ts +105 -46
  96. package/src/runtime/AISDKThreads.ts +1 -1
  97. package/src/runtime/useAISDKRuntime.approval.integration.test.tsx +1639 -19
  98. package/src/runtime/useAISDKRuntime.approval.test.tsx +252 -9
  99. package/src/runtime/useAISDKRuntime.fast-refresh.test.tsx +182 -0
  100. package/src/runtime/useAISDKRuntime.test.ts +275 -5
  101. package/src/runtime/useAISDKRuntime.ts +533 -60
  102. package/src/runtime/useAISDKRuntime.voice.test.tsx +50 -1
  103. package/src/runtime/useChatRuntime.fast-refresh.test.tsx +94 -0
  104. package/src/runtime/useChatRuntime.integration.test.tsx +143 -65
  105. package/src/runtime/useChatRuntime.test.ts +11 -7
  106. package/src/runtime/useChatRuntime.ts +6 -2
  107. package/src/runtime/useChatThread.test.ts +166 -2
  108. package/src/runtime/useChatThread.transport.test.tsx +152 -0
  109. package/src/runtime/useChatThread.ts +89 -22
  110. package/src/runtime/useExternalHistory.test.ts +943 -3
  111. package/src/runtime/useExternalHistory.ts +378 -15
  112. package/src/runtime/useResourceCleanup.ts +41 -15
  113. package/src/transport/AssistantChatTransport.test.ts +164 -0
  114. package/src/transport/AssistantChatTransport.ts +22 -2
  115. package/src/usage.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useChatThread.d.ts","names":[],"sources":["../../src/runtime/useChatThread.ts"],"mappings":";;;;;;;YAiCY,kBAAkB,mBAAmB,cAAY,eAC3D,SAAS,cACP;EACE;EACA,WAAW;EACX,kBAAkB;EAClB,WAAW;EACX,mBAAmB;EACnB,0BAA0B;;;;;;;EAO1B,kBAAkB;EAClB,eAAe;EACf,oBAAoB,oBAAoB;EACxC,0BAA0B;;YAGpB,sBAAsB,mBAAmB,cAAY;EAC/D;EACA;EACA,yBAAyB;EACzB;;;;;;EAMA,OAAO,KAAK;;;;;;EAMZ,4BAA4B;;;;;;;qBA4DjB,yBAA0B,mBAAmB,aACxD,SAAS,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;EAnFE,iBAAA;;;;;;;;;;;;;;;;;;;KA4H1B,cAAc,mBAAmB,eAAa,KACjD,SAAS;;;;;;qBASE,aAAc,mBAAmB,aAC5C,MAAM,SAAS,aACf;WAAyB,SAAS,cAAc;MAC/C,KAAK;qBAWK,gBAAiB,mBAAmB,cAAY,aAC3D,SAAS,kBAAkB,yBAC3B,KAAK,sBAAsB,gBAC1B"}
1
+ {"version":3,"file":"useChatThread.d.ts","sourceRoot":"","sources":["../../src/runtime/useChatThread.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,8 @@
2
2
  import { useAISDKRuntime } from "./useAISDKRuntime.js";
3
3
  import { AssistantChatTransport } from "../transport/AssistantChatTransport.js";
4
4
  import { useResourceCleanup } from "./useResourceCleanup.js";
5
- import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "@assistant-ui/tap/react-shim";
6
5
  import { pickExternalStoreSharedOptions } from "@assistant-ui/core";
6
+ import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "@assistant-ui/tap/react-shim";
7
7
  import { Chat, useChat } from "@ai-sdk/react";
8
8
  //#region src/runtime/useChatThread.ts
9
9
  const useDynamicChatTransport = (transport) => {
@@ -55,24 +55,38 @@ const splitChatThreadOptions = (options) => {
55
55
  chatInit
56
56
  };
57
57
  };
58
+ const requestsByChat = /* @__PURE__ */ new WeakMap();
58
59
  /**
59
60
  * Constructs a `Chat` whose callbacks read the latest options through
60
61
  * `callbacksRef`, the forwarding `useChat` applies only to a chat it
61
62
  * constructs itself.
62
63
  */
63
- const createChat = (init, callbacksRef) => new Chat({
64
- ...init,
65
- onToolCall: (arg) => callbacksRef.current?.onToolCall?.(arg),
66
- onData: (arg) => callbacksRef.current?.onData?.(arg),
67
- onFinish: (arg) => callbacksRef.current?.onFinish?.(arg),
68
- onError: (arg) => callbacksRef.current?.onError?.(arg),
69
- sendAutomaticallyWhen: (arg) => callbacksRef.current?.sendAutomaticallyWhen?.(arg) ?? false
70
- });
64
+ const createChat = (init, callbacksRef) => {
65
+ const transport = init.transport;
66
+ const chat = new Chat({
67
+ ...init,
68
+ ...transport && { transport: {
69
+ sendMessages: (options) => {
70
+ requestsByChat.set(chat, Symbol());
71
+ return transport.sendMessages(options);
72
+ },
73
+ reconnectToStream: (options) => {
74
+ requestsByChat.set(chat, Symbol());
75
+ return transport.reconnectToStream(options);
76
+ }
77
+ } },
78
+ onToolCall: (arg) => callbacksRef.current?.onToolCall?.(arg),
79
+ onData: (arg) => callbacksRef.current?.onData?.(arg),
80
+ onFinish: (arg) => callbacksRef.current?.onFinish?.(arg),
81
+ onError: (arg) => callbacksRef.current?.onError?.(arg),
82
+ sendAutomaticallyWhen: (arg) => callbacksRef.current?.sendAutomaticallyWhen?.(arg) ?? false
83
+ });
84
+ return chat;
85
+ };
71
86
  const useChatThread = (options, env) => {
72
87
  const { adapters, transport: transportOptions, throttle, toCreateMessage, onResume, onResumeToolCall, onRespondToToolApproval, onResumeError, joinStrategy, messageRepository, unstable_onBranchChange, chatInit: chatOptions } = splitChatThreadOptions(options);
73
- const { id, isMainThread, getThreadListItem, stopOnClientDestroy = true, chat: externalChat, messageRepositoryInstance } = env;
74
- const defaultTransport = useMemo(() => new AssistantChatTransport(), []);
75
- const sourceTransport = transportOptions ?? defaultTransport;
88
+ const { id, isMainThread, getThreadListItem, stopOnClientDestroy = true, hostDestroySignal, chat: externalChat, messageRepositoryInstance } = env;
89
+ const sourceTransport = useMemo(() => transportOptions === void 0 ? new AssistantChatTransport() : externalChat === void 0 && transportOptions instanceof AssistantChatTransport ? transportOptions.__internal_clone() : transportOptions, [transportOptions, externalChat]);
76
90
  const transport = useDynamicChatTransport(sourceTransport);
77
91
  const latestChatOptionsRef = useRef(chatOptions);
78
92
  useEffect(() => {
@@ -89,9 +103,15 @@ const useChatThread = (options, env) => {
89
103
  });
90
104
  useResourceCleanup(stopOnClientDestroy, () => {
91
105
  chat.stop().catch(() => {});
92
- });
106
+ }, hostDestroySignal);
93
107
  const runtime = useAISDKRuntime(chat, {
94
- adapters,
108
+ adapters: {
109
+ ...adapters,
110
+ threadList: {
111
+ threadId: id,
112
+ ...adapters?.threadList
113
+ }
114
+ },
95
115
  ...pickExternalStoreSharedOptions(options ?? {}),
96
116
  ...toCreateMessage && { toCreateMessage },
97
117
  ...onResume && { onResume },
@@ -100,6 +120,7 @@ const useChatThread = (options, env) => {
100
120
  ...joinStrategy && { joinStrategy },
101
121
  ...messageRepository && { messageRepository },
102
122
  ...messageRepositoryInstance && { unstable_messageRepositoryInstance: messageRepositoryInstance },
123
+ unstable_hostApprovalOwner: externalChat ?? ownedChat,
103
124
  ...unstable_onBranchChange && { unstable_onBranchChange }
104
125
  });
105
126
  if (sourceTransport instanceof AssistantChatTransport) {
@@ -135,7 +156,13 @@ const useChatThread = (options, env) => {
135
156
  }
136
157
  if (isLoadingHistory) return;
137
158
  resumedStreamIds.add(pendingStreamId);
138
- chat.resumeStream().catch((err) => {
159
+ const activeChat = externalChat ?? ownedChat;
160
+ activeChat.clearError();
161
+ const pending = chat.resumeStream();
162
+ const request = requestsByChat.get(activeChat);
163
+ pending.then(() => {
164
+ if (requestsByChat.get(activeChat) === request && activeChat.error) throw activeChat.error;
165
+ }).catch((err) => {
139
166
  console.warn("[assistant-ui] resumable: resume failed", err);
140
167
  try {
141
168
  onResumeErrorRef.current?.(err);
@@ -147,10 +174,12 @@ const useChatThread = (options, env) => {
147
174
  });
148
175
  }, [
149
176
  chat,
177
+ externalChat,
150
178
  id,
151
179
  isChatRunning,
152
180
  isLoadingHistory,
153
181
  pendingStreamId,
182
+ ownedChat,
154
183
  resumableStorage,
155
184
  resumedStreamIds
156
185
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"useChatThread.js","names":["Chat","useChat","UIMessage","MessageRepository","pickExternalStoreSharedOptions","AssistantRuntime","ExternalStoreSharedOptions","useAISDKRuntime","AISDKRuntimeAdapter","CustomToCreateMessageFunction","ChatInit","ChatTransport","AssistantChatTransport","InitializableThreadListItem","AssistantChatResumableOptions","ResumableClientStorage","useCallback","useEffect","useMemo","useRef","useState","useSyncExternalStore","useResourceCleanup","ChatThreadOptions","UI_MESSAGE","throttle","adapters","toCreateMessage","onResume","onResumeToolCall","onRespondToToolApproval","onResumeError","error","joinStrategy","messageRepository","unstable_onBranchChange","ChatThreadEnvironment","id","isMainThread","getThreadListItem","stopOnClientDestroy","chat","messageRepositoryInstance","useDynamicChatTransport","transport","transportRef","current","dynamicTransport","Proxy","get","_","prop","res","bind","getResumableAdapter","candidate","undefined","call","getNoPendingStreamId","resumedStreamIdsByStorage","WeakMap","Set","getResumedStreamIds","storage","resumedStreamIds","set","splitChatThreadOptions","options","isDisabled","_isDisabled","isSendDisabled","_isSendDisabled","unstable_capabilities","_unstable_capabilities","suggestions","_suggestions","chatInit","ChatCallbacks","Pick","createChat","init","callbacksRef","onToolCall","arg","onData","onFinish","onError","sendAutomaticallyWhen","useChatThread","env","transportOptions","chatOptions","externalChat","defaultTransport","sourceTransport","latestChatOptionsRef","ownedChat","stop","catch","runtime","unstable_messageRepositoryInstance","setRuntime","__internal_setGetThreadListItem","subscribeToRuntime","callback","thread","subscribe","getHistoryLoadingSnapshot","getState","isLoading","isLoadingHistory","resumableStorage","subscribeToResumableStorage","getPendingStreamId","getStreamId","pendingStreamId","isChatRunning","status","onResumeErrorRef","has","add","resumeStream","err","console","warn","callbackError","clear"],"sources":["../../src/runtime/useChatThread.ts"],"sourcesContent":["\"use client\";\n\nimport { Chat, useChat, type UIMessage } from \"@ai-sdk/react\";\nimport type { MessageRepository } from \"@assistant-ui/core/internal\";\nimport {\n pickExternalStoreSharedOptions,\n type AssistantRuntime,\n type ExternalStoreSharedOptions,\n} from \"@assistant-ui/core\";\nimport {\n useAISDKRuntime,\n type AISDKRuntimeAdapter,\n type CustomToCreateMessageFunction,\n} from \"./useAISDKRuntime\";\nimport type { ChatInit, ChatTransport } from \"ai\";\nimport {\n AssistantChatTransport,\n type InitializableThreadListItem,\n} from \"../transport/AssistantChatTransport\";\nimport type {\n AssistantChatResumableOptions,\n ResumableClientStorage,\n} from \"../transport/resumable\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { useResourceCleanup } from \"./useResourceCleanup\";\n\nexport type ChatThreadOptions<UI_MESSAGE extends UIMessage = UIMessage> =\n ChatInit<UI_MESSAGE> &\n ExternalStoreSharedOptions & {\n throttle?: number | undefined;\n adapters?: AISDKRuntimeAdapter[\"adapters\"] | undefined;\n toCreateMessage?: CustomToCreateMessageFunction;\n onResume?: AISDKRuntimeAdapter[\"onResume\"];\n onResumeToolCall?: AISDKRuntimeAdapter[\"onResumeToolCall\"];\n onRespondToToolApproval?: AISDKRuntimeAdapter[\"onRespondToToolApproval\"];\n /**\n * Called when an automatic resumable stream reconnect fails. Use this to\n * surface a toast, report telemetry, or mark the thread as needing a\n * retry. The failed stream id is cleared after the callback unless a\n * newer id has replaced it.\n */\n onResumeError?: ((error: unknown) => void) | undefined;\n joinStrategy?: AISDKRuntimeAdapter[\"joinStrategy\"];\n messageRepository?: AISDKRuntimeAdapter<UI_MESSAGE>[\"messageRepository\"];\n unstable_onBranchChange?: AISDKRuntimeAdapter[\"unstable_onBranchChange\"];\n };\n\nexport type ChatThreadEnvironment<UI_MESSAGE extends UIMessage = UIMessage> = {\n id: string;\n isMainThread: boolean;\n getThreadListItem: () => InitializableThreadListItem | undefined;\n stopOnClientDestroy?: boolean;\n /**\n * An externally owned chat instance. State lives on the instance, so it\n * survives the hosting resource unmounting; construction options are read\n * from the instance.\n */\n chat?: Chat<UI_MESSAGE> | undefined;\n /**\n * An externally owned per-thread message repository. Hosts that route\n * multiple threads through one mounting pass a distinct instance per\n * thread so histories and branches stay isolated.\n */\n messageRepositoryInstance?: MessageRepository | undefined;\n};\n\nconst useDynamicChatTransport = <UI_MESSAGE extends UIMessage = UIMessage>(\n transport: ChatTransport<UI_MESSAGE>,\n): ChatTransport<UI_MESSAGE> => {\n const transportRef = useRef<ChatTransport<UI_MESSAGE>>(transport);\n useEffect(() => {\n transportRef.current = transport;\n });\n const dynamicTransport = useMemo(\n () =>\n new Proxy(transportRef.current, {\n get(_, prop) {\n const res =\n transportRef.current[prop as keyof ChatTransport<UI_MESSAGE>];\n return typeof res === \"function\"\n ? res.bind(transportRef.current)\n : res;\n },\n }),\n [],\n );\n return dynamicTransport;\n};\n\nconst getResumableAdapter = <UI_MESSAGE extends UIMessage>(\n transport: ChatTransport<UI_MESSAGE>,\n): AssistantChatResumableOptions | undefined => {\n if (transport instanceof AssistantChatTransport) {\n return transport.getResumableAdapter();\n }\n const candidate = (transport as { getResumableAdapter?: () => unknown })\n .getResumableAdapter;\n if (typeof candidate !== \"function\") return undefined;\n return candidate.call(transport) as AssistantChatResumableOptions | undefined;\n};\n\nconst getNoPendingStreamId = () => null;\n\nconst resumedStreamIdsByStorage = new WeakMap<\n ResumableClientStorage,\n Set<string>\n>();\n\nconst getResumedStreamIds = (storage: ResumableClientStorage | undefined) => {\n if (!storage) return new Set<string>();\n let resumedStreamIds = resumedStreamIdsByStorage.get(storage);\n if (!resumedStreamIds) {\n resumedStreamIds = new Set();\n resumedStreamIdsByStorage.set(storage, resumedStreamIds);\n }\n return resumedStreamIds;\n};\n\n/**\n * Splits the combined options into the assistant-ui side and the `ChatInit`\n * remainder the AI SDK consumes, so external `Chat` construction forwards the\n * same fields `useChat` would.\n */\nexport const splitChatThreadOptions = <UI_MESSAGE extends UIMessage>(\n options: ChatThreadOptions<UI_MESSAGE> | undefined,\n) => {\n const {\n adapters,\n transport,\n throttle,\n toCreateMessage,\n isDisabled: _isDisabled,\n isSendDisabled: _isSendDisabled,\n unstable_capabilities: _unstable_capabilities,\n suggestions: _suggestions,\n onResume,\n onResumeToolCall,\n onRespondToToolApproval,\n onResumeError,\n joinStrategy,\n messageRepository,\n unstable_onBranchChange,\n ...chatInit\n } = options ?? {};\n // peel guard: any shared key left in `chatInit` collapses this to `never`\n true satisfies keyof typeof chatInit &\n keyof ExternalStoreSharedOptions extends never\n ? true\n : never;\n return {\n adapters,\n transport,\n throttle,\n toCreateMessage,\n onResume,\n onResumeToolCall,\n onRespondToToolApproval,\n onResumeError,\n joinStrategy,\n messageRepository,\n unstable_onBranchChange,\n chatInit,\n };\n};\n\ntype ChatCallbacks<UI_MESSAGE extends UIMessage> = Pick<\n ChatInit<UI_MESSAGE>,\n \"onToolCall\" | \"onData\" | \"onFinish\" | \"onError\" | \"sendAutomaticallyWhen\"\n>;\n\n/**\n * Constructs a `Chat` whose callbacks read the latest options through\n * `callbacksRef`, the forwarding `useChat` applies only to a chat it\n * constructs itself.\n */\nexport const createChat = <UI_MESSAGE extends UIMessage>(\n init: ChatInit<UI_MESSAGE>,\n callbacksRef: { readonly current: ChatCallbacks<UI_MESSAGE> | undefined },\n): Chat<UI_MESSAGE> =>\n new Chat<UI_MESSAGE>({\n ...init,\n onToolCall: (arg) => callbacksRef.current?.onToolCall?.(arg),\n onData: (arg) => callbacksRef.current?.onData?.(arg),\n onFinish: (arg) => callbacksRef.current?.onFinish?.(arg),\n onError: (arg) => callbacksRef.current?.onError?.(arg),\n sendAutomaticallyWhen: (arg) =>\n callbacksRef.current?.sendAutomaticallyWhen?.(arg) ?? false,\n });\n\nexport const useChatThread = <UI_MESSAGE extends UIMessage = UIMessage>(\n options: ChatThreadOptions<UI_MESSAGE> | undefined,\n env: ChatThreadEnvironment<UI_MESSAGE>,\n): AssistantRuntime => {\n const {\n adapters,\n transport: transportOptions,\n throttle,\n toCreateMessage,\n onResume,\n onResumeToolCall,\n onRespondToToolApproval,\n onResumeError,\n joinStrategy,\n messageRepository,\n unstable_onBranchChange,\n chatInit: chatOptions,\n } = splitChatThreadOptions(options);\n\n const {\n id,\n isMainThread,\n getThreadListItem,\n stopOnClientDestroy = true,\n chat: externalChat,\n messageRepositoryInstance,\n } = env;\n\n const defaultTransport = useMemo(() => new AssistantChatTransport(), []);\n const sourceTransport = transportOptions ?? defaultTransport;\n const transport = useDynamicChatTransport(sourceTransport);\n\n const latestChatOptionsRef = useRef(chatOptions);\n useEffect(() => {\n latestChatOptionsRef.current = chatOptions;\n });\n // `useChat` stops a chat it constructs whenever it unmounts, and a\n // resource's soft unmount runs that cleanup, so the thread owns its chat.\n const [ownedChat] = useState(\n () =>\n externalChat ??\n createChat({ ...chatOptions, id, transport }, latestChatOptionsRef),\n );\n\n const chat = useChat({\n chat: externalChat ?? ownedChat,\n ...(throttle !== undefined && { throttle }),\n });\n\n useResourceCleanup(stopOnClientDestroy, () => {\n void chat.stop().catch(() => {});\n });\n\n const runtime = useAISDKRuntime(chat, {\n adapters,\n ...pickExternalStoreSharedOptions(options ?? {}),\n ...(toCreateMessage && { toCreateMessage }),\n ...(onResume && { onResume }),\n ...(onResumeToolCall && { onResumeToolCall }),\n ...(onRespondToToolApproval && { onRespondToToolApproval }),\n ...(joinStrategy && { joinStrategy }),\n ...(messageRepository && { messageRepository }),\n ...(messageRepositoryInstance && {\n unstable_messageRepositoryInstance: messageRepositoryInstance,\n }),\n ...(unstable_onBranchChange && { unstable_onBranchChange }),\n });\n\n if (sourceTransport instanceof AssistantChatTransport) {\n sourceTransport.setRuntime(runtime);\n sourceTransport.__internal_setGetThreadListItem(getThreadListItem);\n }\n\n const subscribeToRuntime = useCallback(\n (callback: () => void) => runtime.thread.subscribe(callback),\n [runtime],\n );\n const getHistoryLoadingSnapshot = useCallback(\n () => runtime.thread.getState().isLoading,\n [runtime],\n );\n const isLoadingHistory = useSyncExternalStore(\n subscribeToRuntime,\n getHistoryLoadingSnapshot,\n getHistoryLoadingSnapshot,\n );\n\n const resumableStorage = useMemo(\n () => getResumableAdapter(sourceTransport)?.storage,\n [sourceTransport],\n );\n const subscribeToResumableStorage = useCallback(\n (callback: () => void) =>\n isMainThread\n ? (resumableStorage?.subscribe?.(callback, id) ?? (() => {}))\n : () => {},\n [id, isMainThread, resumableStorage],\n );\n const getPendingStreamId = useCallback(\n () => (isMainThread ? (resumableStorage?.getStreamId(id) ?? null) : null),\n [id, isMainThread, resumableStorage],\n );\n const pendingStreamId = useSyncExternalStore(\n subscribeToResumableStorage,\n getPendingStreamId,\n getNoPendingStreamId,\n );\n const isChatRunning =\n chat.status === \"submitted\" || chat.status === \"streaming\";\n\n const resumedStreamIds = useMemo(\n () => getResumedStreamIds(resumableStorage),\n [resumableStorage],\n );\n const onResumeErrorRef = useRef(onResumeError);\n useEffect(() => {\n onResumeErrorRef.current = onResumeError;\n });\n useEffect(() => {\n if (!pendingStreamId || resumedStreamIds.has(pendingStreamId)) {\n return;\n }\n if (isChatRunning) {\n resumedStreamIds.add(pendingStreamId);\n return;\n }\n if (isLoadingHistory) return;\n resumedStreamIds.add(pendingStreamId);\n chat.resumeStream().catch((err: unknown) => {\n console.warn(\"[assistant-ui] resumable: resume failed\", err);\n try {\n onResumeErrorRef.current?.(err);\n } catch (callbackError) {\n console.error(\n \"[assistant-ui] resumable: onResumeError callback failed\",\n callbackError,\n );\n } finally {\n if (resumableStorage?.getStreamId(id) === pendingStreamId) {\n resumableStorage.clear(id);\n }\n }\n });\n }, [\n chat,\n id,\n isChatRunning,\n isLoadingHistory,\n pendingStreamId,\n resumableStorage,\n resumedStreamIds,\n ]);\n\n return runtime;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useChatThread.js","names":["Chat","useChat","UIMessage","MessageRepository","pickExternalStoreSharedOptions","AssistantRuntime","ExternalStoreSharedOptions","useAISDKRuntime","AISDKRuntimeAdapter","CustomToCreateMessageFunction","ChatInit","ChatTransport","AssistantChatTransport","InitializableThreadListItem","AssistantChatResumableOptions","ResumableClientStorage","useCallback","useEffect","useMemo","useRef","useState","useSyncExternalStore","useResourceCleanup","ChatThreadOptions","UI_MESSAGE","throttle","adapters","toCreateMessage","onResume","onResumeToolCall","onRespondToToolApproval","onResumeError","error","joinStrategy","messageRepository","unstable_onBranchChange","ChatThreadEnvironment","id","isMainThread","getThreadListItem","stopOnClientDestroy","hostDestroySignal","AbortSignal","chat","messageRepositoryInstance","useDynamicChatTransport","transport","transportRef","current","dynamicTransport","Proxy","get","_","prop","res","bind","getResumableAdapter","candidate","undefined","call","getNoPendingStreamId","resumedStreamIdsByStorage","WeakMap","Set","getResumedStreamIds","storage","resumedStreamIds","set","splitChatThreadOptions","options","isDisabled","_isDisabled","isSendDisabled","_isSendDisabled","unstable_capabilities","_unstable_capabilities","suggestions","_suggestions","chatInit","ChatCallbacks","Pick","requestsByChat","createChat","init","callbacksRef","sendMessages","Symbol","reconnectToStream","onToolCall","arg","onData","onFinish","onError","sendAutomaticallyWhen","useChatThread","env","transportOptions","chatOptions","externalChat","sourceTransport","__internal_clone","latestChatOptionsRef","ownedChat","stop","catch","runtime","threadList","threadId","unstable_messageRepositoryInstance","unstable_hostApprovalOwner","setRuntime","__internal_setGetThreadListItem","subscribeToRuntime","callback","thread","subscribe","getHistoryLoadingSnapshot","getState","isLoading","isLoadingHistory","resumableStorage","subscribeToResumableStorage","getPendingStreamId","getStreamId","pendingStreamId","isChatRunning","status","onResumeErrorRef","has","add","activeChat","clearError","pending","resumeStream","request","then","err","console","warn","callbackError","clear"],"sources":["../../src/runtime/useChatThread.ts"],"sourcesContent":["\"use client\";\n\nimport { Chat, useChat, type UIMessage } from \"@ai-sdk/react\";\nimport type { MessageRepository } from \"@assistant-ui/core/internal\";\nimport {\n pickExternalStoreSharedOptions,\n type AssistantRuntime,\n type ExternalStoreSharedOptions,\n} from \"@assistant-ui/core\";\nimport {\n useAISDKRuntime,\n type AISDKRuntimeAdapter,\n type CustomToCreateMessageFunction,\n} from \"./useAISDKRuntime\";\nimport type { ChatInit, ChatTransport } from \"ai\";\nimport {\n AssistantChatTransport,\n type InitializableThreadListItem,\n} from \"../transport/AssistantChatTransport\";\nimport type {\n AssistantChatResumableOptions,\n ResumableClientStorage,\n} from \"../transport/resumable\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { useResourceCleanup } from \"./useResourceCleanup\";\n\nexport type ChatThreadOptions<UI_MESSAGE extends UIMessage = UIMessage> =\n ChatInit<UI_MESSAGE> &\n ExternalStoreSharedOptions & {\n throttle?: number | undefined;\n adapters?: AISDKRuntimeAdapter[\"adapters\"] | undefined;\n toCreateMessage?: CustomToCreateMessageFunction;\n onResume?: AISDKRuntimeAdapter[\"onResume\"];\n onResumeToolCall?: AISDKRuntimeAdapter[\"onResumeToolCall\"];\n onRespondToToolApproval?: AISDKRuntimeAdapter[\"onRespondToToolApproval\"];\n /**\n * Called when an automatic resumable stream reconnect fails. Use this to\n * surface a toast, report telemetry, or mark the thread as needing a\n * retry. The failed stream id is cleared after the callback unless a\n * newer id has replaced it.\n */\n onResumeError?: ((error: unknown) => void) | undefined;\n joinStrategy?: AISDKRuntimeAdapter[\"joinStrategy\"];\n messageRepository?: AISDKRuntimeAdapter<UI_MESSAGE>[\"messageRepository\"];\n unstable_onBranchChange?: AISDKRuntimeAdapter[\"unstable_onBranchChange\"];\n };\n\nexport type ChatThreadEnvironment<UI_MESSAGE extends UIMessage = UIMessage> = {\n id: string;\n isMainThread: boolean;\n getThreadListItem: () => InitializableThreadListItem | undefined;\n stopOnClientDestroy?: boolean;\n /**\n * Aborts when the React component hosting the runtime is deleted. A nested\n * runtime resolves the destroy signal of the provider above it, which\n * outlives the nested component, so this stops the chat on its own unmount.\n */\n hostDestroySignal?: AbortSignal | undefined;\n /**\n * An externally owned chat instance. State lives on the instance, so it\n * survives the hosting resource unmounting; construction options are read\n * from the instance.\n */\n chat?: Chat<UI_MESSAGE> | undefined;\n /**\n * An externally owned per-thread message repository. Hosts that route\n * multiple threads through one mounting pass a distinct instance per\n * thread so histories and branches stay isolated.\n */\n messageRepositoryInstance?: MessageRepository | undefined;\n};\n\nconst useDynamicChatTransport = <UI_MESSAGE extends UIMessage = UIMessage>(\n transport: ChatTransport<UI_MESSAGE>,\n): ChatTransport<UI_MESSAGE> => {\n const transportRef = useRef<ChatTransport<UI_MESSAGE>>(transport);\n useEffect(() => {\n transportRef.current = transport;\n });\n const dynamicTransport = useMemo(\n () =>\n new Proxy(transportRef.current, {\n get(_, prop) {\n const res =\n transportRef.current[prop as keyof ChatTransport<UI_MESSAGE>];\n return typeof res === \"function\"\n ? res.bind(transportRef.current)\n : res;\n },\n }),\n [],\n );\n return dynamicTransport;\n};\n\nconst getResumableAdapter = <UI_MESSAGE extends UIMessage>(\n transport: ChatTransport<UI_MESSAGE>,\n): AssistantChatResumableOptions | undefined => {\n if (transport instanceof AssistantChatTransport) {\n return transport.getResumableAdapter();\n }\n const candidate = (transport as { getResumableAdapter?: () => unknown })\n .getResumableAdapter;\n if (typeof candidate !== \"function\") return undefined;\n return candidate.call(transport) as AssistantChatResumableOptions | undefined;\n};\n\nconst getNoPendingStreamId = () => null;\n\nconst resumedStreamIdsByStorage = new WeakMap<\n ResumableClientStorage,\n Set<string>\n>();\n\nconst getResumedStreamIds = (storage: ResumableClientStorage | undefined) => {\n if (!storage) return new Set<string>();\n let resumedStreamIds = resumedStreamIdsByStorage.get(storage);\n if (!resumedStreamIds) {\n resumedStreamIds = new Set();\n resumedStreamIdsByStorage.set(storage, resumedStreamIds);\n }\n return resumedStreamIds;\n};\n\n/**\n * Splits the combined options into the assistant-ui side and the `ChatInit`\n * remainder the AI SDK consumes, so external `Chat` construction forwards the\n * same fields `useChat` would.\n */\nexport const splitChatThreadOptions = <UI_MESSAGE extends UIMessage>(\n options: ChatThreadOptions<UI_MESSAGE> | undefined,\n) => {\n const {\n adapters,\n transport,\n throttle,\n toCreateMessage,\n isDisabled: _isDisabled,\n isSendDisabled: _isSendDisabled,\n unstable_capabilities: _unstable_capabilities,\n suggestions: _suggestions,\n onResume,\n onResumeToolCall,\n onRespondToToolApproval,\n onResumeError,\n joinStrategy,\n messageRepository,\n unstable_onBranchChange,\n ...chatInit\n } = options ?? {};\n // peel guard: any shared key left in `chatInit` collapses this to `never`\n true satisfies keyof typeof chatInit &\n keyof ExternalStoreSharedOptions extends never\n ? true\n : never;\n return {\n adapters,\n transport,\n throttle,\n toCreateMessage,\n onResume,\n onResumeToolCall,\n onRespondToToolApproval,\n onResumeError,\n joinStrategy,\n messageRepository,\n unstable_onBranchChange,\n chatInit,\n };\n};\n\ntype ChatCallbacks<UI_MESSAGE extends UIMessage> = Pick<\n ChatInit<UI_MESSAGE>,\n \"onToolCall\" | \"onData\" | \"onFinish\" | \"onError\" | \"sendAutomaticallyWhen\"\n>;\n\nconst requestsByChat = new WeakMap<object, symbol>();\n\n/**\n * Constructs a `Chat` whose callbacks read the latest options through\n * `callbacksRef`, the forwarding `useChat` applies only to a chat it\n * constructs itself.\n */\nexport const createChat = <UI_MESSAGE extends UIMessage>(\n init: ChatInit<UI_MESSAGE>,\n callbacksRef: { readonly current: ChatCallbacks<UI_MESSAGE> | undefined },\n): Chat<UI_MESSAGE> => {\n const transport = init.transport;\n const chat = new Chat<UI_MESSAGE>({\n ...init,\n ...(transport && {\n transport: {\n sendMessages: (options) => {\n requestsByChat.set(chat, Symbol());\n return transport.sendMessages(options);\n },\n reconnectToStream: (options) => {\n requestsByChat.set(chat, Symbol());\n return transport.reconnectToStream(options);\n },\n },\n }),\n onToolCall: (arg) => callbacksRef.current?.onToolCall?.(arg),\n onData: (arg) => callbacksRef.current?.onData?.(arg),\n onFinish: (arg) => callbacksRef.current?.onFinish?.(arg),\n onError: (arg) => callbacksRef.current?.onError?.(arg),\n sendAutomaticallyWhen: (arg) =>\n callbacksRef.current?.sendAutomaticallyWhen?.(arg) ?? false,\n });\n return chat;\n};\n\nexport const useChatThread = <UI_MESSAGE extends UIMessage = UIMessage>(\n options: ChatThreadOptions<UI_MESSAGE> | undefined,\n env: ChatThreadEnvironment<UI_MESSAGE>,\n): AssistantRuntime => {\n const {\n adapters,\n transport: transportOptions,\n throttle,\n toCreateMessage,\n onResume,\n onResumeToolCall,\n onRespondToToolApproval,\n onResumeError,\n joinStrategy,\n messageRepository,\n unstable_onBranchChange,\n chatInit: chatOptions,\n } = splitChatThreadOptions(options);\n\n const {\n id,\n isMainThread,\n getThreadListItem,\n stopOnClientDestroy = true,\n hostDestroySignal,\n chat: externalChat,\n messageRepositoryInstance,\n } = env;\n\n // Wiring below is per thread and mutated on the instance, so a transport\n // shared across simultaneously mounted threads is last-writer-wins. A\n // caller-owned chat is already bound to its own clone, so cloning again\n // here would wire a copy the chat never sends through.\n const sourceTransport = useMemo(\n () =>\n transportOptions === undefined\n ? new AssistantChatTransport()\n : externalChat === undefined &&\n transportOptions instanceof AssistantChatTransport\n ? transportOptions.__internal_clone()\n : transportOptions,\n [transportOptions, externalChat],\n );\n const transport = useDynamicChatTransport(sourceTransport);\n\n const latestChatOptionsRef = useRef(chatOptions);\n useEffect(() => {\n latestChatOptionsRef.current = chatOptions;\n });\n // `useChat` stops a chat it constructs whenever it unmounts, and a\n // resource's soft unmount runs that cleanup, so the thread owns its chat.\n const [ownedChat] = useState(\n () =>\n externalChat ??\n createChat({ ...chatOptions, id, transport }, latestChatOptionsRef),\n );\n\n const chat = useChat({\n chat: externalChat ?? ownedChat,\n ...(throttle !== undefined && { throttle }),\n });\n\n useResourceCleanup(\n stopOnClientDestroy,\n () => {\n void chat.stop().catch(() => {});\n },\n hostDestroySignal,\n );\n\n const runtime = useAISDKRuntime(chat, {\n adapters: {\n ...adapters,\n threadList: { threadId: id, ...adapters?.threadList },\n },\n ...pickExternalStoreSharedOptions(options ?? {}),\n ...(toCreateMessage && { toCreateMessage }),\n ...(onResume && { onResume }),\n ...(onResumeToolCall && { onResumeToolCall }),\n ...(onRespondToToolApproval && { onRespondToToolApproval }),\n ...(joinStrategy && { joinStrategy }),\n ...(messageRepository && { messageRepository }),\n ...(messageRepositoryInstance && {\n unstable_messageRepositoryInstance: messageRepositoryInstance,\n }),\n // The chat outlives this runtime when a host mounts only the visible\n // thread, so a host approval answer is kept with it. This is the Chat\n // instance, not the useChat helpers, which are re-minted every render and\n // would be a dead WeakMap key by the next one.\n unstable_hostApprovalOwner: externalChat ?? ownedChat,\n ...(unstable_onBranchChange && { unstable_onBranchChange }),\n });\n\n // Wire in render, not an effect: a send from a descendant's mount effect\n // runs before this hook's effect would (effects fire child-first), and must\n // see a wired transport. The clone is per thread, so a discarded render's\n // wiring is discarded with it and the committed render re-wires the same\n // instance.\n if (sourceTransport instanceof AssistantChatTransport) {\n sourceTransport.setRuntime(runtime);\n sourceTransport.__internal_setGetThreadListItem(getThreadListItem);\n }\n\n const subscribeToRuntime = useCallback(\n (callback: () => void) => runtime.thread.subscribe(callback),\n [runtime],\n );\n const getHistoryLoadingSnapshot = useCallback(\n () => runtime.thread.getState().isLoading,\n [runtime],\n );\n const isLoadingHistory = useSyncExternalStore(\n subscribeToRuntime,\n getHistoryLoadingSnapshot,\n getHistoryLoadingSnapshot,\n );\n\n const resumableStorage = useMemo(\n () => getResumableAdapter(sourceTransport)?.storage,\n [sourceTransport],\n );\n const subscribeToResumableStorage = useCallback(\n (callback: () => void) =>\n isMainThread\n ? (resumableStorage?.subscribe?.(callback, id) ?? (() => {}))\n : () => {},\n [id, isMainThread, resumableStorage],\n );\n const getPendingStreamId = useCallback(\n () => (isMainThread ? (resumableStorage?.getStreamId(id) ?? null) : null),\n [id, isMainThread, resumableStorage],\n );\n const pendingStreamId = useSyncExternalStore(\n subscribeToResumableStorage,\n getPendingStreamId,\n getNoPendingStreamId,\n );\n const isChatRunning =\n chat.status === \"submitted\" || chat.status === \"streaming\";\n\n const resumedStreamIds = useMemo(\n () => getResumedStreamIds(resumableStorage),\n [resumableStorage],\n );\n const onResumeErrorRef = useRef(onResumeError);\n useEffect(() => {\n onResumeErrorRef.current = onResumeError;\n });\n useEffect(() => {\n if (!pendingStreamId || resumedStreamIds.has(pendingStreamId)) {\n return;\n }\n if (isChatRunning) {\n resumedStreamIds.add(pendingStreamId);\n return;\n }\n if (isLoadingHistory) return;\n resumedStreamIds.add(pendingStreamId);\n const activeChat = externalChat ?? ownedChat;\n activeChat.clearError();\n const pending = chat.resumeStream();\n const request = requestsByChat.get(activeChat);\n pending\n .then(() => {\n // Chat.error is shared with sends and resumes that can start before\n // this promise settles, including inside the caller's onFinish.\n if (requestsByChat.get(activeChat) === request && activeChat.error) {\n throw activeChat.error;\n }\n })\n .catch((err: unknown) => {\n console.warn(\"[assistant-ui] resumable: resume failed\", err);\n try {\n onResumeErrorRef.current?.(err);\n } catch (callbackError) {\n console.error(\n \"[assistant-ui] resumable: onResumeError callback failed\",\n callbackError,\n );\n } finally {\n if (resumableStorage?.getStreamId(id) === pendingStreamId) {\n resumableStorage.clear(id);\n }\n }\n });\n }, [\n chat,\n externalChat,\n id,\n isChatRunning,\n isLoadingHistory,\n pendingStreamId,\n ownedChat,\n resumableStorage,\n resumedStreamIds,\n ]);\n\n return runtime;\n};\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
- import { RefObject } from "react";
2
- import { AssistantRuntime, ExportedMessageRepository, MessageFormatAdapter, MessageFormatRepository, ThreadHistoryAdapter, ThreadMessage } from "@assistant-ui/core";
3
- //#region src/runtime/useExternalHistory.d.ts
1
+ import type { AssistantRuntime, ThreadHistoryAdapter, ThreadMessage, MessageFormatAdapter, MessageFormatRepository, ExportedMessageRepository, RespondToToolApprovalOptions, Unstable_ToolInteractionLog } from "@assistant-ui/core";
2
+ import { type RefObject } from "react";
4
3
  export declare const toExportedMessageRepository: <TMessage>(toThreadMessages: (messages: TMessage[]) => ThreadMessage[], messages: MessageFormatRepository<TMessage>) => ExportedMessageRepository;
5
- export declare const useExternalHistory: <TMessage>(runtimeRef: RefObject<AssistantRuntime>, historyAdapter: ThreadHistoryAdapter | undefined, toThreadMessages: (messages: TMessage[]) => ThreadMessage[], storageFormatAdapter: MessageFormatAdapter<TMessage, any>, onSetMessages: (messages: TMessage[]) => void) => {
6
- isLoading: boolean;
7
- deleteMessage: (messageId: string) => Promise<void>;
4
+ export declare const useExternalHistory: <TMessage>(runtimeRef: RefObject<AssistantRuntime>, historyAdapter: ThreadHistoryAdapter | undefined, toThreadMessages: (messages: TMessage[]) => ThreadMessage[], storageFormatAdapter: MessageFormatAdapter<TMessage, any>, onSetMessages: (messages: TMessage[]) => void, toolArtifacts?: Map<string, unknown>, onToolArtifactsRestored?: () => void, toolInteractions?: Map<string, Unstable_ToolInteractionLog>, onToolInteractionsRestored?: () => void, toolApprovalResponses?: Map<string, RespondToToolApprovalOptions>, onToolApprovalResponsesRestored?: () => void) => {
5
+ isLoading: boolean;
6
+ deleteMessage: (messageId: string) => Promise<void>;
7
+ persistToolInteractions: (messageId: string) => Promise<void>;
8
+ persistToolApprovalResponses: (messageId: string) => Promise<void>;
8
9
  };
9
- //#endregion
10
10
  //# sourceMappingURL=useExternalHistory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useExternalHistory.d.ts","names":[],"sources":["../../src/runtime/useExternalHistory.ts"],"mappings":";;;qBAuBa,8BAA+B,UAC1C,mBAAmB,UAAU,eAAe,iBAC5C,UAAU,wBAAwB,cACjC;qBAoCU,qBAAsB,UACjC,YAAY,UAAU,mBACtB,gBAAgB,kCAChB,mBAAmB,UAAU,eAAe,iBAC5C,sBAAsB,qBAAqB,gBAC3C,gBAAgB,UAAU;;EAuVN,gBAAA,sBAAM"}
1
+ {"version":3,"file":"useExternalHistory.d.ts","sourceRoot":"","sources":["../../src/runtime/useExternalHistory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,oBAAoB,EAEpB,uBAAuB,EACvB,yBAAyB,EACzB,4BAA4B,EAC5B,2BAA2B,EAC5B,MAAM,oBAAoB,CAAC;AAO5B,OAAO,EAIL,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;AAEf,eAAO,MAAM,2BAA2B,GAAI,QAAQ,EAClD,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,EAC3D,UAAU,uBAAuB,CAAC,QAAQ,CAAC,KAC1C,yBAoBF,CAAC;AAmOF,eAAO,MAAM,kBAAkB,GAAI,QAAQ,EACzC,YAAY,SAAS,CAAC,gBAAgB,CAAC,EACvC,gBAAgB,oBAAoB,GAAG,SAAS,EAChD,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,EAC3D,sBAAsB,oBAAoB,CAAC,QAAQ,EAAE,GAAG,CAAC,EACzD,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,IAAI,EAC7C,gBAAgB,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,0BAA0B,MAAM,IAAI,EACpC,mBAAmB,GAAG,CAAC,MAAM,EAAE,2BAA2B,CAAC,EAC3D,6BAA6B,MAAM,IAAI,EACvC,wBAAwB,GAAG,CAAC,MAAM,EAAE,4BAA4B,CAAC,EACjE,kCAAkC,MAAM,IAAI;;+BA+dxB,MAAM;yCA3UZ,MAAM;8CAAN,MAAM;CAyXrB,CAAC"}