@tambo-ai/react 0.68.0 → 0.69.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.
- package/README.md +1 -1
- package/dist/context-helpers/context-helpers.test.js +16 -4
- package/dist/context-helpers/context-helpers.test.js.map +1 -1
- package/dist/context-helpers/current-interactables-context-helper.d.ts +2 -2
- package/dist/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
- package/dist/context-helpers/current-interactables-context-helper.js +31 -15
- package/dist/context-helpers/current-interactables-context-helper.js.map +1 -1
- package/dist/context-helpers/registry.d.ts +2 -2
- package/dist/context-helpers/registry.d.ts.map +1 -1
- package/dist/context-helpers/registry.js.map +1 -1
- package/dist/context-helpers/types.d.ts +2 -2
- package/dist/context-helpers/types.d.ts.map +1 -1
- package/dist/context-helpers/types.js.map +1 -1
- package/dist/hooks/use-message-images.test.js +174 -37
- package/dist/hooks/use-message-images.test.js.map +1 -1
- package/dist/hooks/use-tambo-voice.d.ts +1 -1
- package/dist/hooks/use-tambo-voice.js +1 -1
- package/dist/hooks/use-tambo-voice.js.map +1 -1
- package/dist/hooks/use-tambo-voice.test.d.ts +2 -0
- package/dist/hooks/use-tambo-voice.test.d.ts.map +1 -0
- package/dist/hooks/use-tambo-voice.test.js +239 -0
- package/dist/hooks/use-tambo-voice.test.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/elicitation.d.ts.map +1 -1
- package/dist/mcp/elicitation.js +12 -0
- package/dist/mcp/elicitation.js.map +1 -1
- package/dist/mcp/elicitation.test.js +8 -1
- package/dist/mcp/elicitation.test.js.map +1 -1
- package/dist/mcp/mcp-client.d.ts +6 -10
- package/dist/mcp/mcp-client.d.ts.map +1 -1
- package/dist/mcp/mcp-client.js.map +1 -1
- package/dist/mcp/mcp-hooks.d.ts +12 -60
- package/dist/mcp/mcp-hooks.d.ts.map +1 -1
- package/dist/mcp/mcp-hooks.js +90 -10
- package/dist/mcp/mcp-hooks.js.map +1 -1
- package/dist/mcp/mcp-hooks.test.js +423 -0
- package/dist/mcp/mcp-hooks.test.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/dist/mcp/tambo-mcp-provider.js +3 -0
- package/dist/mcp/tambo-mcp-provider.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.test.js +37 -0
- package/dist/mcp/tambo-mcp-provider.test.js.map +1 -1
- package/dist/model/component-metadata.d.ts +53 -20
- package/dist/model/component-metadata.d.ts.map +1 -1
- package/dist/model/component-metadata.js.map +1 -1
- package/dist/model/tambo-interactable.d.ts +6 -0
- package/dist/model/tambo-interactable.d.ts.map +1 -1
- package/dist/model/tambo-interactable.js.map +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/tambo-client-provider.d.ts +8 -0
- package/dist/providers/tambo-client-provider.d.ts.map +1 -1
- package/dist/providers/tambo-client-provider.js +10 -11
- package/dist/providers/tambo-client-provider.js.map +1 -1
- package/dist/providers/tambo-client-provider.test.d.ts +2 -0
- package/dist/providers/tambo-client-provider.test.d.ts.map +1 -0
- package/dist/providers/tambo-client-provider.test.js +208 -0
- package/dist/providers/tambo-client-provider.test.js.map +1 -0
- package/dist/providers/tambo-context-attachment-provider.d.ts +34 -92
- package/dist/providers/tambo-context-attachment-provider.d.ts.map +1 -1
- package/dist/providers/tambo-context-attachment-provider.js +62 -105
- package/dist/providers/tambo-context-attachment-provider.js.map +1 -1
- package/dist/providers/tambo-context-attachment-provider.test.js +229 -463
- package/dist/providers/tambo-context-attachment-provider.test.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.d.ts +2 -0
- package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/dist/providers/tambo-interactable-provider.js +29 -4
- package/dist/providers/tambo-interactable-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.test.js +1 -1
- package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
- package/dist/providers/tambo-interactables-additional-context.test.js +2 -5
- package/dist/providers/tambo-interactables-additional-context.test.js.map +1 -1
- package/dist/providers/tambo-provider.d.ts +2 -3
- package/dist/providers/tambo-provider.d.ts.map +1 -1
- package/dist/providers/tambo-provider.js +5 -6
- package/dist/providers/tambo-provider.js.map +1 -1
- package/dist/providers/tambo-registry-provider.test.js +16 -0
- package/dist/providers/tambo-registry-provider.test.js.map +1 -1
- package/dist/providers/tambo-registry-schema-compat.test.js +31 -0
- package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -1
- package/dist/providers/tambo-thread-input-provider.d.ts +1 -1
- package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-input-provider.js +5 -1
- package/dist/providers/tambo-thread-input-provider.js.map +1 -1
- package/dist/providers/tambo-thread-provider-initial-messages.test.js +84 -2
- package/dist/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
- package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-provider.js +56 -43
- package/dist/providers/tambo-thread-provider.js.map +1 -1
- package/dist/providers/tambo-thread-provider.test.js +456 -262
- package/dist/providers/tambo-thread-provider.test.js.map +1 -1
- package/dist/schema/json-schema.js +29 -29
- package/dist/schema/json-schema.js.map +1 -1
- package/dist/schema/schema.test.js +237 -0
- package/dist/schema/schema.test.js.map +1 -1
- package/dist/schema/standard-schema.d.ts +1 -0
- package/dist/schema/standard-schema.d.ts.map +1 -1
- package/dist/schema/standard-schema.js +18 -13
- package/dist/schema/standard-schema.js.map +1 -1
- package/dist/schema/standard-schema.test.d.ts +2 -0
- package/dist/schema/standard-schema.test.d.ts.map +1 -0
- package/dist/schema/standard-schema.test.js +165 -0
- package/dist/schema/standard-schema.test.js.map +1 -0
- package/dist/schema/validate.test.js +149 -0
- package/dist/schema/validate.test.js.map +1 -1
- package/dist/schema/zod.d.ts +7 -4
- package/dist/schema/zod.d.ts.map +1 -1
- package/dist/schema/zod.js +65 -22
- package/dist/schema/zod.js.map +1 -1
- package/dist/schema/zod.test.js +112 -0
- package/dist/schema/zod.test.js.map +1 -1
- package/dist/testing/tools.d.ts +4 -1
- package/dist/testing/tools.d.ts.map +1 -1
- package/dist/testing/tools.js +6 -1
- package/dist/testing/tools.js.map +1 -1
- package/dist/util/generate-component.d.ts.map +1 -1
- package/dist/util/generate-component.js +18 -3
- package/dist/util/generate-component.js.map +1 -1
- package/dist/util/generate-component.test.d.ts +2 -0
- package/dist/util/generate-component.test.d.ts.map +1 -0
- package/dist/util/generate-component.test.js +340 -0
- package/dist/util/generate-component.test.js.map +1 -0
- package/dist/util/is-promise.d.ts +9 -0
- package/dist/util/is-promise.d.ts.map +1 -0
- package/dist/util/is-promise.js +20 -0
- package/dist/util/is-promise.js.map +1 -0
- package/dist/util/is-promise.test.d.ts +2 -0
- package/dist/util/is-promise.test.d.ts.map +1 -0
- package/dist/util/is-promise.test.js +48 -0
- package/dist/util/is-promise.test.js.map +1 -0
- package/dist/util/query-utils.test.d.ts +2 -0
- package/dist/util/query-utils.test.d.ts.map +1 -0
- package/dist/util/query-utils.test.js +382 -0
- package/dist/util/query-utils.test.js.map +1 -0
- package/dist/util/registry-validators.d.ts.map +1 -1
- package/dist/util/registry-validators.js +7 -0
- package/dist/util/registry-validators.js.map +1 -1
- package/dist/util/registry-validators.test.js +57 -0
- package/dist/util/registry-validators.test.js.map +1 -1
- package/dist/util/registry.d.ts.map +1 -1
- package/dist/util/registry.js +9 -0
- package/dist/util/registry.js.map +1 -1
- package/dist/util/registry.test.js +323 -1
- package/dist/util/registry.test.js.map +1 -1
- package/dist/util/resource-validators.test.d.ts +2 -0
- package/dist/util/resource-validators.test.d.ts.map +1 -0
- package/dist/util/resource-validators.test.js +90 -0
- package/dist/util/resource-validators.test.js.map +1 -0
- package/dist/util/tool-caller.d.ts +2 -2
- package/dist/util/tool-caller.d.ts.map +1 -1
- package/dist/util/tool-caller.js +8 -8
- package/dist/util/tool-caller.js.map +1 -1
- package/dist/util/validate-component-name.test.d.ts +2 -0
- package/dist/util/validate-component-name.test.d.ts.map +1 -0
- package/dist/util/validate-component-name.test.js +35 -0
- package/dist/util/validate-component-name.test.js.map +1 -0
- package/esm/context-helpers/context-helpers.test.js +16 -4
- package/esm/context-helpers/context-helpers.test.js.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.d.ts +2 -2
- package/esm/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.js +31 -15
- package/esm/context-helpers/current-interactables-context-helper.js.map +1 -1
- package/esm/context-helpers/registry.d.ts +2 -2
- package/esm/context-helpers/registry.d.ts.map +1 -1
- package/esm/context-helpers/registry.js.map +1 -1
- package/esm/context-helpers/types.d.ts +2 -2
- package/esm/context-helpers/types.d.ts.map +1 -1
- package/esm/context-helpers/types.js.map +1 -1
- package/esm/hooks/use-message-images.test.js +174 -37
- package/esm/hooks/use-message-images.test.js.map +1 -1
- package/esm/hooks/use-tambo-voice.d.ts +1 -1
- package/esm/hooks/use-tambo-voice.js +1 -1
- package/esm/hooks/use-tambo-voice.js.map +1 -1
- package/esm/hooks/use-tambo-voice.test.d.ts +2 -0
- package/esm/hooks/use-tambo-voice.test.d.ts.map +1 -0
- package/esm/hooks/use-tambo-voice.test.js +234 -0
- package/esm/hooks/use-tambo-voice.test.js.map +1 -0
- package/esm/index.d.ts +2 -2
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js.map +1 -1
- package/esm/mcp/elicitation.d.ts.map +1 -1
- package/esm/mcp/elicitation.js +12 -0
- package/esm/mcp/elicitation.js.map +1 -1
- package/esm/mcp/elicitation.test.js +8 -1
- package/esm/mcp/elicitation.test.js.map +1 -1
- package/esm/mcp/mcp-client.d.ts +6 -10
- package/esm/mcp/mcp-client.d.ts.map +1 -1
- package/esm/mcp/mcp-client.js.map +1 -1
- package/esm/mcp/mcp-hooks.d.ts +12 -60
- package/esm/mcp/mcp-hooks.d.ts.map +1 -1
- package/esm/mcp/mcp-hooks.js +57 -10
- package/esm/mcp/mcp-hooks.js.map +1 -1
- package/esm/mcp/mcp-hooks.test.js +423 -0
- package/esm/mcp/mcp-hooks.test.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/esm/mcp/tambo-mcp-provider.js +3 -0
- package/esm/mcp/tambo-mcp-provider.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.test.js +37 -0
- package/esm/mcp/tambo-mcp-provider.test.js.map +1 -1
- package/esm/model/component-metadata.d.ts +53 -20
- package/esm/model/component-metadata.d.ts.map +1 -1
- package/esm/model/component-metadata.js.map +1 -1
- package/esm/model/tambo-interactable.d.ts +6 -0
- package/esm/model/tambo-interactable.d.ts.map +1 -1
- package/esm/model/tambo-interactable.js.map +1 -1
- package/esm/providers/index.d.ts +1 -1
- package/esm/providers/index.d.ts.map +1 -1
- package/esm/providers/index.js.map +1 -1
- package/esm/providers/tambo-client-provider.d.ts +8 -0
- package/esm/providers/tambo-client-provider.d.ts.map +1 -1
- package/esm/providers/tambo-client-provider.js +11 -12
- package/esm/providers/tambo-client-provider.js.map +1 -1
- package/esm/providers/tambo-client-provider.test.d.ts +2 -0
- package/esm/providers/tambo-client-provider.test.d.ts.map +1 -0
- package/esm/providers/tambo-client-provider.test.js +203 -0
- package/esm/providers/tambo-client-provider.test.js.map +1 -0
- package/esm/providers/tambo-context-attachment-provider.d.ts +34 -92
- package/esm/providers/tambo-context-attachment-provider.d.ts.map +1 -1
- package/esm/providers/tambo-context-attachment-provider.js +63 -106
- package/esm/providers/tambo-context-attachment-provider.js.map +1 -1
- package/esm/providers/tambo-context-attachment-provider.test.js +230 -464
- package/esm/providers/tambo-context-attachment-provider.test.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +2 -0
- package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/esm/providers/tambo-interactable-provider.js +29 -4
- package/esm/providers/tambo-interactable-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.test.js +1 -1
- package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
- package/esm/providers/tambo-interactables-additional-context.test.js +2 -5
- package/esm/providers/tambo-interactables-additional-context.test.js.map +1 -1
- package/esm/providers/tambo-provider.d.ts +2 -3
- package/esm/providers/tambo-provider.d.ts.map +1 -1
- package/esm/providers/tambo-provider.js +5 -6
- package/esm/providers/tambo-provider.js.map +1 -1
- package/esm/providers/tambo-registry-provider.test.js +16 -0
- package/esm/providers/tambo-registry-provider.test.js.map +1 -1
- package/esm/providers/tambo-registry-schema-compat.test.js +31 -0
- package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -1
- package/esm/providers/tambo-thread-input-provider.d.ts +1 -1
- package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-input-provider.js +5 -1
- package/esm/providers/tambo-thread-input-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider-initial-messages.test.js +84 -2
- package/esm/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
- package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-provider.js +56 -43
- package/esm/providers/tambo-thread-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider.test.js +456 -262
- package/esm/providers/tambo-thread-provider.test.js.map +1 -1
- package/esm/schema/json-schema.js +1 -1
- package/esm/schema/json-schema.js.map +1 -1
- package/esm/schema/schema.test.js +238 -1
- package/esm/schema/schema.test.js.map +1 -1
- package/esm/schema/standard-schema.d.ts +1 -0
- package/esm/schema/standard-schema.d.ts.map +1 -1
- package/esm/schema/standard-schema.js +18 -13
- package/esm/schema/standard-schema.js.map +1 -1
- package/esm/schema/standard-schema.test.d.ts +2 -0
- package/esm/schema/standard-schema.test.d.ts.map +1 -0
- package/esm/schema/standard-schema.test.js +130 -0
- package/esm/schema/standard-schema.test.js.map +1 -0
- package/esm/schema/validate.test.js +149 -0
- package/esm/schema/validate.test.js.map +1 -1
- package/esm/schema/zod.d.ts +7 -4
- package/esm/schema/zod.d.ts.map +1 -1
- package/esm/schema/zod.js +65 -22
- package/esm/schema/zod.js.map +1 -1
- package/esm/schema/zod.test.js +113 -1
- package/esm/schema/zod.test.js.map +1 -1
- package/esm/testing/tools.d.ts +4 -1
- package/esm/testing/tools.d.ts.map +1 -1
- package/esm/testing/tools.js +6 -1
- package/esm/testing/tools.js.map +1 -1
- package/esm/util/generate-component.d.ts.map +1 -1
- package/esm/util/generate-component.js +18 -3
- package/esm/util/generate-component.js.map +1 -1
- package/esm/util/generate-component.test.d.ts +2 -0
- package/esm/util/generate-component.test.d.ts.map +1 -0
- package/esm/util/generate-component.test.js +302 -0
- package/esm/util/generate-component.test.js.map +1 -0
- package/esm/util/is-promise.d.ts +9 -0
- package/esm/util/is-promise.d.ts.map +1 -0
- package/esm/util/is-promise.js +17 -0
- package/esm/util/is-promise.js.map +1 -0
- package/esm/util/is-promise.test.d.ts +2 -0
- package/esm/util/is-promise.test.d.ts.map +1 -0
- package/esm/util/is-promise.test.js +46 -0
- package/esm/util/is-promise.test.js.map +1 -0
- package/esm/util/query-utils.test.d.ts +2 -0
- package/esm/util/query-utils.test.d.ts.map +1 -0
- package/esm/util/query-utils.test.js +380 -0
- package/esm/util/query-utils.test.js.map +1 -0
- package/esm/util/registry-validators.d.ts.map +1 -1
- package/esm/util/registry-validators.js +7 -0
- package/esm/util/registry-validators.js.map +1 -1
- package/esm/util/registry-validators.test.js +57 -0
- package/esm/util/registry-validators.test.js.map +1 -1
- package/esm/util/registry.d.ts.map +1 -1
- package/esm/util/registry.js +9 -0
- package/esm/util/registry.js.map +1 -1
- package/esm/util/registry.test.js +324 -2
- package/esm/util/registry.test.js.map +1 -1
- package/esm/util/resource-validators.test.d.ts +2 -0
- package/esm/util/resource-validators.test.d.ts.map +1 -0
- package/esm/util/resource-validators.test.js +88 -0
- package/esm/util/resource-validators.test.js.map +1 -0
- package/esm/util/tool-caller.d.ts +2 -2
- package/esm/util/tool-caller.d.ts.map +1 -1
- package/esm/util/tool-caller.js +8 -8
- package/esm/util/tool-caller.js.map +1 -1
- package/esm/util/validate-component-name.test.d.ts +2 -0
- package/esm/util/validate-component-name.test.d.ts.map +1 -0
- package/esm/util/validate-component-name.test.js +33 -0
- package/esm/util/validate-component-name.test.js.map +1 -0
- package/package.json +15 -23
- package/dist/schema/alias.d.ts +0 -3
- package/dist/schema/alias.d.ts.map +0 -1
- package/dist/schema/alias.js +0 -6
- package/dist/schema/alias.js.map +0 -1
- package/esm/schema/alias.d.ts +0 -3
- package/esm/schema/alias.d.ts.map +0 -1
- package/esm/schema/alias.js +0 -13
- package/esm/schema/alias.js.map +0 -1
|
@@ -115,8 +115,18 @@ describe("TamboThreadProvider", () => {
|
|
|
115
115
|
],
|
|
116
116
|
},
|
|
117
117
|
];
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Creates a test wrapper component with configurable options.
|
|
120
|
+
* Reduces duplication across tests by centralizing provider setup.
|
|
121
|
+
* @param options - Configuration options for the wrapper
|
|
122
|
+
* @param options.components - The Tambo components to register
|
|
123
|
+
* @param options.streaming - Whether to enable streaming responses
|
|
124
|
+
* @param options.onCallUnregisteredTool - Handler for unregistered tool calls
|
|
125
|
+
* @param options.autoGenerateThreadName - Whether to auto-generate thread names
|
|
126
|
+
* @param options.autoGenerateNameThreshold - Token threshold for auto-generating names
|
|
127
|
+
* @returns A React component that wraps children with the necessary providers
|
|
128
|
+
*/
|
|
129
|
+
const createWrapper = ({ components = mockRegistry, streaming = false, onCallUnregisteredTool, autoGenerateThreadName, autoGenerateNameThreshold, } = {}) => function TestWrapper({ children }) {
|
|
120
130
|
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
121
131
|
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
122
132
|
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
@@ -124,14 +134,16 @@ describe("TamboThreadProvider", () => {
|
|
|
124
134
|
queryClient,
|
|
125
135
|
isUpdatingToken: false,
|
|
126
136
|
} },
|
|
127
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components:
|
|
137
|
+
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: components, onCallUnregisteredTool: onCallUnregisteredTool },
|
|
128
138
|
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
129
139
|
currentTimeContextHelper: () => null,
|
|
130
140
|
currentPageContextHelper: () => null,
|
|
131
141
|
} },
|
|
132
142
|
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
133
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming:
|
|
143
|
+
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: streaming, autoGenerateThreadName: autoGenerateThreadName, autoGenerateNameThreshold: autoGenerateNameThreshold }, children))))));
|
|
134
144
|
};
|
|
145
|
+
// Default wrapper for most tests
|
|
146
|
+
const Wrapper = createWrapper();
|
|
135
147
|
beforeEach(() => {
|
|
136
148
|
jest.clearAllMocks();
|
|
137
149
|
// Setup mock query client
|
|
@@ -349,22 +361,6 @@ describe("TamboThreadProvider", () => {
|
|
|
349
361
|
const mockOnCallUnregisteredTool = jest
|
|
350
362
|
.fn()
|
|
351
363
|
.mockResolvedValue("unregistered-tool-result");
|
|
352
|
-
const WrapperWithUnregisteredTool = ({ children, }) => {
|
|
353
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
354
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
355
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
356
|
-
client,
|
|
357
|
-
queryClient,
|
|
358
|
-
isUpdatingToken: false,
|
|
359
|
-
} },
|
|
360
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: mockRegistry, onCallUnregisteredTool: mockOnCallUnregisteredTool },
|
|
361
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
362
|
-
currentTimeContextHelper: () => null,
|
|
363
|
-
currentPageContextHelper: () => null,
|
|
364
|
-
} },
|
|
365
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
366
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: false }, children))))));
|
|
367
|
-
};
|
|
368
364
|
const mockUnregisteredToolCallResponse = {
|
|
369
365
|
responseMessageDto: {
|
|
370
366
|
id: "unregistered-tool-call-1",
|
|
@@ -399,7 +395,9 @@ describe("TamboThreadProvider", () => {
|
|
|
399
395
|
mcpAccessToken: "test-mcp-access-token",
|
|
400
396
|
});
|
|
401
397
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
402
|
-
wrapper:
|
|
398
|
+
wrapper: createWrapper({
|
|
399
|
+
onCallUnregisteredTool: mockOnCallUnregisteredTool,
|
|
400
|
+
}),
|
|
403
401
|
});
|
|
404
402
|
await (0, react_1.act)(async () => {
|
|
405
403
|
await result.current.sendThreadMessage("Use unregistered tool", {
|
|
@@ -456,23 +454,6 @@ describe("TamboThreadProvider", () => {
|
|
|
456
454
|
});
|
|
457
455
|
describe("streaming behavior", () => {
|
|
458
456
|
it("should call advanceStream when streamResponse=true", async () => {
|
|
459
|
-
// Use wrapper with streaming=true to show that explicit streamResponse=true works
|
|
460
|
-
const WrapperWithStreaming = ({ children, }) => {
|
|
461
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
462
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
463
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
464
|
-
client,
|
|
465
|
-
queryClient,
|
|
466
|
-
isUpdatingToken: false,
|
|
467
|
-
} },
|
|
468
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: mockRegistry },
|
|
469
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
470
|
-
currentTimeContextHelper: () => null,
|
|
471
|
-
currentPageContextHelper: () => null,
|
|
472
|
-
} },
|
|
473
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
474
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: true }, children))))));
|
|
475
|
-
};
|
|
476
457
|
const mockStreamResponse = {
|
|
477
458
|
responseMessageDto: {
|
|
478
459
|
id: "stream-response",
|
|
@@ -493,7 +474,7 @@ describe("TamboThreadProvider", () => {
|
|
|
493
474
|
};
|
|
494
475
|
jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
|
|
495
476
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
496
|
-
wrapper:
|
|
477
|
+
wrapper: createWrapper({ streaming: true }),
|
|
497
478
|
});
|
|
498
479
|
await (0, react_1.act)(async () => {
|
|
499
480
|
await result.current.sendThreadMessage("Hello streaming", {
|
|
@@ -528,24 +509,8 @@ describe("TamboThreadProvider", () => {
|
|
|
528
509
|
});
|
|
529
510
|
it("should call advanceById when streamResponse=false for existing thread", async () => {
|
|
530
511
|
// Use wrapper with streaming=true to show that explicit streamResponse=false overrides provider setting
|
|
531
|
-
const WrapperWithStreaming = ({ children, }) => {
|
|
532
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
533
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
534
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
535
|
-
client,
|
|
536
|
-
queryClient,
|
|
537
|
-
isUpdatingToken: false,
|
|
538
|
-
} },
|
|
539
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: mockRegistry },
|
|
540
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
541
|
-
currentTimeContextHelper: () => null,
|
|
542
|
-
currentPageContextHelper: () => null,
|
|
543
|
-
} },
|
|
544
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
545
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: true }, children))))));
|
|
546
|
-
};
|
|
547
512
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
548
|
-
wrapper:
|
|
513
|
+
wrapper: createWrapper({ streaming: true }),
|
|
549
514
|
});
|
|
550
515
|
await (0, react_1.act)(async () => {
|
|
551
516
|
await result.current.sendThreadMessage("Hello non-streaming", {
|
|
@@ -580,24 +545,8 @@ describe("TamboThreadProvider", () => {
|
|
|
580
545
|
});
|
|
581
546
|
it("should call advanceById when streamResponse is undefined and provider streaming=false", async () => {
|
|
582
547
|
// Use wrapper with streaming=false to test that undefined streamResponse respects provider setting
|
|
583
|
-
const WrapperWithoutStreaming = ({ children, }) => {
|
|
584
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
585
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
586
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
587
|
-
client,
|
|
588
|
-
queryClient,
|
|
589
|
-
isUpdatingToken: false,
|
|
590
|
-
} },
|
|
591
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: mockRegistry },
|
|
592
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
593
|
-
currentTimeContextHelper: () => null,
|
|
594
|
-
currentPageContextHelper: () => null,
|
|
595
|
-
} },
|
|
596
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
597
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: false }, children))))));
|
|
598
|
-
};
|
|
599
548
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
600
|
-
wrapper:
|
|
549
|
+
wrapper: createWrapper({ streaming: false }),
|
|
601
550
|
});
|
|
602
551
|
await (0, react_1.act)(async () => {
|
|
603
552
|
await result.current.sendThreadMessage("Hello default", {
|
|
@@ -631,23 +580,6 @@ describe("TamboThreadProvider", () => {
|
|
|
631
580
|
expect(typescript_sdk_1.advanceStream).not.toHaveBeenCalled();
|
|
632
581
|
});
|
|
633
582
|
it("should call advanceStream when streamResponse is undefined and provider streaming=true (default)", async () => {
|
|
634
|
-
// Use wrapper with streaming=true (default) to test that undefined streamResponse respects provider setting
|
|
635
|
-
const WrapperWithDefaultStreaming = ({ children, }) => {
|
|
636
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
637
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
638
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
639
|
-
client,
|
|
640
|
-
queryClient,
|
|
641
|
-
isUpdatingToken: false,
|
|
642
|
-
} },
|
|
643
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: mockRegistry },
|
|
644
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
645
|
-
currentTimeContextHelper: () => null,
|
|
646
|
-
currentPageContextHelper: () => null,
|
|
647
|
-
} },
|
|
648
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
649
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, null, children))))));
|
|
650
|
-
};
|
|
651
583
|
const mockStreamResponse = {
|
|
652
584
|
responseMessageDto: {
|
|
653
585
|
id: "stream-response",
|
|
@@ -668,7 +600,7 @@ describe("TamboThreadProvider", () => {
|
|
|
668
600
|
};
|
|
669
601
|
jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
|
|
670
602
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
671
|
-
wrapper:
|
|
603
|
+
wrapper: createWrapper({ streaming: true }),
|
|
672
604
|
});
|
|
673
605
|
await (0, react_1.act)(async () => {
|
|
674
606
|
await result.current.sendThreadMessage("Hello default streaming", {
|
|
@@ -703,24 +635,8 @@ describe("TamboThreadProvider", () => {
|
|
|
703
635
|
});
|
|
704
636
|
it("should call advance when streamResponse=false for placeholder thread", async () => {
|
|
705
637
|
// Use wrapper with streaming=true to show that explicit streamResponse=false overrides provider setting
|
|
706
|
-
const WrapperWithStreaming = ({ children, }) => {
|
|
707
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
708
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
709
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
710
|
-
client,
|
|
711
|
-
queryClient,
|
|
712
|
-
isUpdatingToken: false,
|
|
713
|
-
} },
|
|
714
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: mockRegistry },
|
|
715
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
716
|
-
currentTimeContextHelper: () => null,
|
|
717
|
-
currentPageContextHelper: () => null,
|
|
718
|
-
} },
|
|
719
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
720
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: true }, children))))));
|
|
721
|
-
};
|
|
722
638
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
723
|
-
wrapper:
|
|
639
|
+
wrapper: createWrapper({ streaming: true }),
|
|
724
640
|
});
|
|
725
641
|
// Start with placeholder thread (which is the default state)
|
|
726
642
|
expect(result.current.thread.id).toBe("placeholder");
|
|
@@ -756,23 +672,6 @@ describe("TamboThreadProvider", () => {
|
|
|
756
672
|
expect(typescript_sdk_1.advanceStream).not.toHaveBeenCalled();
|
|
757
673
|
});
|
|
758
674
|
it("should call advanceStream when streamResponse=true for placeholder thread", async () => {
|
|
759
|
-
// Use wrapper with streaming=false to show that explicit streamResponse=true overrides provider setting
|
|
760
|
-
const WrapperWithoutStreaming = ({ children, }) => {
|
|
761
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
762
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
763
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
764
|
-
client,
|
|
765
|
-
queryClient,
|
|
766
|
-
isUpdatingToken: false,
|
|
767
|
-
} },
|
|
768
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: mockRegistry },
|
|
769
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
770
|
-
currentTimeContextHelper: () => null,
|
|
771
|
-
currentPageContextHelper: () => null,
|
|
772
|
-
} },
|
|
773
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
774
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: false }, children))))));
|
|
775
|
-
};
|
|
776
675
|
const mockStreamResponse = {
|
|
777
676
|
responseMessageDto: {
|
|
778
677
|
id: "stream-response",
|
|
@@ -793,7 +692,7 @@ describe("TamboThreadProvider", () => {
|
|
|
793
692
|
};
|
|
794
693
|
jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
|
|
795
694
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
796
|
-
wrapper:
|
|
695
|
+
wrapper: createWrapper({ streaming: false }),
|
|
797
696
|
});
|
|
798
697
|
// Start with placeholder thread (which is the default state)
|
|
799
698
|
expect(result.current.thread.id).toBe("placeholder");
|
|
@@ -828,6 +727,94 @@ describe("TamboThreadProvider", () => {
|
|
|
828
727
|
expect(mockThreadsApi.advance).not.toHaveBeenCalled();
|
|
829
728
|
expect(mockThreadsApi.advanceByID).not.toHaveBeenCalled();
|
|
830
729
|
});
|
|
730
|
+
it("should handle multiple sequential messages during streaming (server tool scenario)", async () => {
|
|
731
|
+
// This test verifies the fix for the bug where the second message doesn't render
|
|
732
|
+
// during server tool response streaming. The scenario:
|
|
733
|
+
// 1. First message: "I will call the tool..." with statusMessage
|
|
734
|
+
// 2. Second message: The tool result response streaming in
|
|
735
|
+
// First message - tool announcement (server tools don't have componentName set during streaming)
|
|
736
|
+
const mockFirstMessage = {
|
|
737
|
+
responseMessageDto: {
|
|
738
|
+
id: "msg-first",
|
|
739
|
+
content: [{ type: "text", text: "I will search the docs..." }],
|
|
740
|
+
role: "assistant",
|
|
741
|
+
threadId: "test-thread-1",
|
|
742
|
+
component: {
|
|
743
|
+
componentName: "",
|
|
744
|
+
componentState: {},
|
|
745
|
+
message: "",
|
|
746
|
+
props: {},
|
|
747
|
+
statusMessage: "searching the Tambo docs...",
|
|
748
|
+
},
|
|
749
|
+
componentState: {},
|
|
750
|
+
createdAt: new Date().toISOString(),
|
|
751
|
+
},
|
|
752
|
+
generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
|
|
753
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
754
|
+
};
|
|
755
|
+
// Second message - tool result (different ID!)
|
|
756
|
+
const mockSecondMessageChunk1 = {
|
|
757
|
+
responseMessageDto: {
|
|
758
|
+
id: "msg-second",
|
|
759
|
+
content: [{ type: "text", text: "Here's what I found..." }],
|
|
760
|
+
role: "assistant",
|
|
761
|
+
threadId: "test-thread-1",
|
|
762
|
+
componentState: {},
|
|
763
|
+
createdAt: new Date().toISOString(),
|
|
764
|
+
},
|
|
765
|
+
generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
|
|
766
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
767
|
+
};
|
|
768
|
+
const mockSecondMessageChunk2 = {
|
|
769
|
+
responseMessageDto: {
|
|
770
|
+
id: "msg-second",
|
|
771
|
+
content: [
|
|
772
|
+
{
|
|
773
|
+
type: "text",
|
|
774
|
+
text: "Here's what I found in the documentation about that topic.",
|
|
775
|
+
},
|
|
776
|
+
],
|
|
777
|
+
role: "assistant",
|
|
778
|
+
threadId: "test-thread-1",
|
|
779
|
+
componentState: {},
|
|
780
|
+
createdAt: new Date().toISOString(),
|
|
781
|
+
},
|
|
782
|
+
generationStage: generate_component_response_1.GenerationStage.COMPLETE,
|
|
783
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
784
|
+
};
|
|
785
|
+
const mockAsyncIterator = {
|
|
786
|
+
[Symbol.asyncIterator]: async function* () {
|
|
787
|
+
yield mockFirstMessage;
|
|
788
|
+
yield mockSecondMessageChunk1;
|
|
789
|
+
yield mockSecondMessageChunk2;
|
|
790
|
+
},
|
|
791
|
+
};
|
|
792
|
+
jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValue(mockAsyncIterator);
|
|
793
|
+
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
794
|
+
wrapper: createWrapper({ streaming: true }),
|
|
795
|
+
});
|
|
796
|
+
await (0, react_1.act)(async () => {
|
|
797
|
+
await result.current.sendThreadMessage("Search the docs", {
|
|
798
|
+
threadId: "test-thread-1",
|
|
799
|
+
streamResponse: true,
|
|
800
|
+
});
|
|
801
|
+
});
|
|
802
|
+
// Thread should have 3 messages: user message + 2 assistant messages
|
|
803
|
+
expect(result.current.thread.messages).toHaveLength(3);
|
|
804
|
+
// Filter to assistant messages only
|
|
805
|
+
const assistantMessages = result.current.thread.messages.filter((m) => m.role === "assistant");
|
|
806
|
+
expect(assistantMessages).toHaveLength(2);
|
|
807
|
+
// First assistant message should have the tool status
|
|
808
|
+
const firstMsg = result.current.thread.messages.find((m) => m.id === "msg-first");
|
|
809
|
+
expect(firstMsg).toBeDefined();
|
|
810
|
+
expect(firstMsg?.content[0]?.text).toContain("search the docs");
|
|
811
|
+
// Second assistant message should have the final content
|
|
812
|
+
const secondMsg = result.current.thread.messages.find((m) => m.id === "msg-second");
|
|
813
|
+
expect(secondMsg).toBeDefined();
|
|
814
|
+
expect(secondMsg?.content[0]?.text).toContain("what I found in the documentation");
|
|
815
|
+
// Generation should be complete
|
|
816
|
+
expect(result.current.generationStage).toBe(generate_component_response_1.GenerationStage.COMPLETE);
|
|
817
|
+
});
|
|
831
818
|
});
|
|
832
819
|
describe("error handling", () => {
|
|
833
820
|
it("should set generation stage to ERROR when non-streaming sendThreadMessage fails", async () => {
|
|
@@ -978,22 +965,6 @@ describe("TamboThreadProvider", () => {
|
|
|
978
965
|
],
|
|
979
966
|
},
|
|
980
967
|
];
|
|
981
|
-
const WrapperWithCustomTool = ({ children, }) => {
|
|
982
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
983
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
984
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
985
|
-
client,
|
|
986
|
-
queryClient,
|
|
987
|
-
isUpdatingToken: false,
|
|
988
|
-
} },
|
|
989
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: customToolRegistry },
|
|
990
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
991
|
-
currentTimeContextHelper: () => null,
|
|
992
|
-
currentPageContextHelper: () => null,
|
|
993
|
-
} },
|
|
994
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
995
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: false }, children))))));
|
|
996
|
-
};
|
|
997
968
|
const mockToolCallResponse = {
|
|
998
969
|
responseMessageDto: {
|
|
999
970
|
id: "tool-call-1",
|
|
@@ -1026,7 +997,7 @@ describe("TamboThreadProvider", () => {
|
|
|
1026
997
|
mcpAccessToken: "test-mcp-access-token",
|
|
1027
998
|
});
|
|
1028
999
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
1029
|
-
wrapper:
|
|
1000
|
+
wrapper: createWrapper({ components: customToolRegistry }),
|
|
1030
1001
|
});
|
|
1031
1002
|
await (0, react_1.act)(async () => {
|
|
1032
1003
|
await result.current.sendThreadMessage("Use custom tool", {
|
|
@@ -1079,22 +1050,6 @@ describe("TamboThreadProvider", () => {
|
|
|
1079
1050
|
],
|
|
1080
1051
|
},
|
|
1081
1052
|
];
|
|
1082
|
-
const WrapperWithAsyncTool = ({ children, }) => {
|
|
1083
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
1084
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
1085
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
1086
|
-
client,
|
|
1087
|
-
queryClient,
|
|
1088
|
-
isUpdatingToken: false,
|
|
1089
|
-
} },
|
|
1090
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: customToolRegistry },
|
|
1091
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
1092
|
-
currentTimeContextHelper: () => null,
|
|
1093
|
-
currentPageContextHelper: () => null,
|
|
1094
|
-
} },
|
|
1095
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
1096
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: true }, children))))));
|
|
1097
|
-
};
|
|
1098
1053
|
const mockToolCallChunk = {
|
|
1099
1054
|
responseMessageDto: {
|
|
1100
1055
|
id: "tool-call-chunk",
|
|
@@ -1140,7 +1095,10 @@ describe("TamboThreadProvider", () => {
|
|
|
1140
1095
|
},
|
|
1141
1096
|
});
|
|
1142
1097
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
1143
|
-
wrapper:
|
|
1098
|
+
wrapper: createWrapper({
|
|
1099
|
+
components: customToolRegistry,
|
|
1100
|
+
streaming: true,
|
|
1101
|
+
}),
|
|
1144
1102
|
});
|
|
1145
1103
|
await (0, react_1.act)(async () => {
|
|
1146
1104
|
await result.current.sendThreadMessage("Use async tool", {
|
|
@@ -1188,22 +1146,6 @@ describe("TamboThreadProvider", () => {
|
|
|
1188
1146
|
],
|
|
1189
1147
|
},
|
|
1190
1148
|
];
|
|
1191
|
-
const WrapperWithoutTransform = ({ children, }) => {
|
|
1192
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
1193
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
1194
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
1195
|
-
client,
|
|
1196
|
-
queryClient,
|
|
1197
|
-
isUpdatingToken: false,
|
|
1198
|
-
} },
|
|
1199
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: toolWithoutTransform },
|
|
1200
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
1201
|
-
currentTimeContextHelper: () => null,
|
|
1202
|
-
currentPageContextHelper: () => null,
|
|
1203
|
-
} },
|
|
1204
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
1205
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: false }, children))))));
|
|
1206
|
-
};
|
|
1207
1149
|
const mockToolCallResponse = {
|
|
1208
1150
|
responseMessageDto: {
|
|
1209
1151
|
id: "tool-call-1",
|
|
@@ -1236,7 +1178,7 @@ describe("TamboThreadProvider", () => {
|
|
|
1236
1178
|
mcpAccessToken: "test-mcp-access-token",
|
|
1237
1179
|
});
|
|
1238
1180
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
1239
|
-
wrapper:
|
|
1181
|
+
wrapper: createWrapper({ components: toolWithoutTransform }),
|
|
1240
1182
|
});
|
|
1241
1183
|
await (0, react_1.act)(async () => {
|
|
1242
1184
|
await result.current.sendThreadMessage("Use tool without transform", {
|
|
@@ -1286,22 +1228,6 @@ describe("TamboThreadProvider", () => {
|
|
|
1286
1228
|
],
|
|
1287
1229
|
},
|
|
1288
1230
|
];
|
|
1289
|
-
const WrapperWithErrorTool = ({ children, }) => {
|
|
1290
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
1291
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
1292
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
1293
|
-
client,
|
|
1294
|
-
queryClient,
|
|
1295
|
-
isUpdatingToken: false,
|
|
1296
|
-
} },
|
|
1297
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: toolWithTransform },
|
|
1298
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
1299
|
-
currentTimeContextHelper: () => null,
|
|
1300
|
-
currentPageContextHelper: () => null,
|
|
1301
|
-
} },
|
|
1302
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
1303
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: false }, children))))));
|
|
1304
|
-
};
|
|
1305
1231
|
const mockToolCallResponse = {
|
|
1306
1232
|
responseMessageDto: {
|
|
1307
1233
|
id: "tool-call-1",
|
|
@@ -1334,7 +1260,7 @@ describe("TamboThreadProvider", () => {
|
|
|
1334
1260
|
mcpAccessToken: "test-mcp-access-token",
|
|
1335
1261
|
});
|
|
1336
1262
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
1337
|
-
wrapper:
|
|
1263
|
+
wrapper: createWrapper({ components: toolWithTransform }),
|
|
1338
1264
|
});
|
|
1339
1265
|
await (0, react_1.act)(async () => {
|
|
1340
1266
|
await result.current.sendThreadMessage("Use error tool", {
|
|
@@ -1360,26 +1286,339 @@ describe("TamboThreadProvider", () => {
|
|
|
1360
1286
|
}));
|
|
1361
1287
|
});
|
|
1362
1288
|
});
|
|
1289
|
+
describe("tamboStreamableHint streaming behavior", () => {
|
|
1290
|
+
it("should call streamable tool during streaming when tamboStreamableHint is true", async () => {
|
|
1291
|
+
const streamableToolFn = jest
|
|
1292
|
+
.fn()
|
|
1293
|
+
.mockResolvedValue({ data: "streamed" });
|
|
1294
|
+
const customToolRegistry = [
|
|
1295
|
+
{
|
|
1296
|
+
name: "TestComponent",
|
|
1297
|
+
component: () => react_2.default.createElement("div", null, "Test"),
|
|
1298
|
+
description: "Test",
|
|
1299
|
+
propsSchema: v4_1.z.object({ test: v4_1.z.string() }),
|
|
1300
|
+
associatedTools: [
|
|
1301
|
+
{
|
|
1302
|
+
name: "streamable-tool",
|
|
1303
|
+
tool: streamableToolFn,
|
|
1304
|
+
description: "Tool safe for streaming",
|
|
1305
|
+
inputSchema: v4_1.z.object({ input: v4_1.z.string() }),
|
|
1306
|
+
outputSchema: v4_1.z.object({ data: v4_1.z.string() }),
|
|
1307
|
+
annotations: { tamboStreamableHint: true },
|
|
1308
|
+
},
|
|
1309
|
+
],
|
|
1310
|
+
},
|
|
1311
|
+
];
|
|
1312
|
+
// First chunk initializes finalMessage
|
|
1313
|
+
const mockInitialChunk = {
|
|
1314
|
+
responseMessageDto: {
|
|
1315
|
+
id: "initial-chunk",
|
|
1316
|
+
content: [{ type: "text", text: "Starting..." }],
|
|
1317
|
+
role: "assistant",
|
|
1318
|
+
threadId: "test-thread-1",
|
|
1319
|
+
componentState: {},
|
|
1320
|
+
createdAt: new Date().toISOString(),
|
|
1321
|
+
},
|
|
1322
|
+
generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
|
|
1323
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
1324
|
+
};
|
|
1325
|
+
// Second chunk has the tool call - this triggers streaming tool handling
|
|
1326
|
+
const mockToolCallChunk = {
|
|
1327
|
+
responseMessageDto: {
|
|
1328
|
+
id: "initial-chunk", // Same ID as initial - it's an update
|
|
1329
|
+
content: [{ type: "text", text: "Streaming..." }],
|
|
1330
|
+
role: "assistant",
|
|
1331
|
+
threadId: "test-thread-1",
|
|
1332
|
+
component: {
|
|
1333
|
+
componentName: "",
|
|
1334
|
+
componentState: {},
|
|
1335
|
+
message: "",
|
|
1336
|
+
props: {},
|
|
1337
|
+
toolCallRequest: {
|
|
1338
|
+
toolName: "streamable-tool",
|
|
1339
|
+
parameters: [
|
|
1340
|
+
{ parameterName: "input", parameterValue: "stream-test" },
|
|
1341
|
+
],
|
|
1342
|
+
},
|
|
1343
|
+
},
|
|
1344
|
+
componentState: {},
|
|
1345
|
+
createdAt: new Date().toISOString(),
|
|
1346
|
+
},
|
|
1347
|
+
generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
|
|
1348
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
1349
|
+
};
|
|
1350
|
+
const mockFinalChunk = {
|
|
1351
|
+
responseMessageDto: {
|
|
1352
|
+
id: "initial-chunk",
|
|
1353
|
+
content: [{ type: "text", text: "Complete" }],
|
|
1354
|
+
role: "assistant",
|
|
1355
|
+
threadId: "test-thread-1",
|
|
1356
|
+
componentState: {},
|
|
1357
|
+
createdAt: new Date().toISOString(),
|
|
1358
|
+
},
|
|
1359
|
+
generationStage: generate_component_response_1.GenerationStage.COMPLETE,
|
|
1360
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
1361
|
+
};
|
|
1362
|
+
const mockAsyncIterator = {
|
|
1363
|
+
[Symbol.asyncIterator]: async function* () {
|
|
1364
|
+
yield mockInitialChunk;
|
|
1365
|
+
yield mockToolCallChunk;
|
|
1366
|
+
yield mockFinalChunk;
|
|
1367
|
+
},
|
|
1368
|
+
};
|
|
1369
|
+
jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValueOnce(mockAsyncIterator);
|
|
1370
|
+
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
1371
|
+
wrapper: createWrapper({
|
|
1372
|
+
components: customToolRegistry,
|
|
1373
|
+
streaming: true,
|
|
1374
|
+
}),
|
|
1375
|
+
});
|
|
1376
|
+
await (0, react_1.act)(async () => {
|
|
1377
|
+
await result.current.sendThreadMessage("Test streamable tool", {
|
|
1378
|
+
threadId: "test-thread-1",
|
|
1379
|
+
streamResponse: true,
|
|
1380
|
+
});
|
|
1381
|
+
});
|
|
1382
|
+
// Streamable tool should be called during streaming
|
|
1383
|
+
expect(streamableToolFn).toHaveBeenCalledWith({ input: "stream-test" });
|
|
1384
|
+
});
|
|
1385
|
+
it("should NOT call non-streamable tool during streaming", async () => {
|
|
1386
|
+
const nonStreamableToolFn = jest
|
|
1387
|
+
.fn()
|
|
1388
|
+
.mockResolvedValue({ data: "result" });
|
|
1389
|
+
const customToolRegistry = [
|
|
1390
|
+
{
|
|
1391
|
+
name: "TestComponent",
|
|
1392
|
+
component: () => react_2.default.createElement("div", null, "Test"),
|
|
1393
|
+
description: "Test",
|
|
1394
|
+
propsSchema: v4_1.z.object({ test: v4_1.z.string() }),
|
|
1395
|
+
associatedTools: [
|
|
1396
|
+
{
|
|
1397
|
+
name: "non-streamable-tool",
|
|
1398
|
+
tool: nonStreamableToolFn,
|
|
1399
|
+
description: "Tool not safe for streaming",
|
|
1400
|
+
inputSchema: v4_1.z.object({ input: v4_1.z.string() }),
|
|
1401
|
+
outputSchema: v4_1.z.object({ data: v4_1.z.string() }),
|
|
1402
|
+
// No tamboStreamableHint - defaults to false
|
|
1403
|
+
},
|
|
1404
|
+
],
|
|
1405
|
+
},
|
|
1406
|
+
];
|
|
1407
|
+
// First chunk initializes finalMessage
|
|
1408
|
+
const mockInitialChunk = {
|
|
1409
|
+
responseMessageDto: {
|
|
1410
|
+
id: "streaming-chunk",
|
|
1411
|
+
content: [{ type: "text", text: "Starting..." }],
|
|
1412
|
+
role: "assistant",
|
|
1413
|
+
threadId: "test-thread-1",
|
|
1414
|
+
componentState: {},
|
|
1415
|
+
createdAt: new Date().toISOString(),
|
|
1416
|
+
},
|
|
1417
|
+
generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
|
|
1418
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
1419
|
+
};
|
|
1420
|
+
// Second chunk has the tool call - but tool is NOT streamable
|
|
1421
|
+
const mockToolCallChunk = {
|
|
1422
|
+
responseMessageDto: {
|
|
1423
|
+
id: "streaming-chunk",
|
|
1424
|
+
content: [{ type: "text", text: "Streaming..." }],
|
|
1425
|
+
role: "assistant",
|
|
1426
|
+
threadId: "test-thread-1",
|
|
1427
|
+
component: {
|
|
1428
|
+
componentName: "",
|
|
1429
|
+
componentState: {},
|
|
1430
|
+
message: "",
|
|
1431
|
+
props: {},
|
|
1432
|
+
toolCallRequest: {
|
|
1433
|
+
toolName: "non-streamable-tool",
|
|
1434
|
+
parameters: [{ parameterName: "input", parameterValue: "test" }],
|
|
1435
|
+
},
|
|
1436
|
+
},
|
|
1437
|
+
componentState: {},
|
|
1438
|
+
createdAt: new Date().toISOString(),
|
|
1439
|
+
},
|
|
1440
|
+
generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
|
|
1441
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
1442
|
+
};
|
|
1443
|
+
const mockFinalChunk = {
|
|
1444
|
+
responseMessageDto: {
|
|
1445
|
+
id: "streaming-chunk",
|
|
1446
|
+
content: [{ type: "text", text: "Complete" }],
|
|
1447
|
+
role: "assistant",
|
|
1448
|
+
threadId: "test-thread-1",
|
|
1449
|
+
componentState: {},
|
|
1450
|
+
createdAt: new Date().toISOString(),
|
|
1451
|
+
},
|
|
1452
|
+
generationStage: generate_component_response_1.GenerationStage.COMPLETE,
|
|
1453
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
1454
|
+
};
|
|
1455
|
+
const mockAsyncIterator = {
|
|
1456
|
+
[Symbol.asyncIterator]: async function* () {
|
|
1457
|
+
yield mockInitialChunk;
|
|
1458
|
+
yield mockToolCallChunk;
|
|
1459
|
+
yield mockFinalChunk;
|
|
1460
|
+
},
|
|
1461
|
+
};
|
|
1462
|
+
jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValueOnce(mockAsyncIterator);
|
|
1463
|
+
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
1464
|
+
wrapper: createWrapper({
|
|
1465
|
+
components: customToolRegistry,
|
|
1466
|
+
streaming: true,
|
|
1467
|
+
}),
|
|
1468
|
+
});
|
|
1469
|
+
await (0, react_1.act)(async () => {
|
|
1470
|
+
await result.current.sendThreadMessage("Test non-streamable tool", {
|
|
1471
|
+
threadId: "test-thread-1",
|
|
1472
|
+
streamResponse: true,
|
|
1473
|
+
});
|
|
1474
|
+
});
|
|
1475
|
+
// Non-streamable tool should NOT be called during the streaming chunk phase
|
|
1476
|
+
// (it would only be called when generationStage is COMPLETE with a toolCallRequest)
|
|
1477
|
+
expect(nonStreamableToolFn).not.toHaveBeenCalled();
|
|
1478
|
+
});
|
|
1479
|
+
it("should only call streamable tools during streaming when mixed", async () => {
|
|
1480
|
+
const streamableToolFn = jest
|
|
1481
|
+
.fn()
|
|
1482
|
+
.mockResolvedValue({ data: "streamed" });
|
|
1483
|
+
const nonStreamableToolFn = jest
|
|
1484
|
+
.fn()
|
|
1485
|
+
.mockResolvedValue({ data: "not-streamed" });
|
|
1486
|
+
const customToolRegistry = [
|
|
1487
|
+
{
|
|
1488
|
+
name: "TestComponent",
|
|
1489
|
+
component: () => react_2.default.createElement("div", null, "Test"),
|
|
1490
|
+
description: "Test",
|
|
1491
|
+
propsSchema: v4_1.z.object({ test: v4_1.z.string() }),
|
|
1492
|
+
associatedTools: [
|
|
1493
|
+
{
|
|
1494
|
+
name: "streamable-tool",
|
|
1495
|
+
tool: streamableToolFn,
|
|
1496
|
+
description: "Tool safe for streaming",
|
|
1497
|
+
inputSchema: v4_1.z.object({ input: v4_1.z.string() }),
|
|
1498
|
+
outputSchema: v4_1.z.object({ data: v4_1.z.string() }),
|
|
1499
|
+
annotations: { tamboStreamableHint: true },
|
|
1500
|
+
},
|
|
1501
|
+
{
|
|
1502
|
+
name: "non-streamable-tool",
|
|
1503
|
+
tool: nonStreamableToolFn,
|
|
1504
|
+
description: "Tool not safe for streaming",
|
|
1505
|
+
inputSchema: v4_1.z.object({ input: v4_1.z.string() }),
|
|
1506
|
+
outputSchema: v4_1.z.object({ data: v4_1.z.string() }),
|
|
1507
|
+
annotations: { tamboStreamableHint: false },
|
|
1508
|
+
},
|
|
1509
|
+
],
|
|
1510
|
+
},
|
|
1511
|
+
];
|
|
1512
|
+
// First chunk initializes finalMessage
|
|
1513
|
+
const mockInitialChunk = {
|
|
1514
|
+
responseMessageDto: {
|
|
1515
|
+
id: "streaming-chunk",
|
|
1516
|
+
content: [{ type: "text", text: "Starting..." }],
|
|
1517
|
+
role: "assistant",
|
|
1518
|
+
threadId: "test-thread-1",
|
|
1519
|
+
componentState: {},
|
|
1520
|
+
createdAt: new Date().toISOString(),
|
|
1521
|
+
},
|
|
1522
|
+
generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
|
|
1523
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
1524
|
+
};
|
|
1525
|
+
// Second chunk calls the streamable tool
|
|
1526
|
+
const mockStreamableToolChunk = {
|
|
1527
|
+
responseMessageDto: {
|
|
1528
|
+
id: "streaming-chunk",
|
|
1529
|
+
content: [{ type: "text", text: "Calling streamable..." }],
|
|
1530
|
+
role: "assistant",
|
|
1531
|
+
threadId: "test-thread-1",
|
|
1532
|
+
component: {
|
|
1533
|
+
componentName: "",
|
|
1534
|
+
componentState: {},
|
|
1535
|
+
message: "",
|
|
1536
|
+
props: {},
|
|
1537
|
+
toolCallRequest: {
|
|
1538
|
+
toolName: "streamable-tool",
|
|
1539
|
+
parameters: [
|
|
1540
|
+
{ parameterName: "input", parameterValue: "streamed-input" },
|
|
1541
|
+
],
|
|
1542
|
+
},
|
|
1543
|
+
},
|
|
1544
|
+
componentState: {},
|
|
1545
|
+
createdAt: new Date().toISOString(),
|
|
1546
|
+
},
|
|
1547
|
+
generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
|
|
1548
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
1549
|
+
};
|
|
1550
|
+
// Third chunk calls the non-streamable tool
|
|
1551
|
+
const mockNonStreamableToolChunk = {
|
|
1552
|
+
responseMessageDto: {
|
|
1553
|
+
id: "streaming-chunk",
|
|
1554
|
+
content: [{ type: "text", text: "Calling non-streamable..." }],
|
|
1555
|
+
role: "assistant",
|
|
1556
|
+
threadId: "test-thread-1",
|
|
1557
|
+
component: {
|
|
1558
|
+
componentName: "",
|
|
1559
|
+
componentState: {},
|
|
1560
|
+
message: "",
|
|
1561
|
+
props: {},
|
|
1562
|
+
toolCallRequest: {
|
|
1563
|
+
toolName: "non-streamable-tool",
|
|
1564
|
+
parameters: [
|
|
1565
|
+
{
|
|
1566
|
+
parameterName: "input",
|
|
1567
|
+
parameterValue: "non-streamed-input",
|
|
1568
|
+
},
|
|
1569
|
+
],
|
|
1570
|
+
},
|
|
1571
|
+
},
|
|
1572
|
+
componentState: {},
|
|
1573
|
+
createdAt: new Date().toISOString(),
|
|
1574
|
+
},
|
|
1575
|
+
generationStage: generate_component_response_1.GenerationStage.STREAMING_RESPONSE,
|
|
1576
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
1577
|
+
};
|
|
1578
|
+
const mockFinalChunk = {
|
|
1579
|
+
responseMessageDto: {
|
|
1580
|
+
id: "streaming-chunk",
|
|
1581
|
+
content: [{ type: "text", text: "Complete" }],
|
|
1582
|
+
role: "assistant",
|
|
1583
|
+
threadId: "test-thread-1",
|
|
1584
|
+
componentState: {},
|
|
1585
|
+
createdAt: new Date().toISOString(),
|
|
1586
|
+
},
|
|
1587
|
+
generationStage: generate_component_response_1.GenerationStage.COMPLETE,
|
|
1588
|
+
mcpAccessToken: "test-mcp-access-token",
|
|
1589
|
+
};
|
|
1590
|
+
const mockAsyncIterator = {
|
|
1591
|
+
[Symbol.asyncIterator]: async function* () {
|
|
1592
|
+
yield mockInitialChunk;
|
|
1593
|
+
yield mockStreamableToolChunk;
|
|
1594
|
+
yield mockNonStreamableToolChunk;
|
|
1595
|
+
yield mockFinalChunk;
|
|
1596
|
+
},
|
|
1597
|
+
};
|
|
1598
|
+
jest.mocked(typescript_sdk_1.advanceStream).mockResolvedValueOnce(mockAsyncIterator);
|
|
1599
|
+
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
1600
|
+
wrapper: createWrapper({
|
|
1601
|
+
components: customToolRegistry,
|
|
1602
|
+
streaming: true,
|
|
1603
|
+
}),
|
|
1604
|
+
});
|
|
1605
|
+
await (0, react_1.act)(async () => {
|
|
1606
|
+
await result.current.sendThreadMessage("Test mixed tools", {
|
|
1607
|
+
threadId: "test-thread-1",
|
|
1608
|
+
streamResponse: true,
|
|
1609
|
+
});
|
|
1610
|
+
});
|
|
1611
|
+
// Only the streamable tool should be called during streaming
|
|
1612
|
+
expect(streamableToolFn).toHaveBeenCalledWith({
|
|
1613
|
+
input: "streamed-input",
|
|
1614
|
+
});
|
|
1615
|
+
expect(nonStreamableToolFn).not.toHaveBeenCalled();
|
|
1616
|
+
});
|
|
1617
|
+
});
|
|
1363
1618
|
describe("auto-generate thread name", () => {
|
|
1364
1619
|
it("should auto-generate thread name after reaching threshold", async () => {
|
|
1365
|
-
const WrapperWithAutoGenerate = ({ children, }) => {
|
|
1366
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
1367
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
1368
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
1369
|
-
client,
|
|
1370
|
-
queryClient,
|
|
1371
|
-
isUpdatingToken: false,
|
|
1372
|
-
} },
|
|
1373
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: mockRegistry },
|
|
1374
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
1375
|
-
currentTimeContextHelper: () => null,
|
|
1376
|
-
currentPageContextHelper: () => null,
|
|
1377
|
-
} },
|
|
1378
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
1379
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: false, autoGenerateNameThreshold: 2 }, children))))));
|
|
1380
|
-
};
|
|
1381
1620
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
1382
|
-
wrapper:
|
|
1621
|
+
wrapper: createWrapper({ autoGenerateNameThreshold: 2 }),
|
|
1383
1622
|
});
|
|
1384
1623
|
const existingThread = createMockThread({
|
|
1385
1624
|
id: "test-thread-1",
|
|
@@ -1416,24 +1655,11 @@ describe("TamboThreadProvider", () => {
|
|
|
1416
1655
|
expect(mockQueryClient.setQueryData).toHaveBeenCalledWith(["threads", "test-project-id", undefined], expect.any(Function));
|
|
1417
1656
|
});
|
|
1418
1657
|
it("should NOT auto-generate when autoGenerateThreadName is false", async () => {
|
|
1419
|
-
const WrapperWithDisabled = ({ children, }) => {
|
|
1420
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
1421
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
1422
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
1423
|
-
client,
|
|
1424
|
-
queryClient,
|
|
1425
|
-
isUpdatingToken: false,
|
|
1426
|
-
} },
|
|
1427
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: mockRegistry },
|
|
1428
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
1429
|
-
currentTimeContextHelper: () => null,
|
|
1430
|
-
currentPageContextHelper: () => null,
|
|
1431
|
-
} },
|
|
1432
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
1433
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: false, autoGenerateThreadName: false, autoGenerateNameThreshold: 2 }, children))))));
|
|
1434
|
-
};
|
|
1435
1658
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
1436
|
-
wrapper:
|
|
1659
|
+
wrapper: createWrapper({
|
|
1660
|
+
autoGenerateThreadName: false,
|
|
1661
|
+
autoGenerateNameThreshold: 2,
|
|
1662
|
+
}),
|
|
1437
1663
|
});
|
|
1438
1664
|
const existingThread = createMockThread({
|
|
1439
1665
|
id: "test-thread-1",
|
|
@@ -1466,24 +1692,8 @@ describe("TamboThreadProvider", () => {
|
|
|
1466
1692
|
expect(mockThreadsApi.generateName).not.toHaveBeenCalled();
|
|
1467
1693
|
});
|
|
1468
1694
|
it("should NOT auto-generate when thread already has a name", async () => {
|
|
1469
|
-
const WrapperWithAutoGenerate = ({ children, }) => {
|
|
1470
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
1471
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
1472
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
1473
|
-
client,
|
|
1474
|
-
queryClient,
|
|
1475
|
-
isUpdatingToken: false,
|
|
1476
|
-
} },
|
|
1477
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: mockRegistry },
|
|
1478
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
1479
|
-
currentTimeContextHelper: () => null,
|
|
1480
|
-
currentPageContextHelper: () => null,
|
|
1481
|
-
} },
|
|
1482
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
1483
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: false, autoGenerateNameThreshold: 2 }, children))))));
|
|
1484
|
-
};
|
|
1485
1695
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
1486
|
-
wrapper:
|
|
1696
|
+
wrapper: createWrapper({ autoGenerateNameThreshold: 2 }),
|
|
1487
1697
|
});
|
|
1488
1698
|
const threadWithName = createMockThread({
|
|
1489
1699
|
id: "test-thread-1",
|
|
@@ -1521,24 +1731,8 @@ describe("TamboThreadProvider", () => {
|
|
|
1521
1731
|
expect(mockThreadsApi.generateName).not.toHaveBeenCalled();
|
|
1522
1732
|
});
|
|
1523
1733
|
it("should NOT auto-generate for placeholder thread", async () => {
|
|
1524
|
-
const WrapperWithAutoGenerate = ({ children, }) => {
|
|
1525
|
-
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
1526
|
-
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
1527
|
-
return (react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
1528
|
-
client,
|
|
1529
|
-
queryClient,
|
|
1530
|
-
isUpdatingToken: false,
|
|
1531
|
-
} },
|
|
1532
|
-
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: mockRegistry },
|
|
1533
|
-
react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, { contextHelpers: {
|
|
1534
|
-
currentTimeContextHelper: () => null,
|
|
1535
|
-
currentPageContextHelper: () => null,
|
|
1536
|
-
} },
|
|
1537
|
-
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
1538
|
-
react_2.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: false, autoGenerateNameThreshold: 2 }, children))))));
|
|
1539
|
-
};
|
|
1540
1734
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_thread_provider_1.useTamboThread)(), {
|
|
1541
|
-
wrapper:
|
|
1735
|
+
wrapper: createWrapper({ autoGenerateNameThreshold: 2 }),
|
|
1542
1736
|
});
|
|
1543
1737
|
// Stay on placeholder thread
|
|
1544
1738
|
expect(result.current.thread.id).toBe("placeholder");
|