@tambo-ai/react 0.73.0 → 0.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -12
- package/dist/hooks/use-component-state.d.ts +1 -1
- package/dist/hooks/use-component-state.js.map +1 -1
- package/dist/hooks/use-streaming-props.d.ts +1 -1
- package/dist/hooks/use-streaming-props.js +1 -1
- package/dist/hooks/use-streaming-props.js.map +1 -1
- package/dist/hooks/use-tambo-stream-status.d.ts +1 -1
- package/dist/hooks/use-tambo-stream-status.js +1 -1
- package/dist/hooks/use-tambo-stream-status.js.map +1 -1
- package/dist/mcp/mcp-hooks.d.ts +4 -0
- package/dist/mcp/mcp-hooks.d.ts.map +1 -1
- package/dist/mcp/mcp-hooks.js +4 -0
- package/dist/mcp/mcp-hooks.js.map +1 -1
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js +3 -3
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.js +2 -2
- package/dist/providers/tambo-interactable-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.test.js +3 -3
- package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
- package/dist/providers/tambo-provider.d.ts +3 -0
- package/dist/providers/tambo-provider.d.ts.map +1 -1
- package/dist/providers/tambo-provider.js +3 -0
- package/dist/providers/tambo-provider.js.map +1 -1
- package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-input-provider.js +1 -0
- package/dist/providers/tambo-thread-input-provider.js.map +1 -1
- package/dist/util/resource-content-resolver.d.ts.map +1 -1
- package/dist/util/resource-content-resolver.js +2 -0
- package/dist/util/resource-content-resolver.js.map +1 -1
- package/dist/v1/__tests__/v1-interactables.test.d.ts +2 -0
- package/dist/v1/__tests__/v1-interactables.test.d.ts.map +1 -0
- package/dist/v1/__tests__/v1-interactables.test.js +135 -0
- package/dist/v1/__tests__/v1-interactables.test.js.map +1 -0
- package/dist/v1/components/v1-component-renderer.d.ts +48 -0
- package/dist/v1/components/v1-component-renderer.d.ts.map +1 -0
- package/dist/v1/components/v1-component-renderer.js +137 -0
- package/dist/v1/components/v1-component-renderer.js.map +1 -0
- package/dist/v1/components/v1-component-renderer.test.d.ts +2 -0
- package/dist/v1/components/v1-component-renderer.test.d.ts.map +1 -0
- package/dist/v1/components/v1-component-renderer.test.js +270 -0
- package/dist/v1/components/v1-component-renderer.test.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.js +2 -25
- package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js +2 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-messages.test.js +25 -1
- package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +18 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.js +204 -17
- package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js +261 -7
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts +90 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.js +179 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.d.ts +2 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js +371 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts +78 -54
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.js +153 -87
- package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js +213 -134
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +148 -13
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts +8 -21
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.js +11 -10
- package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +37 -2
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.d.ts +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.js +2 -7
- package/dist/v1/hooks/use-tambo-v1-thread.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.test.js +2 -0
- package/dist/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.d.ts +12 -28
- package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.js +164 -31
- package/dist/v1/hooks/use-tambo-v1.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.test.js +891 -18
- package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/dist/v1/index.d.ts +7 -1
- package/dist/v1/index.d.ts.map +1 -1
- package/dist/v1/index.js +18 -1
- package/dist/v1/index.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts +16 -6
- package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.js +14 -19
- package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.test.js +34 -20
- package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.d.ts +3 -3
- package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.js +60 -12
- package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.test.js +49 -20
- package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.js +2 -0
- package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.test.js +7 -6
- package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +1 -6
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.js +14 -12
- package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/dist/v1/types/event.d.ts +9 -1
- package/dist/v1/types/event.d.ts.map +1 -1
- package/dist/v1/types/event.js.map +1 -1
- package/dist/v1/types/event.test.js +5 -1
- package/dist/v1/types/event.test.js.map +1 -1
- package/dist/v1/types/message.d.ts +65 -7
- package/dist/v1/types/message.d.ts.map +1 -1
- package/dist/v1/types/message.js.map +1 -1
- package/dist/v1/types/thread.d.ts +4 -0
- package/dist/v1/types/thread.d.ts.map +1 -1
- package/dist/v1/types/thread.js.map +1 -1
- package/dist/v1/utils/event-accumulator.d.ts +40 -4
- package/dist/v1/utils/event-accumulator.d.ts.map +1 -1
- package/dist/v1/utils/event-accumulator.js +444 -35
- package/dist/v1/utils/event-accumulator.js.map +1 -1
- package/dist/v1/utils/event-accumulator.test.js +1041 -28
- package/dist/v1/utils/event-accumulator.test.js.map +1 -1
- package/dist/v1/utils/registry-conversion.d.ts +9 -9
- package/dist/v1/utils/registry-conversion.d.ts.map +1 -1
- package/dist/v1/utils/registry-conversion.js +10 -11
- package/dist/v1/utils/registry-conversion.js.map +1 -1
- package/dist/v1/utils/registry-conversion.test.js +39 -11
- package/dist/v1/utils/registry-conversion.test.js.map +1 -1
- package/dist/v1/utils/thread-utils.d.ts +16 -0
- package/dist/v1/utils/thread-utils.d.ts.map +1 -0
- package/dist/v1/utils/thread-utils.js +34 -0
- package/dist/v1/utils/thread-utils.js.map +1 -0
- package/dist/v1/utils/tool-executor.d.ts.map +1 -1
- package/dist/v1/utils/tool-executor.js +2 -0
- package/dist/v1/utils/tool-executor.js.map +1 -1
- package/dist/v1/utils/tool-executor.test.js +5 -0
- package/dist/v1/utils/tool-executor.test.js.map +1 -1
- package/esm/context-helpers/context-helpers-provider.test.js +2 -2
- package/esm/context-helpers/context-helpers.test.js +1 -1
- package/esm/context-helpers/current-interactables-context-helper.d.ts +1 -1
- package/esm/context-helpers/current-page-context-helper.d.ts +1 -1
- package/esm/context-helpers/current-time-context-helper.d.ts +1 -1
- package/esm/context-helpers/index.d.ts +4 -4
- package/esm/context-helpers/index.js +4 -4
- package/esm/hoc/with-tambo-interactable.d.ts +1 -1
- package/esm/hoc/with-tambo-interactable.js +2 -2
- package/esm/hoc/with-tambo-interactable.test.js +3 -3
- package/esm/hooks/index.d.ts +8 -8
- package/esm/hooks/index.js +8 -8
- package/esm/hooks/react-query-hooks.js +1 -1
- package/esm/hooks/use-component-state.d.ts +1 -1
- package/esm/hooks/use-component-state.js +3 -3
- package/esm/hooks/use-component-state.js.map +1 -1
- package/esm/hooks/use-component-state.test.js +5 -5
- package/esm/hooks/use-current-message.d.ts +1 -1
- package/esm/hooks/use-current-message.test.js +1 -1
- package/esm/hooks/use-message-images.test.js +1 -1
- package/esm/hooks/use-streaming-props.d.ts +1 -1
- package/esm/hooks/use-streaming-props.js +1 -1
- package/esm/hooks/use-streaming-props.js.map +1 -1
- package/esm/hooks/use-suggestions.d.ts +2 -2
- package/esm/hooks/use-suggestions.js +10 -10
- package/esm/hooks/use-suggestions.test.js +7 -7
- package/esm/hooks/use-tambo-stream-status.d.ts +1 -1
- package/esm/hooks/use-tambo-stream-status.js +4 -4
- package/esm/hooks/use-tambo-stream-status.js.map +1 -1
- package/esm/hooks/use-tambo-stream-status.test.js +4 -4
- package/esm/hooks/use-tambo-threads.js +3 -3
- package/esm/hooks/use-tambo-threads.test.js +3 -3
- package/esm/hooks/use-tambo-voice.js +2 -2
- package/esm/hooks/use-tambo-voice.test.js +3 -3
- package/esm/index.d.ts +22 -22
- package/esm/index.js +15 -15
- package/esm/mcp/elicitation.d.ts +1 -1
- package/esm/mcp/elicitation.test.js +1 -1
- package/esm/mcp/index.d.ts +7 -7
- package/esm/mcp/index.js +3 -3
- package/esm/mcp/mcp-client.d.ts +1 -1
- package/esm/mcp/mcp-client.js +1 -1
- package/esm/mcp/mcp-client.test.js +1 -1
- package/esm/mcp/mcp-hooks.d.ts +5 -1
- package/esm/mcp/mcp-hooks.d.ts.map +1 -1
- package/esm/mcp/mcp-hooks.js +8 -4
- package/esm/mcp/mcp-hooks.js.map +1 -1
- package/esm/mcp/mcp-hooks.test.js +6 -6
- package/esm/mcp/tambo-mcp-provider.d.ts +4 -4
- package/esm/mcp/tambo-mcp-provider.js +7 -7
- package/esm/mcp/tambo-mcp-provider.test.js +5 -5
- package/esm/mcp/use-mcp-servers.test.js +4 -4
- package/esm/model/generate-component-response.d.ts +1 -1
- package/esm/model/tambo-interactable.d.ts +1 -1
- package/esm/model/tambo-thread.d.ts +1 -1
- package/esm/providers/__tests__/thread-input-resource-resolution.test.js +3 -3
- package/esm/providers/hooks/use-tambo-session-token.test.js +1 -1
- package/esm/providers/index.d.ts +12 -12
- package/esm/providers/index.js +10 -10
- package/esm/providers/tambo-client-provider.js +1 -1
- package/esm/providers/tambo-client-provider.test.js +2 -2
- package/esm/providers/tambo-component-provider.d.ts +1 -1
- package/esm/providers/tambo-component-provider.js +2 -2
- package/esm/providers/tambo-context-attachment-provider.js +1 -1
- package/esm/providers/tambo-context-attachment-provider.test.js +2 -2
- package/esm/providers/tambo-context-helpers-provider.d.ts +1 -1
- package/esm/providers/tambo-context-helpers-provider.js +1 -1
- package/esm/providers/tambo-context-helpers-provider.test.js +2 -2
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js +4 -4
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +5 -5
- package/esm/providers/tambo-interactable-provider.js +6 -6
- package/esm/providers/tambo-interactable-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.test.js +4 -4
- package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
- package/esm/providers/tambo-interactables-additional-context-edge-cases.test.js +4 -4
- package/esm/providers/tambo-interactables-additional-context.test.js +4 -4
- package/esm/providers/tambo-mcp-token-provider.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/index.d.ts +8 -8
- package/esm/providers/tambo-prop-stream-provider/index.js +9 -9
- package/esm/providers/tambo-prop-stream-provider/pending.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/pending.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/provider.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/provider.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/streaming.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/streaming.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/success.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/success.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/types.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider.test.js +4 -4
- package/esm/providers/tambo-provider.d.ts +10 -7
- package/esm/providers/tambo-provider.d.ts.map +1 -1
- package/esm/providers/tambo-provider.js +13 -10
- package/esm/providers/tambo-provider.js.map +1 -1
- package/esm/providers/tambo-registry-provider.d.ts +3 -3
- package/esm/providers/tambo-registry-provider.js +3 -3
- package/esm/providers/tambo-registry-provider.test.js +2 -2
- package/esm/providers/tambo-registry-schema-compat.test.js +2 -2
- package/esm/providers/tambo-stubs.d.ts +4 -4
- package/esm/providers/tambo-stubs.js +9 -9
- package/esm/providers/tambo-stubs.test.js +2 -2
- package/esm/providers/tambo-thread-input-provider.d.ts +2 -2
- package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-input-provider.js +11 -10
- package/esm/providers/tambo-thread-input-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider-initial-messages.test.js +6 -6
- package/esm/providers/tambo-thread-provider.d.ts +2 -2
- package/esm/providers/tambo-thread-provider.js +8 -8
- package/esm/providers/tambo-thread-provider.test.js +7 -7
- package/esm/schema/index.d.ts +4 -4
- package/esm/schema/index.js +4 -4
- package/esm/schema/json-schema.test.js +1 -1
- package/esm/schema/schema.d.ts +1 -1
- package/esm/schema/schema.js +2 -2
- package/esm/schema/schema.test.js +3 -3
- package/esm/schema/standard-schema.test.js +1 -1
- package/esm/schema/validate.js +2 -2
- package/esm/schema/validate.test.js +1 -1
- package/esm/testing/tools.d.ts +3 -3
- package/esm/testing/tools.js +2 -2
- package/esm/util/content-parts.test.js +1 -1
- package/esm/util/generate-component.d.ts +2 -2
- package/esm/util/generate-component.js +4 -4
- package/esm/util/generate-component.test.js +2 -2
- package/esm/util/is-promise.test.js +1 -1
- package/esm/util/mcp-server-utils.d.ts +1 -1
- package/esm/util/mcp-server-utils.js +1 -1
- package/esm/util/mcp-server-utils.test.js +2 -2
- package/esm/util/message-builder.d.ts +1 -1
- package/esm/util/message-builder.test.js +1 -1
- package/esm/util/query-utils.test.js +1 -1
- package/esm/util/registry-validators.d.ts +1 -1
- package/esm/util/registry-validators.js +2 -2
- package/esm/util/registry-validators.test.js +1 -1
- package/esm/util/registry.d.ts +1 -1
- package/esm/util/registry.js +1 -1
- package/esm/util/registry.test.js +2 -2
- package/esm/util/resource-content-resolver.d.ts +2 -2
- package/esm/util/resource-content-resolver.d.ts.map +1 -1
- package/esm/util/resource-content-resolver.js +3 -1
- package/esm/util/resource-content-resolver.js.map +1 -1
- package/esm/util/resource-content-resolver.test.js +3 -3
- package/esm/util/resource-validators.d.ts +1 -1
- package/esm/util/resource-validators.test.js +1 -1
- package/esm/util/tool-caller.d.ts +1 -1
- package/esm/util/tool-caller.js +1 -1
- package/esm/util/validate-component-name.test.js +1 -1
- package/esm/v1/__tests__/v1-interactables.test.d.ts +2 -0
- package/esm/v1/__tests__/v1-interactables.test.d.ts.map +1 -0
- package/esm/v1/__tests__/v1-interactables.test.js +130 -0
- package/esm/v1/__tests__/v1-interactables.test.js.map +1 -0
- package/esm/v1/components/v1-component-renderer.d.ts +48 -0
- package/esm/v1/components/v1-component-renderer.d.ts.map +1 -0
- package/esm/v1/components/v1-component-renderer.js +100 -0
- package/esm/v1/components/v1-component-renderer.js.map +1 -0
- package/esm/v1/components/v1-component-renderer.test.d.ts +2 -0
- package/esm/v1/components/v1-component-renderer.test.d.ts.map +1 -0
- package/esm/v1/components/v1-component-renderer.test.js +265 -0
- package/esm/v1/components/v1-component-renderer.test.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.js +4 -27
- package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js +6 -5
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.test.js +27 -3
- package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +20 -2
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.js +213 -26
- package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js +266 -12
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts +90 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.js +176 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.d.ts +2 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js +369 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts +78 -54
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.js +157 -91
- package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js +218 -139
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +151 -16
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts +8 -21
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.js +12 -11
- package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +39 -4
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.js +3 -8
- package/esm/v1/hooks/use-tambo-v1-thread.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.test.js +4 -2
- package/esm/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.d.ts +15 -31
- package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.js +134 -34
- package/esm/v1/hooks/use-tambo-v1.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.test.js +862 -19
- package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/esm/v1/index.d.ts +28 -22
- package/esm/v1/index.d.ts.map +1 -1
- package/esm/v1/index.js +30 -18
- package/esm/v1/index.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts +21 -11
- package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.js +20 -25
- package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.test.js +40 -26
- package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.d.ts +4 -4
- package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.js +62 -14
- package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.test.js +50 -21
- package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts +3 -3
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.js +7 -5
- package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.test.js +12 -11
- package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +3 -8
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.js +18 -16
- package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/esm/v1/types/event.d.ts +9 -1
- package/esm/v1/types/event.d.ts.map +1 -1
- package/esm/v1/types/event.js.map +1 -1
- package/esm/v1/types/event.test.js +6 -2
- package/esm/v1/types/event.test.js.map +1 -1
- package/esm/v1/types/message.d.ts +65 -7
- package/esm/v1/types/message.d.ts.map +1 -1
- package/esm/v1/types/message.js.map +1 -1
- package/esm/v1/types/thread.d.ts +5 -1
- package/esm/v1/types/thread.d.ts.map +1 -1
- package/esm/v1/types/thread.js.map +1 -1
- package/esm/v1/utils/component-renderer.test.js +1 -1
- package/esm/v1/utils/event-accumulator.d.ts +41 -5
- package/esm/v1/utils/event-accumulator.d.ts.map +1 -1
- package/esm/v1/utils/event-accumulator.js +444 -36
- package/esm/v1/utils/event-accumulator.js.map +1 -1
- package/esm/v1/utils/event-accumulator.test.js +1042 -29
- package/esm/v1/utils/event-accumulator.test.js.map +1 -1
- package/esm/v1/utils/json-patch.test.js +1 -1
- package/esm/v1/utils/registry-conversion.d.ts +9 -9
- package/esm/v1/utils/registry-conversion.d.ts.map +1 -1
- package/esm/v1/utils/registry-conversion.js +11 -12
- package/esm/v1/utils/registry-conversion.js.map +1 -1
- package/esm/v1/utils/registry-conversion.test.js +40 -12
- package/esm/v1/utils/registry-conversion.test.js.map +1 -1
- package/esm/v1/utils/stream-handler.test.js +1 -1
- package/esm/v1/utils/thread-utils.d.ts +16 -0
- package/esm/v1/utils/thread-utils.d.ts.map +1 -0
- package/esm/v1/utils/thread-utils.js +31 -0
- package/esm/v1/utils/thread-utils.js.map +1 -0
- package/esm/v1/utils/tool-call-tracker.d.ts +1 -1
- package/esm/v1/utils/tool-executor.d.ts +1 -1
- package/esm/v1/utils/tool-executor.d.ts.map +1 -1
- package/esm/v1/utils/tool-executor.js +2 -0
- package/esm/v1/utils/tool-executor.js.map +1 -1
- package/esm/v1/utils/tool-executor.test.js +6 -1
- package/esm/v1/utils/tool-executor.test.js.map +1 -1
- package/package.json +11 -10
|
@@ -13,12 +13,16 @@ const tambo_registry_provider_1 = require("../../providers/tambo-registry-provid
|
|
|
13
13
|
const tambo_context_helpers_provider_1 = require("../../providers/tambo-context-helpers-provider");
|
|
14
14
|
const tambo_v1_stream_context_1 = require("./tambo-v1-stream-context");
|
|
15
15
|
const tambo_v1_provider_1 = require("./tambo-v1-provider");
|
|
16
|
+
// Module-level QueryClient for tests - created lazily
|
|
17
|
+
let testQueryClient = null;
|
|
16
18
|
// Mock the client provider to capture the apiKey
|
|
17
|
-
jest.mock("../../providers/tambo-client-provider", () =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}))
|
|
19
|
+
jest.mock("../../providers/tambo-client-provider", () => {
|
|
20
|
+
return {
|
|
21
|
+
useTamboClient: jest.fn(),
|
|
22
|
+
useTamboQueryClient: jest.fn(),
|
|
23
|
+
TamboClientProvider: jest.fn(({ children }) => children),
|
|
24
|
+
};
|
|
25
|
+
});
|
|
22
26
|
// Mock useTamboV1SendMessage to avoid complex dependencies
|
|
23
27
|
jest.mock("../hooks/use-tambo-v1-send-message", () => ({
|
|
24
28
|
useTamboV1SendMessage: jest.fn(() => ({
|
|
@@ -40,7 +44,20 @@ describe("TamboV1Provider", () => {
|
|
|
40
44
|
fetch: mockFetch,
|
|
41
45
|
});
|
|
42
46
|
beforeEach(() => {
|
|
47
|
+
// Create a fresh QueryClient for each test
|
|
48
|
+
testQueryClient = new react_query_1.QueryClient({
|
|
49
|
+
defaultOptions: {
|
|
50
|
+
queries: { retry: false },
|
|
51
|
+
mutations: { retry: false },
|
|
52
|
+
},
|
|
53
|
+
});
|
|
43
54
|
jest.mocked(tambo_client_provider_1.useTamboClient).mockReturnValue(mockClient);
|
|
55
|
+
jest.mocked(tambo_client_provider_1.useTamboQueryClient).mockReturnValue(testQueryClient);
|
|
56
|
+
// Mock TamboClientProvider to wrap children with QueryClientProvider
|
|
57
|
+
const { TamboClientProvider } = jest.requireMock("../../providers/tambo-client-provider");
|
|
58
|
+
jest
|
|
59
|
+
.mocked(TamboClientProvider)
|
|
60
|
+
.mockImplementation(({ children }) => (react_2.default.createElement(react_query_1.QueryClientProvider, { client: testQueryClient }, children)));
|
|
44
61
|
});
|
|
45
62
|
it("provides access to registry context", () => {
|
|
46
63
|
const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_provider_1.TamboV1Provider, { apiKey: "test-api-key" }, children));
|
|
@@ -50,11 +67,13 @@ describe("TamboV1Provider", () => {
|
|
|
50
67
|
expect(typeof result.current.registerComponent).toBe("function");
|
|
51
68
|
expect(typeof result.current.registerTool).toBe("function");
|
|
52
69
|
});
|
|
53
|
-
it("provides access to stream context", () => {
|
|
70
|
+
it("provides access to stream context with placeholder thread ready", () => {
|
|
54
71
|
const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_provider_1.TamboV1Provider, { apiKey: "test-api-key" }, children));
|
|
55
72
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_stream_context_1.useStreamState)(), { wrapper });
|
|
56
73
|
expect(result.current.threadMap).toBeDefined();
|
|
57
|
-
|
|
74
|
+
// Initial state has placeholder thread for optimistic UI
|
|
75
|
+
expect(result.current.currentThreadId).toBe("placeholder");
|
|
76
|
+
expect(result.current.threadMap.placeholder).toBeDefined();
|
|
58
77
|
});
|
|
59
78
|
it("manages threads via useThreadManagement", () => {
|
|
60
79
|
const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_provider_1.TamboV1Provider, { apiKey: "test-api-key" }, children));
|
|
@@ -62,9 +81,9 @@ describe("TamboV1Provider", () => {
|
|
|
62
81
|
state: (0, tambo_v1_stream_context_1.useStreamState)(),
|
|
63
82
|
management: (0, tambo_v1_stream_context_1.useThreadManagement)(),
|
|
64
83
|
}), { wrapper });
|
|
65
|
-
// Initially
|
|
66
|
-
expect(result.current.state.currentThreadId).
|
|
67
|
-
// Initialize and switch to a thread
|
|
84
|
+
// Initially has placeholder thread for optimistic UI
|
|
85
|
+
expect(result.current.state.currentThreadId).toBe("placeholder");
|
|
86
|
+
// Initialize and switch to a different thread
|
|
68
87
|
(0, react_1.act)(() => {
|
|
69
88
|
result.current.management.initThread("thread_123");
|
|
70
89
|
result.current.management.switchThread("thread_123");
|
|
@@ -72,17 +91,11 @@ describe("TamboV1Provider", () => {
|
|
|
72
91
|
expect(result.current.state.currentThreadId).toBe("thread_123");
|
|
73
92
|
expect(result.current.state.threadMap.thread_123).toBeDefined();
|
|
74
93
|
});
|
|
75
|
-
it("provides access to query client", () => {
|
|
94
|
+
it("provides access to query client via useTamboQueryClient", () => {
|
|
76
95
|
const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_provider_1.TamboV1Provider, { apiKey: "test-api-key" }, children));
|
|
77
|
-
const { result } = (0, react_1.renderHook)(() => (0,
|
|
96
|
+
const { result } = (0, react_1.renderHook)(() => (0, tambo_client_provider_1.useTamboQueryClient)(), { wrapper });
|
|
78
97
|
expect(result.current).toBeInstanceOf(react_query_1.QueryClient);
|
|
79
98
|
});
|
|
80
|
-
it("uses custom query client when provided", () => {
|
|
81
|
-
const customClient = new react_query_1.QueryClient();
|
|
82
|
-
const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_provider_1.TamboV1Provider, { apiKey: "test-api-key", queryClient: customClient }, children));
|
|
83
|
-
const { result } = (0, react_1.renderHook)(() => (0, react_query_1.useQueryClient)(), { wrapper });
|
|
84
|
-
expect(result.current).toBe(customClient);
|
|
85
|
-
});
|
|
86
99
|
it("registers components when provided", () => {
|
|
87
100
|
const TestComponent = () => react_2.default.createElement("div", null, "Test");
|
|
88
101
|
const propsSchema = zod_1.z.object({
|
|
@@ -188,11 +201,12 @@ describe("TamboV1Provider", () => {
|
|
|
188
201
|
expect(helpers.getUserName).toBe(contextHelpers.getUserName);
|
|
189
202
|
expect(helpers.getCurrentTime).toBe(contextHelpers.getCurrentTime);
|
|
190
203
|
});
|
|
191
|
-
it("returns
|
|
204
|
+
it("returns only interactables contextHelper when none explicitly provided", async () => {
|
|
192
205
|
const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_provider_1.TamboV1Provider, { apiKey: "test-api-key" }, children));
|
|
193
206
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_helpers_provider_1.useTamboContextHelpers)(), { wrapper });
|
|
194
207
|
const helpers = result.current.getContextHelpers();
|
|
195
|
-
|
|
208
|
+
// TamboInteractableProvider registers an "interactables" context helper
|
|
209
|
+
expect(Object.keys(helpers)).toEqual(["interactables"]);
|
|
196
210
|
});
|
|
197
211
|
});
|
|
198
212
|
//# sourceMappingURL=tambo-v1-provider.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-v1-provider.test.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.test.tsx"],"names":[],"mappings":";;;;;AAAA,8EAA+C;AAC/C,uDAAoE;AACpE,kDAAyD;AACzD,kDAA0B;AAC1B,6BAAwB;AACxB,iFAAuE;AACvE,qFAA2E;AAC3E,mGAAwF;AACxF,uEAAgF;AAChF,2DAAwE;AAExE,iDAAiD;AACjD,IAAI,CAAC,IAAI,CAAC,uCAAuC,EAAE,GAAG,EAAE,CAAC,CAAC;IACxD,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;IACzB,mBAAmB,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,yBAAW,EAAE,CAAC;IACrD,mBAAmB,EAAE,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CACnE,QAAQ;CACX,CAAC,CAAC,CAAC;AAEJ,2DAA2D;AAC3D,IAAI,CAAC,IAAI,CAAC,oCAAoC,EAAE,GAAG,EAAE,CAAC,CAAC;IACrD,qBAAqB,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QACpC,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE;QACtB,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;QACjB,SAAS,EAAE,KAAK;QAChB,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,KAAK;QAChB,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;KACjB,CAAC,CAAC;CACJ,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,MAAM,SAAS,GAAiB,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE;QACjD,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,wBAAO,CAAC;QAC7B,MAAM,EAAE,cAAc;QACtB,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;IAEH,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,MAAM,CAAC,sCAAc,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAmB,CACpE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;QAClD,MAAM,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjE,MAAM,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAmB,CACpE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,wCAAc,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAmB,CACpE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAC3B,GAAG,EAAE,CAAC,CAAC;YACL,KAAK,EAAE,IAAA,wCAAc,GAAE;YACvB,UAAU,EAAE,IAAA,6CAAmB,GAAE;SAClC,CAAC,EACF,EAAE,OAAO,EAAE,CACZ,CAAC;QAEF,sBAAsB;QACtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAC;QAExD,oCAAoC;QACpC,IAAA,WAAG,EAAC,GAAG,EAAE;YACP,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YACnD,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAmB,CACpE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,4BAAc,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,yBAAW,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,YAAY,GAAG,IAAI,yBAAW,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAE,YAAY,IAC7D,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,4BAAc,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,kDAAe,CAAC;QAC5C,MAAM,WAAW,GAAG,OAAC,CAAC,MAAM,CAAC;YAC3B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;SACxC,CAAC,CAAC;QACH,MAAM,UAAU,GAAG;YACjB;gBACE,IAAI,EAAE,eAAe;gBACrB,WAAW,EAAE,kBAAkB;gBAC/B,SAAS,EAAE,aAAa;gBACxB,WAAW;aACZ;SACF,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,EAAC,UAAU,EAAE,UAAU,IAC1D,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAC1D,eAAe,CAChB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,WAAW,GAAG,OAAC,CAAC,MAAM,CAAC;YAC3B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;SAC3C,CAAC,CAAC;QACH,MAAM,YAAY,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG;YACZ;gBACE,IAAI,EAAE,UAAU;gBAChB,WAAW,EAAE,aAAa;gBAC1B,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ;gBAC1B,WAAW;gBACX,YAAY;aACb;SACF,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,EAAC,KAAK,EAAE,KAAK,IAChD,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,UAAU,GAAG;YACjB,EAAE,GAAG,EAAE,yBAAyB,EAAE,IAAI,EAAE,aAAa,EAAE;SACxD,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,EAAC,UAAU,EAAE,UAAU,IAC1D,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAC/C,yBAAyB,CAC1B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,sBAAsB,GAAG,IAAI;aAChC,EAAE,EAAE;aACJ,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;QAExC,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IACd,MAAM,EAAC,cAAc,EACrB,sBAAsB,EAAE,sBAAsB,IAE7C,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,SAAS,GAAG;YAChB;gBACE,GAAG,EAAE,yBAAyB;gBAC9B,IAAI,EAAE,eAAe;gBACrB,WAAW,EAAE,iBAAiB;gBAC9B,QAAQ,EAAE,YAAY;aACvB;SACF,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,EAAC,SAAS,EAAE,SAAS,IACxD,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACxE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,aAAa,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;QACrE,MAAM,WAAW,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QAElE,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IACd,MAAM,EAAC,cAAc,EACrB,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW,IAEvB,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,0CAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACzE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,EAAC,OAAO,EAAC,aAAa,IACzD,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,oCAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QAClF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAmB,CACpE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,oCAAgB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAErE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,cAAc,GAAG;YACrB,WAAW,EAAE,GAAG,EAAE,CAAC,WAAW;YAC9B,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC/C,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,EAAC,cAAc,EAAE,cAAc,IAClE,QAAQ,CACO,CACnB,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,uDAAsB,GAAE,EAAE;YACtE,OAAO;SACR,CAAC,CAAC;QAEH,yEAAyE;QACzE,MAAM,IAAA,WAAG,EAAC,KAAK,IAAI,EAAE;YACnB,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAC7D,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,OAAO,GAAG,CAAC,EAAE,QAAQ,EAAiC,EAAE,EAAE,CAAC,CAC/D,8BAAC,mCAAe,IAAC,MAAM,EAAC,cAAc,IAAE,QAAQ,CAAmB,CACpE,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,uDAAsB,GAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAE3E,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, useQueryClient } from \"@tanstack/react-query\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport { useStreamState, useThreadManagement } from \"./tambo-v1-stream-context\";\nimport { TamboV1Provider, useTamboV1Config } from \"./tambo-v1-provider\";\n\n// Mock the client provider to capture the apiKey\njest.mock(\"../../providers/tambo-client-provider\", () => ({\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(() => new QueryClient()),\n TamboClientProvider: ({ children }: { children: React.ReactNode }) =>\n children,\n}));\n\n// Mock useTamboV1SendMessage to avoid complex dependencies\njest.mock(\"../hooks/use-tambo-v1-send-message\", () => ({\n useTamboV1SendMessage: jest.fn(() => ({\n mutateAsync: jest.fn(),\n mutate: jest.fn(),\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n reset: jest.fn(),\n })),\n}));\n\ndescribe(\"TamboV1Provider\", () => {\n const mockFetch: typeof fetch = async (..._args) => {\n throw new Error(\"fetch not implemented\");\n };\n\n const mockClient = new TamboAI({\n apiKey: \"test-api-key\",\n fetch: mockFetch,\n });\n\n beforeEach(() => {\n jest.mocked(useTamboClient).mockReturnValue(mockClient);\n });\n\n it(\"provides access to registry context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList).toBeDefined();\n expect(result.current.toolRegistry).toBeDefined();\n expect(typeof result.current.registerComponent).toBe(\"function\");\n expect(typeof result.current.registerTool).toBe(\"function\");\n });\n\n it(\"provides access to stream context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.threadMap).toBeDefined();\n expect(result.current.currentThreadId).toBeNull();\n });\n\n it(\"manages threads via useThreadManagement\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(\n () => ({\n state: useStreamState(),\n management: useThreadManagement(),\n }),\n { wrapper },\n );\n\n // Initially no thread\n expect(result.current.state.currentThreadId).toBeNull();\n\n // Initialize and switch to a thread\n act(() => {\n result.current.management.initThread(\"thread_123\");\n result.current.management.switchThread(\"thread_123\");\n });\n\n expect(result.current.state.currentThreadId).toBe(\"thread_123\");\n expect(result.current.state.threadMap.thread_123).toBeDefined();\n });\n\n it(\"provides access to query client\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useQueryClient(), { wrapper });\n\n expect(result.current).toBeInstanceOf(QueryClient);\n });\n\n it(\"uses custom query client when provided\", () => {\n const customClient = new QueryClient();\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" queryClient={customClient}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useQueryClient(), { wrapper });\n\n expect(result.current).toBe(customClient);\n });\n\n it(\"registers components when provided\", () => {\n const TestComponent = () => <div>Test</div>;\n const propsSchema = z.object({\n title: z.string().describe(\"The title\"),\n });\n const components = [\n {\n name: \"TestComponent\",\n description: \"A test component\",\n component: TestComponent,\n propsSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" components={components}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList.TestComponent).toBeDefined();\n expect(result.current.componentList.TestComponent.name).toBe(\n \"TestComponent\",\n );\n });\n\n it(\"registers tools when provided\", () => {\n const inputSchema = z.object({\n query: z.string().describe(\"Search query\"),\n });\n const outputSchema = z.string().describe(\"Result string\");\n const tools = [\n {\n name: \"testTool\",\n description: \"A test tool\",\n tool: async () => \"result\",\n inputSchema,\n outputSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" tools={tools}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.toolRegistry.testTool).toBeDefined();\n expect(result.current.toolRegistry.testTool.name).toBe(\"testTool\");\n });\n\n it(\"registers MCP servers when provided\", () => {\n const mcpServers = [\n { url: \"https://mcp.example.com\", name: \"Example MCP\" },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" mcpServers={mcpServers}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.mcpServerInfos).toHaveLength(1);\n expect(result.current.mcpServerInfos[0].url).toBe(\n \"https://mcp.example.com\",\n );\n });\n\n it(\"provides onCallUnregisteredTool to registry\", () => {\n const onCallUnregisteredTool = jest\n .fn()\n .mockResolvedValue(\"fallback result\");\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider\n apiKey=\"test-api-key\"\n onCallUnregisteredTool={onCallUnregisteredTool}\n >\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.onCallUnregisteredTool).toBe(onCallUnregisteredTool);\n });\n\n it(\"registers static resources when provided\", () => {\n const resources = [\n {\n uri: \"resource://test/example\",\n name: \"Test Resource\",\n description: \"A test resource\",\n mimeType: \"text/plain\",\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" resources={resources}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resources).toHaveLength(1);\n expect(result.current.resources[0].uri).toBe(\"resource://test/example\");\n expect(result.current.resources[0].name).toBe(\"Test Resource\");\n });\n\n it(\"registers resource source when listResources and getResource provided\", () => {\n const listResources = jest.fn().mockResolvedValue({ resources: [] });\n const getResource = jest.fn().mockResolvedValue({ contents: [] });\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider\n apiKey=\"test-api-key\"\n listResources={listResources}\n getResource={getResource}\n >\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resourceSource).toBeDefined();\n expect(result.current.resourceSource?.listResources).toBe(listResources);\n expect(result.current.resourceSource?.getResource).toBe(getResource);\n });\n\n it(\"provides userKey via useTamboV1Config\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" userKey=\"my-user-key\">\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboV1Config(), { wrapper });\n\n expect(result.current.userKey).toBe(\"my-user-key\");\n });\n\n it(\"returns undefined userKey from useTamboV1Config when no userKey provided\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboV1Config(), { wrapper });\n\n expect(result.current.userKey).toBeUndefined();\n });\n\n it(\"provides context helpers via useTamboContextHelpers hook\", async () => {\n const contextHelpers = {\n getUserName: () => \"Test User\",\n getCurrentTime: () => new Date().toISOString(),\n };\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" contextHelpers={contextHelpers}>\n {children}\n </TamboV1Provider>\n );\n\n const { result, rerender } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n // Helpers are registered via useEffect, so we need to trigger a rerender\n await act(async () => {\n rerender();\n });\n\n const helpers = result.current.getContextHelpers();\n expect(helpers.getUserName).toBe(contextHelpers.getUserName);\n expect(helpers.getCurrentTime).toBe(contextHelpers.getCurrentTime);\n });\n\n it(\"returns empty contextHelpers when none provided\", async () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboContextHelpers(), { wrapper });\n\n const helpers = result.current.getContextHelpers();\n expect(Object.keys(helpers)).toHaveLength(0);\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"tambo-v1-provider.test.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-provider.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import TamboAI from \"@tambo-ai/typescript-sdk\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { renderHook, act } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport { useStreamState, useThreadManagement } from \"./tambo-v1-stream-context\";\nimport { TamboV1Provider, useTamboV1Config } from \"./tambo-v1-provider\";\n\n// Module-level QueryClient for tests - created lazily\nlet testQueryClient: QueryClient | null = null;\n\n// Mock the client provider to capture the apiKey\njest.mock(\"../../providers/tambo-client-provider\", () => {\n return {\n useTamboClient: jest.fn(),\n useTamboQueryClient: jest.fn(),\n TamboClientProvider: jest.fn(\n ({ children }: { children: React.ReactNode }) => children,\n ),\n };\n});\n\n// Mock useTamboV1SendMessage to avoid complex dependencies\njest.mock(\"../hooks/use-tambo-v1-send-message\", () => ({\n useTamboV1SendMessage: jest.fn(() => ({\n mutateAsync: jest.fn(),\n mutate: jest.fn(),\n isPending: false,\n isError: false,\n error: null,\n isSuccess: false,\n reset: jest.fn(),\n })),\n}));\n\ndescribe(\"TamboV1Provider\", () => {\n const mockFetch: typeof fetch = async (..._args) => {\n throw new Error(\"fetch not implemented\");\n };\n\n const mockClient = new TamboAI({\n apiKey: \"test-api-key\",\n fetch: mockFetch,\n });\n\n beforeEach(() => {\n // Create a fresh QueryClient for each test\n testQueryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n jest.mocked(useTamboClient).mockReturnValue(mockClient);\n jest.mocked(useTamboQueryClient).mockReturnValue(testQueryClient);\n\n // Mock TamboClientProvider to wrap children with QueryClientProvider\n const { TamboClientProvider } = jest.requireMock(\n \"../../providers/tambo-client-provider\",\n );\n jest\n .mocked(TamboClientProvider)\n .mockImplementation(({ children }: { children: React.ReactNode }) => (\n <QueryClientProvider client={testQueryClient!}>\n {children}\n </QueryClientProvider>\n ));\n });\n\n it(\"provides access to registry context\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList).toBeDefined();\n expect(result.current.toolRegistry).toBeDefined();\n expect(typeof result.current.registerComponent).toBe(\"function\");\n expect(typeof result.current.registerTool).toBe(\"function\");\n });\n\n it(\"provides access to stream context with placeholder thread ready\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useStreamState(), { wrapper });\n\n expect(result.current.threadMap).toBeDefined();\n // Initial state has placeholder thread for optimistic UI\n expect(result.current.currentThreadId).toBe(\"placeholder\");\n expect(result.current.threadMap.placeholder).toBeDefined();\n });\n\n it(\"manages threads via useThreadManagement\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(\n () => ({\n state: useStreamState(),\n management: useThreadManagement(),\n }),\n { wrapper },\n );\n\n // Initially has placeholder thread for optimistic UI\n expect(result.current.state.currentThreadId).toBe(\"placeholder\");\n\n // Initialize and switch to a different thread\n act(() => {\n result.current.management.initThread(\"thread_123\");\n result.current.management.switchThread(\"thread_123\");\n });\n\n expect(result.current.state.currentThreadId).toBe(\"thread_123\");\n expect(result.current.state.threadMap.thread_123).toBeDefined();\n });\n\n it(\"provides access to query client via useTamboQueryClient\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboQueryClient(), { wrapper });\n\n expect(result.current).toBeInstanceOf(QueryClient);\n });\n\n it(\"registers components when provided\", () => {\n const TestComponent = () => <div>Test</div>;\n const propsSchema = z.object({\n title: z.string().describe(\"The title\"),\n });\n const components = [\n {\n name: \"TestComponent\",\n description: \"A test component\",\n component: TestComponent,\n propsSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" components={components}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.componentList.TestComponent).toBeDefined();\n expect(result.current.componentList.TestComponent.name).toBe(\n \"TestComponent\",\n );\n });\n\n it(\"registers tools when provided\", () => {\n const inputSchema = z.object({\n query: z.string().describe(\"Search query\"),\n });\n const outputSchema = z.string().describe(\"Result string\");\n const tools = [\n {\n name: \"testTool\",\n description: \"A test tool\",\n tool: async () => \"result\",\n inputSchema,\n outputSchema,\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" tools={tools}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.toolRegistry.testTool).toBeDefined();\n expect(result.current.toolRegistry.testTool.name).toBe(\"testTool\");\n });\n\n it(\"registers MCP servers when provided\", () => {\n const mcpServers = [\n { url: \"https://mcp.example.com\", name: \"Example MCP\" },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" mcpServers={mcpServers}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.mcpServerInfos).toHaveLength(1);\n expect(result.current.mcpServerInfos[0].url).toBe(\n \"https://mcp.example.com\",\n );\n });\n\n it(\"provides onCallUnregisteredTool to registry\", () => {\n const onCallUnregisteredTool = jest\n .fn()\n .mockResolvedValue(\"fallback result\");\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider\n apiKey=\"test-api-key\"\n onCallUnregisteredTool={onCallUnregisteredTool}\n >\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.onCallUnregisteredTool).toBe(onCallUnregisteredTool);\n });\n\n it(\"registers static resources when provided\", () => {\n const resources = [\n {\n uri: \"resource://test/example\",\n name: \"Test Resource\",\n description: \"A test resource\",\n mimeType: \"text/plain\",\n },\n ];\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" resources={resources}>\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resources).toHaveLength(1);\n expect(result.current.resources[0].uri).toBe(\"resource://test/example\");\n expect(result.current.resources[0].name).toBe(\"Test Resource\");\n });\n\n it(\"registers resource source when listResources and getResource provided\", () => {\n const listResources = jest.fn().mockResolvedValue({ resources: [] });\n const getResource = jest.fn().mockResolvedValue({ contents: [] });\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider\n apiKey=\"test-api-key\"\n listResources={listResources}\n getResource={getResource}\n >\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboRegistry(), { wrapper });\n\n expect(result.current.resourceSource).toBeDefined();\n expect(result.current.resourceSource?.listResources).toBe(listResources);\n expect(result.current.resourceSource?.getResource).toBe(getResource);\n });\n\n it(\"provides userKey via useTamboV1Config\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" userKey=\"my-user-key\">\n {children}\n </TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboV1Config(), { wrapper });\n\n expect(result.current.userKey).toBe(\"my-user-key\");\n });\n\n it(\"returns undefined userKey from useTamboV1Config when no userKey provided\", () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboV1Config(), { wrapper });\n\n expect(result.current.userKey).toBeUndefined();\n });\n\n it(\"provides context helpers via useTamboContextHelpers hook\", async () => {\n const contextHelpers = {\n getUserName: () => \"Test User\",\n getCurrentTime: () => new Date().toISOString(),\n };\n\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\" contextHelpers={contextHelpers}>\n {children}\n </TamboV1Provider>\n );\n\n const { result, rerender } = renderHook(() => useTamboContextHelpers(), {\n wrapper,\n });\n\n // Helpers are registered via useEffect, so we need to trigger a rerender\n await act(async () => {\n rerender();\n });\n\n const helpers = result.current.getContextHelpers();\n expect(helpers.getUserName).toBe(contextHelpers.getUserName);\n expect(helpers.getCurrentTime).toBe(contextHelpers.getCurrentTime);\n });\n\n it(\"returns only interactables contextHelper when none explicitly provided\", async () => {\n const wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboV1Provider apiKey=\"test-api-key\">{children}</TamboV1Provider>\n );\n\n const { result } = renderHook(() => useTamboContextHelpers(), { wrapper });\n\n const helpers = result.current.getContextHelpers();\n // TamboInteractableProvider registers an \"interactables\" context helper\n expect(Object.keys(helpers)).toEqual([\"interactables\"]);\n });\n});\n"]}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* following the split-context pattern for optimal re-render performance.
|
|
7
7
|
*/
|
|
8
8
|
import React from "react";
|
|
9
|
-
import { type StreamState, type StreamAction } from "../utils/event-accumulator";
|
|
10
9
|
import type { TamboV1Thread } from "../types/thread";
|
|
10
|
+
import { type StreamAction, type StreamState } from "../utils/event-accumulator";
|
|
11
11
|
/**
|
|
12
12
|
* Thread management functions exposed by the stream context.
|
|
13
13
|
*/
|
|
@@ -22,9 +22,9 @@ export interface ThreadManagement {
|
|
|
22
22
|
/**
|
|
23
23
|
* Switch the current active thread.
|
|
24
24
|
* Does not fetch thread data - use useTamboV1Thread for that.
|
|
25
|
-
* @param threadId - The thread ID to switch to
|
|
25
|
+
* @param threadId - The thread ID to switch to
|
|
26
26
|
*/
|
|
27
|
-
switchThread: (threadId: string
|
|
27
|
+
switchThread: (threadId: string) => void;
|
|
28
28
|
/**
|
|
29
29
|
* Start a new thread (generates a temporary ID).
|
|
30
30
|
* The actual thread ID will be assigned when the first message is sent.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-v1-stream-context.d.ts","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-stream-context.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"tambo-v1-stream-context.d.ts","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-stream-context.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAQN,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAML,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,4BAA4B,CAAC;AAEpC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,UAAU,EAAE,CACV,QAAQ,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,KACnC,IAAI,CAAC;IAEV;;;;OAIG;IACH,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAEzC;;;;OAIG;IACH,cAAc,EAAE,MAAM,MAAM,CAAC;CAC9B;AAqBD;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B;;;OAGG;IACH,KAAK,CAAC,EAAE,WAAW,CAAC;IAEpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAExC;;OAEG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,qBAkFtE;AAsDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAQ5C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAUhE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CAUtD"}
|
|
@@ -46,6 +46,8 @@ exports.useThreadManagement = useThreadManagement;
|
|
|
46
46
|
* following the split-context pattern for optimal re-render performance.
|
|
47
47
|
*/
|
|
48
48
|
const react_1 = __importStar(require("react"));
|
|
49
|
+
const tambo_client_provider_1 = require("../../providers/tambo-client-provider");
|
|
50
|
+
const react_query_hooks_1 = require("../../hooks/react-query-hooks");
|
|
49
51
|
const event_accumulator_1 = require("../utils/event-accumulator");
|
|
50
52
|
/**
|
|
51
53
|
* Context for accessing stream state (read-only).
|
|
@@ -95,12 +97,8 @@ function TamboV1StreamProvider(props) {
|
|
|
95
97
|
}
|
|
96
98
|
}
|
|
97
99
|
// Create stable initial state - only computed once on mount
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
() => ({
|
|
101
|
-
threadMap: {},
|
|
102
|
-
currentThreadId: null,
|
|
103
|
-
}));
|
|
100
|
+
// Uses createInitialState which sets up placeholder thread for optimistic UI
|
|
101
|
+
const [state, dispatch] = (0, react_1.useReducer)(event_accumulator_1.streamReducer, undefined, event_accumulator_1.createInitialState);
|
|
104
102
|
const activeState = providedState ?? state;
|
|
105
103
|
const activeDispatch = providedDispatch ?? dispatch;
|
|
106
104
|
// Thread management functions
|
|
@@ -111,11 +109,14 @@ function TamboV1StreamProvider(props) {
|
|
|
111
109
|
activeDispatch({ type: "SET_CURRENT_THREAD", threadId });
|
|
112
110
|
}, [activeDispatch]);
|
|
113
111
|
const startNewThread = (0, react_1.useCallback)(() => {
|
|
114
|
-
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
// Reset placeholder thread to empty state and switch to it
|
|
113
|
+
// This prepares for a new conversation while preserving existing threads
|
|
114
|
+
activeDispatch({
|
|
115
|
+
type: "START_NEW_THREAD",
|
|
116
|
+
threadId: event_accumulator_1.PLACEHOLDER_THREAD_ID,
|
|
117
|
+
initialThread: (0, event_accumulator_1.createInitialThreadState)(event_accumulator_1.PLACEHOLDER_THREAD_ID).thread,
|
|
118
|
+
});
|
|
119
|
+
return event_accumulator_1.PLACEHOLDER_THREAD_ID;
|
|
119
120
|
}, [activeDispatch]);
|
|
120
121
|
const threadManagement = (0, react_1.useMemo)(() => {
|
|
121
122
|
return (props.threadManagement ?? {
|
|
@@ -126,7 +127,54 @@ function TamboV1StreamProvider(props) {
|
|
|
126
127
|
}, [props.threadManagement, initThread, switchThread, startNewThread]);
|
|
127
128
|
return (react_1.default.createElement(StreamStateContext.Provider, { value: activeState },
|
|
128
129
|
react_1.default.createElement(StreamDispatchContext.Provider, { value: activeDispatch },
|
|
129
|
-
react_1.default.createElement(ThreadManagementContext.Provider, { value: threadManagement },
|
|
130
|
+
react_1.default.createElement(ThreadManagementContext.Provider, { value: threadManagement },
|
|
131
|
+
react_1.default.createElement(ThreadSyncManager, null),
|
|
132
|
+
children))));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Internal component that handles automatic thread message syncing.
|
|
136
|
+
* Fetches thread messages when switching to a non-placeholder thread.
|
|
137
|
+
* Must be used within StreamStateContext, StreamDispatchContext, and TamboClientProvider.
|
|
138
|
+
* @internal
|
|
139
|
+
* @returns null - this component renders nothing
|
|
140
|
+
*/
|
|
141
|
+
function ThreadSyncManager() {
|
|
142
|
+
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
143
|
+
const state = (0, react_1.useContext)(StreamStateContext);
|
|
144
|
+
const dispatch = (0, react_1.useContext)(StreamDispatchContext);
|
|
145
|
+
// Track which threads have been synced to avoid redundant fetches
|
|
146
|
+
const lastSyncedThreadRef = (0, react_1.useRef)(null);
|
|
147
|
+
const currentThreadId = state?.currentThreadId ?? event_accumulator_1.PLACEHOLDER_THREAD_ID;
|
|
148
|
+
const threadState = state?.threadMap[currentThreadId];
|
|
149
|
+
// Determine if we need to fetch thread messages
|
|
150
|
+
// Only fetch for non-placeholder threads that haven't been synced and have no messages
|
|
151
|
+
const isNotPlaceholder = !(0, event_accumulator_1.isPlaceholderThreadId)(currentThreadId);
|
|
152
|
+
const isNotSynced = currentThreadId !== lastSyncedThreadRef.current;
|
|
153
|
+
const hasNoMessages = !threadState || threadState.thread.messages.length === 0;
|
|
154
|
+
const shouldFetch = isNotPlaceholder && isNotSynced && hasNoMessages;
|
|
155
|
+
// Fetch messages from the messages endpoint (not the thread endpoint)
|
|
156
|
+
const { data: messagesData, isSuccess } = (0, react_query_hooks_1.useTamboQuery)({
|
|
157
|
+
queryKey: ["v1-thread-messages", currentThreadId],
|
|
158
|
+
queryFn: async () => await client.threads.messages.list(currentThreadId),
|
|
159
|
+
enabled: shouldFetch,
|
|
160
|
+
staleTime: 1000,
|
|
161
|
+
refetchOnWindowFocus: false,
|
|
162
|
+
});
|
|
163
|
+
// Sync fetched messages to stream state
|
|
164
|
+
(0, react_1.useEffect)(() => {
|
|
165
|
+
if (!isSuccess || !messagesData || !dispatch)
|
|
166
|
+
return;
|
|
167
|
+
if (lastSyncedThreadRef.current === currentThreadId)
|
|
168
|
+
return;
|
|
169
|
+
dispatch({
|
|
170
|
+
type: "LOAD_THREAD_MESSAGES",
|
|
171
|
+
threadId: currentThreadId,
|
|
172
|
+
messages: messagesData.messages,
|
|
173
|
+
skipIfStreaming: true,
|
|
174
|
+
});
|
|
175
|
+
lastSyncedThreadRef.current = currentThreadId;
|
|
176
|
+
}, [isSuccess, messagesData, currentThreadId, dispatch]);
|
|
177
|
+
return null;
|
|
130
178
|
}
|
|
131
179
|
/**
|
|
132
180
|
* Hook to access stream state.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-v1-stream-context.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-stream-context.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * Stream Context Provider for v1 API\n *\n * Manages streaming state using React Context and useReducer.\n * Provides state and dispatch to child components via separate contexts\n * following the split-context pattern for optimal re-render performance.\n */\n\nimport React, {\n createContext,\n useReducer,\n useContext,\n useMemo,\n useCallback,\n} from \"react\";\nimport {\n streamReducer,\n type StreamState,\n type StreamAction,\n} from \"../utils/event-accumulator\";\nimport type { TamboV1Thread } from \"../types/thread\";\n\n/**\n * Thread management functions exposed by the stream context.\n */\nexport interface ThreadManagement {\n /**\n * Initialize a new thread in the stream context.\n * Use this before sending messages to a new thread.\n * @param threadId - The thread ID to initialize\n * @param initialThread - Optional initial thread data\n */\n initThread: (\n threadId: string,\n initialThread?: Partial<TamboV1Thread>,\n ) => void;\n\n /**\n * Switch the current active thread.\n * Does not fetch thread data - use useTamboV1Thread for that.\n * @param threadId - The thread ID to switch to, or null to clear\n */\n switchThread: (threadId: string | null) => void;\n\n /**\n * Start a new thread (generates a temporary ID).\n * The actual thread ID will be assigned when the first message is sent.\n * @returns The temporary thread ID\n */\n startNewThread: () => string;\n}\n\n/**\n * Context for accessing stream state (read-only).\n * Separated from dispatch context to prevent unnecessary re-renders.\n */\nconst StreamStateContext = createContext<StreamState | null>(null);\n\n/**\n * Context for dispatching events to the stream reducer.\n * Separated from state context to prevent unnecessary re-renders.\n */\nconst StreamDispatchContext =\n createContext<React.Dispatch<StreamAction> | null>(null);\n\n/**\n * Context for thread management functions.\n * Separated from state to prevent unnecessary re-renders.\n */\nconst ThreadManagementContext = createContext<ThreadManagement | null>(null);\n\n/**\n * Props for TamboV1StreamProvider\n */\nexport interface TamboV1StreamProviderProps {\n children: React.ReactNode;\n\n /**\n * Optional override for stream state (primarily for tests).\n * If provided, you must also provide `dispatch`.\n */\n state?: StreamState;\n\n /**\n * Optional override for stream dispatch (primarily for tests).\n * If provided, you must also provide `state`.\n */\n dispatch?: React.Dispatch<StreamAction>;\n\n /**\n * Optional override for thread management functions (primarily for tests).\n */\n threadManagement?: ThreadManagement;\n}\n\n/**\n * Provider component for stream state management.\n *\n * Uses useReducer with streamReducer to accumulate AG-UI events into\n * thread state. Provides state, dispatch, and thread management via separate contexts.\n *\n * Thread management is done programmatically via the hooks:\n * - startNewThread() - Start a new conversation\n * - switchThread(threadId) - Switch to an existing thread\n * - initThread(threadId) - Initialize a thread for receiving events\n * @returns JSX element wrapping children with stream contexts\n * @example\n * ```tsx\n * <TamboV1StreamProvider>\n * <ChatInterface />\n * </TamboV1StreamProvider>\n * ```\n */\nexport function TamboV1StreamProvider(props: TamboV1StreamProviderProps) {\n const { children, state: providedState, dispatch: providedDispatch } = props;\n\n if (\n (providedState && !providedDispatch) ||\n (!providedState && providedDispatch)\n ) {\n throw new Error(\n \"TamboV1StreamProvider requires both state and dispatch when overriding\",\n );\n }\n\n if (props.threadManagement) {\n const { initThread, switchThread, startNewThread } = props.threadManagement;\n if (\n typeof initThread !== \"function\" ||\n typeof switchThread !== \"function\" ||\n typeof startNewThread !== \"function\"\n ) {\n throw new Error(\n \"TamboV1StreamProvider: threadManagement override is missing required methods\",\n );\n }\n }\n\n // Create stable initial state - only computed once on mount\n const [state, dispatch] = useReducer(\n streamReducer,\n undefined,\n // Lazy initializer function\n () => ({\n threadMap: {},\n currentThreadId: null,\n }),\n );\n\n const activeState = providedState ?? state;\n const activeDispatch = providedDispatch ?? dispatch;\n\n // Thread management functions\n const initThread = useCallback(\n (threadId: string, initialThread?: Partial<TamboV1Thread>) => {\n activeDispatch({ type: \"INIT_THREAD\", threadId, initialThread });\n },\n [activeDispatch],\n );\n\n const switchThread = useCallback(\n (threadId: string | null) => {\n activeDispatch({ type: \"SET_CURRENT_THREAD\", threadId });\n },\n [activeDispatch],\n );\n\n const startNewThread = useCallback(() => {\n const tempId = `temp_${crypto.randomUUID()}`;\n // Use atomic START_NEW_THREAD action to prevent race conditions\n // when multiple calls happen concurrently (e.g., double-click)\n activeDispatch({ type: \"START_NEW_THREAD\", threadId: tempId });\n return tempId;\n }, [activeDispatch]);\n\n const threadManagement = useMemo<ThreadManagement>(() => {\n return (\n props.threadManagement ?? {\n initThread,\n switchThread,\n startNewThread,\n }\n );\n }, [props.threadManagement, initThread, switchThread, startNewThread]);\n\n return (\n <StreamStateContext.Provider value={activeState}>\n <StreamDispatchContext.Provider value={activeDispatch}>\n <ThreadManagementContext.Provider value={threadManagement}>\n {children}\n </ThreadManagementContext.Provider>\n </StreamDispatchContext.Provider>\n </StreamStateContext.Provider>\n );\n}\n\n/**\n * Hook to access stream state.\n *\n * Must be used within TamboV1StreamProvider.\n * @returns Current stream state\n * @throws {Error} if used outside TamboV1StreamProvider\n * @example\n * ```tsx\n * function ChatMessages() {\n * const { thread, streaming } = useStreamState();\n *\n * return (\n * <div>\n * {thread.messages.map(msg => <Message key={msg.id} message={msg} />)}\n * {streaming.status === 'streaming' && <LoadingIndicator />}\n * </div>\n * );\n * }\n * ```\n */\nexport function useStreamState(): StreamState {\n const context = useContext(StreamStateContext);\n\n if (!context) {\n throw new Error(\"useStreamState must be used within TamboV1StreamProvider\");\n }\n\n return context;\n}\n\n/**\n * Hook to access stream dispatch function.\n *\n * Must be used within TamboV1StreamProvider.\n * @returns Dispatch function for sending events to reducer\n * @throws {Error} if used outside TamboV1StreamProvider\n * @example\n * ```tsx\n * function StreamHandler() {\n * const dispatch = useStreamDispatch();\n *\n * useEffect(() => {\n * async function handleStream() {\n * for await (const event of streamEvents) {\n * dispatch({ type: 'EVENT', event });\n * }\n * }\n * handleStream();\n * }, [dispatch]);\n *\n * return null;\n * }\n * ```\n */\nexport function useStreamDispatch(): React.Dispatch<StreamAction> {\n const context = useContext(StreamDispatchContext);\n\n if (!context) {\n throw new Error(\n \"useStreamDispatch must be used within TamboV1StreamProvider\",\n );\n }\n\n return context;\n}\n\n/**\n * Hook to access thread management functions.\n *\n * Must be used within TamboV1StreamProvider.\n * @returns Thread management functions\n * @throws {Error} if used outside TamboV1StreamProvider\n * @example\n * ```tsx\n * function ThreadSwitcher() {\n * const { switchThread, startNewThread } = useThreadManagement();\n *\n * return (\n * <div>\n * <button onClick={() => switchThread('thread_123')}>\n * Load Thread\n * </button>\n * <button onClick={startNewThread}>\n * New Chat\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useThreadManagement(): ThreadManagement {\n const context = useContext(ThreadManagementContext);\n\n if (!context) {\n throw new Error(\n \"useThreadManagement must be used within TamboV1StreamProvider\",\n );\n }\n\n return context;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tambo-v1-stream-context.js","sourceRoot":"","sources":["../../../src/v1/providers/tambo-v1-stream-context.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * Stream Context Provider for v1 API\n *\n * Manages streaming state using React Context and useReducer.\n * Provides state and dispatch to child components via separate contexts\n * following the split-context pattern for optimal re-render performance.\n */\n\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n} from \"react\";\nimport { useTamboClient } from \"../../providers/tambo-client-provider\";\nimport { useTamboQuery } from \"../../hooks/react-query-hooks\";\nimport type { TamboV1Message } from \"../types/message\";\nimport type { TamboV1Thread } from \"../types/thread\";\nimport {\n createInitialState,\n createInitialThreadState,\n isPlaceholderThreadId,\n PLACEHOLDER_THREAD_ID,\n streamReducer,\n type StreamAction,\n type StreamState,\n} from \"../utils/event-accumulator\";\n\n/**\n * Thread management functions exposed by the stream context.\n */\nexport interface ThreadManagement {\n /**\n * Initialize a new thread in the stream context.\n * Use this before sending messages to a new thread.\n * @param threadId - The thread ID to initialize\n * @param initialThread - Optional initial thread data\n */\n initThread: (\n threadId: string,\n initialThread?: Partial<TamboV1Thread>,\n ) => void;\n\n /**\n * Switch the current active thread.\n * Does not fetch thread data - use useTamboV1Thread for that.\n * @param threadId - The thread ID to switch to\n */\n switchThread: (threadId: string) => void;\n\n /**\n * Start a new thread (generates a temporary ID).\n * The actual thread ID will be assigned when the first message is sent.\n * @returns The temporary thread ID\n */\n startNewThread: () => string;\n}\n\n/**\n * Context for accessing stream state (read-only).\n * Separated from dispatch context to prevent unnecessary re-renders.\n */\nconst StreamStateContext = createContext<StreamState | null>(null);\n\n/**\n * Context for dispatching events to the stream reducer.\n * Separated from state context to prevent unnecessary re-renders.\n */\nconst StreamDispatchContext =\n createContext<React.Dispatch<StreamAction> | null>(null);\n\n/**\n * Context for thread management functions.\n * Separated from state to prevent unnecessary re-renders.\n */\nconst ThreadManagementContext = createContext<ThreadManagement | null>(null);\n\n/**\n * Props for TamboV1StreamProvider\n */\nexport interface TamboV1StreamProviderProps {\n children: React.ReactNode;\n\n /**\n * Optional override for stream state (primarily for tests).\n * If provided, you must also provide `dispatch`.\n */\n state?: StreamState;\n\n /**\n * Optional override for stream dispatch (primarily for tests).\n * If provided, you must also provide `state`.\n */\n dispatch?: React.Dispatch<StreamAction>;\n\n /**\n * Optional override for thread management functions (primarily for tests).\n */\n threadManagement?: ThreadManagement;\n}\n\n/**\n * Provider component for stream state management.\n *\n * Uses useReducer with streamReducer to accumulate AG-UI events into\n * thread state. Provides state, dispatch, and thread management via separate contexts.\n *\n * Thread management is done programmatically via the hooks:\n * - startNewThread() - Start a new conversation\n * - switchThread(threadId) - Switch to an existing thread\n * - initThread(threadId) - Initialize a thread for receiving events\n * @returns JSX element wrapping children with stream contexts\n * @example\n * ```tsx\n * <TamboV1StreamProvider>\n * <ChatInterface />\n * </TamboV1StreamProvider>\n * ```\n */\nexport function TamboV1StreamProvider(props: TamboV1StreamProviderProps) {\n const { children, state: providedState, dispatch: providedDispatch } = props;\n\n if (\n (providedState && !providedDispatch) ||\n (!providedState && providedDispatch)\n ) {\n throw new Error(\n \"TamboV1StreamProvider requires both state and dispatch when overriding\",\n );\n }\n\n if (props.threadManagement) {\n const { initThread, switchThread, startNewThread } = props.threadManagement;\n if (\n typeof initThread !== \"function\" ||\n typeof switchThread !== \"function\" ||\n typeof startNewThread !== \"function\"\n ) {\n throw new Error(\n \"TamboV1StreamProvider: threadManagement override is missing required methods\",\n );\n }\n }\n\n // Create stable initial state - only computed once on mount\n // Uses createInitialState which sets up placeholder thread for optimistic UI\n const [state, dispatch] = useReducer(\n streamReducer,\n undefined,\n createInitialState,\n );\n\n const activeState = providedState ?? state;\n const activeDispatch = providedDispatch ?? dispatch;\n\n // Thread management functions\n const initThread = useCallback(\n (threadId: string, initialThread?: Partial<TamboV1Thread>) => {\n activeDispatch({ type: \"INIT_THREAD\", threadId, initialThread });\n },\n [activeDispatch],\n );\n\n const switchThread = useCallback(\n (threadId: string) => {\n activeDispatch({ type: \"SET_CURRENT_THREAD\", threadId });\n },\n [activeDispatch],\n );\n\n const startNewThread = useCallback(() => {\n // Reset placeholder thread to empty state and switch to it\n // This prepares for a new conversation while preserving existing threads\n activeDispatch({\n type: \"START_NEW_THREAD\",\n threadId: PLACEHOLDER_THREAD_ID,\n initialThread: createInitialThreadState(PLACEHOLDER_THREAD_ID).thread,\n });\n return PLACEHOLDER_THREAD_ID;\n }, [activeDispatch]);\n\n const threadManagement = useMemo<ThreadManagement>(() => {\n return (\n props.threadManagement ?? {\n initThread,\n switchThread,\n startNewThread,\n }\n );\n }, [props.threadManagement, initThread, switchThread, startNewThread]);\n\n return (\n <StreamStateContext.Provider value={activeState}>\n <StreamDispatchContext.Provider value={activeDispatch}>\n <ThreadManagementContext.Provider value={threadManagement}>\n <ThreadSyncManager />\n {children}\n </ThreadManagementContext.Provider>\n </StreamDispatchContext.Provider>\n </StreamStateContext.Provider>\n );\n}\n\n/**\n * Internal component that handles automatic thread message syncing.\n * Fetches thread messages when switching to a non-placeholder thread.\n * Must be used within StreamStateContext, StreamDispatchContext, and TamboClientProvider.\n * @internal\n * @returns null - this component renders nothing\n */\nfunction ThreadSyncManager(): null {\n const client = useTamboClient();\n const state = useContext(StreamStateContext);\n const dispatch = useContext(StreamDispatchContext);\n\n // Track which threads have been synced to avoid redundant fetches\n const lastSyncedThreadRef = useRef<string | null>(null);\n const currentThreadId = state?.currentThreadId ?? PLACEHOLDER_THREAD_ID;\n const threadState = state?.threadMap[currentThreadId];\n\n // Determine if we need to fetch thread messages\n // Only fetch for non-placeholder threads that haven't been synced and have no messages\n const isNotPlaceholder = !isPlaceholderThreadId(currentThreadId);\n const isNotSynced = currentThreadId !== lastSyncedThreadRef.current;\n const hasNoMessages =\n !threadState || threadState.thread.messages.length === 0;\n const shouldFetch = isNotPlaceholder && isNotSynced && hasNoMessages;\n\n // Fetch messages from the messages endpoint (not the thread endpoint)\n const { data: messagesData, isSuccess } = useTamboQuery({\n queryKey: [\"v1-thread-messages\", currentThreadId],\n queryFn: async () => await client.threads.messages.list(currentThreadId),\n enabled: shouldFetch,\n staleTime: 1000,\n refetchOnWindowFocus: false,\n });\n\n // Sync fetched messages to stream state\n useEffect(() => {\n if (!isSuccess || !messagesData || !dispatch) return;\n if (lastSyncedThreadRef.current === currentThreadId) return;\n\n dispatch({\n type: \"LOAD_THREAD_MESSAGES\",\n threadId: currentThreadId,\n messages: messagesData.messages as TamboV1Message[],\n skipIfStreaming: true,\n });\n\n lastSyncedThreadRef.current = currentThreadId;\n }, [isSuccess, messagesData, currentThreadId, dispatch]);\n\n return null;\n}\n\n/**\n * Hook to access stream state.\n *\n * Must be used within TamboV1StreamProvider.\n * @returns Current stream state\n * @throws {Error} if used outside TamboV1StreamProvider\n * @example\n * ```tsx\n * function ChatMessages() {\n * const { thread, streaming } = useStreamState();\n *\n * return (\n * <div>\n * {thread.messages.map(msg => <Message key={msg.id} message={msg} />)}\n * {streaming.status === 'streaming' && <LoadingIndicator />}\n * </div>\n * );\n * }\n * ```\n */\nexport function useStreamState(): StreamState {\n const context = useContext(StreamStateContext);\n\n if (!context) {\n throw new Error(\"useStreamState must be used within TamboV1StreamProvider\");\n }\n\n return context;\n}\n\n/**\n * Hook to access stream dispatch function.\n *\n * Must be used within TamboV1StreamProvider.\n * @returns Dispatch function for sending events to reducer\n * @throws {Error} if used outside TamboV1StreamProvider\n * @example\n * ```tsx\n * function StreamHandler() {\n * const dispatch = useStreamDispatch();\n *\n * useEffect(() => {\n * async function handleStream() {\n * for await (const event of streamEvents) {\n * dispatch({ type: 'EVENT', event });\n * }\n * }\n * handleStream();\n * }, [dispatch]);\n *\n * return null;\n * }\n * ```\n */\nexport function useStreamDispatch(): React.Dispatch<StreamAction> {\n const context = useContext(StreamDispatchContext);\n\n if (!context) {\n throw new Error(\n \"useStreamDispatch must be used within TamboV1StreamProvider\",\n );\n }\n\n return context;\n}\n\n/**\n * Hook to access thread management functions.\n *\n * Must be used within TamboV1StreamProvider.\n * @returns Thread management functions\n * @throws {Error} if used outside TamboV1StreamProvider\n * @example\n * ```tsx\n * function ThreadSwitcher() {\n * const { switchThread, startNewThread } = useThreadManagement();\n *\n * return (\n * <div>\n * <button onClick={() => switchThread('thread_123')}>\n * Load Thread\n * </button>\n * <button onClick={startNewThread}>\n * New Chat\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useThreadManagement(): ThreadManagement {\n const context = useContext(ThreadManagementContext);\n\n if (!context) {\n throw new Error(\n \"useThreadManagement must be used within TamboV1StreamProvider\",\n );\n }\n\n return context;\n}\n"]}
|
|
@@ -4,10 +4,40 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const core_1 = require("@ag-ui/core");
|
|
7
|
+
const react_query_1 = require("@tanstack/react-query");
|
|
7
8
|
const react_1 = require("@testing-library/react");
|
|
8
9
|
const react_2 = __importDefault(require("react"));
|
|
9
10
|
const tambo_v1_stream_context_1 = require("./tambo-v1-stream-context");
|
|
11
|
+
// Mock useTamboClient and useTamboQueryClient to avoid TamboClientProvider dependency
|
|
12
|
+
jest.mock("../../providers/tambo-client-provider", () => ({
|
|
13
|
+
useTamboClient: jest.fn(() => ({
|
|
14
|
+
threads: {
|
|
15
|
+
messages: {
|
|
16
|
+
list: jest.fn().mockResolvedValue({ messages: [], hasMore: false }),
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
})),
|
|
20
|
+
useTamboQueryClient: jest.fn(),
|
|
21
|
+
}));
|
|
22
|
+
// Import for mocking
|
|
23
|
+
const tambo_client_provider_1 = require("../../providers/tambo-client-provider");
|
|
10
24
|
describe("TamboV1StreamProvider", () => {
|
|
25
|
+
let queryClient;
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
queryClient = new react_query_1.QueryClient({
|
|
28
|
+
defaultOptions: {
|
|
29
|
+
queries: { retry: false },
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
// Configure mock to return the test's queryClient
|
|
33
|
+
jest.mocked(tambo_client_provider_1.useTamboQueryClient).mockReturnValue(queryClient);
|
|
34
|
+
});
|
|
35
|
+
const createWrapper = () => {
|
|
36
|
+
return function Wrapper({ children }) {
|
|
37
|
+
return (react_2.default.createElement(react_query_1.QueryClientProvider, { client: queryClient },
|
|
38
|
+
react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children)));
|
|
39
|
+
};
|
|
40
|
+
};
|
|
11
41
|
describe("useStreamState", () => {
|
|
12
42
|
it("throws when used outside provider", () => {
|
|
13
43
|
// Suppress console.error for expected error
|
|
@@ -19,18 +49,22 @@ describe("TamboV1StreamProvider", () => {
|
|
|
19
49
|
}).toThrow("useStreamState must be used within TamboV1StreamProvider");
|
|
20
50
|
consoleSpy.mockRestore();
|
|
21
51
|
});
|
|
22
|
-
it("returns initial state with
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
52
|
+
it("returns initial state with placeholder thread ready for new messages", () => {
|
|
53
|
+
const { result } = (0, react_1.renderHook)(() => (0, tambo_v1_stream_context_1.useStreamState)(), {
|
|
54
|
+
wrapper: createWrapper(),
|
|
55
|
+
});
|
|
56
|
+
// Initial state should have placeholder thread ready for optimistic UI
|
|
57
|
+
expect(result.current.currentThreadId).toBe("placeholder");
|
|
58
|
+
expect(result.current.threadMap.placeholder).toBeDefined();
|
|
59
|
+
expect(result.current.threadMap.placeholder.thread.id).toBe("placeholder");
|
|
60
|
+
expect(result.current.threadMap.placeholder.thread.messages).toEqual([]);
|
|
61
|
+
expect(result.current.threadMap.placeholder.streaming.status).toBe("idle");
|
|
27
62
|
});
|
|
28
63
|
it("initializes thread via dispatch", () => {
|
|
29
|
-
const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children));
|
|
30
64
|
const { result } = (0, react_1.renderHook)(() => ({
|
|
31
65
|
state: (0, tambo_v1_stream_context_1.useStreamState)(),
|
|
32
66
|
dispatch: (0, tambo_v1_stream_context_1.useStreamDispatch)(),
|
|
33
|
-
}), { wrapper });
|
|
67
|
+
}), { wrapper: createWrapper() });
|
|
34
68
|
(0, react_1.act)(() => {
|
|
35
69
|
result.current.dispatch({
|
|
36
70
|
type: "INIT_THREAD",
|
|
@@ -43,11 +77,10 @@ describe("TamboV1StreamProvider", () => {
|
|
|
43
77
|
expect(result.current.state.threadMap.thread_123.thread.messages).toEqual([]);
|
|
44
78
|
});
|
|
45
79
|
it("initializes thread with initial data via dispatch", () => {
|
|
46
|
-
const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children));
|
|
47
80
|
const { result } = (0, react_1.renderHook)(() => ({
|
|
48
81
|
state: (0, tambo_v1_stream_context_1.useStreamState)(),
|
|
49
82
|
dispatch: (0, tambo_v1_stream_context_1.useStreamDispatch)(),
|
|
50
|
-
}), { wrapper });
|
|
83
|
+
}), { wrapper: createWrapper() });
|
|
51
84
|
(0, react_1.act)(() => {
|
|
52
85
|
result.current.dispatch({
|
|
53
86
|
type: "INIT_THREAD",
|
|
@@ -77,11 +110,10 @@ describe("TamboV1StreamProvider", () => {
|
|
|
77
110
|
consoleSpy.mockRestore();
|
|
78
111
|
});
|
|
79
112
|
it("dispatches events to update state", () => {
|
|
80
|
-
const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children));
|
|
81
113
|
const { result } = (0, react_1.renderHook)(() => ({
|
|
82
114
|
state: (0, tambo_v1_stream_context_1.useStreamState)(),
|
|
83
115
|
dispatch: (0, tambo_v1_stream_context_1.useStreamDispatch)(),
|
|
84
|
-
}), { wrapper });
|
|
116
|
+
}), { wrapper: createWrapper() });
|
|
85
117
|
// Initialize the thread first
|
|
86
118
|
(0, react_1.act)(() => {
|
|
87
119
|
result.current.dispatch({
|
|
@@ -117,11 +149,10 @@ describe("TamboV1StreamProvider", () => {
|
|
|
117
149
|
consoleSpy.mockRestore();
|
|
118
150
|
});
|
|
119
151
|
it("initThread creates a new thread", () => {
|
|
120
|
-
const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children));
|
|
121
152
|
const { result } = (0, react_1.renderHook)(() => ({
|
|
122
153
|
state: (0, tambo_v1_stream_context_1.useStreamState)(),
|
|
123
154
|
management: (0, tambo_v1_stream_context_1.useThreadManagement)(),
|
|
124
|
-
}), { wrapper });
|
|
155
|
+
}), { wrapper: createWrapper() });
|
|
125
156
|
(0, react_1.act)(() => {
|
|
126
157
|
result.current.management.initThread("thread_456");
|
|
127
158
|
});
|
|
@@ -129,11 +160,10 @@ describe("TamboV1StreamProvider", () => {
|
|
|
129
160
|
expect(result.current.state.threadMap.thread_456.thread.id).toBe("thread_456");
|
|
130
161
|
});
|
|
131
162
|
it("switchThread changes currentThreadId", () => {
|
|
132
|
-
const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children));
|
|
133
163
|
const { result } = (0, react_1.renderHook)(() => ({
|
|
134
164
|
state: (0, tambo_v1_stream_context_1.useStreamState)(),
|
|
135
165
|
management: (0, tambo_v1_stream_context_1.useThreadManagement)(),
|
|
136
|
-
}), { wrapper });
|
|
166
|
+
}), { wrapper: createWrapper() });
|
|
137
167
|
// Initialize and switch to a thread
|
|
138
168
|
(0, react_1.act)(() => {
|
|
139
169
|
result.current.management.initThread("thread_789");
|
|
@@ -142,18 +172,17 @@ describe("TamboV1StreamProvider", () => {
|
|
|
142
172
|
expect(result.current.state.currentThreadId).toBe("thread_789");
|
|
143
173
|
});
|
|
144
174
|
it("startNewThread creates temp thread and switches to it", () => {
|
|
145
|
-
const wrapper = ({ children }) => (react_2.default.createElement(tambo_v1_stream_context_1.TamboV1StreamProvider, null, children));
|
|
146
175
|
const { result } = (0, react_1.renderHook)(() => ({
|
|
147
176
|
state: (0, tambo_v1_stream_context_1.useStreamState)(),
|
|
148
177
|
management: (0, tambo_v1_stream_context_1.useThreadManagement)(),
|
|
149
|
-
}), { wrapper });
|
|
178
|
+
}), { wrapper: createWrapper() });
|
|
150
179
|
let tempId;
|
|
151
180
|
(0, react_1.act)(() => {
|
|
152
181
|
tempId = result.current.management.startNewThread();
|
|
153
182
|
});
|
|
154
|
-
expect(tempId).
|
|
155
|
-
expect(result.current.state.currentThreadId).toBe(
|
|
156
|
-
expect(result.current.state.threadMap
|
|
183
|
+
expect(tempId).toBe("placeholder");
|
|
184
|
+
expect(result.current.state.currentThreadId).toBe("placeholder");
|
|
185
|
+
expect(result.current.state.threadMap.placeholder).toBeDefined();
|
|
157
186
|
});
|
|
158
187
|
});
|
|
159
188
|
});
|