@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.
- package/README.md +9 -0
- package/dist/hooks/__tests__/use-suggestions.test.d.ts +1 -0
- package/dist/hooks/__tests__/use-suggestions.test.js +167 -0
- package/dist/hooks/__tests__/use-suggestions.test.js.map +1 -0
- package/dist/hooks/react-query-hooks.d.ts +21 -0
- package/dist/hooks/react-query-hooks.js +33 -0
- package/dist/hooks/react-query-hooks.js.map +1 -0
- package/dist/hooks/use-component-state.d.ts +8 -0
- package/dist/hooks/use-component-state.js +42 -0
- package/dist/hooks/use-component-state.js.map +1 -0
- package/dist/hooks/use-current-message.d.ts +18 -0
- package/dist/hooks/use-current-message.js +73 -0
- package/dist/hooks/use-current-message.js.map +1 -0
- package/dist/hooks/use-query-client.d.ts +0 -0
- package/dist/hooks/use-query-client.js +2 -0
- package/dist/hooks/use-query-client.js.map +1 -0
- package/dist/hooks/use-suggestions.d.ts +44 -0
- package/dist/hooks/use-suggestions.js +111 -0
- package/dist/hooks/use-suggestions.js.map +1 -0
- package/dist/hooks/use-tambo-threads.d.ts +137 -0
- package/dist/hooks/use-tambo-threads.js +33 -0
- package/dist/hooks/use-tambo-threads.js.map +1 -0
- package/dist/hooks/use-thread-input.d.ts +48 -0
- package/dist/hooks/use-thread-input.js +53 -0
- package/dist/hooks/use-thread-input.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/model/component-metadata.d.ts +32 -0
- package/dist/model/component-metadata.js +3 -0
- package/dist/model/component-metadata.js.map +1 -0
- package/dist/model/generate-component-response.d.ts +17 -0
- package/dist/model/generate-component-response.js +22 -0
- package/dist/model/generate-component-response.js.map +1 -0
- package/dist/model/tambo-thread.d.ts +7 -0
- package/dist/model/tambo-thread.js +3 -0
- package/dist/model/tambo-thread.js.map +1 -0
- package/dist/model/thread-input-error.d.ts +3 -0
- package/dist/model/thread-input-error.js +8 -0
- package/dist/model/thread-input-error.js.map +1 -0
- package/dist/model/validate-input.d.ts +6 -0
- package/dist/model/validate-input.js +27 -0
- package/dist/model/validate-input.js.map +1 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.js +21 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/tambo-client-provider.d.ts +15 -0
- package/dist/providers/tambo-client-provider.js +66 -0
- package/dist/providers/tambo-client-provider.js.map +1 -0
- package/dist/providers/tambo-component-provider.d.ts +18 -0
- package/dist/providers/tambo-component-provider.js +129 -0
- package/dist/providers/tambo-component-provider.js.map +1 -0
- package/dist/providers/tambo-provider.d.ts +10 -0
- package/dist/providers/tambo-provider.js +70 -0
- package/dist/providers/tambo-provider.js.map +1 -0
- package/dist/providers/tambo-registry-provider.d.ts +21 -0
- package/dist/providers/tambo-registry-provider.js +117 -0
- package/dist/providers/tambo-registry-provider.js.map +1 -0
- package/dist/providers/tambo-thread-provider.d.ts +28 -0
- package/dist/providers/tambo-thread-provider.js +417 -0
- package/dist/providers/tambo-thread-provider.js.map +1 -0
- package/dist/setupTests.d.ts +1 -0
- package/dist/setupTests.js +20 -0
- package/dist/setupTests.js.map +1 -0
- package/dist/util/generate-component.d.ts +8 -0
- package/dist/util/generate-component.js +209 -0
- package/dist/util/generate-component.js.map +1 -0
- package/dist/util/messages.d.ts +2 -0
- package/dist/util/messages.js +12 -0
- package/dist/util/messages.js.map +1 -0
- package/dist/util/query-utils.d.ts +5 -0
- package/dist/util/query-utils.js +63 -0
- package/dist/util/query-utils.js.map +1 -0
- package/dist/util/registry.d.ts +7 -0
- package/dist/util/registry.js +99 -0
- package/dist/util/registry.js.map +1 -0
- package/dist/util/tool-caller.d.ts +3 -0
- package/dist/util/tool-caller.js +30 -0
- package/dist/util/tool-caller.js.map +1 -0
- package/esm/hooks/__tests__/use-suggestions.test.d.ts +1 -0
- package/esm/hooks/__tests__/use-suggestions.test.js +165 -0
- package/esm/hooks/__tests__/use-suggestions.test.js.map +1 -0
- package/esm/hooks/react-query-hooks.d.ts +21 -0
- package/esm/hooks/react-query-hooks.js +28 -0
- package/esm/hooks/react-query-hooks.js.map +1 -0
- package/esm/hooks/use-component-state.d.ts +8 -0
- package/esm/hooks/use-component-state.js +39 -0
- package/esm/hooks/use-component-state.js.map +1 -0
- package/esm/hooks/use-current-message.d.ts +18 -0
- package/esm/hooks/use-current-message.js +33 -0
- package/esm/hooks/use-current-message.js.map +1 -0
- package/esm/hooks/use-query-client.d.ts +0 -0
- package/esm/hooks/use-query-client.js +2 -0
- package/esm/hooks/use-query-client.js.map +1 -0
- package/esm/hooks/use-suggestions.d.ts +44 -0
- package/esm/hooks/use-suggestions.js +108 -0
- package/esm/hooks/use-suggestions.js.map +1 -0
- package/esm/hooks/use-tambo-threads.d.ts +137 -0
- package/esm/hooks/use-tambo-threads.js +30 -0
- package/esm/hooks/use-tambo-threads.js.map +1 -0
- package/esm/hooks/use-thread-input.d.ts +48 -0
- package/esm/hooks/use-thread-input.js +49 -0
- package/esm/hooks/use-thread-input.js.map +1 -0
- package/esm/index.d.ts +12 -0
- package/esm/index.js +10 -0
- package/esm/index.js.map +1 -0
- package/esm/model/component-metadata.d.ts +32 -0
- package/esm/model/component-metadata.js +2 -0
- package/esm/model/component-metadata.js.map +1 -0
- package/esm/model/generate-component-response.d.ts +17 -0
- package/esm/model/generate-component-response.js +18 -0
- package/esm/model/generate-component-response.js.map +1 -0
- package/esm/model/tambo-thread.d.ts +7 -0
- package/esm/model/tambo-thread.js +2 -0
- package/esm/model/tambo-thread.js.map +1 -0
- package/esm/model/thread-input-error.d.ts +3 -0
- package/esm/model/thread-input-error.js +4 -0
- package/esm/model/thread-input-error.js.map +1 -0
- package/esm/model/validate-input.d.ts +6 -0
- package/esm/model/validate-input.js +24 -0
- package/esm/model/validate-input.js.map +1 -0
- package/esm/providers/index.d.ts +5 -0
- package/esm/providers/index.js +6 -0
- package/esm/providers/index.js.map +1 -0
- package/esm/providers/tambo-client-provider.d.ts +15 -0
- package/esm/providers/tambo-client-provider.js +24 -0
- package/esm/providers/tambo-client-provider.js.map +1 -0
- package/esm/providers/tambo-component-provider.d.ts +18 -0
- package/esm/providers/tambo-component-provider.js +91 -0
- package/esm/providers/tambo-component-provider.js.map +1 -0
- package/esm/providers/tambo-provider.d.ts +10 -0
- package/esm/providers/tambo-provider.js +32 -0
- package/esm/providers/tambo-provider.js.map +1 -0
- package/esm/providers/tambo-registry-provider.d.ts +21 -0
- package/esm/providers/tambo-registry-provider.js +79 -0
- package/esm/providers/tambo-registry-provider.js.map +1 -0
- package/esm/providers/tambo-thread-provider.d.ts +28 -0
- package/esm/providers/tambo-thread-provider.js +379 -0
- package/esm/providers/tambo-thread-provider.js.map +1 -0
- package/esm/setupTests.d.ts +1 -0
- package/esm/setupTests.js +18 -0
- package/esm/setupTests.js.map +1 -0
- package/esm/util/generate-component.d.ts +8 -0
- package/esm/util/generate-component.js +202 -0
- package/esm/util/generate-component.js.map +1 -0
- package/esm/util/messages.d.ts +2 -0
- package/esm/util/messages.js +9 -0
- package/esm/util/messages.js.map +1 -0
- package/esm/util/query-utils.d.ts +5 -0
- package/esm/util/query-utils.js +59 -0
- package/esm/util/query-utils.js.map +1 -0
- package/esm/util/registry.d.ts +7 -0
- package/esm/util/registry.js +88 -0
- package/esm/util/registry.js.map +1 -0
- package/esm/util/tool-caller.d.ts +3 -0
- package/esm/util/tool-caller.js +26 -0
- package/esm/util/tool-caller.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.useTamboThread = exports.TamboThreadProvider = exports.TamboThreadContext = exports.PLACEHOLDER_THREAD = void 0;
|
|
38
|
+
const typescript_sdk_1 = require("@tambo-ai/typescript-sdk");
|
|
39
|
+
const react_1 = __importStar(require("react"));
|
|
40
|
+
const generate_component_response_1 = require("../model/generate-component-response");
|
|
41
|
+
const generate_component_1 = require("../util/generate-component");
|
|
42
|
+
const registry_1 = require("../util/registry");
|
|
43
|
+
const tool_caller_1 = require("../util/tool-caller");
|
|
44
|
+
const tambo_client_provider_1 = require("./tambo-client-provider");
|
|
45
|
+
const tambo_registry_provider_1 = require("./tambo-registry-provider");
|
|
46
|
+
/** This is a stub entry for when the thread is not yet created, the first time
|
|
47
|
+
* the user sends a message
|
|
48
|
+
*
|
|
49
|
+
* Note that the consumer needs to be careful never to send `PLACEHOLDER_THREAD.id` to the server,
|
|
50
|
+
* as this doesn't really exist on the server side.
|
|
51
|
+
*/
|
|
52
|
+
exports.PLACEHOLDER_THREAD = {
|
|
53
|
+
id: "placeholder",
|
|
54
|
+
messages: [],
|
|
55
|
+
createdAt: "",
|
|
56
|
+
projectId: "",
|
|
57
|
+
updatedAt: "",
|
|
58
|
+
metadata: {},
|
|
59
|
+
};
|
|
60
|
+
exports.TamboThreadContext = (0, react_1.createContext)({
|
|
61
|
+
thread: exports.PLACEHOLDER_THREAD,
|
|
62
|
+
switchCurrentThread: () => {
|
|
63
|
+
throw new Error("switchCurrentThread not implemented");
|
|
64
|
+
},
|
|
65
|
+
addThreadMessage: () => {
|
|
66
|
+
throw new Error("updateThreadMessageHistory not implemented");
|
|
67
|
+
},
|
|
68
|
+
setLastThreadStatus: () => {
|
|
69
|
+
throw new Error("setLastThreadStatus not implemented");
|
|
70
|
+
},
|
|
71
|
+
inputValue: "",
|
|
72
|
+
setInputValue: () => {
|
|
73
|
+
throw new Error("setInputValue not implemented");
|
|
74
|
+
},
|
|
75
|
+
updateThreadMessage: () => {
|
|
76
|
+
throw new Error("updateThreadMessage not implemented");
|
|
77
|
+
},
|
|
78
|
+
sendThreadMessage: () => {
|
|
79
|
+
throw new Error("advance not implemented");
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
const TamboThreadProvider = ({ children, }) => {
|
|
83
|
+
const [threadMap, setThreadMap] = (0, react_1.useState)({
|
|
84
|
+
[exports.PLACEHOLDER_THREAD.id]: exports.PLACEHOLDER_THREAD,
|
|
85
|
+
});
|
|
86
|
+
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
87
|
+
const { componentList, toolRegistry, componentToolAssociations } = (0, tambo_registry_provider_1.useTamboRegistry)();
|
|
88
|
+
const [inputValue, setInputValue] = (0, react_1.useState)("");
|
|
89
|
+
const [currentThreadId, setCurrentThreadId] = (0, react_1.useState)(exports.PLACEHOLDER_THREAD.id);
|
|
90
|
+
const [unresolvedThreadId, setUnresolvedThreadId] = (0, react_1.useState)(exports.PLACEHOLDER_THREAD.id);
|
|
91
|
+
const currentThread = threadMap[currentThreadId];
|
|
92
|
+
// Use existing messages from the current thread to avoid re-generating any components
|
|
93
|
+
const currentMessageCache = (0, react_1.useMemo)(() => {
|
|
94
|
+
const messageCache = new Map();
|
|
95
|
+
if (currentThread) {
|
|
96
|
+
for (const message of currentThread.messages) {
|
|
97
|
+
messageCache.set(message.id, message);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return messageCache;
|
|
101
|
+
}, [currentThread]);
|
|
102
|
+
const fetchThread = (0, react_1.useCallback)(async (threadId) => {
|
|
103
|
+
const thread = await client.beta.threads.retrieve(threadId);
|
|
104
|
+
const threadWithRenderedComponents = {
|
|
105
|
+
...thread,
|
|
106
|
+
messages: thread.messages.map((message) => {
|
|
107
|
+
if (currentMessageCache.has(message.id)) {
|
|
108
|
+
const renderedMessage = currentMessageCache.get(message.id);
|
|
109
|
+
return {
|
|
110
|
+
...renderedMessage,
|
|
111
|
+
...message,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (message.component?.componentName) {
|
|
115
|
+
const messageWithComponent = (0, generate_component_1.renderComponentIntoMessage)(message, componentList);
|
|
116
|
+
return messageWithComponent;
|
|
117
|
+
}
|
|
118
|
+
return message;
|
|
119
|
+
}),
|
|
120
|
+
};
|
|
121
|
+
setThreadMap((prevMap) => ({
|
|
122
|
+
...prevMap,
|
|
123
|
+
[threadId]: threadWithRenderedComponents,
|
|
124
|
+
}));
|
|
125
|
+
}, [client.beta.threads, componentList, currentMessageCache]);
|
|
126
|
+
(0, react_1.useEffect)(() => {
|
|
127
|
+
if (currentThreadId &&
|
|
128
|
+
currentThreadId !== exports.PLACEHOLDER_THREAD.id &&
|
|
129
|
+
!threadMap[currentThreadId]) {
|
|
130
|
+
fetchThread(currentThreadId);
|
|
131
|
+
}
|
|
132
|
+
}, [currentThreadId, fetchThread, threadMap]);
|
|
133
|
+
const addThreadMessage = (0, react_1.useCallback)(async (message, sendToServer = true, createdAt = new Date().toISOString()) => {
|
|
134
|
+
if (!currentThread) {
|
|
135
|
+
console.warn("Cannot add messages if we do not have a current thread");
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
const chatMessage = {
|
|
139
|
+
...message,
|
|
140
|
+
additionalContext: message.role === "user" ? (0, registry_1.getClientContext)() : undefined,
|
|
141
|
+
createdAt,
|
|
142
|
+
};
|
|
143
|
+
const threadId = message.threadId;
|
|
144
|
+
// optimistically update the thread in the local state
|
|
145
|
+
setThreadMap((prevMap) => {
|
|
146
|
+
if (!threadId) {
|
|
147
|
+
return prevMap;
|
|
148
|
+
}
|
|
149
|
+
const prevMessages = prevMap[threadId]?.messages || [];
|
|
150
|
+
return {
|
|
151
|
+
...prevMap,
|
|
152
|
+
[threadId]: {
|
|
153
|
+
...prevMap[threadId],
|
|
154
|
+
messages: [...prevMessages, chatMessage],
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
});
|
|
158
|
+
if (sendToServer) {
|
|
159
|
+
// TODO: if this fails, we need to revert the local state update
|
|
160
|
+
await client.beta.threads.messages.create(currentThreadId, {
|
|
161
|
+
content: message.content,
|
|
162
|
+
role: message.role,
|
|
163
|
+
// additionalContext: chatMessage.additionalContext,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
const updatedMessageHistory = [...currentThread.messages, chatMessage];
|
|
167
|
+
return updatedMessageHistory;
|
|
168
|
+
}, [client.beta.threads.messages, currentThread, currentThreadId]);
|
|
169
|
+
const updateThreadMessage = (0, react_1.useCallback)(async (id, message, sendToServer = true, createdAt = new Date().toISOString()) => {
|
|
170
|
+
const chatMessage = {
|
|
171
|
+
...message,
|
|
172
|
+
createdAt,
|
|
173
|
+
};
|
|
174
|
+
setThreadMap((prevMap) => {
|
|
175
|
+
if (!message.threadId) {
|
|
176
|
+
return prevMap;
|
|
177
|
+
}
|
|
178
|
+
const prevMessages = prevMap[message.threadId]?.messages || [];
|
|
179
|
+
const updatedMessages = prevMessages.map((msg) => {
|
|
180
|
+
if (msg.id === id) {
|
|
181
|
+
return chatMessage;
|
|
182
|
+
}
|
|
183
|
+
return msg;
|
|
184
|
+
});
|
|
185
|
+
return {
|
|
186
|
+
...prevMap,
|
|
187
|
+
[message.threadId]: {
|
|
188
|
+
...prevMap[message.threadId],
|
|
189
|
+
messages: updatedMessages,
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
});
|
|
193
|
+
if (sendToServer) {
|
|
194
|
+
// TODO: if this fails, we need to revert the local state update
|
|
195
|
+
await client.beta.threads.messages.create(currentThreadId, {
|
|
196
|
+
content: message.content,
|
|
197
|
+
role: message.role,
|
|
198
|
+
// additionalContext: chatMessage.additionalContext,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}, [client.beta.threads.messages, currentThreadId]);
|
|
202
|
+
(0, react_1.useEffect)(() => {
|
|
203
|
+
if (unresolvedThreadId && currentThreadId !== unresolvedThreadId) {
|
|
204
|
+
setThreadMap((prevMap) => {
|
|
205
|
+
const unresolvedThread = prevMap[unresolvedThreadId];
|
|
206
|
+
const currentThread = prevMap[currentThreadId];
|
|
207
|
+
return {
|
|
208
|
+
...prevMap,
|
|
209
|
+
[unresolvedThreadId]: exports.PLACEHOLDER_THREAD,
|
|
210
|
+
[currentThreadId]: {
|
|
211
|
+
...currentThread,
|
|
212
|
+
id: currentThreadId,
|
|
213
|
+
messages: [...unresolvedThread.messages, ...currentThread.messages],
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
});
|
|
217
|
+
setUnresolvedThreadId(undefined);
|
|
218
|
+
}
|
|
219
|
+
}, [currentThreadId, unresolvedThreadId]);
|
|
220
|
+
const switchCurrentThread = (0, react_1.useCallback)(async (threadId) => {
|
|
221
|
+
if (threadId === exports.PLACEHOLDER_THREAD.id) {
|
|
222
|
+
console.warn("Switching to placeholder thread, may be a bug");
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
setCurrentThreadId(threadId);
|
|
226
|
+
if (!threadMap[threadId]) {
|
|
227
|
+
setThreadMap((prevMap) => ({
|
|
228
|
+
...prevMap,
|
|
229
|
+
[threadId]: {
|
|
230
|
+
...exports.PLACEHOLDER_THREAD,
|
|
231
|
+
id: threadId,
|
|
232
|
+
},
|
|
233
|
+
}));
|
|
234
|
+
}
|
|
235
|
+
await fetchThread(threadId);
|
|
236
|
+
}, [fetchThread, threadMap]);
|
|
237
|
+
const setLastThreadStatus = (status) => {
|
|
238
|
+
setThreadMap((prevMap) => {
|
|
239
|
+
if (!currentThreadId) {
|
|
240
|
+
return prevMap;
|
|
241
|
+
}
|
|
242
|
+
const headMessages = prevMap[currentThreadId].messages.slice(0, -1);
|
|
243
|
+
const lastMessage = prevMap[currentThreadId].messages[prevMap[currentThreadId].messages.length - 1];
|
|
244
|
+
const updatedLastMessage = {
|
|
245
|
+
...lastMessage,
|
|
246
|
+
status,
|
|
247
|
+
};
|
|
248
|
+
return {
|
|
249
|
+
...prevMap,
|
|
250
|
+
[currentThreadId]: {
|
|
251
|
+
...prevMap[currentThreadId],
|
|
252
|
+
messages: [...headMessages, updatedLastMessage],
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
});
|
|
256
|
+
};
|
|
257
|
+
const updateThreadStatus = (0, react_1.useCallback)((stage) => {
|
|
258
|
+
setThreadMap((prevMap) => {
|
|
259
|
+
return {
|
|
260
|
+
...prevMap,
|
|
261
|
+
[currentThreadId]: {
|
|
262
|
+
...prevMap[currentThreadId],
|
|
263
|
+
generationStage: stage,
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
});
|
|
267
|
+
}, [currentThreadId]);
|
|
268
|
+
const handleAdvanceStream = (0, react_1.useCallback)(async (stream, params) => {
|
|
269
|
+
let finalMessage;
|
|
270
|
+
let hasSetThreadId = false;
|
|
271
|
+
updateThreadStatus(generate_component_response_1.GenerationStage.STREAMING_RESPONSE);
|
|
272
|
+
for await (const chunk of stream) {
|
|
273
|
+
if (chunk.responseMessageDto.toolCallRequest) {
|
|
274
|
+
updateThreadStatus(generate_component_response_1.GenerationStage.FETCHING_CONTEXT);
|
|
275
|
+
const toolCallResponse = await (0, tool_caller_1.handleToolCall)(chunk.responseMessageDto, toolRegistry);
|
|
276
|
+
const toolCallResponseParams = {
|
|
277
|
+
...params,
|
|
278
|
+
messageToAppend: {
|
|
279
|
+
content: [{ type: "text", text: "tool response" }],
|
|
280
|
+
role: "tool",
|
|
281
|
+
actionType: "tool_response",
|
|
282
|
+
toolResponse: toolCallResponse,
|
|
283
|
+
component: chunk.responseMessageDto.component,
|
|
284
|
+
},
|
|
285
|
+
};
|
|
286
|
+
updateThreadStatus(generate_component_response_1.GenerationStage.STREAMING_RESPONSE);
|
|
287
|
+
const toolCallResponseStream = await (0, typescript_sdk_1.advanceStream)(client, toolCallResponseParams, chunk.responseMessageDto.threadId);
|
|
288
|
+
return handleAdvanceStream(toolCallResponseStream, toolCallResponseParams);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
if (!hasSetThreadId &&
|
|
292
|
+
chunk.responseMessageDto.threadId &&
|
|
293
|
+
chunk.responseMessageDto.threadId !== currentThread?.id) {
|
|
294
|
+
hasSetThreadId = true;
|
|
295
|
+
switchCurrentThread(chunk.responseMessageDto.threadId);
|
|
296
|
+
}
|
|
297
|
+
if (!finalMessage) {
|
|
298
|
+
finalMessage = chunk.responseMessageDto.component?.componentName
|
|
299
|
+
? (0, generate_component_1.renderComponentIntoMessage)(chunk.responseMessageDto, componentList)
|
|
300
|
+
: chunk.responseMessageDto;
|
|
301
|
+
addThreadMessage(finalMessage, false);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
const previousId = finalMessage.id;
|
|
305
|
+
finalMessage = chunk.responseMessageDto.component?.componentName
|
|
306
|
+
? (0, generate_component_1.renderComponentIntoMessage)(chunk.responseMessageDto, componentList)
|
|
307
|
+
: chunk.responseMessageDto;
|
|
308
|
+
updateThreadMessage(previousId, finalMessage, false);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
updateThreadStatus(generate_component_response_1.GenerationStage.COMPLETE);
|
|
313
|
+
return (finalMessage ?? {
|
|
314
|
+
threadId: "",
|
|
315
|
+
content: [{ type: "text", text: `Error processing stream` }],
|
|
316
|
+
role: "hydra",
|
|
317
|
+
createdAt: new Date().toISOString(),
|
|
318
|
+
id: crypto.randomUUID(),
|
|
319
|
+
});
|
|
320
|
+
}, [
|
|
321
|
+
toolRegistry,
|
|
322
|
+
client,
|
|
323
|
+
currentThread?.id,
|
|
324
|
+
switchCurrentThread,
|
|
325
|
+
componentList,
|
|
326
|
+
addThreadMessage,
|
|
327
|
+
updateThreadMessage,
|
|
328
|
+
]);
|
|
329
|
+
const sendThreadMessage = (0, react_1.useCallback)(async (message, options = {}) => {
|
|
330
|
+
const { threadId, streamResponse } = options;
|
|
331
|
+
const currentThreadId = threadId ?? currentThread?.id;
|
|
332
|
+
if (currentThreadId !== exports.PLACEHOLDER_THREAD.id) {
|
|
333
|
+
await switchCurrentThread(currentThreadId);
|
|
334
|
+
}
|
|
335
|
+
updateThreadStatus(generate_component_response_1.GenerationStage.CHOOSING_COMPONENT);
|
|
336
|
+
addThreadMessage({
|
|
337
|
+
content: [{ type: "text", text: message }],
|
|
338
|
+
renderedComponent: null,
|
|
339
|
+
role: "user",
|
|
340
|
+
threadId: currentThread.id,
|
|
341
|
+
id: crypto.randomUUID(),
|
|
342
|
+
createdAt: new Date().toISOString(),
|
|
343
|
+
}, false);
|
|
344
|
+
const availableComponents = (0, registry_1.getAvailableComponents)(componentList, toolRegistry, componentToolAssociations);
|
|
345
|
+
const params = {
|
|
346
|
+
messageToAppend: {
|
|
347
|
+
content: [{ type: "text", text: message }],
|
|
348
|
+
role: "user",
|
|
349
|
+
},
|
|
350
|
+
contextKey: options.contextKey,
|
|
351
|
+
availableComponents: availableComponents,
|
|
352
|
+
};
|
|
353
|
+
if (streamResponse) {
|
|
354
|
+
const advanceStreamResponse = await (0, typescript_sdk_1.advanceStream)(client, params, currentThreadId === exports.PLACEHOLDER_THREAD.id
|
|
355
|
+
? undefined
|
|
356
|
+
: currentThreadId);
|
|
357
|
+
return handleAdvanceStream(advanceStreamResponse, params);
|
|
358
|
+
}
|
|
359
|
+
let advanceResponse = await (currentThreadId === exports.PLACEHOLDER_THREAD.id
|
|
360
|
+
? client.beta.threads.advance(params)
|
|
361
|
+
: client.beta.threads.advanceById(currentThreadId, params));
|
|
362
|
+
//handle tool calls
|
|
363
|
+
while (advanceResponse.responseMessageDto.toolCallRequest) {
|
|
364
|
+
updateThreadStatus(generate_component_response_1.GenerationStage.FETCHING_CONTEXT);
|
|
365
|
+
const toolCallResponse = await (0, tool_caller_1.handleToolCall)(advanceResponse.responseMessageDto, toolRegistry);
|
|
366
|
+
const toolCallResponseParams = {
|
|
367
|
+
...params,
|
|
368
|
+
messageToAppend: {
|
|
369
|
+
...params.messageToAppend,
|
|
370
|
+
content: [{ type: "text", text: "tool response" }],
|
|
371
|
+
role: "tool",
|
|
372
|
+
actionType: "tool_response",
|
|
373
|
+
toolResponse: toolCallResponse,
|
|
374
|
+
component: advanceResponse.responseMessageDto.component,
|
|
375
|
+
},
|
|
376
|
+
};
|
|
377
|
+
updateThreadStatus(generate_component_response_1.GenerationStage.HYDRATING_COMPONENT);
|
|
378
|
+
advanceResponse = await client.beta.threads.advanceById(advanceResponse.responseMessageDto.threadId, toolCallResponseParams);
|
|
379
|
+
}
|
|
380
|
+
const finalMessage = advanceResponse.responseMessageDto.component
|
|
381
|
+
?.componentName
|
|
382
|
+
? (0, generate_component_1.renderComponentIntoMessage)(advanceResponse.responseMessageDto, componentList)
|
|
383
|
+
: advanceResponse.responseMessageDto;
|
|
384
|
+
await switchCurrentThread(advanceResponse.responseMessageDto.threadId);
|
|
385
|
+
updateThreadStatus(generate_component_response_1.GenerationStage.COMPLETE);
|
|
386
|
+
return finalMessage;
|
|
387
|
+
}, [
|
|
388
|
+
componentList,
|
|
389
|
+
toolRegistry,
|
|
390
|
+
componentToolAssociations,
|
|
391
|
+
currentThread,
|
|
392
|
+
switchCurrentThread,
|
|
393
|
+
addThreadMessage,
|
|
394
|
+
client,
|
|
395
|
+
handleAdvanceStream,
|
|
396
|
+
]);
|
|
397
|
+
return (react_1.default.createElement(exports.TamboThreadContext.Provider, { value: {
|
|
398
|
+
thread: currentThread,
|
|
399
|
+
switchCurrentThread,
|
|
400
|
+
addThreadMessage,
|
|
401
|
+
updateThreadMessage,
|
|
402
|
+
setLastThreadStatus,
|
|
403
|
+
inputValue,
|
|
404
|
+
setInputValue,
|
|
405
|
+
sendThreadMessage,
|
|
406
|
+
} }, children));
|
|
407
|
+
};
|
|
408
|
+
exports.TamboThreadProvider = TamboThreadProvider;
|
|
409
|
+
const useTamboThread = () => {
|
|
410
|
+
const context = (0, react_1.useContext)(exports.TamboThreadContext);
|
|
411
|
+
if (context === undefined) {
|
|
412
|
+
throw new Error("useTamboThread must be used within a TamboThreadProvider");
|
|
413
|
+
}
|
|
414
|
+
return context;
|
|
415
|
+
};
|
|
416
|
+
exports.useTamboThread = useTamboThread;
|
|
417
|
+
//# 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,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
require("@testing-library/jest-dom");
|
|
4
|
+
// Mock AbortController
|
|
5
|
+
const mockSignal = {
|
|
6
|
+
aborted: false,
|
|
7
|
+
reason: undefined,
|
|
8
|
+
onabort: null,
|
|
9
|
+
addEventListener: jest.fn(),
|
|
10
|
+
removeEventListener: jest.fn(),
|
|
11
|
+
dispatchEvent: jest.fn(),
|
|
12
|
+
throwIfAborted: jest.fn(),
|
|
13
|
+
any: jest.fn(),
|
|
14
|
+
};
|
|
15
|
+
const MockAbortController = class {
|
|
16
|
+
signal = mockSignal;
|
|
17
|
+
abort = jest.fn();
|
|
18
|
+
};
|
|
19
|
+
global.AbortController = MockAbortController;
|
|
20
|
+
//# sourceMappingURL=setupTests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupTests.js","sourceRoot":"","sources":["../src/setupTests.ts"],"names":[],"mappings":";;AAAA,qCAAmC;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;
|