@tambo-ai/react 0.71.0 → 0.72.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 (83) hide show
  1. package/dist/v1/hooks/use-tambo-v1-component-state.d.ts +44 -0
  2. package/dist/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -0
  3. package/dist/v1/hooks/use-tambo-v1-component-state.js +134 -0
  4. package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -0
  5. package/dist/v1/hooks/use-tambo-v1-component-state.test.d.ts +2 -0
  6. package/dist/v1/hooks/use-tambo-v1-component-state.test.d.ts.map +1 -0
  7. package/dist/v1/hooks/use-tambo-v1-component-state.test.js +292 -0
  8. package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -0
  9. package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts +62 -0
  10. package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -0
  11. package/dist/v1/hooks/use-tambo-v1-thread-input.js +76 -0
  12. package/dist/v1/hooks/use-tambo-v1-thread-input.js.map +1 -0
  13. package/dist/v1/hooks/use-tambo-v1-thread-input.test.d.ts +2 -0
  14. package/dist/v1/hooks/use-tambo-v1-thread-input.test.d.ts.map +1 -0
  15. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +168 -0
  16. package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -0
  17. package/dist/v1/index.d.ts +23 -12
  18. package/dist/v1/index.d.ts.map +1 -1
  19. package/dist/v1/index.js +48 -14
  20. package/dist/v1/index.js.map +1 -1
  21. package/dist/v1/providers/tambo-v1-provider.d.ts +43 -1
  22. package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  23. package/dist/v1/providers/tambo-v1-provider.js +24 -3
  24. package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
  25. package/dist/v1/providers/tambo-v1-provider.test.js +58 -0
  26. package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
  27. package/dist/v1/types/message.d.ts +27 -2
  28. package/dist/v1/types/message.d.ts.map +1 -1
  29. package/dist/v1/types/message.js.map +1 -1
  30. package/dist/v1/utils/component-renderer.d.ts +89 -0
  31. package/dist/v1/utils/component-renderer.d.ts.map +1 -0
  32. package/dist/v1/utils/component-renderer.js +216 -0
  33. package/dist/v1/utils/component-renderer.js.map +1 -0
  34. package/dist/v1/utils/component-renderer.test.d.ts +2 -0
  35. package/dist/v1/utils/component-renderer.test.d.ts.map +1 -0
  36. package/dist/v1/utils/component-renderer.test.js +380 -0
  37. package/dist/v1/utils/component-renderer.test.js.map +1 -0
  38. package/dist/v1/utils/event-accumulator.js +28 -8
  39. package/dist/v1/utils/event-accumulator.js.map +1 -1
  40. package/dist/v1/utils/event-accumulator.test.js +201 -6
  41. package/dist/v1/utils/event-accumulator.test.js.map +1 -1
  42. package/esm/v1/hooks/use-tambo-v1-component-state.d.ts +44 -0
  43. package/esm/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -0
  44. package/esm/v1/hooks/use-tambo-v1-component-state.js +131 -0
  45. package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -0
  46. package/esm/v1/hooks/use-tambo-v1-component-state.test.d.ts +2 -0
  47. package/esm/v1/hooks/use-tambo-v1-component-state.test.d.ts.map +1 -0
  48. package/esm/v1/hooks/use-tambo-v1-component-state.test.js +290 -0
  49. package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -0
  50. package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts +62 -0
  51. package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -0
  52. package/esm/v1/hooks/use-tambo-v1-thread-input.js +73 -0
  53. package/esm/v1/hooks/use-tambo-v1-thread-input.js.map +1 -0
  54. package/esm/v1/hooks/use-tambo-v1-thread-input.test.d.ts +2 -0
  55. package/esm/v1/hooks/use-tambo-v1-thread-input.test.d.ts.map +1 -0
  56. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +166 -0
  57. package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -0
  58. package/esm/v1/index.d.ts +23 -12
  59. package/esm/v1/index.d.ts.map +1 -1
  60. package/esm/v1/index.js +31 -12
  61. package/esm/v1/index.js.map +1 -1
  62. package/esm/v1/providers/tambo-v1-provider.d.ts +43 -1
  63. package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
  64. package/esm/v1/providers/tambo-v1-provider.js +24 -4
  65. package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
  66. package/esm/v1/providers/tambo-v1-provider.test.js +59 -1
  67. package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
  68. package/esm/v1/types/message.d.ts +27 -2
  69. package/esm/v1/types/message.d.ts.map +1 -1
  70. package/esm/v1/types/message.js.map +1 -1
  71. package/esm/v1/utils/component-renderer.d.ts +89 -0
  72. package/esm/v1/utils/component-renderer.d.ts.map +1 -0
  73. package/esm/v1/utils/component-renderer.js +175 -0
  74. package/esm/v1/utils/component-renderer.js.map +1 -0
  75. package/esm/v1/utils/component-renderer.test.d.ts +2 -0
  76. package/esm/v1/utils/component-renderer.test.d.ts.map +1 -0
  77. package/esm/v1/utils/component-renderer.test.js +375 -0
  78. package/esm/v1/utils/component-renderer.test.js.map +1 -0
  79. package/esm/v1/utils/event-accumulator.js +28 -8
  80. package/esm/v1/utils/event-accumulator.js.map +1 -1
  81. package/esm/v1/utils/event-accumulator.test.js +201 -6
  82. package/esm/v1/utils/event-accumulator.test.js.map +1 -1
  83. package/package.json +1 -1
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  };
35
35
  })();
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.useContextKey = useContextKey;
37
38
  exports.TamboV1Provider = TamboV1Provider;
38
39
  /**
39
40
  * TamboV1Provider - Main Provider for v1 API
@@ -41,6 +42,7 @@ exports.TamboV1Provider = TamboV1Provider;
41
42
  * Composes the necessary providers for the v1 SDK:
42
43
  * - TamboClientProvider: API client and authentication
43
44
  * - TamboRegistryProvider: Component and tool registration
45
+ * - TamboContextHelpersProvider: Context helper functions
44
46
  * - TamboV1StreamProvider: Streaming state management
45
47
  *
46
48
  * This provider should wrap your entire application or the portion
@@ -50,7 +52,19 @@ const react_1 = __importStar(require("react"));
50
52
  const react_query_1 = require("@tanstack/react-query");
51
53
  const tambo_client_provider_1 = require("../../providers/tambo-client-provider");
52
54
  const tambo_registry_provider_1 = require("../../providers/tambo-registry-provider");
55
+ const tambo_context_helpers_provider_1 = require("../../providers/tambo-context-helpers-provider");
53
56
  const tambo_v1_stream_context_1 = require("./tambo-v1-stream-context");
57
+ /**
58
+ * Context for providing contextKey to child components.
59
+ */
60
+ const ContextKeyContext = (0, react_1.createContext)(undefined);
61
+ /**
62
+ * Hook to access the contextKey from TamboV1Provider.
63
+ * @returns The contextKey if provided, undefined otherwise
64
+ */
65
+ function useContextKey() {
66
+ return (0, react_1.useContext)(ContextKeyContext);
67
+ }
54
68
  /**
55
69
  * Main provider for the Tambo v1 SDK.
56
70
  *
@@ -70,6 +84,11 @@ const tambo_v1_stream_context_1 = require("./tambo-v1-stream-context");
70
84
  * @param props.tools - Tools to register for client-side execution
71
85
  * @param props.mcpServers - MCP servers to register for additional tools/resources
72
86
  * @param props.onCallUnregisteredTool - Callback for handling unknown tool calls
87
+ * @param props.resources - Static resources to register with the AI
88
+ * @param props.listResources - Dynamic resource search function (must be paired with getResource)
89
+ * @param props.getResource - Dynamic resource fetch function (must be paired with listResources)
90
+ * @param props.contextHelpers - Configuration for context helper functions
91
+ * @param props.contextKey - Optional context key for thread scoping/isolation
73
92
  * @param props.queryClient - Optional custom React Query client
74
93
  * @param props.children - Child components
75
94
  * @returns Provider component tree
@@ -90,7 +109,7 @@ const tambo_v1_stream_context_1 = require("./tambo-v1-stream-context");
90
109
  * }
91
110
  * ```
92
111
  */
93
- function TamboV1Provider({ apiKey, tamboUrl, environment, userToken, components, tools, mcpServers, onCallUnregisteredTool, queryClient, children, }) {
112
+ function TamboV1Provider({ apiKey, tamboUrl, environment, userToken, components, tools, mcpServers, onCallUnregisteredTool, resources, listResources, getResource, contextHelpers, contextKey, queryClient, children, }) {
94
113
  // Create a stable default QueryClient if none provided.
95
114
  // Using useState to avoid SSR issues with module-level singletons.
96
115
  const [defaultQueryClient] = (0, react_1.useState)(() => new react_query_1.QueryClient({
@@ -104,7 +123,9 @@ function TamboV1Provider({ apiKey, tamboUrl, environment, userToken, components,
104
123
  const client = queryClient ?? defaultQueryClient;
105
124
  return (react_1.default.createElement(react_query_1.QueryClientProvider, { client: client },
106
125
  react_1.default.createElement(tambo_client_provider_1.TamboClientProvider, { apiKey: apiKey, tamboUrl: tamboUrl, environment: environment, userToken: userToken },
107
- react_1.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: components, tools: tools, mcpServers: mcpServers, onCallUnregisteredTool: onCallUnregisteredTool },
108
- react_1.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children)))));
126
+ react_1.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: components, tools: tools, mcpServers: mcpServers, onCallUnregisteredTool: onCallUnregisteredTool, resources: resources, listResources: listResources, getResource: getResource },
127
+ react_1.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: contextHelpers },
128
+ react_1.default.createElement(ContextKeyContext.Provider, { value: contextKey },
129
+ react_1.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children)))))));
109
130
  }
110
131
  //# sourceMappingURL=tambo-v1-provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-v1-provider.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6Gb,0CA+CC;AA1JD;;;;;;;;;;GAUG;AAEH,+CAAgE;AAChE,uDAAyE;AACzE,iFAG+C;AAC/C,qFAGiD;AAEjD,uEAAkE;AA6ClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,SAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,QAAQ,EACR,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,UAAU,EACV,sBAAsB,EACtB,WAAW,EACX,QAAQ,GACgC;IACxC,wDAAwD;IACxD,mEAAmE;IACnE,MAAM,CAAC,kBAAkB,CAAC,GAAG,IAAA,gBAAQ,EACnC,GAAG,EAAE,CACH,IAAI,yBAAW,CAAC;QACd,cAAc,EAAE;YACd,OAAO,EAAE;gBACP,SAAS,EAAE,IAAI;gBACf,KAAK,EAAE,CAAC;aACT;SACF;KACF,CAAC,CACL,CAAC;IAEF,MAAM,MAAM,GAAG,WAAW,IAAI,kBAAkB,CAAC;IAEjD,OAAO,CACL,8BAAC,iCAAmB,IAAC,MAAM,EAAE,MAAM;QACjC,8BAAC,2CAAmB,IAClB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS;YAEpB,8BAAC,+CAAqB,IACpB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,sBAAsB,EAAE,sBAAsB;gBAE9C,8BAAC,+CAAqB,QAAE,QAAQ,CAAyB,CACnC,CACJ,CACF,CACvB,CAAC;AACJ,CAAC","sourcesContent":["\"use client\";\n\n/**\n * TamboV1Provider - Main Provider for v1 API\n *\n * Composes the necessary providers for the v1 SDK:\n * - TamboClientProvider: API client and authentication\n * - TamboRegistryProvider: Component and tool registration\n * - TamboV1StreamProvider: Streaming state management\n *\n * This provider should wrap your entire application or the portion\n * that needs access to Tambo v1 functionality.\n */\n\nimport React, { type PropsWithChildren, useState } from \"react\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport {\n TamboClientProvider,\n type TamboClientProviderProps,\n} from \"../../providers/tambo-client-provider\";\nimport {\n TamboRegistryProvider,\n type TamboRegistryProviderProps,\n} from \"../../providers/tambo-registry-provider\";\nimport type { McpServerInfo } from \"../../model/mcp-server-info\";\nimport { TamboV1StreamProvider } from \"./tambo-v1-stream-context\";\n\n/**\n * Props for TamboV1Provider\n */\nexport interface TamboV1ProviderProps extends Pick<\n TamboClientProviderProps,\n \"apiKey\" | \"tamboUrl\" | \"environment\" | \"userToken\"\n> {\n /**\n * Components to register with the registry.\n * These will be available for the AI to use in responses.\n */\n components?: TamboRegistryProviderProps[\"components\"];\n\n /**\n * Tools to register with the registry.\n * These will be executed client-side when requested by the AI.\n */\n tools?: TamboRegistryProviderProps[\"tools\"];\n\n /**\n * MCP servers to register with the registry.\n * These provide additional tools and resources from MCP-compatible servers.\n */\n mcpServers?: (McpServerInfo | string)[];\n\n /**\n * Callback function called when an unregistered tool is called.\n * If not provided, an error will be thrown for unknown tools.\n */\n onCallUnregisteredTool?: TamboRegistryProviderProps[\"onCallUnregisteredTool\"];\n\n /**\n * Optional custom QueryClient instance.\n * If not provided, a default client will be created.\n */\n queryClient?: QueryClient;\n\n /**\n * Children components\n */\n children: React.ReactNode;\n}\n\n/**\n * Main provider for the Tambo v1 SDK.\n *\n * Composes TamboClientProvider, TamboRegistryProvider, and TamboV1StreamProvider\n * to provide a complete context for building AI-powered applications.\n *\n * Threads are managed dynamically through useTamboV1() hook functions:\n * - startNewThread() - Begin a new conversation\n * - switchThread(threadId) - Switch to an existing thread\n * - initThread(threadId) - Initialize a thread for receiving events\n * @param props - Provider configuration\n * @param props.apiKey - Tambo API key for authentication\n * @param props.tamboUrl - Optional custom Tambo API URL\n * @param props.environment - Optional environment configuration\n * @param props.userToken - Optional OAuth token for user authentication\n * @param props.components - Components to register with the AI\n * @param props.tools - Tools to register for client-side execution\n * @param props.mcpServers - MCP servers to register for additional tools/resources\n * @param props.onCallUnregisteredTool - Callback for handling unknown tool calls\n * @param props.queryClient - Optional custom React Query client\n * @param props.children - Child components\n * @returns Provider component tree\n * @example\n * ```tsx\n * import { TamboV1Provider } from '@tambo-ai/react/v1';\n *\n * function App() {\n * return (\n * <TamboV1Provider\n * apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}\n * components={[WeatherCard, StockChart]}\n * tools={[searchTool, calculatorTool]}\n * >\n * <ChatInterface />\n * </TamboV1Provider>\n * );\n * }\n * ```\n */\nexport function TamboV1Provider({\n apiKey,\n tamboUrl,\n environment,\n userToken,\n components,\n tools,\n mcpServers,\n onCallUnregisteredTool,\n queryClient,\n children,\n}: PropsWithChildren<TamboV1ProviderProps>) {\n // Create a stable default QueryClient if none provided.\n // Using useState to avoid SSR issues with module-level singletons.\n const [defaultQueryClient] = useState(\n () =>\n new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 1000,\n retry: 1,\n },\n },\n }),\n );\n\n const client = queryClient ?? defaultQueryClient;\n\n return (\n <QueryClientProvider client={client}>\n <TamboClientProvider\n apiKey={apiKey}\n tamboUrl={tamboUrl}\n environment={environment}\n userToken={userToken}\n >\n <TamboRegistryProvider\n components={components}\n tools={tools}\n mcpServers={mcpServers}\n onCallUnregisteredTool={onCallUnregisteredTool}\n >\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </TamboRegistryProvider>\n </TamboClientProvider>\n </QueryClientProvider>\n );\n}\n"]}
1
+ {"version":3,"file":"tambo-v1-provider.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDb,sCAEC;AA2HD,0CA2DC;AAtOD;;;;;;;;;;;GAWG;AAEH,+CAKe;AACf,uDAAyE;AACzE,iFAG+C;AAC/C,qFAGiD;AACjD,mGAA6F;AAO7F,uEAAkE;AAElE;;GAEG;AACH,MAAM,iBAAiB,GAAG,IAAA,qBAAa,EAAqB,SAAS,CAAC,CAAC;AAEvE;;;GAGG;AACH,SAAgB,aAAa;IAC3B,OAAO,IAAA,kBAAU,EAAC,iBAAiB,CAAC,CAAC;AACvC,CAAC;AA+ED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,SAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,QAAQ,EACR,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,UAAU,EACV,sBAAsB,EACtB,SAAS,EACT,aAAa,EACb,WAAW,EACX,cAAc,EACd,UAAU,EACV,WAAW,EACX,QAAQ,GACgC;IACxC,wDAAwD;IACxD,mEAAmE;IACnE,MAAM,CAAC,kBAAkB,CAAC,GAAG,IAAA,gBAAQ,EACnC,GAAG,EAAE,CACH,IAAI,yBAAW,CAAC;QACd,cAAc,EAAE;YACd,OAAO,EAAE;gBACP,SAAS,EAAE,IAAI;gBACf,KAAK,EAAE,CAAC;aACT;SACF;KACF,CAAC,CACL,CAAC;IAEF,MAAM,MAAM,GAAG,WAAW,IAAI,kBAAkB,CAAC;IAEjD,OAAO,CACL,8BAAC,iCAAmB,IAAC,MAAM,EAAE,MAAM;QACjC,8BAAC,2CAAmB,IAClB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS;YAEpB,8BAAC,+CAAqB,IACpB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,sBAAsB,EAAE,sBAAsB,EAC9C,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW;gBAExB,8BAAC,4DAA2B,IAAC,cAAc,EAAE,cAAc;oBACzD,8BAAC,iBAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,UAAU;wBAC3C,8BAAC,+CAAqB,QAAE,QAAQ,CAAyB,CAC9B,CACD,CACR,CACJ,CACF,CACvB,CAAC;AACJ,CAAC","sourcesContent":["\"use client\";\n\n/**\n * TamboV1Provider - Main Provider for v1 API\n *\n * Composes the necessary providers for the v1 SDK:\n * - TamboClientProvider: API client and authentication\n * - TamboRegistryProvider: Component and tool registration\n * - TamboContextHelpersProvider: Context helper functions\n * - TamboV1StreamProvider: Streaming state management\n *\n * This provider should wrap your entire application or the portion\n * that needs access to Tambo v1 functionality.\n */\n\nimport React, {\n createContext,\n useContext,\n type PropsWithChildren,\n useState,\n} from \"react\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport {\n TamboClientProvider,\n type TamboClientProviderProps,\n} from \"../../providers/tambo-client-provider\";\nimport {\n TamboRegistryProvider,\n type TamboRegistryProviderProps,\n} from \"../../providers/tambo-registry-provider\";\nimport { TamboContextHelpersProvider } from \"../../providers/tambo-context-helpers-provider\";\nimport type { ContextHelpers } from \"../../context-helpers\";\nimport type { McpServerInfo } from \"../../model/mcp-server-info\";\nimport type {\n ListResourceItem,\n ResourceSource,\n} from \"../../model/resource-info\";\nimport { TamboV1StreamProvider } from \"./tambo-v1-stream-context\";\n\n/**\n * Context for providing contextKey to child components.\n */\nconst ContextKeyContext = createContext<string | undefined>(undefined);\n\n/**\n * Hook to access the contextKey from TamboV1Provider.\n * @returns The contextKey if provided, undefined otherwise\n */\nexport function useContextKey(): string | undefined {\n return useContext(ContextKeyContext);\n}\n\n/**\n * Props for TamboV1Provider\n */\nexport interface TamboV1ProviderProps extends Pick<\n TamboClientProviderProps,\n \"apiKey\" | \"tamboUrl\" | \"environment\" | \"userToken\"\n> {\n /**\n * Components to register with the registry.\n * These will be available for the AI to use in responses.\n */\n components?: TamboRegistryProviderProps[\"components\"];\n\n /**\n * Tools to register with the registry.\n * These will be executed client-side when requested by the AI.\n */\n tools?: TamboRegistryProviderProps[\"tools\"];\n\n /**\n * MCP servers to register with the registry.\n * These provide additional tools and resources from MCP-compatible servers.\n */\n mcpServers?: (McpServerInfo | string)[];\n\n /**\n * Callback function called when an unregistered tool is called.\n * If not provided, an error will be thrown for unknown tools.\n */\n onCallUnregisteredTool?: TamboRegistryProviderProps[\"onCallUnregisteredTool\"];\n\n /**\n * Static resources to register with the registry.\n * These will be available for the AI to access.\n */\n resources?: ListResourceItem[];\n\n /**\n * Dynamic resource search function.\n * Must be paired with getResource.\n * Called when searching for resources dynamically.\n */\n listResources?: ResourceSource[\"listResources\"];\n\n /**\n * Dynamic resource fetch function.\n * Must be paired with listResources.\n * Called when fetching a specific resource by URI.\n */\n getResource?: ResourceSource[\"getResource\"];\n\n /**\n * Configuration for context helpers.\n * A dictionary of functions that provide additional context to the AI.\n * Each key becomes the context name, and the function returns the value.\n */\n contextHelpers?: ContextHelpers;\n\n /**\n * Optional context key for thread scoping/isolation.\n * Threads created with the same contextKey are grouped together.\n * Useful for multi-tenant applications or separating conversation contexts.\n */\n contextKey?: string;\n\n /**\n * Optional custom QueryClient instance.\n * If not provided, a default client will be created.\n */\n queryClient?: QueryClient;\n\n /**\n * Children components\n */\n children: React.ReactNode;\n}\n\n/**\n * Main provider for the Tambo v1 SDK.\n *\n * Composes TamboClientProvider, TamboRegistryProvider, and TamboV1StreamProvider\n * to provide a complete context for building AI-powered applications.\n *\n * Threads are managed dynamically through useTamboV1() hook functions:\n * - startNewThread() - Begin a new conversation\n * - switchThread(threadId) - Switch to an existing thread\n * - initThread(threadId) - Initialize a thread for receiving events\n * @param props - Provider configuration\n * @param props.apiKey - Tambo API key for authentication\n * @param props.tamboUrl - Optional custom Tambo API URL\n * @param props.environment - Optional environment configuration\n * @param props.userToken - Optional OAuth token for user authentication\n * @param props.components - Components to register with the AI\n * @param props.tools - Tools to register for client-side execution\n * @param props.mcpServers - MCP servers to register for additional tools/resources\n * @param props.onCallUnregisteredTool - Callback for handling unknown tool calls\n * @param props.resources - Static resources to register with the AI\n * @param props.listResources - Dynamic resource search function (must be paired with getResource)\n * @param props.getResource - Dynamic resource fetch function (must be paired with listResources)\n * @param props.contextHelpers - Configuration for context helper functions\n * @param props.contextKey - Optional context key for thread scoping/isolation\n * @param props.queryClient - Optional custom React Query client\n * @param props.children - Child components\n * @returns Provider component tree\n * @example\n * ```tsx\n * import { TamboV1Provider } from '@tambo-ai/react/v1';\n *\n * function App() {\n * return (\n * <TamboV1Provider\n * apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}\n * components={[WeatherCard, StockChart]}\n * tools={[searchTool, calculatorTool]}\n * >\n * <ChatInterface />\n * </TamboV1Provider>\n * );\n * }\n * ```\n */\nexport function TamboV1Provider({\n apiKey,\n tamboUrl,\n environment,\n userToken,\n components,\n tools,\n mcpServers,\n onCallUnregisteredTool,\n resources,\n listResources,\n getResource,\n contextHelpers,\n contextKey,\n queryClient,\n children,\n}: PropsWithChildren<TamboV1ProviderProps>) {\n // Create a stable default QueryClient if none provided.\n // Using useState to avoid SSR issues with module-level singletons.\n const [defaultQueryClient] = useState(\n () =>\n new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 1000,\n retry: 1,\n },\n },\n }),\n );\n\n const client = queryClient ?? defaultQueryClient;\n\n return (\n <QueryClientProvider client={client}>\n <TamboClientProvider\n apiKey={apiKey}\n tamboUrl={tamboUrl}\n environment={environment}\n userToken={userToken}\n >\n <TamboRegistryProvider\n components={components}\n tools={tools}\n mcpServers={mcpServers}\n onCallUnregisteredTool={onCallUnregisteredTool}\n resources={resources}\n listResources={listResources}\n getResource={getResource}\n >\n <TamboContextHelpersProvider contextHelpers={contextHelpers}>\n <ContextKeyContext.Provider value={contextKey}>\n <TamboV1StreamProvider>{children}</TamboV1StreamProvider>\n </ContextKeyContext.Provider>\n </TamboContextHelpersProvider>\n </TamboRegistryProvider>\n </TamboClientProvider>\n </QueryClientProvider>\n );\n}\n"]}
@@ -9,6 +9,7 @@ const react_2 = __importDefault(require("react"));
9
9
  const zod_1 = require("zod");
10
10
  const tambo_client_provider_1 = require("../../providers/tambo-client-provider");
11
11
  const tambo_registry_provider_1 = require("../../providers/tambo-registry-provider");
12
+ const tambo_context_helpers_provider_1 = require("../../providers/tambo-context-helpers-provider");
12
13
  const tambo_v1_stream_context_1 = require("./tambo-v1-stream-context");
13
14
  const tambo_v1_provider_1 = require("./tambo-v1-provider");
14
15
  // Mock the client provider to capture the apiKey
@@ -119,5 +120,62 @@ describe("TamboV1Provider", () => {
119
120
  const { result } = (0, react_1.renderHook)(() => (0, tambo_registry_provider_1.useTamboRegistry)(), { wrapper });
120
121
  expect(result.current.onCallUnregisteredTool).toBe(onCallUnregisteredTool);
121
122
  });
123
+ it("registers static resources when provided", () => {
124
+ const resources = [
125
+ {
126
+ uri: "resource://test/example",
127
+ name: "Test Resource",
128
+ description: "A test resource",
129
+ mimeType: "text/plain",
130
+ },
131
+ ];
132
+ const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_provider_1.TamboV1Provider, { apiKey: "test-api-key", resources: resources }, children));
133
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_registry_provider_1.useTamboRegistry)(), { wrapper });
134
+ expect(result.current.resources).toHaveLength(1);
135
+ expect(result.current.resources[0].uri).toBe("resource://test/example");
136
+ expect(result.current.resources[0].name).toBe("Test Resource");
137
+ });
138
+ it("registers resource source when listResources and getResource provided", () => {
139
+ const listResources = jest.fn().mockResolvedValue({ resources: [] });
140
+ const getResource = jest.fn().mockResolvedValue({ contents: [] });
141
+ const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_provider_1.TamboV1Provider, { apiKey: "test-api-key", listResources: listResources, getResource: getResource }, children));
142
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_registry_provider_1.useTamboRegistry)(), { wrapper });
143
+ expect(result.current.resourceSource).toBeDefined();
144
+ expect(result.current.resourceSource?.listResources).toBe(listResources);
145
+ expect(result.current.resourceSource?.getResource).toBe(getResource);
146
+ });
147
+ it("provides contextKey via useContextKey hook", () => {
148
+ const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_provider_1.TamboV1Provider, { apiKey: "test-api-key", contextKey: "my-context-key" }, children));
149
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_provider_1.useContextKey)(), { wrapper });
150
+ expect(result.current).toBe("my-context-key");
151
+ });
152
+ it("returns undefined from useContextKey when no contextKey provided", () => {
153
+ const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_provider_1.TamboV1Provider, { apiKey: "test-api-key" }, children));
154
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_provider_1.useContextKey)(), { wrapper });
155
+ expect(result.current).toBeUndefined();
156
+ });
157
+ it("provides context helpers via useTamboContextHelpers hook", async () => {
158
+ const contextHelpers = {
159
+ getUserName: () => "Test User",
160
+ getCurrentTime: () => new Date().toISOString(),
161
+ };
162
+ const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_provider_1.TamboV1Provider, { apiKey: "test-api-key", contextHelpers: contextHelpers }, children));
163
+ const { result, rerender } = (0, react_1.renderHook)(() => (0, tambo_context_helpers_provider_1.useTamboContextHelpers)(), {
164
+ wrapper,
165
+ });
166
+ // Helpers are registered via useEffect, so we need to trigger a rerender
167
+ await (0, react_1.act)(async () => {
168
+ rerender();
169
+ });
170
+ const helpers = result.current.getContextHelpers();
171
+ expect(helpers.getUserName).toBe(contextHelpers.getUserName);
172
+ expect(helpers.getCurrentTime).toBe(contextHelpers.getCurrentTime);
173
+ });
174
+ it("returns empty contextHelpers when none provided", async () => {
175
+ const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_provider_1.TamboV1Provider, { apiKey: "test-api-key" }, children));
176
+ const { result } = (0, react_1.renderHook)(() => (0, tambo_context_helpers_provider_1.useTamboContextHelpers)(), { wrapper });
177
+ const helpers = result.current.getContextHelpers();
178
+ expect(Object.keys(helpers)).toHaveLength(0);
179
+ });
122
180
  });
123
181
  //# sourceMappingURL=tambo-v1-provider.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-v1-provider.test.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.test.tsx"],"names":[],"mappings":";;;;;AACA,uDAAoE;AACpE,kDAAyD;AACzD,kDAA0B;AAC1B,6BAAwB;AACxB,iFAAuE;AACvE,qFAA2E;AAC3E,uEAAgF;AAChF,2DAAsD;AAEtD,iDAAiD;AACjD,IAAI,CAAC,IAAI,CAAC,uCAAuC,EAAE,GAAG,EAAE,CAAC,CAAC;IACxD,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;IACzB,mBAAmB,EAAE,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CACnE,QAAQ;CACX,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,MAAM,UAAU,GAAG;QACjB,MAAM,EAAE,cAAc;QACtB,OAAO,EAAE,EAAE;KACU,CAAC;IAExB,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,MAAM,CAAC,sCAAc,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAmB,CACpE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;QAClD,MAAM,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjE,MAAM,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAmB,CACpE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,wCAAc,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAmB,CACpE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAC3B,GAAG,EAAE,CAAC,CAAC;YACL,KAAK,EAAE,IAAA,wCAAc,GAAE;YACvB,UAAU,EAAE,IAAA,6CAAmB,GAAE;SAClC,CAAC,EACF,EAAE,OAAO,EAAE,CACZ,CAAC;QAEF,sBAAsB;QACtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAC;QAExD,oCAAoC;QACpC,IAAA,WAAG,EAAC,GAAG,EAAE;YACP,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YACnD,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAmB,CACpE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,4BAAc,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,yBAAW,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,YAAY,GAAG,IAAI,yBAAW,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAE,YAAY,IAC7D,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,4BAAc,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,kDAAe,CAAC;QAC5C,MAAM,WAAW,GAAG,OAAC,CAAC,MAAM,CAAC;YAC3B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;SACxC,CAAC,CAAC;QACH,MAAM,UAAU,GAAG;YACjB;gBACE,IAAI,EAAE,eAAe;gBACrB,WAAW,EAAE,kBAAkB;gBAC/B,SAAS,EAAE,aAAa;gBACxB,WAAW;aACZ;SACF,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,EAAC,UAAU,EAAE,UAAU,IAC1D,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAC1D,eAAe,CAChB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,WAAW,GAAG,OAAC,CAAC,MAAM,CAAC;YAC3B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;SAC3C,CAAC,CAAC;QACH,MAAM,YAAY,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG;YACZ;gBACE,IAAI,EAAE,UAAU;gBAChB,WAAW,EAAE,aAAa;gBAC1B,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ;gBAC1B,WAAW;gBACX,YAAY;aACb;SACF,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,EAAC,KAAK,EAAE,KAAK,IAChD,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,UAAU,GAAG;YACjB,EAAE,GAAG,EAAE,yBAAyB,EAAE,IAAI,EAAE,aAAa,EAAE;SACxD,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,EAAC,UAAU,EAAE,UAAU,IAC1D,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAC/C,yBAAyB,CAC1B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,sBAAsB,GAAG,IAAI;aAChC,EAAE,EAAE;aACJ,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;QAExC,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IACd,MAAM,EAAC,cAAc,EACrB,sBAAsB,EAAE,sBAAsB,IAE7C,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, useQueryClient } from \"@tanstack/react-query\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useStreamState, useThreadManagement } from \"./tambo-v1-stream-context\";\nimport { TamboV1Provider } from \"./tambo-v1-provider\";\n\n// Mock the client provider to capture the apiKey\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n TamboClientProvider: ({ children }: { children: React.ReactNode }) =>\n children,\n}));\n\ndescribe(\"TamboV1Provider\", () => {\n const mockClient = {\n apiKey: \"test-api-key\",\n threads: {},\n } as unknown as TamboAI;\n\n beforeEach(() => {\n jest.mocked(useTamboClient).mockReturnValue(mockClient);\n });\n\n it(\"provides access to registry context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList).toBeDefined();\n expect(result.current.toolRegistry).toBeDefined();\n expect(typeof result.current.registerComponent).toBe(\"function\");\n expect(typeof result.current.registerTool).toBe(\"function\");\n });\n\n it(\"provides access to stream context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.threadMap).toBeDefined();\n expect(result.current.currentThreadId).toBeNull();\n });\n\n it(\"manages threads via useThreadManagement\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(\n () => ({\n state: useStreamState(),\n management: useThreadManagement(),\n }),\n { wrapper },\n );\n\n // Initially no thread\n expect(result.current.state.currentThreadId).toBeNull();\n\n // Initialize and switch to a thread\n act(() => {\n result.current.management.initThread(\"thread_123\");\n result.current.management.switchThread(\"thread_123\");\n });\n\n expect(result.current.state.currentThreadId).toBe(\"thread_123\");\n expect(result.current.state.threadMap.thread_123).toBeDefined();\n });\n\n it(\"provides access to query client\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useQueryClient(), { wrapper });\n\n expect(result.current).toBeInstanceOf(QueryClient);\n });\n\n it(\"uses custom query client when provided\", () => {\n const customClient = new QueryClient();\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" queryClient={customClient}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useQueryClient(), { wrapper });\n\n expect(result.current).toBe(customClient);\n });\n\n it(\"registers components when provided\", () => {\n const TestComponent = () => <div>Test</div>;\n const propsSchema = z.object({\n title: z.string().describe(\"The title\"),\n });\n const components = [\n {\n name: \"TestComponent\",\n description: \"A test component\",\n component: TestComponent,\n propsSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" components={components}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList.TestComponent).toBeDefined();\n expect(result.current.componentList.TestComponent.name).toBe(\n \"TestComponent\",\n );\n });\n\n it(\"registers tools when provided\", () => {\n const inputSchema = z.object({\n query: z.string().describe(\"Search query\"),\n });\n const outputSchema = z.string().describe(\"Result string\");\n const tools = [\n {\n name: \"testTool\",\n description: \"A test tool\",\n tool: async () => \"result\",\n inputSchema,\n outputSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" tools={tools}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.toolRegistry.testTool).toBeDefined();\n expect(result.current.toolRegistry.testTool.name).toBe(\"testTool\");\n });\n\n it(\"registers MCP servers when provided\", () => {\n const mcpServers = [\n { url: \"https://mcp.example.com\", name: \"Example MCP\" },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" mcpServers={mcpServers}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.mcpServerInfos).toHaveLength(1);\n expect(result.current.mcpServerInfos[0].url).toBe(\n \"https://mcp.example.com\",\n );\n });\n\n it(\"provides onCallUnregisteredTool to registry\", () => {\n const onCallUnregisteredTool = jest\n .fn()\n .mockResolvedValue(\"fallback result\");\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider\n apiKey=\"test-api-key\"\n onCallUnregisteredTool={onCallUnregisteredTool}\n >\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.onCallUnregisteredTool).toBe(onCallUnregisteredTool);\n });\n});\n"]}
1
+ {"version":3,"file":"tambo-v1-provider.test.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, useQueryClient } from \"@tanstack/react-query\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport { useStreamState, useThreadManagement } from \"./tambo-v1-stream-context\";\nimport { TamboV1Provider, useContextKey } from \"./tambo-v1-provider\";\n\n// Mock the client provider to capture the apiKey\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n TamboClientProvider: ({ children }: { children: React.ReactNode }) =>\n children,\n}));\n\ndescribe(\"TamboV1Provider\", () => {\n const mockClient = {\n apiKey: \"test-api-key\",\n threads: {},\n } as unknown as TamboAI;\n\n beforeEach(() => {\n jest.mocked(useTamboClient).mockReturnValue(mockClient);\n });\n\n it(\"provides access to registry context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList).toBeDefined();\n expect(result.current.toolRegistry).toBeDefined();\n expect(typeof result.current.registerComponent).toBe(\"function\");\n expect(typeof result.current.registerTool).toBe(\"function\");\n });\n\n it(\"provides access to stream context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.threadMap).toBeDefined();\n expect(result.current.currentThreadId).toBeNull();\n });\n\n it(\"manages threads via useThreadManagement\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(\n () => ({\n state: useStreamState(),\n management: useThreadManagement(),\n }),\n { wrapper },\n );\n\n // Initially no thread\n expect(result.current.state.currentThreadId).toBeNull();\n\n // Initialize and switch to a thread\n act(() => {\n result.current.management.initThread(\"thread_123\");\n result.current.management.switchThread(\"thread_123\");\n });\n\n expect(result.current.state.currentThreadId).toBe(\"thread_123\");\n expect(result.current.state.threadMap.thread_123).toBeDefined();\n });\n\n it(\"provides access to query client\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useQueryClient(), { wrapper });\n\n expect(result.current).toBeInstanceOf(QueryClient);\n });\n\n it(\"uses custom query client when provided\", () => {\n const customClient = new QueryClient();\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" queryClient={customClient}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useQueryClient(), { wrapper });\n\n expect(result.current).toBe(customClient);\n });\n\n it(\"registers components when provided\", () => {\n const TestComponent = () => <div>Test</div>;\n const propsSchema = z.object({\n title: z.string().describe(\"The title\"),\n });\n const components = [\n {\n name: \"TestComponent\",\n description: \"A test component\",\n component: TestComponent,\n propsSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" components={components}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList.TestComponent).toBeDefined();\n expect(result.current.componentList.TestComponent.name).toBe(\n \"TestComponent\",\n );\n });\n\n it(\"registers tools when provided\", () => {\n const inputSchema = z.object({\n query: z.string().describe(\"Search query\"),\n });\n const outputSchema = z.string().describe(\"Result string\");\n const tools = [\n {\n name: \"testTool\",\n description: \"A test tool\",\n tool: async () => \"result\",\n inputSchema,\n outputSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" tools={tools}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.toolRegistry.testTool).toBeDefined();\n expect(result.current.toolRegistry.testTool.name).toBe(\"testTool\");\n });\n\n it(\"registers MCP servers when provided\", () => {\n const mcpServers = [\n { url: \"https://mcp.example.com\", name: \"Example MCP\" },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" mcpServers={mcpServers}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.mcpServerInfos).toHaveLength(1);\n expect(result.current.mcpServerInfos[0].url).toBe(\n \"https://mcp.example.com\",\n );\n });\n\n it(\"provides onCallUnregisteredTool to registry\", () => {\n const onCallUnregisteredTool = jest\n .fn()\n .mockResolvedValue(\"fallback result\");\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider\n apiKey=\"test-api-key\"\n onCallUnregisteredTool={onCallUnregisteredTool}\n >\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.onCallUnregisteredTool).toBe(onCallUnregisteredTool);\n });\n\n it(\"registers static resources when provided\", () => {\n const resources = [\n {\n uri: \"resource://test/example\",\n name: \"Test Resource\",\n description: \"A test resource\",\n mimeType: \"text/plain\",\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" resources={resources}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resources).toHaveLength(1);\n expect(result.current.resources[0].uri).toBe(\"resource://test/example\");\n expect(result.current.resources[0].name).toBe(\"Test Resource\");\n });\n\n it(\"registers resource source when listResources and getResource provided\", () => {\n const listResources = jest.fn().mockResolvedValue({ resources: [] });\n const getResource = jest.fn().mockResolvedValue({ contents: [] });\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider\n apiKey=\"test-api-key\"\n listResources={listResources}\n getResource={getResource}\n >\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resourceSource).toBeDefined();\n expect(result.current.resourceSource?.listResources).toBe(listResources);\n expect(result.current.resourceSource?.getResource).toBe(getResource);\n });\n\n it(\"provides contextKey via useContextKey hook\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" contextKey=\"my-context-key\">\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useContextKey(), { wrapper });\n\n expect(result.current).toBe(\"my-context-key\");\n });\n\n it(\"returns undefined from useContextKey when no contextKey provided\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useContextKey(), { wrapper });\n\n expect(result.current).toBeUndefined();\n });\n\n it(\"provides context helpers via useTamboContextHelpers hook\", async () => {\n const contextHelpers = {\n getUserName: () => \"Test User\",\n getCurrentTime: () => new Date().toISOString(),\n };\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" contextHelpers={contextHelpers}>\n {children}\n </TamboV1Provider>\n );\n\n const { result, rerender } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n // Helpers are registered via useEffect, so we need to trigger a rerender\n await act(async () => {\n rerender();\n });\n\n const helpers = result.current.getContextHelpers();\n expect(helpers.getUserName).toBe(contextHelpers.getUserName);\n expect(helpers.getCurrentTime).toBe(contextHelpers.getCurrentTime);\n });\n\n it(\"returns empty contextHelpers when none provided\", async () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboContextHelpers(), { wrapper });\n\n const helpers = result.current.getContextHelpers();\n expect(Object.keys(helpers)).toHaveLength(0);\n });\n});\n"]}
@@ -5,18 +5,43 @@
5
5
  * Messages use Anthropic-style content blocks pattern where a message
6
6
  * contains an array of content blocks (text, tool calls, tool results, components).
7
7
  */
8
+ import type { ReactElement } from "react";
8
9
  export type { TextContent, ToolUseContent, ToolResultContent, ComponentContent, ResourceContent, } from "@tambo-ai/typescript-sdk/resources/threads/threads";
9
10
  export type { InputMessage } from "@tambo-ai/typescript-sdk/resources/threads/runs";
10
11
  export type { MessageListResponse, MessageGetResponse, } from "@tambo-ai/typescript-sdk/resources/threads/messages";
11
12
  import type { TextContent, ToolUseContent, ToolResultContent, ComponentContent, ResourceContent } from "@tambo-ai/typescript-sdk/resources/threads/threads";
13
+ /**
14
+ * Streaming state for component content blocks.
15
+ * Tracks the lifecycle of component prop/state streaming.
16
+ */
17
+ export type ComponentStreamingState = "started" | "streaming" | "done";
18
+ /**
19
+ * Extended ComponentContent with streaming state and rendered element.
20
+ * Used by the v1 SDK to track component rendering lifecycle.
21
+ */
22
+ export interface V1ComponentContent extends ComponentContent {
23
+ /**
24
+ * Current streaming state of this component's props.
25
+ * - 'started': Component block created, awaiting props
26
+ * - 'streaming': Props are being streamed
27
+ * - 'done': Props streaming complete
28
+ */
29
+ streamingState: ComponentStreamingState;
30
+ /**
31
+ * The rendered React element for this component.
32
+ * undefined if not yet rendered, null if the component couldn't be found in the registry.
33
+ */
34
+ renderedComponent?: ReactElement | null;
35
+ }
12
36
  /**
13
37
  * Message role (from SDK)
14
38
  */
15
39
  export type MessageRole = "user" | "assistant";
16
40
  /**
17
- * Union type of all content block types
41
+ * Union type of all content block types.
42
+ * Uses V1ComponentContent which includes streaming state and rendered component.
18
43
  */
19
- export type Content = TextContent | ToolUseContent | ToolResultContent | ComponentContent | ResourceContent;
44
+ export type Content = TextContent | ToolUseContent | ToolResultContent | V1ComponentContent | ResourceContent;
20
45
  /**
21
46
  * Message in a thread (simplified from SDK's MessageGetResponse)
22
47
  */
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/v1/types/message.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EACV,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,GAChB,MAAM,oDAAoD,CAAC;AAG5D,YAAY,EAAE,YAAY,EAAE,MAAM,iDAAiD,CAAC;AAEpF,YAAY,EACV,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qDAAqD,CAAC;AAG7D,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EAChB,MAAM,oDAAoD,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,OAAO,GACf,WAAW,GACX,cAAc,GACd,iBAAiB,GACjB,gBAAgB,GAChB,eAAe,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IAEX,uCAAuC;IACvC,IAAI,EAAE,WAAW,CAAC;IAElB,oCAAoC;IACpC,OAAO,EAAE,OAAO,EAAE,CAAC;IAEnB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAElB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC"}
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/v1/types/message.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C,YAAY,EACV,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,GAChB,MAAM,oDAAoD,CAAC;AAG5D,YAAY,EAAE,YAAY,EAAE,MAAM,iDAAiD,CAAC;AAEpF,YAAY,EACV,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qDAAqD,CAAC;AAG7D,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EAChB,MAAM,oDAAoD,CAAC;AAE5D;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC;AAEvE;;;GAGG;AACH,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC1D;;;;;OAKG;IACH,cAAc,EAAE,uBAAuB,CAAC;IAExC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,CAAC;AAE/C;;;GAGG;AACH,MAAM,MAAM,OAAO,GACf,WAAW,GACX,cAAc,GACd,iBAAiB,GACjB,kBAAkB,GAClB,eAAe,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IAEX,uCAAuC;IACvC,IAAI,EAAE,WAAW,CAAC;IAElB,oCAAoC;IACpC,OAAO,EAAE,OAAO,EAAE,CAAC;IAEnB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAElB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC"}
@@ -1 +1 @@
1
- {"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/v1/types/message.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG","sourcesContent":["/**\n * Message and Content Types for v1 API\n *\n * Re-exports message and content types from `@tambo-ai/typescript-sdk`.\n * Messages use Anthropic-style content blocks pattern where a message\n * contains an array of content blocks (text, tool calls, tool results, components).\n */\n\n// Re-export content block types from TypeScript SDK\nexport type {\n TextContent,\n ToolUseContent,\n ToolResultContent,\n ComponentContent,\n ResourceContent,\n} from \"@tambo-ai/typescript-sdk/resources/threads/threads\";\n\n// Re-export message types from TypeScript SDK\nexport type { InputMessage } from \"@tambo-ai/typescript-sdk/resources/threads/runs\";\n\nexport type {\n MessageListResponse,\n MessageGetResponse,\n} from \"@tambo-ai/typescript-sdk/resources/threads/messages\";\n\n// Import for Content union type\nimport type {\n TextContent,\n ToolUseContent,\n ToolResultContent,\n ComponentContent,\n ResourceContent,\n} from \"@tambo-ai/typescript-sdk/resources/threads/threads\";\n\n/**\n * Message role (from SDK)\n */\nexport type MessageRole = \"user\" | \"assistant\";\n\n/**\n * Union type of all content block types\n */\nexport type Content =\n | TextContent\n | ToolUseContent\n | ToolResultContent\n | ComponentContent\n | ResourceContent;\n\n/**\n * Message in a thread (simplified from SDK's MessageGetResponse)\n */\nexport interface TamboV1Message {\n /** Unique message identifier */\n id: string;\n\n /** Message role (user or assistant) */\n role: MessageRole;\n\n /** Content blocks in the message */\n content: Content[];\n\n /** When the message was created */\n createdAt: string;\n\n /** Message metadata */\n metadata?: Record<string, unknown>;\n}\n"]}
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/v1/types/message.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG","sourcesContent":["/**\n * Message and Content Types for v1 API\n *\n * Re-exports message and content types from `@tambo-ai/typescript-sdk`.\n * Messages use Anthropic-style content blocks pattern where a message\n * contains an array of content blocks (text, tool calls, tool results, components).\n */\n\nimport type { ReactElement } from \"react\";\n\n// Re-export content block types from TypeScript SDK\nexport type {\n TextContent,\n ToolUseContent,\n ToolResultContent,\n ComponentContent,\n ResourceContent,\n} from \"@tambo-ai/typescript-sdk/resources/threads/threads\";\n\n// Re-export message types from TypeScript SDK\nexport type { InputMessage } from \"@tambo-ai/typescript-sdk/resources/threads/runs\";\n\nexport type {\n MessageListResponse,\n MessageGetResponse,\n} from \"@tambo-ai/typescript-sdk/resources/threads/messages\";\n\n// Import for Content union type\nimport type {\n TextContent,\n ToolUseContent,\n ToolResultContent,\n ComponentContent,\n ResourceContent,\n} from \"@tambo-ai/typescript-sdk/resources/threads/threads\";\n\n/**\n * Streaming state for component content blocks.\n * Tracks the lifecycle of component prop/state streaming.\n */\nexport type ComponentStreamingState = \"started\" | \"streaming\" | \"done\";\n\n/**\n * Extended ComponentContent with streaming state and rendered element.\n * Used by the v1 SDK to track component rendering lifecycle.\n */\nexport interface V1ComponentContent extends ComponentContent {\n /**\n * Current streaming state of this component's props.\n * - 'started': Component block created, awaiting props\n * - 'streaming': Props are being streamed\n * - 'done': Props streaming complete\n */\n streamingState: ComponentStreamingState;\n\n /**\n * The rendered React element for this component.\n * undefined if not yet rendered, null if the component couldn't be found in the registry.\n */\n renderedComponent?: ReactElement | null;\n}\n\n/**\n * Message role (from SDK)\n */\nexport type MessageRole = \"user\" | \"assistant\";\n\n/**\n * Union type of all content block types.\n * Uses V1ComponentContent which includes streaming state and rendered component.\n */\nexport type Content =\n | TextContent\n | ToolUseContent\n | ToolResultContent\n | V1ComponentContent\n | ResourceContent;\n\n/**\n * Message in a thread (simplified from SDK's MessageGetResponse)\n */\nexport interface TamboV1Message {\n /** Unique message identifier */\n id: string;\n\n /** Message role (user or assistant) */\n role: MessageRole;\n\n /** Content blocks in the message */\n content: Content[];\n\n /** When the message was created */\n createdAt: string;\n\n /** Message metadata */\n metadata?: Record<string, unknown>;\n}\n"]}
@@ -0,0 +1,89 @@
1
+ import type { ComponentRegistry } from "../../model/component-metadata";
2
+ import type { Content, TamboV1Message, V1ComponentContent } from "../types/message";
3
+ /**
4
+ * Context for component content blocks.
5
+ * Provides access to the component ID and thread ID for component state hooks.
6
+ */
7
+ export interface V1ComponentContentContext {
8
+ /** Component instance ID */
9
+ componentId: string;
10
+ /** Thread ID the component belongs to */
11
+ threadId: string;
12
+ /** Message ID the component belongs to */
13
+ messageId: string;
14
+ /** Component name */
15
+ componentName: string;
16
+ }
17
+ /**
18
+ * Hook to access the current component content context.
19
+ * Must be used within a rendered component.
20
+ * @returns Component content context
21
+ * @throws {Error} If used outside a rendered component
22
+ */
23
+ export declare function useV1ComponentContent(): V1ComponentContentContext;
24
+ /**
25
+ * Hook to optionally access the current component content context.
26
+ * Returns null if not within a rendered component.
27
+ * @returns Component content context or null
28
+ */
29
+ export declare function useV1ComponentContentOptional(): V1ComponentContentContext | null;
30
+ /**
31
+ * Options for rendering a component content block.
32
+ */
33
+ export interface RenderComponentOptions {
34
+ /** Thread ID for the component context */
35
+ threadId: string;
36
+ /** Message ID the component belongs to */
37
+ messageId: string;
38
+ /** Component registry to look up components */
39
+ componentList: ComponentRegistry;
40
+ }
41
+ /**
42
+ * Check if a content block is a component.
43
+ * @param content - Content block to check
44
+ * @returns True if content is a V1ComponentContent
45
+ */
46
+ export declare function isComponentContent(content: Content): content is V1ComponentContent;
47
+ /**
48
+ * Render a component content block into a React element.
49
+ *
50
+ * Looks up the component in the registry, creates a React element with props,
51
+ * and wraps it with the component content context provider.
52
+ * @param content - Component content block to render
53
+ * @param options - Rendering options including registry and context info
54
+ * @returns V1ComponentContent with the renderedComponent attached
55
+ * @example
56
+ * ```tsx
57
+ * const rendered = renderComponentContent(componentContent, {
58
+ * threadId: 'thread_123',
59
+ * messageId: 'msg_456',
60
+ * componentList: registry.componentList,
61
+ * });
62
+ *
63
+ * // Use in JSX:
64
+ * {rendered.renderedComponent}
65
+ * ```
66
+ */
67
+ export declare function renderComponentContent(content: V1ComponentContent, options: RenderComponentOptions): V1ComponentContent;
68
+ /**
69
+ * Render all component content blocks in a message.
70
+ *
71
+ * Renders component content blocks and attaches renderedComponent.
72
+ * Non-component content blocks are passed through unchanged.
73
+ * @param content - Array of content blocks
74
+ * @param options - Rendering options including registry and context info
75
+ * @returns Array of content with rendered components
76
+ */
77
+ export declare function renderMessageContent(content: Content[], options: RenderComponentOptions): Content[];
78
+ /**
79
+ * Render all components in a message.
80
+ *
81
+ * Creates a new message object with all component content blocks rendered.
82
+ * @param message - Message to render components for
83
+ * @param options - Rendering options (threadId is extracted from message if not provided)
84
+ * @returns Message with rendered component content
85
+ */
86
+ export declare function renderMessageComponents(message: TamboV1Message, options: Omit<RenderComponentOptions, "messageId"> & {
87
+ threadId: string;
88
+ }): TamboV1Message;
89
+ //# sourceMappingURL=component-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-renderer.d.ts","sourceRoot":"","sources":["../../../src/v1/utils/component-renderer.tsx"],"names":[],"mappings":"AAuDA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAE1B;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACxC,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AA+BD;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,yBAAyB,CAQjE;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,yBAAyB,GAAG,IAAI,CAEhF;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,aAAa,EAAE,iBAAiB,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,GACf,OAAO,IAAI,kBAAkB,CAE/B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,sBAAsB,GAC9B,kBAAkB,CAwDpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAAE,EAClB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,EAAE,CAQX;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,IAAI,CAAC,sBAAsB,EAAE,WAAW,CAAC,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GACxE,cAAc,CAUhB"}
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ "use client";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.useV1ComponentContent = useV1ComponentContent;
38
+ exports.useV1ComponentContentOptional = useV1ComponentContentOptional;
39
+ exports.isComponentContent = isComponentContent;
40
+ exports.renderComponentContent = renderComponentContent;
41
+ exports.renderMessageContent = renderMessageContent;
42
+ exports.renderMessageComponents = renderMessageComponents;
43
+ /**
44
+ * Component Renderer Utility for v1 API
45
+ *
46
+ * Provides utilities for rendering React components from component content blocks.
47
+ * Components are looked up in the registry and wrapped with context providers.
48
+ */
49
+ const react_1 = __importStar(require("react"));
50
+ /**
51
+ * Props that should be filtered out when rendering components.
52
+ * These could be used for event handler injection or other security concerns.
53
+ */
54
+ const DANGEROUS_PROP_PATTERNS = [
55
+ /^on[A-Z]/, // Event handlers (onClick, onError, etc.)
56
+ /^dangerouslySetInnerHTML$/,
57
+ ];
58
+ const DANGEROUS_PROP_NAMES = new Set(["ref", "key", "children"]);
59
+ /**
60
+ * Sanitize props by removing potentially dangerous properties.
61
+ * Filters out event handlers, refs, and other props that could be abused.
62
+ * @param props - Raw props from the component content
63
+ * @returns Sanitized props safe for spreading to components
64
+ */
65
+ function sanitizeProps(props) {
66
+ const sanitized = {};
67
+ for (const [key, value] of Object.entries(props)) {
68
+ // Skip dangerous prop names
69
+ if (DANGEROUS_PROP_NAMES.has(key)) {
70
+ continue;
71
+ }
72
+ // Skip props matching dangerous patterns
73
+ if (DANGEROUS_PROP_PATTERNS.some((pattern) => pattern.test(key))) {
74
+ continue;
75
+ }
76
+ sanitized[key] = value;
77
+ }
78
+ return sanitized;
79
+ }
80
+ const ComponentContentContext = (0, react_1.createContext)(null);
81
+ /**
82
+ * Provider for component content context.
83
+ * Wraps rendered components to provide access to component metadata.
84
+ * @returns Provider component with memoized context value
85
+ */
86
+ function V1ComponentContentProvider({ children, componentId, threadId, messageId, componentName, }) {
87
+ // Memoize context value to prevent unnecessary re-renders of consumers
88
+ const value = (0, react_1.useMemo)(() => ({ componentId, threadId, messageId, componentName }), [componentId, threadId, messageId, componentName]);
89
+ return (react_1.default.createElement(ComponentContentContext.Provider, { value: value }, children));
90
+ }
91
+ /**
92
+ * Hook to access the current component content context.
93
+ * Must be used within a rendered component.
94
+ * @returns Component content context
95
+ * @throws {Error} If used outside a rendered component
96
+ */
97
+ function useV1ComponentContent() {
98
+ const context = (0, react_1.useContext)(ComponentContentContext);
99
+ if (!context) {
100
+ throw new Error("useV1ComponentContent must be used within a rendered component");
101
+ }
102
+ return context;
103
+ }
104
+ /**
105
+ * Hook to optionally access the current component content context.
106
+ * Returns null if not within a rendered component.
107
+ * @returns Component content context or null
108
+ */
109
+ function useV1ComponentContentOptional() {
110
+ return (0, react_1.useContext)(ComponentContentContext);
111
+ }
112
+ /**
113
+ * Check if a content block is a component.
114
+ * @param content - Content block to check
115
+ * @returns True if content is a V1ComponentContent
116
+ */
117
+ function isComponentContent(content) {
118
+ return content.type === "component";
119
+ }
120
+ /**
121
+ * Render a component content block into a React element.
122
+ *
123
+ * Looks up the component in the registry, creates a React element with props,
124
+ * and wraps it with the component content context provider.
125
+ * @param content - Component content block to render
126
+ * @param options - Rendering options including registry and context info
127
+ * @returns V1ComponentContent with the renderedComponent attached
128
+ * @example
129
+ * ```tsx
130
+ * const rendered = renderComponentContent(componentContent, {
131
+ * threadId: 'thread_123',
132
+ * messageId: 'msg_456',
133
+ * componentList: registry.componentList,
134
+ * });
135
+ *
136
+ * // Use in JSX:
137
+ * {rendered.renderedComponent}
138
+ * ```
139
+ */
140
+ function renderComponentContent(content, options) {
141
+ const { threadId, messageId, componentList } = options;
142
+ // Look up component in registry
143
+ const registeredComponent = componentList[content.name];
144
+ if (!registeredComponent) {
145
+ console.warn(`Component "${content.name}" not found in registry`);
146
+ return {
147
+ ...content,
148
+ renderedComponent: null,
149
+ };
150
+ }
151
+ const Component = registeredComponent.component;
152
+ const LoadingComponent = registeredComponent.loadingComponent;
153
+ // Determine if we should show loading state
154
+ const isStreaming = content.streamingState !== "done";
155
+ // Sanitize props to prevent injection of event handlers or other dangerous props
156
+ const props = sanitizeProps(content.props);
157
+ // Create the component element
158
+ let element;
159
+ if (isStreaming && LoadingComponent) {
160
+ // Show loading component during streaming (with props for partial data display)
161
+ element = (0, react_1.createElement)(LoadingComponent, props);
162
+ }
163
+ else {
164
+ // Show main component - props stream in as they're filled out
165
+ element = (0, react_1.createElement)(Component, {
166
+ ...props,
167
+ // Pass state as initialState prop only if not already provided
168
+ ...(props.initialState === undefined
169
+ ? { initialState: content.state }
170
+ : {}),
171
+ });
172
+ }
173
+ // Wrap with component content context
174
+ const wrappedElement = (react_1.default.createElement(V1ComponentContentProvider, { componentId: content.id, threadId: threadId, messageId: messageId, componentName: content.name }, element));
175
+ return {
176
+ ...content,
177
+ renderedComponent: wrappedElement,
178
+ };
179
+ }
180
+ /**
181
+ * Render all component content blocks in a message.
182
+ *
183
+ * Renders component content blocks and attaches renderedComponent.
184
+ * Non-component content blocks are passed through unchanged.
185
+ * @param content - Array of content blocks
186
+ * @param options - Rendering options including registry and context info
187
+ * @returns Array of content with rendered components
188
+ */
189
+ function renderMessageContent(content, options) {
190
+ return content.map((block) => {
191
+ if (isComponentContent(block)) {
192
+ return renderComponentContent(block, options);
193
+ }
194
+ // Pass through non-component content unchanged
195
+ return block;
196
+ });
197
+ }
198
+ /**
199
+ * Render all components in a message.
200
+ *
201
+ * Creates a new message object with all component content blocks rendered.
202
+ * @param message - Message to render components for
203
+ * @param options - Rendering options (threadId is extracted from message if not provided)
204
+ * @returns Message with rendered component content
205
+ */
206
+ function renderMessageComponents(message, options) {
207
+ const renderedContent = renderMessageContent(message.content, {
208
+ ...options,
209
+ messageId: message.id,
210
+ });
211
+ return {
212
+ ...message,
213
+ content: renderedContent,
214
+ };
215
+ }
216
+ //# sourceMappingURL=component-renderer.js.map