@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.
- package/dist/context-helpers/__tests__/context-helpers-provider.test.js +9 -5
- package/dist/context-helpers/__tests__/context-helpers-provider.test.js.map +1 -1
- package/dist/context-helpers/current-interactables-context-helper.d.ts +28 -0
- package/dist/context-helpers/current-interactables-context-helper.d.ts.map +1 -0
- package/dist/context-helpers/current-interactables-context-helper.js +61 -0
- package/dist/context-helpers/current-interactables-context-helper.js.map +1 -0
- package/dist/context-helpers/index.d.ts +1 -0
- package/dist/context-helpers/index.d.ts.map +1 -1
- package/dist/context-helpers/index.js +1 -0
- package/dist/context-helpers/index.js.map +1 -1
- package/dist/context-helpers/registry.d.ts +1 -22
- package/dist/context-helpers/registry.d.ts.map +1 -1
- package/dist/context-helpers/registry.js +1 -35
- package/dist/context-helpers/registry.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/__tests__/tambo-mcp-provider.test.d.ts +2 -0
- package/dist/mcp/__tests__/tambo-mcp-provider.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/tambo-mcp-provider.test.js +115 -0
- package/dist/mcp/__tests__/tambo-mcp-provider.test.js.map +1 -0
- package/dist/mcp/tambo-mcp-provider.d.ts +6 -0
- package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/dist/mcp/tambo-mcp-provider.js +25 -2
- package/dist/mcp/tambo-mcp-provider.js.map +1 -1
- package/dist/providers/__tests__/tambo-context-helpers-provider.test.js +0 -34
- package/dist/providers/__tests__/tambo-context-helpers-provider.test.js.map +1 -1
- package/dist/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.d.ts +2 -0
- package/dist/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.d.ts.map +1 -0
- package/dist/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.js +339 -0
- package/dist/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.js.map +1 -0
- package/dist/providers/__tests__/tambo-interactables-additional-context.test.d.ts +2 -0
- package/dist/providers/__tests__/tambo-interactables-additional-context.test.d.ts.map +1 -0
- package/dist/providers/__tests__/tambo-interactables-additional-context.test.js +299 -0
- package/dist/providers/__tests__/tambo-interactables-additional-context.test.js.map +1 -0
- package/dist/providers/tambo-context-helpers-provider.d.ts +1 -1
- package/dist/providers/tambo-context-helpers-provider.d.ts.map +1 -1
- package/dist/providers/tambo-context-helpers-provider.js +33 -21
- package/dist/providers/tambo-context-helpers-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.d.ts +20 -0
- package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/dist/providers/tambo-interactable-provider.js +117 -85
- package/dist/providers/tambo-interactable-provider.js.map +1 -1
- package/esm/context-helpers/__tests__/context-helpers-provider.test.js +10 -6
- package/esm/context-helpers/__tests__/context-helpers-provider.test.js.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.d.ts +28 -0
- package/esm/context-helpers/current-interactables-context-helper.d.ts.map +1 -0
- package/esm/context-helpers/current-interactables-context-helper.js +56 -0
- package/esm/context-helpers/current-interactables-context-helper.js.map +1 -0
- package/esm/context-helpers/index.d.ts +1 -0
- package/esm/context-helpers/index.d.ts.map +1 -1
- package/esm/context-helpers/index.js +1 -0
- package/esm/context-helpers/index.js.map +1 -1
- package/esm/context-helpers/registry.d.ts +1 -22
- package/esm/context-helpers/registry.d.ts.map +1 -1
- package/esm/context-helpers/registry.js +1 -31
- package/esm/context-helpers/registry.js.map +1 -1
- package/esm/index.d.ts +1 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -1
- package/esm/index.js.map +1 -1
- package/esm/mcp/__tests__/tambo-mcp-provider.test.d.ts +2 -0
- package/esm/mcp/__tests__/tambo-mcp-provider.test.d.ts.map +1 -0
- package/esm/mcp/__tests__/tambo-mcp-provider.test.js +113 -0
- package/esm/mcp/__tests__/tambo-mcp-provider.test.js.map +1 -0
- package/esm/mcp/tambo-mcp-provider.d.ts +6 -0
- package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/esm/mcp/tambo-mcp-provider.js +24 -2
- package/esm/mcp/tambo-mcp-provider.js.map +1 -1
- package/esm/providers/__tests__/tambo-context-helpers-provider.test.js +0 -34
- package/esm/providers/__tests__/tambo-context-helpers-provider.test.js.map +1 -1
- package/esm/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.d.ts +2 -0
- package/esm/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.d.ts.map +1 -0
- package/esm/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.js +334 -0
- package/esm/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.js.map +1 -0
- package/esm/providers/__tests__/tambo-interactables-additional-context.test.d.ts +2 -0
- package/esm/providers/__tests__/tambo-interactables-additional-context.test.d.ts.map +1 -0
- package/esm/providers/__tests__/tambo-interactables-additional-context.test.js +294 -0
- package/esm/providers/__tests__/tambo-interactables-additional-context.test.js.map +1 -0
- package/esm/providers/tambo-context-helpers-provider.d.ts +1 -1
- package/esm/providers/tambo-context-helpers-provider.d.ts.map +1 -1
- package/esm/providers/tambo-context-helpers-provider.js +35 -23
- package/esm/providers/tambo-context-helpers-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +20 -0
- package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/esm/providers/tambo-interactable-provider.js +115 -84
- package/esm/providers/tambo-interactable-provider.js.map +1 -1
- package/package.json +8 -8
- package/dist/mcp/mcp-tools-client.d.ts +0 -96
- package/dist/mcp/mcp-tools-client.d.ts.map +0 -1
- package/dist/mcp/mcp-tools-client.js +0 -178
- package/dist/mcp/mcp-tools-client.js.map +0 -1
- package/esm/mcp/mcp-tools-client.d.ts +0 -96
- package/esm/mcp/mcp-tools-client.d.ts.map +0 -1
- package/esm/mcp/mcp-tools-client.js +0 -174
- 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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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:
|
|
52
|
-
|
|
71
|
+
success: true,
|
|
72
|
+
component: {
|
|
73
|
+
id: component.id,
|
|
74
|
+
componentName: component.name,
|
|
75
|
+
props: component.props,
|
|
76
|
+
},
|
|
53
77
|
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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:
|
|
87
|
-
|
|
107
|
+
success: true,
|
|
108
|
+
componentId,
|
|
109
|
+
removedComponent: {
|
|
110
|
+
id: component.id,
|
|
111
|
+
componentName: component.name,
|
|
112
|
+
props: component.props,
|
|
113
|
+
},
|
|
88
114
|
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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).
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
94
|
-
"eslint-plugin-jsdoc": "^
|
|
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.
|
|
98
|
-
"jest-environment-jsdom": "^30.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.
|
|
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
|