@tambo-ai/react 0.57.0 → 0.58.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/README.md +36 -0
- package/dist/hooks/react-query-hooks.d.ts +4 -4
- package/dist/hooks/react-query-hooks.js +4 -4
- package/dist/hooks/react-query-hooks.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/dist/mcp/tambo-mcp-provider.js +9 -0
- package/dist/mcp/tambo-mcp-provider.js.map +1 -1
- package/dist/model/component-metadata.d.ts +7 -0
- package/dist/model/component-metadata.d.ts.map +1 -1
- package/dist/model/component-metadata.js.map +1 -1
- package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-provider.js +18 -5
- package/dist/providers/tambo-thread-provider.js.map +1 -1
- package/dist/testing/tools.d.ts +1 -0
- package/dist/testing/tools.d.ts.map +1 -1
- package/dist/util/__tests__/content-parts.test.d.ts +2 -0
- package/dist/util/__tests__/content-parts.test.d.ts.map +1 -0
- package/dist/util/__tests__/content-parts.test.js +47 -0
- package/dist/util/__tests__/content-parts.test.js.map +1 -0
- package/dist/util/content-parts.d.ts +19 -0
- package/dist/util/content-parts.d.ts.map +1 -0
- package/dist/util/content-parts.js +40 -0
- package/dist/util/content-parts.js.map +1 -0
- package/dist/util/tool-caller.d.ts +4 -3
- package/dist/util/tool-caller.d.ts.map +1 -1
- package/dist/util/tool-caller.js +9 -5
- package/dist/util/tool-caller.js.map +1 -1
- package/esm/hooks/react-query-hooks.d.ts +4 -4
- package/esm/hooks/react-query-hooks.js +4 -4
- package/esm/hooks/react-query-hooks.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/esm/mcp/tambo-mcp-provider.js +9 -0
- package/esm/mcp/tambo-mcp-provider.js.map +1 -1
- package/esm/model/component-metadata.d.ts +7 -0
- package/esm/model/component-metadata.d.ts.map +1 -1
- package/esm/model/component-metadata.js.map +1 -1
- package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-provider.js +18 -5
- package/esm/providers/tambo-thread-provider.js.map +1 -1
- package/esm/testing/tools.d.ts +1 -0
- package/esm/testing/tools.d.ts.map +1 -1
- package/esm/util/__tests__/content-parts.test.d.ts +2 -0
- package/esm/util/__tests__/content-parts.test.d.ts.map +1 -0
- package/esm/util/__tests__/content-parts.test.js +45 -0
- package/esm/util/__tests__/content-parts.test.js.map +1 -0
- package/esm/util/content-parts.d.ts +19 -0
- package/esm/util/content-parts.d.ts.map +1 -0
- package/esm/util/content-parts.js +35 -0
- package/esm/util/content-parts.js.map +1 -0
- package/esm/util/tool-caller.d.ts +4 -3
- package/esm/util/tool-caller.d.ts.map +1 -1
- package/esm/util/tool-caller.js +9 -5
- package/esm/util/tool-caller.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -387,6 +387,42 @@ const tools: TamboTool[] = [
|
|
|
387
387
|
</TamboProvider>;
|
|
388
388
|
```
|
|
389
389
|
|
|
390
|
+
#### Advanced: Transforming Tool Responses
|
|
391
|
+
|
|
392
|
+
By default, tool responses are converted to strings and wrapped in a text content part. For tools that return rich content (like images, audio, or mixed media), you can provide a `transformToContent` function to convert the tool's response into an array of content parts:
|
|
393
|
+
|
|
394
|
+
```tsx
|
|
395
|
+
const tools: TamboTool[] = [
|
|
396
|
+
{
|
|
397
|
+
name: "getImageData",
|
|
398
|
+
description: "Fetches image data with metadata",
|
|
399
|
+
tool: async (imageId: string) => {
|
|
400
|
+
const data = await fetchImageData(imageId);
|
|
401
|
+
return {
|
|
402
|
+
url: data.imageUrl,
|
|
403
|
+
description: data.description,
|
|
404
|
+
};
|
|
405
|
+
},
|
|
406
|
+
toolSchema: z
|
|
407
|
+
.function()
|
|
408
|
+
.args(z.string().describe("Image ID"))
|
|
409
|
+
.returns(
|
|
410
|
+
z.object({
|
|
411
|
+
url: z.string(),
|
|
412
|
+
description: z.string(),
|
|
413
|
+
}),
|
|
414
|
+
),
|
|
415
|
+
// Transform the tool response into content parts
|
|
416
|
+
transformToContent: (result) => [
|
|
417
|
+
{ type: "text", text: result.description },
|
|
418
|
+
{ type: "image_url", image_url: { url: result.url } },
|
|
419
|
+
],
|
|
420
|
+
},
|
|
421
|
+
];
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
This feature is particularly useful for MCP (Model Context Protocol) tools, which already return content in the correct format. The MCP integration automatically uses `transformToContent` to pass through rich content.
|
|
425
|
+
|
|
390
426
|
### Using MCP Servers
|
|
391
427
|
|
|
392
428
|
```tsx
|
|
@@ -2,16 +2,16 @@ import { QueryKey, UseMutationOptions, UseMutationResult, UseQueryOptions, UseQu
|
|
|
2
2
|
/**
|
|
3
3
|
* Wrapper around useQuery that uses the internal tambo query client.
|
|
4
4
|
*
|
|
5
|
-
* Use this instead of useQuery from
|
|
6
|
-
* @param options - The options for the query, same as useQuery from
|
|
5
|
+
* Use this instead of useQuery from `@tanstack/react-query`
|
|
6
|
+
* @param options - The options for the query, same as useQuery from `@tanstack/react-query`
|
|
7
7
|
* @returns The query result
|
|
8
8
|
*/
|
|
9
9
|
export declare function useTamboQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>): UseQueryResult<import("@tanstack/react-query").NoInfer<TData>, TError>;
|
|
10
10
|
/**
|
|
11
11
|
* Wrapper around useMutation that uses the internal tambo query client.
|
|
12
12
|
*
|
|
13
|
-
* Use this instead of useMutation from
|
|
14
|
-
* @param options - The options for the mutation, same as useMutation from
|
|
13
|
+
* Use this instead of useMutation from `@tanstack/react-query`
|
|
14
|
+
* @param options - The options for the mutation, same as useMutation from `@tanstack/react-query`
|
|
15
15
|
* @returns The mutation result
|
|
16
16
|
*/
|
|
17
17
|
export declare function useTamboMutation<TData = unknown, TError = Error, TVariables = void, TContext = unknown>(options: UseMutationOptions<TData, TError, TVariables, TContext>): UseMutationResult<TData, TError, TVariables, TContext>;
|
|
@@ -8,8 +8,8 @@ const tambo_client_provider_1 = require("../providers/tambo-client-provider");
|
|
|
8
8
|
/**
|
|
9
9
|
* Wrapper around useQuery that uses the internal tambo query client.
|
|
10
10
|
*
|
|
11
|
-
* Use this instead of useQuery from
|
|
12
|
-
* @param options - The options for the query, same as useQuery from
|
|
11
|
+
* Use this instead of useQuery from `@tanstack/react-query`
|
|
12
|
+
* @param options - The options for the query, same as useQuery from `@tanstack/react-query`
|
|
13
13
|
* @returns The query result
|
|
14
14
|
*/
|
|
15
15
|
function useTamboQuery(options) {
|
|
@@ -19,8 +19,8 @@ function useTamboQuery(options) {
|
|
|
19
19
|
/**
|
|
20
20
|
* Wrapper around useMutation that uses the internal tambo query client.
|
|
21
21
|
*
|
|
22
|
-
* Use this instead of useMutation from
|
|
23
|
-
* @param options - The options for the mutation, same as useMutation from
|
|
22
|
+
* Use this instead of useMutation from `@tanstack/react-query`
|
|
23
|
+
* @param options - The options for the mutation, same as useMutation from `@tanstack/react-query`
|
|
24
24
|
* @returns The mutation result
|
|
25
25
|
*/
|
|
26
26
|
function useTamboMutation(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-query-hooks.js","sourceRoot":"","sources":["../../src/hooks/react-query-hooks.ts"],"names":[],"mappings":";;AAmBA,sCAQC;AASD,4CAQC;AA5CD,gBAAgB;AAChB,uDAQ+B;AAC/B,8EAAyE;AAEzE;;;;;;GAMG;AACH,SAAgB,aAAa,CAK3B,OAAgE;IAChE,MAAM,WAAW,GAAG,IAAA,2CAAmB,GAAE,CAAC;IAC1C,OAAO,IAAA,sBAAQ,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAK9B,OAAgE;IAChE,MAAM,WAAW,GAAG,IAAA,2CAAmB,GAAE,CAAC;IAC1C,OAAO,IAAA,yBAAW,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AAC3C,CAAC","sourcesContent":["// tamboHooks.ts\nimport {\n QueryKey,\n useMutation,\n UseMutationOptions,\n UseMutationResult,\n useQuery,\n UseQueryOptions,\n UseQueryResult,\n} from \"@tanstack/react-query\";\nimport { useTamboQueryClient } from \"../providers/tambo-client-provider\";\n\n/**\n * Wrapper around useQuery that uses the internal tambo query client.\n *\n * Use this instead of useQuery from
|
|
1
|
+
{"version":3,"file":"react-query-hooks.js","sourceRoot":"","sources":["../../src/hooks/react-query-hooks.ts"],"names":[],"mappings":";;AAmBA,sCAQC;AASD,4CAQC;AA5CD,gBAAgB;AAChB,uDAQ+B;AAC/B,8EAAyE;AAEzE;;;;;;GAMG;AACH,SAAgB,aAAa,CAK3B,OAAgE;IAChE,MAAM,WAAW,GAAG,IAAA,2CAAmB,GAAE,CAAC;IAC1C,OAAO,IAAA,sBAAQ,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAK9B,OAAgE;IAChE,MAAM,WAAW,GAAG,IAAA,2CAAmB,GAAE,CAAC;IAC1C,OAAO,IAAA,yBAAW,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AAC3C,CAAC","sourcesContent":["// tamboHooks.ts\nimport {\n QueryKey,\n useMutation,\n UseMutationOptions,\n UseMutationResult,\n useQuery,\n UseQueryOptions,\n UseQueryResult,\n} from \"@tanstack/react-query\";\nimport { useTamboQueryClient } from \"../providers/tambo-client-provider\";\n\n/**\n * Wrapper around useQuery that uses the internal tambo query client.\n *\n * Use this instead of useQuery from `@tanstack/react-query`\n * @param options - The options for the query, same as useQuery from `@tanstack/react-query`\n * @returns The query result\n */\nexport function useTamboQuery<\n TQueryFnData = unknown,\n TError = Error,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>) {\n const queryClient = useTamboQueryClient();\n return useQuery(options, queryClient);\n}\n\n/**\n * Wrapper around useMutation that uses the internal tambo query client.\n *\n * Use this instead of useMutation from `@tanstack/react-query`\n * @param options - The options for the mutation, same as useMutation from `@tanstack/react-query`\n * @returns The mutation result\n */\nexport function useTamboMutation<\n TData = unknown,\n TError = Error,\n TVariables = void,\n TContext = unknown,\n>(options: UseMutationOptions<TData, TError, TVariables, TContext>) {\n const queryClient = useTamboQueryClient();\n return useMutation(options, queryClient);\n}\n\n/**\n * Type alias for the result of a mutation.\n */\nexport type UseTamboMutationResult<\n TData = unknown,\n TError = Error,\n TVariables = void,\n TContext = unknown,\n> = UseMutationResult<TData, TError, TVariables, TContext>;\n\n/**\n * Type alias for the result of a query.\n */\nexport type UseTamboQueryResult<\n TData = unknown,\n TError = Error,\n> = UseQueryResult<TData, TError>;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-mcp-provider.d.ts","sourceRoot":"","sources":["../../src/mcp/tambo-mcp-provider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAEZ,EAAE,EAIH,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"tambo-mcp-provider.d.ts","sourceRoot":"","sources":["../../src/mcp/tambo-mcp-provider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAEZ,EAAE,EAIH,MAAM,OAAO,CAAC;AAIf,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEvD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAsB5D;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACvD,MAAM,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,eAAe,EAAE,KAAK,CAAC;CACxB;AAED,MAAM,MAAM,SAAS,GAAG,kBAAkB,GAAG,eAAe,CAAC;AAG7D;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC;IAChC,UAAU,EAAE,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC;IACvC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAgJA,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,kBAAkB,mBAE9B,CAAC"}
|
|
@@ -37,6 +37,7 @@ exports.useTamboMcpServers = exports.TamboMcpProvider = void 0;
|
|
|
37
37
|
exports.extractErrorMessage = extractErrorMessage;
|
|
38
38
|
const fast_equals_1 = require("fast-equals");
|
|
39
39
|
const react_1 = __importStar(require("react"));
|
|
40
|
+
const content_parts_1 = require("../util/content-parts");
|
|
40
41
|
const tambo_registry_provider_1 = require("../providers/tambo-registry-provider");
|
|
41
42
|
const mcp_client_1 = require("./mcp-client");
|
|
42
43
|
/**
|
|
@@ -158,6 +159,14 @@ const TamboMcpProvider = ({ mcpServers, children }) => {
|
|
|
158
159
|
return result.content;
|
|
159
160
|
},
|
|
160
161
|
toolSchema: tool.inputSchema,
|
|
162
|
+
transformToContent: (content) => {
|
|
163
|
+
// MCP tools can return content in various formats; pass through arrays of content parts
|
|
164
|
+
// unchanged, otherwise stringify into a text content part.
|
|
165
|
+
if ((0, content_parts_1.isContentPartArray)(content)) {
|
|
166
|
+
return content;
|
|
167
|
+
}
|
|
168
|
+
return [{ type: "text", text: (0, content_parts_1.toText)(content) }];
|
|
169
|
+
},
|
|
161
170
|
});
|
|
162
171
|
});
|
|
163
172
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-mcp-provider.js","sourceRoot":"","sources":["../../src/mcp/tambo-mcp-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["import { deepEqual } from \"fast-equals\";\nimport React, {\n createContext,\n FC,\n useContext,\n useEffect,\n useState,\n} from \"react\";\nimport { TamboTool } from \"../model/component-metadata\";\nimport { useTamboRegistry } from \"../providers/tambo-registry-provider\";\nimport { MCPClient, MCPTransport } from \"./mcp-client\";\n\n/**\n * Extracts error message from MCP tool result content.\n * Handles both array and string content formats.\n * Always returns a string, even for invalid/null inputs.\n * @returns The extracted error message as a string\n */\nexport function extractErrorMessage(content: unknown): string {\n if (content === undefined || content === null) {\n return \"Unknown error occurred\";\n }\n\n if (Array.isArray(content)) {\n const textItems = content\n .filter(\n (item) => item && item.type === \"text\" && typeof item.text === \"string\",\n )\n .map((item) => item.text);\n\n return textItems.length > 0\n ? textItems.join(\" \")\n : \"Error occurred but no details provided\";\n }\n\n if (typeof content === \"object\") {\n return JSON.stringify(content);\n }\n\n return `${content}`;\n}\n\nexport interface McpServerInfo {\n name?: string;\n url: string;\n description?: string;\n transport?: MCPTransport;\n customHeaders?: Record<string, string>;\n}\n\nexport interface ConnectedMcpServer extends McpServerInfo {\n client: MCPClient;\n}\n\nexport interface FailedMcpServer extends McpServerInfo {\n client?: never;\n connectionError: Error;\n}\n\nexport type McpServer = ConnectedMcpServer | FailedMcpServer;\n\nconst McpProviderContext = createContext<McpServer[]>([]);\n/**\n * This provider is used to register tools from MCP servers.\n * @returns the wrapped children\n */\nexport const TamboMcpProvider: FC<{\n mcpServers: (McpServerInfo | string)[];\n children: React.ReactNode;\n}> = ({ mcpServers, children }) => {\n const { registerTool } = useTamboRegistry();\n const [connectedMcpServers, setConnectedMcpServers] = useState<McpServer[]>(\n [],\n );\n\n useEffect(() => {\n if (!mcpServers) {\n return;\n }\n async function registerMcpServers(mcpServerInfos: McpServerInfo[]) {\n // Maps tool names to the MCP client that registered them\n const mcpServerMap = new Map<string, McpServer>();\n setConnectedMcpServers((prev) =>\n // remove any servers that are not in the new list\n prev.filter((s) =>\n mcpServerInfos.some((mcpServerInfo) =>\n equalsMcpServer(s, mcpServerInfo),\n ),\n ),\n );\n\n // initialize the MCP clients, converting McpServerInfo -> McpServer\n const mcpServers = await Promise.allSettled(\n mcpServerInfos.map(async (mcpServerInfo): Promise<McpServer> => {\n try {\n const client = await MCPClient.create(\n mcpServerInfo.url,\n mcpServerInfo.transport,\n mcpServerInfo.customHeaders,\n undefined, // no oauth support yet\n undefined, // starting with no session id at first.\n );\n const connectedMcpServer = {\n ...mcpServerInfo,\n client: client,\n };\n // note because the promises may resolve in any order, the resulting\n // array may not be in the same order as the input array\n setConnectedMcpServers((prev) => [\n // replace the server if it already exists\n ...prev.filter((s) => !equalsMcpServer(s, mcpServerInfo)),\n connectedMcpServer,\n ]);\n return connectedMcpServer;\n } catch (error) {\n const failedMcpServer = {\n ...mcpServerInfo,\n connectionError: error as Error,\n };\n // note because the promises may resolve in any order, the resulting\n // array may not be in the same order as the input array\n setConnectedMcpServers((prev) => [\n // replace the server if it already exists\n ...prev.filter((s) => !equalsMcpServer(s, mcpServerInfo)),\n failedMcpServer,\n ]);\n return failedMcpServer;\n }\n }),\n );\n\n // note do not rely on the state\n const connectedMcpServers = mcpServers\n .filter((result) => result.status === \"fulfilled\")\n .map((result) => result.value);\n\n // Now create a map of tool name to MCP client\n const serverToolLists = connectedMcpServers.map(async (mcpServer) => {\n const tools = (await mcpServer.client?.listTools()) ?? [];\n tools.forEach((tool) => {\n mcpServerMap.set(tool.name, mcpServer);\n });\n return tools;\n });\n const toolResults = await Promise.allSettled(serverToolLists);\n\n // Just log the failed tools, we can't do anything about them\n const failedTools = toolResults.filter(\n (result) => result.status === \"rejected\",\n );\n if (failedTools.length > 0) {\n console.error(\n \"Failed to register tools from MCP servers:\",\n failedTools.map((result) => result.reason),\n );\n }\n\n // Register the successful tools\n const allTools = toolResults\n .filter((result) => result.status === \"fulfilled\")\n .map((result) => result.value)\n .flat();\n allTools.forEach((tool) => {\n registerTool({\n description: tool.description ?? \"\",\n name: tool.name,\n tool: async (args: Record<string, unknown>) => {\n const mcpServer = mcpServerMap.get(tool.name);\n if (!mcpServer) {\n // should never happen\n throw new Error(`MCP server for tool ${tool.name} not found`);\n }\n if (!mcpServer.client) {\n // this can't actually happen because the tool can't be registered if the server is not connected\n throw new Error(\n `MCP server for tool ${tool.name} is not connected`,\n );\n }\n const result = await mcpServer.client.callTool(tool.name, args);\n if (result.isError) {\n const errorMessage = extractErrorMessage(result.content);\n throw new Error(errorMessage);\n }\n return result.content;\n },\n toolSchema: tool.inputSchema as TamboTool[\"toolSchema\"],\n });\n });\n }\n\n // normalize the server infos\n const mcpServerInfos = mcpServers.map((mcpServer) =>\n typeof mcpServer === \"string\"\n ? { url: mcpServer, transport: MCPTransport.SSE }\n : mcpServer,\n );\n\n registerMcpServers(mcpServerInfos);\n }, [mcpServers, registerTool]);\n\n return (\n <McpProviderContext.Provider value={connectedMcpServers}>\n {children}\n </McpProviderContext.Provider>\n );\n};\n\n/**\n * Hook to access the actual MCP servers, as they are connected (or fail to\n * connect).\n *\n * You can call methods on the MCP client that is included in the MCP server\n * object.\n *\n * If the server fails to connect, the `client` property will be `undefined` and\n * the `connectionError` property will be set.\n *\n * For example, to forcibly disconnect and reconnect all MCP servers:\n *\n * ```tsx\n * const mcpServers = useTamboMcpServers();\n * mcpServers.forEach((mcpServer) => {\n * mcpServer.client?.reconnect();\n * });\n * ```\n *\n * Note that the MCP servers are not guaranteed to be in the same order as the\n * input array, because they are added as they are connected.\n * @returns The MCP servers\n */\nexport const useTamboMcpServers = () => {\n return useContext(McpProviderContext);\n};\nfunction equalsMcpServer(s: McpServer, mcpServerInfo: McpServerInfo): boolean {\n return (\n s.url === mcpServerInfo.url &&\n s.transport === mcpServerInfo.transport &&\n deepEqual(s.customHeaders, mcpServerInfo.customHeaders)\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tambo-mcp-provider.js","sourceRoot":"","sources":["../../src/mcp/tambo-mcp-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["import { deepEqual } from \"fast-equals\";\nimport React, {\n createContext,\n FC,\n useContext,\n useEffect,\n useState,\n} from \"react\";\nimport { TamboTool } from \"../model/component-metadata\";\nimport { isContentPartArray, toText } from \"../util/content-parts\";\nimport { useTamboRegistry } from \"../providers/tambo-registry-provider\";\nimport { MCPClient, MCPTransport } from \"./mcp-client\";\n\n/**\n * Extracts error message from MCP tool result content.\n * Handles both array and string content formats.\n * Always returns a string, even for invalid/null inputs.\n * @returns The extracted error message as a string\n */\nexport function extractErrorMessage(content: unknown): string {\n if (content === undefined || content === null) {\n return \"Unknown error occurred\";\n }\n\n if (Array.isArray(content)) {\n const textItems = content\n .filter(\n (item) => item && item.type === \"text\" && typeof item.text === \"string\",\n )\n .map((item) => item.text);\n\n return textItems.length > 0\n ? textItems.join(\" \")\n : \"Error occurred but no details provided\";\n }\n\n if (typeof content === \"object\") {\n return JSON.stringify(content);\n }\n\n return `${content}`;\n}\n\nexport interface McpServerInfo {\n name?: string;\n url: string;\n description?: string;\n transport?: MCPTransport;\n customHeaders?: Record<string, string>;\n}\n\nexport interface ConnectedMcpServer extends McpServerInfo {\n client: MCPClient;\n}\n\nexport interface FailedMcpServer extends McpServerInfo {\n client?: never;\n connectionError: Error;\n}\n\nexport type McpServer = ConnectedMcpServer | FailedMcpServer;\n\nconst McpProviderContext = createContext<McpServer[]>([]);\n/**\n * This provider is used to register tools from MCP servers.\n * @returns the wrapped children\n */\nexport const TamboMcpProvider: FC<{\n mcpServers: (McpServerInfo | string)[];\n children: React.ReactNode;\n}> = ({ mcpServers, children }) => {\n const { registerTool } = useTamboRegistry();\n const [connectedMcpServers, setConnectedMcpServers] = useState<McpServer[]>(\n [],\n );\n\n useEffect(() => {\n if (!mcpServers) {\n return;\n }\n async function registerMcpServers(mcpServerInfos: McpServerInfo[]) {\n // Maps tool names to the MCP client that registered them\n const mcpServerMap = new Map<string, McpServer>();\n setConnectedMcpServers((prev) =>\n // remove any servers that are not in the new list\n prev.filter((s) =>\n mcpServerInfos.some((mcpServerInfo) =>\n equalsMcpServer(s, mcpServerInfo),\n ),\n ),\n );\n\n // initialize the MCP clients, converting McpServerInfo -> McpServer\n const mcpServers = await Promise.allSettled(\n mcpServerInfos.map(async (mcpServerInfo): Promise<McpServer> => {\n try {\n const client = await MCPClient.create(\n mcpServerInfo.url,\n mcpServerInfo.transport,\n mcpServerInfo.customHeaders,\n undefined, // no oauth support yet\n undefined, // starting with no session id at first.\n );\n const connectedMcpServer = {\n ...mcpServerInfo,\n client: client,\n };\n // note because the promises may resolve in any order, the resulting\n // array may not be in the same order as the input array\n setConnectedMcpServers((prev) => [\n // replace the server if it already exists\n ...prev.filter((s) => !equalsMcpServer(s, mcpServerInfo)),\n connectedMcpServer,\n ]);\n return connectedMcpServer;\n } catch (error) {\n const failedMcpServer = {\n ...mcpServerInfo,\n connectionError: error as Error,\n };\n // note because the promises may resolve in any order, the resulting\n // array may not be in the same order as the input array\n setConnectedMcpServers((prev) => [\n // replace the server if it already exists\n ...prev.filter((s) => !equalsMcpServer(s, mcpServerInfo)),\n failedMcpServer,\n ]);\n return failedMcpServer;\n }\n }),\n );\n\n // note do not rely on the state\n const connectedMcpServers = mcpServers\n .filter((result) => result.status === \"fulfilled\")\n .map((result) => result.value);\n\n // Now create a map of tool name to MCP client\n const serverToolLists = connectedMcpServers.map(async (mcpServer) => {\n const tools = (await mcpServer.client?.listTools()) ?? [];\n tools.forEach((tool) => {\n mcpServerMap.set(tool.name, mcpServer);\n });\n return tools;\n });\n const toolResults = await Promise.allSettled(serverToolLists);\n\n // Just log the failed tools, we can't do anything about them\n const failedTools = toolResults.filter(\n (result) => result.status === \"rejected\",\n );\n if (failedTools.length > 0) {\n console.error(\n \"Failed to register tools from MCP servers:\",\n failedTools.map((result) => result.reason),\n );\n }\n\n // Register the successful tools\n const allTools = toolResults\n .filter((result) => result.status === \"fulfilled\")\n .map((result) => result.value)\n .flat();\n allTools.forEach((tool) => {\n registerTool({\n description: tool.description ?? \"\",\n name: tool.name,\n tool: async (args: Record<string, unknown>) => {\n const mcpServer = mcpServerMap.get(tool.name);\n if (!mcpServer) {\n // should never happen\n throw new Error(`MCP server for tool ${tool.name} not found`);\n }\n if (!mcpServer.client) {\n // this can't actually happen because the tool can't be registered if the server is not connected\n throw new Error(\n `MCP server for tool ${tool.name} is not connected`,\n );\n }\n const result = await mcpServer.client.callTool(tool.name, args);\n if (result.isError) {\n const errorMessage = extractErrorMessage(result.content);\n throw new Error(errorMessage);\n }\n return result.content;\n },\n toolSchema: tool.inputSchema as TamboTool[\"toolSchema\"],\n transformToContent: (content: unknown) => {\n // MCP tools can return content in various formats; pass through arrays of content parts\n // unchanged, otherwise stringify into a text content part.\n if (isContentPartArray(content)) {\n return content;\n }\n return [{ type: \"text\", text: toText(content) }];\n },\n });\n });\n }\n\n // normalize the server infos\n const mcpServerInfos = mcpServers.map((mcpServer) =>\n typeof mcpServer === \"string\"\n ? { url: mcpServer, transport: MCPTransport.SSE }\n : mcpServer,\n );\n\n registerMcpServers(mcpServerInfos);\n }, [mcpServers, registerTool]);\n\n return (\n <McpProviderContext.Provider value={connectedMcpServers}>\n {children}\n </McpProviderContext.Provider>\n );\n};\n\n/**\n * Hook to access the actual MCP servers, as they are connected (or fail to\n * connect).\n *\n * You can call methods on the MCP client that is included in the MCP server\n * object.\n *\n * If the server fails to connect, the `client` property will be `undefined` and\n * the `connectionError` property will be set.\n *\n * For example, to forcibly disconnect and reconnect all MCP servers:\n *\n * ```tsx\n * const mcpServers = useTamboMcpServers();\n * mcpServers.forEach((mcpServer) => {\n * mcpServer.client?.reconnect();\n * });\n * ```\n *\n * Note that the MCP servers are not guaranteed to be in the same order as the\n * input array, because they are added as they are connected.\n * @returns The MCP servers\n */\nexport const useTamboMcpServers = () => {\n return useContext(McpProviderContext);\n};\nfunction equalsMcpServer(s: McpServer, mcpServerInfo: McpServerInfo): boolean {\n return (\n s.url === mcpServerInfo.url &&\n s.transport === mcpServerInfo.transport &&\n deepEqual(s.customHeaders, mcpServerInfo.customHeaders)\n );\n}\n"]}
|
|
@@ -38,6 +38,13 @@ export interface TamboTool<Args extends z.ZodTuple<any, any> = z.ZodTuple<any, a
|
|
|
38
38
|
description: string;
|
|
39
39
|
tool: (...args: z.infer<Args>) => z.infer<Returns>;
|
|
40
40
|
toolSchema: z.ZodFunction<Args, Returns> | JSONSchemaLite;
|
|
41
|
+
/**
|
|
42
|
+
* Optional function to transform the tool's return value into an array of content parts.
|
|
43
|
+
* If not provided, the return value will be converted to a string and wrapped in a text content part.
|
|
44
|
+
* @param result - The result returned by the tool function
|
|
45
|
+
* @returns An array of content parts to be sent back to the AI
|
|
46
|
+
*/
|
|
47
|
+
transformToContent?: (result: z.infer<Returns>) => TamboAI.Beta.Threads.ChatCompletionContentPart[];
|
|
41
48
|
}
|
|
42
49
|
export type TamboToolAssociations = Record<string, string[]>;
|
|
43
50
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-metadata.d.ts","sourceRoot":"","sources":["../../src/model/component-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,0BAA0B,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,OAAO,KAAK,eAAe,MAAM,oBAAoB,CAAC;AACtD,+FAA+F;AAC/F,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,cAAc,GAAG;IACnD,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;CAC7C,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,4BACf,SAAQ,OAAO,CAAC,4BAA4B;IAC5C,UAAU,EAAE,aAAa,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,mBAAmB,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACtD,UAAU,EAAE,4BAA4B,CAAC;CAC1C;AAED,MAAM,WAAW,mBAAoB,SAAQ,OAAO,CAAC,kBAAkB;IACrE,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAC9B,gBAAgB,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;CACvC;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAEpE,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,GAAG;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,SAAS,CACxB,IAAI,SAAS,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EACxD,OAAO,SAAS,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU;IAE3C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnD,UAAU,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"component-metadata.d.ts","sourceRoot":"","sources":["../../src/model/component-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,0BAA0B,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,OAAO,KAAK,eAAe,MAAM,oBAAoB,CAAC;AACtD,+FAA+F;AAC/F,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,cAAc,GAAG;IACnD,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;CAC7C,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,4BACf,SAAQ,OAAO,CAAC,4BAA4B;IAC5C,UAAU,EAAE,aAAa,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,mBAAmB,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACtD,UAAU,EAAE,4BAA4B,CAAC;CAC1C;AAED,MAAM,WAAW,mBAAoB,SAAQ,OAAO,CAAC,kBAAkB;IACrE,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAC9B,gBAAgB,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;CACvC;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAEpE,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,GAAG;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,SAAS,CACxB,IAAI,SAAS,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,EACxD,OAAO,SAAS,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU;IAE3C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnD,UAAU,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,cAAc,CAAC;IAC1D;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,CACnB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KACrB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,CAAC;CACvD;AAED,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAC7D;;GAEG;AAEH,MAAM,WAAW,cAAc;IAC7B,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAE9B;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,CAAC,UAAU,GAAG,WAAW,CAAC;IACzC;;;;OAIG;IACH,eAAe,CAAC,EAAE,GAAG,CAAC;IACtB,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IACtC,uDAAuD;IACvD,eAAe,CAAC,EAAE,SAAS,EAAE,CAAC;CAC/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-metadata.js","sourceRoot":"","sources":["../../src/model/component-metadata.ts"],"names":[],"mappings":"","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { JSONSchema7 } from \"json-schema\";\nimport { ComponentType } from \"react\";\nimport z from \"zod\";\nimport type zodToJsonSchema from \"zod-to-json-schema\";\n/** Extension of the ToolParameters interface from Tambo AI to include JSONSchema definition */\nexport type ParameterSpec = TamboAI.ToolParameters & {\n schema?: ReturnType<typeof zodToJsonSchema>;\n};\n\n/**\n * Extends the base ContextTool interface from Tambo AI to include schema information\n * for parameter validation using zod-to-json-schema.\n */\nexport interface ComponentContextToolMetadata\n extends TamboAI.ComponentContextToolMetadata {\n parameters: ParameterSpec[];\n}\n\nexport interface ComponentContextTool {\n getComponentContext: (...args: any[]) => Promise<any>;\n definition: ComponentContextToolMetadata;\n}\n\nexport interface RegisteredComponent extends TamboAI.AvailableComponent {\n component: ComponentType<any>;\n loadingComponent?: ComponentType<any>;\n}\n\nexport type ComponentRegistry = Record<string, RegisteredComponent>;\n\nexport type TamboToolRegistry = Record<string, TamboTool>;\n\n/**\n * A JSON Schema that is compatible with the MCP.\n * This is a simplified JSON Schema that is compatible with the MCPClient and the toolSchema.\n *\n * Do not export this type from the SDK.\n */\nexport type JSONSchemaLite = ReturnType<typeof zodToJsonSchema> & {\n description?: string;\n};\n\nexport interface TamboTool<\n Args extends z.ZodTuple<any, any> = z.ZodTuple<any, any>,\n Returns extends z.ZodTypeAny = z.ZodTypeAny,\n> {\n name: string;\n description: string;\n tool: (...args: z.infer<Args>) => z.infer<Returns>;\n toolSchema: z.ZodFunction<Args, Returns> | JSONSchemaLite;\n}\n\nexport type TamboToolAssociations = Record<string, string[]>;\n/**\n * A component that can be registered with the TamboRegistryProvider.\n */\n\nexport interface TamboComponent {\n /** The name of the component */\n name: string;\n /** The description of the component */\n description: string;\n /**\n * The React component to render.\n *\n * Make sure to pass the Component itself, not an instance of the component. For example,\n * if you have a component like this:\n *\n * ```tsx\n * const MyComponent = () => {\n * return <div>My Component</div>;\n * };\n * ```\n *\n * You should pass the `Component`:\n *\n * ```tsx\n * const components = [MyComponent];\n * <TamboRegistryProvider components={components} />\n * ```\n */\n component: ComponentType<any>;\n\n /**\n * A zod schema for the component props. (Recommended)\n * Either this or propsDefinition must be provided, but not both.\n */\n propsSchema?: z.ZodTypeAny | JSONSchema7;\n /**\n * The props definition of the component as a JSON object.\n * Either this or propsSchema must be provided, but not both.\n * @deprecated Use propsSchema instead.\n */\n propsDefinition?: any;\n /** The loading component to render while the component is loading */\n loadingComponent?: ComponentType<any>;\n /** The tools that are associated with the component */\n associatedTools?: TamboTool[];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"component-metadata.js","sourceRoot":"","sources":["../../src/model/component-metadata.ts"],"names":[],"mappings":"","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { JSONSchema7 } from \"json-schema\";\nimport { ComponentType } from \"react\";\nimport z from \"zod\";\nimport type zodToJsonSchema from \"zod-to-json-schema\";\n/** Extension of the ToolParameters interface from Tambo AI to include JSONSchema definition */\nexport type ParameterSpec = TamboAI.ToolParameters & {\n schema?: ReturnType<typeof zodToJsonSchema>;\n};\n\n/**\n * Extends the base ContextTool interface from Tambo AI to include schema information\n * for parameter validation using zod-to-json-schema.\n */\nexport interface ComponentContextToolMetadata\n extends TamboAI.ComponentContextToolMetadata {\n parameters: ParameterSpec[];\n}\n\nexport interface ComponentContextTool {\n getComponentContext: (...args: any[]) => Promise<any>;\n definition: ComponentContextToolMetadata;\n}\n\nexport interface RegisteredComponent extends TamboAI.AvailableComponent {\n component: ComponentType<any>;\n loadingComponent?: ComponentType<any>;\n}\n\nexport type ComponentRegistry = Record<string, RegisteredComponent>;\n\nexport type TamboToolRegistry = Record<string, TamboTool>;\n\n/**\n * A JSON Schema that is compatible with the MCP.\n * This is a simplified JSON Schema that is compatible with the MCPClient and the toolSchema.\n *\n * Do not export this type from the SDK.\n */\nexport type JSONSchemaLite = ReturnType<typeof zodToJsonSchema> & {\n description?: string;\n};\n\nexport interface TamboTool<\n Args extends z.ZodTuple<any, any> = z.ZodTuple<any, any>,\n Returns extends z.ZodTypeAny = z.ZodTypeAny,\n> {\n name: string;\n description: string;\n tool: (...args: z.infer<Args>) => z.infer<Returns>;\n toolSchema: z.ZodFunction<Args, Returns> | JSONSchemaLite;\n /**\n * Optional function to transform the tool's return value into an array of content parts.\n * If not provided, the return value will be converted to a string and wrapped in a text content part.\n * @param result - The result returned by the tool function\n * @returns An array of content parts to be sent back to the AI\n */\n transformToContent?: (\n result: z.infer<Returns>,\n ) => TamboAI.Beta.Threads.ChatCompletionContentPart[];\n}\n\nexport type TamboToolAssociations = Record<string, string[]>;\n/**\n * A component that can be registered with the TamboRegistryProvider.\n */\n\nexport interface TamboComponent {\n /** The name of the component */\n name: string;\n /** The description of the component */\n description: string;\n /**\n * The React component to render.\n *\n * Make sure to pass the Component itself, not an instance of the component. For example,\n * if you have a component like this:\n *\n * ```tsx\n * const MyComponent = () => {\n * return <div>My Component</div>;\n * };\n * ```\n *\n * You should pass the `Component`:\n *\n * ```tsx\n * const components = [MyComponent];\n * <TamboRegistryProvider components={components} />\n * ```\n */\n component: ComponentType<any>;\n\n /**\n * A zod schema for the component props. (Recommended)\n * Either this or propsDefinition must be provided, but not both.\n */\n propsSchema?: z.ZodTypeAny | JSONSchema7;\n /**\n * The props definition of the component as a JSON object.\n * Either this or propsSchema must be provided, but not both.\n * @deprecated Use propsSchema instead.\n */\n propsDefinition?: any;\n /** The loading component to render while the component is loading */\n loadingComponent?: ComponentType<any>;\n /** The tools that are associated with the component */\n associatedTools?: TamboTool[];\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-thread-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-thread-provider.tsx"],"names":[],"mappings":"AACA,OAAO,OAA0B,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,yDAAyD,CAAC;AACjF,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAOlB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"tambo-thread-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-thread-provider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -38,6 +38,7 @@ exports.useTamboThread = exports.useTamboGenerationStage = exports.TamboThreadPr
|
|
|
38
38
|
const typescript_sdk_1 = require("@tambo-ai/typescript-sdk");
|
|
39
39
|
const react_1 = __importStar(require("react"));
|
|
40
40
|
const generate_component_response_1 = require("../model/generate-component-response");
|
|
41
|
+
const content_parts_1 = require("../util/content-parts");
|
|
41
42
|
const generate_component_1 = require("../util/generate-component");
|
|
42
43
|
const registry_1 = require("../util/registry");
|
|
43
44
|
const tool_caller_1 = require("../util/tool-caller");
|
|
@@ -670,14 +671,12 @@ const TamboThreadProvider = ({ children, streaming = true, initialMessages = []
|
|
|
670
671
|
}
|
|
671
672
|
updateThreadStatus(threadId, generate_component_response_1.GenerationStage.FETCHING_CONTEXT);
|
|
672
673
|
const toolCallResponse = await (0, tool_caller_1.handleToolCall)(advanceResponse.responseMessageDto, toolRegistry, onCallUnregisteredTool);
|
|
673
|
-
const
|
|
674
|
-
? toolCallResponse.result
|
|
675
|
-
: JSON.stringify(toolCallResponse.result);
|
|
674
|
+
const contentParts = convertToolResponse(toolCallResponse);
|
|
676
675
|
const toolCallResponseParams = {
|
|
677
676
|
...params,
|
|
678
677
|
messageToAppend: {
|
|
679
678
|
...params.messageToAppend,
|
|
680
|
-
content:
|
|
679
|
+
content: contentParts,
|
|
681
680
|
role: "tool",
|
|
682
681
|
actionType: "tool_response",
|
|
683
682
|
component: advanceResponse.responseMessageDto.component,
|
|
@@ -696,7 +695,7 @@ const TamboThreadProvider = ({ children, streaming = true, initialMessages = []
|
|
|
696
695
|
updateThreadStatus(threadId, generate_component_response_1.GenerationStage.HYDRATING_COMPONENT);
|
|
697
696
|
addThreadMessage({
|
|
698
697
|
threadId: threadId,
|
|
699
|
-
content:
|
|
698
|
+
content: contentParts,
|
|
700
699
|
role: "tool",
|
|
701
700
|
id: crypto.randomUUID(),
|
|
702
701
|
createdAt: new Date().toISOString(),
|
|
@@ -791,4 +790,18 @@ const useTamboThread = () => {
|
|
|
791
790
|
};
|
|
792
791
|
};
|
|
793
792
|
exports.useTamboThread = useTamboThread;
|
|
793
|
+
function convertToolResponse(toolCallResponse) {
|
|
794
|
+
// If the tool call errored, surface that as text so the model reliably sees the error
|
|
795
|
+
if (toolCallResponse.error) {
|
|
796
|
+
return [{ type: "text", text: (0, content_parts_1.toText)(toolCallResponse.result) }];
|
|
797
|
+
}
|
|
798
|
+
// Use custom transform when available
|
|
799
|
+
if (toolCallResponse.tamboTool?.transformToContent) {
|
|
800
|
+
return toolCallResponse.tamboTool.transformToContent(
|
|
801
|
+
// result shape is user-defined; let the transform decide how to handle it
|
|
802
|
+
toolCallResponse.result);
|
|
803
|
+
}
|
|
804
|
+
// Default fallback to stringified text
|
|
805
|
+
return [{ type: "text", text: (0, content_parts_1.toText)(toolCallResponse.result) }];
|
|
806
|
+
}
|
|
794
807
|
//# sourceMappingURL=tambo-thread-provider.js.map
|