@tambo-ai/react 0.41.2 → 0.42.1

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 (111) hide show
  1. package/dist/context-helpers/__tests__/context-helpers.test.d.ts +2 -0
  2. package/dist/context-helpers/__tests__/context-helpers.test.d.ts.map +1 -0
  3. package/dist/context-helpers/__tests__/context-helpers.test.js +44 -0
  4. package/dist/context-helpers/__tests__/context-helpers.test.js.map +1 -0
  5. package/dist/context-helpers/index.d.ts +9 -0
  6. package/dist/context-helpers/index.d.ts.map +1 -0
  7. package/dist/context-helpers/index.js +38 -0
  8. package/dist/context-helpers/index.js.map +1 -0
  9. package/dist/context-helpers/types.d.ts +30 -0
  10. package/dist/context-helpers/types.d.ts.map +1 -0
  11. package/dist/context-helpers/types.js +3 -0
  12. package/dist/context-helpers/types.js.map +1 -0
  13. package/dist/context-helpers/user-page.d.ts +7 -0
  14. package/dist/context-helpers/user-page.d.ts.map +1 -0
  15. package/dist/context-helpers/user-page.js +31 -0
  16. package/dist/context-helpers/user-page.js.map +1 -0
  17. package/dist/context-helpers/user-time.d.ts +7 -0
  18. package/dist/context-helpers/user-time.d.ts.map +1 -0
  19. package/dist/context-helpers/user-time.js +20 -0
  20. package/dist/context-helpers/user-time.js.map +1 -0
  21. package/dist/index.d.ts +3 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +8 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/providers/__tests__/tambo-context-helpers-provider.test.d.ts +2 -0
  26. package/dist/providers/__tests__/tambo-context-helpers-provider.test.d.ts.map +1 -0
  27. package/dist/providers/__tests__/tambo-context-helpers-provider.test.js +194 -0
  28. package/dist/providers/__tests__/tambo-context-helpers-provider.test.js.map +1 -0
  29. package/dist/providers/__tests__/tambo-thread-provider.test.js +51 -31
  30. package/dist/providers/__tests__/tambo-thread-provider.test.js.map +1 -1
  31. package/dist/providers/index.d.ts +1 -0
  32. package/dist/providers/index.d.ts.map +1 -1
  33. package/dist/providers/index.js +4 -1
  34. package/dist/providers/index.js.map +1 -1
  35. package/dist/providers/tambo-context-helpers-provider.d.ts +28 -0
  36. package/dist/providers/tambo-context-helpers-provider.d.ts.map +1 -0
  37. package/dist/providers/tambo-context-helpers-provider.js +98 -0
  38. package/dist/providers/tambo-context-helpers-provider.js.map +1 -0
  39. package/dist/providers/tambo-interactable-provider.js +1 -1
  40. package/dist/providers/tambo-interactable-provider.js.map +1 -1
  41. package/dist/providers/tambo-provider.d.ts +4 -2
  42. package/dist/providers/tambo-provider.d.ts.map +1 -1
  43. package/dist/providers/tambo-provider.js +10 -5
  44. package/dist/providers/tambo-provider.js.map +1 -1
  45. package/dist/providers/tambo-stubs.d.ts +4 -0
  46. package/dist/providers/tambo-stubs.d.ts.map +1 -1
  47. package/dist/providers/tambo-stubs.js +6 -3
  48. package/dist/providers/tambo-stubs.js.map +1 -1
  49. package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
  50. package/dist/providers/tambo-thread-provider.js +10 -1
  51. package/dist/providers/tambo-thread-provider.js.map +1 -1
  52. package/dist/util/registry.d.ts +0 -8
  53. package/dist/util/registry.d.ts.map +1 -1
  54. package/dist/util/registry.js +1 -15
  55. package/dist/util/registry.js.map +1 -1
  56. package/esm/context-helpers/__tests__/context-helpers.test.d.ts +2 -0
  57. package/esm/context-helpers/__tests__/context-helpers.test.d.ts.map +1 -0
  58. package/esm/context-helpers/__tests__/context-helpers.test.js +42 -0
  59. package/esm/context-helpers/__tests__/context-helpers.test.js.map +1 -0
  60. package/esm/context-helpers/index.d.ts +9 -0
  61. package/esm/context-helpers/index.d.ts.map +1 -0
  62. package/esm/context-helpers/index.js +21 -0
  63. package/esm/context-helpers/index.js.map +1 -0
  64. package/esm/context-helpers/types.d.ts +30 -0
  65. package/esm/context-helpers/types.d.ts.map +1 -0
  66. package/esm/context-helpers/types.js +2 -0
  67. package/esm/context-helpers/types.js.map +1 -0
  68. package/esm/context-helpers/user-page.d.ts +7 -0
  69. package/esm/context-helpers/user-page.d.ts.map +1 -0
  70. package/esm/context-helpers/user-page.js +28 -0
  71. package/esm/context-helpers/user-page.js.map +1 -0
  72. package/esm/context-helpers/user-time.d.ts +7 -0
  73. package/esm/context-helpers/user-time.d.ts.map +1 -0
  74. package/esm/context-helpers/user-time.js +17 -0
  75. package/esm/context-helpers/user-time.js.map +1 -0
  76. package/esm/index.d.ts +3 -1
  77. package/esm/index.d.ts.map +1 -1
  78. package/esm/index.js +3 -1
  79. package/esm/index.js.map +1 -1
  80. package/esm/providers/__tests__/tambo-context-helpers-provider.test.d.ts +2 -0
  81. package/esm/providers/__tests__/tambo-context-helpers-provider.test.d.ts.map +1 -0
  82. package/esm/providers/__tests__/tambo-context-helpers-provider.test.js +156 -0
  83. package/esm/providers/__tests__/tambo-context-helpers-provider.test.js.map +1 -0
  84. package/esm/providers/__tests__/tambo-thread-provider.test.js +51 -31
  85. package/esm/providers/__tests__/tambo-thread-provider.test.js.map +1 -1
  86. package/esm/providers/index.d.ts +1 -0
  87. package/esm/providers/index.d.ts.map +1 -1
  88. package/esm/providers/index.js +1 -0
  89. package/esm/providers/index.js.map +1 -1
  90. package/esm/providers/tambo-context-helpers-provider.d.ts +28 -0
  91. package/esm/providers/tambo-context-helpers-provider.d.ts.map +1 -0
  92. package/esm/providers/tambo-context-helpers-provider.js +60 -0
  93. package/esm/providers/tambo-context-helpers-provider.js.map +1 -0
  94. package/esm/providers/tambo-interactable-provider.js +1 -1
  95. package/esm/providers/tambo-interactable-provider.js.map +1 -1
  96. package/esm/providers/tambo-provider.d.ts +4 -2
  97. package/esm/providers/tambo-provider.d.ts.map +1 -1
  98. package/esm/providers/tambo-provider.js +10 -5
  99. package/esm/providers/tambo-provider.js.map +1 -1
  100. package/esm/providers/tambo-stubs.d.ts +4 -0
  101. package/esm/providers/tambo-stubs.d.ts.map +1 -1
  102. package/esm/providers/tambo-stubs.js +6 -3
  103. package/esm/providers/tambo-stubs.js.map +1 -1
  104. package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
  105. package/esm/providers/tambo-thread-provider.js +11 -2
  106. package/esm/providers/tambo-thread-provider.js.map +1 -1
  107. package/esm/util/registry.d.ts +0 -8
  108. package/esm/util/registry.d.ts.map +1 -1
  109. package/esm/util/registry.js +0 -13
  110. package/esm/util/registry.js.map +1 -1
  111. package/package.json +5 -5
package/esm/index.js CHANGED
@@ -6,9 +6,11 @@ export * from "./hooks/use-suggestions";
6
6
  export { useTamboStreamStatus, } from "./hooks/use-tambo-stream-status";
7
7
  export { useTamboThreadInput } from "./hooks/use-thread-input";
8
8
  // Re-export provider components
9
- export { TamboClientProvider, TamboComponentProvider, TamboPropStreamProvider, TamboProvider, TamboStubProvider, TamboThreadProvider, useTambo, useTamboClient, useTamboStream, useTamboThread, } from "./providers";
9
+ export { TamboClientProvider, TamboComponentProvider, TamboContextHelpersProvider, TamboPropStreamProvider, TamboProvider, TamboStubProvider, TamboThreadProvider, useTambo, useTamboClient, useTamboContextHelpers, useTamboStream, useTamboThread, } from "./providers";
10
10
  export { useTamboThreadList } from "./hooks/use-tambo-threads";
11
11
  export { GenerationStage, } from "./model/generate-component-response";
12
12
  export { withTamboInteractable as withInteractable, } from "./providers/hoc/with-tambo-interactable";
13
13
  export { useTamboInteractable } from "./providers/tambo-interactable-provider";
14
+ // Context helpers exports
15
+ export { DEFAULT_CONTEXT_HELPERS, getUserPageContext, getUserTimeContext, } from "./context-helpers";
14
16
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wKAAwK;AAExK,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,cAAc,yBAAyB,CAAC;AACxC,OAAO,EACL,oBAAoB,GAGrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,gCAAgC;AAChC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,EACR,cAAc,EACd,cAAc,EACd,cAAc,GAIf,MAAM,aAAa,CAAC;AAcrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,OAAO,EACL,eAAe,GAEhB,MAAM,qCAAqC,CAAC;AAO7C,OAAO,EACL,qBAAqB,IAAI,gBAAgB,GAG1C,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC","sourcesContent":["/** Exports for the library. Only publically available exports are re-exported here. Anything not exported here is not supported and may change or break at any time. */\n\nexport { useTamboComponentState } from \"./hooks/use-component-state\";\nexport {\n TamboMessageProvider,\n useTamboCurrentMessage,\n useTamboMessageContext,\n} from \"./hooks/use-current-message\";\nexport { useTamboStreamingProps } from \"./hooks/use-streaming-props\";\nexport * from \"./hooks/use-suggestions\";\nexport {\n useTamboStreamStatus,\n type PropStatus,\n type StreamStatus,\n} from \"./hooks/use-tambo-stream-status\";\nexport { useTamboThreadInput } from \"./hooks/use-thread-input\";\n\n// Re-export provider components\nexport {\n TamboClientProvider,\n TamboComponentProvider,\n TamboPropStreamProvider,\n TamboProvider,\n TamboStubProvider,\n TamboThreadProvider,\n useTambo,\n useTamboClient,\n useTamboStream,\n useTamboThread,\n type TamboComponent,\n type TamboRegistryContext,\n type TamboStubProviderProps,\n} from \"./providers\";\n\n// Re-export types from Tambo Node SDK\nexport type {\n APIError,\n RateLimitError,\n TamboAIError,\n} from \"@tambo-ai/typescript-sdk\";\nexport type {\n Suggestion,\n SuggestionGenerateParams,\n SuggestionGenerateResponse,\n SuggestionListResponse,\n} from \"@tambo-ai/typescript-sdk/resources/beta/threads/suggestions\";\nexport { useTamboThreadList } from \"./hooks/use-tambo-threads\";\nexport {\n type ComponentContextToolMetadata,\n type ComponentRegistry,\n type ParameterSpec,\n type RegisteredComponent,\n type TamboTool,\n} from \"./model/component-metadata\";\nexport {\n GenerationStage,\n type TamboThreadMessage,\n} from \"./model/generate-component-response\";\nexport { type TamboThread } from \"./model/tambo-thread\";\n\nexport type {\n TamboInteractableComponent as InteractableComponent,\n TamboInteractableContext,\n} from \"./model/tambo-interactable\";\nexport {\n withTamboInteractable as withInteractable,\n type InteractableConfig,\n type WithTamboInteractableProps,\n} from \"./providers/hoc/with-tambo-interactable\";\nexport { useTamboInteractable } from \"./providers/tambo-interactable-provider\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wKAAwK;AAExK,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,cAAc,yBAAyB,CAAC;AACxC,OAAO,EACL,oBAAoB,GAGrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,gCAAgC;AAChC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,2BAA2B,EAC3B,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,EACR,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,cAAc,GAMf,MAAM,aAAa,CAAC;AAcrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,OAAO,EACL,eAAe,GAEhB,MAAM,qCAAqC,CAAC;AAO7C,OAAO,EACL,qBAAqB,IAAI,gBAAgB,GAG1C,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAE/E,0BAA0B;AAC1B,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC","sourcesContent":["/** Exports for the library. Only publically available exports are re-exported here. Anything not exported here is not supported and may change or break at any time. */\n\nexport { useTamboComponentState } from \"./hooks/use-component-state\";\nexport {\n TamboMessageProvider,\n useTamboCurrentMessage,\n useTamboMessageContext,\n} from \"./hooks/use-current-message\";\nexport { useTamboStreamingProps } from \"./hooks/use-streaming-props\";\nexport * from \"./hooks/use-suggestions\";\nexport {\n useTamboStreamStatus,\n type PropStatus,\n type StreamStatus,\n} from \"./hooks/use-tambo-stream-status\";\nexport { useTamboThreadInput } from \"./hooks/use-thread-input\";\n\n// Re-export provider components\nexport {\n TamboClientProvider,\n TamboComponentProvider,\n TamboContextHelpersProvider,\n TamboPropStreamProvider,\n TamboProvider,\n TamboStubProvider,\n TamboThreadProvider,\n useTambo,\n useTamboClient,\n useTamboContextHelpers,\n useTamboStream,\n useTamboThread,\n type TamboComponent,\n type TamboContextHelpersContextProps,\n type TamboContextHelpersProviderProps,\n type TamboRegistryContext,\n type TamboStubProviderProps,\n} from \"./providers\";\n\n// Re-export types from Tambo Node SDK\nexport type {\n APIError,\n RateLimitError,\n TamboAIError,\n} from \"@tambo-ai/typescript-sdk\";\nexport type {\n Suggestion,\n SuggestionGenerateParams,\n SuggestionGenerateResponse,\n SuggestionListResponse,\n} from \"@tambo-ai/typescript-sdk/resources/beta/threads/suggestions\";\nexport { useTamboThreadList } from \"./hooks/use-tambo-threads\";\nexport {\n type ComponentContextToolMetadata,\n type ComponentRegistry,\n type ParameterSpec,\n type RegisteredComponent,\n type TamboTool,\n} from \"./model/component-metadata\";\nexport {\n GenerationStage,\n type TamboThreadMessage,\n} from \"./model/generate-component-response\";\nexport { type TamboThread } from \"./model/tambo-thread\";\n\nexport type {\n TamboInteractableComponent as InteractableComponent,\n TamboInteractableContext,\n} from \"./model/tambo-interactable\";\nexport {\n withTamboInteractable as withInteractable,\n type InteractableConfig,\n type WithTamboInteractableProps,\n} from \"./providers/hoc/with-tambo-interactable\";\nexport { useTamboInteractable } from \"./providers/tambo-interactable-provider\";\n\n// Context helpers exports\nexport {\n DEFAULT_CONTEXT_HELPERS,\n getUserPageContext,\n getUserTimeContext,\n} from \"./context-helpers\";\nexport type {\n AdditionalContext,\n AdditionalContextHelper,\n ContextHelpersConfig,\n} from \"./context-helpers\";\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tambo-context-helpers-provider.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tambo-context-helpers-provider.test.d.ts","sourceRoot":"","sources":["../../../src/providers/__tests__/tambo-context-helpers-provider.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,156 @@
1
+ import { act, renderHook } from "@testing-library/react";
2
+ import React from "react";
3
+ import * as contextHelpers from "../../context-helpers";
4
+ import { DEFAULT_CONTEXT_HELPERS } from "../../context-helpers";
5
+ import { TamboContextHelpersProvider, useTamboContextHelpers, } from "../tambo-context-helpers-provider";
6
+ describe("TamboContextHelpersProvider", () => {
7
+ // Create a wrapper component that provides the context for testing hooks
8
+ const wrapper = ({ children }) => (React.createElement(TamboContextHelpersProvider, null, children));
9
+ describe("useTamboContextHelpers", () => {
10
+ /**
11
+ * Test: Hook throws error when used outside of provider
12
+ * This ensures developers get a clear error message if they forget to wrap
13
+ * their components with the TamboContextHelpersProvider
14
+ */
15
+ it("should throw error when used outside provider", () => {
16
+ // Mock console.error to prevent error output in test logs
17
+ const consoleSpy = jest
18
+ .spyOn(console, "error")
19
+ .mockImplementation(() => { });
20
+ // Verify that using the hook without a provider throws the expected error
21
+ expect(() => {
22
+ renderHook(() => useTamboContextHelpers());
23
+ }).toThrow("useTamboContextHelpers must be used within a TamboContextHelpersProvider");
24
+ // Restore console.error to its original implementation
25
+ consoleSpy.mockRestore();
26
+ });
27
+ /**
28
+ * Test: Hook provides the expected API functions
29
+ * Verifies that all required functions are available when the hook is used
30
+ * within the provider context
31
+ */
32
+ it("should provide context helpers functions", () => {
33
+ const { result } = renderHook(() => useTamboContextHelpers(), {
34
+ wrapper,
35
+ });
36
+ // Verify all expected functions are present in the hook's return value
37
+ expect(result.current).toHaveProperty("getAdditionalContext");
38
+ expect(result.current).toHaveProperty("getContextHelpers");
39
+ expect(result.current).toHaveProperty("setContextHelperEnabled");
40
+ });
41
+ /**
42
+ * Test: Default configuration is applied correctly
43
+ * Ensures that the default context helpers are loaded with their
44
+ * expected enabled/disabled states
45
+ */
46
+ it("should return default context helpers configuration", () => {
47
+ const { result } = renderHook(() => useTamboContextHelpers(), {
48
+ wrapper,
49
+ });
50
+ const helpers = result.current.getContextHelpers();
51
+ // Verify we have the expected number of default helpers
52
+ expect(helpers).toHaveLength(DEFAULT_CONTEXT_HELPERS.length);
53
+ // Check specific helpers have their expected default states
54
+ const userTimeHelper = helpers.find((h) => h.name === "userTime");
55
+ const userPageHelper = helpers.find((h) => h.name === "userPage");
56
+ // userTime should be disabled by default
57
+ expect(userTimeHelper?.enabled).toBe(false);
58
+ // userPage should be disabled by default
59
+ expect(userPageHelper?.enabled).toBe(false);
60
+ });
61
+ /**
62
+ * Test: Context helper enabled state can be toggled
63
+ * Verifies that the setContextHelperEnabled function correctly updates
64
+ * the enabled state of individual helpers
65
+ */
66
+ it("should allow toggling context helper enabled state", () => {
67
+ const { result } = renderHook(() => useTamboContextHelpers(), {
68
+ wrapper,
69
+ });
70
+ // Enable the userPage helper using the provided function
71
+ act(() => {
72
+ result.current.setContextHelperEnabled("userPage", true);
73
+ });
74
+ // Verify the helper's state was updated
75
+ const helpers = result.current.getContextHelpers();
76
+ const userPageHelper = helpers.find((h) => h.name === "userPage");
77
+ expect(userPageHelper?.enabled).toBe(true);
78
+ });
79
+ /**
80
+ * Test: Only enabled helpers contribute to additional context
81
+ * Verifies that getAdditionalContext only runs and returns data from
82
+ * helpers that are currently enabled
83
+ */
84
+ it("should get additional context from enabled helpers", async () => {
85
+ const { result } = renderHook(() => useTamboContextHelpers(), {
86
+ wrapper,
87
+ });
88
+ const contexts = await result.current.getAdditionalContext();
89
+ // By default, no context helpers are enabled, so we should get no contexts
90
+ expect(contexts).toHaveLength(0);
91
+ });
92
+ /**
93
+ * Test: Provider respects configuration prop
94
+ * Verifies that initial configuration can be customized through the
95
+ * contextHelpers prop on the provider
96
+ */
97
+ it("should respect contextHelpers configuration prop", () => {
98
+ // Create a custom wrapper with specific configuration
99
+ const customWrapper = ({ children }) => (React.createElement(TamboContextHelpersProvider, { contextHelpers: {
100
+ userTime: false, // Disable userTime
101
+ userPage: true, // Enable userPage
102
+ } }, children));
103
+ const { result } = renderHook(() => useTamboContextHelpers(), {
104
+ wrapper: customWrapper,
105
+ });
106
+ // Verify the custom configuration is applied
107
+ const helpers = result.current.getContextHelpers();
108
+ const userTimeHelper = helpers.find((h) => h.name === "userTime");
109
+ const userPageHelper = helpers.find((h) => h.name === "userPage");
110
+ expect(userTimeHelper?.enabled).toBe(false);
111
+ expect(userPageHelper?.enabled).toBe(true);
112
+ });
113
+ /**
114
+ * Test: Errors in context helpers are handled gracefully
115
+ * Verifies that if a context helper throws an error, it doesn't crash
116
+ * the entire system and other helpers continue to work
117
+ */
118
+ it("should handle errors in context helper functions gracefully", async () => {
119
+ // Mock console.error to capture error logs
120
+ const consoleErrorSpy = jest
121
+ .spyOn(console, "error")
122
+ .mockImplementation(() => { });
123
+ // Create a helper that will throw an error when run
124
+ const errorHelper = {
125
+ name: "errorHelper",
126
+ enabled: true,
127
+ run: () => {
128
+ throw new Error("Test error");
129
+ },
130
+ };
131
+ // Temporarily add the error helper to the default helpers
132
+ // Store original helpers to restore later
133
+ const originalHelpers = DEFAULT_CONTEXT_HELPERS;
134
+ Object.defineProperty(contextHelpers, "DEFAULT_CONTEXT_HELPERS", {
135
+ value: [...originalHelpers, errorHelper],
136
+ writable: true,
137
+ });
138
+ const { result } = renderHook(() => useTamboContextHelpers(), {
139
+ wrapper,
140
+ });
141
+ // Call getAdditionalContext, which should handle the error gracefully
142
+ const contexts = await result.current.getAdditionalContext();
143
+ // Should have no contexts because the error helper should be skipped
144
+ expect(contexts.length).toBe(0);
145
+ // Verify that the error was logged appropriately
146
+ expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining("Error running context helper errorHelper"), expect.any(Error));
147
+ // Restore the original helpers and console.error
148
+ Object.defineProperty(contextHelpers, "DEFAULT_CONTEXT_HELPERS", {
149
+ value: originalHelpers,
150
+ writable: true,
151
+ });
152
+ consoleErrorSpy.mockRestore();
153
+ });
154
+ });
155
+ });
156
+ //# sourceMappingURL=tambo-context-helpers-provider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tambo-context-helpers-provider.test.js","sourceRoot":"","sources":["../../../src/providers/__tests__/tambo-context-helpers-provider.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { act, renderHook } from \"@testing-library/react\";\nimport React from \"react\";\nimport * as contextHelpers from \"../../context-helpers\";\nimport { DEFAULT_CONTEXT_HELPERS } from \"../../context-helpers\";\nimport {\n TamboContextHelpersProvider,\n useTamboContextHelpers,\n} from \"../tambo-context-helpers-provider\";\n\ndescribe(\"TamboContextHelpersProvider\", () => {\n // Create a wrapper component that provides the context for testing hooks\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboContextHelpersProvider>{children}</TamboContextHelpersProvider>\n );\n\n describe(\"useTamboContextHelpers\", () => {\n /**\n * Test: Hook throws error when used outside of provider\n * This ensures developers get a clear error message if they forget to wrap\n * their components with the TamboContextHelpersProvider\n */\n it(\"should throw error when used outside provider\", () => {\n // Mock console.error to prevent error output in test logs\n const consoleSpy = jest\n .spyOn(console, \"error\")\n .mockImplementation(() => {});\n\n // Verify that using the hook without a provider throws the expected error\n expect(() => {\n renderHook(() => useTamboContextHelpers());\n }).toThrow(\n \"useTamboContextHelpers must be used within a TamboContextHelpersProvider\",\n );\n\n // Restore console.error to its original implementation\n consoleSpy.mockRestore();\n });\n\n /**\n * Test: Hook provides the expected API functions\n * Verifies that all required functions are available when the hook is used\n * within the provider context\n */\n it(\"should provide context helpers functions\", () => {\n const { result } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n // Verify all expected functions are present in the hook's return value\n expect(result.current).toHaveProperty(\"getAdditionalContext\");\n expect(result.current).toHaveProperty(\"getContextHelpers\");\n expect(result.current).toHaveProperty(\"setContextHelperEnabled\");\n });\n\n /**\n * Test: Default configuration is applied correctly\n * Ensures that the default context helpers are loaded with their\n * expected enabled/disabled states\n */\n it(\"should return default context helpers configuration\", () => {\n const { result } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n const helpers = result.current.getContextHelpers();\n\n // Verify we have the expected number of default helpers\n expect(helpers).toHaveLength(DEFAULT_CONTEXT_HELPERS.length);\n\n // Check specific helpers have their expected default states\n const userTimeHelper = helpers.find((h) => h.name === \"userTime\");\n const userPageHelper = helpers.find((h) => h.name === \"userPage\");\n\n // userTime should be disabled by default\n expect(userTimeHelper?.enabled).toBe(false);\n // userPage should be disabled by default\n expect(userPageHelper?.enabled).toBe(false);\n });\n\n /**\n * Test: Context helper enabled state can be toggled\n * Verifies that the setContextHelperEnabled function correctly updates\n * the enabled state of individual helpers\n */\n it(\"should allow toggling context helper enabled state\", () => {\n const { result } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n // Enable the userPage helper using the provided function\n act(() => {\n result.current.setContextHelperEnabled(\"userPage\", true);\n });\n\n // Verify the helper's state was updated\n const helpers = result.current.getContextHelpers();\n const userPageHelper = helpers.find((h) => h.name === \"userPage\");\n\n expect(userPageHelper?.enabled).toBe(true);\n });\n\n /**\n * Test: Only enabled helpers contribute to additional context\n * Verifies that getAdditionalContext only runs and returns data from\n * helpers that are currently enabled\n */\n it(\"should get additional context from enabled helpers\", async () => {\n const { result } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n const contexts = await result.current.getAdditionalContext();\n\n // By default, no context helpers are enabled, so we should get no contexts\n expect(contexts).toHaveLength(0);\n });\n\n /**\n * Test: Provider respects configuration prop\n * Verifies that initial configuration can be customized through the\n * contextHelpers prop on the provider\n */\n it(\"should respect contextHelpers configuration prop\", () => {\n // Create a custom wrapper with specific configuration\n const customWrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboContextHelpersProvider\n contextHelpers={{\n userTime: false, // Disable userTime\n userPage: true, // Enable userPage\n }}\n >\n {children}\n </TamboContextHelpersProvider>\n );\n\n const { result } = renderHook(() => useTamboContextHelpers(), {\n wrapper: customWrapper,\n });\n\n // Verify the custom configuration is applied\n const helpers = result.current.getContextHelpers();\n const userTimeHelper = helpers.find((h) => h.name === \"userTime\");\n const userPageHelper = helpers.find((h) => h.name === \"userPage\");\n\n expect(userTimeHelper?.enabled).toBe(false);\n expect(userPageHelper?.enabled).toBe(true);\n });\n\n /**\n * Test: Errors in context helpers are handled gracefully\n * Verifies that if a context helper throws an error, it doesn't crash\n * the entire system and other helpers continue to work\n */\n it(\"should handle errors in context helper functions gracefully\", async () => {\n // Mock console.error to capture error logs\n const consoleErrorSpy = jest\n .spyOn(console, \"error\")\n .mockImplementation(() => {});\n\n // Create a helper that will throw an error when run\n const errorHelper = {\n name: \"errorHelper\",\n enabled: true,\n run: () => {\n throw new Error(\"Test error\");\n },\n };\n\n // Temporarily add the error helper to the default helpers\n // Store original helpers to restore later\n const originalHelpers = DEFAULT_CONTEXT_HELPERS;\n Object.defineProperty(contextHelpers, \"DEFAULT_CONTEXT_HELPERS\", {\n value: [...originalHelpers, errorHelper],\n writable: true,\n });\n\n const { result } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n // Call getAdditionalContext, which should handle the error gracefully\n const contexts = await result.current.getAdditionalContext();\n\n // Should have no contexts because the error helper should be skipped\n expect(contexts.length).toBe(0);\n\n // Verify that the error was logged appropriately\n expect(consoleErrorSpy).toHaveBeenCalledWith(\n expect.stringContaining(\"Error running context helper errorHelper\"),\n expect.any(Error),\n );\n\n // Restore the original helpers and console.error\n Object.defineProperty(contextHelpers, \"DEFAULT_CONTEXT_HELPERS\", {\n value: originalHelpers,\n writable: true,\n });\n consoleErrorSpy.mockRestore();\n });\n });\n});\n"]}
@@ -5,6 +5,7 @@ import { z } from "zod";
5
5
  import { GenerationStage, } from "../../model/generate-component-response";
6
6
  import { serializeRegistry } from "../../testing/tools";
7
7
  import { useTamboClient } from "../tambo-client-provider";
8
+ import { TamboContextHelpersProvider } from "../tambo-context-helpers-provider";
8
9
  import { TamboRegistryProvider } from "../tambo-registry-provider";
9
10
  import { TamboThreadProvider, useTamboThread } from "../tambo-thread-provider";
10
11
  // Mock crypto.randomUUID
@@ -20,29 +21,13 @@ jest.mock("../tambo-client-provider", () => ({
20
21
  jest.mock("@tambo-ai/typescript-sdk", () => ({
21
22
  advanceStream: jest.fn(),
22
23
  }));
23
- // Mock the system context and getCustomContext
24
+ // Mock the getCustomContext
24
25
  jest.mock("../../util/registry", () => ({
25
26
  ...jest.requireActual("../../util/registry"),
26
- getSystemContext: () => ({
27
- localTime: "7/24/2025, 6:26:21 PM",
28
- timezone: "America/New_York",
29
- }),
30
27
  getCustomContext: () => ({
31
28
  message: "additional instructions",
32
29
  }),
33
30
  }));
34
- // Mock the combined context which includes the system context and the custom context
35
- const mockCombinedContext = {
36
- system: {
37
- localTime: "7/24/2025, 6:26:21 PM",
38
- timezone: "America/New_York",
39
- },
40
- ...{
41
- custom: {
42
- message: "additional instructions",
43
- },
44
- },
45
- };
46
31
  // Test utilities
47
32
  const createMockMessage = (overrides = {}) => ({
48
33
  id: "test-message-1",
@@ -115,7 +100,8 @@ describe("TamboThreadProvider", () => {
115
100
  },
116
101
  ];
117
102
  const wrapper = ({ children }) => (React.createElement(TamboRegistryProvider, { components: mockRegistry },
118
- React.createElement(TamboThreadProvider, { streaming: false }, children)));
103
+ React.createElement(TamboContextHelpersProvider, { contextHelpers: { userTime: false, userPage: false } },
104
+ React.createElement(TamboThreadProvider, { streaming: false }, children))));
119
105
  beforeEach(() => {
120
106
  jest.clearAllMocks();
121
107
  jest.mocked(mockThreadsApi.retrieve).mockResolvedValue(mockThread);
@@ -223,7 +209,11 @@ describe("TamboThreadProvider", () => {
223
209
  messageToAppend: {
224
210
  content: [{ type: "text", text: "Hello" }],
225
211
  role: "user",
226
- additionalContext: mockCombinedContext,
212
+ additionalContext: {
213
+ custom: {
214
+ message: "additional instructions",
215
+ },
216
+ },
227
217
  },
228
218
  availableComponents: serializeRegistry(mockRegistry),
229
219
  contextKey: undefined,
@@ -316,7 +306,8 @@ describe("TamboThreadProvider", () => {
316
306
  it("should call advanceStream when streamResponse=true", async () => {
317
307
  // Use wrapper with streaming=true to show that explicit streamResponse=true works
318
308
  const wrapperWithStreaming = ({ children, }) => (React.createElement(TamboRegistryProvider, { components: mockRegistry },
319
- React.createElement(TamboThreadProvider, { streaming: true }, children)));
309
+ React.createElement(TamboContextHelpersProvider, { contextHelpers: { userTime: false, userPage: false } },
310
+ React.createElement(TamboThreadProvider, { streaming: true }, children))));
320
311
  const mockStreamResponse = {
321
312
  responseMessageDto: {
322
313
  id: "stream-response",
@@ -354,7 +345,11 @@ describe("TamboThreadProvider", () => {
354
345
  messageToAppend: {
355
346
  content: [{ type: "text", text: "Hello streaming" }],
356
347
  role: "user",
357
- additionalContext: mockCombinedContext,
348
+ additionalContext: {
349
+ custom: {
350
+ message: "additional instructions",
351
+ },
352
+ },
358
353
  },
359
354
  availableComponents: serializeRegistry(mockRegistry),
360
355
  contextKey: undefined,
@@ -369,7 +364,8 @@ describe("TamboThreadProvider", () => {
369
364
  it("should call advanceById when streamResponse=false for existing thread", async () => {
370
365
  // Use wrapper with streaming=true to show that explicit streamResponse=false overrides provider setting
371
366
  const wrapperWithStreaming = ({ children, }) => (React.createElement(TamboRegistryProvider, { components: mockRegistry },
372
- React.createElement(TamboThreadProvider, { streaming: true }, children)));
367
+ React.createElement(TamboContextHelpersProvider, { contextHelpers: { userTime: false, userPage: false } },
368
+ React.createElement(TamboThreadProvider, { streaming: true }, children))));
373
369
  const { result } = renderHook(() => useTamboThread(), {
374
370
  wrapper: wrapperWithStreaming,
375
371
  });
@@ -388,7 +384,11 @@ describe("TamboThreadProvider", () => {
388
384
  messageToAppend: {
389
385
  content: [{ type: "text", text: "Hello non-streaming" }],
390
386
  role: "user",
391
- additionalContext: mockCombinedContext,
387
+ additionalContext: {
388
+ custom: {
389
+ message: "additional instructions",
390
+ },
391
+ },
392
392
  },
393
393
  availableComponents: serializeRegistry(mockRegistry),
394
394
  contextKey: undefined,
@@ -403,7 +403,8 @@ describe("TamboThreadProvider", () => {
403
403
  it("should call advanceById when streamResponse is undefined and provider streaming=false", async () => {
404
404
  // Use wrapper with streaming=false to test that undefined streamResponse respects provider setting
405
405
  const wrapperWithoutStreaming = ({ children, }) => (React.createElement(TamboRegistryProvider, { components: mockRegistry },
406
- React.createElement(TamboThreadProvider, { streaming: false }, children)));
406
+ React.createElement(TamboContextHelpersProvider, { contextHelpers: { userTime: false, userPage: false } },
407
+ React.createElement(TamboThreadProvider, { streaming: false }, children))));
407
408
  const { result } = renderHook(() => useTamboThread(), {
408
409
  wrapper: wrapperWithoutStreaming,
409
410
  });
@@ -422,7 +423,11 @@ describe("TamboThreadProvider", () => {
422
423
  messageToAppend: {
423
424
  content: [{ type: "text", text: "Hello default" }],
424
425
  role: "user",
425
- additionalContext: mockCombinedContext,
426
+ additionalContext: {
427
+ custom: {
428
+ message: "additional instructions",
429
+ },
430
+ },
426
431
  },
427
432
  availableComponents: serializeRegistry(mockRegistry),
428
433
  contextKey: undefined,
@@ -437,7 +442,8 @@ describe("TamboThreadProvider", () => {
437
442
  it("should call advanceStream when streamResponse is undefined and provider streaming=true (default)", async () => {
438
443
  // Use wrapper with streaming=true (default) to test that undefined streamResponse respects provider setting
439
444
  const wrapperWithDefaultStreaming = ({ children, }) => (React.createElement(TamboRegistryProvider, { components: mockRegistry },
440
- React.createElement(TamboThreadProvider, null, children)));
445
+ React.createElement(TamboContextHelpersProvider, { contextHelpers: { userTime: false, userPage: false } },
446
+ React.createElement(TamboThreadProvider, null, children))));
441
447
  const mockStreamResponse = {
442
448
  responseMessageDto: {
443
449
  id: "stream-response",
@@ -475,7 +481,11 @@ describe("TamboThreadProvider", () => {
475
481
  messageToAppend: {
476
482
  content: [{ type: "text", text: "Hello default streaming" }],
477
483
  role: "user",
478
- additionalContext: mockCombinedContext,
484
+ additionalContext: {
485
+ custom: {
486
+ message: "additional instructions",
487
+ },
488
+ },
479
489
  },
480
490
  availableComponents: serializeRegistry(mockRegistry),
481
491
  contextKey: undefined,
@@ -490,7 +500,8 @@ describe("TamboThreadProvider", () => {
490
500
  it("should call advance when streamResponse=false for placeholder thread", async () => {
491
501
  // Use wrapper with streaming=true to show that explicit streamResponse=false overrides provider setting
492
502
  const wrapperWithStreaming = ({ children, }) => (React.createElement(TamboRegistryProvider, { components: mockRegistry },
493
- React.createElement(TamboThreadProvider, { streaming: true }, children)));
503
+ React.createElement(TamboContextHelpersProvider, { contextHelpers: { userTime: false, userPage: false } },
504
+ React.createElement(TamboThreadProvider, { streaming: true }, children))));
494
505
  const { result } = renderHook(() => useTamboThread(), {
495
506
  wrapper: wrapperWithStreaming,
496
507
  });
@@ -511,7 +522,11 @@ describe("TamboThreadProvider", () => {
511
522
  messageToAppend: {
512
523
  content: [{ type: "text", text: "Hello new thread" }],
513
524
  role: "user",
514
- additionalContext: mockCombinedContext,
525
+ additionalContext: {
526
+ custom: {
527
+ message: "additional instructions",
528
+ },
529
+ },
515
530
  },
516
531
  availableComponents: serializeRegistry(mockRegistry),
517
532
  contextKey: undefined,
@@ -526,7 +541,8 @@ describe("TamboThreadProvider", () => {
526
541
  it("should call advanceStream when streamResponse=true for placeholder thread", async () => {
527
542
  // Use wrapper with streaming=false to show that explicit streamResponse=true overrides provider setting
528
543
  const wrapperWithoutStreaming = ({ children, }) => (React.createElement(TamboRegistryProvider, { components: mockRegistry },
529
- React.createElement(TamboThreadProvider, { streaming: false }, children)));
544
+ React.createElement(TamboContextHelpersProvider, { contextHelpers: { userTime: false, userPage: false } },
545
+ React.createElement(TamboThreadProvider, { streaming: false }, children))));
530
546
  const mockStreamResponse = {
531
547
  responseMessageDto: {
532
548
  id: "stream-response",
@@ -566,7 +582,11 @@ describe("TamboThreadProvider", () => {
566
582
  messageToAppend: {
567
583
  content: [{ type: "text", text: "Hello streaming new thread" }],
568
584
  role: "user",
569
- additionalContext: mockCombinedContext,
585
+ additionalContext: {
586
+ custom: {
587
+ message: "additional instructions",
588
+ },
589
+ },
570
590
  },
571
591
  availableComponents: serializeRegistry(mockRegistry),
572
592
  contextKey: undefined,