@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
@@ -3,6 +3,8 @@
3
3
  import React, { createContext, useCallback, useContext, useEffect, useState, } from "react";
4
4
  import { z } from "zod";
5
5
  import { useTamboComponent } from "./tambo-component-provider";
6
+ import { useTamboContextHelpers } from "./tambo-context-helpers-provider";
7
+ import { createInteractablesContextHelper } from "../context-helpers/current-interactables-context-helper";
6
8
  const TamboInteractableContext = createContext({
7
9
  interactableComponents: [],
8
10
  addInteractableComponent: () => "",
@@ -23,95 +25,109 @@ const TamboInteractableContext = createContext({
23
25
  export const TamboInteractableProvider = ({ children, }) => {
24
26
  const [interactableComponents, setInteractableComponents] = useState([]);
25
27
  const { registerTool } = useTamboComponent();
28
+ const { addContextHelper, removeContextHelper } = useTamboContextHelpers();
29
+ // Create a stable context helper function
30
+ const contextHelper = useCallback(() => {
31
+ return createInteractablesContextHelper(() => interactableComponents)();
32
+ }, [interactableComponents]);
33
+ // Register the default interactables context helper
26
34
  useEffect(() => {
27
- registerTool({
28
- name: "get_all_interactable_components",
29
- description: "Only use this tool if the user is asking about interactable components.Get all currently interactable components with their details including their current props. These are components that you can interact with on behalf of the user.",
30
- tool: () => {
31
- return {
32
- components: interactableComponents,
33
- };
34
- },
35
- toolSchema: z.function().returns(z.object({
36
- components: z.array(z.object({
37
- id: z.string(),
38
- componentName: z.string(),
39
- props: z.record(z.any()),
40
- propsSchema: z.object({}).optional(),
35
+ addContextHelper("interactables", contextHelper);
36
+ return () => {
37
+ removeContextHelper("interactables");
38
+ };
39
+ }, [contextHelper, addContextHelper, removeContextHelper]);
40
+ useEffect(() => {
41
+ if (interactableComponents.length > 0) {
42
+ registerTool({
43
+ name: "get_all_interactable_components",
44
+ description: "Only use this tool if the user is asking about interactable components.Get all currently interactable components with their details including their current props. These are components that you can interact with on behalf of the user.",
45
+ tool: () => {
46
+ return {
47
+ components: interactableComponents,
48
+ };
49
+ },
50
+ toolSchema: z.function().returns(z.object({
51
+ components: z.array(z.object({
52
+ id: z.string(),
53
+ componentName: z.string(),
54
+ props: z.record(z.any()),
55
+ propsSchema: z.object({}).optional(),
56
+ })),
41
57
  })),
42
- })),
43
- });
44
- registerTool({
45
- name: "get_interactable_component_by_id",
46
- description: "Get a specific interactable component by its ID",
47
- tool: (componentId) => {
48
- const component = interactableComponents.find((c) => c.id === componentId);
49
- if (!component) {
58
+ });
59
+ registerTool({
60
+ name: "get_interactable_component_by_id",
61
+ description: "Get a specific interactable component by its ID",
62
+ tool: (componentId) => {
63
+ const component = interactableComponents.find((c) => c.id === componentId);
64
+ if (!component) {
65
+ return {
66
+ success: false,
67
+ error: `Component with ID ${componentId} not found`,
68
+ };
69
+ }
50
70
  return {
51
- success: false,
52
- error: `Component with ID ${componentId} not found`,
71
+ success: true,
72
+ component: {
73
+ id: component.id,
74
+ componentName: component.name,
75
+ props: component.props,
76
+ },
53
77
  };
54
- }
55
- return {
56
- success: true,
57
- component: {
58
- id: component.id,
59
- componentName: component.name,
60
- props: component.props,
61
- },
62
- };
63
- },
64
- toolSchema: z
65
- .function()
66
- .args(z.string())
67
- .returns(z.object({
68
- success: z.boolean(),
69
- component: z
70
- .object({
71
- id: z.string(),
72
- componentName: z.string(),
73
- props: z.record(z.any()),
74
- })
75
- .optional(),
76
- error: z.string().optional(),
77
- })),
78
- });
79
- registerTool({
80
- name: "remove_interactable_component",
81
- description: "Remove an interactable component from the system",
82
- tool: (componentId) => {
83
- const component = interactableComponents.find((c) => c.id === componentId);
84
- if (!component) {
78
+ },
79
+ toolSchema: z
80
+ .function()
81
+ .args(z.string())
82
+ .returns(z.object({
83
+ success: z.boolean(),
84
+ component: z
85
+ .object({
86
+ id: z.string(),
87
+ componentName: z.string(),
88
+ props: z.record(z.any()),
89
+ })
90
+ .optional(),
91
+ error: z.string().optional(),
92
+ })),
93
+ });
94
+ registerTool({
95
+ name: "remove_interactable_component",
96
+ description: "Remove an interactable component from the system",
97
+ tool: (componentId) => {
98
+ const component = interactableComponents.find((c) => c.id === componentId);
99
+ if (!component) {
100
+ return {
101
+ success: false,
102
+ error: `Component with ID ${componentId} not found`,
103
+ };
104
+ }
105
+ setInteractableComponents((prev) => prev.filter((c) => c.id !== componentId));
85
106
  return {
86
- success: false,
87
- error: `Component with ID ${componentId} not found`,
107
+ success: true,
108
+ componentId,
109
+ removedComponent: {
110
+ id: component.id,
111
+ componentName: component.name,
112
+ props: component.props,
113
+ },
88
114
  };
89
- }
90
- setInteractableComponents((prev) => prev.filter((c) => c.id !== componentId));
91
- return {
92
- success: true,
93
- componentId,
94
- removedComponent: {
95
- id: component.id,
96
- componentName: component.name,
97
- props: component.props,
98
- },
99
- };
100
- },
101
- toolSchema: z
102
- .function()
103
- .args(z.string())
104
- .returns(z.object({
105
- success: z.boolean(),
106
- componentId: z.string(),
107
- removedComponent: z.object({
108
- id: z.string(),
109
- componentName: z.string(),
110
- props: z.record(z.any()),
111
- }),
112
- error: z.string().optional(),
113
- })),
114
- });
115
+ },
116
+ toolSchema: z
117
+ .function()
118
+ .args(z.string())
119
+ .returns(z.object({
120
+ success: z.boolean(),
121
+ componentId: z.string(),
122
+ removedComponent: z.object({
123
+ id: z.string(),
124
+ componentName: z.string(),
125
+ props: z.record(z.any()),
126
+ }),
127
+ error: z.string().optional(),
128
+ })),
129
+ });
130
+ }
115
131
  }, [interactableComponents, registerTool]);
116
132
  const updateInteractableComponentProps = useCallback((id, newProps) => {
117
133
  let updateResult = "Updated successfully";
@@ -160,7 +176,7 @@ export const TamboInteractableProvider = ({ children, }) => {
160
176
  });
161
177
  }, [registerTool, updateInteractableComponentProps]);
162
178
  const addInteractableComponent = useCallback((component) => {
163
- const id = `${component.name}-${Math.random().toString(36).substr(2, 9)}`;
179
+ const id = `${component.name}-${Math.random().toString(36).slice(2, 11)}`;
164
180
  const newComponent = {
165
181
  ...component,
166
182
  id,
@@ -202,4 +218,19 @@ export const TamboInteractableProvider = ({ children, }) => {
202
218
  export const useTamboInteractable = () => {
203
219
  return useContext(TamboInteractableContext);
204
220
  };
221
+ /**
222
+ * Hook to get a cloned snapshot of the current interactables.
223
+ * Returns a shallow copy of the array with cloned items and props to prevent
224
+ * external mutation from affecting internal state.
225
+ * @returns The current interactables snapshot (cloned).
226
+ */
227
+ export const useCurrentInteractablesSnapshot = () => {
228
+ const { interactableComponents } = useTamboInteractable();
229
+ // Clone the array and each item/props to prevent mutation
230
+ const copy = interactableComponents.map((c) => ({
231
+ ...c,
232
+ props: { ...c.props },
233
+ }));
234
+ return copy;
235
+ };
205
236
  //# sourceMappingURL=tambo-interactable-provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-interactable-provider.js","sourceRoot":"","sources":["../../src/providers/tambo-interactable-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["// react-sdk/src/providers/tambo-interactable-provider.tsx\n\"use client\";\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\nimport { z } from \"zod\";\nimport {\n TamboInteractableComponent,\n type TamboInteractableContext,\n} from \"../model/tambo-interactable\";\nimport { useTamboComponent } from \"./tambo-component-provider\";\n\nconst TamboInteractableContext = createContext<TamboInteractableContext>({\n interactableComponents: [],\n addInteractableComponent: () => \"\",\n removeInteractableComponent: () => {},\n updateInteractableComponentProps: () => {},\n getInteractableComponent: () => undefined,\n getInteractableComponentsByName: () => [],\n clearAllInteractableComponents: () => {},\n});\n\n/**\n * The TamboInteractableProvider manages a list of components that are currently\n * interactable, allowing tambo to interact with them by updating their props. It also registers tools\n * for Tambo to perform CRUD operations on the components list.\n * @param props - The props for the TamboInteractableProvider\n * @param props.children - The children to wrap\n * @returns The TamboInteractableProvider component\n */\nexport const TamboInteractableProvider: React.FC<PropsWithChildren> = ({\n children,\n}) => {\n const [interactableComponents, setInteractableComponents] = useState<\n TamboInteractableComponent[]\n >([]);\n const { registerTool } = useTamboComponent();\n\n useEffect(() => {\n registerTool({\n name: \"get_all_interactable_components\",\n description:\n \"Only use this tool if the user is asking about interactable components.Get all currently interactable components with their details including their current props. These are components that you can interact with on behalf of the user.\",\n tool: () => {\n return {\n components: interactableComponents,\n };\n },\n toolSchema: z.function().returns(\n z.object({\n components: z.array(\n z.object({\n id: z.string(),\n componentName: z.string(),\n props: z.record(z.any()),\n propsSchema: z.object({}).optional(),\n }),\n ),\n }),\n ),\n });\n\n registerTool({\n name: \"get_interactable_component_by_id\",\n description: \"Get a specific interactable component by its ID\",\n tool: (componentId: string) => {\n const component = interactableComponents.find(\n (c) => c.id === componentId,\n );\n\n if (!component) {\n return {\n success: false,\n error: `Component with ID ${componentId} not found`,\n };\n }\n\n return {\n success: true,\n component: {\n id: component.id,\n componentName: component.name,\n props: component.props,\n },\n };\n },\n toolSchema: z\n .function()\n .args(z.string())\n .returns(\n z.object({\n success: z.boolean(),\n component: z\n .object({\n id: z.string(),\n componentName: z.string(),\n props: z.record(z.any()),\n })\n .optional(),\n error: z.string().optional(),\n }),\n ),\n });\n\n registerTool({\n name: \"remove_interactable_component\",\n description: \"Remove an interactable component from the system\",\n tool: (componentId: string) => {\n const component = interactableComponents.find(\n (c) => c.id === componentId,\n );\n\n if (!component) {\n return {\n success: false,\n error: `Component with ID ${componentId} not found`,\n };\n }\n\n setInteractableComponents((prev) =>\n prev.filter((c) => c.id !== componentId),\n );\n\n return {\n success: true,\n componentId,\n removedComponent: {\n id: component.id,\n componentName: component.name,\n props: component.props,\n },\n };\n },\n toolSchema: z\n .function()\n .args(z.string())\n .returns(\n z.object({\n success: z.boolean(),\n componentId: z.string(),\n removedComponent: z.object({\n id: z.string(),\n componentName: z.string(),\n props: z.record(z.any()),\n }),\n error: z.string().optional(),\n }),\n ),\n });\n }, [interactableComponents, registerTool]);\n\n const updateInteractableComponentProps = useCallback(\n (id: string, newProps: Record<string, any>) => {\n let updateResult = \"Updated successfully\";\n\n setInteractableComponents((prev) => {\n const componentExists = prev.some((c) => c.id === id);\n\n if (!componentExists) {\n updateResult = `Error: Component with ID ${id} not found`;\n return prev;\n }\n\n const updatedComponents = prev.map((c) =>\n c.id === id ? { ...c, props: { ...c.props, ...newProps } } : c,\n );\n\n // Check if the update actually changed anything\n const originalComponent = prev.find((c) => c.id === id);\n const updatedComponent = updatedComponents.find((c) => c.id === id);\n\n if (!originalComponent || !updatedComponent) {\n updateResult = `Error: Failed to update component with ID ${id}`;\n return prev;\n }\n\n // Check if props actually changed\n const propsChanged =\n JSON.stringify(originalComponent.props) !==\n JSON.stringify(updatedComponent.props);\n\n if (!propsChanged) {\n updateResult = `Warning: No changes detected for component with ID ${id}. The update might not have worked.`;\n return prev;\n }\n\n return updatedComponents;\n });\n\n return updateResult;\n },\n [],\n );\n\n const registerInteractableComponentUpdateTool = useCallback(\n (component: TamboInteractableComponent) => {\n const schemaForArgs =\n typeof component.propsSchema === \"object\" &&\n \"describe\" in component.propsSchema\n ? component.propsSchema\n : z.object({});\n\n registerTool({\n name: `update_interactable_component_${component.id}`,\n description: `Update the props of interactable component ${component.id} (${component.name})`,\n tool: (componentId: string, newProps: any) => {\n return updateInteractableComponentProps(componentId, newProps);\n },\n toolSchema: z\n .function()\n .args(\n z\n .string()\n .describe(\"The ID of the interactable component to update\"),\n schemaForArgs.describe(\n \"The new props to update the component with\",\n ),\n )\n .returns(z.string()),\n });\n },\n [registerTool, updateInteractableComponentProps],\n );\n\n const addInteractableComponent = useCallback(\n (\n component: Omit<TamboInteractableComponent, \"id\" | \"createdAt\">,\n ): string => {\n const id = `${component.name}-${Math.random().toString(36).substr(2, 9)}`;\n const newComponent: TamboInteractableComponent = {\n ...component,\n id,\n };\n\n registerInteractableComponentUpdateTool(newComponent);\n\n setInteractableComponents((prev) => {\n return [...prev, newComponent];\n });\n\n return id;\n },\n [registerInteractableComponentUpdateTool],\n );\n\n const removeInteractableComponent = useCallback((id: string) => {\n setInteractableComponents((prev) => prev.filter((c) => c.id !== id));\n }, []);\n\n const getInteractableComponent = useCallback(\n (id: string) => {\n return interactableComponents.find((c) => c.id === id);\n },\n [interactableComponents],\n );\n\n const getInteractableComponentsByName = useCallback(\n (componentName: string) => {\n return interactableComponents.filter((c) => c.name === componentName);\n },\n [interactableComponents],\n );\n\n const clearAllInteractableComponents = useCallback(() => {\n setInteractableComponents([]);\n }, []);\n\n const value: TamboInteractableContext = {\n interactableComponents,\n addInteractableComponent,\n removeInteractableComponent,\n updateInteractableComponentProps,\n getInteractableComponent,\n getInteractableComponentsByName,\n clearAllInteractableComponents,\n };\n\n return (\n <TamboInteractableContext.Provider value={value}>\n {children}\n </TamboInteractableContext.Provider>\n );\n};\n\n/**\n * The useTamboInteractable hook provides access to the interactable component\n * management functions.\n * @returns The interactable component management functions\n */\nexport const useTamboInteractable = () => {\n return useContext(TamboInteractableContext);\n};\n"]}
1
+ {"version":3,"file":"tambo-interactable-provider.js","sourceRoot":"","sources":["../../src/providers/tambo-interactable-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["// react-sdk/src/providers/tambo-interactable-provider.tsx\n\"use client\";\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\nimport { z } from \"zod\";\nimport {\n TamboInteractableComponent,\n type TamboInteractableContext,\n} from \"../model/tambo-interactable\";\nimport { useTamboComponent } from \"./tambo-component-provider\";\nimport { useTamboContextHelpers } from \"./tambo-context-helpers-provider\";\nimport { createInteractablesContextHelper } from \"../context-helpers/current-interactables-context-helper\";\n\nconst TamboInteractableContext = createContext<TamboInteractableContext>({\n interactableComponents: [],\n addInteractableComponent: () => \"\",\n removeInteractableComponent: () => {},\n updateInteractableComponentProps: () => {},\n getInteractableComponent: () => undefined,\n getInteractableComponentsByName: () => [],\n clearAllInteractableComponents: () => {},\n});\n\n/**\n * The TamboInteractableProvider manages a list of components that are currently\n * interactable, allowing tambo to interact with them by updating their props. It also registers tools\n * for Tambo to perform CRUD operations on the components list.\n * @param props - The props for the TamboInteractableProvider\n * @param props.children - The children to wrap\n * @returns The TamboInteractableProvider component\n */\nexport const TamboInteractableProvider: React.FC<PropsWithChildren> = ({\n children,\n}) => {\n const [interactableComponents, setInteractableComponents] = useState<\n TamboInteractableComponent[]\n >([]);\n const { registerTool } = useTamboComponent();\n const { addContextHelper, removeContextHelper } = useTamboContextHelpers();\n\n // Create a stable context helper function\n const contextHelper = useCallback(() => {\n return createInteractablesContextHelper(() => interactableComponents)();\n }, [interactableComponents]);\n\n // Register the default interactables context helper\n useEffect(() => {\n addContextHelper(\"interactables\", contextHelper);\n\n return () => {\n removeContextHelper(\"interactables\");\n };\n }, [contextHelper, addContextHelper, removeContextHelper]);\n\n useEffect(() => {\n if (interactableComponents.length > 0) {\n registerTool({\n name: \"get_all_interactable_components\",\n description:\n \"Only use this tool if the user is asking about interactable components.Get all currently interactable components with their details including their current props. These are components that you can interact with on behalf of the user.\",\n tool: () => {\n return {\n components: interactableComponents,\n };\n },\n toolSchema: z.function().returns(\n z.object({\n components: z.array(\n z.object({\n id: z.string(),\n componentName: z.string(),\n props: z.record(z.any()),\n propsSchema: z.object({}).optional(),\n }),\n ),\n }),\n ),\n });\n\n registerTool({\n name: \"get_interactable_component_by_id\",\n description: \"Get a specific interactable component by its ID\",\n tool: (componentId: string) => {\n const component = interactableComponents.find(\n (c) => c.id === componentId,\n );\n\n if (!component) {\n return {\n success: false,\n error: `Component with ID ${componentId} not found`,\n };\n }\n\n return {\n success: true,\n component: {\n id: component.id,\n componentName: component.name,\n props: component.props,\n },\n };\n },\n toolSchema: z\n .function()\n .args(z.string())\n .returns(\n z.object({\n success: z.boolean(),\n component: z\n .object({\n id: z.string(),\n componentName: z.string(),\n props: z.record(z.any()),\n })\n .optional(),\n error: z.string().optional(),\n }),\n ),\n });\n\n registerTool({\n name: \"remove_interactable_component\",\n description: \"Remove an interactable component from the system\",\n tool: (componentId: string) => {\n const component = interactableComponents.find(\n (c) => c.id === componentId,\n );\n\n if (!component) {\n return {\n success: false,\n error: `Component with ID ${componentId} not found`,\n };\n }\n\n setInteractableComponents((prev) =>\n prev.filter((c) => c.id !== componentId),\n );\n\n return {\n success: true,\n componentId,\n removedComponent: {\n id: component.id,\n componentName: component.name,\n props: component.props,\n },\n };\n },\n toolSchema: z\n .function()\n .args(z.string())\n .returns(\n z.object({\n success: z.boolean(),\n componentId: z.string(),\n removedComponent: z.object({\n id: z.string(),\n componentName: z.string(),\n props: z.record(z.any()),\n }),\n error: z.string().optional(),\n }),\n ),\n });\n }\n }, [interactableComponents, registerTool]);\n\n const updateInteractableComponentProps = useCallback(\n (id: string, newProps: Record<string, any>) => {\n let updateResult = \"Updated successfully\";\n\n setInteractableComponents((prev) => {\n const componentExists = prev.some((c) => c.id === id);\n\n if (!componentExists) {\n updateResult = `Error: Component with ID ${id} not found`;\n return prev;\n }\n\n const updatedComponents = prev.map((c) =>\n c.id === id ? { ...c, props: { ...c.props, ...newProps } } : c,\n );\n\n // Check if the update actually changed anything\n const originalComponent = prev.find((c) => c.id === id);\n const updatedComponent = updatedComponents.find((c) => c.id === id);\n\n if (!originalComponent || !updatedComponent) {\n updateResult = `Error: Failed to update component with ID ${id}`;\n return prev;\n }\n\n // Check if props actually changed\n const propsChanged =\n JSON.stringify(originalComponent.props) !==\n JSON.stringify(updatedComponent.props);\n\n if (!propsChanged) {\n updateResult = `Warning: No changes detected for component with ID ${id}. The update might not have worked.`;\n return prev;\n }\n\n return updatedComponents;\n });\n\n return updateResult;\n },\n [],\n );\n\n const registerInteractableComponentUpdateTool = useCallback(\n (component: TamboInteractableComponent) => {\n const schemaForArgs =\n typeof component.propsSchema === \"object\" &&\n \"describe\" in component.propsSchema\n ? component.propsSchema\n : z.object({});\n\n registerTool({\n name: `update_interactable_component_${component.id}`,\n description: `Update the props of interactable component ${component.id} (${component.name})`,\n tool: (componentId: string, newProps: any) => {\n return updateInteractableComponentProps(componentId, newProps);\n },\n toolSchema: z\n .function()\n .args(\n z\n .string()\n .describe(\"The ID of the interactable component to update\"),\n schemaForArgs.describe(\n \"The new props to update the component with\",\n ),\n )\n .returns(z.string()),\n });\n },\n [registerTool, updateInteractableComponentProps],\n );\n\n const addInteractableComponent = useCallback(\n (\n component: Omit<TamboInteractableComponent, \"id\" | \"createdAt\">,\n ): string => {\n const id = `${component.name}-${Math.random().toString(36).slice(2, 11)}`;\n const newComponent: TamboInteractableComponent = {\n ...component,\n id,\n };\n\n registerInteractableComponentUpdateTool(newComponent);\n\n setInteractableComponents((prev) => {\n return [...prev, newComponent];\n });\n\n return id;\n },\n [registerInteractableComponentUpdateTool],\n );\n\n const removeInteractableComponent = useCallback((id: string) => {\n setInteractableComponents((prev) => prev.filter((c) => c.id !== id));\n }, []);\n\n const getInteractableComponent = useCallback(\n (id: string) => {\n return interactableComponents.find((c) => c.id === id);\n },\n [interactableComponents],\n );\n\n const getInteractableComponentsByName = useCallback(\n (componentName: string) => {\n return interactableComponents.filter((c) => c.name === componentName);\n },\n [interactableComponents],\n );\n\n const clearAllInteractableComponents = useCallback(() => {\n setInteractableComponents([]);\n }, []);\n\n const value: TamboInteractableContext = {\n interactableComponents,\n addInteractableComponent,\n removeInteractableComponent,\n updateInteractableComponentProps,\n getInteractableComponent,\n getInteractableComponentsByName,\n clearAllInteractableComponents,\n };\n\n return (\n <TamboInteractableContext.Provider value={value}>\n {children}\n </TamboInteractableContext.Provider>\n );\n};\n\n/**\n * The useTamboInteractable hook provides access to the interactable component\n * management functions.\n * @returns The interactable component management functions\n */\nexport const useTamboInteractable = () => {\n return useContext(TamboInteractableContext);\n};\n\n/**\n * Hook to get a cloned snapshot of the current interactables.\n * Returns a shallow copy of the array with cloned items and props to prevent\n * external mutation from affecting internal state.\n * @returns The current interactables snapshot (cloned).\n */\nexport const useCurrentInteractablesSnapshot = () => {\n const { interactableComponents } = useTamboInteractable();\n\n // Clone the array and each item/props to prevent mutation\n const copy = interactableComponents.map((c) => ({\n ...c,\n props: { ...c.props },\n }));\n\n return copy;\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tambo-ai/react",
3
- "version": "0.46.5",
3
+ "version": "0.48.0",
4
4
  "description": "React client package for Tambo AI",
5
5
  "repository": {
6
6
  "type": "git",
@@ -74,12 +74,12 @@
74
74
  "react-fast-compare": "^3.2.2",
75
75
  "ts-essentials": "^10.1.1",
76
76
  "ts-node": "^10.9.2",
77
- "use-debounce": "^10.0.5",
77
+ "use-debounce": "^10.0.6",
78
78
  "zod": "^3.25.76",
79
79
  "zod-to-json-schema": "^3.24.6"
80
80
  },
81
81
  "devDependencies": {
82
- "@eslint/js": "^9.34.0",
82
+ "@eslint/js": "^9.35.0",
83
83
  "@tambo-ai/eslint-config": "*",
84
84
  "@tambo-ai/typescript-config": "*",
85
85
  "@testing-library/jest-dom": "^6.8.0",
@@ -90,12 +90,12 @@
90
90
  "@types/react": "^18.3.23",
91
91
  "@types/react-dom": "^18.3.7",
92
92
  "concurrently": "^9.2.1",
93
- "eslint": "^9.34.0",
94
- "eslint-plugin-jsdoc": "^54.1.1",
93
+ "eslint": "^9.35.0",
94
+ "eslint-plugin-jsdoc": "^55.0.0",
95
95
  "eslint-plugin-react": "^7.37.5",
96
96
  "eslint-plugin-react-hooks": "^5.1.0",
97
- "jest": "^30.1.1",
98
- "jest-environment-jsdom": "^30.1.1",
97
+ "jest": "^30.1.3",
98
+ "jest-environment-jsdom": "^30.1.2",
99
99
  "lint-staged": "^16.1.5",
100
100
  "prettier": "^3.6.2",
101
101
  "prettier-2": "npm:prettier@^2",
@@ -103,6 +103,6 @@
103
103
  "react-dom": "^18.3.1",
104
104
  "ts-jest": "^29.4.1",
105
105
  "typescript": "^5.9.2",
106
- "typescript-eslint": "^8.41.0"
106
+ "typescript-eslint": "^8.43.0"
107
107
  }
108
108
  }
@@ -1,96 +0,0 @@
1
- /**
2
- * Minimal Model Context Protocol (MCP) client using JSON-RPC 2.0
3
- * Supports only listTools() and callTool() operations
4
- */
5
- /**
6
- * Interface representing a Tool in the MCP
7
- */
8
- export interface Tool {
9
- name: string;
10
- description?: string;
11
- inputSchema: {
12
- type: "object";
13
- properties: Record<string, any>;
14
- required?: string[];
15
- };
16
- annotations?: Record<string, any>;
17
- }
18
- /**
19
- * Response from tools/list endpoint
20
- */
21
- export interface ListToolsResult {
22
- tools: Tool[];
23
- }
24
- /**
25
- * Content type for tool responses
26
- */
27
- export interface ToolContent {
28
- type: string;
29
- text?: string;
30
- annotations?: Record<string, any>;
31
- }
32
- /**
33
- * Response from tools/call endpoint
34
- */
35
- export interface CallToolResult {
36
- content: ToolContent[];
37
- isError?: boolean;
38
- }
39
- /**
40
- * A minimal TypeScript client for the Model Context Protocol (MCP)
41
- *
42
- * This client provides a streamlined interface to communicate with MCP servers
43
- * using JSON-RPC 2.0 over HTTP. It supports listing available tools and calling tools
44
- * with arguments, including support for Server-Sent Events (SSE) streaming responses.
45
- * @example
46
- * ```typescript
47
- * // Basic usage
48
- * const mcpClient = new MCPClient('https://example.com/mcp');
49
- * const tools = await mcpClient.listTools();
50
- * const toolResponse = await mcpClient.callTool('my-tool', { arg1: 'value1' });
51
- *
52
- * // For streaming responses:
53
- * const stream = await mcpClient.callToolStream('streaming-tool', { arg1: 'value1' });
54
- * for await (const chunk of mcpClient.parseStreamingResponses(stream)) {
55
- * console.log('Received chunk:', chunk);
56
- * }
57
- * ```
58
- */
59
- export declare class MCPClient {
60
- private baseUrl;
61
- private headers;
62
- private requestId;
63
- /**
64
- * Creates a new MCP client
65
- * @param url - The base URL of the MCP server
66
- * @param extraHeaders - Optional additional headers to include in requests
67
- */
68
- constructor(url: string, extraHeaders?: Record<string, string>);
69
- /**
70
- * Lists available tools on the MCP server
71
- * @returns Promise resolving to the list of available tools
72
- */
73
- listTools(): Promise<ListToolsResult>;
74
- /**
75
- * Calls a tool with the provided arguments
76
- * @param toolName - The name of the tool to call
77
- * @param args - The arguments to pass to the tool
78
- * @returns Promise resolving to the tool's response
79
- */
80
- callTool(toolName: string, args: any): Promise<CallToolResult>;
81
- /**
82
- * Calls a tool with the provided arguments and returns a stream of results
83
- * @param toolName - The name of the tool to call
84
- * @param args - The arguments to pass to the tool
85
- * @returns ReadableStream of the tool's response
86
- */
87
- callToolStream(toolName: string, args: any): Promise<ReadableStream<Uint8Array>>;
88
- /**
89
- * Parse SSE messages from a stream into JSON-RPC responses
90
- * @param stream - ReadableStream to parse
91
- * @returns AsyncGenerator yielding parsed JSON-RPC responses
92
- * @yields {CallToolResult} The parsed JSON-RPC response
93
- */
94
- parseStreamingResponses(stream: ReadableStream<Uint8Array>): AsyncGenerator<CallToolResult, void, unknown>;
95
- }
96
- //# sourceMappingURL=mcp-tools-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcp-tools-client.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp-tools-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,SAAS,CAAK;IAEtB;;;;OAIG;gBACS,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAS9D;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;IAgC3C;;;;;OAKG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC;IAmCpE;;;;;OAKG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,GAAG,GACR,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAkCtC;;;;;OAKG;IACI,uBAAuB,CAC5B,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GACjC,cAAc,CAAC,cAAc,EAAE,IAAI,EAAE,OAAO,CAAC;CAwCjD"}
@@ -1,178 +0,0 @@
1
- "use strict";
2
- /**
3
- * Minimal Model Context Protocol (MCP) client using JSON-RPC 2.0
4
- * Supports only listTools() and callTool() operations
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.MCPClient = void 0;
8
- /**
9
- * A minimal TypeScript client for the Model Context Protocol (MCP)
10
- *
11
- * This client provides a streamlined interface to communicate with MCP servers
12
- * using JSON-RPC 2.0 over HTTP. It supports listing available tools and calling tools
13
- * with arguments, including support for Server-Sent Events (SSE) streaming responses.
14
- * @example
15
- * ```typescript
16
- * // Basic usage
17
- * const mcpClient = new MCPClient('https://example.com/mcp');
18
- * const tools = await mcpClient.listTools();
19
- * const toolResponse = await mcpClient.callTool('my-tool', { arg1: 'value1' });
20
- *
21
- * // For streaming responses:
22
- * const stream = await mcpClient.callToolStream('streaming-tool', { arg1: 'value1' });
23
- * for await (const chunk of mcpClient.parseStreamingResponses(stream)) {
24
- * console.log('Received chunk:', chunk);
25
- * }
26
- * ```
27
- */
28
- class MCPClient {
29
- baseUrl;
30
- headers;
31
- requestId = 1;
32
- /**
33
- * Creates a new MCP client
34
- * @param url - The base URL of the MCP server
35
- * @param extraHeaders - Optional additional headers to include in requests
36
- */
37
- constructor(url, extraHeaders) {
38
- this.baseUrl = url.endsWith("/") ? url : `${url}/`;
39
- this.headers = {
40
- "Content-Type": "application/json",
41
- Accept: "application/json",
42
- ...(extraHeaders ?? {}),
43
- };
44
- }
45
- /**
46
- * Lists available tools on the MCP server
47
- * @returns Promise resolving to the list of available tools
48
- */
49
- async listTools() {
50
- const jsonRpcRequest = {
51
- jsonrpc: "2.0",
52
- method: "tools/list",
53
- params: {},
54
- id: this.requestId++,
55
- };
56
- const response = await fetch(this.baseUrl, {
57
- method: "POST",
58
- headers: this.headers,
59
- body: JSON.stringify(jsonRpcRequest),
60
- });
61
- if (!response.ok) {
62
- throw new Error(`Failed to list tools: ${response.status} ${response.statusText}`);
63
- }
64
- const jsonRpcResponse = await response.json();
65
- // Handle JSON-RPC error
66
- if (jsonRpcResponse.error) {
67
- throw new Error(`JSON-RPC error: ${jsonRpcResponse.error.code} - ${jsonRpcResponse.error.message}`);
68
- }
69
- return jsonRpcResponse.result;
70
- }
71
- /**
72
- * Calls a tool with the provided arguments
73
- * @param toolName - The name of the tool to call
74
- * @param args - The arguments to pass to the tool
75
- * @returns Promise resolving to the tool's response
76
- */
77
- async callTool(toolName, args) {
78
- const jsonRpcRequest = {
79
- jsonrpc: "2.0",
80
- method: "tools/call",
81
- params: {
82
- name: toolName,
83
- arguments: args,
84
- },
85
- id: this.requestId++,
86
- };
87
- const response = await fetch(this.baseUrl, {
88
- method: "POST",
89
- headers: this.headers,
90
- body: JSON.stringify(jsonRpcRequest),
91
- });
92
- if (!response.ok) {
93
- throw new Error(`Failed to call tool ${toolName}: ${response.status} ${response.statusText}`);
94
- }
95
- const jsonRpcResponse = await response.json();
96
- // Handle JSON-RPC error
97
- if (jsonRpcResponse.error) {
98
- throw new Error(`JSON-RPC error: ${jsonRpcResponse.error.code} - ${jsonRpcResponse.error.message}`);
99
- }
100
- return jsonRpcResponse.result;
101
- }
102
- /**
103
- * Calls a tool with the provided arguments and returns a stream of results
104
- * @param toolName - The name of the tool to call
105
- * @param args - The arguments to pass to the tool
106
- * @returns ReadableStream of the tool's response
107
- */
108
- async callToolStream(toolName, args) {
109
- const jsonRpcRequest = {
110
- jsonrpc: "2.0",
111
- method: "tools/call",
112
- params: {
113
- name: toolName,
114
- arguments: args,
115
- },
116
- id: this.requestId++,
117
- };
118
- const response = await fetch(this.baseUrl, {
119
- method: "POST",
120
- headers: {
121
- ...this.headers,
122
- Accept: "text/event-stream",
123
- },
124
- body: JSON.stringify(jsonRpcRequest),
125
- });
126
- if (!response.ok) {
127
- throw new Error(`Failed to call tool ${toolName}: ${response.status} ${response.statusText}`);
128
- }
129
- if (!response.body) {
130
- throw new Error("Response body is null");
131
- }
132
- // Return the response body as a stream
133
- return response.body;
134
- }
135
- /**
136
- * Parse SSE messages from a stream into JSON-RPC responses
137
- * @param stream - ReadableStream to parse
138
- * @returns AsyncGenerator yielding parsed JSON-RPC responses
139
- * @yields {CallToolResult} The parsed JSON-RPC response
140
- */
141
- async *parseStreamingResponses(stream) {
142
- const reader = stream.getReader();
143
- const decoder = new TextDecoder();
144
- let buffer = "";
145
- try {
146
- while (true) {
147
- const { done, value } = await reader.read();
148
- if (done)
149
- break;
150
- buffer += decoder.decode(value, { stream: true });
151
- // Process complete SSE messages
152
- const lines = buffer.split("\n\n");
153
- buffer = lines.pop() ?? "";
154
- for (const line of lines) {
155
- if (line.startsWith("data: ")) {
156
- const jsonData = line.slice(6).trim();
157
- try {
158
- const jsonRpcResponse = JSON.parse(jsonData);
159
- // Handle JSON-RPC error
160
- if (jsonRpcResponse.error) {
161
- throw new Error(`JSON-RPC error: ${jsonRpcResponse.error.code} - ${jsonRpcResponse.error.message}`);
162
- }
163
- yield jsonRpcResponse.result;
164
- }
165
- catch (e) {
166
- console.error("Failed to parse JSON:", e);
167
- }
168
- }
169
- }
170
- }
171
- }
172
- finally {
173
- reader.releaseLock();
174
- }
175
- }
176
- }
177
- exports.MCPClient = MCPClient;
178
- //# sourceMappingURL=mcp-tools-client.js.map