@tambo-ai/react 0.71.0 → 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/dist/v1/hooks/use-tambo-v1-component-state.d.ts +44 -0
  2. package/dist/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -0
  3. package/dist/v1/hooks/use-tambo-v1-component-state.js +134 -0
  4. package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -0
  5. package/dist/v1/hooks/use-tambo-v1-component-state.test.d.ts +2 -0
  6. package/dist/v1/hooks/use-tambo-v1-component-state.test.d.ts.map +1 -0
  7. package/dist/v1/hooks/use-tambo-v1-component-state.test.js +292 -0
  8. package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -0
  9. package/dist/v1/hooks/use-tambo-v1-messages.test.js +22 -9
  10. package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
  11. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +1 -0
  12. package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
  13. package/dist/v1/hooks/use-tambo-v1-send-message.js +9 -2
  14. package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
  15. package/dist/v1/hooks/use-tambo-v1-send-message.test.js +22 -9
  16. package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
  17. package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts +91 -0
  18. package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -0
  19. package/dist/v1/hooks/use-tambo-v1-suggestions.js +152 -0
  20. package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -0
  21. package/dist/v1/hooks/use-tambo-v1-suggestions.test.d.ts +2 -0
  22. package/dist/v1/hooks/use-tambo-v1-suggestions.test.d.ts.map +1 -0
  23. package/dist/v1/hooks/use-tambo-v1-suggestions.test.js +511 -0
  24. package/dist/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -0
  25. package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts +11 -0
  26. package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -0
  27. package/dist/v1/hooks/use-tambo-v1-thread-input.js +16 -0
  28. package/dist/v1/hooks/use-tambo-v1-thread-input.js.map +1 -0
  29. package/dist/v1/hooks/use-tambo-v1-thread-input.test.d.ts +2 -0
  30. package/dist/v1/hooks/use-tambo-v1-thread-input.test.d.ts.map +1 -0
  31. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +297 -0
  32. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -0
  33. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts +6 -4
  34. package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
  35. package/dist/v1/hooks/use-tambo-v1-thread-list.js +2 -2
  36. package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
  37. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +2 -2
  38. package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
  39. package/dist/v1/hooks/use-tambo-v1.test.js +16 -7
  40. package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
  41. package/dist/v1/index.d.ts +39 -19
  42. package/dist/v1/index.d.ts.map +1 -1
  43. package/dist/v1/index.js +60 -34
  44. package/dist/v1/index.js.map +1 -1
  45. package/dist/v1/providers/tambo-v1-provider.d.ts +61 -1
  46. package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  47. package/dist/v1/providers/tambo-v1-provider.js +35 -3
  48. package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
  49. package/dist/v1/providers/tambo-v1-provider.test.js +78 -3
  50. package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
  51. package/dist/v1/providers/tambo-v1-stream-context.d.ts +19 -10
  52. package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
  53. package/dist/v1/providers/tambo-v1-stream-context.js +43 -53
  54. package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
  55. package/dist/v1/providers/tambo-v1-stream-context.test.js +94 -19
  56. package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
  57. package/dist/v1/providers/tambo-v1-stub-provider.d.ts +74 -0
  58. package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -0
  59. package/dist/v1/providers/tambo-v1-stub-provider.js +212 -0
  60. package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -0
  61. package/dist/v1/providers/tambo-v1-stub-provider.test.d.ts +2 -0
  62. package/dist/v1/providers/tambo-v1-stub-provider.test.d.ts.map +1 -0
  63. package/dist/v1/providers/tambo-v1-stub-provider.test.js +162 -0
  64. package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -0
  65. package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +105 -0
  66. package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -0
  67. package/dist/v1/providers/tambo-v1-thread-input-provider.js +191 -0
  68. package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -0
  69. package/dist/v1/types/message.d.ts +27 -2
  70. package/dist/v1/types/message.d.ts.map +1 -1
  71. package/dist/v1/types/message.js.map +1 -1
  72. package/dist/v1/utils/component-renderer.d.ts +37 -0
  73. package/dist/v1/utils/component-renderer.d.ts.map +1 -0
  74. package/dist/v1/utils/component-renderer.js +70 -0
  75. package/dist/v1/utils/component-renderer.js.map +1 -0
  76. package/dist/v1/utils/component-renderer.test.d.ts +2 -0
  77. package/dist/v1/utils/component-renderer.test.d.ts.map +1 -0
  78. package/dist/v1/utils/component-renderer.test.js +45 -0
  79. package/dist/v1/utils/component-renderer.test.js.map +1 -0
  80. package/dist/v1/utils/event-accumulator.js +28 -8
  81. package/dist/v1/utils/event-accumulator.js.map +1 -1
  82. package/dist/v1/utils/event-accumulator.test.js +201 -6
  83. package/dist/v1/utils/event-accumulator.test.js.map +1 -1
  84. package/esm/v1/hooks/use-tambo-v1-component-state.d.ts +44 -0
  85. package/esm/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -0
  86. package/esm/v1/hooks/use-tambo-v1-component-state.js +131 -0
  87. package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -0
  88. package/esm/v1/hooks/use-tambo-v1-component-state.test.d.ts +2 -0
  89. package/esm/v1/hooks/use-tambo-v1-component-state.test.d.ts.map +1 -0
  90. package/esm/v1/hooks/use-tambo-v1-component-state.test.js +290 -0
  91. package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -0
  92. package/esm/v1/hooks/use-tambo-v1-messages.test.js +22 -9
  93. package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
  94. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +1 -0
  95. package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
  96. package/esm/v1/hooks/use-tambo-v1-send-message.js +9 -2
  97. package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
  98. package/esm/v1/hooks/use-tambo-v1-send-message.test.js +22 -9
  99. package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
  100. package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts +91 -0
  101. package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -0
  102. package/esm/v1/hooks/use-tambo-v1-suggestions.js +149 -0
  103. package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -0
  104. package/esm/v1/hooks/use-tambo-v1-suggestions.test.d.ts +2 -0
  105. package/esm/v1/hooks/use-tambo-v1-suggestions.test.d.ts.map +1 -0
  106. package/esm/v1/hooks/use-tambo-v1-suggestions.test.js +506 -0
  107. package/esm/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -0
  108. package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts +11 -0
  109. package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -0
  110. package/esm/v1/hooks/use-tambo-v1-thread-input.js +12 -0
  111. package/esm/v1/hooks/use-tambo-v1-thread-input.js.map +1 -0
  112. package/esm/v1/hooks/use-tambo-v1-thread-input.test.d.ts +2 -0
  113. package/esm/v1/hooks/use-tambo-v1-thread-input.test.d.ts.map +1 -0
  114. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +292 -0
  115. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -0
  116. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts +6 -4
  117. package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
  118. package/esm/v1/hooks/use-tambo-v1-thread-list.js +2 -2
  119. package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
  120. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +2 -2
  121. package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
  122. package/esm/v1/hooks/use-tambo-v1.test.js +16 -7
  123. package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
  124. package/esm/v1/index.d.ts +39 -19
  125. package/esm/v1/index.d.ts.map +1 -1
  126. package/esm/v1/index.js +43 -19
  127. package/esm/v1/index.js.map +1 -1
  128. package/esm/v1/providers/tambo-v1-provider.d.ts +61 -1
  129. package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  130. package/esm/v1/providers/tambo-v1-provider.js +34 -4
  131. package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
  132. package/esm/v1/providers/tambo-v1-provider.test.js +79 -4
  133. package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
  134. package/esm/v1/providers/tambo-v1-stream-context.d.ts +19 -10
  135. package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
  136. package/esm/v1/providers/tambo-v1-stream-context.js +44 -54
  137. package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
  138. package/esm/v1/providers/tambo-v1-stream-context.test.js +95 -20
  139. package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
  140. package/esm/v1/providers/tambo-v1-stub-provider.d.ts +74 -0
  141. package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -0
  142. package/esm/v1/providers/tambo-v1-stub-provider.js +176 -0
  143. package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -0
  144. package/esm/v1/providers/tambo-v1-stub-provider.test.d.ts +2 -0
  145. package/esm/v1/providers/tambo-v1-stub-provider.test.d.ts.map +1 -0
  146. package/esm/v1/providers/tambo-v1-stub-provider.test.js +157 -0
  147. package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -0
  148. package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +105 -0
  149. package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -0
  150. package/esm/v1/providers/tambo-v1-thread-input-provider.js +153 -0
  151. package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -0
  152. package/esm/v1/types/message.d.ts +27 -2
  153. package/esm/v1/types/message.d.ts.map +1 -1
  154. package/esm/v1/types/message.js.map +1 -1
  155. package/esm/v1/utils/component-renderer.d.ts +37 -0
  156. package/esm/v1/utils/component-renderer.d.ts.map +1 -0
  157. package/esm/v1/utils/component-renderer.js +33 -0
  158. package/esm/v1/utils/component-renderer.js.map +1 -0
  159. package/esm/v1/utils/component-renderer.test.d.ts +2 -0
  160. package/esm/v1/utils/component-renderer.test.d.ts.map +1 -0
  161. package/esm/v1/utils/component-renderer.test.js +40 -0
  162. package/esm/v1/utils/component-renderer.test.js.map +1 -0
  163. package/esm/v1/utils/event-accumulator.js +28 -8
  164. package/esm/v1/utils/event-accumulator.js.map +1 -1
  165. package/esm/v1/utils/event-accumulator.test.js +201 -6
  166. package/esm/v1/utils/event-accumulator.test.js.map +1 -1
  167. package/package.json +2 -2
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = require("@testing-library/react");
7
+ const react_2 = __importDefault(require("react"));
8
+ const react_query_1 = require("@tanstack/react-query");
9
+ const tambo_v1_thread_input_provider_1 = require("../providers/tambo-v1-thread-input-provider");
10
+ const tambo_v1_stream_context_1 = require("../providers/tambo-v1-stream-context");
11
+ const use_tambo_v1_send_message_1 = require("./use-tambo-v1-send-message");
12
+ // Mock useTamboV1SendMessage
13
+ jest.mock("./use-tambo-v1-send-message", () => ({
14
+ useTamboV1SendMessage: jest.fn(),
15
+ }));
16
+ // Mock useTamboQueryClient to avoid TamboClientProvider dependency
17
+ jest.mock("../../providers/tambo-client-provider", () => ({
18
+ useTamboQueryClient: jest.fn(() => new react_query_1.QueryClient()),
19
+ useTamboClient: jest.fn(),
20
+ }));
21
+ const createSuccessfulFileReader = () => {
22
+ const reader = {
23
+ readAsDataURL: jest.fn(),
24
+ onload: null,
25
+ onerror: null,
26
+ result: "data:image/png;base64,mock-data",
27
+ };
28
+ reader.readAsDataURL = jest.fn(() => {
29
+ setTimeout(() => {
30
+ reader.onload?.({});
31
+ }, 0);
32
+ });
33
+ return reader;
34
+ };
35
+ const originalFileReader = global.FileReader;
36
+ describe("useTamboV1ThreadInput", () => {
37
+ const mockMutateAsync = jest.fn();
38
+ let queryClient;
39
+ function createWrapper({ streamState } = {}) {
40
+ const noopDispatch = () => { };
41
+ return function Wrapper({ children }) {
42
+ const streamProviderProps = streamState === undefined
43
+ ? {}
44
+ : { state: streamState, dispatch: noopDispatch };
45
+ return (react_2.default.createElement(react_query_1.QueryClientProvider, { client: queryClient },
46
+ react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, { ...streamProviderProps },
47
+ react_2.default.createElement(tambo_v1_thread_input_provider_1.TamboV1ThreadInputProvider, null, children))));
48
+ };
49
+ }
50
+ beforeEach(() => {
51
+ jest.clearAllMocks();
52
+ global.FileReader = jest.fn(() => createSuccessfulFileReader());
53
+ queryClient = new react_query_1.QueryClient({
54
+ defaultOptions: {
55
+ queries: { retry: false },
56
+ mutations: { retry: false },
57
+ },
58
+ });
59
+ mockMutateAsync.mockResolvedValue({ threadId: "thread_123" });
60
+ jest.mocked(use_tambo_v1_send_message_1.useTamboV1SendMessage).mockReturnValue({
61
+ mutateAsync: mockMutateAsync,
62
+ mutate: jest.fn(),
63
+ isPending: false,
64
+ isError: false,
65
+ error: null,
66
+ isSuccess: false,
67
+ isIdle: true,
68
+ isPaused: false,
69
+ status: "idle",
70
+ data: undefined,
71
+ variables: undefined,
72
+ failureCount: 0,
73
+ failureReason: null,
74
+ reset: jest.fn(),
75
+ context: undefined,
76
+ submittedAt: 0,
77
+ });
78
+ });
79
+ afterEach(() => {
80
+ global.FileReader = originalFileReader;
81
+ });
82
+ describe("State Management", () => {
83
+ it("initializes with empty value", () => {
84
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
85
+ wrapper: createWrapper(),
86
+ });
87
+ expect(result.current.value).toBe("");
88
+ });
89
+ it("updates value via setValue", () => {
90
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
91
+ wrapper: createWrapper(),
92
+ });
93
+ (0, react_1.act)(() => {
94
+ result.current.setValue("Hello world");
95
+ });
96
+ expect(result.current.value).toBe("Hello world");
97
+ });
98
+ it("supports functional updates for setValue", () => {
99
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
100
+ wrapper: createWrapper(),
101
+ });
102
+ (0, react_1.act)(() => {
103
+ result.current.setValue("Hello");
104
+ });
105
+ (0, react_1.act)(() => {
106
+ result.current.setValue((prev) => `${prev} world`);
107
+ });
108
+ expect(result.current.value).toBe("Hello world");
109
+ });
110
+ });
111
+ describe("Submit Behavior", () => {
112
+ it("submits message and clears input on success", async () => {
113
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
114
+ wrapper: createWrapper(),
115
+ });
116
+ (0, react_1.act)(() => {
117
+ result.current.setValue("Test message");
118
+ });
119
+ await (0, react_1.act)(async () => {
120
+ const response = await result.current.submit();
121
+ expect(response.threadId).toBe("thread_123");
122
+ });
123
+ // Input should be cleared
124
+ await (0, react_1.waitFor)(() => {
125
+ expect(result.current.value).toBe("");
126
+ });
127
+ // Should have called mutateAsync with correct message format
128
+ expect(mockMutateAsync).toHaveBeenCalledWith({
129
+ message: {
130
+ role: "user",
131
+ content: [{ type: "text", text: "Test message" }],
132
+ },
133
+ debug: undefined,
134
+ });
135
+ });
136
+ it("throws error when submitting empty message", async () => {
137
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
138
+ wrapper: createWrapper(),
139
+ });
140
+ await expect(result.current.submit()).rejects.toThrow("Message cannot be empty");
141
+ expect(mockMutateAsync).not.toHaveBeenCalled();
142
+ });
143
+ it("throws error when submitting whitespace-only message", async () => {
144
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
145
+ wrapper: createWrapper(),
146
+ });
147
+ (0, react_1.act)(() => {
148
+ result.current.setValue(" ");
149
+ });
150
+ await expect(result.current.submit()).rejects.toThrow("Message cannot be empty");
151
+ expect(mockMutateAsync).not.toHaveBeenCalled();
152
+ });
153
+ it("passes debug option to mutation", async () => {
154
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
155
+ wrapper: createWrapper(),
156
+ });
157
+ (0, react_1.act)(() => {
158
+ result.current.setValue("Debug message");
159
+ });
160
+ await (0, react_1.act)(async () => {
161
+ await result.current.submit({ debug: true });
162
+ });
163
+ expect(mockMutateAsync).toHaveBeenCalledWith({
164
+ message: {
165
+ role: "user",
166
+ content: [{ type: "text", text: "Debug message" }],
167
+ },
168
+ debug: true,
169
+ });
170
+ });
171
+ it("submits image-only messages as resource content", async () => {
172
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
173
+ wrapper: createWrapper(),
174
+ });
175
+ await (0, react_1.act)(async () => {
176
+ await result.current.addImage(new File(["image"], "photo.png", { type: "image/png" }));
177
+ });
178
+ await (0, react_1.act)(async () => {
179
+ await result.current.submit();
180
+ });
181
+ expect(mockMutateAsync).toHaveBeenCalledWith({
182
+ message: {
183
+ role: "user",
184
+ content: [
185
+ {
186
+ type: "resource",
187
+ resource: {
188
+ blob: "mock-data",
189
+ mimeType: "image/png",
190
+ name: "photo.png",
191
+ },
192
+ },
193
+ ],
194
+ },
195
+ debug: undefined,
196
+ });
197
+ await (0, react_1.waitFor)(() => {
198
+ expect(result.current.images).toEqual([]);
199
+ });
200
+ });
201
+ it("includes both text and image resource content when both are present", async () => {
202
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
203
+ wrapper: createWrapper(),
204
+ });
205
+ (0, react_1.act)(() => {
206
+ result.current.setValue("Test message");
207
+ });
208
+ await (0, react_1.act)(async () => {
209
+ await result.current.addImage(new File(["image"], "photo.png", { type: "image/png" }));
210
+ });
211
+ await (0, react_1.act)(async () => {
212
+ await result.current.submit();
213
+ });
214
+ expect(mockMutateAsync).toHaveBeenCalledWith({
215
+ message: {
216
+ role: "user",
217
+ content: [
218
+ { type: "text", text: "Test message" },
219
+ {
220
+ type: "resource",
221
+ resource: {
222
+ blob: "mock-data",
223
+ mimeType: "image/png",
224
+ name: "photo.png",
225
+ },
226
+ },
227
+ ],
228
+ },
229
+ debug: undefined,
230
+ });
231
+ });
232
+ });
233
+ describe("Thread ID Management", () => {
234
+ it("initializes with undefined threadId", () => {
235
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
236
+ wrapper: createWrapper(),
237
+ });
238
+ expect(result.current.threadId).toBeUndefined();
239
+ });
240
+ it("allows setting threadId via setThreadId", () => {
241
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
242
+ wrapper: createWrapper(),
243
+ });
244
+ (0, react_1.act)(() => {
245
+ result.current.setThreadId("custom_thread_id");
246
+ });
247
+ expect(result.current.threadId).toBe("custom_thread_id");
248
+ });
249
+ it("does not take ownership of threadId when inheriting stream selection", async () => {
250
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
251
+ wrapper: createWrapper({
252
+ streamState: { threadMap: {}, currentThreadId: "thread_stream" },
253
+ }),
254
+ });
255
+ expect(result.current.threadId).toBe("thread_stream");
256
+ expect(jest.mocked(use_tambo_v1_send_message_1.useTamboV1SendMessage).mock.calls.map((call) => call[0])).toContain("thread_stream");
257
+ (0, react_1.act)(() => {
258
+ result.current.setValue("Test message");
259
+ });
260
+ await (0, react_1.act)(async () => {
261
+ await result.current.submit();
262
+ });
263
+ expect(result.current.threadId).toBe("thread_stream");
264
+ expect(jest.mocked(use_tambo_v1_send_message_1.useTamboV1SendMessage).mock.calls.map((call) => call[0])).not.toContain("thread_123");
265
+ });
266
+ });
267
+ describe("Image State", () => {
268
+ it("initializes with empty images array", () => {
269
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
270
+ wrapper: createWrapper(),
271
+ });
272
+ expect(result.current.images).toEqual([]);
273
+ });
274
+ it("exposes image management functions", () => {
275
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)(), {
276
+ wrapper: createWrapper(),
277
+ });
278
+ expect(typeof result.current.addImage).toBe("function");
279
+ expect(typeof result.current.addImages).toBe("function");
280
+ expect(typeof result.current.removeImage).toBe("function");
281
+ expect(typeof result.current.clearImages).toBe("function");
282
+ });
283
+ });
284
+ describe("Error handling", () => {
285
+ it("throws error when used outside provider", () => {
286
+ // Suppress console.error for this test
287
+ const consoleSpy = jest
288
+ .spyOn(console, "error")
289
+ .mockImplementation(() => { });
290
+ expect(() => {
291
+ (0, react_1.renderHook)(() => (0, tambo_v1_thread_input_provider_1.useTamboV1ThreadInput)());
292
+ }).toThrow("useTamboV1ThreadInput must be used within TamboV1ThreadInputProvider");
293
+ consoleSpy.mockRestore();
294
+ });
295
+ });
296
+ });
297
+ //# sourceMappingURL=use-tambo-v1-thread-input.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tambo-v1-thread-input.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-thread-input.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { renderHook, act, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport {\n TamboV1ThreadInputProvider,\n useTamboV1ThreadInput,\n} from \"../providers/tambo-v1-thread-input-provider\";\nimport { TamboV1StreamProvider } from \"../providers/tambo-v1-stream-context\";\nimport { useTamboV1SendMessage } from \"./use-tambo-v1-send-message\";\nimport type { StreamAction, StreamState } from \"../utils/event-accumulator\";\n\n// Mock useTamboV1SendMessage\njest.mock(\"./use-tambo-v1-send-message\", () => ({\n useTamboV1SendMessage: jest.fn(),\n}));\n\n// Mock useTamboQueryClient to avoid TamboClientProvider dependency\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboQueryClient: jest.fn(() => new QueryClient()),\n useTamboClient: jest.fn(),\n}));\n\nconst createSuccessfulFileReader = () => {\n const reader = {\n readAsDataURL: jest.fn(),\n onload: null as ((e: unknown) => void) | null,\n onerror: null as ((e: unknown) => void) | null,\n result: \"data:image/png;base64,mock-data\",\n };\n\n reader.readAsDataURL = jest.fn(() => {\n setTimeout(() => {\n reader.onload?.({});\n }, 0);\n });\n\n return reader;\n};\n\nconst originalFileReader = (global as any).FileReader;\n\ndescribe(\"useTamboV1ThreadInput\", () => {\n const mockMutateAsync = jest.fn();\n let queryClient: QueryClient;\n\n function createWrapper({ streamState }: { streamState?: StreamState } = {}) {\n const noopDispatch: React.Dispatch<StreamAction> = () => {};\n\n return function Wrapper({ children }: { children: React.ReactNode }) {\n const streamProviderProps =\n streamState === undefined\n ? {}\n : { state: streamState, dispatch: noopDispatch };\n\n return (\n <QueryClientProvider client={queryClient}>\n <TamboV1StreamProvider {...streamProviderProps}>\n <TamboV1ThreadInputProvider>{children}</TamboV1ThreadInputProvider>\n </TamboV1StreamProvider>\n </QueryClientProvider>\n );\n };\n }\n\n beforeEach(() => {\n jest.clearAllMocks();\n (global as any).FileReader = jest.fn(() => createSuccessfulFileReader());\n\n queryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n mockMutateAsync.mockResolvedValue({ threadId: \"thread_123\" });\n jest.mocked(useTamboV1SendMessage).mockReturnValue({\n mutateAsync: mockMutateAsync,\n mutate: jest.fn(),\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n isIdle: true,\n isPaused: false,\n status: \"idle\",\n data: undefined,\n variables: undefined,\n failureCount: 0,\n failureReason: null,\n reset: jest.fn(),\n context: undefined,\n submittedAt: 0,\n } as any);\n });\n\n afterEach(() => {\n (global as any).FileReader = originalFileReader;\n });\n\n describe(\"State Management\", () => {\n it(\"initializes with empty value\", () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.value).toBe(\"\");\n });\n\n it(\"updates value via setValue\", () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n act(() => {\n result.current.setValue(\"Hello world\");\n });\n\n expect(result.current.value).toBe(\"Hello world\");\n });\n\n it(\"supports functional updates for setValue\", () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n act(() => {\n result.current.setValue(\"Hello\");\n });\n\n act(() => {\n result.current.setValue((prev) => `${prev} world`);\n });\n\n expect(result.current.value).toBe(\"Hello world\");\n });\n });\n\n describe(\"Submit Behavior\", () => {\n it(\"submits message and clears input on success\", async () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n act(() => {\n result.current.setValue(\"Test message\");\n });\n\n await act(async () => {\n const response = await result.current.submit();\n expect(response.threadId).toBe(\"thread_123\");\n });\n\n // Input should be cleared\n await waitFor(() => {\n expect(result.current.value).toBe(\"\");\n });\n\n // Should have called mutateAsync with correct message format\n expect(mockMutateAsync).toHaveBeenCalledWith({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Test message\" }],\n },\n debug: undefined,\n });\n });\n\n it(\"throws error when submitting empty message\", async () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n await expect(result.current.submit()).rejects.toThrow(\n \"Message cannot be empty\",\n );\n\n expect(mockMutateAsync).not.toHaveBeenCalled();\n });\n\n it(\"throws error when submitting whitespace-only message\", async () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n act(() => {\n result.current.setValue(\" \");\n });\n\n await expect(result.current.submit()).rejects.toThrow(\n \"Message cannot be empty\",\n );\n\n expect(mockMutateAsync).not.toHaveBeenCalled();\n });\n\n it(\"passes debug option to mutation\", async () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n act(() => {\n result.current.setValue(\"Debug message\");\n });\n\n await act(async () => {\n await result.current.submit({ debug: true });\n });\n\n expect(mockMutateAsync).toHaveBeenCalledWith({\n message: {\n role: \"user\",\n content: [{ type: \"text\", text: \"Debug message\" }],\n },\n debug: true,\n });\n });\n\n it(\"submits image-only messages as resource content\", async () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n await act(async () => {\n await result.current.addImage(\n new File([\"image\"], \"photo.png\", { type: \"image/png\" }),\n );\n });\n\n await act(async () => {\n await result.current.submit();\n });\n\n expect(mockMutateAsync).toHaveBeenCalledWith({\n message: {\n role: \"user\",\n content: [\n {\n type: \"resource\",\n resource: {\n blob: \"mock-data\",\n mimeType: \"image/png\",\n name: \"photo.png\",\n },\n },\n ],\n },\n debug: undefined,\n });\n\n await waitFor(() => {\n expect(result.current.images).toEqual([]);\n });\n });\n\n it(\"includes both text and image resource content when both are present\", async () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n act(() => {\n result.current.setValue(\"Test message\");\n });\n\n await act(async () => {\n await result.current.addImage(\n new File([\"image\"], \"photo.png\", { type: \"image/png\" }),\n );\n });\n\n await act(async () => {\n await result.current.submit();\n });\n\n expect(mockMutateAsync).toHaveBeenCalledWith({\n message: {\n role: \"user\",\n content: [\n { type: \"text\", text: \"Test message\" },\n {\n type: \"resource\",\n resource: {\n blob: \"mock-data\",\n mimeType: \"image/png\",\n name: \"photo.png\",\n },\n },\n ],\n },\n debug: undefined,\n });\n });\n });\n\n describe(\"Thread ID Management\", () => {\n it(\"initializes with undefined threadId\", () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.threadId).toBeUndefined();\n });\n\n it(\"allows setting threadId via setThreadId\", () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n act(() => {\n result.current.setThreadId(\"custom_thread_id\");\n });\n\n expect(result.current.threadId).toBe(\"custom_thread_id\");\n });\n\n it(\"does not take ownership of threadId when inheriting stream selection\", async () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper({\n streamState: { threadMap: {}, currentThreadId: \"thread_stream\" },\n }),\n });\n\n expect(result.current.threadId).toBe(\"thread_stream\");\n expect(\n jest.mocked(useTamboV1SendMessage).mock.calls.map((call) => call[0]),\n ).toContain(\"thread_stream\");\n\n act(() => {\n result.current.setValue(\"Test message\");\n });\n\n await act(async () => {\n await result.current.submit();\n });\n\n expect(result.current.threadId).toBe(\"thread_stream\");\n expect(\n jest.mocked(useTamboV1SendMessage).mock.calls.map((call) => call[0]),\n ).not.toContain(\"thread_123\");\n });\n });\n\n describe(\"Image State\", () => {\n it(\"initializes with empty images array\", () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.images).toEqual([]);\n });\n\n it(\"exposes image management functions\", () => {\n const { result } = renderHook(() => useTamboV1ThreadInput(), {\n wrapper: createWrapper(),\n });\n\n expect(typeof result.current.addImage).toBe(\"function\");\n expect(typeof result.current.addImages).toBe(\"function\");\n expect(typeof result.current.removeImage).toBe(\"function\");\n expect(typeof result.current.clearImages).toBe(\"function\");\n });\n });\n\n describe(\"Error handling\", () => {\n it(\"throws error when used outside provider\", () => {\n // Suppress console.error for this test\n const consoleSpy = jest\n .spyOn(console, \"error\")\n .mockImplementation(() => {});\n\n expect(() => {\n renderHook(() => useTamboV1ThreadInput());\n }).toThrow(\n \"useTamboV1ThreadInput must be used within TamboV1ThreadInputProvider\",\n );\n\n consoleSpy.mockRestore();\n });\n });\n});\n"]}
@@ -10,9 +10,11 @@ import type { ThreadListResponse } from "@tambo-ai/typescript-sdk/resources/thre
10
10
  */
11
11
  export interface ThreadListOptions {
12
12
  /**
13
- * Optional context key to filter threads by
13
+ * User key to scope thread list.
14
+ * Only threads owned by this userKey will be returned.
15
+ * If not provided here, uses the userKey from TamboV1Provider context.
14
16
  */
15
- contextKey?: string;
17
+ userKey?: string;
16
18
  /**
17
19
  * Maximum number of threads to return (as string per SDK)
18
20
  */
@@ -35,9 +37,9 @@ export interface ThreadListOptions {
35
37
  * @returns React Query query object with thread list
36
38
  * @example
37
39
  * ```tsx
38
- * function ThreadList({ contextKey }: { contextKey?: string }) {
40
+ * function ThreadList({ userKey }: { userKey?: string }) {
39
41
  * const { data, isLoading, isError } = useTamboV1ThreadList({
40
- * contextKey,
42
+ * userKey,
41
43
  * limit: "20",
42
44
  * });
43
45
  *
@@ -1 +1 @@
1
- {"version":3,"file":"use-tambo-v1-thread-list.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-thread-list.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oDAAoD,CAAC;AAG7F;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,CAAC,EAAE,iBAAiB,EAC/B,YAAY,CAAC,EAAE,IAAI,CACjB,eAAe,CAAC,kBAAkB,CAAC,EACnC,UAAU,GAAG,SAAS,CACvB,6EAUF"}
1
+ {"version":3,"file":"use-tambo-v1-thread-list.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-thread-list.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oDAAoD,CAAC;AAG7F;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,CAAC,EAAE,iBAAiB,EAC/B,YAAY,CAAC,EAAE,IAAI,CACjB,eAAe,CAAC,kBAAkB,CAAC,EACnC,UAAU,GAAG,SAAS,CACvB,6EAUF"}
@@ -22,9 +22,9 @@ const tambo_client_provider_1 = require("../../providers/tambo-client-provider")
22
22
  * @returns React Query query object with thread list
23
23
  * @example
24
24
  * ```tsx
25
- * function ThreadList({ contextKey }: { contextKey?: string }) {
25
+ * function ThreadList({ userKey }: { userKey?: string }) {
26
26
  * const { data, isLoading, isError } = useTamboV1ThreadList({
27
- * contextKey,
27
+ * userKey,
28
28
  * limit: "20",
29
29
  * });
30
30
  *
@@ -1 +1 @@
1
- {"version":3,"file":"use-tambo-v1-thread-list.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-thread-list.ts"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAmEb,oDAeC;AAhFD;;;;GAIG;AAEH,uDAAuE;AAEvE,iFAAuE;AAsBvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,SAAgB,oBAAoB,CAClC,WAA+B,EAC/B,YAGC;IAED,MAAM,MAAM,GAAG,IAAA,sCAAc,GAAE,CAAC;IAEhC,OAAO,IAAA,sBAAQ,EAAC;QACd,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC;QAC7C,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC;QAC3D,SAAS,EAAE,IAAI,EAAE,0BAA0B;QAC3C,GAAG,YAAY;KAChB,CAAC,CAAC;AACL,CAAC","sourcesContent":["\"use client\";\n\n/**\n * Thread List Query Hook for v1 API\n *\n * React Query hook for fetching a list of threads.\n */\n\nimport { useQuery, type UseQueryOptions } from \"@tanstack/react-query\";\nimport type { ThreadListResponse } from \"@tambo-ai/typescript-sdk/resources/threads/threads\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\n\n/**\n * Options for fetching thread list\n */\nexport interface ThreadListOptions {\n /**\n * Optional context key to filter threads by\n */\n contextKey?: string;\n\n /**\n * Maximum number of threads to return (as string per SDK)\n */\n limit?: string;\n\n /**\n * Pagination cursor for fetching next page\n */\n cursor?: string;\n}\n\n/**\n * Hook to fetch a list of threads.\n *\n * Uses React Query for caching and automatic refetching.\n * Threads are considered stale after 5 seconds.\n *\n * Returns the thread list directly from the SDK with no transformation.\n * Each thread includes runStatus, metadata, and all SDK fields.\n * @param listOptions - Filtering and pagination options\n * @param queryOptions - Additional React Query options\n * @returns React Query query object with thread list\n * @example\n * ```tsx\n * function ThreadList({ contextKey }: { contextKey?: string }) {\n * const { data, isLoading, isError } = useTamboV1ThreadList({\n * contextKey,\n * limit: \"20\",\n * });\n *\n * if (isLoading) return <Spinner />;\n * if (isError) return <Error />;\n *\n * return (\n * <ul>\n * {data.threads.map(thread => (\n * <li key={thread.id}>\n * {thread.id} - {thread.runStatus}\n * </li>\n * ))}\n * {data.hasMore && <LoadMoreButton cursor={data.nextCursor} />}\n * </ul>\n * );\n * }\n * ```\n */\nexport function useTamboV1ThreadList(\n listOptions?: ThreadListOptions,\n queryOptions?: Omit<\n UseQueryOptions<ThreadListResponse>,\n \"queryKey\" | \"queryFn\"\n >,\n) {\n const client = useTamboClient();\n\n return useQuery({\n queryKey: [\"v1-threads\", \"list\", listOptions],\n queryFn: async () => await client.threads.list(listOptions),\n staleTime: 5000, // Consider stale after 5s\n ...queryOptions,\n });\n}\n"]}
1
+ {"version":3,"file":"use-tambo-v1-thread-list.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-thread-list.ts"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAqEb,oDAeC;AAlFD;;;;GAIG;AAEH,uDAAuE;AAEvE,iFAAuE;AAwBvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,SAAgB,oBAAoB,CAClC,WAA+B,EAC/B,YAGC;IAED,MAAM,MAAM,GAAG,IAAA,sCAAc,GAAE,CAAC;IAEhC,OAAO,IAAA,sBAAQ,EAAC;QACd,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC;QAC7C,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC;QAC3D,SAAS,EAAE,IAAI,EAAE,0BAA0B;QAC3C,GAAG,YAAY;KAChB,CAAC,CAAC;AACL,CAAC","sourcesContent":["\"use client\";\n\n/**\n * Thread List Query Hook for v1 API\n *\n * React Query hook for fetching a list of threads.\n */\n\nimport { useQuery, type UseQueryOptions } from \"@tanstack/react-query\";\nimport type { ThreadListResponse } from \"@tambo-ai/typescript-sdk/resources/threads/threads\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\n\n/**\n * Options for fetching thread list\n */\nexport interface ThreadListOptions {\n /**\n * User key to scope thread list.\n * Only threads owned by this userKey will be returned.\n * If not provided here, uses the userKey from TamboV1Provider context.\n */\n userKey?: string;\n\n /**\n * Maximum number of threads to return (as string per SDK)\n */\n limit?: string;\n\n /**\n * Pagination cursor for fetching next page\n */\n cursor?: string;\n}\n\n/**\n * Hook to fetch a list of threads.\n *\n * Uses React Query for caching and automatic refetching.\n * Threads are considered stale after 5 seconds.\n *\n * Returns the thread list directly from the SDK with no transformation.\n * Each thread includes runStatus, metadata, and all SDK fields.\n * @param listOptions - Filtering and pagination options\n * @param queryOptions - Additional React Query options\n * @returns React Query query object with thread list\n * @example\n * ```tsx\n * function ThreadList({ userKey }: { userKey?: string }) {\n * const { data, isLoading, isError } = useTamboV1ThreadList({\n * userKey,\n * limit: \"20\",\n * });\n *\n * if (isLoading) return <Spinner />;\n * if (isError) return <Error />;\n *\n * return (\n * <ul>\n * {data.threads.map(thread => (\n * <li key={thread.id}>\n * {thread.id} - {thread.runStatus}\n * </li>\n * ))}\n * {data.hasMore && <LoadMoreButton cursor={data.nextCursor} />}\n * </ul>\n * );\n * }\n * ```\n */\nexport function useTamboV1ThreadList(\n listOptions?: ThreadListOptions,\n queryOptions?: Omit<\n UseQueryOptions<ThreadListResponse>,\n \"queryKey\" | \"queryFn\"\n >,\n) {\n const client = useTamboClient();\n\n return useQuery({\n queryKey: [\"v1-threads\", \"list\", listOptions],\n queryFn: async () => await client.threads.list(listOptions),\n staleTime: 5000, // Consider stale after 5s\n ...queryOptions,\n });\n}\n"]}
@@ -56,14 +56,14 @@ describe("useTamboV1ThreadList", () => {
56
56
  it("passes list options to API", async () => {
57
57
  mockThreadsApi.list.mockResolvedValue(mockThreads);
58
58
  const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_thread_list_1.useTamboV1ThreadList)({
59
- contextKey: "test-context",
59
+ userKey: "test-context",
60
60
  limit: "10",
61
61
  }), { wrapper: TestWrapper });
62
62
  await (0, react_1.waitFor)(() => {
63
63
  expect(result.current.data).toEqual(mockThreads);
64
64
  });
65
65
  expect(mockThreadsApi.list).toHaveBeenCalledWith({
66
- contextKey: "test-context",
66
+ userKey: "test-context",
67
67
  limit: "10",
68
68
  });
69
69
  });
@@ -1 +1 @@
1
- {"version":3,"file":"use-tambo-v1-thread-list.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-thread-list.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport { useTamboV1ThreadList } from \"./use-tambo-v1-thread-list\";\n\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n}));\n\ndescribe(\"useTamboV1ThreadList\", () => {\n const mockThreads = {\n threads: [\n { id: \"thread_1\", runStatus: \"idle\" },\n { id: \"thread_2\", runStatus: \"complete\" },\n ],\n hasMore: false,\n nextCursor: undefined,\n };\n\n const mockThreadsApi = {\n retrieve: jest.fn(),\n list: jest.fn(),\n };\n\n const mockTamboAI = {\n apiKey: \"\",\n threads: mockThreadsApi,\n } as unknown as TamboAI;\n\n let queryClient: QueryClient;\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>\n );\n }\n\n beforeEach(() => {\n queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: false,\n },\n },\n });\n jest.mocked(useTamboClient).mockReturnValue(mockTamboAI);\n mockThreadsApi.list.mockReset();\n });\n\n it(\"fetches thread list\", async () => {\n mockThreadsApi.list.mockResolvedValue(mockThreads);\n\n const { result } = renderHook(() => useTamboV1ThreadList(), {\n wrapper: TestWrapper,\n });\n\n await waitFor(() => {\n expect(result.current.data).toEqual(mockThreads);\n });\n\n expect(mockThreadsApi.list).toHaveBeenCalledWith(undefined);\n });\n\n it(\"passes list options to API\", async () => {\n mockThreadsApi.list.mockResolvedValue(mockThreads);\n\n const { result } = renderHook(\n () =>\n useTamboV1ThreadList({\n contextKey: \"test-context\",\n limit: \"10\",\n }),\n { wrapper: TestWrapper },\n );\n\n await waitFor(() => {\n expect(result.current.data).toEqual(mockThreads);\n });\n\n expect(mockThreadsApi.list).toHaveBeenCalledWith({\n contextKey: \"test-context\",\n limit: \"10\",\n });\n });\n\n it(\"handles loading state\", async () => {\n let resolvePromise: (value: unknown) => void;\n const promise = new Promise((resolve) => {\n resolvePromise = resolve;\n });\n mockThreadsApi.list.mockReturnValue(promise);\n\n const { result } = renderHook(() => useTamboV1ThreadList(), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.isLoading).toBe(true);\n expect(result.current.data).toBeUndefined();\n\n resolvePromise!(mockThreads);\n await waitFor(() => {\n expect(result.current.isLoading).toBe(false);\n });\n });\n\n it(\"handles error state\", async () => {\n const mockError = new Error(\"Failed to fetch threads\");\n mockThreadsApi.list.mockRejectedValue(mockError);\n\n const { result } = renderHook(() => useTamboV1ThreadList(), {\n wrapper: TestWrapper,\n });\n\n await waitFor(() => {\n expect(result.current.isError).toBe(true);\n expect(result.current.error).toBe(mockError);\n });\n });\n});\n"]}
1
+ {"version":3,"file":"use-tambo-v1-thread-list.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-thread-list.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport { useTamboV1ThreadList } from \"./use-tambo-v1-thread-list\";\n\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n}));\n\ndescribe(\"useTamboV1ThreadList\", () => {\n const mockThreads = {\n threads: [\n { id: \"thread_1\", runStatus: \"idle\" },\n { id: \"thread_2\", runStatus: \"complete\" },\n ],\n hasMore: false,\n nextCursor: undefined,\n };\n\n const mockThreadsApi = {\n retrieve: jest.fn(),\n list: jest.fn(),\n };\n\n const mockTamboAI = {\n apiKey: \"\",\n threads: mockThreadsApi,\n } as unknown as TamboAI;\n\n let queryClient: QueryClient;\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>\n );\n }\n\n beforeEach(() => {\n queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: false,\n },\n },\n });\n jest.mocked(useTamboClient).mockReturnValue(mockTamboAI);\n mockThreadsApi.list.mockReset();\n });\n\n it(\"fetches thread list\", async () => {\n mockThreadsApi.list.mockResolvedValue(mockThreads);\n\n const { result } = renderHook(() => useTamboV1ThreadList(), {\n wrapper: TestWrapper,\n });\n\n await waitFor(() => {\n expect(result.current.data).toEqual(mockThreads);\n });\n\n expect(mockThreadsApi.list).toHaveBeenCalledWith(undefined);\n });\n\n it(\"passes list options to API\", async () => {\n mockThreadsApi.list.mockResolvedValue(mockThreads);\n\n const { result } = renderHook(\n () =>\n useTamboV1ThreadList({\n userKey: \"test-context\",\n limit: \"10\",\n }),\n { wrapper: TestWrapper },\n );\n\n await waitFor(() => {\n expect(result.current.data).toEqual(mockThreads);\n });\n\n expect(mockThreadsApi.list).toHaveBeenCalledWith({\n userKey: \"test-context\",\n limit: \"10\",\n });\n });\n\n it(\"handles loading state\", async () => {\n let resolvePromise: (value: unknown) => void;\n const promise = new Promise((resolve) => {\n resolvePromise = resolve;\n });\n mockThreadsApi.list.mockReturnValue(promise);\n\n const { result } = renderHook(() => useTamboV1ThreadList(), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.isLoading).toBe(true);\n expect(result.current.data).toBeUndefined();\n\n resolvePromise!(mockThreads);\n await waitFor(() => {\n expect(result.current.isLoading).toBe(false);\n });\n });\n\n it(\"handles error state\", async () => {\n const mockError = new Error(\"Failed to fetch threads\");\n mockThreadsApi.list.mockRejectedValue(mockError);\n\n const { result } = renderHook(() => useTamboV1ThreadList(), {\n wrapper: TestWrapper,\n });\n\n await waitFor(() => {\n expect(result.current.isError).toBe(true);\n expect(result.current.error).toBe(mockError);\n });\n });\n});\n"]}
@@ -38,10 +38,6 @@ describe("useTamboV1", () => {
38
38
  return (react_2.default.createElement(tambo_registry_provider_1.TamboRegistryContext.Provider, { value: mockRegistry },
39
39
  react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children)));
40
40
  }
41
- function TestWrapperWithThreadId({ children, }) {
42
- return (react_2.default.createElement(tambo_registry_provider_1.TamboRegistryContext.Provider, { value: mockRegistry },
43
- react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, { threadId: "thread_123" }, children)));
44
- }
45
41
  beforeEach(() => {
46
42
  jest.mocked(tambo_client_provider_1.useTamboClient).mockReturnValue(mockTamboClient);
47
43
  jest.clearAllMocks();
@@ -71,7 +67,11 @@ describe("useTamboV1", () => {
71
67
  });
72
68
  it("returns thread state when threadId provided", () => {
73
69
  const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_1.useTamboV1)("thread_123"), {
74
- wrapper: TestWrapperWithThreadId,
70
+ wrapper: TestWrapper,
71
+ });
72
+ // Initialize thread first
73
+ (0, react_1.act)(() => {
74
+ result.current.initThread("thread_123");
75
75
  });
76
76
  expect(result.current.thread).toBeDefined();
77
77
  expect(result.current.thread?.thread.id).toBe("thread_123");
@@ -88,7 +88,11 @@ describe("useTamboV1", () => {
88
88
  });
89
89
  it("returns thread streaming state when thread loaded", () => {
90
90
  const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_1.useTamboV1)("thread_123"), {
91
- wrapper: TestWrapperWithThreadId,
91
+ wrapper: TestWrapper,
92
+ });
93
+ // Initialize thread first
94
+ (0, react_1.act)(() => {
95
+ result.current.initThread("thread_123");
92
96
  });
93
97
  expect(result.current.streamingState.status).toBe("idle");
94
98
  expect(result.current.isIdle).toBe(true);
@@ -140,7 +144,12 @@ describe("useTamboV1", () => {
140
144
  });
141
145
  it("uses current thread when no threadId argument provided", () => {
142
146
  const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_1.useTamboV1)(), {
143
- wrapper: TestWrapperWithThreadId,
147
+ wrapper: TestWrapper,
148
+ });
149
+ // Initialize and switch to a thread
150
+ (0, react_1.act)(() => {
151
+ result.current.initThread("thread_123");
152
+ result.current.switchThread("thread_123");
144
153
  });
145
154
  // Should use current thread from context (thread_123)
146
155
  expect(result.current.currentThreadId).toBe("thread_123");
@@ -1 +1 @@
1
- {"version":3,"file":"use-tambo-v1.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport {\n TamboRegistryContext,\n type TamboRegistryContext as TamboRegistryContextType,\n} from \"../../providers/tambo-registry-provider\";\nimport { TamboV1StreamProvider } from \"../providers/tambo-v1-stream-context\";\nimport { useTamboV1 } from \"./use-tambo-v1\";\n\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n}));\n\ndescribe(\"useTamboV1\", () => {\n const mockTamboClient = {\n apiKey: \"\",\n threads: {},\n } as unknown as TamboAI;\n\n const mockRegistry: TamboRegistryContextType = {\n componentList: {},\n toolRegistry: {},\n componentToolAssociations: {},\n mcpServerInfos: [],\n resources: [],\n resourceSource: null,\n registerComponent: jest.fn(),\n registerTool: jest.fn(),\n registerTools: jest.fn(),\n addToolAssociation: jest.fn(),\n registerMcpServer: jest.fn(),\n registerMcpServers: jest.fn(),\n registerResource: jest.fn(),\n registerResources: jest.fn(),\n registerResourceSource: jest.fn(),\n };\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <TamboRegistryContext.Provider value={mockRegistry}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n );\n }\n\n function TestWrapperWithThreadId({\n children,\n }: {\n children: React.ReactNode;\n }) {\n return (\n <TamboRegistryContext.Provider value={mockRegistry}>\n <TamboV1StreamProvider threadId=\"thread_123\">\n {children}\n </TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n );\n }\n\n beforeEach(() => {\n jest.mocked(useTamboClient).mockReturnValue(mockTamboClient);\n jest.clearAllMocks();\n });\n\n it(\"returns client from useTamboClient\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.client).toBe(mockTamboClient);\n });\n\n it(\"returns registry functions\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.registerComponent).toBe(\n mockRegistry.registerComponent,\n );\n expect(result.current.registerTool).toBe(mockRegistry.registerTool);\n expect(result.current.registerTools).toBe(mockRegistry.registerTools);\n expect(result.current.componentList).toBe(mockRegistry.componentList);\n expect(result.current.toolRegistry).toBe(mockRegistry.toolRegistry);\n });\n\n it(\"returns undefined thread when no threadId provided\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.thread).toBeUndefined();\n expect(result.current.messages).toEqual([]);\n });\n\n it(\"returns thread state when threadId provided\", () => {\n const { result } = renderHook(() => useTamboV1(\"thread_123\"), {\n wrapper: TestWrapperWithThreadId,\n });\n\n expect(result.current.thread).toBeDefined();\n expect(result.current.thread?.thread.id).toBe(\"thread_123\");\n expect(result.current.messages).toEqual([]);\n });\n\n it(\"returns default streaming state when thread not loaded\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.streamingState).toEqual({ status: \"idle\" });\n expect(result.current.isIdle).toBe(true);\n expect(result.current.isStreaming).toBe(false);\n expect(result.current.isWaiting).toBe(false);\n });\n\n it(\"returns thread streaming state when thread loaded\", () => {\n const { result } = renderHook(() => useTamboV1(\"thread_123\"), {\n wrapper: TestWrapperWithThreadId,\n });\n\n expect(result.current.streamingState.status).toBe(\"idle\");\n expect(result.current.isIdle).toBe(true);\n expect(result.current.isStreaming).toBe(false);\n expect(result.current.isWaiting).toBe(false);\n });\n\n it(\"provides dispatch function for advanced usage\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n expect(typeof result.current.dispatch).toBe(\"function\");\n });\n\n it(\"provides thread management functions\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n expect(typeof result.current.initThread).toBe(\"function\");\n expect(typeof result.current.switchThread).toBe(\"function\");\n expect(typeof result.current.startNewThread).toBe(\"function\");\n });\n\n it(\"initializes and switches threads\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n // Initially no current thread\n expect(result.current.currentThreadId).toBeNull();\n expect(result.current.thread).toBeUndefined();\n\n // Initialize a new thread\n act(() => {\n result.current.initThread(\"new_thread_1\");\n });\n\n // Switch to the new thread\n act(() => {\n result.current.switchThread(\"new_thread_1\");\n });\n\n expect(result.current.currentThreadId).toBe(\"new_thread_1\");\n });\n\n it(\"starts new thread with generated ID\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n let newThreadId: string;\n act(() => {\n newThreadId = result.current.startNewThread();\n });\n\n expect(newThreadId!).toMatch(/^temp_/);\n expect(result.current.currentThreadId).toBe(newThreadId!);\n expect(result.current.thread).toBeDefined();\n });\n\n it(\"uses current thread when no threadId argument provided\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapperWithThreadId,\n });\n\n // Should use current thread from context (thread_123)\n expect(result.current.currentThreadId).toBe(\"thread_123\");\n expect(result.current.thread?.thread.id).toBe(\"thread_123\");\n });\n});\n"]}
1
+ {"version":3,"file":"use-tambo-v1.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport {\n TamboRegistryContext,\n type TamboRegistryContext as TamboRegistryContextType,\n} from \"../../providers/tambo-registry-provider\";\nimport { TamboV1StreamProvider } from \"../providers/tambo-v1-stream-context\";\nimport { useTamboV1 } from \"./use-tambo-v1\";\n\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n}));\n\ndescribe(\"useTamboV1\", () => {\n const mockTamboClient = {\n apiKey: \"\",\n threads: {},\n } as unknown as TamboAI;\n\n const mockRegistry: TamboRegistryContextType = {\n componentList: {},\n toolRegistry: {},\n componentToolAssociations: {},\n mcpServerInfos: [],\n resources: [],\n resourceSource: null,\n registerComponent: jest.fn(),\n registerTool: jest.fn(),\n registerTools: jest.fn(),\n addToolAssociation: jest.fn(),\n registerMcpServer: jest.fn(),\n registerMcpServers: jest.fn(),\n registerResource: jest.fn(),\n registerResources: jest.fn(),\n registerResourceSource: jest.fn(),\n };\n\n function TestWrapper({ children }: { children: React.ReactNode }) {\n return (\n <TamboRegistryContext.Provider value={mockRegistry}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryContext.Provider>\n );\n }\n\n beforeEach(() => {\n jest.mocked(useTamboClient).mockReturnValue(mockTamboClient);\n jest.clearAllMocks();\n });\n\n it(\"returns client from useTamboClient\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.client).toBe(mockTamboClient);\n });\n\n it(\"returns registry functions\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.registerComponent).toBe(\n mockRegistry.registerComponent,\n );\n expect(result.current.registerTool).toBe(mockRegistry.registerTool);\n expect(result.current.registerTools).toBe(mockRegistry.registerTools);\n expect(result.current.componentList).toBe(mockRegistry.componentList);\n expect(result.current.toolRegistry).toBe(mockRegistry.toolRegistry);\n });\n\n it(\"returns undefined thread when no threadId provided\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.thread).toBeUndefined();\n expect(result.current.messages).toEqual([]);\n });\n\n it(\"returns thread state when threadId provided\", () => {\n const { result } = renderHook(() => useTamboV1(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n // Initialize thread first\n act(() => {\n result.current.initThread(\"thread_123\");\n });\n\n expect(result.current.thread).toBeDefined();\n expect(result.current.thread?.thread.id).toBe(\"thread_123\");\n expect(result.current.messages).toEqual([]);\n });\n\n it(\"returns default streaming state when thread not loaded\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n expect(result.current.streamingState).toEqual({ status: \"idle\" });\n expect(result.current.isIdle).toBe(true);\n expect(result.current.isStreaming).toBe(false);\n expect(result.current.isWaiting).toBe(false);\n });\n\n it(\"returns thread streaming state when thread loaded\", () => {\n const { result } = renderHook(() => useTamboV1(\"thread_123\"), {\n wrapper: TestWrapper,\n });\n\n // Initialize thread first\n act(() => {\n result.current.initThread(\"thread_123\");\n });\n\n expect(result.current.streamingState.status).toBe(\"idle\");\n expect(result.current.isIdle).toBe(true);\n expect(result.current.isStreaming).toBe(false);\n expect(result.current.isWaiting).toBe(false);\n });\n\n it(\"provides dispatch function for advanced usage\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n expect(typeof result.current.dispatch).toBe(\"function\");\n });\n\n it(\"provides thread management functions\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n expect(typeof result.current.initThread).toBe(\"function\");\n expect(typeof result.current.switchThread).toBe(\"function\");\n expect(typeof result.current.startNewThread).toBe(\"function\");\n });\n\n it(\"initializes and switches threads\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n // Initially no current thread\n expect(result.current.currentThreadId).toBeNull();\n expect(result.current.thread).toBeUndefined();\n\n // Initialize a new thread\n act(() => {\n result.current.initThread(\"new_thread_1\");\n });\n\n // Switch to the new thread\n act(() => {\n result.current.switchThread(\"new_thread_1\");\n });\n\n expect(result.current.currentThreadId).toBe(\"new_thread_1\");\n });\n\n it(\"starts new thread with generated ID\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n let newThreadId: string;\n act(() => {\n newThreadId = result.current.startNewThread();\n });\n\n expect(newThreadId!).toMatch(/^temp_/);\n expect(result.current.currentThreadId).toBe(newThreadId!);\n expect(result.current.thread).toBeDefined();\n });\n\n it(\"uses current thread when no threadId argument provided\", () => {\n const { result } = renderHook(() => useTamboV1(), {\n wrapper: TestWrapper,\n });\n\n // Initialize and switch to a thread\n act(() => {\n result.current.initThread(\"thread_123\");\n result.current.switchThread(\"thread_123\");\n });\n\n // Should use current thread from context (thread_123)\n expect(result.current.currentThreadId).toBe(\"thread_123\");\n expect(result.current.thread?.thread.id).toBe(\"thread_123\");\n });\n});\n"]}