@tambo-ai/react 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/README.md +9 -0
  2. package/dist/hooks/__tests__/use-suggestions.test.d.ts +1 -0
  3. package/dist/hooks/__tests__/use-suggestions.test.js +167 -0
  4. package/dist/hooks/__tests__/use-suggestions.test.js.map +1 -0
  5. package/dist/hooks/react-query-hooks.d.ts +21 -0
  6. package/dist/hooks/react-query-hooks.js +33 -0
  7. package/dist/hooks/react-query-hooks.js.map +1 -0
  8. package/dist/hooks/use-component-state.d.ts +8 -0
  9. package/dist/hooks/use-component-state.js +42 -0
  10. package/dist/hooks/use-component-state.js.map +1 -0
  11. package/dist/hooks/use-current-message.d.ts +18 -0
  12. package/dist/hooks/use-current-message.js +73 -0
  13. package/dist/hooks/use-current-message.js.map +1 -0
  14. package/dist/hooks/use-query-client.d.ts +0 -0
  15. package/dist/hooks/use-query-client.js +2 -0
  16. package/dist/hooks/use-query-client.js.map +1 -0
  17. package/dist/hooks/use-suggestions.d.ts +44 -0
  18. package/dist/hooks/use-suggestions.js +111 -0
  19. package/dist/hooks/use-suggestions.js.map +1 -0
  20. package/dist/hooks/use-tambo-threads.d.ts +137 -0
  21. package/dist/hooks/use-tambo-threads.js +33 -0
  22. package/dist/hooks/use-tambo-threads.js.map +1 -0
  23. package/dist/hooks/use-thread-input.d.ts +48 -0
  24. package/dist/hooks/use-thread-input.js +53 -0
  25. package/dist/hooks/use-thread-input.js.map +1 -0
  26. package/dist/index.d.ts +12 -0
  27. package/dist/index.js +34 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/model/component-metadata.d.ts +32 -0
  30. package/dist/model/component-metadata.js +3 -0
  31. package/dist/model/component-metadata.js.map +1 -0
  32. package/dist/model/generate-component-response.d.ts +17 -0
  33. package/dist/model/generate-component-response.js +22 -0
  34. package/dist/model/generate-component-response.js.map +1 -0
  35. package/dist/model/tambo-thread.d.ts +7 -0
  36. package/dist/model/tambo-thread.js +3 -0
  37. package/dist/model/tambo-thread.js.map +1 -0
  38. package/dist/model/thread-input-error.d.ts +3 -0
  39. package/dist/model/thread-input-error.js +8 -0
  40. package/dist/model/thread-input-error.js.map +1 -0
  41. package/dist/model/validate-input.d.ts +6 -0
  42. package/dist/model/validate-input.js +27 -0
  43. package/dist/model/validate-input.js.map +1 -0
  44. package/dist/providers/index.d.ts +5 -0
  45. package/dist/providers/index.js +21 -0
  46. package/dist/providers/index.js.map +1 -0
  47. package/dist/providers/tambo-client-provider.d.ts +15 -0
  48. package/dist/providers/tambo-client-provider.js +66 -0
  49. package/dist/providers/tambo-client-provider.js.map +1 -0
  50. package/dist/providers/tambo-component-provider.d.ts +18 -0
  51. package/dist/providers/tambo-component-provider.js +129 -0
  52. package/dist/providers/tambo-component-provider.js.map +1 -0
  53. package/dist/providers/tambo-provider.d.ts +10 -0
  54. package/dist/providers/tambo-provider.js +70 -0
  55. package/dist/providers/tambo-provider.js.map +1 -0
  56. package/dist/providers/tambo-registry-provider.d.ts +21 -0
  57. package/dist/providers/tambo-registry-provider.js +117 -0
  58. package/dist/providers/tambo-registry-provider.js.map +1 -0
  59. package/dist/providers/tambo-thread-provider.d.ts +28 -0
  60. package/dist/providers/tambo-thread-provider.js +417 -0
  61. package/dist/providers/tambo-thread-provider.js.map +1 -0
  62. package/dist/setupTests.d.ts +1 -0
  63. package/dist/setupTests.js +20 -0
  64. package/dist/setupTests.js.map +1 -0
  65. package/dist/util/generate-component.d.ts +8 -0
  66. package/dist/util/generate-component.js +209 -0
  67. package/dist/util/generate-component.js.map +1 -0
  68. package/dist/util/messages.d.ts +2 -0
  69. package/dist/util/messages.js +12 -0
  70. package/dist/util/messages.js.map +1 -0
  71. package/dist/util/query-utils.d.ts +5 -0
  72. package/dist/util/query-utils.js +63 -0
  73. package/dist/util/query-utils.js.map +1 -0
  74. package/dist/util/registry.d.ts +7 -0
  75. package/dist/util/registry.js +99 -0
  76. package/dist/util/registry.js.map +1 -0
  77. package/dist/util/tool-caller.d.ts +3 -0
  78. package/dist/util/tool-caller.js +30 -0
  79. package/dist/util/tool-caller.js.map +1 -0
  80. package/esm/hooks/__tests__/use-suggestions.test.d.ts +1 -0
  81. package/esm/hooks/__tests__/use-suggestions.test.js +165 -0
  82. package/esm/hooks/__tests__/use-suggestions.test.js.map +1 -0
  83. package/esm/hooks/react-query-hooks.d.ts +21 -0
  84. package/esm/hooks/react-query-hooks.js +28 -0
  85. package/esm/hooks/react-query-hooks.js.map +1 -0
  86. package/esm/hooks/use-component-state.d.ts +8 -0
  87. package/esm/hooks/use-component-state.js +39 -0
  88. package/esm/hooks/use-component-state.js.map +1 -0
  89. package/esm/hooks/use-current-message.d.ts +18 -0
  90. package/esm/hooks/use-current-message.js +33 -0
  91. package/esm/hooks/use-current-message.js.map +1 -0
  92. package/esm/hooks/use-query-client.d.ts +0 -0
  93. package/esm/hooks/use-query-client.js +2 -0
  94. package/esm/hooks/use-query-client.js.map +1 -0
  95. package/esm/hooks/use-suggestions.d.ts +44 -0
  96. package/esm/hooks/use-suggestions.js +108 -0
  97. package/esm/hooks/use-suggestions.js.map +1 -0
  98. package/esm/hooks/use-tambo-threads.d.ts +137 -0
  99. package/esm/hooks/use-tambo-threads.js +30 -0
  100. package/esm/hooks/use-tambo-threads.js.map +1 -0
  101. package/esm/hooks/use-thread-input.d.ts +48 -0
  102. package/esm/hooks/use-thread-input.js +49 -0
  103. package/esm/hooks/use-thread-input.js.map +1 -0
  104. package/esm/index.d.ts +12 -0
  105. package/esm/index.js +10 -0
  106. package/esm/index.js.map +1 -0
  107. package/esm/model/component-metadata.d.ts +32 -0
  108. package/esm/model/component-metadata.js +2 -0
  109. package/esm/model/component-metadata.js.map +1 -0
  110. package/esm/model/generate-component-response.d.ts +17 -0
  111. package/esm/model/generate-component-response.js +18 -0
  112. package/esm/model/generate-component-response.js.map +1 -0
  113. package/esm/model/tambo-thread.d.ts +7 -0
  114. package/esm/model/tambo-thread.js +2 -0
  115. package/esm/model/tambo-thread.js.map +1 -0
  116. package/esm/model/thread-input-error.d.ts +3 -0
  117. package/esm/model/thread-input-error.js +4 -0
  118. package/esm/model/thread-input-error.js.map +1 -0
  119. package/esm/model/validate-input.d.ts +6 -0
  120. package/esm/model/validate-input.js +24 -0
  121. package/esm/model/validate-input.js.map +1 -0
  122. package/esm/providers/index.d.ts +5 -0
  123. package/esm/providers/index.js +6 -0
  124. package/esm/providers/index.js.map +1 -0
  125. package/esm/providers/tambo-client-provider.d.ts +15 -0
  126. package/esm/providers/tambo-client-provider.js +24 -0
  127. package/esm/providers/tambo-client-provider.js.map +1 -0
  128. package/esm/providers/tambo-component-provider.d.ts +18 -0
  129. package/esm/providers/tambo-component-provider.js +91 -0
  130. package/esm/providers/tambo-component-provider.js.map +1 -0
  131. package/esm/providers/tambo-provider.d.ts +10 -0
  132. package/esm/providers/tambo-provider.js +32 -0
  133. package/esm/providers/tambo-provider.js.map +1 -0
  134. package/esm/providers/tambo-registry-provider.d.ts +21 -0
  135. package/esm/providers/tambo-registry-provider.js +79 -0
  136. package/esm/providers/tambo-registry-provider.js.map +1 -0
  137. package/esm/providers/tambo-thread-provider.d.ts +28 -0
  138. package/esm/providers/tambo-thread-provider.js +379 -0
  139. package/esm/providers/tambo-thread-provider.js.map +1 -0
  140. package/esm/setupTests.d.ts +1 -0
  141. package/esm/setupTests.js +18 -0
  142. package/esm/setupTests.js.map +1 -0
  143. package/esm/util/generate-component.d.ts +8 -0
  144. package/esm/util/generate-component.js +202 -0
  145. package/esm/util/generate-component.js.map +1 -0
  146. package/esm/util/messages.d.ts +2 -0
  147. package/esm/util/messages.js +9 -0
  148. package/esm/util/messages.js.map +1 -0
  149. package/esm/util/query-utils.d.ts +5 -0
  150. package/esm/util/query-utils.js +59 -0
  151. package/esm/util/query-utils.js.map +1 -0
  152. package/esm/util/registry.d.ts +7 -0
  153. package/esm/util/registry.js +88 -0
  154. package/esm/util/registry.js.map +1 -0
  155. package/esm/util/tool-caller.d.ts +3 -0
  156. package/esm/util/tool-caller.js +26 -0
  157. package/esm/util/tool-caller.js.map +1 -0
  158. package/package.json +84 -0
@@ -0,0 +1,379 @@
1
+ "use client";
2
+ import { advanceStream } from "@tambo-ai/typescript-sdk";
3
+ import React, { createContext, useCallback, useContext, useEffect, useMemo, useState, } from "react";
4
+ import { GenerationStage, } from "../model/generate-component-response";
5
+ import { renderComponentIntoMessage } from "../util/generate-component";
6
+ import { getAvailableComponents, getClientContext } from "../util/registry";
7
+ import { handleToolCall } from "../util/tool-caller";
8
+ import { useTamboClient } from "./tambo-client-provider";
9
+ import { useTamboRegistry } from "./tambo-registry-provider";
10
+ /** This is a stub entry for when the thread is not yet created, the first time
11
+ * the user sends a message
12
+ *
13
+ * Note that the consumer needs to be careful never to send `PLACEHOLDER_THREAD.id` to the server,
14
+ * as this doesn't really exist on the server side.
15
+ */
16
+ export const PLACEHOLDER_THREAD = {
17
+ id: "placeholder",
18
+ messages: [],
19
+ createdAt: "",
20
+ projectId: "",
21
+ updatedAt: "",
22
+ metadata: {},
23
+ };
24
+ export const TamboThreadContext = createContext({
25
+ thread: PLACEHOLDER_THREAD,
26
+ switchCurrentThread: () => {
27
+ throw new Error("switchCurrentThread not implemented");
28
+ },
29
+ addThreadMessage: () => {
30
+ throw new Error("updateThreadMessageHistory not implemented");
31
+ },
32
+ setLastThreadStatus: () => {
33
+ throw new Error("setLastThreadStatus not implemented");
34
+ },
35
+ inputValue: "",
36
+ setInputValue: () => {
37
+ throw new Error("setInputValue not implemented");
38
+ },
39
+ updateThreadMessage: () => {
40
+ throw new Error("updateThreadMessage not implemented");
41
+ },
42
+ sendThreadMessage: () => {
43
+ throw new Error("advance not implemented");
44
+ },
45
+ });
46
+ export const TamboThreadProvider = ({ children, }) => {
47
+ const [threadMap, setThreadMap] = useState({
48
+ [PLACEHOLDER_THREAD.id]: PLACEHOLDER_THREAD,
49
+ });
50
+ const client = useTamboClient();
51
+ const { componentList, toolRegistry, componentToolAssociations } = useTamboRegistry();
52
+ const [inputValue, setInputValue] = useState("");
53
+ const [currentThreadId, setCurrentThreadId] = useState(PLACEHOLDER_THREAD.id);
54
+ const [unresolvedThreadId, setUnresolvedThreadId] = useState(PLACEHOLDER_THREAD.id);
55
+ const currentThread = threadMap[currentThreadId];
56
+ // Use existing messages from the current thread to avoid re-generating any components
57
+ const currentMessageCache = useMemo(() => {
58
+ const messageCache = new Map();
59
+ if (currentThread) {
60
+ for (const message of currentThread.messages) {
61
+ messageCache.set(message.id, message);
62
+ }
63
+ }
64
+ return messageCache;
65
+ }, [currentThread]);
66
+ const fetchThread = useCallback(async (threadId) => {
67
+ const thread = await client.beta.threads.retrieve(threadId);
68
+ const threadWithRenderedComponents = {
69
+ ...thread,
70
+ messages: thread.messages.map((message) => {
71
+ if (currentMessageCache.has(message.id)) {
72
+ const renderedMessage = currentMessageCache.get(message.id);
73
+ return {
74
+ ...renderedMessage,
75
+ ...message,
76
+ };
77
+ }
78
+ if (message.component?.componentName) {
79
+ const messageWithComponent = renderComponentIntoMessage(message, componentList);
80
+ return messageWithComponent;
81
+ }
82
+ return message;
83
+ }),
84
+ };
85
+ setThreadMap((prevMap) => ({
86
+ ...prevMap,
87
+ [threadId]: threadWithRenderedComponents,
88
+ }));
89
+ }, [client.beta.threads, componentList, currentMessageCache]);
90
+ useEffect(() => {
91
+ if (currentThreadId &&
92
+ currentThreadId !== PLACEHOLDER_THREAD.id &&
93
+ !threadMap[currentThreadId]) {
94
+ fetchThread(currentThreadId);
95
+ }
96
+ }, [currentThreadId, fetchThread, threadMap]);
97
+ const addThreadMessage = useCallback(async (message, sendToServer = true, createdAt = new Date().toISOString()) => {
98
+ if (!currentThread) {
99
+ console.warn("Cannot add messages if we do not have a current thread");
100
+ return [];
101
+ }
102
+ const chatMessage = {
103
+ ...message,
104
+ additionalContext: message.role === "user" ? getClientContext() : undefined,
105
+ createdAt,
106
+ };
107
+ const threadId = message.threadId;
108
+ // optimistically update the thread in the local state
109
+ setThreadMap((prevMap) => {
110
+ if (!threadId) {
111
+ return prevMap;
112
+ }
113
+ const prevMessages = prevMap[threadId]?.messages || [];
114
+ return {
115
+ ...prevMap,
116
+ [threadId]: {
117
+ ...prevMap[threadId],
118
+ messages: [...prevMessages, chatMessage],
119
+ },
120
+ };
121
+ });
122
+ if (sendToServer) {
123
+ // TODO: if this fails, we need to revert the local state update
124
+ await client.beta.threads.messages.create(currentThreadId, {
125
+ content: message.content,
126
+ role: message.role,
127
+ // additionalContext: chatMessage.additionalContext,
128
+ });
129
+ }
130
+ const updatedMessageHistory = [...currentThread.messages, chatMessage];
131
+ return updatedMessageHistory;
132
+ }, [client.beta.threads.messages, currentThread, currentThreadId]);
133
+ const updateThreadMessage = useCallback(async (id, message, sendToServer = true, createdAt = new Date().toISOString()) => {
134
+ const chatMessage = {
135
+ ...message,
136
+ createdAt,
137
+ };
138
+ setThreadMap((prevMap) => {
139
+ if (!message.threadId) {
140
+ return prevMap;
141
+ }
142
+ const prevMessages = prevMap[message.threadId]?.messages || [];
143
+ const updatedMessages = prevMessages.map((msg) => {
144
+ if (msg.id === id) {
145
+ return chatMessage;
146
+ }
147
+ return msg;
148
+ });
149
+ return {
150
+ ...prevMap,
151
+ [message.threadId]: {
152
+ ...prevMap[message.threadId],
153
+ messages: updatedMessages,
154
+ },
155
+ };
156
+ });
157
+ if (sendToServer) {
158
+ // TODO: if this fails, we need to revert the local state update
159
+ await client.beta.threads.messages.create(currentThreadId, {
160
+ content: message.content,
161
+ role: message.role,
162
+ // additionalContext: chatMessage.additionalContext,
163
+ });
164
+ }
165
+ }, [client.beta.threads.messages, currentThreadId]);
166
+ useEffect(() => {
167
+ if (unresolvedThreadId && currentThreadId !== unresolvedThreadId) {
168
+ setThreadMap((prevMap) => {
169
+ const unresolvedThread = prevMap[unresolvedThreadId];
170
+ const currentThread = prevMap[currentThreadId];
171
+ return {
172
+ ...prevMap,
173
+ [unresolvedThreadId]: PLACEHOLDER_THREAD,
174
+ [currentThreadId]: {
175
+ ...currentThread,
176
+ id: currentThreadId,
177
+ messages: [...unresolvedThread.messages, ...currentThread.messages],
178
+ },
179
+ };
180
+ });
181
+ setUnresolvedThreadId(undefined);
182
+ }
183
+ }, [currentThreadId, unresolvedThreadId]);
184
+ const switchCurrentThread = useCallback(async (threadId) => {
185
+ if (threadId === PLACEHOLDER_THREAD.id) {
186
+ console.warn("Switching to placeholder thread, may be a bug");
187
+ return;
188
+ }
189
+ setCurrentThreadId(threadId);
190
+ if (!threadMap[threadId]) {
191
+ setThreadMap((prevMap) => ({
192
+ ...prevMap,
193
+ [threadId]: {
194
+ ...PLACEHOLDER_THREAD,
195
+ id: threadId,
196
+ },
197
+ }));
198
+ }
199
+ await fetchThread(threadId);
200
+ }, [fetchThread, threadMap]);
201
+ const setLastThreadStatus = (status) => {
202
+ setThreadMap((prevMap) => {
203
+ if (!currentThreadId) {
204
+ return prevMap;
205
+ }
206
+ const headMessages = prevMap[currentThreadId].messages.slice(0, -1);
207
+ const lastMessage = prevMap[currentThreadId].messages[prevMap[currentThreadId].messages.length - 1];
208
+ const updatedLastMessage = {
209
+ ...lastMessage,
210
+ status,
211
+ };
212
+ return {
213
+ ...prevMap,
214
+ [currentThreadId]: {
215
+ ...prevMap[currentThreadId],
216
+ messages: [...headMessages, updatedLastMessage],
217
+ },
218
+ };
219
+ });
220
+ };
221
+ const updateThreadStatus = useCallback((stage) => {
222
+ setThreadMap((prevMap) => {
223
+ return {
224
+ ...prevMap,
225
+ [currentThreadId]: {
226
+ ...prevMap[currentThreadId],
227
+ generationStage: stage,
228
+ },
229
+ };
230
+ });
231
+ }, [currentThreadId]);
232
+ const handleAdvanceStream = useCallback(async (stream, params) => {
233
+ let finalMessage;
234
+ let hasSetThreadId = false;
235
+ updateThreadStatus(GenerationStage.STREAMING_RESPONSE);
236
+ for await (const chunk of stream) {
237
+ if (chunk.responseMessageDto.toolCallRequest) {
238
+ updateThreadStatus(GenerationStage.FETCHING_CONTEXT);
239
+ const toolCallResponse = await handleToolCall(chunk.responseMessageDto, toolRegistry);
240
+ const toolCallResponseParams = {
241
+ ...params,
242
+ messageToAppend: {
243
+ content: [{ type: "text", text: "tool response" }],
244
+ role: "tool",
245
+ actionType: "tool_response",
246
+ toolResponse: toolCallResponse,
247
+ component: chunk.responseMessageDto.component,
248
+ },
249
+ };
250
+ updateThreadStatus(GenerationStage.STREAMING_RESPONSE);
251
+ const toolCallResponseStream = await advanceStream(client, toolCallResponseParams, chunk.responseMessageDto.threadId);
252
+ return handleAdvanceStream(toolCallResponseStream, toolCallResponseParams);
253
+ }
254
+ else {
255
+ if (!hasSetThreadId &&
256
+ chunk.responseMessageDto.threadId &&
257
+ chunk.responseMessageDto.threadId !== currentThread?.id) {
258
+ hasSetThreadId = true;
259
+ switchCurrentThread(chunk.responseMessageDto.threadId);
260
+ }
261
+ if (!finalMessage) {
262
+ finalMessage = chunk.responseMessageDto.component?.componentName
263
+ ? renderComponentIntoMessage(chunk.responseMessageDto, componentList)
264
+ : chunk.responseMessageDto;
265
+ addThreadMessage(finalMessage, false);
266
+ }
267
+ else {
268
+ const previousId = finalMessage.id;
269
+ finalMessage = chunk.responseMessageDto.component?.componentName
270
+ ? renderComponentIntoMessage(chunk.responseMessageDto, componentList)
271
+ : chunk.responseMessageDto;
272
+ updateThreadMessage(previousId, finalMessage, false);
273
+ }
274
+ }
275
+ }
276
+ updateThreadStatus(GenerationStage.COMPLETE);
277
+ return (finalMessage ?? {
278
+ threadId: "",
279
+ content: [{ type: "text", text: `Error processing stream` }],
280
+ role: "hydra",
281
+ createdAt: new Date().toISOString(),
282
+ id: crypto.randomUUID(),
283
+ });
284
+ }, [
285
+ toolRegistry,
286
+ client,
287
+ currentThread?.id,
288
+ switchCurrentThread,
289
+ componentList,
290
+ addThreadMessage,
291
+ updateThreadMessage,
292
+ ]);
293
+ const sendThreadMessage = useCallback(async (message, options = {}) => {
294
+ const { threadId, streamResponse } = options;
295
+ const currentThreadId = threadId ?? currentThread?.id;
296
+ if (currentThreadId !== PLACEHOLDER_THREAD.id) {
297
+ await switchCurrentThread(currentThreadId);
298
+ }
299
+ updateThreadStatus(GenerationStage.CHOOSING_COMPONENT);
300
+ addThreadMessage({
301
+ content: [{ type: "text", text: message }],
302
+ renderedComponent: null,
303
+ role: "user",
304
+ threadId: currentThread.id,
305
+ id: crypto.randomUUID(),
306
+ createdAt: new Date().toISOString(),
307
+ }, false);
308
+ const availableComponents = getAvailableComponents(componentList, toolRegistry, componentToolAssociations);
309
+ const params = {
310
+ messageToAppend: {
311
+ content: [{ type: "text", text: message }],
312
+ role: "user",
313
+ },
314
+ contextKey: options.contextKey,
315
+ availableComponents: availableComponents,
316
+ };
317
+ if (streamResponse) {
318
+ const advanceStreamResponse = await advanceStream(client, params, currentThreadId === PLACEHOLDER_THREAD.id
319
+ ? undefined
320
+ : currentThreadId);
321
+ return handleAdvanceStream(advanceStreamResponse, params);
322
+ }
323
+ let advanceResponse = await (currentThreadId === PLACEHOLDER_THREAD.id
324
+ ? client.beta.threads.advance(params)
325
+ : client.beta.threads.advanceById(currentThreadId, params));
326
+ //handle tool calls
327
+ while (advanceResponse.responseMessageDto.toolCallRequest) {
328
+ updateThreadStatus(GenerationStage.FETCHING_CONTEXT);
329
+ const toolCallResponse = await handleToolCall(advanceResponse.responseMessageDto, toolRegistry);
330
+ const toolCallResponseParams = {
331
+ ...params,
332
+ messageToAppend: {
333
+ ...params.messageToAppend,
334
+ content: [{ type: "text", text: "tool response" }],
335
+ role: "tool",
336
+ actionType: "tool_response",
337
+ toolResponse: toolCallResponse,
338
+ component: advanceResponse.responseMessageDto.component,
339
+ },
340
+ };
341
+ updateThreadStatus(GenerationStage.HYDRATING_COMPONENT);
342
+ advanceResponse = await client.beta.threads.advanceById(advanceResponse.responseMessageDto.threadId, toolCallResponseParams);
343
+ }
344
+ const finalMessage = advanceResponse.responseMessageDto.component
345
+ ?.componentName
346
+ ? renderComponentIntoMessage(advanceResponse.responseMessageDto, componentList)
347
+ : advanceResponse.responseMessageDto;
348
+ await switchCurrentThread(advanceResponse.responseMessageDto.threadId);
349
+ updateThreadStatus(GenerationStage.COMPLETE);
350
+ return finalMessage;
351
+ }, [
352
+ componentList,
353
+ toolRegistry,
354
+ componentToolAssociations,
355
+ currentThread,
356
+ switchCurrentThread,
357
+ addThreadMessage,
358
+ client,
359
+ handleAdvanceStream,
360
+ ]);
361
+ return (React.createElement(TamboThreadContext.Provider, { value: {
362
+ thread: currentThread,
363
+ switchCurrentThread,
364
+ addThreadMessage,
365
+ updateThreadMessage,
366
+ setLastThreadStatus,
367
+ inputValue,
368
+ setInputValue,
369
+ sendThreadMessage,
370
+ } }, children));
371
+ };
372
+ export const useTamboThread = () => {
373
+ const context = useContext(TamboThreadContext);
374
+ if (context === undefined) {
375
+ throw new Error("useTamboThread must be used within a TamboThreadProvider");
376
+ }
377
+ return context;
378
+ };
379
+ //# sourceMappingURL=tambo-thread-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tambo-thread-provider.js","sourceRoot":"","sources":["../../src/providers/tambo-thread-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport TamboAI, { advanceStream } from \"@tambo-ai/typescript-sdk\";\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport {\n GenerationStage,\n TamboThreadMessage,\n} from \"../model/generate-component-response\";\nimport { TamboThread } from \"../model/tambo-thread\";\nimport { renderComponentIntoMessage } from \"../util/generate-component\";\nimport { getAvailableComponents, getClientContext } from \"../util/registry\";\nimport { handleToolCall } from \"../util/tool-caller\";\nimport { useTamboClient } from \"./tambo-client-provider\";\nimport { useTamboRegistry } from \"./tambo-registry-provider\";\n\nexport interface TamboThreadContextProps {\n thread: TamboThread;\n switchCurrentThread: (threadId: string) => void;\n addThreadMessage: (\n message: TamboThreadMessage,\n sendToServer: boolean,\n ) => Promise<TamboAI.Beta.Threads.ThreadMessage[]>;\n updateThreadMessage: (\n id: string,\n message: TamboThreadMessage,\n sendToServer: boolean,\n ) => Promise<void>;\n setLastThreadStatus: (status: GenerationStage) => void;\n inputValue: string;\n setInputValue: (value: string) => void;\n sendThreadMessage: (\n message: string,\n options?: {\n threadId?: string;\n streamResponse?: boolean;\n contextKey?: string;\n },\n ) => Promise<TamboThreadMessage>;\n}\n\n/** This is a stub entry for when the thread is not yet created, the first time\n * the user sends a message\n *\n * Note that the consumer needs to be careful never to send `PLACEHOLDER_THREAD.id` to the server,\n * as this doesn't really exist on the server side.\n */\nexport const PLACEHOLDER_THREAD: TamboThread = {\n id: \"placeholder\",\n messages: [],\n createdAt: \"\",\n projectId: \"\",\n updatedAt: \"\",\n metadata: {},\n};\n\nexport const TamboThreadContext = createContext<TamboThreadContextProps>({\n thread: PLACEHOLDER_THREAD,\n switchCurrentThread: () => {\n throw new Error(\"switchCurrentThread not implemented\");\n },\n addThreadMessage: () => {\n throw new Error(\"updateThreadMessageHistory not implemented\");\n },\n setLastThreadStatus: () => {\n throw new Error(\"setLastThreadStatus not implemented\");\n },\n inputValue: \"\",\n setInputValue: () => {\n throw new Error(\"setInputValue not implemented\");\n },\n updateThreadMessage: () => {\n throw new Error(\"updateThreadMessage not implemented\");\n },\n sendThreadMessage: () => {\n throw new Error(\"advance not implemented\");\n },\n});\n\nexport const TamboThreadProvider: React.FC<PropsWithChildren> = ({\n children,\n}) => {\n const [threadMap, setThreadMap] = useState<Record<string, TamboThread>>({\n [PLACEHOLDER_THREAD.id]: PLACEHOLDER_THREAD,\n });\n const client = useTamboClient();\n const { componentList, toolRegistry, componentToolAssociations } =\n useTamboRegistry();\n const [inputValue, setInputValue] = useState(\"\");\n\n const [currentThreadId, setCurrentThreadId] = useState<string>(\n PLACEHOLDER_THREAD.id,\n );\n const [unresolvedThreadId, setUnresolvedThreadId] = useState<\n string | undefined\n >(PLACEHOLDER_THREAD.id);\n const currentThread: TamboThread | undefined = threadMap[currentThreadId];\n // Use existing messages from the current thread to avoid re-generating any components\n const currentMessageCache = useMemo(() => {\n const messageCache = new Map<string, TamboThreadMessage>();\n if (currentThread) {\n for (const message of currentThread.messages) {\n messageCache.set(message.id, message);\n }\n }\n return messageCache;\n }, [currentThread]);\n\n const fetchThread = useCallback(\n async (threadId: string) => {\n const thread = await client.beta.threads.retrieve(threadId);\n const threadWithRenderedComponents = {\n ...thread,\n messages: thread.messages.map((message) => {\n if (currentMessageCache.has(message.id)) {\n const renderedMessage = currentMessageCache.get(message.id);\n return {\n ...renderedMessage,\n ...message,\n };\n }\n if (message.component?.componentName) {\n const messageWithComponent = renderComponentIntoMessage(\n message,\n componentList,\n );\n return messageWithComponent;\n }\n return message;\n }),\n };\n\n setThreadMap((prevMap) => ({\n ...prevMap,\n [threadId]: threadWithRenderedComponents,\n }));\n },\n [client.beta.threads, componentList, currentMessageCache],\n );\n\n useEffect(() => {\n if (\n currentThreadId &&\n currentThreadId !== PLACEHOLDER_THREAD.id &&\n !threadMap[currentThreadId]\n ) {\n fetchThread(currentThreadId);\n }\n }, [currentThreadId, fetchThread, threadMap]);\n\n const addThreadMessage = useCallback(\n async (\n message: TamboThreadMessage,\n sendToServer = true,\n createdAt: string = new Date().toISOString(),\n ) => {\n if (!currentThread) {\n console.warn(\"Cannot add messages if we do not have a current thread\");\n return [];\n }\n const chatMessage: TamboThreadMessage & {\n additionalContext?: string;\n } = {\n ...message,\n additionalContext:\n message.role === \"user\" ? getClientContext() : undefined,\n createdAt,\n };\n const threadId = message.threadId;\n // optimistically update the thread in the local state\n setThreadMap((prevMap) => {\n if (!threadId) {\n return prevMap;\n }\n const prevMessages = prevMap[threadId]?.messages || [];\n return {\n ...prevMap,\n [threadId]: {\n ...prevMap[threadId],\n messages: [...prevMessages, chatMessage],\n },\n };\n });\n if (sendToServer) {\n // TODO: if this fails, we need to revert the local state update\n await client.beta.threads.messages.create(currentThreadId, {\n content: message.content,\n role: message.role,\n // additionalContext: chatMessage.additionalContext,\n });\n }\n const updatedMessageHistory = [...currentThread.messages, chatMessage];\n\n return updatedMessageHistory;\n },\n [client.beta.threads.messages, currentThread, currentThreadId],\n );\n\n const updateThreadMessage = useCallback(\n async (\n id: string,\n message: TamboThreadMessage,\n sendToServer = true,\n createdAt: string = new Date().toISOString(),\n ) => {\n const chatMessage: TamboThreadMessage = {\n ...message,\n createdAt,\n };\n\n setThreadMap((prevMap) => {\n if (!message.threadId) {\n return prevMap;\n }\n const prevMessages = prevMap[message.threadId]?.messages || [];\n const updatedMessages = prevMessages.map((msg) => {\n if (msg.id === id) {\n return chatMessage;\n }\n return msg;\n });\n return {\n ...prevMap,\n [message.threadId]: {\n ...prevMap[message.threadId],\n messages: updatedMessages,\n },\n };\n });\n if (sendToServer) {\n // TODO: if this fails, we need to revert the local state update\n await client.beta.threads.messages.create(currentThreadId, {\n content: message.content,\n role: message.role,\n // additionalContext: chatMessage.additionalContext,\n });\n }\n },\n [client.beta.threads.messages, currentThreadId],\n );\n\n useEffect(() => {\n if (unresolvedThreadId && currentThreadId !== unresolvedThreadId) {\n setThreadMap((prevMap) => {\n const unresolvedThread = prevMap[unresolvedThreadId];\n const currentThread = prevMap[currentThreadId];\n return {\n ...prevMap,\n [unresolvedThreadId]: PLACEHOLDER_THREAD,\n [currentThreadId]: {\n ...currentThread,\n id: currentThreadId,\n messages: [...unresolvedThread.messages, ...currentThread.messages],\n },\n };\n });\n setUnresolvedThreadId(undefined);\n }\n }, [currentThreadId, unresolvedThreadId]);\n\n const switchCurrentThread = useCallback(\n async (threadId: string) => {\n if (threadId === PLACEHOLDER_THREAD.id) {\n console.warn(\"Switching to placeholder thread, may be a bug\");\n return;\n }\n setCurrentThreadId(threadId);\n if (!threadMap[threadId]) {\n setThreadMap((prevMap) => ({\n ...prevMap,\n [threadId]: {\n ...PLACEHOLDER_THREAD,\n id: threadId,\n },\n }));\n }\n await fetchThread(threadId);\n },\n [fetchThread, threadMap],\n );\n\n const setLastThreadStatus = (status: GenerationStage) => {\n setThreadMap((prevMap) => {\n if (!currentThreadId) {\n return prevMap;\n }\n const headMessages = prevMap[currentThreadId].messages.slice(0, -1);\n const lastMessage =\n prevMap[currentThreadId].messages[\n prevMap[currentThreadId].messages.length - 1\n ];\n const updatedLastMessage = {\n ...lastMessage,\n status,\n };\n return {\n ...prevMap,\n [currentThreadId]: {\n ...prevMap[currentThreadId],\n messages: [...headMessages, updatedLastMessage],\n },\n };\n });\n };\n\n const updateThreadStatus = useCallback(\n (stage: GenerationStage) => {\n setThreadMap((prevMap) => {\n return {\n ...prevMap,\n [currentThreadId]: {\n ...prevMap[currentThreadId],\n generationStage: stage,\n },\n };\n });\n },\n [currentThreadId],\n );\n\n const handleAdvanceStream = useCallback(\n async (\n stream: AsyncIterable<TamboAI.Beta.Threads.ThreadAdvanceResponse>,\n params: TamboAI.Beta.Threads.ThreadAdvanceParams,\n ): Promise<TamboThreadMessage> => {\n let finalMessage: TamboThreadMessage | undefined;\n let hasSetThreadId = false;\n updateThreadStatus(GenerationStage.STREAMING_RESPONSE);\n for await (const chunk of stream) {\n if (chunk.responseMessageDto.toolCallRequest) {\n updateThreadStatus(GenerationStage.FETCHING_CONTEXT);\n const toolCallResponse = await handleToolCall(\n chunk.responseMessageDto,\n toolRegistry,\n );\n const toolCallResponseParams: TamboAI.Beta.Threads.ThreadAdvanceParams =\n {\n ...params,\n messageToAppend: {\n content: [{ type: \"text\", text: \"tool response\" }],\n role: \"tool\",\n actionType: \"tool_response\",\n toolResponse: toolCallResponse,\n component: chunk.responseMessageDto.component,\n },\n };\n updateThreadStatus(GenerationStage.STREAMING_RESPONSE);\n const toolCallResponseStream = await advanceStream(\n client,\n toolCallResponseParams,\n chunk.responseMessageDto.threadId,\n );\n return handleAdvanceStream(\n toolCallResponseStream,\n toolCallResponseParams,\n );\n } else {\n if (\n !hasSetThreadId &&\n chunk.responseMessageDto.threadId &&\n chunk.responseMessageDto.threadId !== currentThread?.id\n ) {\n hasSetThreadId = true;\n switchCurrentThread(chunk.responseMessageDto.threadId);\n }\n\n if (!finalMessage) {\n finalMessage = chunk.responseMessageDto.component?.componentName\n ? renderComponentIntoMessage(\n chunk.responseMessageDto,\n componentList,\n )\n : chunk.responseMessageDto;\n addThreadMessage(finalMessage, false);\n } else {\n const previousId = finalMessage.id;\n finalMessage = chunk.responseMessageDto.component?.componentName\n ? renderComponentIntoMessage(\n chunk.responseMessageDto,\n componentList,\n )\n : chunk.responseMessageDto;\n updateThreadMessage(previousId, finalMessage, false);\n }\n }\n }\n\n updateThreadStatus(GenerationStage.COMPLETE);\n return (\n finalMessage ?? {\n threadId: \"\",\n content: [{ type: \"text\", text: `Error processing stream` }],\n role: \"hydra\",\n createdAt: new Date().toISOString(),\n id: crypto.randomUUID(),\n }\n );\n },\n [\n toolRegistry,\n client,\n currentThread?.id,\n switchCurrentThread,\n componentList,\n addThreadMessage,\n updateThreadMessage,\n ],\n );\n\n const sendThreadMessage = useCallback(\n async (\n message: string,\n options: {\n threadId?: string;\n streamResponse?: boolean;\n contextKey?: string;\n } = {},\n ): Promise<TamboThreadMessage> => {\n const { threadId, streamResponse } = options;\n const currentThreadId = threadId ?? currentThread?.id;\n\n if (currentThreadId !== PLACEHOLDER_THREAD.id) {\n await switchCurrentThread(currentThreadId);\n }\n\n updateThreadStatus(GenerationStage.CHOOSING_COMPONENT);\n\n addThreadMessage(\n {\n content: [{ type: \"text\", text: message }],\n renderedComponent: null,\n role: \"user\",\n threadId: currentThread.id,\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n },\n false,\n );\n\n const availableComponents = getAvailableComponents(\n componentList,\n toolRegistry,\n componentToolAssociations,\n );\n const params: TamboAI.Beta.Threads.ThreadAdvanceParams = {\n messageToAppend: {\n content: [{ type: \"text\", text: message }],\n role: \"user\",\n },\n contextKey: options.contextKey,\n availableComponents: availableComponents,\n };\n\n if (streamResponse) {\n const advanceStreamResponse = await advanceStream(\n client,\n params,\n currentThreadId === PLACEHOLDER_THREAD.id\n ? undefined\n : currentThreadId,\n );\n return handleAdvanceStream(advanceStreamResponse, params);\n }\n let advanceResponse = await (currentThreadId === PLACEHOLDER_THREAD.id\n ? client.beta.threads.advance(params)\n : client.beta.threads.advanceById(currentThreadId, params));\n\n //handle tool calls\n while (advanceResponse.responseMessageDto.toolCallRequest) {\n updateThreadStatus(GenerationStage.FETCHING_CONTEXT);\n const toolCallResponse = await handleToolCall(\n advanceResponse.responseMessageDto,\n toolRegistry,\n );\n const toolCallResponseParams: TamboAI.Beta.Threads.ThreadAdvanceParams =\n {\n ...params,\n messageToAppend: {\n ...params.messageToAppend,\n content: [{ type: \"text\", text: \"tool response\" }],\n role: \"tool\",\n actionType: \"tool_response\",\n toolResponse: toolCallResponse,\n component: advanceResponse.responseMessageDto.component,\n },\n };\n updateThreadStatus(GenerationStage.HYDRATING_COMPONENT);\n advanceResponse = await client.beta.threads.advanceById(\n advanceResponse.responseMessageDto.threadId,\n toolCallResponseParams,\n );\n }\n\n const finalMessage = advanceResponse.responseMessageDto.component\n ?.componentName\n ? renderComponentIntoMessage(\n advanceResponse.responseMessageDto,\n componentList,\n )\n : advanceResponse.responseMessageDto;\n await switchCurrentThread(advanceResponse.responseMessageDto.threadId);\n updateThreadStatus(GenerationStage.COMPLETE);\n return finalMessage;\n },\n [\n componentList,\n toolRegistry,\n componentToolAssociations,\n currentThread,\n switchCurrentThread,\n addThreadMessage,\n client,\n handleAdvanceStream,\n ],\n );\n\n return (\n <TamboThreadContext.Provider\n value={{\n thread: currentThread,\n switchCurrentThread,\n addThreadMessage,\n updateThreadMessage,\n setLastThreadStatus,\n inputValue,\n setInputValue,\n sendThreadMessage,\n }}\n >\n {children}\n </TamboThreadContext.Provider>\n );\n};\n\nexport const useTamboThread = () => {\n const context = useContext(TamboThreadContext);\n if (context === undefined) {\n throw new Error(\"useTamboThread must be used within a TamboThreadProvider\");\n }\n return context;\n};\n"]}
@@ -0,0 +1 @@
1
+ import "@testing-library/jest-dom";
@@ -0,0 +1,18 @@
1
+ import "@testing-library/jest-dom";
2
+ // Mock AbortController
3
+ const mockSignal = {
4
+ aborted: false,
5
+ reason: undefined,
6
+ onabort: null,
7
+ addEventListener: jest.fn(),
8
+ removeEventListener: jest.fn(),
9
+ dispatchEvent: jest.fn(),
10
+ throwIfAborted: jest.fn(),
11
+ any: jest.fn(),
12
+ };
13
+ const MockAbortController = class {
14
+ signal = mockSignal;
15
+ abort = jest.fn();
16
+ };
17
+ global.AbortController = MockAbortController;
18
+ //# sourceMappingURL=setupTests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setupTests.js","sourceRoot":"","sources":["../src/setupTests.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC;AAEnC,uBAAuB;AACvB,MAAM,UAAU,GAAG;IACjB,OAAO,EAAE,KAAK;IACd,MAAM,EAAE,SAAS;IACjB,OAAO,EAAE,IAAI;IACb,gBAAgB,EAAE,IAAI,CAAC,EAAE,EAAE;IAC3B,mBAAmB,EAAE,IAAI,CAAC,EAAE,EAAE;IAC9B,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE;IACxB,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;IACzB,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE;CACW,CAAC;AAE5B,MAAM,mBAAmB,GAAG;IAC1B,MAAM,GAAG,UAAU,CAAC;IACpB,KAAK,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;CACkB,CAAC;AAEvC,MAAM,CAAC,eAAe,GAAG,mBAAmB,CAAC","sourcesContent":["import \"@testing-library/jest-dom\";\n\n// Mock AbortController\nconst mockSignal = {\n aborted: false,\n reason: undefined,\n onabort: null,\n addEventListener: jest.fn(),\n removeEventListener: jest.fn(),\n dispatchEvent: jest.fn(),\n throwIfAborted: jest.fn(),\n any: jest.fn(),\n} as unknown as AbortSignal;\n\nconst MockAbortController = class {\n signal = mockSignal;\n abort = jest.fn();\n} as unknown as typeof AbortController;\n\nglobal.AbortController = MockAbortController;\n"]}
@@ -0,0 +1,8 @@
1
+ import TamboAI from "@tambo-ai/typescript-sdk";
2
+ import { ComponentRegistry, TamboToolAssociations, TamboToolRegistry } from "../model/component-metadata";
3
+ import { GenerationStage, TamboThreadMessage } from "../model/generate-component-response";
4
+ export declare function generateAndHydrate(client: TamboAI, componentList: ComponentRegistry, toolRegistry: TamboToolRegistry, toolAssociations: TamboToolAssociations, currentThreadId: string | undefined, content: TamboAI.Beta.Threads.ChatCompletionContentPart[], params: TamboAI.Beta.Components.ComponentGenerateParams, onUpdateState: (state: GenerationStage) => void, stream?: boolean, options?: TamboAI.RequestOptions): Promise<TamboThreadMessage | AsyncIterable<TamboThreadMessage>>;
5
+ /**
6
+ * Generate a message that has a component rendered into it, if the message came with one
7
+ */
8
+ export declare function renderComponentIntoMessage(message: TamboAI.Beta.Threads.ThreadMessage, componentList: ComponentRegistry): TamboThreadMessage;