@tambo-ai/react 0.46.5 → 0.48.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 (97) hide show
  1. package/dist/context-helpers/__tests__/context-helpers-provider.test.js +9 -5
  2. package/dist/context-helpers/__tests__/context-helpers-provider.test.js.map +1 -1
  3. package/dist/context-helpers/current-interactables-context-helper.d.ts +28 -0
  4. package/dist/context-helpers/current-interactables-context-helper.d.ts.map +1 -0
  5. package/dist/context-helpers/current-interactables-context-helper.js +61 -0
  6. package/dist/context-helpers/current-interactables-context-helper.js.map +1 -0
  7. package/dist/context-helpers/index.d.ts +1 -0
  8. package/dist/context-helpers/index.d.ts.map +1 -1
  9. package/dist/context-helpers/index.js +1 -0
  10. package/dist/context-helpers/index.js.map +1 -1
  11. package/dist/context-helpers/registry.d.ts +1 -22
  12. package/dist/context-helpers/registry.d.ts.map +1 -1
  13. package/dist/context-helpers/registry.js +1 -35
  14. package/dist/context-helpers/registry.js.map +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +2 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/mcp/__tests__/tambo-mcp-provider.test.d.ts +2 -0
  20. package/dist/mcp/__tests__/tambo-mcp-provider.test.d.ts.map +1 -0
  21. package/dist/mcp/__tests__/tambo-mcp-provider.test.js +115 -0
  22. package/dist/mcp/__tests__/tambo-mcp-provider.test.js.map +1 -0
  23. package/dist/mcp/tambo-mcp-provider.d.ts +6 -0
  24. package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
  25. package/dist/mcp/tambo-mcp-provider.js +25 -2
  26. package/dist/mcp/tambo-mcp-provider.js.map +1 -1
  27. package/dist/providers/__tests__/tambo-context-helpers-provider.test.js +0 -34
  28. package/dist/providers/__tests__/tambo-context-helpers-provider.test.js.map +1 -1
  29. package/dist/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.d.ts +2 -0
  30. package/dist/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.d.ts.map +1 -0
  31. package/dist/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.js +339 -0
  32. package/dist/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.js.map +1 -0
  33. package/dist/providers/__tests__/tambo-interactables-additional-context.test.d.ts +2 -0
  34. package/dist/providers/__tests__/tambo-interactables-additional-context.test.d.ts.map +1 -0
  35. package/dist/providers/__tests__/tambo-interactables-additional-context.test.js +299 -0
  36. package/dist/providers/__tests__/tambo-interactables-additional-context.test.js.map +1 -0
  37. package/dist/providers/tambo-context-helpers-provider.d.ts +1 -1
  38. package/dist/providers/tambo-context-helpers-provider.d.ts.map +1 -1
  39. package/dist/providers/tambo-context-helpers-provider.js +33 -21
  40. package/dist/providers/tambo-context-helpers-provider.js.map +1 -1
  41. package/dist/providers/tambo-interactable-provider.d.ts +20 -0
  42. package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
  43. package/dist/providers/tambo-interactable-provider.js +117 -85
  44. package/dist/providers/tambo-interactable-provider.js.map +1 -1
  45. package/esm/context-helpers/__tests__/context-helpers-provider.test.js +10 -6
  46. package/esm/context-helpers/__tests__/context-helpers-provider.test.js.map +1 -1
  47. package/esm/context-helpers/current-interactables-context-helper.d.ts +28 -0
  48. package/esm/context-helpers/current-interactables-context-helper.d.ts.map +1 -0
  49. package/esm/context-helpers/current-interactables-context-helper.js +56 -0
  50. package/esm/context-helpers/current-interactables-context-helper.js.map +1 -0
  51. package/esm/context-helpers/index.d.ts +1 -0
  52. package/esm/context-helpers/index.d.ts.map +1 -1
  53. package/esm/context-helpers/index.js +1 -0
  54. package/esm/context-helpers/index.js.map +1 -1
  55. package/esm/context-helpers/registry.d.ts +1 -22
  56. package/esm/context-helpers/registry.d.ts.map +1 -1
  57. package/esm/context-helpers/registry.js +1 -31
  58. package/esm/context-helpers/registry.js.map +1 -1
  59. package/esm/index.d.ts +1 -1
  60. package/esm/index.d.ts.map +1 -1
  61. package/esm/index.js +1 -1
  62. package/esm/index.js.map +1 -1
  63. package/esm/mcp/__tests__/tambo-mcp-provider.test.d.ts +2 -0
  64. package/esm/mcp/__tests__/tambo-mcp-provider.test.d.ts.map +1 -0
  65. package/esm/mcp/__tests__/tambo-mcp-provider.test.js +113 -0
  66. package/esm/mcp/__tests__/tambo-mcp-provider.test.js.map +1 -0
  67. package/esm/mcp/tambo-mcp-provider.d.ts +6 -0
  68. package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
  69. package/esm/mcp/tambo-mcp-provider.js +24 -2
  70. package/esm/mcp/tambo-mcp-provider.js.map +1 -1
  71. package/esm/providers/__tests__/tambo-context-helpers-provider.test.js +0 -34
  72. package/esm/providers/__tests__/tambo-context-helpers-provider.test.js.map +1 -1
  73. package/esm/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.d.ts +2 -0
  74. package/esm/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.d.ts.map +1 -0
  75. package/esm/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.js +334 -0
  76. package/esm/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.js.map +1 -0
  77. package/esm/providers/__tests__/tambo-interactables-additional-context.test.d.ts +2 -0
  78. package/esm/providers/__tests__/tambo-interactables-additional-context.test.d.ts.map +1 -0
  79. package/esm/providers/__tests__/tambo-interactables-additional-context.test.js +294 -0
  80. package/esm/providers/__tests__/tambo-interactables-additional-context.test.js.map +1 -0
  81. package/esm/providers/tambo-context-helpers-provider.d.ts +1 -1
  82. package/esm/providers/tambo-context-helpers-provider.d.ts.map +1 -1
  83. package/esm/providers/tambo-context-helpers-provider.js +35 -23
  84. package/esm/providers/tambo-context-helpers-provider.js.map +1 -1
  85. package/esm/providers/tambo-interactable-provider.d.ts +20 -0
  86. package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
  87. package/esm/providers/tambo-interactable-provider.js +115 -84
  88. package/esm/providers/tambo-interactable-provider.js.map +1 -1
  89. package/package.json +8 -8
  90. package/dist/mcp/mcp-tools-client.d.ts +0 -96
  91. package/dist/mcp/mcp-tools-client.d.ts.map +0 -1
  92. package/dist/mcp/mcp-tools-client.js +0 -178
  93. package/dist/mcp/mcp-tools-client.js.map +0 -1
  94. package/esm/mcp/mcp-tools-client.d.ts +0 -96
  95. package/esm/mcp/mcp-tools-client.d.ts.map +0 -1
  96. package/esm/mcp/mcp-tools-client.js +0 -174
  97. package/esm/mcp/mcp-tools-client.js.map +0 -1
@@ -0,0 +1,294 @@
1
+ import { render, waitFor } from "@testing-library/react";
2
+ import React from "react";
3
+ import { z } from "zod";
4
+ import { useTamboContextHelpers, TamboContextHelpersProvider, } from "../tambo-context-helpers-provider";
5
+ import { TamboInteractableProvider, useCurrentInteractablesSnapshot, } from "../tambo-interactable-provider";
6
+ import { TamboStubProvider } from "../tambo-stubs";
7
+ import { withTamboInteractable } from "../hoc/with-tambo-interactable";
8
+ function wrapperWithProviders(children) {
9
+ const thread = {
10
+ id: "t-1",
11
+ projectId: "p-1",
12
+ createdAt: new Date().toISOString(),
13
+ updatedAt: new Date().toISOString(),
14
+ messages: [],
15
+ metadata: {},
16
+ };
17
+ return (React.createElement(TamboStubProvider, { thread: thread, registerTool: () => { }, registerTools: () => { }, registerComponent: () => { }, addToolAssociation: () => { } },
18
+ React.createElement(TamboContextHelpersProvider, null, children)));
19
+ }
20
+ describe("Interactables AdditionalContext (provider-based)", () => {
21
+ test("registers default helper and returns payload with description and components", async () => {
22
+ const Note = ({ title }) => React.createElement("div", null, title);
23
+ const InteractableNote = withTamboInteractable(Note, {
24
+ componentName: "Note",
25
+ description: "A note",
26
+ propsSchema: z.object({ title: z.string() }),
27
+ });
28
+ let capturedContexts = [];
29
+ const TestComponent = () => {
30
+ const { getAdditionalContext } = useTamboContextHelpers();
31
+ React.useEffect(() => {
32
+ let mounted = true;
33
+ getAdditionalContext().then((contexts) => {
34
+ if (mounted) {
35
+ capturedContexts = contexts;
36
+ }
37
+ });
38
+ return () => {
39
+ mounted = false;
40
+ };
41
+ }, [getAdditionalContext]);
42
+ return React.createElement("div", { "data-testid": "ready" }, "ready");
43
+ };
44
+ const { getByTestId } = render(wrapperWithProviders(React.createElement(TamboInteractableProvider, null,
45
+ React.createElement(InteractableNote, { title: "hello" }),
46
+ React.createElement(TestComponent, null))));
47
+ await waitFor(() => {
48
+ expect(getByTestId("ready")).toBeInTheDocument();
49
+ const entry = capturedContexts.find((c) => c.name === "interactables");
50
+ expect(entry).toBeDefined();
51
+ expect(entry?.context?.description).toMatch(/interactable components/i);
52
+ expect(Array.isArray(entry?.context?.components)).toBe(true);
53
+ const comp = entry.context.components[0];
54
+ expect(comp.componentName).toBe("Note");
55
+ expect(comp.props).toEqual({ title: "hello" });
56
+ });
57
+ });
58
+ test("returns null when no interactable components are present", async () => {
59
+ let capturedContexts = [];
60
+ const TestComponent = () => {
61
+ const { getAdditionalContext } = useTamboContextHelpers();
62
+ React.useEffect(() => {
63
+ let mounted = true;
64
+ getAdditionalContext().then((contexts) => {
65
+ if (mounted) {
66
+ capturedContexts = contexts;
67
+ }
68
+ });
69
+ return () => {
70
+ mounted = false;
71
+ };
72
+ }, [getAdditionalContext]);
73
+ return React.createElement("div", { "data-testid": "ready" }, "ready");
74
+ };
75
+ const { getByTestId } = render(wrapperWithProviders(React.createElement(TamboInteractableProvider, null,
76
+ React.createElement("div", null, "No interactables here"),
77
+ React.createElement(TestComponent, null))));
78
+ await waitFor(() => {
79
+ expect(getByTestId("ready")).toBeInTheDocument();
80
+ const entry = capturedContexts.find((c) => c.name === "interactables");
81
+ expect(entry).toBeUndefined(); // Should be filtered out when helper returns null
82
+ });
83
+ });
84
+ test("context includes proper AI prompt with clear instructions", async () => {
85
+ const Note = ({ title }) => React.createElement("div", null, title);
86
+ const InteractableNote = withTamboInteractable(Note, {
87
+ componentName: "Note",
88
+ description: "A simple note",
89
+ propsSchema: z.object({ title: z.string() }),
90
+ });
91
+ let capturedContexts = [];
92
+ const TestComponent = () => {
93
+ const { getAdditionalContext } = useTamboContextHelpers();
94
+ React.useEffect(() => {
95
+ let mounted = true;
96
+ getAdditionalContext().then((contexts) => {
97
+ if (mounted) {
98
+ capturedContexts = contexts;
99
+ }
100
+ });
101
+ return () => {
102
+ mounted = false;
103
+ };
104
+ }, [getAdditionalContext]);
105
+ return React.createElement("div", { "data-testid": "ready" }, "ready");
106
+ };
107
+ const { getByTestId } = render(wrapperWithProviders(React.createElement(TamboInteractableProvider, null,
108
+ React.createElement(InteractableNote, { title: "test" }),
109
+ React.createElement(TestComponent, null))));
110
+ await waitFor(() => {
111
+ expect(getByTestId("ready")).toBeInTheDocument();
112
+ const entry = capturedContexts.find((c) => c.name === "interactables");
113
+ expect(entry?.context?.description).toContain("interactable components");
114
+ expect(entry?.context?.description).toContain("visible on the page");
115
+ expect(entry?.context?.description).toContain("you can read and modify");
116
+ expect(entry?.context?.description).toContain("tools to update");
117
+ });
118
+ });
119
+ test("includes component metadata in expected format", async () => {
120
+ const Note = ({ title, color = "white", }) => React.createElement("div", { className: `note-${color}` }, title);
121
+ const InteractableNote = withTamboInteractable(Note, {
122
+ componentName: "Note",
123
+ description: "A colorful note component",
124
+ propsSchema: z.object({
125
+ title: z.string(),
126
+ color: z.string().optional(),
127
+ }),
128
+ });
129
+ let capturedContexts = [];
130
+ const TestComponent = () => {
131
+ const { getAdditionalContext } = useTamboContextHelpers();
132
+ React.useEffect(() => {
133
+ let mounted = true;
134
+ getAdditionalContext().then((contexts) => {
135
+ if (mounted) {
136
+ capturedContexts = contexts;
137
+ }
138
+ });
139
+ return () => {
140
+ mounted = false;
141
+ };
142
+ }, [getAdditionalContext]);
143
+ return React.createElement("div", { "data-testid": "ready" }, "ready");
144
+ };
145
+ const { getByTestId } = render(wrapperWithProviders(React.createElement(TamboInteractableProvider, null,
146
+ React.createElement(InteractableNote, { title: "test note", color: "blue" }),
147
+ React.createElement(TestComponent, null))));
148
+ await waitFor(() => {
149
+ expect(getByTestId("ready")).toBeInTheDocument();
150
+ const entry = capturedContexts.find((c) => c.name === "interactables");
151
+ const component = entry.context.components[0];
152
+ expect(component).toMatchObject({
153
+ id: expect.any(String),
154
+ componentName: "Note",
155
+ description: "A colorful note component",
156
+ props: { title: "test note", color: "blue" },
157
+ propsSchema: "Available - use component-specific update tools",
158
+ });
159
+ });
160
+ });
161
+ test("snapshot hook returns immutable copies", async () => {
162
+ const Note = ({ title }) => React.createElement("div", null, title);
163
+ const InteractableNote = withTamboInteractable(Note, {
164
+ componentName: "Note",
165
+ description: "A note",
166
+ propsSchema: z.object({ title: z.string() }),
167
+ });
168
+ const TestComponent = () => {
169
+ const snapshot = useCurrentInteractablesSnapshot();
170
+ const [testResult, setTestResult] = React.useState("pending");
171
+ React.useEffect(() => {
172
+ if (snapshot.length > 0) {
173
+ const originalLength = snapshot.length;
174
+ // Try to mutate the returned array and props
175
+ snapshot.push({
176
+ id: "fake",
177
+ name: "Fake",
178
+ description: "",
179
+ component: () => null,
180
+ props: {},
181
+ });
182
+ snapshot[0].props.title = "MUTATED";
183
+ // The mutations should succeed on the returned copy, proving it's a separate object
184
+ if (snapshot.length === originalLength + 1 &&
185
+ snapshot[0].props.title === "MUTATED") {
186
+ setTestResult("mutation-successful-but-isolated");
187
+ }
188
+ else {
189
+ setTestResult("mutation-failed");
190
+ }
191
+ }
192
+ }, [snapshot]);
193
+ return React.createElement("div", { "data-testid": "test-result" }, testResult);
194
+ };
195
+ const { getByTestId } = render(wrapperWithProviders(React.createElement(TamboInteractableProvider, null,
196
+ React.createElement(InteractableNote, { title: "immutable test" }),
197
+ React.createElement(TestComponent, null))));
198
+ await waitFor(() => {
199
+ const result = getByTestId("test-result").textContent;
200
+ expect(result).toBe("mutation-successful-but-isolated");
201
+ });
202
+ });
203
+ test("multiple interactables from same provider appear in context", async () => {
204
+ const Note = ({ title }) => React.createElement("div", null, title);
205
+ const Counter = ({ count }) => (React.createElement("div", null, count));
206
+ const InteractableNote = withTamboInteractable(Note, {
207
+ componentName: "Note",
208
+ description: "A note",
209
+ propsSchema: z.object({ title: z.string() }),
210
+ });
211
+ const InteractableCounter = withTamboInteractable(Counter, {
212
+ componentName: "Counter",
213
+ description: "A counter",
214
+ propsSchema: z.object({ count: z.number() }),
215
+ });
216
+ let capturedContexts = [];
217
+ const TestComponent = () => {
218
+ const { getAdditionalContext } = useTamboContextHelpers();
219
+ React.useEffect(() => {
220
+ let mounted = true;
221
+ getAdditionalContext().then((contexts) => {
222
+ if (mounted) {
223
+ capturedContexts = contexts;
224
+ }
225
+ });
226
+ return () => {
227
+ mounted = false;
228
+ };
229
+ }, [getAdditionalContext]);
230
+ return React.createElement("div", { "data-testid": "ready" }, "ready");
231
+ };
232
+ const { getByTestId } = render(wrapperWithProviders(React.createElement(TamboInteractableProvider, null,
233
+ React.createElement(InteractableNote, { title: "first" }),
234
+ React.createElement(InteractableCounter, { count: 42 }),
235
+ React.createElement(TestComponent, null))));
236
+ await waitFor(() => {
237
+ expect(getByTestId("ready")).toBeInTheDocument();
238
+ const entry = capturedContexts.find((c) => c.name === "interactables");
239
+ expect(entry?.context?.components).toHaveLength(2);
240
+ const components = entry.context.components;
241
+ expect(components[0].componentName).toBe("Note");
242
+ expect(components[0].props).toEqual({ title: "first" });
243
+ expect(components[1].componentName).toBe("Counter");
244
+ expect(components[1].props).toEqual({ count: 42 });
245
+ });
246
+ });
247
+ test("can be disabled by returning null", async () => {
248
+ const Note = ({ title }) => React.createElement("div", null, title);
249
+ const InteractableNote = withTamboInteractable(Note, {
250
+ componentName: "Note",
251
+ description: "A note",
252
+ propsSchema: z.object({ title: z.string() }),
253
+ });
254
+ // Create a context helpers provider with a disabled interactables helper
255
+ const DisabledContextHelpers = ({ children, }) => (React.createElement(TamboContextHelpersProvider, { contextHelpers: {
256
+ ["interactables"]: () => null,
257
+ } }, children));
258
+ let capturedContexts = [];
259
+ const TestComponent = () => {
260
+ const { getAdditionalContext } = useTamboContextHelpers();
261
+ React.useEffect(() => {
262
+ let mounted = true;
263
+ getAdditionalContext().then((contexts) => {
264
+ if (mounted) {
265
+ capturedContexts = contexts;
266
+ }
267
+ });
268
+ return () => {
269
+ mounted = false;
270
+ };
271
+ }, [getAdditionalContext]);
272
+ return React.createElement("div", { "data-testid": "ready" }, "ready");
273
+ };
274
+ const thread = {
275
+ id: "t-1",
276
+ projectId: "p-1",
277
+ createdAt: new Date().toISOString(),
278
+ updatedAt: new Date().toISOString(),
279
+ messages: [],
280
+ metadata: {},
281
+ };
282
+ const { getByTestId } = render(React.createElement(TamboStubProvider, { thread: thread, registerTool: () => { }, registerTools: () => { }, registerComponent: () => { }, addToolAssociation: () => { } },
283
+ React.createElement(DisabledContextHelpers, null,
284
+ React.createElement(TamboInteractableProvider, null,
285
+ React.createElement(InteractableNote, { title: "should not appear" }),
286
+ React.createElement(TestComponent, null)))));
287
+ await waitFor(() => {
288
+ expect(getByTestId("ready")).toBeInTheDocument();
289
+ const entry = capturedContexts.find((c) => c.name === "interactables");
290
+ expect(entry).toBeUndefined(); // Should be filtered out when helper returns null
291
+ });
292
+ });
293
+ });
294
+ //# sourceMappingURL=tambo-interactables-additional-context.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tambo-interactables-additional-context.test.js","sourceRoot":"","sources":["../../../src/providers/__tests__/tambo-interactables-additional-context.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { render, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport {\n useTamboContextHelpers,\n TamboContextHelpersProvider,\n} from \"../tambo-context-helpers-provider\";\nimport {\n TamboInteractableProvider,\n useCurrentInteractablesSnapshot,\n} from \"../tambo-interactable-provider\";\nimport { TamboStubProvider } from \"../tambo-stubs\";\nimport { withTamboInteractable } from \"../hoc/with-tambo-interactable\";\n\nfunction wrapperWithProviders(children: React.ReactNode) {\n const thread = {\n id: \"t-1\",\n projectId: \"p-1\",\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n messages: [],\n metadata: {},\n } as any;\n\n return (\n <TamboStubProvider\n thread={thread}\n registerTool={() => {}}\n registerTools={() => {}}\n registerComponent={() => {}}\n addToolAssociation={() => {}}\n >\n <TamboContextHelpersProvider>{children}</TamboContextHelpersProvider>\n </TamboStubProvider>\n );\n}\n\ndescribe(\"Interactables AdditionalContext (provider-based)\", () => {\n test(\"registers default helper and returns payload with description and components\", async () => {\n const Note: React.FC<{ title: string }> = ({ title }) => <div>{title}</div>;\n\n const InteractableNote = withTamboInteractable(Note, {\n componentName: \"Note\",\n description: \"A note\",\n propsSchema: z.object({ title: z.string() }),\n });\n\n let capturedContexts: any[] = [];\n const TestComponent = () => {\n const { getAdditionalContext } = useTamboContextHelpers();\n\n React.useEffect(() => {\n let mounted = true;\n getAdditionalContext().then((contexts) => {\n if (mounted) {\n capturedContexts = contexts;\n }\n });\n return () => {\n mounted = false;\n };\n }, [getAdditionalContext]);\n\n return <div data-testid=\"ready\">ready</div>;\n };\n\n const { getByTestId } = render(\n wrapperWithProviders(\n <TamboInteractableProvider>\n <InteractableNote title=\"hello\" />\n <TestComponent />\n </TamboInteractableProvider>,\n ),\n );\n\n await waitFor(() => {\n expect(getByTestId(\"ready\")).toBeInTheDocument();\n const entry = capturedContexts.find(\n (c: any) => c.name === \"interactables\",\n );\n expect(entry).toBeDefined();\n expect(entry?.context?.description).toMatch(/interactable components/i);\n expect(Array.isArray(entry?.context?.components)).toBe(true);\n const comp = entry!.context.components[0];\n expect(comp.componentName).toBe(\"Note\");\n expect(comp.props).toEqual({ title: \"hello\" });\n });\n });\n\n test(\"returns null when no interactable components are present\", async () => {\n let capturedContexts: any[] = [];\n const TestComponent = () => {\n const { getAdditionalContext } = useTamboContextHelpers();\n\n React.useEffect(() => {\n let mounted = true;\n getAdditionalContext().then((contexts) => {\n if (mounted) {\n capturedContexts = contexts;\n }\n });\n return () => {\n mounted = false;\n };\n }, [getAdditionalContext]);\n\n return <div data-testid=\"ready\">ready</div>;\n };\n\n const { getByTestId } = render(\n wrapperWithProviders(\n <TamboInteractableProvider>\n <div>No interactables here</div>\n <TestComponent />\n </TamboInteractableProvider>,\n ),\n );\n\n await waitFor(() => {\n expect(getByTestId(\"ready\")).toBeInTheDocument();\n const entry = capturedContexts.find(\n (c: any) => c.name === \"interactables\",\n );\n expect(entry).toBeUndefined(); // Should be filtered out when helper returns null\n });\n });\n\n test(\"context includes proper AI prompt with clear instructions\", async () => {\n const Note: React.FC<{ title: string }> = ({ title }) => <div>{title}</div>;\n const InteractableNote = withTamboInteractable(Note, {\n componentName: \"Note\",\n description: \"A simple note\",\n propsSchema: z.object({ title: z.string() }),\n });\n\n let capturedContexts: any[] = [];\n const TestComponent = () => {\n const { getAdditionalContext } = useTamboContextHelpers();\n\n React.useEffect(() => {\n let mounted = true;\n getAdditionalContext().then((contexts) => {\n if (mounted) {\n capturedContexts = contexts;\n }\n });\n return () => {\n mounted = false;\n };\n }, [getAdditionalContext]);\n\n return <div data-testid=\"ready\">ready</div>;\n };\n\n const { getByTestId } = render(\n wrapperWithProviders(\n <TamboInteractableProvider>\n <InteractableNote title=\"test\" />\n <TestComponent />\n </TamboInteractableProvider>,\n ),\n );\n\n await waitFor(() => {\n expect(getByTestId(\"ready\")).toBeInTheDocument();\n const entry = capturedContexts.find(\n (c: any) => c.name === \"interactables\",\n );\n expect(entry?.context?.description).toContain(\"interactable components\");\n expect(entry?.context?.description).toContain(\"visible on the page\");\n expect(entry?.context?.description).toContain(\"you can read and modify\");\n expect(entry?.context?.description).toContain(\"tools to update\");\n });\n });\n\n test(\"includes component metadata in expected format\", async () => {\n const Note: React.FC<{ title: string; color?: string }> = ({\n title,\n color = \"white\",\n }) => <div className={`note-${color}`}>{title}</div>;\n\n const InteractableNote = withTamboInteractable(Note, {\n componentName: \"Note\",\n description: \"A colorful note component\",\n propsSchema: z.object({\n title: z.string(),\n color: z.string().optional(),\n }),\n });\n\n let capturedContexts: any[] = [];\n const TestComponent = () => {\n const { getAdditionalContext } = useTamboContextHelpers();\n\n React.useEffect(() => {\n let mounted = true;\n getAdditionalContext().then((contexts) => {\n if (mounted) {\n capturedContexts = contexts;\n }\n });\n return () => {\n mounted = false;\n };\n }, [getAdditionalContext]);\n\n return <div data-testid=\"ready\">ready</div>;\n };\n\n const { getByTestId } = render(\n wrapperWithProviders(\n <TamboInteractableProvider>\n <InteractableNote title=\"test note\" color=\"blue\" />\n <TestComponent />\n </TamboInteractableProvider>,\n ),\n );\n\n await waitFor(() => {\n expect(getByTestId(\"ready\")).toBeInTheDocument();\n const entry = capturedContexts.find(\n (c: any) => c.name === \"interactables\",\n );\n const component = entry!.context.components[0];\n\n expect(component).toMatchObject({\n id: expect.any(String),\n componentName: \"Note\",\n description: \"A colorful note component\",\n props: { title: \"test note\", color: \"blue\" },\n propsSchema: \"Available - use component-specific update tools\",\n });\n });\n });\n\n test(\"snapshot hook returns immutable copies\", async () => {\n const Note: React.FC<{ title: string }> = ({ title }) => <div>{title}</div>;\n const InteractableNote = withTamboInteractable(Note, {\n componentName: \"Note\",\n description: \"A note\",\n propsSchema: z.object({ title: z.string() }),\n });\n\n const TestComponent = () => {\n const snapshot = useCurrentInteractablesSnapshot();\n const [testResult, setTestResult] = React.useState<string>(\"pending\");\n\n React.useEffect(() => {\n if (snapshot.length > 0) {\n const originalLength = snapshot.length;\n\n // Try to mutate the returned array and props\n snapshot.push({\n id: \"fake\",\n name: \"Fake\",\n description: \"\",\n component: () => null,\n props: {},\n } as any);\n (snapshot[0].props as any).title = \"MUTATED\";\n\n // The mutations should succeed on the returned copy, proving it's a separate object\n if (\n snapshot.length === originalLength + 1 &&\n snapshot[0].props.title === \"MUTATED\"\n ) {\n setTestResult(\"mutation-successful-but-isolated\");\n } else {\n setTestResult(\"mutation-failed\");\n }\n }\n }, [snapshot]);\n\n return <div data-testid=\"test-result\">{testResult}</div>;\n };\n\n const { getByTestId } = render(\n wrapperWithProviders(\n <TamboInteractableProvider>\n <InteractableNote title=\"immutable test\" />\n <TestComponent />\n </TamboInteractableProvider>,\n ),\n );\n\n await waitFor(() => {\n const result = getByTestId(\"test-result\").textContent;\n expect(result).toBe(\"mutation-successful-but-isolated\");\n });\n });\n\n test(\"multiple interactables from same provider appear in context\", async () => {\n const Note: React.FC<{ title: string }> = ({ title }) => <div>{title}</div>;\n const Counter: React.FC<{ count: number }> = ({ count }) => (\n <div>{count}</div>\n );\n\n const InteractableNote = withTamboInteractable(Note, {\n componentName: \"Note\",\n description: \"A note\",\n propsSchema: z.object({ title: z.string() }),\n });\n\n const InteractableCounter = withTamboInteractable(Counter, {\n componentName: \"Counter\",\n description: \"A counter\",\n propsSchema: z.object({ count: z.number() }),\n });\n\n let capturedContexts: any[] = [];\n const TestComponent = () => {\n const { getAdditionalContext } = useTamboContextHelpers();\n\n React.useEffect(() => {\n let mounted = true;\n getAdditionalContext().then((contexts) => {\n if (mounted) {\n capturedContexts = contexts;\n }\n });\n return () => {\n mounted = false;\n };\n }, [getAdditionalContext]);\n\n return <div data-testid=\"ready\">ready</div>;\n };\n\n const { getByTestId } = render(\n wrapperWithProviders(\n <TamboInteractableProvider>\n <InteractableNote title=\"first\" />\n <InteractableCounter count={42} />\n <TestComponent />\n </TamboInteractableProvider>,\n ),\n );\n\n await waitFor(() => {\n expect(getByTestId(\"ready\")).toBeInTheDocument();\n const entry = capturedContexts.find(\n (c: any) => c.name === \"interactables\",\n );\n expect(entry?.context?.components).toHaveLength(2);\n\n const components = entry!.context.components;\n expect(components[0].componentName).toBe(\"Note\");\n expect(components[0].props).toEqual({ title: \"first\" });\n expect(components[1].componentName).toBe(\"Counter\");\n expect(components[1].props).toEqual({ count: 42 });\n });\n });\n\n test(\"can be disabled by returning null\", async () => {\n const Note: React.FC<{ title: string }> = ({ title }) => <div>{title}</div>;\n const InteractableNote = withTamboInteractable(Note, {\n componentName: \"Note\",\n description: \"A note\",\n propsSchema: z.object({ title: z.string() }),\n });\n\n // Create a context helpers provider with a disabled interactables helper\n const DisabledContextHelpers = ({\n children,\n }: {\n children: React.ReactNode;\n }) => (\n <TamboContextHelpersProvider\n contextHelpers={{\n [\"interactables\"]: () => null,\n }}\n >\n {children}\n </TamboContextHelpersProvider>\n );\n\n let capturedContexts: any[] = [];\n const TestComponent = () => {\n const { getAdditionalContext } = useTamboContextHelpers();\n\n React.useEffect(() => {\n let mounted = true;\n getAdditionalContext().then((contexts) => {\n if (mounted) {\n capturedContexts = contexts;\n }\n });\n return () => {\n mounted = false;\n };\n }, [getAdditionalContext]);\n\n return <div data-testid=\"ready\">ready</div>;\n };\n\n const thread = {\n id: \"t-1\",\n projectId: \"p-1\",\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n messages: [],\n metadata: {},\n } as any;\n\n const { getByTestId } = render(\n <TamboStubProvider\n thread={thread}\n registerTool={() => {}}\n registerTools={() => {}}\n registerComponent={() => {}}\n addToolAssociation={() => {}}\n >\n <DisabledContextHelpers>\n <TamboInteractableProvider>\n <InteractableNote title=\"should not appear\" />\n <TestComponent />\n </TamboInteractableProvider>\n </DisabledContextHelpers>\n </TamboStubProvider>,\n );\n\n await waitFor(() => {\n expect(getByTestId(\"ready\")).toBeInTheDocument();\n const entry = capturedContexts.find(\n (c: any) => c.name === \"interactables\",\n );\n expect(entry).toBeUndefined(); // Should be filtered out when helper returns null\n });\n });\n});\n"]}
@@ -1,5 +1,5 @@
1
1
  import React, { PropsWithChildren } from "react";
2
- import { AdditionalContext, ContextHelpers, ContextHelperFn } from "../context-helpers";
2
+ import { AdditionalContext, ContextHelperFn, ContextHelpers } from "../context-helpers";
3
3
  export interface TamboContextHelpersProviderProps {
4
4
  /**
5
5
  * A dictionary of context helper functions.
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-context-helpers-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-context-helpers-provider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAIlB,MAAM,OAAO,CAAC;AACf,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAQ5B,MAAM,WAAW,gCAAgC;IAC/C;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,WAAW,+BAA+B;IAC9C,iEAAiE;IACjE,oBAAoB,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACzD,0CAA0C;IAC1C,iBAAiB,EAAE,MAAM,cAAc,CAAC;IACxC,6CAA6C;IAC7C,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAClE,sCAAsC;IACtC,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAKD;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,EAAE,KAAK,CAAC,EAAE,CAChD,iBAAiB,CAAC,gCAAgC,CAAC,CAgEpD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,uCAalC,CAAC"}
1
+ {"version":3,"file":"tambo-context-helpers-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-context-helpers-provider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAMlB,MAAM,OAAO,CAAC;AACf,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,cAAc,EACf,MAAM,oBAAoB,CAAC;AAG5B,MAAM,WAAW,gCAAgC;IAC/C;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,WAAW,+BAA+B;IAC9C,iEAAiE;IACjE,oBAAoB,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACzD,0CAA0C;IAC1C,iBAAiB,EAAE,MAAM,cAAc,CAAC;IACxC,6CAA6C;IAC7C,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAClE,sCAAsC;IACtC,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAKD;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,EAAE,KAAK,CAAC,EAAE,CAChD,iBAAiB,CAAC,gCAAgC,CAAC,CAkEpD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,uCAmBlC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import React, { createContext, useCallback, useContext, useMemo, } from "react";
3
- import { addHelper, getHelpers, removeHelper as removeGlobalHelper, resolveAdditionalContext, } from "../context-helpers/registry";
2
+ import React, { createContext, useCallback, useContext, useEffect, useMemo, useState, } from "react";
3
+ import { resolveAdditionalContext } from "../context-helpers/registry";
4
4
  const TamboContextHelpersContext = createContext(null);
5
5
  /**
6
6
  * Provider for managing additional context helpers.
@@ -12,38 +12,42 @@ const TamboContextHelpersContext = createContext(null);
12
12
  * @returns The provider that exposes context helper APIs via useTamboContextHelpers.
13
13
  */
14
14
  export const TamboContextHelpersProvider = ({ children, contextHelpers }) => {
15
+ const [helpers, setHelpers] = useState({});
16
+ const addContextHelper = useCallback((name, fn) => {
17
+ setHelpers((prev) => ({ ...prev, [name]: fn }));
18
+ }, []);
19
+ const removeContextHelper = useCallback((name, fn) => {
20
+ setHelpers((prev) => {
21
+ const { [name]: registeredFn, ...rest } = prev;
22
+ if (fn === undefined || registeredFn === fn) {
23
+ return rest;
24
+ }
25
+ return prev;
26
+ });
27
+ }, []);
15
28
  // Hydrate the global registry with initial helpers (runs on prop changes)
16
- React.useEffect(() => {
29
+ useEffect(() => {
17
30
  const addedEntries = [];
18
31
  if (contextHelpers) {
19
32
  for (const [name, fn] of Object.entries(contextHelpers)) {
20
- addHelper(name, fn);
33
+ addContextHelper(name, fn);
21
34
  addedEntries.push([name, fn]);
22
35
  }
23
36
  }
24
37
  return () => {
25
- const current = getHelpers();
26
38
  for (const [name, fn] of addedEntries) {
27
39
  // Only remove if the registry still points to the same function
28
- if (current[name] === fn) {
29
- removeGlobalHelper(name);
30
- }
40
+ removeContextHelper(name, fn);
31
41
  }
32
42
  };
33
- }, [contextHelpers]);
43
+ }, [addContextHelper, contextHelpers, removeContextHelper]);
34
44
  const getAdditionalContext = useCallback(async () => {
35
- const contexts = await resolveAdditionalContext();
45
+ const contexts = await resolveAdditionalContext(helpers);
36
46
  return contexts;
37
- }, []);
47
+ }, [helpers]);
38
48
  const getContextHelpers = useCallback(() => {
39
- return getHelpers();
40
- }, []);
41
- const addContextHelper = useCallback((name, helper) => {
42
- addHelper(name, helper);
43
- }, []);
44
- const removeContextHelper = useCallback((name) => {
45
- removeGlobalHelper(name);
46
- }, []);
49
+ return helpers;
50
+ }, [helpers]);
47
51
  const value = useMemo(() => ({
48
52
  getAdditionalContext,
49
53
  getContextHelpers,
@@ -68,10 +72,18 @@ export const useTamboContextHelpers = () => {
68
72
  return context;
69
73
  // Fallback to global registry so the API is standalone outside any provider
70
74
  return {
71
- getAdditionalContext: async () => (await resolveAdditionalContext()),
72
- getContextHelpers: () => getHelpers(),
73
- addContextHelper: (name, helper) => addHelper(name, helper),
74
- removeContextHelper: (name) => removeGlobalHelper(name),
75
+ getAdditionalContext: async () => {
76
+ throw new Error("No provider found");
77
+ },
78
+ getContextHelpers: () => {
79
+ throw new Error("No provider found");
80
+ },
81
+ addContextHelper: (_name, _helper) => {
82
+ throw new Error("No provider found");
83
+ },
84
+ removeContextHelper: (_name) => {
85
+ throw new Error("No provider found");
86
+ },
75
87
  };
76
88
  };
77
89
  //# sourceMappingURL=tambo-context-helpers-provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-context-helpers-provider.js","sourceRoot":"","sources":["../../src/providers/tambo-context-helpers-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useMemo,\n} from \"react\";\nimport {\n AdditionalContext,\n ContextHelpers,\n ContextHelperFn,\n} from \"../context-helpers\";\nimport {\n addHelper,\n getHelpers,\n removeHelper as removeGlobalHelper,\n resolveAdditionalContext,\n} from \"../context-helpers/registry\";\n\nexport interface TamboContextHelpersProviderProps {\n /**\n * A dictionary of context helper functions.\n * The key becomes the AdditionalContext.name and the function returns the value.\n * Return null/undefined to skip including that context.\n */\n contextHelpers?: ContextHelpers;\n}\n\nexport interface TamboContextHelpersContextProps {\n /** Get all additional context by running all helper functions */\n getAdditionalContext: () => Promise<AdditionalContext[]>;\n /** Get the current context helpers map */\n getContextHelpers: () => ContextHelpers;\n /** Add or update a context helper by name */\n addContextHelper: (name: string, helper: ContextHelperFn) => void;\n /** Remove a context helper by name */\n removeContextHelper: (name: string) => void;\n}\n\nconst TamboContextHelpersContext =\n createContext<TamboContextHelpersContextProps | null>(null);\n\n/**\n * Provider for managing additional context helpers.\n * Accepts a map of { key: () => any | null | undefined | Promise<any | null | undefined> }.\n * Returning null/undefined skips inclusion; returned values are wrapped as { name: key, context: value }.\n * @param props - The props for the TamboContextHelpersProvider.\n * @param props.contextHelpers - A dictionary of context helper functions keyed by context name.\n * @param props.children - The children to render.\n * @returns The provider that exposes context helper APIs via useTamboContextHelpers.\n */\nexport const TamboContextHelpersProvider: React.FC<\n PropsWithChildren<TamboContextHelpersProviderProps>\n> = ({ children, contextHelpers }) => {\n // Hydrate the global registry with initial helpers (runs on prop changes)\n React.useEffect(() => {\n const addedEntries: [string, ContextHelperFn][] = [];\n\n if (contextHelpers) {\n for (const [name, fn] of Object.entries(contextHelpers)) {\n addHelper(name, fn);\n addedEntries.push([name, fn]);\n }\n }\n\n return () => {\n const current = getHelpers();\n for (const [name, fn] of addedEntries) {\n // Only remove if the registry still points to the same function\n if (current[name] === fn) {\n removeGlobalHelper(name);\n }\n }\n };\n }, [contextHelpers]);\n\n const getAdditionalContext = useCallback(async () => {\n const contexts = await resolveAdditionalContext();\n return contexts as AdditionalContext[];\n }, []);\n\n const getContextHelpers = useCallback(() => {\n return getHelpers() as ContextHelpers;\n }, []);\n\n const addContextHelper = useCallback(\n (name: string, helper: ContextHelperFn) => {\n addHelper(name, helper);\n },\n [],\n );\n\n const removeContextHelper = useCallback((name: string) => {\n removeGlobalHelper(name);\n }, []);\n\n const value = useMemo(\n () => ({\n getAdditionalContext,\n getContextHelpers,\n addContextHelper,\n removeContextHelper,\n }),\n [\n getAdditionalContext,\n getContextHelpers,\n addContextHelper,\n removeContextHelper,\n ],\n );\n\n return (\n <TamboContextHelpersContext.Provider value={value}>\n {children}\n </TamboContextHelpersContext.Provider>\n );\n};\n\n/**\n * Hook to access context helpers functionality.\n * Safe to call even when no provider is present: proxies to the global registry.\n * @returns The context helpers context props (registry-backed).\n */\nexport const useTamboContextHelpers = () => {\n const context = useContext(TamboContextHelpersContext);\n if (context) return context;\n\n // Fallback to global registry so the API is standalone outside any provider\n return {\n getAdditionalContext: async () =>\n (await resolveAdditionalContext()) as AdditionalContext[],\n getContextHelpers: () => getHelpers() as ContextHelpers,\n addContextHelper: (name: string, helper: ContextHelperFn) =>\n addHelper(name, helper),\n removeContextHelper: (name: string) => removeGlobalHelper(name),\n } as TamboContextHelpersContextProps;\n};\n"]}
1
+ {"version":3,"file":"tambo-context-helpers-provider.js","sourceRoot":"","sources":["../../src/providers/tambo-context-helpers-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport {\n AdditionalContext,\n ContextHelperFn,\n ContextHelpers,\n} from \"../context-helpers\";\nimport { resolveAdditionalContext } from \"../context-helpers/registry\";\n\nexport interface TamboContextHelpersProviderProps {\n /**\n * A dictionary of context helper functions.\n * The key becomes the AdditionalContext.name and the function returns the value.\n * Return null/undefined to skip including that context.\n */\n contextHelpers?: ContextHelpers;\n}\n\nexport interface TamboContextHelpersContextProps {\n /** Get all additional context by running all helper functions */\n getAdditionalContext: () => Promise<AdditionalContext[]>;\n /** Get the current context helpers map */\n getContextHelpers: () => ContextHelpers;\n /** Add or update a context helper by name */\n addContextHelper: (name: string, helper: ContextHelperFn) => void;\n /** Remove a context helper by name */\n removeContextHelper: (name: string) => void;\n}\n\nconst TamboContextHelpersContext =\n createContext<TamboContextHelpersContextProps | null>(null);\n\n/**\n * Provider for managing additional context helpers.\n * Accepts a map of { key: () => any | null | undefined | Promise<any | null | undefined> }.\n * Returning null/undefined skips inclusion; returned values are wrapped as { name: key, context: value }.\n * @param props - The props for the TamboContextHelpersProvider.\n * @param props.contextHelpers - A dictionary of context helper functions keyed by context name.\n * @param props.children - The children to render.\n * @returns The provider that exposes context helper APIs via useTamboContextHelpers.\n */\nexport const TamboContextHelpersProvider: React.FC<\n PropsWithChildren<TamboContextHelpersProviderProps>\n> = ({ children, contextHelpers }) => {\n const [helpers, setHelpers] = useState<Record<string, ContextHelperFn>>({});\n const addContextHelper = useCallback((name: string, fn: ContextHelperFn) => {\n setHelpers((prev) => ({ ...prev, [name]: fn }));\n }, []);\n const removeContextHelper = useCallback(\n (name: string, fn?: ContextHelperFn) => {\n setHelpers((prev) => {\n const { [name]: registeredFn, ...rest } = prev;\n if (fn === undefined || registeredFn === fn) {\n return rest;\n }\n return prev;\n });\n },\n [],\n );\n // Hydrate the global registry with initial helpers (runs on prop changes)\n useEffect(() => {\n const addedEntries: [string, ContextHelperFn][] = [];\n\n if (contextHelpers) {\n for (const [name, fn] of Object.entries(contextHelpers)) {\n addContextHelper(name, fn);\n addedEntries.push([name, fn]);\n }\n }\n\n return () => {\n for (const [name, fn] of addedEntries) {\n // Only remove if the registry still points to the same function\n removeContextHelper(name, fn);\n }\n };\n }, [addContextHelper, contextHelpers, removeContextHelper]);\n\n const getAdditionalContext = useCallback(async () => {\n const contexts = await resolveAdditionalContext(helpers);\n return contexts as AdditionalContext[];\n }, [helpers]);\n\n const getContextHelpers = useCallback(() => {\n return helpers as ContextHelpers;\n }, [helpers]);\n\n const value = useMemo(\n () => ({\n getAdditionalContext,\n getContextHelpers,\n addContextHelper,\n removeContextHelper,\n }),\n [\n getAdditionalContext,\n getContextHelpers,\n addContextHelper,\n removeContextHelper,\n ],\n );\n\n return (\n <TamboContextHelpersContext.Provider value={value}>\n {children}\n </TamboContextHelpersContext.Provider>\n );\n};\n\n/**\n * Hook to access context helpers functionality.\n * Safe to call even when no provider is present: proxies to the global registry.\n * @returns The context helpers context props (registry-backed).\n */\nexport const useTamboContextHelpers = () => {\n const context = useContext(TamboContextHelpersContext);\n if (context) return context;\n\n // Fallback to global registry so the API is standalone outside any provider\n return {\n getAdditionalContext: async () => {\n throw new Error(\"No provider found\");\n },\n getContextHelpers: () => {\n throw new Error(\"No provider found\");\n },\n addContextHelper: (_name: string, _helper: ContextHelperFn) => {\n throw new Error(\"No provider found\");\n },\n removeContextHelper: (_name: string) => {\n throw new Error(\"No provider found\");\n },\n } as TamboContextHelpersContextProps;\n};\n"]}
@@ -1,4 +1,5 @@
1
1
  import React, { PropsWithChildren } from "react";
2
+ import { z } from "zod";
2
3
  import { type TamboInteractableContext } from "../model/tambo-interactable";
3
4
  declare const TamboInteractableContext: React.Context<TamboInteractableContext>;
4
5
  /**
@@ -16,5 +17,24 @@ export declare const TamboInteractableProvider: React.FC<PropsWithChildren>;
16
17
  * @returns The interactable component management functions
17
18
  */
18
19
  export declare const useTamboInteractable: () => TamboInteractableContext;
20
+ /**
21
+ * Hook to get a cloned snapshot of the current interactables.
22
+ * Returns a shallow copy of the array with cloned items and props to prevent
23
+ * external mutation from affecting internal state.
24
+ * @returns The current interactables snapshot (cloned).
25
+ */
26
+ export declare const useCurrentInteractablesSnapshot: () => {
27
+ props: {
28
+ [x: string]: any;
29
+ };
30
+ id: string;
31
+ name: string;
32
+ description: string;
33
+ component: React.ComponentType<any>;
34
+ propsSchema?: z.ZodTypeAny | import("json-schema").JSONSchema7;
35
+ propsDefinition?: any;
36
+ loadingComponent?: React.ComponentType<any>;
37
+ associatedTools?: import(".").TamboTool[];
38
+ }[];
19
39
  export {};
20
40
  //# sourceMappingURL=tambo-interactable-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-interactable-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-interactable-provider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAKlB,MAAM,OAAO,CAAC;AAEf,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,6BAA6B,CAAC;AAGrC,QAAA,MAAM,wBAAwB,yCAQ5B,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA4PjE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,gCAEhC,CAAC"}
1
+ {"version":3,"file":"tambo-interactable-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-interactable-provider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAKlB,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,6BAA6B,CAAC;AAKrC,QAAA,MAAM,wBAAwB,yCAQ5B,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA6QjE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,gCAEhC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;GAU3C,CAAC"}