@tambo-ai/react 0.37.2 → 0.38.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/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/model/tambo-interactable.d.ts +24 -0
- package/dist/model/tambo-interactable.d.ts.map +1 -0
- package/dist/model/tambo-interactable.js +3 -0
- package/dist/model/tambo-interactable.js.map +1 -0
- package/dist/providers/__tests__/tambo-prop-stream-provider.test.d.ts +2 -0
- package/dist/providers/__tests__/tambo-prop-stream-provider.test.d.ts.map +1 -0
- package/dist/providers/__tests__/tambo-prop-stream-provider.test.js +278 -0
- package/dist/providers/__tests__/tambo-prop-stream-provider.test.js.map +1 -0
- package/dist/providers/__tests__/tambo-thread-provider.test.js +7 -0
- package/dist/providers/__tests__/tambo-thread-provider.test.js.map +1 -1
- package/dist/providers/hoc/with-tambo-interactable.d.ts +34 -0
- package/dist/providers/hoc/with-tambo-interactable.d.ts.map +1 -0
- package/dist/providers/hoc/with-tambo-interactable.js +119 -0
- package/dist/providers/hoc/with-tambo-interactable.js.map +1 -0
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +3 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.d.ts +20 -0
- package/dist/providers/tambo-interactable-provider.d.ts.map +1 -0
- package/dist/providers/tambo-interactable-provider.js +243 -0
- package/dist/providers/tambo-interactable-provider.js.map +1 -0
- package/dist/providers/tambo-prop-stream-provider.d.ts +96 -0
- package/dist/providers/tambo-prop-stream-provider.d.ts.map +1 -0
- package/dist/providers/tambo-prop-stream-provider.js +185 -0
- package/dist/providers/tambo-prop-stream-provider.js.map +1 -0
- package/dist/providers/tambo-provider.d.ts +6 -4
- package/dist/providers/tambo-provider.d.ts.map +1 -1
- package/dist/providers/tambo-provider.js +9 -4
- package/dist/providers/tambo-provider.js.map +1 -1
- package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-provider.js +14 -0
- package/dist/providers/tambo-thread-provider.js.map +1 -1
- package/esm/index.d.ts +4 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -1
- package/esm/index.js.map +1 -1
- package/esm/model/tambo-interactable.d.ts +24 -0
- package/esm/model/tambo-interactable.d.ts.map +1 -0
- package/esm/model/tambo-interactable.js +2 -0
- package/esm/model/tambo-interactable.js.map +1 -0
- package/esm/providers/__tests__/tambo-prop-stream-provider.test.d.ts +2 -0
- package/esm/providers/__tests__/tambo-prop-stream-provider.test.d.ts.map +1 -0
- package/esm/providers/__tests__/tambo-prop-stream-provider.test.js +273 -0
- package/esm/providers/__tests__/tambo-prop-stream-provider.test.js.map +1 -0
- package/esm/providers/__tests__/tambo-thread-provider.test.js +7 -0
- package/esm/providers/__tests__/tambo-thread-provider.test.js.map +1 -1
- package/esm/providers/hoc/with-tambo-interactable.d.ts +34 -0
- package/esm/providers/hoc/with-tambo-interactable.d.ts.map +1 -0
- package/esm/providers/hoc/with-tambo-interactable.js +83 -0
- package/esm/providers/hoc/with-tambo-interactable.js.map +1 -0
- package/esm/providers/index.d.ts +1 -0
- package/esm/providers/index.d.ts.map +1 -1
- package/esm/providers/index.js +1 -0
- package/esm/providers/index.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +20 -0
- package/esm/providers/tambo-interactable-provider.d.ts.map +1 -0
- package/esm/providers/tambo-interactable-provider.js +205 -0
- package/esm/providers/tambo-interactable-provider.js.map +1 -0
- package/esm/providers/tambo-prop-stream-provider.d.ts +96 -0
- package/esm/providers/tambo-prop-stream-provider.d.ts.map +1 -0
- package/esm/providers/tambo-prop-stream-provider.js +148 -0
- package/esm/providers/tambo-prop-stream-provider.js.map +1 -0
- package/esm/providers/tambo-provider.d.ts +6 -4
- package/esm/providers/tambo-provider.d.ts.map +1 -1
- package/esm/providers/tambo-provider.js +9 -4
- package/esm/providers/tambo-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-provider.js +14 -0
- package/esm/providers/tambo-thread-provider.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { render, screen } from "@testing-library/react";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { TamboPropStreamProvider, useTamboStream, } from "../tambo-prop-stream-provider";
|
|
4
|
+
// Helper component to test hook usage
|
|
5
|
+
const TestHookComponent = ({ testKey = "default", }) => {
|
|
6
|
+
const { data, streamStatus, getStatusForKey } = useTamboStream();
|
|
7
|
+
const status = getStatusForKey(testKey);
|
|
8
|
+
return (React.createElement("div", null,
|
|
9
|
+
React.createElement("div", { "data-testid": "data" }, JSON.stringify(data)),
|
|
10
|
+
React.createElement("div", { "data-testid": "stream-status" }, JSON.stringify(streamStatus)),
|
|
11
|
+
React.createElement("div", { "data-testid": "key-status" }, JSON.stringify(status))));
|
|
12
|
+
};
|
|
13
|
+
describe("TamboPropStreamProvider", () => {
|
|
14
|
+
describe("Hook Error Handling", () => {
|
|
15
|
+
it("should throw error when useTamboStream is used outside provider", () => {
|
|
16
|
+
// Suppress console.error for this test
|
|
17
|
+
const originalError = console.error;
|
|
18
|
+
console.error = jest.fn();
|
|
19
|
+
expect(() => {
|
|
20
|
+
render(React.createElement(TestHookComponent, null));
|
|
21
|
+
}).toThrow("useTamboStream must be used within a TamboPropStreamProvider");
|
|
22
|
+
console.error = originalError;
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe("Basic Functionality", () => {
|
|
26
|
+
it("should provide data and stream status through context", () => {
|
|
27
|
+
const testData = { message: "Hello World" };
|
|
28
|
+
const testStreamStatus = {
|
|
29
|
+
isPending: false,
|
|
30
|
+
isStreaming: false,
|
|
31
|
+
isSuccess: true,
|
|
32
|
+
isError: false,
|
|
33
|
+
streamError: undefined,
|
|
34
|
+
};
|
|
35
|
+
render(React.createElement(TamboPropStreamProvider, { data: testData, streamStatus: testStreamStatus },
|
|
36
|
+
React.createElement(TestHookComponent, null)));
|
|
37
|
+
expect(screen.getByTestId("data")).toHaveTextContent(JSON.stringify(testData));
|
|
38
|
+
expect(screen.getByTestId("stream-status")).toHaveTextContent(JSON.stringify(testStreamStatus));
|
|
39
|
+
});
|
|
40
|
+
it("should use default stream status when none provided", () => {
|
|
41
|
+
const testData = { message: "Hello World" };
|
|
42
|
+
const expectedDefaultStatus = {
|
|
43
|
+
isPending: false,
|
|
44
|
+
isStreaming: false,
|
|
45
|
+
isSuccess: true,
|
|
46
|
+
isError: false,
|
|
47
|
+
streamError: undefined,
|
|
48
|
+
};
|
|
49
|
+
render(React.createElement(TamboPropStreamProvider, { data: testData },
|
|
50
|
+
React.createElement(TestHookComponent, null)));
|
|
51
|
+
expect(screen.getByTestId("stream-status")).toHaveTextContent(JSON.stringify(expectedDefaultStatus));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe("Compound Components", () => {
|
|
55
|
+
describe("Loading Component", () => {
|
|
56
|
+
it("should render loading when isPending is true", () => {
|
|
57
|
+
const streamStatus = {
|
|
58
|
+
isPending: true,
|
|
59
|
+
isStreaming: false,
|
|
60
|
+
isSuccess: false,
|
|
61
|
+
isError: false,
|
|
62
|
+
};
|
|
63
|
+
render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
64
|
+
React.createElement(TamboPropStreamProvider.Loading, null,
|
|
65
|
+
React.createElement("div", { "data-testid": "loading" }, "Loading..."))));
|
|
66
|
+
expect(screen.getByTestId("loading")).toBeInTheDocument();
|
|
67
|
+
});
|
|
68
|
+
it("should render loading when isStreaming is true", () => {
|
|
69
|
+
const streamStatus = {
|
|
70
|
+
isPending: false,
|
|
71
|
+
isStreaming: true,
|
|
72
|
+
isSuccess: false,
|
|
73
|
+
isError: false,
|
|
74
|
+
};
|
|
75
|
+
render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
76
|
+
React.createElement(TamboPropStreamProvider.Loading, null,
|
|
77
|
+
React.createElement("div", { "data-testid": "loading" }, "Loading..."))));
|
|
78
|
+
expect(screen.getByTestId("loading")).toBeInTheDocument();
|
|
79
|
+
});
|
|
80
|
+
it("should not render loading when not pending or streaming", () => {
|
|
81
|
+
const streamStatus = {
|
|
82
|
+
isPending: false,
|
|
83
|
+
isStreaming: false,
|
|
84
|
+
isSuccess: true,
|
|
85
|
+
isError: false,
|
|
86
|
+
};
|
|
87
|
+
render(React.createElement(TamboPropStreamProvider, { data: "test", streamStatus: streamStatus },
|
|
88
|
+
React.createElement(TamboPropStreamProvider.Loading, null,
|
|
89
|
+
React.createElement("div", { "data-testid": "loading" }, "Loading..."))));
|
|
90
|
+
expect(screen.queryByTestId("loading")).not.toBeInTheDocument();
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe("Complete Component", () => {
|
|
94
|
+
it("should render complete when isSuccess is true and data exists", () => {
|
|
95
|
+
const streamStatus = {
|
|
96
|
+
isPending: false,
|
|
97
|
+
isStreaming: false,
|
|
98
|
+
isSuccess: true,
|
|
99
|
+
isError: false,
|
|
100
|
+
};
|
|
101
|
+
render(React.createElement(TamboPropStreamProvider, { data: "test data", streamStatus: streamStatus },
|
|
102
|
+
React.createElement(TamboPropStreamProvider.Complete, null,
|
|
103
|
+
React.createElement("div", { "data-testid": "complete" }, "Complete!"))));
|
|
104
|
+
expect(screen.getByTestId("complete")).toBeInTheDocument();
|
|
105
|
+
});
|
|
106
|
+
it("should not render complete when data is null", () => {
|
|
107
|
+
const streamStatus = {
|
|
108
|
+
isPending: false,
|
|
109
|
+
isStreaming: false,
|
|
110
|
+
isSuccess: true,
|
|
111
|
+
isError: false,
|
|
112
|
+
};
|
|
113
|
+
render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
114
|
+
React.createElement(TamboPropStreamProvider.Complete, null,
|
|
115
|
+
React.createElement("div", { "data-testid": "complete" }, "Complete!"))));
|
|
116
|
+
expect(screen.queryByTestId("complete")).not.toBeInTheDocument();
|
|
117
|
+
});
|
|
118
|
+
it("should not render complete when data is undefined", () => {
|
|
119
|
+
const streamStatus = {
|
|
120
|
+
isPending: false,
|
|
121
|
+
isStreaming: false,
|
|
122
|
+
isSuccess: true,
|
|
123
|
+
isError: false,
|
|
124
|
+
};
|
|
125
|
+
render(React.createElement(TamboPropStreamProvider, { data: undefined, streamStatus: streamStatus },
|
|
126
|
+
React.createElement(TamboPropStreamProvider.Complete, null,
|
|
127
|
+
React.createElement("div", { "data-testid": "complete" }, "Complete!"))));
|
|
128
|
+
expect(screen.queryByTestId("complete")).not.toBeInTheDocument();
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe("Empty Component", () => {
|
|
132
|
+
it("should render empty when no data and not loading/streaming/success/error", () => {
|
|
133
|
+
const streamStatus = {
|
|
134
|
+
isPending: false,
|
|
135
|
+
isStreaming: false,
|
|
136
|
+
isSuccess: false,
|
|
137
|
+
isError: false,
|
|
138
|
+
};
|
|
139
|
+
render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
140
|
+
React.createElement(TamboPropStreamProvider.Empty, null,
|
|
141
|
+
React.createElement("div", { "data-testid": "empty" }, "No data"))));
|
|
142
|
+
expect(screen.getByTestId("empty")).toBeInTheDocument();
|
|
143
|
+
});
|
|
144
|
+
it("should render empty when data is empty string", () => {
|
|
145
|
+
const streamStatus = {
|
|
146
|
+
isPending: false,
|
|
147
|
+
isStreaming: false,
|
|
148
|
+
isSuccess: false,
|
|
149
|
+
isError: false,
|
|
150
|
+
};
|
|
151
|
+
render(React.createElement(TamboPropStreamProvider, { data: "", streamStatus: streamStatus },
|
|
152
|
+
React.createElement(TamboPropStreamProvider.Empty, null,
|
|
153
|
+
React.createElement("div", { "data-testid": "empty" }, "No data"))));
|
|
154
|
+
expect(screen.getByTestId("empty")).toBeInTheDocument();
|
|
155
|
+
});
|
|
156
|
+
it("should not render empty when loading", () => {
|
|
157
|
+
const streamStatus = {
|
|
158
|
+
isPending: true,
|
|
159
|
+
isStreaming: false,
|
|
160
|
+
isSuccess: false,
|
|
161
|
+
isError: false,
|
|
162
|
+
};
|
|
163
|
+
render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
164
|
+
React.createElement(TamboPropStreamProvider.Empty, null,
|
|
165
|
+
React.createElement("div", { "data-testid": "empty" }, "No data"))));
|
|
166
|
+
expect(screen.queryByTestId("empty")).not.toBeInTheDocument();
|
|
167
|
+
});
|
|
168
|
+
it("should not render empty when successful", () => {
|
|
169
|
+
const streamStatus = {
|
|
170
|
+
isPending: false,
|
|
171
|
+
isStreaming: false,
|
|
172
|
+
isSuccess: true,
|
|
173
|
+
isError: false,
|
|
174
|
+
};
|
|
175
|
+
render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
176
|
+
React.createElement(TamboPropStreamProvider.Empty, null,
|
|
177
|
+
React.createElement("div", { "data-testid": "empty" }, "No data"))));
|
|
178
|
+
expect(screen.queryByTestId("empty")).not.toBeInTheDocument();
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
describe("Per-Key Status Tracking", () => {
|
|
183
|
+
it("should track status for object keys", () => {
|
|
184
|
+
const testData = { name: "John", age: null };
|
|
185
|
+
const streamStatus = {
|
|
186
|
+
isPending: false,
|
|
187
|
+
isStreaming: false,
|
|
188
|
+
isSuccess: true,
|
|
189
|
+
isError: false,
|
|
190
|
+
};
|
|
191
|
+
render(React.createElement(TamboPropStreamProvider, { data: testData, streamStatus: streamStatus },
|
|
192
|
+
React.createElement(TestHookComponent, { testKey: "name" })));
|
|
193
|
+
const keyStatus = JSON.parse(screen.getByTestId("key-status").textContent ?? "{}");
|
|
194
|
+
expect(keyStatus.isSuccess).toBe(true); // name has data
|
|
195
|
+
});
|
|
196
|
+
it("should show loading for keys without data", () => {
|
|
197
|
+
const testData = { name: "John", age: null };
|
|
198
|
+
const streamStatus = {
|
|
199
|
+
isPending: false,
|
|
200
|
+
isStreaming: false,
|
|
201
|
+
isSuccess: true,
|
|
202
|
+
isError: false,
|
|
203
|
+
};
|
|
204
|
+
render(React.createElement(TamboPropStreamProvider, { data: testData, streamStatus: streamStatus },
|
|
205
|
+
React.createElement(TestHookComponent, { testKey: "age" })));
|
|
206
|
+
const keyStatus = JSON.parse(screen.getByTestId("key-status").textContent ?? "{}");
|
|
207
|
+
expect(keyStatus.isPending).toBe(true); // age has no data
|
|
208
|
+
});
|
|
209
|
+
it("should handle per-key loading states", () => {
|
|
210
|
+
render(React.createElement(TamboPropStreamProvider, { data: { name: "John", age: null } },
|
|
211
|
+
React.createElement(TamboPropStreamProvider.Loading, { streamKey: "name" },
|
|
212
|
+
React.createElement("div", { "data-testid": "name-loading" }, "Name loading...")),
|
|
213
|
+
React.createElement(TamboPropStreamProvider.Loading, { streamKey: "age" },
|
|
214
|
+
React.createElement("div", { "data-testid": "age-loading" }, "Age loading...")),
|
|
215
|
+
React.createElement(TamboPropStreamProvider.Complete, { streamKey: "name" },
|
|
216
|
+
React.createElement("div", { "data-testid": "name-complete" }, "Name: John"))));
|
|
217
|
+
// Name should be complete (has data)
|
|
218
|
+
expect(screen.getByTestId("name-complete")).toBeInTheDocument();
|
|
219
|
+
expect(screen.queryByTestId("name-loading")).not.toBeInTheDocument();
|
|
220
|
+
// Age should be loading (no data)
|
|
221
|
+
expect(screen.getByTestId("age-loading")).toBeInTheDocument();
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
describe("Edge Cases", () => {
|
|
225
|
+
it("should handle null data gracefully", () => {
|
|
226
|
+
render(React.createElement(TamboPropStreamProvider, { data: null },
|
|
227
|
+
React.createElement(TestHookComponent, null)));
|
|
228
|
+
expect(screen.getByTestId("data")).toHaveTextContent("null");
|
|
229
|
+
});
|
|
230
|
+
it("should handle undefined data gracefully", () => {
|
|
231
|
+
render(React.createElement(TamboPropStreamProvider, { data: undefined },
|
|
232
|
+
React.createElement(TestHookComponent, null)));
|
|
233
|
+
expect(screen.getByTestId("data")).toHaveTextContent("");
|
|
234
|
+
});
|
|
235
|
+
it("should handle array data", () => {
|
|
236
|
+
const arrayData = ["item1", "item2"];
|
|
237
|
+
render(React.createElement(TamboPropStreamProvider, { data: arrayData },
|
|
238
|
+
React.createElement(TestHookComponent, null)));
|
|
239
|
+
expect(screen.getByTestId("data")).toHaveTextContent(JSON.stringify(arrayData));
|
|
240
|
+
});
|
|
241
|
+
it("should handle primitive data types", () => {
|
|
242
|
+
render(React.createElement(TamboPropStreamProvider, { data: "string data" },
|
|
243
|
+
React.createElement(TestHookComponent, null)));
|
|
244
|
+
expect(screen.getByTestId("data")).toHaveTextContent('"string data"');
|
|
245
|
+
});
|
|
246
|
+
it("should fallback to default status for unknown keys", () => {
|
|
247
|
+
const testData = { name: "John" };
|
|
248
|
+
render(React.createElement(TamboPropStreamProvider, { data: testData },
|
|
249
|
+
React.createElement(TestHookComponent, { testKey: "unknown-key" })));
|
|
250
|
+
const keyStatus = JSON.parse(screen.getByTestId("key-status").textContent ?? "{}");
|
|
251
|
+
// Should fallback to default status
|
|
252
|
+
expect(keyStatus.isSuccess).toBe(true);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
describe("Component Attributes", () => {
|
|
256
|
+
it("should add correct data attributes to components", () => {
|
|
257
|
+
const streamStatus = {
|
|
258
|
+
isPending: true,
|
|
259
|
+
isStreaming: false,
|
|
260
|
+
isSuccess: false,
|
|
261
|
+
isError: false,
|
|
262
|
+
};
|
|
263
|
+
render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
264
|
+
React.createElement(TamboPropStreamProvider.Loading, { className: "loading-class" },
|
|
265
|
+
React.createElement("div", null, "Loading..."))));
|
|
266
|
+
const loadingElement = screen.getByText("Loading...").parentElement;
|
|
267
|
+
expect(loadingElement).toHaveAttribute("data-stream-key", "default");
|
|
268
|
+
expect(loadingElement).toHaveAttribute("data-stream-state", "loading");
|
|
269
|
+
expect(loadingElement).toHaveClass("loading-class");
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
//# sourceMappingURL=tambo-prop-stream-provider.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tambo-prop-stream-provider.test.js","sourceRoot":"","sources":["../../../src/providers/__tests__/tambo-prop-stream-provider.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { render, screen } from \"@testing-library/react\";\nimport React from \"react\";\nimport { StreamStatus } from \"../../hooks/use-tambo-stream-status\";\nimport {\n TamboPropStreamProvider,\n useTamboStream,\n} from \"../tambo-prop-stream-provider\";\n\n// Helper component to test hook usage\nconst TestHookComponent: React.FC<{ testKey?: string }> = ({\n testKey = \"default\",\n}) => {\n const { data, streamStatus, getStatusForKey } = useTamboStream();\n const status = getStatusForKey(testKey);\n\n return (\n <div>\n <div data-testid=\"data\">{JSON.stringify(data)}</div>\n <div data-testid=\"stream-status\">{JSON.stringify(streamStatus)}</div>\n <div data-testid=\"key-status\">{JSON.stringify(status)}</div>\n </div>\n );\n};\n\ndescribe(\"TamboPropStreamProvider\", () => {\n describe(\"Hook Error Handling\", () => {\n it(\"should throw error when useTamboStream is used outside provider\", () => {\n // Suppress console.error for this test\n const originalError = console.error;\n console.error = jest.fn();\n\n expect(() => {\n render(<TestHookComponent />);\n }).toThrow(\n \"useTamboStream must be used within a TamboPropStreamProvider\",\n );\n\n console.error = originalError;\n });\n });\n\n describe(\"Basic Functionality\", () => {\n it(\"should provide data and stream status through context\", () => {\n const testData = { message: \"Hello World\" };\n const testStreamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n streamError: undefined,\n };\n\n render(\n <TamboPropStreamProvider\n data={testData}\n streamStatus={testStreamStatus}\n >\n <TestHookComponent />\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"data\")).toHaveTextContent(\n JSON.stringify(testData),\n );\n expect(screen.getByTestId(\"stream-status\")).toHaveTextContent(\n JSON.stringify(testStreamStatus),\n );\n });\n\n it(\"should use default stream status when none provided\", () => {\n const testData = { message: \"Hello World\" };\n const expectedDefaultStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n streamError: undefined,\n };\n\n render(\n <TamboPropStreamProvider data={testData}>\n <TestHookComponent />\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"stream-status\")).toHaveTextContent(\n JSON.stringify(expectedDefaultStatus),\n );\n });\n });\n\n describe(\"Compound Components\", () => {\n describe(\"Loading Component\", () => {\n it(\"should render loading when isPending is true\", () => {\n const streamStatus: StreamStatus = {\n isPending: true,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Loading>\n <div data-testid=\"loading\">Loading...</div>\n </TamboPropStreamProvider.Loading>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"loading\")).toBeInTheDocument();\n });\n\n it(\"should render loading when isStreaming is true\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: true,\n isSuccess: false,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Loading>\n <div data-testid=\"loading\">Loading...</div>\n </TamboPropStreamProvider.Loading>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"loading\")).toBeInTheDocument();\n });\n\n it(\"should not render loading when not pending or streaming\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data=\"test\" streamStatus={streamStatus}>\n <TamboPropStreamProvider.Loading>\n <div data-testid=\"loading\">Loading...</div>\n </TamboPropStreamProvider.Loading>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.queryByTestId(\"loading\")).not.toBeInTheDocument();\n });\n });\n\n describe(\"Complete Component\", () => {\n it(\"should render complete when isSuccess is true and data exists\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data=\"test data\" streamStatus={streamStatus}>\n <TamboPropStreamProvider.Complete>\n <div data-testid=\"complete\">Complete!</div>\n </TamboPropStreamProvider.Complete>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"complete\")).toBeInTheDocument();\n });\n\n it(\"should not render complete when data is null\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Complete>\n <div data-testid=\"complete\">Complete!</div>\n </TamboPropStreamProvider.Complete>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.queryByTestId(\"complete\")).not.toBeInTheDocument();\n });\n\n it(\"should not render complete when data is undefined\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={undefined} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Complete>\n <div data-testid=\"complete\">Complete!</div>\n </TamboPropStreamProvider.Complete>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.queryByTestId(\"complete\")).not.toBeInTheDocument();\n });\n });\n\n describe(\"Empty Component\", () => {\n it(\"should render empty when no data and not loading/streaming/success/error\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Empty>\n <div data-testid=\"empty\">No data</div>\n </TamboPropStreamProvider.Empty>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"empty\")).toBeInTheDocument();\n });\n\n it(\"should render empty when data is empty string\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data=\"\" streamStatus={streamStatus}>\n <TamboPropStreamProvider.Empty>\n <div data-testid=\"empty\">No data</div>\n </TamboPropStreamProvider.Empty>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"empty\")).toBeInTheDocument();\n });\n\n it(\"should not render empty when loading\", () => {\n const streamStatus: StreamStatus = {\n isPending: true,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Empty>\n <div data-testid=\"empty\">No data</div>\n </TamboPropStreamProvider.Empty>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.queryByTestId(\"empty\")).not.toBeInTheDocument();\n });\n\n it(\"should not render empty when successful\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Empty>\n <div data-testid=\"empty\">No data</div>\n </TamboPropStreamProvider.Empty>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.queryByTestId(\"empty\")).not.toBeInTheDocument();\n });\n });\n });\n\n describe(\"Per-Key Status Tracking\", () => {\n it(\"should track status for object keys\", () => {\n const testData = { name: \"John\", age: null };\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={testData} streamStatus={streamStatus}>\n <TestHookComponent testKey=\"name\" />\n </TamboPropStreamProvider>,\n );\n\n const keyStatus = JSON.parse(\n screen.getByTestId(\"key-status\").textContent ?? \"{}\",\n );\n expect(keyStatus.isSuccess).toBe(true); // name has data\n });\n\n it(\"should show loading for keys without data\", () => {\n const testData = { name: \"John\", age: null };\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={testData} streamStatus={streamStatus}>\n <TestHookComponent testKey=\"age\" />\n </TamboPropStreamProvider>,\n );\n\n const keyStatus = JSON.parse(\n screen.getByTestId(\"key-status\").textContent ?? \"{}\",\n );\n expect(keyStatus.isPending).toBe(true); // age has no data\n });\n\n it(\"should handle per-key loading states\", () => {\n render(\n <TamboPropStreamProvider data={{ name: \"John\", age: null }}>\n <TamboPropStreamProvider.Loading streamKey=\"name\">\n <div data-testid=\"name-loading\">Name loading...</div>\n </TamboPropStreamProvider.Loading>\n <TamboPropStreamProvider.Loading streamKey=\"age\">\n <div data-testid=\"age-loading\">Age loading...</div>\n </TamboPropStreamProvider.Loading>\n <TamboPropStreamProvider.Complete streamKey=\"name\">\n <div data-testid=\"name-complete\">Name: John</div>\n </TamboPropStreamProvider.Complete>\n </TamboPropStreamProvider>,\n );\n\n // Name should be complete (has data)\n expect(screen.getByTestId(\"name-complete\")).toBeInTheDocument();\n expect(screen.queryByTestId(\"name-loading\")).not.toBeInTheDocument();\n\n // Age should be loading (no data)\n expect(screen.getByTestId(\"age-loading\")).toBeInTheDocument();\n });\n });\n\n describe(\"Edge Cases\", () => {\n it(\"should handle null data gracefully\", () => {\n render(\n <TamboPropStreamProvider data={null}>\n <TestHookComponent />\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"data\")).toHaveTextContent(\"null\");\n });\n\n it(\"should handle undefined data gracefully\", () => {\n render(\n <TamboPropStreamProvider data={undefined}>\n <TestHookComponent />\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"data\")).toHaveTextContent(\"\");\n });\n\n it(\"should handle array data\", () => {\n const arrayData = [\"item1\", \"item2\"];\n render(\n <TamboPropStreamProvider data={arrayData}>\n <TestHookComponent />\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"data\")).toHaveTextContent(\n JSON.stringify(arrayData),\n );\n });\n\n it(\"should handle primitive data types\", () => {\n render(\n <TamboPropStreamProvider data=\"string data\">\n <TestHookComponent />\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"data\")).toHaveTextContent('\"string data\"');\n });\n\n it(\"should fallback to default status for unknown keys\", () => {\n const testData = { name: \"John\" };\n\n render(\n <TamboPropStreamProvider data={testData}>\n <TestHookComponent testKey=\"unknown-key\" />\n </TamboPropStreamProvider>,\n );\n\n const keyStatus = JSON.parse(\n screen.getByTestId(\"key-status\").textContent ?? \"{}\",\n );\n // Should fallback to default status\n expect(keyStatus.isSuccess).toBe(true);\n });\n });\n\n describe(\"Component Attributes\", () => {\n it(\"should add correct data attributes to components\", () => {\n const streamStatus: StreamStatus = {\n isPending: true,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Loading className=\"loading-class\">\n <div>Loading...</div>\n </TamboPropStreamProvider.Loading>\n </TamboPropStreamProvider>,\n );\n\n const loadingElement = screen.getByText(\"Loading...\").parentElement;\n expect(loadingElement).toHaveAttribute(\"data-stream-key\", \"default\");\n expect(loadingElement).toHaveAttribute(\"data-stream-state\", \"loading\");\n expect(loadingElement).toHaveClass(\"loading-class\");\n });\n });\n});\n"]}
|
|
@@ -199,6 +199,7 @@ describe("TamboThreadProvider", () => {
|
|
|
199
199
|
availableComponents: serializeRegistry(mockRegistry),
|
|
200
200
|
contextKey: undefined,
|
|
201
201
|
clientTools: [],
|
|
202
|
+
toolCallCounts: {},
|
|
202
203
|
});
|
|
203
204
|
expect(result.current.generationStage).toBe(GenerationStage.COMPLETE);
|
|
204
205
|
});
|
|
@@ -324,6 +325,7 @@ describe("TamboThreadProvider", () => {
|
|
|
324
325
|
contextKey: undefined,
|
|
325
326
|
clientTools: [],
|
|
326
327
|
forceToolChoice: undefined,
|
|
328
|
+
toolCallCounts: {},
|
|
327
329
|
}, "test-thread-1");
|
|
328
330
|
// Should not call advance or advanceById
|
|
329
331
|
expect(mockThreadsApi.advance).not.toHaveBeenCalled();
|
|
@@ -351,6 +353,7 @@ describe("TamboThreadProvider", () => {
|
|
|
351
353
|
contextKey: undefined,
|
|
352
354
|
clientTools: [],
|
|
353
355
|
forceToolChoice: undefined,
|
|
356
|
+
toolCallCounts: {},
|
|
354
357
|
});
|
|
355
358
|
// Should not call advance or advanceStream
|
|
356
359
|
expect(mockThreadsApi.advance).not.toHaveBeenCalled();
|
|
@@ -378,6 +381,7 @@ describe("TamboThreadProvider", () => {
|
|
|
378
381
|
contextKey: undefined,
|
|
379
382
|
clientTools: [],
|
|
380
383
|
forceToolChoice: undefined,
|
|
384
|
+
toolCallCounts: {},
|
|
381
385
|
});
|
|
382
386
|
// Should not call advance or advanceStream
|
|
383
387
|
expect(mockThreadsApi.advance).not.toHaveBeenCalled();
|
|
@@ -424,6 +428,7 @@ describe("TamboThreadProvider", () => {
|
|
|
424
428
|
contextKey: undefined,
|
|
425
429
|
clientTools: [],
|
|
426
430
|
forceToolChoice: undefined,
|
|
431
|
+
toolCallCounts: {},
|
|
427
432
|
}, "test-thread-1");
|
|
428
433
|
// Should not call advance or advanceById
|
|
429
434
|
expect(mockThreadsApi.advance).not.toHaveBeenCalled();
|
|
@@ -453,6 +458,7 @@ describe("TamboThreadProvider", () => {
|
|
|
453
458
|
contextKey: undefined,
|
|
454
459
|
clientTools: [],
|
|
455
460
|
forceToolChoice: undefined,
|
|
461
|
+
toolCallCounts: {},
|
|
456
462
|
});
|
|
457
463
|
// Should not call advanceById or advanceStream
|
|
458
464
|
expect(mockThreadsApi.advanceById).not.toHaveBeenCalled();
|
|
@@ -501,6 +507,7 @@ describe("TamboThreadProvider", () => {
|
|
|
501
507
|
contextKey: undefined,
|
|
502
508
|
clientTools: [],
|
|
503
509
|
forceToolChoice: undefined,
|
|
510
|
+
toolCallCounts: {},
|
|
504
511
|
}, undefined);
|
|
505
512
|
// Should not call advance or advanceById
|
|
506
513
|
expect(mockThreadsApi.advance).not.toHaveBeenCalled();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-thread-provider.test.js","sourceRoot":"","sources":["../../../src/providers/__tests__/tambo-thread-provider.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI, { advanceStream } from \"@tambo-ai/typescript-sdk\";\nimport { act, renderHook } from \"@testing-library/react\";\nimport React from \"react\";\nimport { DeepPartial } from \"ts-essentials\";\nimport { z } from \"zod\";\nimport { TamboComponent } from \"../../model/component-metadata\";\nimport {\n GenerationStage,\n TamboThreadMessage,\n} from \"../../model/generate-component-response\";\nimport { serializeRegistry } from \"../../testing/tools\";\nimport { useTamboClient } from \"../tambo-client-provider\";\nimport { TamboRegistryProvider } from \"../tambo-registry-provider\";\nimport { TamboThreadProvider, useTamboThread } from \"../tambo-thread-provider\";\n\ntype PartialTamboAI = DeepPartial<TamboAI>;\n\n// Mock crypto.randomUUID\nObject.defineProperty(global, \"crypto\", {\n value: {\n randomUUID: jest.fn().mockReturnValue(\"test-uuid\"),\n },\n});\n\n// Mock the required providers\njest.mock(\"../tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n}));\njest.mock(\"@tambo-ai/typescript-sdk\", () => ({\n advanceStream: jest.fn(),\n}));\n\n// Test utilities\nconst createMockMessage = (\n overrides: Partial<TamboThreadMessage> = {},\n): TamboThreadMessage => ({\n id: \"test-message-1\",\n content: [{ type: \"text\", text: \"Hello\" }],\n role: \"user\",\n threadId: \"test-thread-1\",\n createdAt: new Date().toISOString(),\n componentState: {},\n ...overrides,\n});\n\nconst createMockThread = (\n overrides: Partial<TamboAI.Beta.Threads.Thread> = {},\n) => ({\n id: \"test-thread-1\",\n messages: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n projectId: \"test-project\",\n updatedAt: \"2024-01-01T00:00:00Z\",\n metadata: {},\n ...overrides,\n});\n\nconst createMockAdvanceResponse = (\n overrides: Partial<TamboAI.Beta.Threads.ThreadAdvanceResponse> = {},\n): TamboAI.Beta.Threads.ThreadAdvanceResponse => ({\n responseMessageDto: {\n id: \"test-uuid\",\n content: [{ type: \"text\" as const, text: \"Default response\" }],\n role: \"assistant\",\n threadId: \"test-thread-1\",\n component: undefined,\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n ...overrides,\n});\n\ndescribe(\"TamboThreadProvider\", () => {\n const mockThread = createMockThread();\n\n const mockThreadsApi = {\n messages: {\n create: jest.fn(),\n },\n retrieve: jest.fn(),\n advance: jest.fn(),\n advanceById: jest.fn(),\n } satisfies DeepPartial<\n TamboAI[\"beta\"][\"threads\"]\n > as unknown as TamboAI.Beta.Threads;\n\n const mockBeta = {\n threads: mockThreadsApi,\n } satisfies PartialTamboAI[\"beta\"];\n\n const mockTamboAI = {\n apiKey: \"\",\n beta: mockBeta,\n } satisfies PartialTamboAI as unknown as TamboAI;\n\n const mockRegistry: TamboComponent[] = [\n {\n name: \"TestOnly\",\n component: () => <div>TestOnly</div>,\n description: \"TestOnly\",\n propsSchema: z.object({\n test: z.string(),\n }),\n associatedTools: [\n {\n name: \"test-tool\",\n tool: jest.fn().mockResolvedValue(\"test-tool\"),\n description: \"test-tool\",\n toolSchema: z\n .function()\n .args(z.string().describe(\"test-param-description\"))\n .returns(z.string()),\n },\n ],\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider streaming={false}>{children}</TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n beforeEach(() => {\n jest.clearAllMocks();\n jest.mocked(mockThreadsApi.retrieve).mockResolvedValue(mockThread);\n jest\n .mocked(mockThreadsApi.messages.create)\n .mockResolvedValue(createMockMessage());\n jest\n .mocked(mockThreadsApi.advance)\n .mockResolvedValue(createMockAdvanceResponse());\n jest\n .mocked(mockThreadsApi.advanceById)\n .mockResolvedValue(createMockAdvanceResponse());\n jest.mocked(useTamboClient).mockReturnValue(mockTamboAI);\n });\n\n it(\"should initialize with placeholder thread\", () => {\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n expect(result.current.thread.id).toBe(\"placeholder\");\n expect(result.current.isIdle).toBe(true);\n expect(result.current.generationStage).toBe(GenerationStage.IDLE);\n });\n\n it(\"should switch to a new thread\", async () => {\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n await act(async () => {\n await result.current.switchCurrentThread(\"test-thread-1\");\n });\n\n expect(mockThreadsApi.retrieve).toHaveBeenCalledWith(\"test-thread-1\", {\n includeInternal: true,\n });\n expect(result.current.thread.id).toBe(\"test-thread-1\");\n });\n\n it(\"should start a new thread\", async () => {\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n await act(async () => {\n result.current.startNewThread();\n });\n\n expect(result.current.thread.id).toBe(\"placeholder\");\n expect(result.current.isIdle).toBe(true);\n });\n\n it(\"should add a message to the thread\", async () => {\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n const testMessage: TamboThreadMessage = {\n id: \"test-message-1\",\n content: [{ type: \"text\", text: \"Hello\" }],\n role: \"user\",\n threadId: \"test-thread-1\",\n createdAt: new Date().toISOString(),\n componentState: {},\n };\n\n await act(async () => {\n await result.current.addThreadMessage(testMessage, true);\n });\n\n expect(mockThreadsApi.messages.create).toHaveBeenCalledWith(\n \"test-thread-1\",\n {\n content: testMessage.content,\n role: testMessage.role,\n },\n );\n });\n\n it(\"should update a message in the thread\", async () => {\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n const testMessage: TamboThreadMessage = {\n id: \"test-message-1\",\n content: [{ type: \"text\", text: \"Updated message\" }],\n role: \"user\",\n threadId: \"test-thread-1\",\n createdAt: new Date().toISOString(),\n componentState: {},\n };\n\n await act(async () => {\n await result.current.updateThreadMessage(\n \"test-message-1\",\n testMessage,\n true,\n );\n });\n\n expect(mockThreadsApi.messages.create).toHaveBeenCalledWith(\n \"test-thread-1\",\n {\n content: testMessage.content,\n role: testMessage.role,\n },\n );\n });\n\n it(\"should send a message and update thread state\", async () => {\n const mockAdvanceResponse: TamboAI.Beta.Threads.ThreadAdvanceResponse = {\n responseMessageDto: {\n id: \"response-1\",\n content: [{ type: \"text\", text: \"Response\" }],\n role: \"assistant\",\n threadId: \"test-thread-1\",\n component: undefined,\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n };\n\n jest\n .mocked(mockThreadsApi.advanceById)\n .mockResolvedValue(mockAdvanceResponse);\n\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello\", {\n threadId: \"test-thread-1\",\n streamResponse: false,\n });\n });\n\n expect(mockThreadsApi.advanceById).toHaveBeenCalledWith(\"test-thread-1\", {\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n });\n expect(result.current.generationStage).toBe(GenerationStage.COMPLETE);\n });\n\n it(\"should handle input value changes\", () => {\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n act(() => {\n result.current.setInputValue(\"New input\");\n });\n\n expect(result.current.inputValue).toBe(\"New input\");\n });\n\n it(\"should handle streaming responses\", async () => {\n const mockStreamResponse: TamboAI.Beta.Threads.ThreadAdvanceResponse = {\n responseMessageDto: {\n id: \"stream-1\",\n content: [{ type: \"text\", text: \"Streaming response\" }],\n role: \"assistant\",\n threadId: \"test-thread-1\",\n component: undefined,\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n };\n\n // Create an async iterator mock\n const mockAsyncIterator = {\n [Symbol.asyncIterator]: async function* () {\n yield mockStreamResponse;\n },\n };\n\n // Mock advanceStream to return our async iterator\n jest.mocked(advanceStream).mockResolvedValue(mockAsyncIterator);\n\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello\", {\n threadId: \"test-thread-1\",\n streamResponse: true,\n });\n });\n\n expect(result.current.generationStage).toBe(GenerationStage.COMPLETE);\n });\n\n it(\"should handle tool calls during message processing.\", async () => {\n const mockToolCallResponse: TamboAI.Beta.Threads.ThreadAdvanceResponse = {\n responseMessageDto: {\n id: \"tool-call-1\",\n content: [{ type: \"text\", text: \"Tool response\" }],\n role: \"tool\",\n threadId: \"test-thread-1\",\n toolCallRequest: {\n toolName: \"test-tool\",\n parameters: [{ parameterName: \"test\", parameterValue: \"test\" }],\n },\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n };\n\n jest\n .mocked(mockThreadsApi.advanceById)\n .mockResolvedValueOnce(mockToolCallResponse)\n .mockResolvedValueOnce({\n responseMessageDto: {\n id: \"advance-response2\",\n content: [{ type: \"text\", text: \"response 2\" }],\n role: \"user\",\n threadId: \"test-thread-1\",\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n });\n\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Use tool\", {\n threadId: \"test-thread-1\",\n streamResponse: false,\n });\n });\n expect(result.current.generationStage).toBe(GenerationStage.COMPLETE);\n expect(mockRegistry[0]?.associatedTools?.[0]?.tool).toHaveBeenCalledWith(\n \"test\",\n );\n });\n\n describe(\"streaming behavior\", () => {\n it(\"should call advanceStream when streamResponse=true\", async () => {\n // Use wrapper with streaming=true to show that explicit streamResponse=true works\n const wrapperWithStreaming = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider streaming={true}>{children}</TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n const mockStreamResponse: TamboAI.Beta.Threads.ThreadAdvanceResponse = {\n responseMessageDto: {\n id: \"stream-response\",\n content: [{ type: \"text\", text: \"Streaming response\" }],\n role: \"assistant\",\n threadId: \"test-thread-1\",\n component: undefined,\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n };\n\n const mockAsyncIterator = {\n [Symbol.asyncIterator]: async function* () {\n yield mockStreamResponse;\n },\n };\n\n jest.mocked(advanceStream).mockResolvedValue(mockAsyncIterator);\n\n const { result } = renderHook(() => useTamboThread(), {\n wrapper: wrapperWithStreaming,\n });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello streaming\", {\n threadId: \"test-thread-1\",\n streamResponse: true,\n });\n });\n\n expect(advanceStream).toHaveBeenCalledWith(\n mockTamboAI,\n {\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello streaming\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n forceToolChoice: undefined,\n },\n \"test-thread-1\",\n );\n\n // Should not call advance or advanceById\n expect(mockThreadsApi.advance).not.toHaveBeenCalled();\n expect(mockThreadsApi.advanceById).not.toHaveBeenCalled();\n });\n\n it(\"should call advanceById when streamResponse=false for existing thread\", async () => {\n // Use wrapper with streaming=true to show that explicit streamResponse=false overrides provider setting\n const wrapperWithStreaming = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider streaming={true}>{children}</TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n const { result } = renderHook(() => useTamboThread(), {\n wrapper: wrapperWithStreaming,\n });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello non-streaming\", {\n threadId: \"test-thread-1\",\n streamResponse: false,\n });\n });\n\n expect(mockThreadsApi.advanceById).toHaveBeenCalledWith(\"test-thread-1\", {\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello non-streaming\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n forceToolChoice: undefined,\n });\n\n // Should not call advance or advanceStream\n expect(mockThreadsApi.advance).not.toHaveBeenCalled();\n expect(advanceStream).not.toHaveBeenCalled();\n });\n\n it(\"should call advanceById when streamResponse is undefined and provider streaming=false\", async () => {\n // Use wrapper with streaming=false to test that undefined streamResponse respects provider setting\n const wrapperWithoutStreaming = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider streaming={false}>\n {children}\n </TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n const { result } = renderHook(() => useTamboThread(), {\n wrapper: wrapperWithoutStreaming,\n });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello default\", {\n threadId: \"test-thread-1\",\n // streamResponse is undefined, should use provider's streaming=false\n });\n });\n\n expect(mockThreadsApi.advanceById).toHaveBeenCalledWith(\"test-thread-1\", {\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello default\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n forceToolChoice: undefined,\n });\n\n // Should not call advance or advanceStream\n expect(mockThreadsApi.advance).not.toHaveBeenCalled();\n expect(advanceStream).not.toHaveBeenCalled();\n });\n\n it(\"should call advanceStream when streamResponse is undefined and provider streaming=true (default)\", async () => {\n // Use wrapper with streaming=true (default) to test that undefined streamResponse respects provider setting\n const wrapperWithDefaultStreaming = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider>{children}</TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n const mockStreamResponse: TamboAI.Beta.Threads.ThreadAdvanceResponse = {\n responseMessageDto: {\n id: \"stream-response\",\n content: [{ type: \"text\", text: \"Streaming response\" }],\n role: \"assistant\",\n threadId: \"test-thread-1\",\n component: undefined,\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n };\n\n const mockAsyncIterator = {\n [Symbol.asyncIterator]: async function* () {\n yield mockStreamResponse;\n },\n };\n\n jest.mocked(advanceStream).mockResolvedValue(mockAsyncIterator);\n\n const { result } = renderHook(() => useTamboThread(), {\n wrapper: wrapperWithDefaultStreaming,\n });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello default streaming\", {\n threadId: \"test-thread-1\",\n // streamResponse is undefined, should use provider's streaming=true (default)\n });\n });\n\n expect(advanceStream).toHaveBeenCalledWith(\n mockTamboAI,\n {\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello default streaming\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n forceToolChoice: undefined,\n },\n \"test-thread-1\",\n );\n\n // Should not call advance or advanceById\n expect(mockThreadsApi.advance).not.toHaveBeenCalled();\n expect(mockThreadsApi.advanceById).not.toHaveBeenCalled();\n });\n\n it(\"should call advance when streamResponse=false for placeholder thread\", async () => {\n // Use wrapper with streaming=true to show that explicit streamResponse=false overrides provider setting\n const wrapperWithStreaming = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider streaming={true}>{children}</TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n const { result } = renderHook(() => useTamboThread(), {\n wrapper: wrapperWithStreaming,\n });\n\n // Start with placeholder thread (which is the default state)\n expect(result.current.thread.id).toBe(\"placeholder\");\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello new thread\", {\n threadId: \"placeholder\",\n streamResponse: false,\n });\n });\n\n expect(mockThreadsApi.advance).toHaveBeenCalledWith({\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello new thread\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n forceToolChoice: undefined,\n });\n\n // Should not call advanceById or advanceStream\n expect(mockThreadsApi.advanceById).not.toHaveBeenCalled();\n expect(advanceStream).not.toHaveBeenCalled();\n });\n\n it(\"should call advanceStream when streamResponse=true for placeholder thread\", async () => {\n // Use wrapper with streaming=false to show that explicit streamResponse=true overrides provider setting\n const wrapperWithoutStreaming = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider streaming={false}>\n {children}\n </TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n const mockStreamResponse: TamboAI.Beta.Threads.ThreadAdvanceResponse = {\n responseMessageDto: {\n id: \"stream-response\",\n content: [{ type: \"text\", text: \"Streaming response\" }],\n role: \"assistant\",\n threadId: \"new-thread-1\",\n component: undefined,\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n };\n\n const mockAsyncIterator = {\n [Symbol.asyncIterator]: async function* () {\n yield mockStreamResponse;\n },\n };\n\n jest.mocked(advanceStream).mockResolvedValue(mockAsyncIterator);\n\n const { result } = renderHook(() => useTamboThread(), {\n wrapper: wrapperWithoutStreaming,\n });\n\n // Start with placeholder thread (which is the default state)\n expect(result.current.thread.id).toBe(\"placeholder\");\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello streaming new thread\", {\n threadId: \"placeholder\",\n streamResponse: true,\n });\n });\n\n expect(advanceStream).toHaveBeenCalledWith(\n mockTamboAI,\n {\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello streaming new thread\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n forceToolChoice: undefined,\n },\n undefined, // threadId is undefined for placeholder thread\n );\n\n // Should not call advance or advanceById\n expect(mockThreadsApi.advance).not.toHaveBeenCalled();\n expect(mockThreadsApi.advanceById).not.toHaveBeenCalled();\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"tambo-thread-provider.test.js","sourceRoot":"","sources":["../../../src/providers/__tests__/tambo-thread-provider.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI, { advanceStream } from \"@tambo-ai/typescript-sdk\";\nimport { act, renderHook } from \"@testing-library/react\";\nimport React from \"react\";\nimport { DeepPartial } from \"ts-essentials\";\nimport { z } from \"zod\";\nimport { TamboComponent } from \"../../model/component-metadata\";\nimport {\n GenerationStage,\n TamboThreadMessage,\n} from \"../../model/generate-component-response\";\nimport { serializeRegistry } from \"../../testing/tools\";\nimport { useTamboClient } from \"../tambo-client-provider\";\nimport { TamboRegistryProvider } from \"../tambo-registry-provider\";\nimport { TamboThreadProvider, useTamboThread } from \"../tambo-thread-provider\";\n\ntype PartialTamboAI = DeepPartial<TamboAI>;\n\n// Mock crypto.randomUUID\nObject.defineProperty(global, \"crypto\", {\n value: {\n randomUUID: jest.fn().mockReturnValue(\"test-uuid\"),\n },\n});\n\n// Mock the required providers\njest.mock(\"../tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n}));\njest.mock(\"@tambo-ai/typescript-sdk\", () => ({\n advanceStream: jest.fn(),\n}));\n\n// Test utilities\nconst createMockMessage = (\n overrides: Partial<TamboThreadMessage> = {},\n): TamboThreadMessage => ({\n id: \"test-message-1\",\n content: [{ type: \"text\", text: \"Hello\" }],\n role: \"user\",\n threadId: \"test-thread-1\",\n createdAt: new Date().toISOString(),\n componentState: {},\n ...overrides,\n});\n\nconst createMockThread = (\n overrides: Partial<TamboAI.Beta.Threads.Thread> = {},\n) => ({\n id: \"test-thread-1\",\n messages: [],\n createdAt: \"2024-01-01T00:00:00Z\",\n projectId: \"test-project\",\n updatedAt: \"2024-01-01T00:00:00Z\",\n metadata: {},\n ...overrides,\n});\n\nconst createMockAdvanceResponse = (\n overrides: Partial<TamboAI.Beta.Threads.ThreadAdvanceResponse> = {},\n): TamboAI.Beta.Threads.ThreadAdvanceResponse => ({\n responseMessageDto: {\n id: \"test-uuid\",\n content: [{ type: \"text\" as const, text: \"Default response\" }],\n role: \"assistant\",\n threadId: \"test-thread-1\",\n component: undefined,\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n ...overrides,\n});\n\ndescribe(\"TamboThreadProvider\", () => {\n const mockThread = createMockThread();\n\n const mockThreadsApi = {\n messages: {\n create: jest.fn(),\n },\n retrieve: jest.fn(),\n advance: jest.fn(),\n advanceById: jest.fn(),\n } satisfies DeepPartial<\n TamboAI[\"beta\"][\"threads\"]\n > as unknown as TamboAI.Beta.Threads;\n\n const mockBeta = {\n threads: mockThreadsApi,\n } satisfies PartialTamboAI[\"beta\"];\n\n const mockTamboAI = {\n apiKey: \"\",\n beta: mockBeta,\n } satisfies PartialTamboAI as unknown as TamboAI;\n\n const mockRegistry: TamboComponent[] = [\n {\n name: \"TestOnly\",\n component: () => <div>TestOnly</div>,\n description: \"TestOnly\",\n propsSchema: z.object({\n test: z.string(),\n }),\n associatedTools: [\n {\n name: \"test-tool\",\n tool: jest.fn().mockResolvedValue(\"test-tool\"),\n description: \"test-tool\",\n toolSchema: z\n .function()\n .args(z.string().describe(\"test-param-description\"))\n .returns(z.string()),\n },\n ],\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider streaming={false}>{children}</TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n beforeEach(() => {\n jest.clearAllMocks();\n jest.mocked(mockThreadsApi.retrieve).mockResolvedValue(mockThread);\n jest\n .mocked(mockThreadsApi.messages.create)\n .mockResolvedValue(createMockMessage());\n jest\n .mocked(mockThreadsApi.advance)\n .mockResolvedValue(createMockAdvanceResponse());\n jest\n .mocked(mockThreadsApi.advanceById)\n .mockResolvedValue(createMockAdvanceResponse());\n jest.mocked(useTamboClient).mockReturnValue(mockTamboAI);\n });\n\n it(\"should initialize with placeholder thread\", () => {\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n expect(result.current.thread.id).toBe(\"placeholder\");\n expect(result.current.isIdle).toBe(true);\n expect(result.current.generationStage).toBe(GenerationStage.IDLE);\n });\n\n it(\"should switch to a new thread\", async () => {\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n await act(async () => {\n await result.current.switchCurrentThread(\"test-thread-1\");\n });\n\n expect(mockThreadsApi.retrieve).toHaveBeenCalledWith(\"test-thread-1\", {\n includeInternal: true,\n });\n expect(result.current.thread.id).toBe(\"test-thread-1\");\n });\n\n it(\"should start a new thread\", async () => {\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n await act(async () => {\n result.current.startNewThread();\n });\n\n expect(result.current.thread.id).toBe(\"placeholder\");\n expect(result.current.isIdle).toBe(true);\n });\n\n it(\"should add a message to the thread\", async () => {\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n const testMessage: TamboThreadMessage = {\n id: \"test-message-1\",\n content: [{ type: \"text\", text: \"Hello\" }],\n role: \"user\",\n threadId: \"test-thread-1\",\n createdAt: new Date().toISOString(),\n componentState: {},\n };\n\n await act(async () => {\n await result.current.addThreadMessage(testMessage, true);\n });\n\n expect(mockThreadsApi.messages.create).toHaveBeenCalledWith(\n \"test-thread-1\",\n {\n content: testMessage.content,\n role: testMessage.role,\n },\n );\n });\n\n it(\"should update a message in the thread\", async () => {\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n const testMessage: TamboThreadMessage = {\n id: \"test-message-1\",\n content: [{ type: \"text\", text: \"Updated message\" }],\n role: \"user\",\n threadId: \"test-thread-1\",\n createdAt: new Date().toISOString(),\n componentState: {},\n };\n\n await act(async () => {\n await result.current.updateThreadMessage(\n \"test-message-1\",\n testMessage,\n true,\n );\n });\n\n expect(mockThreadsApi.messages.create).toHaveBeenCalledWith(\n \"test-thread-1\",\n {\n content: testMessage.content,\n role: testMessage.role,\n },\n );\n });\n\n it(\"should send a message and update thread state\", async () => {\n const mockAdvanceResponse: TamboAI.Beta.Threads.ThreadAdvanceResponse = {\n responseMessageDto: {\n id: \"response-1\",\n content: [{ type: \"text\", text: \"Response\" }],\n role: \"assistant\",\n threadId: \"test-thread-1\",\n component: undefined,\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n };\n\n jest\n .mocked(mockThreadsApi.advanceById)\n .mockResolvedValue(mockAdvanceResponse);\n\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello\", {\n threadId: \"test-thread-1\",\n streamResponse: false,\n });\n });\n\n expect(mockThreadsApi.advanceById).toHaveBeenCalledWith(\"test-thread-1\", {\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n toolCallCounts: {},\n });\n expect(result.current.generationStage).toBe(GenerationStage.COMPLETE);\n });\n\n it(\"should handle input value changes\", () => {\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n act(() => {\n result.current.setInputValue(\"New input\");\n });\n\n expect(result.current.inputValue).toBe(\"New input\");\n });\n\n it(\"should handle streaming responses\", async () => {\n const mockStreamResponse: TamboAI.Beta.Threads.ThreadAdvanceResponse = {\n responseMessageDto: {\n id: \"stream-1\",\n content: [{ type: \"text\", text: \"Streaming response\" }],\n role: \"assistant\",\n threadId: \"test-thread-1\",\n component: undefined,\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n };\n\n // Create an async iterator mock\n const mockAsyncIterator = {\n [Symbol.asyncIterator]: async function* () {\n yield mockStreamResponse;\n },\n };\n\n // Mock advanceStream to return our async iterator\n jest.mocked(advanceStream).mockResolvedValue(mockAsyncIterator);\n\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello\", {\n threadId: \"test-thread-1\",\n streamResponse: true,\n });\n });\n\n expect(result.current.generationStage).toBe(GenerationStage.COMPLETE);\n });\n\n it(\"should handle tool calls during message processing.\", async () => {\n const mockToolCallResponse: TamboAI.Beta.Threads.ThreadAdvanceResponse = {\n responseMessageDto: {\n id: \"tool-call-1\",\n content: [{ type: \"text\", text: \"Tool response\" }],\n role: \"tool\",\n threadId: \"test-thread-1\",\n toolCallRequest: {\n toolName: \"test-tool\",\n parameters: [{ parameterName: \"test\", parameterValue: \"test\" }],\n },\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n };\n\n jest\n .mocked(mockThreadsApi.advanceById)\n .mockResolvedValueOnce(mockToolCallResponse)\n .mockResolvedValueOnce({\n responseMessageDto: {\n id: \"advance-response2\",\n content: [{ type: \"text\", text: \"response 2\" }],\n role: \"user\",\n threadId: \"test-thread-1\",\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n });\n\n const { result } = renderHook(() => useTamboThread(), { wrapper });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Use tool\", {\n threadId: \"test-thread-1\",\n streamResponse: false,\n });\n });\n expect(result.current.generationStage).toBe(GenerationStage.COMPLETE);\n expect(mockRegistry[0]?.associatedTools?.[0]?.tool).toHaveBeenCalledWith(\n \"test\",\n );\n });\n\n describe(\"streaming behavior\", () => {\n it(\"should call advanceStream when streamResponse=true\", async () => {\n // Use wrapper with streaming=true to show that explicit streamResponse=true works\n const wrapperWithStreaming = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider streaming={true}>{children}</TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n const mockStreamResponse: TamboAI.Beta.Threads.ThreadAdvanceResponse = {\n responseMessageDto: {\n id: \"stream-response\",\n content: [{ type: \"text\", text: \"Streaming response\" }],\n role: \"assistant\",\n threadId: \"test-thread-1\",\n component: undefined,\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n };\n\n const mockAsyncIterator = {\n [Symbol.asyncIterator]: async function* () {\n yield mockStreamResponse;\n },\n };\n\n jest.mocked(advanceStream).mockResolvedValue(mockAsyncIterator);\n\n const { result } = renderHook(() => useTamboThread(), {\n wrapper: wrapperWithStreaming,\n });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello streaming\", {\n threadId: \"test-thread-1\",\n streamResponse: true,\n });\n });\n\n expect(advanceStream).toHaveBeenCalledWith(\n mockTamboAI,\n {\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello streaming\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n forceToolChoice: undefined,\n toolCallCounts: {},\n },\n \"test-thread-1\",\n );\n\n // Should not call advance or advanceById\n expect(mockThreadsApi.advance).not.toHaveBeenCalled();\n expect(mockThreadsApi.advanceById).not.toHaveBeenCalled();\n });\n\n it(\"should call advanceById when streamResponse=false for existing thread\", async () => {\n // Use wrapper with streaming=true to show that explicit streamResponse=false overrides provider setting\n const wrapperWithStreaming = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider streaming={true}>{children}</TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n const { result } = renderHook(() => useTamboThread(), {\n wrapper: wrapperWithStreaming,\n });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello non-streaming\", {\n threadId: \"test-thread-1\",\n streamResponse: false,\n });\n });\n\n expect(mockThreadsApi.advanceById).toHaveBeenCalledWith(\"test-thread-1\", {\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello non-streaming\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n forceToolChoice: undefined,\n toolCallCounts: {},\n });\n\n // Should not call advance or advanceStream\n expect(mockThreadsApi.advance).not.toHaveBeenCalled();\n expect(advanceStream).not.toHaveBeenCalled();\n });\n\n it(\"should call advanceById when streamResponse is undefined and provider streaming=false\", async () => {\n // Use wrapper with streaming=false to test that undefined streamResponse respects provider setting\n const wrapperWithoutStreaming = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider streaming={false}>\n {children}\n </TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n const { result } = renderHook(() => useTamboThread(), {\n wrapper: wrapperWithoutStreaming,\n });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello default\", {\n threadId: \"test-thread-1\",\n // streamResponse is undefined, should use provider's streaming=false\n });\n });\n\n expect(mockThreadsApi.advanceById).toHaveBeenCalledWith(\"test-thread-1\", {\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello default\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n forceToolChoice: undefined,\n toolCallCounts: {},\n });\n\n // Should not call advance or advanceStream\n expect(mockThreadsApi.advance).not.toHaveBeenCalled();\n expect(advanceStream).not.toHaveBeenCalled();\n });\n\n it(\"should call advanceStream when streamResponse is undefined and provider streaming=true (default)\", async () => {\n // Use wrapper with streaming=true (default) to test that undefined streamResponse respects provider setting\n const wrapperWithDefaultStreaming = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider>{children}</TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n const mockStreamResponse: TamboAI.Beta.Threads.ThreadAdvanceResponse = {\n responseMessageDto: {\n id: \"stream-response\",\n content: [{ type: \"text\", text: \"Streaming response\" }],\n role: \"assistant\",\n threadId: \"test-thread-1\",\n component: undefined,\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n };\n\n const mockAsyncIterator = {\n [Symbol.asyncIterator]: async function* () {\n yield mockStreamResponse;\n },\n };\n\n jest.mocked(advanceStream).mockResolvedValue(mockAsyncIterator);\n\n const { result } = renderHook(() => useTamboThread(), {\n wrapper: wrapperWithDefaultStreaming,\n });\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello default streaming\", {\n threadId: \"test-thread-1\",\n // streamResponse is undefined, should use provider's streaming=true (default)\n });\n });\n\n expect(advanceStream).toHaveBeenCalledWith(\n mockTamboAI,\n {\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello default streaming\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n forceToolChoice: undefined,\n toolCallCounts: {},\n },\n \"test-thread-1\",\n );\n\n // Should not call advance or advanceById\n expect(mockThreadsApi.advance).not.toHaveBeenCalled();\n expect(mockThreadsApi.advanceById).not.toHaveBeenCalled();\n });\n\n it(\"should call advance when streamResponse=false for placeholder thread\", async () => {\n // Use wrapper with streaming=true to show that explicit streamResponse=false overrides provider setting\n const wrapperWithStreaming = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider streaming={true}>{children}</TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n const { result } = renderHook(() => useTamboThread(), {\n wrapper: wrapperWithStreaming,\n });\n\n // Start with placeholder thread (which is the default state)\n expect(result.current.thread.id).toBe(\"placeholder\");\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello new thread\", {\n threadId: \"placeholder\",\n streamResponse: false,\n });\n });\n\n expect(mockThreadsApi.advance).toHaveBeenCalledWith({\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello new thread\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n forceToolChoice: undefined,\n toolCallCounts: {},\n });\n\n // Should not call advanceById or advanceStream\n expect(mockThreadsApi.advanceById).not.toHaveBeenCalled();\n expect(advanceStream).not.toHaveBeenCalled();\n });\n\n it(\"should call advanceStream when streamResponse=true for placeholder thread\", async () => {\n // Use wrapper with streaming=false to show that explicit streamResponse=true overrides provider setting\n const wrapperWithoutStreaming = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboRegistryProvider components={mockRegistry}>\n <TamboThreadProvider streaming={false}>\n {children}\n </TamboThreadProvider>\n </TamboRegistryProvider>\n );\n\n const mockStreamResponse: TamboAI.Beta.Threads.ThreadAdvanceResponse = {\n responseMessageDto: {\n id: \"stream-response\",\n content: [{ type: \"text\", text: \"Streaming response\" }],\n role: \"assistant\",\n threadId: \"new-thread-1\",\n component: undefined,\n componentState: {},\n createdAt: new Date().toISOString(),\n },\n generationStage: GenerationStage.COMPLETE,\n mcpAccessToken: \"test-mcp-access-token\",\n };\n\n const mockAsyncIterator = {\n [Symbol.asyncIterator]: async function* () {\n yield mockStreamResponse;\n },\n };\n\n jest.mocked(advanceStream).mockResolvedValue(mockAsyncIterator);\n\n const { result } = renderHook(() => useTamboThread(), {\n wrapper: wrapperWithoutStreaming,\n });\n\n // Start with placeholder thread (which is the default state)\n expect(result.current.thread.id).toBe(\"placeholder\");\n\n await act(async () => {\n await result.current.sendThreadMessage(\"Hello streaming new thread\", {\n threadId: \"placeholder\",\n streamResponse: true,\n });\n });\n\n expect(advanceStream).toHaveBeenCalledWith(\n mockTamboAI,\n {\n messageToAppend: {\n content: [{ type: \"text\", text: \"Hello streaming new thread\" }],\n role: \"user\",\n },\n availableComponents: serializeRegistry(mockRegistry),\n contextKey: undefined,\n clientTools: [],\n forceToolChoice: undefined,\n toolCallCounts: {},\n },\n undefined, // threadId is undefined for placeholder thread\n );\n\n // Should not call advance or advanceById\n expect(mockThreadsApi.advance).not.toHaveBeenCalled();\n expect(mockThreadsApi.advanceById).not.toHaveBeenCalled();\n });\n });\n});\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export interface InteractableConfig {
|
|
4
|
+
componentName: string;
|
|
5
|
+
description: string;
|
|
6
|
+
propsSchema?: z.ZodTypeAny;
|
|
7
|
+
}
|
|
8
|
+
export interface WithTamboInteractableProps {
|
|
9
|
+
interactableId?: string;
|
|
10
|
+
onInteractableReady?: (id: string) => void;
|
|
11
|
+
onPropsUpdate?: (newProps: Record<string, any>) => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Higher-Order Component that makes any component interactable by tambo.
|
|
15
|
+
* @param WrappedComponent - The component to make interactable
|
|
16
|
+
* @param config - Configuration for the interactable component
|
|
17
|
+
* @returns A new component that is automatically registered as interactable
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* const MyInteractableNote = withTamboInteractable(MyNote, {
|
|
21
|
+
* componentName: "MyNote",
|
|
22
|
+
* description: "A note component",
|
|
23
|
+
* propsSchema: z.object({
|
|
24
|
+
* title: z.string(),
|
|
25
|
+
* content: z.string(),
|
|
26
|
+
* }),
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // Usage
|
|
30
|
+
* <MyInteractableNote title="My Note" content="This is my note" />
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function withTamboInteractable<P extends object>(WrappedComponent: React.ComponentType<P>, config: InteractableConfig): React.FC<P & WithTamboInteractableProps>;
|
|
34
|
+
//# sourceMappingURL=with-tambo-interactable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-tambo-interactable.d.ts","sourceRoot":"","sources":["../../../src/providers/hoc/with-tambo-interactable.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;CACzD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EACpD,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EACxC,MAAM,EAAE,kBAAkB,4CA+E3B"}
|