@tambo-ai/react 0.20.2 → 0.20.3
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/hooks/__tests__/use-suggestions.test.js +66 -23
- package/dist/hooks/__tests__/use-suggestions.test.js.map +1 -1
- package/dist/hooks/__tests__/use-tambo-threads.test.d.ts +2 -0
- package/dist/hooks/__tests__/use-tambo-threads.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/use-tambo-threads.test.js +212 -0
- package/dist/hooks/__tests__/use-tambo-threads.test.js.map +1 -0
- package/dist/hooks/react-query-hooks.d.ts +0 -8
- package/dist/hooks/react-query-hooks.d.ts.map +1 -1
- package/dist/hooks/react-query-hooks.js +0 -11
- package/dist/hooks/react-query-hooks.js.map +1 -1
- package/dist/hooks/use-suggestions.js +2 -2
- package/dist/hooks/use-suggestions.js.map +1 -1
- package/dist/hooks/use-tambo-threads.d.ts +13 -11
- package/dist/hooks/use-tambo-threads.d.ts.map +1 -1
- package/dist/hooks/use-tambo-threads.js +3 -1
- package/dist/hooks/use-tambo-threads.js.map +1 -1
- package/dist/providers/__tests__/tambo-thread-provider.test.d.ts +2 -0
- package/dist/providers/__tests__/tambo-thread-provider.test.d.ts.map +1 -0
- package/dist/providers/__tests__/tambo-thread-provider.test.js +279 -0
- package/dist/providers/__tests__/tambo-thread-provider.test.js.map +1 -0
- package/dist/providers/tambo-provider.d.ts +1 -2
- package/dist/providers/tambo-provider.d.ts.map +1 -1
- package/dist/providers/tambo-provider.js.map +1 -1
- package/dist/providers/tambo-registry-provider.js +1 -4
- package/dist/providers/tambo-registry-provider.js.map +1 -1
- package/dist/setupTests.d.ts +3 -0
- package/dist/setupTests.d.ts.map +1 -0
- package/dist/setupTests.js +8 -0
- package/dist/setupTests.js.map +1 -0
- package/dist/testing/tools.d.ts +24 -0
- package/dist/testing/tools.d.ts.map +1 -0
- package/dist/testing/tools.js +31 -0
- package/dist/testing/tools.js.map +1 -0
- package/dist/testing/types.d.ts +4 -0
- package/dist/testing/types.d.ts.map +1 -0
- package/dist/testing/types.js +3 -0
- package/dist/testing/types.js.map +1 -0
- package/esm/hooks/__tests__/use-suggestions.test.js +69 -26
- package/esm/hooks/__tests__/use-suggestions.test.js.map +1 -1
- package/esm/hooks/__tests__/use-tambo-threads.test.d.ts +2 -0
- package/esm/hooks/__tests__/use-tambo-threads.test.d.ts.map +1 -0
- package/esm/hooks/__tests__/use-tambo-threads.test.js +210 -0
- package/esm/hooks/__tests__/use-tambo-threads.test.js.map +1 -0
- package/esm/hooks/react-query-hooks.d.ts +0 -8
- package/esm/hooks/react-query-hooks.d.ts.map +1 -1
- package/esm/hooks/react-query-hooks.js +0 -10
- package/esm/hooks/react-query-hooks.js.map +1 -1
- package/esm/hooks/use-suggestions.js +3 -3
- package/esm/hooks/use-suggestions.js.map +1 -1
- package/esm/hooks/use-tambo-threads.d.ts +13 -11
- package/esm/hooks/use-tambo-threads.d.ts.map +1 -1
- package/esm/hooks/use-tambo-threads.js +3 -1
- package/esm/hooks/use-tambo-threads.js.map +1 -1
- package/esm/providers/__tests__/tambo-thread-provider.test.d.ts +2 -0
- package/esm/providers/__tests__/tambo-thread-provider.test.d.ts.map +1 -0
- package/esm/providers/__tests__/tambo-thread-provider.test.js +274 -0
- package/esm/providers/__tests__/tambo-thread-provider.test.js.map +1 -0
- package/esm/providers/tambo-provider.d.ts +1 -2
- package/esm/providers/tambo-provider.d.ts.map +1 -1
- package/esm/providers/tambo-provider.js.map +1 -1
- package/esm/providers/tambo-registry-provider.js +1 -4
- package/esm/providers/tambo-registry-provider.js.map +1 -1
- package/esm/setupTests.d.ts +3 -0
- package/esm/setupTests.d.ts.map +1 -0
- package/esm/setupTests.js +6 -0
- package/esm/setupTests.js.map +1 -0
- package/esm/testing/tools.d.ts +24 -0
- package/esm/testing/tools.d.ts.map +1 -0
- package/esm/testing/tools.js +25 -0
- package/esm/testing/tools.js.map +1 -0
- package/esm/testing/types.d.ts +4 -0
- package/esm/testing/types.d.ts.map +1 -0
- package/esm/testing/types.js +2 -0
- package/esm/testing/types.js.map +1 -0
- package/package.json +8 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/testing/tools.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,cAAc,EAAE;;;;;;;;;;;;;;;;IA0B/D"}
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
exports.serializeRegistry = serializeRegistry;
|
|
7
|
+
const zod_to_json_schema_1 = __importDefault(require("zod-to-json-schema"));
|
|
8
|
+
/**
|
|
9
|
+
* Serializes the registry for testing purposes
|
|
10
|
+
* @param mockRegistry - The registry to serialize
|
|
11
|
+
* @returns The serialized registry
|
|
12
|
+
*/
|
|
13
|
+
function serializeRegistry(mockRegistry) {
|
|
14
|
+
return mockRegistry.map(({ component: _component, propsSchema, associatedTools, ...componentEntry }) => ({
|
|
15
|
+
...componentEntry,
|
|
16
|
+
props: (0, zod_to_json_schema_1.default)(propsSchema),
|
|
17
|
+
contextTools: associatedTools?.map(({ toolSchema, tool: _tool, ...toolEntry }) => ({
|
|
18
|
+
...toolEntry,
|
|
19
|
+
parameters: toolSchema
|
|
20
|
+
.parameters()
|
|
21
|
+
.items.map((p, index) => ({
|
|
22
|
+
name: `param${index + 1}`,
|
|
23
|
+
schema: (0, zod_to_json_schema_1.default)(p),
|
|
24
|
+
isRequired: true,
|
|
25
|
+
description: p.description,
|
|
26
|
+
type: (0, zod_to_json_schema_1.default)(p).type,
|
|
27
|
+
})),
|
|
28
|
+
})),
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/testing/tools.ts"],"names":[],"mappings":";;;;;AASA,8CA0BC;AAlCD,4EAAiD;AAGjD;;;;GAIG;AACH,SAAgB,iBAAiB,CAAC,YAA8B;IAC9D,OAAO,YAAY,CAAC,GAAG,CACrB,CAAC,EACC,SAAS,EAAE,UAAU,EACrB,WAAW,EACX,eAAe,EACf,GAAG,cAAc,EAClB,EAAE,EAAE,CAAC,CAAC;QACL,GAAG,cAAc;QACjB,KAAK,EAAE,IAAA,4BAAe,EAAC,WAA2B,CAAC;QACnD,YAAY,EAAE,eAAe,EAAE,GAAG,CAChC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;YAC9C,GAAG,SAAS;YACZ,UAAU,EAAE,UAAU;iBACnB,UAAU,EAAE;iBACZ,KAAK,CAAC,GAAG,CAAC,CAAC,CAAe,EAAE,KAAa,EAAE,EAAE,CAAC,CAAC;gBAC9C,IAAI,EAAE,QAAQ,KAAK,GAAG,CAAC,EAAE;gBACzB,MAAM,EAAE,IAAA,4BAAe,EAAC,CAAC,CAAC;gBAC1B,UAAU,EAAE,IAAI;gBAChB,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,IAAI,EAAG,IAAA,4BAAe,EAAC,CAAC,CAAS,CAAC,IAAI;aACvC,CAAC,CAAC;SACN,CAAC,CACH;KACF,CAAC,CACH,CAAC;AACJ,CAAC","sourcesContent":["import { z } from \"zod\";\nimport zodToJsonSchema from \"zod-to-json-schema\";\nimport { TamboComponent } from \"../providers\";\n\n/**\n * Serializes the registry for testing purposes\n * @param mockRegistry - The registry to serialize\n * @returns The serialized registry\n */\nexport function serializeRegistry(mockRegistry: TamboComponent[]) {\n return mockRegistry.map(\n ({\n component: _component,\n propsSchema,\n associatedTools,\n ...componentEntry\n }) => ({\n ...componentEntry,\n props: zodToJsonSchema(propsSchema as z.ZodTypeAny),\n contextTools: associatedTools?.map(\n ({ toolSchema, tool: _tool, ...toolEntry }) => ({\n ...toolEntry,\n parameters: toolSchema\n .parameters()\n .items.map((p: z.ZodTypeAny, index: number) => ({\n name: `param${index + 1}`,\n schema: zodToJsonSchema(p),\n isRequired: true,\n description: p.description,\n type: (zodToJsonSchema(p) as any).type,\n })),\n }),\n ),\n }),\n );\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/testing/types.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,0BAA0B,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/testing/types.ts"],"names":[],"mappings":"","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { DeepPartial } from \"ts-essentials\";\n\nexport type PartialTamboAI = DeepPartial<TamboAI>;\n"]}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { QueryClient } from "@tanstack/react-query";
|
|
2
2
|
import { act, renderHook } from "@testing-library/react";
|
|
3
|
-
import { useTamboClient } from "../../providers/tambo-client-provider";
|
|
3
|
+
import { useTamboClient, useTamboQueryClient, } from "../../providers/tambo-client-provider";
|
|
4
4
|
import { useTambo } from "../../providers/tambo-provider";
|
|
5
|
-
import { useTamboThread } from "../../providers/tambo-thread-provider";
|
|
6
|
-
import { useTamboQuery } from "../react-query-hooks";
|
|
5
|
+
import { useTamboThread, } from "../../providers/tambo-thread-provider";
|
|
6
|
+
import { useTamboMutation, useTamboQuery } from "../react-query-hooks";
|
|
7
7
|
import { useTamboSuggestions } from "../use-suggestions";
|
|
8
8
|
import { useTamboThreadInput } from "../use-thread-input";
|
|
9
9
|
// Mock the required providers
|
|
10
10
|
jest.mock("../../providers/tambo-client-provider", () => ({
|
|
11
11
|
useTamboClient: jest.fn(),
|
|
12
|
-
useTamboQueryClient: jest.fn()
|
|
12
|
+
useTamboQueryClient: jest.fn(),
|
|
13
13
|
}));
|
|
14
14
|
jest.mock("../../providers/tambo-provider", () => ({ useTambo: jest.fn() }));
|
|
15
15
|
jest.mock("../../providers/tambo-thread-provider", () => ({
|
|
@@ -19,12 +19,7 @@ jest.mock("../use-thread-input", () => ({ useTamboThreadInput: jest.fn() }));
|
|
|
19
19
|
// Mock the react-query-hooks
|
|
20
20
|
jest.mock("../react-query-hooks", () => ({
|
|
21
21
|
useTamboQuery: jest.fn(),
|
|
22
|
-
|
|
23
|
-
mutateAsync: mutationFn,
|
|
24
|
-
isLoading: false,
|
|
25
|
-
isError: false,
|
|
26
|
-
error: null,
|
|
27
|
-
})),
|
|
22
|
+
useTamboMutation: jest.fn(),
|
|
28
23
|
}));
|
|
29
24
|
describe("useTamboSuggestions", () => {
|
|
30
25
|
const mockSuggestions = [
|
|
@@ -42,23 +37,39 @@ describe("useTamboSuggestions", () => {
|
|
|
42
37
|
},
|
|
43
38
|
];
|
|
44
39
|
beforeEach(() => {
|
|
45
|
-
jest.
|
|
40
|
+
jest.mocked(useTamboQueryClient).mockReturnValue(new QueryClient());
|
|
41
|
+
jest.mocked(useTamboMutation).mockImplementation(({ mutationFn }) => ({
|
|
42
|
+
mutateAsync: mutationFn,
|
|
43
|
+
isLoading: false,
|
|
44
|
+
isError: false,
|
|
45
|
+
error: null,
|
|
46
|
+
}));
|
|
46
47
|
// Setup default mock implementations
|
|
47
|
-
useTamboClient.mockReturnValue({
|
|
48
|
+
jest.mocked(useTamboClient).mockReturnValue({
|
|
48
49
|
beta: { threads: { suggestions: { generate: jest.fn() } } },
|
|
49
50
|
});
|
|
50
|
-
useTambo.mockReturnValue({
|
|
51
|
-
|
|
51
|
+
jest.mocked(useTambo).mockReturnValue({
|
|
52
|
+
sendThreadMessage: jest.fn(),
|
|
53
|
+
});
|
|
54
|
+
jest.mocked(useTamboThread).mockReturnValue({
|
|
52
55
|
thread: {
|
|
53
56
|
id: "test-thread-id",
|
|
54
57
|
messages: [
|
|
55
|
-
{
|
|
58
|
+
{
|
|
59
|
+
id: "test-message-id",
|
|
60
|
+
role: "hydra",
|
|
61
|
+
content: [{ type: "text", text: "Test message" }],
|
|
62
|
+
},
|
|
56
63
|
],
|
|
57
64
|
},
|
|
58
65
|
});
|
|
59
|
-
useTamboThreadInput.mockReturnValue({
|
|
66
|
+
jest.mocked(useTamboThreadInput).mockReturnValue({
|
|
67
|
+
setValue: jest.fn(),
|
|
68
|
+
value: "",
|
|
69
|
+
submit: jest.fn(),
|
|
70
|
+
});
|
|
60
71
|
// Default query mock returns empty array
|
|
61
|
-
useTamboQuery.mockReturnValue({
|
|
72
|
+
jest.mocked(useTamboQuery).mockReturnValue({
|
|
62
73
|
data: [],
|
|
63
74
|
isLoading: false,
|
|
64
75
|
isError: false,
|
|
@@ -72,11 +83,30 @@ describe("useTamboSuggestions", () => {
|
|
|
72
83
|
});
|
|
73
84
|
it("should generate suggestions when latest message is from Tambo", async () => {
|
|
74
85
|
const mockGenerate = jest.fn().mockResolvedValue(mockSuggestions);
|
|
75
|
-
useTamboClient.mockReturnValue({
|
|
76
|
-
beta: {
|
|
86
|
+
jest.mocked(useTamboClient).mockReturnValue({
|
|
87
|
+
beta: {
|
|
88
|
+
threads: {
|
|
89
|
+
suggestions: {
|
|
90
|
+
generate: mockGenerate,
|
|
91
|
+
list: jest.fn(),
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
jest.mocked(useTamboThread).mockReturnValue({
|
|
97
|
+
thread: {
|
|
98
|
+
id: "test-thread-id",
|
|
99
|
+
messages: [
|
|
100
|
+
{
|
|
101
|
+
id: "test-message-id",
|
|
102
|
+
role: "assistant",
|
|
103
|
+
content: [{ type: "text", text: "Test message" }],
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
77
107
|
});
|
|
78
108
|
// Mock the query result to return the mock suggestions
|
|
79
|
-
useTamboQuery.mockReturnValue({
|
|
109
|
+
jest.mocked(useTamboQuery).mockReturnValue({
|
|
80
110
|
data: mockSuggestions,
|
|
81
111
|
isLoading: false,
|
|
82
112
|
isError: false,
|
|
@@ -93,15 +123,26 @@ describe("useTamboSuggestions", () => {
|
|
|
93
123
|
});
|
|
94
124
|
it("should not generate suggestions when latest message is not from Tambo", async () => {
|
|
95
125
|
const mockGenerate = jest.fn();
|
|
96
|
-
useTamboClient.mockReturnValue({
|
|
97
|
-
beta: {
|
|
126
|
+
jest.mocked(useTamboClient).mockReturnValue({
|
|
127
|
+
beta: {
|
|
128
|
+
threads: {
|
|
129
|
+
suggestions: {
|
|
130
|
+
generate: mockGenerate,
|
|
131
|
+
list: jest.fn(),
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
},
|
|
98
135
|
});
|
|
99
136
|
// Mock the thread to have a non-Tambo message
|
|
100
|
-
useTamboThread.mockReturnValue({
|
|
137
|
+
jest.mocked(useTamboThread).mockReturnValue({
|
|
101
138
|
thread: {
|
|
102
139
|
id: "test-thread-id",
|
|
103
140
|
messages: [
|
|
104
|
-
{
|
|
141
|
+
{
|
|
142
|
+
id: "test-message-id",
|
|
143
|
+
role: "user",
|
|
144
|
+
content: [{ type: "text", text: "Test message" }],
|
|
145
|
+
},
|
|
105
146
|
],
|
|
106
147
|
},
|
|
107
148
|
});
|
|
@@ -115,8 +156,10 @@ describe("useTamboSuggestions", () => {
|
|
|
115
156
|
});
|
|
116
157
|
it("should accept a suggestion and update input value", async () => {
|
|
117
158
|
const mockSetValue = jest.fn();
|
|
118
|
-
useTamboThreadInput.mockReturnValue({
|
|
159
|
+
jest.mocked(useTamboThreadInput).mockReturnValue({
|
|
119
160
|
setValue: mockSetValue,
|
|
161
|
+
value: "",
|
|
162
|
+
submit: jest.fn(),
|
|
120
163
|
});
|
|
121
164
|
const { result } = renderHook(() => useTamboSuggestions());
|
|
122
165
|
await act(async () => {
|
|
@@ -130,7 +173,7 @@ describe("useTamboSuggestions", () => {
|
|
|
130
173
|
});
|
|
131
174
|
it("should accept a suggestion and submit it", async () => {
|
|
132
175
|
const mockSendThreadMessage = jest.fn();
|
|
133
|
-
useTambo.mockReturnValue({
|
|
176
|
+
jest.mocked(useTambo).mockReturnValue({
|
|
134
177
|
sendThreadMessage: mockSendThreadMessage,
|
|
135
178
|
});
|
|
136
179
|
const { result } = renderHook(() => useTamboSuggestions());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-suggestions.test.js","sourceRoot":"","sources":["../../../src/hooks/__tests__/use-suggestions.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient } from \"@tanstack/react-query\";\nimport { act, renderHook } from \"@testing-library/react\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport { useTambo } from \"../../providers/tambo-provider\";\nimport { useTamboThread } from \"../../providers/tambo-thread-provider\";\nimport { useTamboQuery } from \"../react-query-hooks\";\nimport { useTamboSuggestions } from \"../use-suggestions\";\nimport { useTamboThreadInput } from \"../use-thread-input\";\n\n// Mock the required providers\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn().mockReturnValue(new QueryClient()),\n}));\n\njest.mock(\"../../providers/tambo-provider\", () => ({ useTambo: jest.fn() }));\n\njest.mock(\"../../providers/tambo-thread-provider\", () => ({\n useTamboThread: jest.fn(),\n}));\n\njest.mock(\"../use-thread-input\", () => ({ useTamboThreadInput: jest.fn() }));\n\n// Mock the react-query-hooks\njest.mock(\"../react-query-hooks\", () => ({\n useTamboQuery: jest.fn(),\n useTamboMutationResult: jest.fn().mockImplementation(({ mutationFn }) => ({\n mutateAsync: mutationFn,\n isLoading: false,\n isError: false,\n error: null,\n })),\n}));\n\ndescribe(\"useTamboSuggestions\", () => {\n const mockSuggestions: TamboAI.Beta.Threads.Suggestion[] = [\n {\n id: \"suggestion-1\",\n messageId: \"test-message-id\",\n title: \"Test Suggestion 1\",\n detailedSuggestion: \"Test suggestion 1\",\n },\n {\n id: \"suggestion-2\",\n messageId: \"test-message-id\",\n title: \"Test Suggestion 2\",\n detailedSuggestion: \"Test suggestion 2\",\n },\n ];\n\n beforeEach(() => {\n jest.clearAllMocks();\n // Setup default mock implementations\n (useTamboClient as jest.Mock).mockReturnValue({\n beta: { threads: { suggestions: { generate: jest.fn() } } },\n });\n (useTambo as jest.Mock).mockReturnValue({ sendThreadMessage: jest.fn() });\n (useTamboThread as jest.Mock).mockReturnValue({\n thread: {\n id: \"test-thread-id\",\n messages: [\n { id: \"test-message-id\", role: \"hydra\", content: \"Test message\" },\n ],\n },\n });\n (useTamboThreadInput as jest.Mock).mockReturnValue({ setValue: jest.fn() });\n // Default query mock returns empty array\n (useTamboQuery as jest.Mock).mockReturnValue({\n data: [],\n isLoading: false,\n isError: false,\n error: null,\n });\n });\n\n it(\"should initialize with empty suggestions and no selected suggestion\", () => {\n const { result } = renderHook(() => useTamboSuggestions());\n\n expect(result.current.suggestions).toEqual([]);\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n\n it(\"should generate suggestions when latest message is from Tambo\", async () => {\n const mockGenerate = jest.fn().mockResolvedValue(mockSuggestions);\n (useTamboClient as jest.Mock).mockReturnValue({\n beta: { threads: { suggestions: { generate: mockGenerate } } },\n });\n\n // Mock the query result to return the mock suggestions\n (useTamboQuery as jest.Mock).mockReturnValue({\n data: mockSuggestions,\n isLoading: false,\n isError: false,\n error: null,\n });\n\n const { result } = renderHook(() => useTamboSuggestions());\n\n // Wait for the effect to run\n await act(async () => {\n await new Promise((resolve) => setTimeout(resolve, 0));\n });\n\n // Since we're mocking useTamboQuery to return the suggestions directly,\n // the generate function won't be called, so we don't need to check that\n expect(result.current.suggestions).toEqual(mockSuggestions);\n });\n\n it(\"should not generate suggestions when latest message is not from Tambo\", async () => {\n const mockGenerate = jest.fn();\n (useTamboClient as jest.Mock).mockReturnValue({\n beta: { threads: { suggestions: { generate: mockGenerate } } },\n });\n\n // Mock the thread to have a non-Tambo message\n (useTamboThread as jest.Mock).mockReturnValue({\n thread: {\n id: \"test-thread-id\",\n messages: [\n { id: \"test-message-id\", role: \"user\", content: \"Test message\" },\n ],\n },\n });\n\n const { result } = renderHook(() => useTamboSuggestions());\n\n // Wait for the effect to run\n await act(async () => {\n await new Promise((resolve) => setTimeout(resolve, 0));\n });\n\n expect(mockGenerate).not.toHaveBeenCalled();\n expect(result.current.suggestions).toEqual([]);\n });\n\n it(\"should accept a suggestion and update input value\", async () => {\n const mockSetValue = jest.fn();\n (useTamboThreadInput as jest.Mock).mockReturnValue({\n setValue: mockSetValue,\n });\n\n const { result } = renderHook(() => useTamboSuggestions());\n\n await act(async () => {\n await result.current.accept({\n suggestion: mockSuggestions[0],\n shouldSubmit: false,\n });\n });\n\n expect(mockSetValue).toHaveBeenCalledWith(\"Test suggestion 1\");\n expect(result.current.selectedSuggestionId).toBe(\"suggestion-1\");\n });\n\n it(\"should accept a suggestion and submit it\", async () => {\n const mockSendThreadMessage = jest.fn();\n (useTambo as jest.Mock).mockReturnValue({\n sendThreadMessage: mockSendThreadMessage,\n });\n\n const { result } = renderHook(() => useTamboSuggestions());\n\n await act(async () => {\n await result.current.accept({\n suggestion: mockSuggestions[0],\n shouldSubmit: true,\n });\n });\n\n expect(mockSendThreadMessage).toHaveBeenCalledWith(\"Test suggestion 1\", {\n threadId: \"test-thread-id\",\n });\n expect(result.current.selectedSuggestionId).toBe(\"suggestion-1\");\n });\n\n it(\"should throw error when accepting invalid suggestion\", async () => {\n const invalidSuggestion = {\n id: \"invalid-suggestion\",\n messageId: \"test-message-id\",\n title: \"Invalid Suggestion\",\n detailedSuggestion: \"\", // Empty suggestion should fail validation\n };\n\n const { result } = renderHook(() => useTamboSuggestions());\n\n await act(async () => {\n await expect(\n result.current.accept({\n suggestion: invalidSuggestion,\n shouldSubmit: false,\n }),\n ).rejects.toThrow(\"Message cannot be empty\");\n });\n\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"use-suggestions.test.js","sourceRoot":"","sources":["../../../src/hooks/__tests__/use-suggestions.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import type TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, UseQueryResult } from \"@tanstack/react-query\";\nimport { act, renderHook } from \"@testing-library/react\";\nimport { TamboThreadMessage } from \"../../model/generate-component-response\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { TamboContextProps, useTambo } from \"../../providers/tambo-provider\";\nimport {\n TamboThreadContextProps,\n useTamboThread,\n} from \"../../providers/tambo-thread-provider\";\nimport { PartialTamboAI } from \"../../testing/types\";\nimport { useTamboMutation, useTamboQuery } from \"../react-query-hooks\";\nimport { useTamboSuggestions } from \"../use-suggestions\";\nimport { useTamboThreadInput, UseThreadInput } from \"../use-thread-input\";\n\n// Mock the required providers\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(),\n}));\n\njest.mock(\"../../providers/tambo-provider\", () => ({ useTambo: jest.fn() }));\n\njest.mock(\"../../providers/tambo-thread-provider\", () => ({\n useTamboThread: jest.fn(),\n}));\n\njest.mock(\"../use-thread-input\", () => ({ useTamboThreadInput: jest.fn() }));\n\n// Mock the react-query-hooks\njest.mock(\"../react-query-hooks\", () => ({\n useTamboQuery: jest.fn(),\n useTamboMutation: jest.fn(),\n}));\n\ndescribe(\"useTamboSuggestions\", () => {\n const mockSuggestions: TamboAI.Beta.Threads.Suggestion[] = [\n {\n id: \"suggestion-1\",\n messageId: \"test-message-id\",\n title: \"Test Suggestion 1\",\n detailedSuggestion: \"Test suggestion 1\",\n },\n {\n id: \"suggestion-2\",\n messageId: \"test-message-id\",\n title: \"Test Suggestion 2\",\n detailedSuggestion: \"Test suggestion 2\",\n },\n ];\n\n beforeEach(() => {\n jest.mocked(useTamboQueryClient).mockReturnValue(new QueryClient());\n jest.mocked(useTamboMutation).mockImplementation(\n ({ mutationFn }) =>\n ({\n mutateAsync: mutationFn,\n isLoading: false,\n isError: false,\n error: null,\n }) as any,\n );\n // Setup default mock implementations\n jest.mocked(useTamboClient).mockReturnValue({\n beta: { threads: { suggestions: { generate: jest.fn() } } },\n } satisfies PartialTamboAI as any);\n jest.mocked(useTambo).mockReturnValue({\n sendThreadMessage: jest.fn(),\n } satisfies Partial<TamboContextProps> as any);\n jest.mocked(useTamboThread).mockReturnValue({\n thread: {\n id: \"test-thread-id\",\n messages: [\n {\n id: \"test-message-id\",\n role: \"hydra\",\n content: [{ type: \"text\", text: \"Test message\" }],\n },\n ],\n },\n } as TamboThreadContextProps);\n jest.mocked(useTamboThreadInput).mockReturnValue({\n setValue: jest.fn(),\n value: \"\",\n submit: jest.fn(),\n } satisfies Partial<UseThreadInput> as any);\n // Default query mock returns empty array\n jest.mocked(useTamboQuery).mockReturnValue({\n data: [],\n isLoading: false,\n isError: false,\n error: null,\n } satisfies Partial<UseQueryResult<unknown, unknown>> as any);\n });\n\n it(\"should initialize with empty suggestions and no selected suggestion\", () => {\n const { result } = renderHook(() => useTamboSuggestions());\n\n expect(result.current.suggestions).toEqual([]);\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n\n it(\"should generate suggestions when latest message is from Tambo\", async () => {\n const mockGenerate = jest.fn().mockResolvedValue(mockSuggestions);\n jest.mocked(useTamboClient).mockReturnValue({\n beta: {\n threads: {\n suggestions: {\n generate: mockGenerate,\n list: jest.fn(),\n },\n },\n },\n } satisfies PartialTamboAI as any);\n jest.mocked(useTamboThread).mockReturnValue({\n thread: {\n id: \"test-thread-id\",\n messages: [\n {\n id: \"test-message-id\",\n role: \"assistant\",\n content: [{ type: \"text\", text: \"Test message\" }],\n } as TamboThreadMessage,\n ],\n },\n } as TamboThreadContextProps);\n\n // Mock the query result to return the mock suggestions\n jest.mocked(useTamboQuery).mockReturnValue({\n data: mockSuggestions,\n isLoading: false,\n isError: false,\n error: null,\n } as UseQueryResult<unknown, unknown>);\n\n const { result } = renderHook(() => useTamboSuggestions());\n\n // Wait for the effect to run\n await act(async () => {\n await new Promise((resolve) => setTimeout(resolve, 0));\n });\n\n // Since we're mocking useTamboQuery to return the suggestions directly,\n // the generate function won't be called, so we don't need to check that\n expect(result.current.suggestions).toEqual(mockSuggestions);\n });\n\n it(\"should not generate suggestions when latest message is not from Tambo\", async () => {\n const mockGenerate = jest.fn();\n jest.mocked(useTamboClient).mockReturnValue({\n beta: {\n threads: {\n suggestions: {\n generate: mockGenerate,\n list: jest.fn(),\n },\n },\n },\n } satisfies PartialTamboAI as any);\n // Mock the thread to have a non-Tambo message\n jest.mocked(useTamboThread).mockReturnValue({\n thread: {\n id: \"test-thread-id\",\n messages: [\n {\n id: \"test-message-id\",\n role: \"user\",\n content: [{ type: \"text\", text: \"Test message\" }],\n } as TamboThreadMessage,\n ],\n },\n } as TamboThreadContextProps);\n\n const { result } = renderHook(() => useTamboSuggestions());\n\n // Wait for the effect to run\n await act(async () => {\n await new Promise((resolve) => setTimeout(resolve, 0));\n });\n\n expect(mockGenerate).not.toHaveBeenCalled();\n expect(result.current.suggestions).toEqual([]);\n });\n\n it(\"should accept a suggestion and update input value\", async () => {\n const mockSetValue = jest.fn();\n jest.mocked(useTamboThreadInput).mockReturnValue({\n setValue: mockSetValue,\n value: \"\",\n submit: jest.fn(),\n } satisfies Partial<UseThreadInput> as any);\n\n const { result } = renderHook(() => useTamboSuggestions());\n\n await act(async () => {\n await result.current.accept({\n suggestion: mockSuggestions[0],\n shouldSubmit: false,\n });\n });\n\n expect(mockSetValue).toHaveBeenCalledWith(\"Test suggestion 1\");\n expect(result.current.selectedSuggestionId).toBe(\"suggestion-1\");\n });\n\n it(\"should accept a suggestion and submit it\", async () => {\n const mockSendThreadMessage = jest.fn();\n jest.mocked(useTambo).mockReturnValue({\n sendThreadMessage: mockSendThreadMessage,\n } satisfies Partial<TamboContextProps> as any);\n\n const { result } = renderHook(() => useTamboSuggestions());\n\n await act(async () => {\n await result.current.accept({\n suggestion: mockSuggestions[0],\n shouldSubmit: true,\n });\n });\n\n expect(mockSendThreadMessage).toHaveBeenCalledWith(\"Test suggestion 1\", {\n threadId: \"test-thread-id\",\n });\n expect(result.current.selectedSuggestionId).toBe(\"suggestion-1\");\n });\n\n it(\"should throw error when accepting invalid suggestion\", async () => {\n const invalidSuggestion = {\n id: \"invalid-suggestion\",\n messageId: \"test-message-id\",\n title: \"Invalid Suggestion\",\n detailedSuggestion: \"\", // Empty suggestion should fail validation\n };\n\n const { result } = renderHook(() => useTamboSuggestions());\n\n await act(async () => {\n await expect(\n result.current.accept({\n suggestion: invalidSuggestion,\n shouldSubmit: false,\n }),\n ).rejects.toThrow(\"Message cannot be empty\");\n });\n\n expect(result.current.selectedSuggestionId).toBeNull();\n });\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-tambo-threads.test.d.ts","sourceRoot":"","sources":["../../../src/hooks/__tests__/use-tambo-threads.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { QueryClient } from "@tanstack/react-query";
|
|
2
|
+
import { renderHook, waitFor } from "@testing-library/react";
|
|
3
|
+
import { useTamboClient, useTamboQueryClient, } from "../../providers/tambo-client-provider";
|
|
4
|
+
import { useTamboThreadList } from "../use-tambo-threads";
|
|
5
|
+
jest.mock("../../providers/tambo-client-provider", () => ({
|
|
6
|
+
useTamboClient: jest.fn(),
|
|
7
|
+
useTamboQueryClient: jest.fn(),
|
|
8
|
+
}));
|
|
9
|
+
describe("useTamboThreadList", () => {
|
|
10
|
+
const mockThreads = [
|
|
11
|
+
{ id: "thread-1", title: "Thread 1" },
|
|
12
|
+
{ id: "thread-2", title: "Thread 2" },
|
|
13
|
+
];
|
|
14
|
+
const mockProjects = {
|
|
15
|
+
getCurrent: jest.fn(),
|
|
16
|
+
retrieve: jest.fn(),
|
|
17
|
+
delete: jest.fn(),
|
|
18
|
+
};
|
|
19
|
+
const mockThreadsApi = {
|
|
20
|
+
list: jest.fn(),
|
|
21
|
+
messages: {
|
|
22
|
+
list: jest.fn(),
|
|
23
|
+
create: jest.fn(),
|
|
24
|
+
delete: jest.fn(),
|
|
25
|
+
updateComponentState: jest.fn(),
|
|
26
|
+
},
|
|
27
|
+
suggestions: {
|
|
28
|
+
list: jest.fn(),
|
|
29
|
+
generate: jest.fn(),
|
|
30
|
+
},
|
|
31
|
+
create: jest.fn(),
|
|
32
|
+
retrieve: jest.fn(),
|
|
33
|
+
update: jest.fn(),
|
|
34
|
+
delete: jest.fn(),
|
|
35
|
+
advance: jest.fn(),
|
|
36
|
+
advanceById: jest.fn(),
|
|
37
|
+
};
|
|
38
|
+
const mockBeta = {
|
|
39
|
+
projects: mockProjects,
|
|
40
|
+
threads: mockThreadsApi,
|
|
41
|
+
registry: {
|
|
42
|
+
retrieve: jest.fn(),
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
const mockTamboAI = {
|
|
46
|
+
apiKey: "",
|
|
47
|
+
components: {},
|
|
48
|
+
beta: mockBeta,
|
|
49
|
+
};
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
jest.mocked(useTamboQueryClient).mockReturnValue(new QueryClient());
|
|
52
|
+
});
|
|
53
|
+
it("should fetch threads for current project when no projectId is provided", async () => {
|
|
54
|
+
const mockClient = jest.mocked(useTamboClient);
|
|
55
|
+
mockClient.mockReturnValue({
|
|
56
|
+
...mockTamboAI,
|
|
57
|
+
beta: {
|
|
58
|
+
...mockBeta,
|
|
59
|
+
projects: {
|
|
60
|
+
...mockProjects,
|
|
61
|
+
getCurrent: jest.fn().mockResolvedValue({ id: "current-project" }),
|
|
62
|
+
},
|
|
63
|
+
threads: {
|
|
64
|
+
...mockThreadsApi,
|
|
65
|
+
list: jest.fn().mockResolvedValue(mockThreads),
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
const { result } = renderHook(() => useTamboThreadList());
|
|
70
|
+
await waitFor(() => {
|
|
71
|
+
expect(result.current.data).toEqual(mockThreads);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
it("should fetch threads for specified projectId", async () => {
|
|
75
|
+
const mockList = jest.fn().mockResolvedValue(mockThreads);
|
|
76
|
+
const mockClient = jest.mocked(useTamboClient);
|
|
77
|
+
mockClient.mockReturnValue({
|
|
78
|
+
...mockTamboAI,
|
|
79
|
+
beta: {
|
|
80
|
+
...mockBeta,
|
|
81
|
+
threads: {
|
|
82
|
+
...mockThreadsApi,
|
|
83
|
+
list: mockList,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
const { result } = renderHook(() => useTamboThreadList({ projectId: "custom-project" }));
|
|
88
|
+
await waitFor(() => {
|
|
89
|
+
expect(result.current.data).toEqual(mockThreads);
|
|
90
|
+
});
|
|
91
|
+
expect(mockList).toHaveBeenCalledWith("custom-project", {});
|
|
92
|
+
});
|
|
93
|
+
it("should fetch threads with contextKey when provided", async () => {
|
|
94
|
+
const mockList = jest.fn().mockResolvedValue(mockThreads);
|
|
95
|
+
const mockClient = jest.mocked(useTamboClient);
|
|
96
|
+
mockClient.mockReturnValue({
|
|
97
|
+
...mockTamboAI,
|
|
98
|
+
beta: {
|
|
99
|
+
...mockBeta,
|
|
100
|
+
projects: {
|
|
101
|
+
...mockProjects,
|
|
102
|
+
getCurrent: jest.fn().mockResolvedValue({ id: "current-project" }),
|
|
103
|
+
},
|
|
104
|
+
threads: {
|
|
105
|
+
...mockThreadsApi,
|
|
106
|
+
list: mockList,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
const { result } = renderHook(() => useTamboThreadList({ contextKey: "test-context" }));
|
|
111
|
+
await waitFor(() => {
|
|
112
|
+
expect(result.current.data).toEqual(mockThreads);
|
|
113
|
+
});
|
|
114
|
+
expect(mockList).toHaveBeenCalledWith("current-project", {
|
|
115
|
+
contextKey: "test-context",
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
it("should handle loading state", async () => {
|
|
119
|
+
let resolvePromise;
|
|
120
|
+
const promise = new Promise((resolve) => {
|
|
121
|
+
resolvePromise = resolve;
|
|
122
|
+
});
|
|
123
|
+
const mockClient = jest.mocked(useTamboClient);
|
|
124
|
+
mockClient.mockReturnValue({
|
|
125
|
+
...mockTamboAI,
|
|
126
|
+
beta: {
|
|
127
|
+
...mockBeta,
|
|
128
|
+
projects: {
|
|
129
|
+
...mockProjects,
|
|
130
|
+
getCurrent: jest.fn().mockResolvedValue({ id: "current-project" }),
|
|
131
|
+
},
|
|
132
|
+
threads: {
|
|
133
|
+
...mockThreadsApi,
|
|
134
|
+
list: jest.fn().mockReturnValue(promise),
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
const { result } = renderHook(() => useTamboThreadList({}, { retry: false }));
|
|
139
|
+
expect(result.current).toMatchInlineSnapshot(`
|
|
140
|
+
{
|
|
141
|
+
"data": null,
|
|
142
|
+
"dataUpdatedAt": 0,
|
|
143
|
+
"error": null,
|
|
144
|
+
"errorUpdateCount": 0,
|
|
145
|
+
"errorUpdatedAt": 0,
|
|
146
|
+
"failureCount": 0,
|
|
147
|
+
"failureReason": null,
|
|
148
|
+
"fetchStatus": "fetching",
|
|
149
|
+
"isError": false,
|
|
150
|
+
"isFetched": false,
|
|
151
|
+
"isFetchedAfterMount": false,
|
|
152
|
+
"isFetching": true,
|
|
153
|
+
"isInitialLoading": true,
|
|
154
|
+
"isLoading": true,
|
|
155
|
+
"isLoadingError": false,
|
|
156
|
+
"isPaused": false,
|
|
157
|
+
"isPending": true,
|
|
158
|
+
"isPlaceholderData": false,
|
|
159
|
+
"isRefetchError": false,
|
|
160
|
+
"isRefetching": false,
|
|
161
|
+
"isStale": true,
|
|
162
|
+
"isSuccess": false,
|
|
163
|
+
"promise": Promise {
|
|
164
|
+
"reason": [Error: experimental_prefetchInRender feature flag is not enabled],
|
|
165
|
+
"status": "rejected",
|
|
166
|
+
},
|
|
167
|
+
"refetch": [Function],
|
|
168
|
+
"status": "pending",
|
|
169
|
+
}
|
|
170
|
+
`);
|
|
171
|
+
expect(result.current.isLoading).toBe(true);
|
|
172
|
+
expect(result.current.data).toBeNull();
|
|
173
|
+
resolvePromise(mockThreads);
|
|
174
|
+
await waitFor(() => {
|
|
175
|
+
expect(result.current.isLoading).toBe(false);
|
|
176
|
+
});
|
|
177
|
+
await waitFor(() => {
|
|
178
|
+
expect(result.current.isLoading).toBe(false);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
it("should handle error state", async () => {
|
|
182
|
+
const mockError = new Error("Failed to fetch threads");
|
|
183
|
+
const mockClient = jest.mocked(useTamboClient);
|
|
184
|
+
mockClient.mockReturnValue({
|
|
185
|
+
...mockTamboAI,
|
|
186
|
+
beta: {
|
|
187
|
+
...mockBeta,
|
|
188
|
+
projects: {
|
|
189
|
+
...mockProjects,
|
|
190
|
+
getCurrent: jest.fn().mockResolvedValue({ id: "current-project" }),
|
|
191
|
+
},
|
|
192
|
+
threads: {
|
|
193
|
+
...mockThreadsApi,
|
|
194
|
+
list: jest.fn().mockImplementation(async () => {
|
|
195
|
+
// console.log("Mocking error", mockCount++);
|
|
196
|
+
throw mockError;
|
|
197
|
+
}),
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
const { result } = renderHook(() => useTamboThreadList({}, { retry: false }));
|
|
202
|
+
await waitFor(() => {
|
|
203
|
+
const { isLoading, error, isError } = result.current;
|
|
204
|
+
expect(isLoading).toBe(false);
|
|
205
|
+
expect(isError).toBe(true);
|
|
206
|
+
expect(error).toBe(mockError);
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
//# sourceMappingURL=use-tambo-threads.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-tambo-threads.test.js","sourceRoot":"","sources":["../../../src/hooks/__tests__/use-tambo-threads.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient } from \"@tanstack/react-query\";\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport { DeepPartial } from \"ts-essentials\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { PartialTamboAI } from \"../../testing/types\";\nimport { useTamboThreadList } from \"../use-tambo-threads\";\n\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(),\n}));\n\ndescribe(\"useTamboThreadList\", () => {\n const mockThreads = [\n { id: \"thread-1\", title: \"Thread 1\" },\n { id: \"thread-2\", title: \"Thread 2\" },\n ];\n\n const mockProjects = {\n getCurrent: jest.fn(),\n retrieve: jest.fn(),\n delete: jest.fn(),\n } satisfies Partial<TamboAI[\"beta\"][\"projects\"]>;\n\n const mockThreadsApi = {\n list: jest.fn(),\n messages: {\n list: jest.fn(),\n create: jest.fn(),\n delete: jest.fn(),\n updateComponentState: jest.fn(),\n },\n suggestions: {\n list: jest.fn(),\n generate: jest.fn(),\n },\n create: jest.fn(),\n retrieve: jest.fn(),\n update: jest.fn(),\n delete: jest.fn(),\n advance: jest.fn(),\n advanceById: jest.fn(),\n } satisfies DeepPartial<TamboAI[\"beta\"][\"threads\"]>;\n\n const mockBeta = {\n projects: mockProjects,\n threads: mockThreadsApi,\n registry: {\n retrieve: jest.fn(),\n },\n } satisfies PartialTamboAI[\"beta\"];\n\n const mockTamboAI = {\n apiKey: \"\",\n components: {},\n beta: mockBeta,\n } satisfies PartialTamboAI as unknown as TamboAI;\n\n beforeEach(() => {\n jest.mocked(useTamboQueryClient).mockReturnValue(new QueryClient());\n });\n\n it(\"should fetch threads for current project when no projectId is provided\", async () => {\n const mockClient = jest.mocked(useTamboClient);\n mockClient.mockReturnValue({\n ...mockTamboAI,\n beta: {\n ...mockBeta,\n projects: {\n ...mockProjects,\n getCurrent: jest.fn().mockResolvedValue({ id: \"current-project\" }),\n },\n threads: {\n ...mockThreadsApi,\n list: jest.fn().mockResolvedValue(mockThreads),\n },\n },\n } satisfies PartialTamboAI as any);\n\n const { result } = renderHook(() => useTamboThreadList());\n\n await waitFor(() => {\n expect(result.current.data).toEqual(mockThreads);\n });\n });\n\n it(\"should fetch threads for specified projectId\", async () => {\n const mockList = jest.fn().mockResolvedValue(mockThreads);\n const mockClient = jest.mocked(useTamboClient);\n mockClient.mockReturnValue({\n ...mockTamboAI,\n beta: {\n ...mockBeta,\n threads: {\n ...mockThreadsApi,\n list: mockList,\n },\n },\n } satisfies PartialTamboAI as any);\n\n const { result } = renderHook(() =>\n useTamboThreadList({ projectId: \"custom-project\" }),\n );\n\n await waitFor(() => {\n expect(result.current.data).toEqual(mockThreads);\n });\n\n expect(mockList).toHaveBeenCalledWith(\"custom-project\", {});\n });\n\n it(\"should fetch threads with contextKey when provided\", async () => {\n const mockList = jest.fn().mockResolvedValue(mockThreads);\n const mockClient = jest.mocked(useTamboClient);\n mockClient.mockReturnValue({\n ...mockTamboAI,\n beta: {\n ...mockBeta,\n projects: {\n ...mockProjects,\n getCurrent: jest.fn().mockResolvedValue({ id: \"current-project\" }),\n },\n threads: {\n ...mockThreadsApi,\n list: mockList,\n },\n },\n } satisfies PartialTamboAI as any);\n\n const { result } = renderHook(() =>\n useTamboThreadList({ contextKey: \"test-context\" }),\n );\n\n await waitFor(() => {\n expect(result.current.data).toEqual(mockThreads);\n });\n\n expect(mockList).toHaveBeenCalledWith(\"current-project\", {\n contextKey: \"test-context\",\n });\n });\n\n it(\"should handle loading state\", async () => {\n let resolvePromise: (value: any) => void;\n const promise = new Promise((resolve) => {\n resolvePromise = resolve;\n });\n\n const mockClient = jest.mocked(useTamboClient);\n mockClient.mockReturnValue({\n ...mockTamboAI,\n beta: {\n ...mockBeta,\n projects: {\n ...mockProjects,\n getCurrent: jest.fn().mockResolvedValue({ id: \"current-project\" }),\n },\n threads: {\n ...mockThreadsApi,\n list: jest.fn().mockReturnValue(promise),\n },\n },\n } satisfies PartialTamboAI as any);\n\n const { result } = renderHook(() =>\n useTamboThreadList({}, { retry: false }),\n );\n\n expect(result.current).toMatchInlineSnapshot(`\n {\n \"data\": null,\n \"dataUpdatedAt\": 0,\n \"error\": null,\n \"errorUpdateCount\": 0,\n \"errorUpdatedAt\": 0,\n \"failureCount\": 0,\n \"failureReason\": null,\n \"fetchStatus\": \"fetching\",\n \"isError\": false,\n \"isFetched\": false,\n \"isFetchedAfterMount\": false,\n \"isFetching\": true,\n \"isInitialLoading\": true,\n \"isLoading\": true,\n \"isLoadingError\": false,\n \"isPaused\": false,\n \"isPending\": true,\n \"isPlaceholderData\": false,\n \"isRefetchError\": false,\n \"isRefetching\": false,\n \"isStale\": true,\n \"isSuccess\": false,\n \"promise\": Promise {\n \"reason\": [Error: experimental_prefetchInRender feature flag is not enabled],\n \"status\": \"rejected\",\n },\n \"refetch\": [Function],\n \"status\": \"pending\",\n }\n `);\n expect(result.current.isLoading).toBe(true);\n expect(result.current.data).toBeNull();\n\n resolvePromise!(mockThreads);\n await waitFor(() => {\n expect(result.current.isLoading).toBe(false);\n });\n await waitFor(() => {\n expect(result.current.isLoading).toBe(false);\n });\n });\n\n it(\"should handle error state\", async () => {\n const mockError = new Error(\"Failed to fetch threads\");\n const mockClient = jest.mocked(useTamboClient);\n mockClient.mockReturnValue({\n ...mockTamboAI,\n beta: {\n ...mockBeta,\n projects: {\n ...mockProjects,\n getCurrent: jest.fn().mockResolvedValue({ id: \"current-project\" }),\n },\n threads: {\n ...mockThreadsApi,\n list: jest.fn().mockImplementation(async () => {\n // console.log(\"Mocking error\", mockCount++);\n throw mockError;\n }),\n },\n },\n } satisfies PartialTamboAI as any);\n\n const { result } = renderHook(() =>\n useTamboThreadList({}, { retry: false }),\n );\n\n await waitFor(() => {\n const { isLoading, error, isError } = result.current;\n expect(isLoading).toBe(false);\n expect(isError).toBe(true);\n expect(error).toBe(mockError);\n });\n });\n});\n"]}
|
|
@@ -19,14 +19,6 @@ export declare function useTamboMutation<TData = unknown, TError = Error, TVaria
|
|
|
19
19
|
* Type alias for the result of a mutation.
|
|
20
20
|
*/
|
|
21
21
|
export type UseTamboMutationResult<TData = unknown, TError = Error, TVariables = void, TContext = unknown> = UseMutationResult<TData, TError, TVariables, TContext>;
|
|
22
|
-
/**
|
|
23
|
-
* Hook for creating a mutation with the tambo query client.
|
|
24
|
-
*
|
|
25
|
-
* Use this instead of useMutation from @tanstack/react-query
|
|
26
|
-
* @param options - The options for the mutation, same as useMutation from @tanstack/react-query
|
|
27
|
-
* @returns The mutation result
|
|
28
|
-
*/
|
|
29
|
-
export declare function useTamboMutationResult<TData = unknown, TError = Error, TVariables = void, TContext = unknown>(options: UseMutationOptions<TData, TError, TVariables, TContext>): UseMutationResult<TData, TError, TVariables, TContext>;
|
|
30
22
|
/**
|
|
31
23
|
* Type alias for the result of a query.
|
|
32
24
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-query-hooks.d.ts","sourceRoot":"","sources":["../../src/hooks/react-query-hooks.ts"],"names":[],"mappings":"AACA,OAAO,EACL,QAAQ,EAER,kBAAkB,EAClB,iBAAiB,EAEjB,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAG/B;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,YAAY,GAAG,OAAO,EACtB,MAAM,GAAG,KAAK,EACd,KAAK,GAAG,YAAY,EACpB,SAAS,SAAS,QAAQ,GAAG,QAAQ,EACrC,OAAO,EAAE,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,iCAGjE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,GAAG,OAAO,EACf,MAAM,GAAG,KAAK,EACd,UAAU,GAAG,IAAI,EACjB,QAAQ,GAAG,OAAO,EAClB,OAAO,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,0DAGjE;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,CAChC,KAAK,GAAG,OAAO,EACf,MAAM,GAAG,KAAK,EACd,UAAU,GAAG,IAAI,EACjB,QAAQ,GAAG,OAAO,IAChB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AAE3D
|
|
1
|
+
{"version":3,"file":"react-query-hooks.d.ts","sourceRoot":"","sources":["../../src/hooks/react-query-hooks.ts"],"names":[],"mappings":"AACA,OAAO,EACL,QAAQ,EAER,kBAAkB,EAClB,iBAAiB,EAEjB,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAG/B;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,YAAY,GAAG,OAAO,EACtB,MAAM,GAAG,KAAK,EACd,KAAK,GAAG,YAAY,EACpB,SAAS,SAAS,QAAQ,GAAG,QAAQ,EACrC,OAAO,EAAE,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,iCAGjE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,GAAG,OAAO,EACf,MAAM,GAAG,KAAK,EACd,UAAU,GAAG,IAAI,EACjB,QAAQ,GAAG,OAAO,EAClB,OAAO,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,0DAGjE;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,CAChC,KAAK,GAAG,OAAO,EACf,MAAM,GAAG,KAAK,EACd,UAAU,GAAG,IAAI,EACjB,QAAQ,GAAG,OAAO,IAChB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAC7B,KAAK,GAAG,OAAO,EACf,MAAM,GAAG,KAAK,IACZ,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC"}
|
|
@@ -23,14 +23,4 @@ export function useTamboMutation(options) {
|
|
|
23
23
|
const queryClient = useTamboQueryClient();
|
|
24
24
|
return useMutation(options, queryClient);
|
|
25
25
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Hook for creating a mutation with the tambo query client.
|
|
28
|
-
*
|
|
29
|
-
* Use this instead of useMutation from @tanstack/react-query
|
|
30
|
-
* @param options - The options for the mutation, same as useMutation from @tanstack/react-query
|
|
31
|
-
* @returns The mutation result
|
|
32
|
-
*/
|
|
33
|
-
export function useTamboMutationResult(options) {
|
|
34
|
-
return useTamboMutation(options);
|
|
35
|
-
}
|
|
36
26
|
//# sourceMappingURL=react-query-hooks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-query-hooks.js","sourceRoot":"","sources":["../../src/hooks/react-query-hooks.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAEL,WAAW,EAGX,QAAQ,GAGT,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAEzE;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAK3B,OAAgE;IAChE,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;IAC1C,OAAO,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAK9B,OAAgE;IAChE,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;IAC1C,OAAO,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AAC3C,CAAC
|
|
1
|
+
{"version":3,"file":"react-query-hooks.js","sourceRoot":"","sources":["../../src/hooks/react-query-hooks.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAEL,WAAW,EAGX,QAAQ,GAGT,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAEzE;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAK3B,OAAgE;IAChE,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;IAC1C,OAAO,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAK9B,OAAgE;IAChE,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;IAC1C,OAAO,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AAC3C,CAAC","sourcesContent":["// tamboHooks.ts\nimport {\n QueryKey,\n useMutation,\n UseMutationOptions,\n UseMutationResult,\n useQuery,\n UseQueryOptions,\n UseQueryResult,\n} from \"@tanstack/react-query\";\nimport { useTamboQueryClient } from \"../providers/tambo-client-provider\";\n\n/**\n * Wrapper around useQuery that uses the internal tambo query client.\n *\n * Use this instead of useQuery from @tanstack/react-query\n * @param options - The options for the query, same as useQuery from @tanstack/react-query\n * @returns The query result\n */\nexport function useTamboQuery<\n TQueryFnData = unknown,\n TError = Error,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>) {\n const queryClient = useTamboQueryClient();\n return useQuery(options, queryClient);\n}\n\n/**\n * Wrapper around useMutation that uses the internal tambo query client.\n *\n * Use this instead of useMutation from @tanstack/react-query\n * @param options - The options for the mutation, same as useMutation from @tanstack/react-query\n * @returns The mutation result\n */\nexport function useTamboMutation<\n TData = unknown,\n TError = Error,\n TVariables = void,\n TContext = unknown,\n>(options: UseMutationOptions<TData, TError, TVariables, TContext>) {\n const queryClient = useTamboQueryClient();\n return useMutation(options, queryClient);\n}\n\n/**\n * Type alias for the result of a mutation.\n */\nexport type UseTamboMutationResult<\n TData = unknown,\n TError = Error,\n TVariables = void,\n TContext = unknown,\n> = UseMutationResult<TData, TError, TVariables, TContext>;\n\n/**\n * Type alias for the result of a query.\n */\nexport type UseTamboQueryResult<\n TData = unknown,\n TError = Error,\n> = UseQueryResult<TData, TError>;\n"]}
|
|
@@ -6,7 +6,7 @@ import { useTamboRegistry } from "../providers/tambo-registry-provider";
|
|
|
6
6
|
import { useTamboThread } from "../providers/tambo-thread-provider";
|
|
7
7
|
import { combineMutationResults, } from "../util/query-utils";
|
|
8
8
|
import { getAvailableComponents } from "../util/registry";
|
|
9
|
-
import {
|
|
9
|
+
import { useTamboMutation, useTamboQuery, } from "./react-query-hooks";
|
|
10
10
|
import { INPUT_ERROR_MESSAGES, useTamboThreadInput } from "./use-thread-input";
|
|
11
11
|
/**
|
|
12
12
|
* Hook for managing Tambo AI suggestions in a thread
|
|
@@ -53,7 +53,7 @@ export function useTamboSuggestions(options = {}) {
|
|
|
53
53
|
retry: false,
|
|
54
54
|
});
|
|
55
55
|
// Accept suggestion mutation
|
|
56
|
-
const acceptMutationState =
|
|
56
|
+
const acceptMutationState = useTamboMutation({
|
|
57
57
|
mutationFn: async ({ suggestion, shouldSubmit = false }) => {
|
|
58
58
|
const validation = validateInput(suggestion.detailedSuggestion);
|
|
59
59
|
if (!validation.isValid) {
|
|
@@ -74,7 +74,7 @@ export function useTamboSuggestions(options = {}) {
|
|
|
74
74
|
},
|
|
75
75
|
});
|
|
76
76
|
// Generate suggestions mutation
|
|
77
|
-
const generateMutationState =
|
|
77
|
+
const generateMutationState = useTamboMutation({
|
|
78
78
|
mutationFn: async (abortController) => {
|
|
79
79
|
if (!latestMessageId || !isLatestFromTambo) {
|
|
80
80
|
return undefined;
|