@tambo-ai/react 0.74.1 → 0.75.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 +46 -449
- package/dist/hoc/with-tambo-interactable.d.ts +8 -0
- package/dist/hoc/with-tambo-interactable.d.ts.map +1 -1
- package/dist/hoc/with-tambo-interactable.js +5 -2
- package/dist/hoc/with-tambo-interactable.js.map +1 -1
- package/dist/hoc/with-tambo-interactable.test.js +12 -0
- package/dist/hoc/with-tambo-interactable.test.js.map +1 -1
- package/dist/hooks/use-tambo-voice.test.js +3 -0
- package/dist/hooks/use-tambo-voice.test.js.map +1 -1
- package/dist/mcp/mcp-hooks.test.js +69 -0
- package/dist/mcp/mcp-hooks.test.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.test.js +24 -0
- package/dist/mcp/tambo-mcp-provider.test.js.map +1 -1
- package/dist/mcp/use-mcp-servers.test.js +9 -0
- package/dist/mcp/use-mcp-servers.test.js.map +1 -1
- package/dist/model/component-metadata.d.ts +4 -4
- package/dist/model/component-metadata.js.map +1 -1
- package/dist/providers/__tests__/thread-input-resource-resolution.test.js +2 -2
- package/dist/providers/__tests__/thread-input-resource-resolution.test.js.map +1 -1
- package/dist/providers/tambo-client-provider.d.ts +6 -0
- package/dist/providers/tambo-client-provider.d.ts.map +1 -1
- package/dist/providers/tambo-client-provider.js +4 -1
- package/dist/providers/tambo-client-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/dist/providers/tambo-interactable-provider.js +8 -0
- package/dist/providers/tambo-interactable-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.test.js +47 -0
- package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
- package/dist/providers/tambo-provider.d.ts.map +1 -1
- package/dist/providers/tambo-provider.js +4 -1
- package/dist/providers/tambo-provider.js.map +1 -1
- package/dist/providers/tambo-stubs.d.ts.map +1 -1
- package/dist/providers/tambo-stubs.js +3 -0
- package/dist/providers/tambo-stubs.js.map +1 -1
- package/dist/providers/tambo-thread-provider-initial-messages.test.js +3 -0
- package/dist/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
- package/dist/providers/tambo-thread-provider.test.js +3 -0
- package/dist/providers/tambo-thread-provider.test.js.map +1 -1
- package/dist/util/registry-validators.js +1 -1
- package/dist/util/registry-validators.js.map +1 -1
- package/dist/util/resource-content-resolver.test.js +1 -1
- package/dist/util/resource-content-resolver.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts +11 -0
- package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-auth-state.js +48 -0
- package/dist/v1/hooks/use-tambo-v1-auth-state.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-auth-state.test.d.ts +2 -0
- package/dist/v1/hooks/use-tambo-v1-auth-state.test.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-auth-state.test.js +105 -0
- package/dist/v1/hooks/use-tambo-v1-auth-state.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 +68 -21
- package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js +100 -0
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-messages.test.js +8 -0
- package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +19 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.js +86 -9
- package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js +273 -0
- 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 +2 -2
- package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.js +2 -2
- package/dist/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js +11 -11
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +13 -0
- 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.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.js +4 -0
- package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +6 -0
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.js +4 -0
- package/dist/v1/hooks/use-tambo-v1-thread.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.test.js +6 -0
- package/dist/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.d.ts +11 -0
- package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.js +5 -0
- package/dist/v1/hooks/use-tambo-v1.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.test.js +13 -0
- package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/dist/v1/index.d.ts +4 -1
- package/dist/v1/index.d.ts.map +1 -1
- package/dist/v1/index.js +5 -2
- package/dist/v1/index.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts +16 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.js +42 -5
- package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.test.js +19 -2
- package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.d.ts +6 -0
- package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.js +50 -11
- package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.test.js +9 -0
- 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 +4 -0
- package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +11 -0
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.js +10 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/dist/v1/types/auth.d.ts +24 -0
- package/dist/v1/types/auth.d.ts.map +1 -0
- package/dist/v1/types/auth.js +3 -0
- package/dist/v1/types/auth.js.map +1 -0
- package/dist/v1/types/message.d.ts +12 -0
- package/dist/v1/types/message.d.ts.map +1 -1
- package/dist/v1/types/message.js.map +1 -1
- package/dist/v1/types/tool-choice.d.ts +8 -0
- package/dist/v1/types/tool-choice.d.ts.map +1 -0
- package/dist/v1/types/tool-choice.js +3 -0
- package/dist/v1/types/tool-choice.js.map +1 -0
- package/dist/v1/utils/event-accumulator.d.ts +28 -2
- package/dist/v1/utils/event-accumulator.d.ts.map +1 -1
- package/dist/v1/utils/event-accumulator.js +67 -15
- package/dist/v1/utils/event-accumulator.js.map +1 -1
- package/dist/v1/utils/event-accumulator.test.js +106 -0
- package/dist/v1/utils/event-accumulator.test.js.map +1 -1
- package/dist/v1/utils/keyed-throttle.d.ts +42 -0
- package/dist/v1/utils/keyed-throttle.d.ts.map +1 -0
- package/dist/v1/utils/keyed-throttle.js +86 -0
- package/dist/v1/utils/keyed-throttle.js.map +1 -0
- package/dist/v1/utils/keyed-throttle.test.d.ts +2 -0
- package/dist/v1/utils/keyed-throttle.test.d.ts.map +1 -0
- package/dist/v1/utils/keyed-throttle.test.js +147 -0
- package/dist/v1/utils/keyed-throttle.test.js.map +1 -0
- package/dist/v1/utils/registry-conversion.d.ts.map +1 -1
- package/dist/v1/utils/registry-conversion.js +2 -0
- package/dist/v1/utils/registry-conversion.js.map +1 -1
- package/dist/v1/utils/registry-conversion.test.js +23 -0
- package/dist/v1/utils/registry-conversion.test.js.map +1 -1
- package/dist/v1/utils/tool-call-tracker.d.ts +10 -0
- package/dist/v1/utils/tool-call-tracker.d.ts.map +1 -1
- package/dist/v1/utils/tool-call-tracker.js +13 -0
- package/dist/v1/utils/tool-call-tracker.js.map +1 -1
- package/dist/v1/utils/tool-call-tracker.test.d.ts +2 -0
- package/dist/v1/utils/tool-call-tracker.test.d.ts.map +1 -0
- package/dist/v1/utils/tool-call-tracker.test.js +67 -0
- package/dist/v1/utils/tool-call-tracker.test.js.map +1 -0
- package/dist/v1/utils/tool-executor.d.ts +34 -0
- package/dist/v1/utils/tool-executor.d.ts.map +1 -1
- package/dist/v1/utils/tool-executor.js +55 -0
- package/dist/v1/utils/tool-executor.js.map +1 -1
- package/dist/v1/utils/tool-executor.test.js +211 -0
- package/dist/v1/utils/tool-executor.test.js.map +1 -1
- package/esm/hoc/with-tambo-interactable.d.ts +8 -0
- package/esm/hoc/with-tambo-interactable.d.ts.map +1 -1
- package/esm/hoc/with-tambo-interactable.js +5 -2
- package/esm/hoc/with-tambo-interactable.js.map +1 -1
- package/esm/hoc/with-tambo-interactable.test.js +12 -0
- package/esm/hoc/with-tambo-interactable.test.js.map +1 -1
- package/esm/hooks/use-tambo-voice.test.js +3 -0
- package/esm/hooks/use-tambo-voice.test.js.map +1 -1
- package/esm/mcp/mcp-hooks.test.js +69 -0
- package/esm/mcp/mcp-hooks.test.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.test.js +24 -0
- package/esm/mcp/tambo-mcp-provider.test.js.map +1 -1
- package/esm/mcp/use-mcp-servers.test.js +9 -0
- package/esm/mcp/use-mcp-servers.test.js.map +1 -1
- package/esm/model/component-metadata.d.ts +4 -4
- package/esm/model/component-metadata.js.map +1 -1
- package/esm/providers/__tests__/thread-input-resource-resolution.test.js +2 -2
- package/esm/providers/__tests__/thread-input-resource-resolution.test.js.map +1 -1
- package/esm/providers/tambo-client-provider.d.ts +6 -0
- package/esm/providers/tambo-client-provider.d.ts.map +1 -1
- package/esm/providers/tambo-client-provider.js +4 -1
- package/esm/providers/tambo-client-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/esm/providers/tambo-interactable-provider.js +8 -0
- package/esm/providers/tambo-interactable-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.test.js +47 -0
- package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
- package/esm/providers/tambo-provider.d.ts.map +1 -1
- package/esm/providers/tambo-provider.js +4 -1
- package/esm/providers/tambo-provider.js.map +1 -1
- package/esm/providers/tambo-stubs.d.ts.map +1 -1
- package/esm/providers/tambo-stubs.js +3 -0
- package/esm/providers/tambo-stubs.js.map +1 -1
- package/esm/providers/tambo-thread-provider-initial-messages.test.js +3 -0
- package/esm/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
- package/esm/providers/tambo-thread-provider.test.js +3 -0
- package/esm/providers/tambo-thread-provider.test.js.map +1 -1
- package/esm/util/registry-validators.js +1 -1
- package/esm/util/registry-validators.js.map +1 -1
- package/esm/util/resource-content-resolver.test.js +1 -1
- package/esm/util/resource-content-resolver.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts +11 -0
- package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-auth-state.js +45 -0
- package/esm/v1/hooks/use-tambo-v1-auth-state.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-auth-state.test.d.ts +2 -0
- package/esm/v1/hooks/use-tambo-v1-auth-state.test.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-auth-state.test.js +100 -0
- package/esm/v1/hooks/use-tambo-v1-auth-state.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 +68 -21
- package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js +100 -0
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.test.js +8 -0
- package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +19 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.js +87 -10
- package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js +273 -0
- 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 +2 -2
- package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.js +2 -2
- package/esm/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js +11 -11
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +13 -0
- 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.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.js +4 -0
- package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +6 -0
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.js +4 -0
- package/esm/v1/hooks/use-tambo-v1-thread.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.test.js +6 -0
- package/esm/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.d.ts +11 -0
- package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.js +5 -0
- package/esm/v1/hooks/use-tambo-v1.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.test.js +13 -0
- package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/esm/v1/index.d.ts +4 -1
- package/esm/v1/index.d.ts.map +1 -1
- package/esm/v1/index.js +3 -1
- package/esm/v1/index.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts +16 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.js +43 -6
- package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.test.js +19 -2
- package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.d.ts +6 -0
- package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.js +51 -12
- package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.test.js +9 -0
- package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.js +4 -0
- package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +11 -0
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.js +10 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/esm/v1/types/auth.d.ts +24 -0
- package/esm/v1/types/auth.d.ts.map +1 -0
- package/esm/v1/types/auth.js +2 -0
- package/esm/v1/types/auth.js.map +1 -0
- package/esm/v1/types/message.d.ts +12 -0
- package/esm/v1/types/message.d.ts.map +1 -1
- package/esm/v1/types/message.js.map +1 -1
- package/esm/v1/types/tool-choice.d.ts +8 -0
- package/esm/v1/types/tool-choice.d.ts.map +1 -0
- package/esm/v1/types/tool-choice.js +2 -0
- package/esm/v1/types/tool-choice.js.map +1 -0
- package/esm/v1/utils/event-accumulator.d.ts +28 -2
- package/esm/v1/utils/event-accumulator.d.ts.map +1 -1
- package/esm/v1/utils/event-accumulator.js +66 -15
- package/esm/v1/utils/event-accumulator.js.map +1 -1
- package/esm/v1/utils/event-accumulator.test.js +106 -0
- package/esm/v1/utils/event-accumulator.test.js.map +1 -1
- package/esm/v1/utils/keyed-throttle.d.ts +42 -0
- package/esm/v1/utils/keyed-throttle.d.ts.map +1 -0
- package/esm/v1/utils/keyed-throttle.js +83 -0
- package/esm/v1/utils/keyed-throttle.js.map +1 -0
- package/esm/v1/utils/keyed-throttle.test.d.ts +2 -0
- package/esm/v1/utils/keyed-throttle.test.d.ts.map +1 -0
- package/esm/v1/utils/keyed-throttle.test.js +145 -0
- package/esm/v1/utils/keyed-throttle.test.js.map +1 -0
- package/esm/v1/utils/registry-conversion.d.ts.map +1 -1
- package/esm/v1/utils/registry-conversion.js +2 -0
- package/esm/v1/utils/registry-conversion.js.map +1 -1
- package/esm/v1/utils/registry-conversion.test.js +23 -0
- package/esm/v1/utils/registry-conversion.test.js.map +1 -1
- package/esm/v1/utils/tool-call-tracker.d.ts +10 -0
- package/esm/v1/utils/tool-call-tracker.d.ts.map +1 -1
- package/esm/v1/utils/tool-call-tracker.js +13 -0
- package/esm/v1/utils/tool-call-tracker.js.map +1 -1
- package/esm/v1/utils/tool-call-tracker.test.d.ts +2 -0
- package/esm/v1/utils/tool-call-tracker.test.d.ts.map +1 -0
- package/esm/v1/utils/tool-call-tracker.test.js +65 -0
- package/esm/v1/utils/tool-call-tracker.test.js.map +1 -0
- package/esm/v1/utils/tool-executor.d.ts +34 -0
- package/esm/v1/utils/tool-executor.d.ts.map +1 -1
- package/esm/v1/utils/tool-executor.js +53 -0
- package/esm/v1/utils/tool-executor.js.map +1 -1
- package/esm/v1/utils/tool-executor.test.js +212 -1
- package/esm/v1/utils/tool-executor.test.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-tambo-interactable.js","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { TamboMessageProvider } from \"../hooks/use-current-message\";\nimport { TamboThreadMessage } from \"../model/generate-component-response\";\nimport { useTamboInteractable } from \"../providers/tambo-interactable-provider\";\nimport { SupportedSchema } from \"../schema\";\n\nexport interface InteractableConfig<\n Props = Record<string, unknown>,\n State = Record<string, unknown>,\n> {\n /**\n * The name of the component, used for identification in Tambo.\n */\n componentName: string;\n /**\n * A brief description of the component's purpose and functionality. LLM will\n * use this to understand how to interact with it.\n */\n description: string;\n /**\n * Optional schema for component props. If provided, prop updates will be\n * validated against this schema.\n */\n propsSchema?: SupportedSchema<Props>;\n /**\n * Optional schema for component state. If provided, state updates will be\n * validated against this schema.\n */\n stateSchema?: SupportedSchema<State>;\n}\n\n/**\n * Props injected by withTamboInteractable HOC. These can be passed to the wrapped\n * component to customize interactable behavior.\n */\nexport interface WithTamboInteractableProps {\n /**\n * Optional ID to use for this interactable component instance.\n * If not provided, a unique ID will be generated automatically.\n */\n interactableId?: string;\n /**\n * Callback fired when the component has been registered as interactable.\n * @param id - The assigned interactable component ID\n */\n onInteractableReady?: (id: string) => void;\n /**\n * Callback fired when the component's serializable props are updated by Tambo\n * through a tool call. Note: Only serializable props are tracked.\n * @param newProps - The updated serializable props\n */\n onPropsUpdate?: (newProps: Record<string, unknown>) => void;\n}\n\n/**\n * Higher-Order Component that makes any component interactable by tambo.\n * @param WrappedComponent - The component to make interactable\n * @param config - Configuration for the interactable component\n * @returns A new component that is automatically registered as interactable\n * @example\n * ```tsx\n * const MyNote: React.FC<{ title: string; content: string }> = ({ title, content }) => {\n * const [isPinned, setIsPinned] = useTamboComponentState(\"isPinned\", false);\n * return (\n * <div style={{ border: isPinned ? \"2px solid gold\" : \"1px solid gray\", order: isPinned ? -1 : 0 }}>\n * <h2>{title}</h2>\n * <p>{content}</p>\n * </div>\n * );\n * };\n *\n * const MyInteractableNote = withTamboInteractable(MyNote, {\n * componentName: \"MyNote\",\n * description: \"A note component\",\n * propsSchema: z.object({\n * title: z.string(),\n * content: z.string(),\n * }),\n * stateSchema: z.object({\n * isPinned: z.boolean(),\n * }),\n * });\n *\n * // Usage\n * <MyInteractableNote title=\"My Note\" content=\"This is my note\" />\n * ```\n */\nexport function withTamboInteractable<ComponentProps extends object>(\n WrappedComponent: React.ComponentType<ComponentProps>,\n config: InteractableConfig,\n) {\n const displayName =\n WrappedComponent.displayName ?? WrappedComponent.name ?? \"Component\";\n\n const TamboInteractableWrapper: React.FC<\n ComponentProps & WithTamboInteractableProps\n > = (props) => {\n const {\n addInteractableComponent,\n updateInteractableComponentProps,\n getInteractableComponent,\n } = useTamboInteractable();\n\n const [interactableId, setInteractableId] = useState<string | null>(null);\n const isInitialized = useRef(false);\n const lastSerializedProps = useRef<Record<string, unknown>>({});\n\n // Extract interactable-specific props from component props\n const {\n interactableId: _providedId, // Reserved for future use\n onInteractableReady,\n onPropsUpdate,\n ...componentProps\n } = props;\n\n // Get the current interactable component to track prop updates\n const currentInteractable = interactableId\n ? getInteractableComponent(interactableId)\n : null;\n\n // Use the props from the interactable component if available, otherwise use the passed props\n // We need to be careful not to create a loop, so we only use stored props if they're different from passed props\n const effectiveProps = currentInteractable?.props ?? componentProps;\n\n // Memoize the registration function\n const registerComponent = useCallback(() => {\n if (!isInitialized.current) {\n const id = addInteractableComponent({\n name: config.componentName,\n description: config.description,\n component: WrappedComponent,\n props: componentProps,\n propsSchema: config.propsSchema,\n stateSchema: config.stateSchema,\n });\n\n setInteractableId(id);\n onInteractableReady?.(id);\n isInitialized.current = true;\n }\n }, [addInteractableComponent, componentProps, onInteractableReady]);\n\n // Register the component as interactable on mount (only once)\n useEffect(() => {\n registerComponent();\n }, [registerComponent]);\n\n // Update the interactable component when props change from parent\n useEffect(() => {\n if (interactableId && isInitialized.current) {\n // Only update if the props are different from what we last sent\n const lastPropsString = JSON.stringify(lastSerializedProps.current);\n const currentPropsString = JSON.stringify(componentProps);\n\n if (lastPropsString !== currentPropsString) {\n updateInteractableComponentProps(interactableId, componentProps);\n onPropsUpdate?.(componentProps);\n lastSerializedProps.current = componentProps;\n }\n }\n }, [\n interactableId,\n componentProps,\n updateInteractableComponentProps,\n onPropsUpdate,\n ]);\n\n // If the interactable ID is not yet set, render the component without provider\n if (!interactableId) {\n return <WrappedComponent {...(effectiveProps as ComponentProps)} />;\n }\n\n // Create a minimal message with interactable metadata\n // This allows useTamboCurrentComponent to work with standalone interactable components\n const minimalMessage: TamboThreadMessage = {\n id: interactableId,\n role: \"assistant\" as const,\n content: [],\n threadId: \"\",\n createdAt: new Date().toISOString(),\n component: {\n componentName: config.componentName,\n componentState: {},\n message: \"\",\n props: effectiveProps,\n },\n componentState: {},\n };\n\n // Wrap with TamboMessageProvider including interactable metadata\n return (\n <TamboMessageProvider\n message={minimalMessage}\n interactableMetadata={{\n id: interactableId,\n componentName: config.componentName,\n description: config.description,\n }}\n >\n <WrappedComponent {...(effectiveProps as ComponentProps)} />\n </TamboMessageProvider>\n );\n };\n\n TamboInteractableWrapper.displayName = `withTamboInteractable(${displayName})`;\n\n return TamboInteractableWrapper;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"with-tambo-interactable.js","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { TamboMessageProvider } from \"../hooks/use-current-message\";\nimport type { ToolAnnotations } from \"../model/component-metadata\";\nimport { TamboThreadMessage } from \"../model/generate-component-response\";\nimport { useTamboInteractable } from \"../providers/tambo-interactable-provider\";\nimport { SupportedSchema } from \"../schema\";\nimport { V1ComponentContentProvider } from \"../v1/utils/component-renderer\";\n\nexport interface InteractableConfig<\n Props = Record<string, unknown>,\n State = Record<string, unknown>,\n> {\n /**\n * The name of the component, used for identification in Tambo.\n */\n componentName: string;\n /**\n * A brief description of the component's purpose and functionality. LLM will\n * use this to understand how to interact with it.\n */\n description: string;\n /**\n * Optional schema for component props. If provided, prop updates will be\n * validated against this schema.\n */\n propsSchema?: SupportedSchema<Props>;\n /**\n * Optional schema for component state. If provided, state updates will be\n * validated against this schema.\n */\n stateSchema?: SupportedSchema<State>;\n /**\n * Optional annotations for the interactable component's auto-registered tools\n * (props update and state update). By default, `tamboStreamableHint` is `true`\n * so props/state updates stream in real-time. Set `{ tamboStreamableHint: false }`\n * to disable streaming for this component's tools.\n */\n annotations?: ToolAnnotations;\n}\n\n/**\n * Props injected by withTamboInteractable HOC. These can be passed to the wrapped\n * component to customize interactable behavior.\n */\nexport interface WithTamboInteractableProps {\n /**\n * Optional ID to use for this interactable component instance.\n * If not provided, a unique ID will be generated automatically.\n */\n interactableId?: string;\n /**\n * Callback fired when the component has been registered as interactable.\n * @param id - The assigned interactable component ID\n */\n onInteractableReady?: (id: string) => void;\n /**\n * Callback fired when the component's serializable props are updated by Tambo\n * through a tool call. Note: Only serializable props are tracked.\n * @param newProps - The updated serializable props\n */\n onPropsUpdate?: (newProps: Record<string, unknown>) => void;\n}\n\n/**\n * Higher-Order Component that makes any component interactable by tambo.\n * @param WrappedComponent - The component to make interactable\n * @param config - Configuration for the interactable component\n * @returns A new component that is automatically registered as interactable\n * @example\n * ```tsx\n * const MyNote: React.FC<{ title: string; content: string }> = ({ title, content }) => {\n * const [isPinned, setIsPinned] = useTamboComponentState(\"isPinned\", false);\n * return (\n * <div style={{ border: isPinned ? \"2px solid gold\" : \"1px solid gray\", order: isPinned ? -1 : 0 }}>\n * <h2>{title}</h2>\n * <p>{content}</p>\n * </div>\n * );\n * };\n *\n * const MyInteractableNote = withTamboInteractable(MyNote, {\n * componentName: \"MyNote\",\n * description: \"A note component\",\n * propsSchema: z.object({\n * title: z.string(),\n * content: z.string(),\n * }),\n * stateSchema: z.object({\n * isPinned: z.boolean(),\n * }),\n * });\n *\n * // Usage\n * <MyInteractableNote title=\"My Note\" content=\"This is my note\" />\n * ```\n */\nexport function withTamboInteractable<ComponentProps extends object>(\n WrappedComponent: React.ComponentType<ComponentProps>,\n config: InteractableConfig,\n) {\n const displayName =\n WrappedComponent.displayName ?? WrappedComponent.name ?? \"Component\";\n\n const TamboInteractableWrapper: React.FC<\n ComponentProps & WithTamboInteractableProps\n > = (props) => {\n const {\n addInteractableComponent,\n updateInteractableComponentProps,\n getInteractableComponent,\n } = useTamboInteractable();\n\n const [interactableId, setInteractableId] = useState<string | null>(null);\n const isInitialized = useRef(false);\n const lastSerializedProps = useRef<Record<string, unknown>>({});\n\n // Extract interactable-specific props from component props\n const {\n interactableId: _providedId, // Reserved for future use\n onInteractableReady,\n onPropsUpdate,\n ...componentProps\n } = props;\n\n // Get the current interactable component to track prop updates\n const currentInteractable = interactableId\n ? getInteractableComponent(interactableId)\n : null;\n\n // Use the props from the interactable component if available, otherwise use the passed props\n // We need to be careful not to create a loop, so we only use stored props if they're different from passed props\n const effectiveProps = currentInteractable?.props ?? componentProps;\n\n // Memoize the registration function\n const registerComponent = useCallback(() => {\n if (!isInitialized.current) {\n const id = addInteractableComponent({\n name: config.componentName,\n description: config.description,\n component: WrappedComponent,\n props: componentProps,\n propsSchema: config.propsSchema,\n stateSchema: config.stateSchema,\n annotations: config.annotations,\n });\n\n setInteractableId(id);\n onInteractableReady?.(id);\n isInitialized.current = true;\n }\n }, [addInteractableComponent, componentProps, onInteractableReady]);\n\n // Register the component as interactable on mount (only once)\n useEffect(() => {\n registerComponent();\n }, [registerComponent]);\n\n // Update the interactable component when props change from parent\n useEffect(() => {\n if (interactableId && isInitialized.current) {\n // Only update if the props are different from what we last sent\n const lastPropsString = JSON.stringify(lastSerializedProps.current);\n const currentPropsString = JSON.stringify(componentProps);\n\n if (lastPropsString !== currentPropsString) {\n updateInteractableComponentProps(interactableId, componentProps);\n onPropsUpdate?.(componentProps);\n lastSerializedProps.current = componentProps;\n }\n }\n }, [\n interactableId,\n componentProps,\n updateInteractableComponentProps,\n onPropsUpdate,\n ]);\n\n // If the interactable ID is not yet set, render the component without provider\n if (!interactableId) {\n return <WrappedComponent {...(effectiveProps as ComponentProps)} />;\n }\n\n // Create a minimal message with interactable metadata\n // This allows useTamboCurrentComponent to work with standalone interactable components\n const minimalMessage: TamboThreadMessage = {\n id: interactableId,\n role: \"assistant\" as const,\n content: [],\n threadId: \"\",\n createdAt: new Date().toISOString(),\n component: {\n componentName: config.componentName,\n componentState: {},\n message: \"\",\n props: effectiveProps,\n },\n componentState: {},\n };\n\n // Wrap with TamboMessageProvider and V1ComponentContentProvider including interactable metadata\n return (\n <TamboMessageProvider\n message={minimalMessage}\n interactableMetadata={{\n id: interactableId,\n componentName: config.componentName,\n description: config.description,\n }}\n >\n <V1ComponentContentProvider\n componentId={interactableId}\n threadId=\"\"\n messageId=\"\"\n componentName={config.componentName}\n >\n <WrappedComponent {...(effectiveProps as ComponentProps)} />\n </V1ComponentContentProvider>\n </TamboMessageProvider>\n );\n };\n\n TamboInteractableWrapper.displayName = `withTamboInteractable(${displayName})`;\n\n return TamboInteractableWrapper;\n}\n"]}
|
|
@@ -154,6 +154,18 @@ describe("withTamboInteractable", () => {
|
|
|
154
154
|
expect(react_1.screen.getByTestId("has-ready")).toHaveTextContent("no");
|
|
155
155
|
expect(react_1.screen.getByTestId("has-update")).toHaveTextContent("no");
|
|
156
156
|
});
|
|
157
|
+
it("should pass annotations config to addInteractableComponent", () => {
|
|
158
|
+
const InteractableComponent = (0, with_tambo_interactable_1.withTamboInteractable)(TestComponent, {
|
|
159
|
+
componentName: "TestComponent",
|
|
160
|
+
description: "A test component",
|
|
161
|
+
annotations: { tamboStreamableHint: false },
|
|
162
|
+
});
|
|
163
|
+
(0, react_1.render)(react_2.default.createElement(tambo_interactable_provider_1.TamboInteractableProvider, null,
|
|
164
|
+
react_2.default.createElement(InteractableComponent, { title: "Test" })));
|
|
165
|
+
expect(mockAddInteractableComponent).toHaveBeenCalledWith(expect.objectContaining({
|
|
166
|
+
annotations: { tamboStreamableHint: false },
|
|
167
|
+
}));
|
|
168
|
+
});
|
|
157
169
|
it("should work without propsSchema", () => {
|
|
158
170
|
const InteractableComponent = (0, with_tambo_interactable_1.withTamboInteractable)(TestComponent, {
|
|
159
171
|
componentName: "TestComponent",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-tambo-interactable.test.js","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { render, screen, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod/v3\";\nimport { useTamboCurrentComponent } from \"../hooks/use-current-message\";\nimport { TamboInteractableProvider } from \"../providers/tambo-interactable-provider\";\nimport { withTamboInteractable } from \"./with-tambo-interactable\";\n\n// Create a consistent mock implementation\nconst mockAddInteractableComponent = jest.fn(() => \"mock-id-123\");\nconst mockUpdateInteractableComponentProps = jest.fn();\nconst mockGetInteractableComponent = jest.fn(() => null);\nconst mockRemoveInteractableComponent = jest.fn();\nconst mockGetInteractableComponentsByName = jest.fn(() => []);\nconst mockClearAllInteractableComponents = jest.fn();\n\n// Mock the interactable provider\njest.mock(\"../providers/tambo-interactable-provider\", () => ({\n TamboInteractableProvider: ({ children }: { children: React.ReactNode }) => (\n <div data-testid=\"interactable-provider\">{children}</div>\n ),\n useTamboInteractable: () => ({\n addInteractableComponent: mockAddInteractableComponent,\n updateInteractableComponentProps: mockUpdateInteractableComponentProps,\n getInteractableComponent: mockGetInteractableComponent,\n removeInteractableComponent: mockRemoveInteractableComponent,\n getInteractableComponentsByName: mockGetInteractableComponentsByName,\n clearAllInteractableComponents: mockClearAllInteractableComponents,\n interactableComponents: [],\n }),\n}));\n\ndescribe(\"withTamboInteractable\", () => {\n // Simple test component\n interface TestComponentProps {\n title: string;\n count?: number;\n }\n\n const TestComponent: React.FC<TestComponentProps> = ({ title, count }) => (\n <div>\n <h1 data-testid=\"title\">{title}</h1>\n {count !== undefined && <span data-testid=\"count\">{count}</span>}\n </div>\n );\n\n const testSchema = z.object({\n title: z.string(),\n count: z.number().optional(),\n });\n\n beforeEach(() => {\n jest.clearAllMocks();\n // Reset mock implementations\n mockAddInteractableComponent.mockReturnValue(\"mock-id-123\");\n mockGetInteractableComponent.mockReturnValue(null);\n mockGetInteractableComponentsByName.mockReturnValue([]);\n });\n\n it(\"should render the wrapped component with provided props\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Hello\" count={42} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Hello\");\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"42\");\n });\n\n it(\"should set displayName correctly\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n expect(InteractableComponent.displayName).toBe(\n \"withTamboInteractable(TestComponent)\",\n );\n });\n\n it(\"should handle components without displayName\", () => {\n const AnonymousComponent = () => <div>Anonymous</div>;\n\n const InteractableComponent = withTamboInteractable(AnonymousComponent, {\n componentName: \"AnonymousComponent\",\n description: \"An anonymous component\",\n });\n\n // Anonymous components get their name from the function name\n expect(InteractableComponent.displayName).toBe(\n \"withTamboInteractable(AnonymousComponent)\",\n );\n });\n\n it(\"should provide TamboMessageProvider with interactable metadata\", async () => {\n // Child component that uses the context\n const ContextConsumer = () => {\n const component = useTamboCurrentComponent();\n return (\n <div>\n <span data-testid=\"interactable-id\">{component?.interactableId}</span>\n <span data-testid=\"component-name\">{component?.componentName}</span>\n <span data-testid=\"description\">{component?.description}</span>\n </div>\n );\n };\n\n // Wrap TestComponent to include ContextConsumer\n const TestComponentWithConsumer: React.FC<TestComponentProps> = (props) => (\n <div>\n <TestComponent {...props} />\n <ContextConsumer />\n </div>\n );\n\n const InteractableWithConsumer = withTamboInteractable(\n TestComponentWithConsumer,\n {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n },\n );\n\n render(\n <TamboInteractableProvider>\n <InteractableWithConsumer title=\"Hello\" />\n </TamboInteractableProvider>,\n );\n\n // Wait for the component to register and render\n await waitFor(() => {\n expect(screen.getByTestId(\"interactable-id\")).toHaveTextContent(\n \"mock-id-123\",\n );\n });\n\n expect(screen.getByTestId(\"component-name\")).toHaveTextContent(\n \"TestComponent\",\n );\n expect(screen.getByTestId(\"description\")).toHaveTextContent(\n \"A test component\",\n );\n });\n\n it(\"should create minimal message with correct structure\", async () => {\n // Child component that checks the message structure\n const MessageChecker = () => {\n const component = useTamboCurrentComponent();\n return (\n <div>\n <span data-testid=\"has-component-name\">\n {component?.componentName ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-props\">{component?.props ? \"yes\" : \"no\"}</span>\n <span data-testid=\"has-interactable-id\">\n {component?.interactableId ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-description\">\n {component?.description ? \"yes\" : \"no\"}\n </span>\n </div>\n );\n };\n\n const TestComponentWithChecker: React.FC<TestComponentProps> = (props) => (\n <div>\n <TestComponent {...props} />\n <MessageChecker />\n </div>\n );\n\n const InteractableWithChecker = withTamboInteractable(\n TestComponentWithChecker,\n {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n },\n );\n\n render(\n <TamboInteractableProvider>\n <InteractableWithChecker title=\"Hello\" count={42} />\n </TamboInteractableProvider>,\n );\n\n await waitFor(() => {\n expect(screen.getByTestId(\"has-component-name\")).toHaveTextContent(\"yes\");\n });\n\n expect(screen.getByTestId(\"has-props\")).toHaveTextContent(\"yes\");\n expect(screen.getByTestId(\"has-interactable-id\")).toHaveTextContent(\"yes\");\n expect(screen.getByTestId(\"has-description\")).toHaveTextContent(\"yes\");\n });\n\n it(\"should pass through all component props correctly\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test Title\" count={100} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test Title\");\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"100\");\n });\n\n it(\"should filter out interactable-specific props from component props\", () => {\n interface ExtendedProps extends TestComponentProps {\n onInteractableReady?: (id: string) => void;\n onPropsUpdate?: (props: Record<string, any>) => void;\n }\n\n const ExtendedComponent: React.FC<ExtendedProps> = ({\n title,\n onInteractableReady,\n onPropsUpdate,\n }) => (\n <div>\n <span data-testid=\"title\">{title}</span>\n <span data-testid=\"has-ready\">\n {onInteractableReady ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-update\">{onPropsUpdate ? \"yes\" : \"no\"}</span>\n </div>\n );\n\n const InteractableComponent = withTamboInteractable(ExtendedComponent, {\n componentName: \"ExtendedComponent\",\n description: \"An extended component\",\n });\n\n const mockReady = jest.fn();\n const mockUpdate = jest.fn();\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent\n title=\"Test\"\n onInteractableReady={mockReady}\n onPropsUpdate={mockUpdate}\n />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test\");\n // These props should be filtered out\n expect(screen.getByTestId(\"has-ready\")).toHaveTextContent(\"no\");\n expect(screen.getByTestId(\"has-update\")).toHaveTextContent(\"no\");\n });\n\n it(\"should work without propsSchema\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"No Schema\" />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"No Schema\");\n });\n\n it(\"should render before interactable ID is set\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n const { container } = render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Early Render\" />\n </TamboInteractableProvider>,\n );\n\n // Component should render even before ID is available\n expect(\n container.querySelector('[data-testid=\"title\"]'),\n ).toBeInTheDocument();\n });\n\n it(\"should handle null/undefined values in props\", () => {\n interface NullableProps {\n title: string;\n optional?: string;\n nullable: string | null;\n }\n\n const NullableComponent: React.FC<NullableProps> = ({\n title,\n optional,\n nullable,\n }) => (\n <div>\n <span data-testid=\"title\">{title}</span>\n <span data-testid=\"optional\">{optional ?? \"undefined\"}</span>\n <span data-testid=\"nullable\">{nullable ?? \"null\"}</span>\n </div>\n );\n\n const InteractableComponent = withTamboInteractable(NullableComponent, {\n componentName: \"NullableComponent\",\n description: \"A component with nullable props\",\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test\" nullable={null} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test\");\n expect(screen.getByTestId(\"optional\")).toHaveTextContent(\"undefined\");\n expect(screen.getByTestId(\"nullable\")).toHaveTextContent(\"null\");\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"with-tambo-interactable.test.js","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { render, screen, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod/v3\";\nimport { useTamboCurrentComponent } from \"../hooks/use-current-message\";\nimport { TamboInteractableProvider } from \"../providers/tambo-interactable-provider\";\nimport { withTamboInteractable } from \"./with-tambo-interactable\";\n\n// Create a consistent mock implementation\nconst mockAddInteractableComponent = jest.fn(() => \"mock-id-123\");\nconst mockUpdateInteractableComponentProps = jest.fn();\nconst mockGetInteractableComponent = jest.fn(() => null);\nconst mockRemoveInteractableComponent = jest.fn();\nconst mockGetInteractableComponentsByName = jest.fn(() => []);\nconst mockClearAllInteractableComponents = jest.fn();\n\n// Mock the interactable provider\njest.mock(\"../providers/tambo-interactable-provider\", () => ({\n TamboInteractableProvider: ({ children }: { children: React.ReactNode }) => (\n <div data-testid=\"interactable-provider\">{children}</div>\n ),\n useTamboInteractable: () => ({\n addInteractableComponent: mockAddInteractableComponent,\n updateInteractableComponentProps: mockUpdateInteractableComponentProps,\n getInteractableComponent: mockGetInteractableComponent,\n removeInteractableComponent: mockRemoveInteractableComponent,\n getInteractableComponentsByName: mockGetInteractableComponentsByName,\n clearAllInteractableComponents: mockClearAllInteractableComponents,\n interactableComponents: [],\n }),\n}));\n\ndescribe(\"withTamboInteractable\", () => {\n // Simple test component\n interface TestComponentProps {\n title: string;\n count?: number;\n }\n\n const TestComponent: React.FC<TestComponentProps> = ({ title, count }) => (\n <div>\n <h1 data-testid=\"title\">{title}</h1>\n {count !== undefined && <span data-testid=\"count\">{count}</span>}\n </div>\n );\n\n const testSchema = z.object({\n title: z.string(),\n count: z.number().optional(),\n });\n\n beforeEach(() => {\n jest.clearAllMocks();\n // Reset mock implementations\n mockAddInteractableComponent.mockReturnValue(\"mock-id-123\");\n mockGetInteractableComponent.mockReturnValue(null);\n mockGetInteractableComponentsByName.mockReturnValue([]);\n });\n\n it(\"should render the wrapped component with provided props\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Hello\" count={42} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Hello\");\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"42\");\n });\n\n it(\"should set displayName correctly\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n expect(InteractableComponent.displayName).toBe(\n \"withTamboInteractable(TestComponent)\",\n );\n });\n\n it(\"should handle components without displayName\", () => {\n const AnonymousComponent = () => <div>Anonymous</div>;\n\n const InteractableComponent = withTamboInteractable(AnonymousComponent, {\n componentName: \"AnonymousComponent\",\n description: \"An anonymous component\",\n });\n\n // Anonymous components get their name from the function name\n expect(InteractableComponent.displayName).toBe(\n \"withTamboInteractable(AnonymousComponent)\",\n );\n });\n\n it(\"should provide TamboMessageProvider with interactable metadata\", async () => {\n // Child component that uses the context\n const ContextConsumer = () => {\n const component = useTamboCurrentComponent();\n return (\n <div>\n <span data-testid=\"interactable-id\">{component?.interactableId}</span>\n <span data-testid=\"component-name\">{component?.componentName}</span>\n <span data-testid=\"description\">{component?.description}</span>\n </div>\n );\n };\n\n // Wrap TestComponent to include ContextConsumer\n const TestComponentWithConsumer: React.FC<TestComponentProps> = (props) => (\n <div>\n <TestComponent {...props} />\n <ContextConsumer />\n </div>\n );\n\n const InteractableWithConsumer = withTamboInteractable(\n TestComponentWithConsumer,\n {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n },\n );\n\n render(\n <TamboInteractableProvider>\n <InteractableWithConsumer title=\"Hello\" />\n </TamboInteractableProvider>,\n );\n\n // Wait for the component to register and render\n await waitFor(() => {\n expect(screen.getByTestId(\"interactable-id\")).toHaveTextContent(\n \"mock-id-123\",\n );\n });\n\n expect(screen.getByTestId(\"component-name\")).toHaveTextContent(\n \"TestComponent\",\n );\n expect(screen.getByTestId(\"description\")).toHaveTextContent(\n \"A test component\",\n );\n });\n\n it(\"should create minimal message with correct structure\", async () => {\n // Child component that checks the message structure\n const MessageChecker = () => {\n const component = useTamboCurrentComponent();\n return (\n <div>\n <span data-testid=\"has-component-name\">\n {component?.componentName ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-props\">{component?.props ? \"yes\" : \"no\"}</span>\n <span data-testid=\"has-interactable-id\">\n {component?.interactableId ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-description\">\n {component?.description ? \"yes\" : \"no\"}\n </span>\n </div>\n );\n };\n\n const TestComponentWithChecker: React.FC<TestComponentProps> = (props) => (\n <div>\n <TestComponent {...props} />\n <MessageChecker />\n </div>\n );\n\n const InteractableWithChecker = withTamboInteractable(\n TestComponentWithChecker,\n {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n },\n );\n\n render(\n <TamboInteractableProvider>\n <InteractableWithChecker title=\"Hello\" count={42} />\n </TamboInteractableProvider>,\n );\n\n await waitFor(() => {\n expect(screen.getByTestId(\"has-component-name\")).toHaveTextContent(\"yes\");\n });\n\n expect(screen.getByTestId(\"has-props\")).toHaveTextContent(\"yes\");\n expect(screen.getByTestId(\"has-interactable-id\")).toHaveTextContent(\"yes\");\n expect(screen.getByTestId(\"has-description\")).toHaveTextContent(\"yes\");\n });\n\n it(\"should pass through all component props correctly\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test Title\" count={100} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test Title\");\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"100\");\n });\n\n it(\"should filter out interactable-specific props from component props\", () => {\n interface ExtendedProps extends TestComponentProps {\n onInteractableReady?: (id: string) => void;\n onPropsUpdate?: (props: Record<string, any>) => void;\n }\n\n const ExtendedComponent: React.FC<ExtendedProps> = ({\n title,\n onInteractableReady,\n onPropsUpdate,\n }) => (\n <div>\n <span data-testid=\"title\">{title}</span>\n <span data-testid=\"has-ready\">\n {onInteractableReady ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-update\">{onPropsUpdate ? \"yes\" : \"no\"}</span>\n </div>\n );\n\n const InteractableComponent = withTamboInteractable(ExtendedComponent, {\n componentName: \"ExtendedComponent\",\n description: \"An extended component\",\n });\n\n const mockReady = jest.fn();\n const mockUpdate = jest.fn();\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent\n title=\"Test\"\n onInteractableReady={mockReady}\n onPropsUpdate={mockUpdate}\n />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test\");\n // These props should be filtered out\n expect(screen.getByTestId(\"has-ready\")).toHaveTextContent(\"no\");\n expect(screen.getByTestId(\"has-update\")).toHaveTextContent(\"no\");\n });\n\n it(\"should pass annotations config to addInteractableComponent\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n annotations: { tamboStreamableHint: false },\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test\" />\n </TamboInteractableProvider>,\n );\n\n expect(mockAddInteractableComponent).toHaveBeenCalledWith(\n expect.objectContaining({\n annotations: { tamboStreamableHint: false },\n }),\n );\n });\n\n it(\"should work without propsSchema\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"No Schema\" />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"No Schema\");\n });\n\n it(\"should render before interactable ID is set\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n const { container } = render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Early Render\" />\n </TamboInteractableProvider>,\n );\n\n // Component should render even before ID is available\n expect(\n container.querySelector('[data-testid=\"title\"]'),\n ).toBeInTheDocument();\n });\n\n it(\"should handle null/undefined values in props\", () => {\n interface NullableProps {\n title: string;\n optional?: string;\n nullable: string | null;\n }\n\n const NullableComponent: React.FC<NullableProps> = ({\n title,\n optional,\n nullable,\n }) => (\n <div>\n <span data-testid=\"title\">{title}</span>\n <span data-testid=\"optional\">{optional ?? \"undefined\"}</span>\n <span data-testid=\"nullable\">{nullable ?? \"null\"}</span>\n </div>\n );\n\n const InteractableComponent = withTamboInteractable(NullableComponent, {\n componentName: \"NullableComponent\",\n description: \"A component with nullable props\",\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test\" nullable={null} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test\");\n expect(screen.getByTestId(\"optional\")).toHaveTextContent(\"undefined\");\n expect(screen.getByTestId(\"nullable\")).toHaveTextContent(\"null\");\n });\n});\n"]}
|
|
@@ -39,6 +39,9 @@ describe("useTamboVoice", () => {
|
|
|
39
39
|
client: mockClient,
|
|
40
40
|
queryClient,
|
|
41
41
|
isUpdatingToken: false,
|
|
42
|
+
tokenExchangeError: null,
|
|
43
|
+
userToken: undefined,
|
|
44
|
+
hasValidToken: false,
|
|
42
45
|
} },
|
|
43
46
|
react_2.default.createElement(react_query_1.QueryClientProvider, { client: queryClient }, children)));
|
|
44
47
|
Wrapper.displayName = "TestWrapper";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-voice.test.js","sourceRoot":"","sources":["../../src/hooks/use-tambo-voice.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { act, renderHook, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { useReactMediaRecorder } from \"react-media-recorder\";\nimport { useTamboVoice } from \"./use-tambo-voice\";\nimport { TamboClientContext } from \"../providers/tambo-client-provider\";\nimport TamboAI from \"@tambo-ai/typescript-sdk\";\n\n// Override the global mock from setupTests.ts with a controllable version\njest.mock(\"react-media-recorder\", () => ({\n useReactMediaRecorder: jest.fn(),\n}));\n\n// Mock the client provider\njest.mock(\"../providers/tambo-client-provider\", () => ({\n ...jest.requireActual(\"../providers/tambo-client-provider\"),\n useTamboClient: jest.fn(),\n}));\n\nimport { useTamboClient } from \"../providers/tambo-client-provider\";\n\n// Mock fetch globally\nconst mockFetch = jest.fn();\n\ndescribe(\"useTamboVoice\", () => {\n let previousFetch: typeof fetch;\n let mockStartRecording: jest.Mock;\n let mockStopRecording: jest.Mock;\n let mockTranscribe: jest.Mock;\n let queryClient: QueryClient;\n\n type MediaRecorderMockValue = Pick<\n ReturnType<typeof useReactMediaRecorder>,\n \"status\" | \"startRecording\" | \"stopRecording\" | \"mediaBlobUrl\" | \"error\"\n >;\n\n const createWrapper = () => {\n const mockClient = {\n beta: {\n audio: {\n transcribe: mockTranscribe,\n },\n },\n } as unknown as TamboAI;\n\n const Wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboClientContext.Provider\n value={{\n client: mockClient,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <QueryClientProvider client={queryClient}>\n {children}\n </QueryClientProvider>\n </TamboClientContext.Provider>\n );\n Wrapper.displayName = \"TestWrapper\";\n return Wrapper;\n };\n\n const setupMediaRecorderMock = (\n overrides: Partial<MediaRecorderMockValue> = {},\n ) => {\n const value: MediaRecorderMockValue = {\n status: \"idle\",\n startRecording: mockStartRecording,\n stopRecording: mockStopRecording,\n mediaBlobUrl: undefined,\n error: \"\",\n ...overrides,\n };\n jest\n .mocked(useReactMediaRecorder)\n .mockReturnValue(\n value as unknown as ReturnType<typeof useReactMediaRecorder>,\n );\n return value;\n };\n\n beforeEach(() => {\n jest.clearAllMocks();\n\n mockFetch.mockReset();\n\n previousFetch = global.fetch;\n global.fetch = mockFetch as unknown as typeof fetch;\n\n mockStartRecording = jest.fn();\n mockStopRecording = jest.fn();\n mockTranscribe = jest.fn();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n // Setup default client mock\n const mockClient = {\n beta: {\n audio: {\n transcribe: mockTranscribe,\n },\n },\n };\n jest\n .mocked(useTamboClient)\n .mockReturnValue(mockClient as unknown as TamboAI);\n\n // Setup default media recorder mock\n setupMediaRecorderMock();\n\n // Setup default fetch mock\n mockFetch.mockResolvedValue({\n blob: async () =>\n await Promise.resolve(new Blob([\"audio data\"], { type: \"audio/webm\" })),\n });\n });\n\n afterEach(() => {\n global.fetch = previousFetch;\n });\n\n describe(\"Initial State\", () => {\n it(\"should initialize with idle state and no transcript\", () => {\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.isRecording).toBe(false);\n expect(result.current.isTranscribing).toBe(false);\n expect(result.current.transcript).toBeNull();\n expect(result.current.transcriptionError).toBeNull();\n expect(result.current.mediaAccessError).toBeNull();\n });\n });\n\n describe(\"Recording Flow\", () => {\n it(\"should expose isRecording=true during active recording\", () => {\n setupMediaRecorderMock({ status: \"recording\" });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.isRecording).toBe(true);\n });\n\n it(\"should call startRecording on the media recorder\", () => {\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n act(() => {\n result.current.startRecording();\n });\n\n expect(mockStartRecording).toHaveBeenCalled();\n });\n\n it(\"should call stopRecording on the media recorder when recording\", () => {\n setupMediaRecorderMock({ status: \"recording\" });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n act(() => {\n result.current.stopRecording();\n });\n\n expect(mockStopRecording).toHaveBeenCalled();\n });\n\n it(\"should reset transcript when starting a new recording\", async () => {\n mockTranscribe.mockResolvedValue(\"first transcript\");\n\n // Start with completed transcription\n setupMediaRecorderMock({\n status: \"stopped\",\n mediaBlobUrl: \"blob:http://localhost/audio1\",\n });\n\n const { result, rerender } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n // Wait for transcription to complete\n await waitFor(() => {\n expect(result.current.transcript).toBe(\"first transcript\");\n });\n\n // Now simulate starting a new recording\n setupMediaRecorderMock({ status: \"idle\" });\n rerender();\n\n act(() => {\n result.current.startRecording();\n });\n\n expect(result.current.transcript).toBeNull();\n });\n });\n\n describe(\"Transcription\", () => {\n it(\"should trigger transcription after recording stops with blob URL\", async () => {\n mockTranscribe.mockResolvedValue(\"Hello world\");\n\n setupMediaRecorderMock({\n status: \"stopped\",\n mediaBlobUrl: \"blob:http://localhost/audio\",\n });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.transcript).toBe(\"Hello world\");\n });\n\n expect(mockFetch).toHaveBeenCalledWith(\"blob:http://localhost/audio\");\n expect(mockTranscribe).toHaveBeenCalled();\n });\n\n it(\"should expose isTranscribing=true during API call\", async () => {\n let resolveTranscription: (value: string) => void;\n mockTranscribe.mockImplementation(\n async () =>\n await new Promise((resolve) => {\n resolveTranscription = resolve;\n }),\n );\n\n setupMediaRecorderMock({\n status: \"stopped\",\n mediaBlobUrl: \"blob:http://localhost/audio\",\n });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.isTranscribing).toBe(true);\n });\n\n // Complete the transcription\n act(() => {\n resolveTranscription!(\"transcribed text\");\n });\n\n await waitFor(() => {\n expect(result.current.isTranscribing).toBe(false);\n });\n });\n });\n\n describe(\"Error Handling\", () => {\n it(\"should expose mediaAccessError when microphone access fails\", () => {\n setupMediaRecorderMock({\n error: \"Permission denied\",\n });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.mediaAccessError).toBe(\"Permission denied\");\n });\n\n it(\"should expose transcriptionError when API call fails\", async () => {\n mockTranscribe.mockRejectedValue(\n new Error(\"Transcription service unavailable\"),\n );\n\n setupMediaRecorderMock({\n status: \"stopped\",\n mediaBlobUrl: \"blob:http://localhost/audio\",\n });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.transcriptionError).toBe(\n \"Transcription service unavailable\",\n );\n });\n\n expect(result.current.isTranscribing).toBe(false);\n });\n\n it(\"should handle blob fetch failure gracefully\", async () => {\n mockFetch.mockRejectedValue(new Error(\"Network error\"));\n\n setupMediaRecorderMock({\n status: \"stopped\",\n mediaBlobUrl: \"blob:http://localhost/audio\",\n });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.transcriptionError).toBe(\"Network error\");\n });\n\n expect(result.current.isTranscribing).toBe(false);\n expect(result.current.transcript).toBeNull();\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"use-tambo-voice.test.js","sourceRoot":"","sources":["../../src/hooks/use-tambo-voice.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { act, renderHook, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { useReactMediaRecorder } from \"react-media-recorder\";\nimport { useTamboVoice } from \"./use-tambo-voice\";\nimport { TamboClientContext } from \"../providers/tambo-client-provider\";\nimport TamboAI from \"@tambo-ai/typescript-sdk\";\n\n// Override the global mock from setupTests.ts with a controllable version\njest.mock(\"react-media-recorder\", () => ({\n useReactMediaRecorder: jest.fn(),\n}));\n\n// Mock the client provider\njest.mock(\"../providers/tambo-client-provider\", () => ({\n ...jest.requireActual(\"../providers/tambo-client-provider\"),\n useTamboClient: jest.fn(),\n}));\n\nimport { useTamboClient } from \"../providers/tambo-client-provider\";\n\n// Mock fetch globally\nconst mockFetch = jest.fn();\n\ndescribe(\"useTamboVoice\", () => {\n let previousFetch: typeof fetch;\n let mockStartRecording: jest.Mock;\n let mockStopRecording: jest.Mock;\n let mockTranscribe: jest.Mock;\n let queryClient: QueryClient;\n\n type MediaRecorderMockValue = Pick<\n ReturnType<typeof useReactMediaRecorder>,\n \"status\" | \"startRecording\" | \"stopRecording\" | \"mediaBlobUrl\" | \"error\"\n >;\n\n const createWrapper = () => {\n const mockClient = {\n beta: {\n audio: {\n transcribe: mockTranscribe,\n },\n },\n } as unknown as TamboAI;\n\n const Wrapper = ({ children }: { children: React.ReactNode }) => (\n <TamboClientContext.Provider\n value={{\n client: mockClient,\n queryClient,\n isUpdatingToken: false,\n tokenExchangeError: null,\n userToken: undefined,\n hasValidToken: false,\n }}\n >\n <QueryClientProvider client={queryClient}>\n {children}\n </QueryClientProvider>\n </TamboClientContext.Provider>\n );\n Wrapper.displayName = \"TestWrapper\";\n return Wrapper;\n };\n\n const setupMediaRecorderMock = (\n overrides: Partial<MediaRecorderMockValue> = {},\n ) => {\n const value: MediaRecorderMockValue = {\n status: \"idle\",\n startRecording: mockStartRecording,\n stopRecording: mockStopRecording,\n mediaBlobUrl: undefined,\n error: \"\",\n ...overrides,\n };\n jest\n .mocked(useReactMediaRecorder)\n .mockReturnValue(\n value as unknown as ReturnType<typeof useReactMediaRecorder>,\n );\n return value;\n };\n\n beforeEach(() => {\n jest.clearAllMocks();\n\n mockFetch.mockReset();\n\n previousFetch = global.fetch;\n global.fetch = mockFetch as unknown as typeof fetch;\n\n mockStartRecording = jest.fn();\n mockStopRecording = jest.fn();\n mockTranscribe = jest.fn();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: { retry: false },\n mutations: { retry: false },\n },\n });\n\n // Setup default client mock\n const mockClient = {\n beta: {\n audio: {\n transcribe: mockTranscribe,\n },\n },\n };\n jest\n .mocked(useTamboClient)\n .mockReturnValue(mockClient as unknown as TamboAI);\n\n // Setup default media recorder mock\n setupMediaRecorderMock();\n\n // Setup default fetch mock\n mockFetch.mockResolvedValue({\n blob: async () =>\n await Promise.resolve(new Blob([\"audio data\"], { type: \"audio/webm\" })),\n });\n });\n\n afterEach(() => {\n global.fetch = previousFetch;\n });\n\n describe(\"Initial State\", () => {\n it(\"should initialize with idle state and no transcript\", () => {\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.isRecording).toBe(false);\n expect(result.current.isTranscribing).toBe(false);\n expect(result.current.transcript).toBeNull();\n expect(result.current.transcriptionError).toBeNull();\n expect(result.current.mediaAccessError).toBeNull();\n });\n });\n\n describe(\"Recording Flow\", () => {\n it(\"should expose isRecording=true during active recording\", () => {\n setupMediaRecorderMock({ status: \"recording\" });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.isRecording).toBe(true);\n });\n\n it(\"should call startRecording on the media recorder\", () => {\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n act(() => {\n result.current.startRecording();\n });\n\n expect(mockStartRecording).toHaveBeenCalled();\n });\n\n it(\"should call stopRecording on the media recorder when recording\", () => {\n setupMediaRecorderMock({ status: \"recording\" });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n act(() => {\n result.current.stopRecording();\n });\n\n expect(mockStopRecording).toHaveBeenCalled();\n });\n\n it(\"should reset transcript when starting a new recording\", async () => {\n mockTranscribe.mockResolvedValue(\"first transcript\");\n\n // Start with completed transcription\n setupMediaRecorderMock({\n status: \"stopped\",\n mediaBlobUrl: \"blob:http://localhost/audio1\",\n });\n\n const { result, rerender } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n // Wait for transcription to complete\n await waitFor(() => {\n expect(result.current.transcript).toBe(\"first transcript\");\n });\n\n // Now simulate starting a new recording\n setupMediaRecorderMock({ status: \"idle\" });\n rerender();\n\n act(() => {\n result.current.startRecording();\n });\n\n expect(result.current.transcript).toBeNull();\n });\n });\n\n describe(\"Transcription\", () => {\n it(\"should trigger transcription after recording stops with blob URL\", async () => {\n mockTranscribe.mockResolvedValue(\"Hello world\");\n\n setupMediaRecorderMock({\n status: \"stopped\",\n mediaBlobUrl: \"blob:http://localhost/audio\",\n });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.transcript).toBe(\"Hello world\");\n });\n\n expect(mockFetch).toHaveBeenCalledWith(\"blob:http://localhost/audio\");\n expect(mockTranscribe).toHaveBeenCalled();\n });\n\n it(\"should expose isTranscribing=true during API call\", async () => {\n let resolveTranscription: (value: string) => void;\n mockTranscribe.mockImplementation(\n async () =>\n await new Promise((resolve) => {\n resolveTranscription = resolve;\n }),\n );\n\n setupMediaRecorderMock({\n status: \"stopped\",\n mediaBlobUrl: \"blob:http://localhost/audio\",\n });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.isTranscribing).toBe(true);\n });\n\n // Complete the transcription\n act(() => {\n resolveTranscription!(\"transcribed text\");\n });\n\n await waitFor(() => {\n expect(result.current.isTranscribing).toBe(false);\n });\n });\n });\n\n describe(\"Error Handling\", () => {\n it(\"should expose mediaAccessError when microphone access fails\", () => {\n setupMediaRecorderMock({\n error: \"Permission denied\",\n });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n expect(result.current.mediaAccessError).toBe(\"Permission denied\");\n });\n\n it(\"should expose transcriptionError when API call fails\", async () => {\n mockTranscribe.mockRejectedValue(\n new Error(\"Transcription service unavailable\"),\n );\n\n setupMediaRecorderMock({\n status: \"stopped\",\n mediaBlobUrl: \"blob:http://localhost/audio\",\n });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.transcriptionError).toBe(\n \"Transcription service unavailable\",\n );\n });\n\n expect(result.current.isTranscribing).toBe(false);\n });\n\n it(\"should handle blob fetch failure gracefully\", async () => {\n mockFetch.mockRejectedValue(new Error(\"Network error\"));\n\n setupMediaRecorderMock({\n status: \"stopped\",\n mediaBlobUrl: \"blob:http://localhost/audio\",\n });\n\n const { result } = renderHook(() => useTamboVoice(), {\n wrapper: createWrapper(),\n });\n\n await waitFor(() => {\n expect(result.current.transcriptionError).toBe(\"Network error\");\n });\n\n expect(result.current.isTranscribing).toBe(false);\n expect(result.current.transcript).toBeNull();\n });\n });\n});\n"]}
|
|
@@ -119,6 +119,9 @@ describe("useTamboMcpPromptList - individual server caching", () => {
|
|
|
119
119
|
client: { baseURL: "https://api.tambo.co" },
|
|
120
120
|
queryClient,
|
|
121
121
|
isUpdatingToken: false,
|
|
122
|
+
tokenExchangeError: null,
|
|
123
|
+
userToken: undefined,
|
|
124
|
+
hasValidToken: false,
|
|
122
125
|
} },
|
|
123
126
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
124
127
|
{
|
|
@@ -204,6 +207,9 @@ describe("useTamboMcpPromptList - individual server caching", () => {
|
|
|
204
207
|
client: { baseURL: "https://api.tambo.co" },
|
|
205
208
|
queryClient,
|
|
206
209
|
isUpdatingToken: false,
|
|
210
|
+
tokenExchangeError: null,
|
|
211
|
+
userToken: undefined,
|
|
212
|
+
hasValidToken: false,
|
|
207
213
|
} },
|
|
208
214
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
209
215
|
{
|
|
@@ -232,6 +238,9 @@ describe("useTamboMcpPromptList - individual server caching", () => {
|
|
|
232
238
|
client: { baseURL: "https://api.tambo.co" },
|
|
233
239
|
queryClient,
|
|
234
240
|
isUpdatingToken: false,
|
|
241
|
+
tokenExchangeError: null,
|
|
242
|
+
userToken: undefined,
|
|
243
|
+
hasValidToken: false,
|
|
235
244
|
} },
|
|
236
245
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
237
246
|
{
|
|
@@ -307,6 +316,9 @@ describe("useTamboMcpPromptList - individual server caching", () => {
|
|
|
307
316
|
client: { baseURL: "https://api.tambo.co" },
|
|
308
317
|
queryClient,
|
|
309
318
|
isUpdatingToken: false,
|
|
319
|
+
tokenExchangeError: null,
|
|
320
|
+
userToken: undefined,
|
|
321
|
+
hasValidToken: false,
|
|
310
322
|
} },
|
|
311
323
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
312
324
|
{
|
|
@@ -387,6 +399,9 @@ describe("useTamboMcpPromptList - individual server caching", () => {
|
|
|
387
399
|
client: { baseURL: "https://api.tambo.co" },
|
|
388
400
|
queryClient,
|
|
389
401
|
isUpdatingToken: false,
|
|
402
|
+
tokenExchangeError: null,
|
|
403
|
+
userToken: undefined,
|
|
404
|
+
hasValidToken: false,
|
|
390
405
|
} },
|
|
391
406
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
392
407
|
{
|
|
@@ -460,6 +475,9 @@ describe("useTamboMcpPromptList - individual server caching", () => {
|
|
|
460
475
|
client: { baseURL: "https://api.tambo.co" },
|
|
461
476
|
queryClient,
|
|
462
477
|
isUpdatingToken: false,
|
|
478
|
+
tokenExchangeError: null,
|
|
479
|
+
userToken: undefined,
|
|
480
|
+
hasValidToken: false,
|
|
463
481
|
} },
|
|
464
482
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
465
483
|
{
|
|
@@ -480,6 +498,9 @@ describe("useTamboMcpPromptList - individual server caching", () => {
|
|
|
480
498
|
client: { baseURL: "https://api.tambo.co" },
|
|
481
499
|
queryClient,
|
|
482
500
|
isUpdatingToken: false,
|
|
501
|
+
tokenExchangeError: null,
|
|
502
|
+
userToken: undefined,
|
|
503
|
+
hasValidToken: false,
|
|
483
504
|
} },
|
|
484
505
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
485
506
|
{
|
|
@@ -553,6 +574,9 @@ describe("useTamboMcpPromptList - search filtering", () => {
|
|
|
553
574
|
client: { baseURL: "https://api.tambo.co" },
|
|
554
575
|
queryClient,
|
|
555
576
|
isUpdatingToken: false,
|
|
577
|
+
tokenExchangeError: null,
|
|
578
|
+
userToken: undefined,
|
|
579
|
+
hasValidToken: false,
|
|
556
580
|
} },
|
|
557
581
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
558
582
|
{
|
|
@@ -572,6 +596,9 @@ describe("useTamboMcpPromptList - search filtering", () => {
|
|
|
572
596
|
client: { baseURL: "https://api.tambo.co" },
|
|
573
597
|
queryClient,
|
|
574
598
|
isUpdatingToken: false,
|
|
599
|
+
tokenExchangeError: null,
|
|
600
|
+
userToken: undefined,
|
|
601
|
+
hasValidToken: false,
|
|
575
602
|
} },
|
|
576
603
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
577
604
|
{
|
|
@@ -623,6 +650,9 @@ describe("useTamboMcpPromptList - search filtering", () => {
|
|
|
623
650
|
client: { baseURL: "https://api.tambo.co" },
|
|
624
651
|
queryClient,
|
|
625
652
|
isUpdatingToken: false,
|
|
653
|
+
tokenExchangeError: null,
|
|
654
|
+
userToken: undefined,
|
|
655
|
+
hasValidToken: false,
|
|
626
656
|
} },
|
|
627
657
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
628
658
|
{
|
|
@@ -750,6 +780,9 @@ describe("useTamboMcpResourceList - resource management", () => {
|
|
|
750
780
|
client: { baseURL: "https://api.tambo.co" },
|
|
751
781
|
queryClient,
|
|
752
782
|
isUpdatingToken: false,
|
|
783
|
+
tokenExchangeError: null,
|
|
784
|
+
userToken: undefined,
|
|
785
|
+
hasValidToken: false,
|
|
753
786
|
} },
|
|
754
787
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
755
788
|
{
|
|
@@ -820,6 +853,9 @@ describe("useTamboMcpResourceList - resource management", () => {
|
|
|
820
853
|
client: { baseURL: "https://api.tambo.co" },
|
|
821
854
|
queryClient,
|
|
822
855
|
isUpdatingToken: false,
|
|
856
|
+
tokenExchangeError: null,
|
|
857
|
+
userToken: undefined,
|
|
858
|
+
hasValidToken: false,
|
|
823
859
|
} },
|
|
824
860
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
825
861
|
{
|
|
@@ -903,6 +939,9 @@ describe("useTamboMcpResourceList - resource management", () => {
|
|
|
903
939
|
client: { baseURL: "https://api.tambo.co" },
|
|
904
940
|
queryClient,
|
|
905
941
|
isUpdatingToken: false,
|
|
942
|
+
tokenExchangeError: null,
|
|
943
|
+
userToken: undefined,
|
|
944
|
+
hasValidToken: false,
|
|
906
945
|
} },
|
|
907
946
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
908
947
|
{
|
|
@@ -929,6 +968,9 @@ describe("useTamboMcpResourceList - resource management", () => {
|
|
|
929
968
|
client: { baseURL: "https://api.tambo.co" },
|
|
930
969
|
queryClient,
|
|
931
970
|
isUpdatingToken: false,
|
|
971
|
+
tokenExchangeError: null,
|
|
972
|
+
userToken: undefined,
|
|
973
|
+
hasValidToken: false,
|
|
932
974
|
} },
|
|
933
975
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
934
976
|
{
|
|
@@ -1012,6 +1054,9 @@ describe("useTamboMcpResourceList - search filtering", () => {
|
|
|
1012
1054
|
client: { baseURL: "https://api.tambo.co" },
|
|
1013
1055
|
queryClient,
|
|
1014
1056
|
isUpdatingToken: false,
|
|
1057
|
+
tokenExchangeError: null,
|
|
1058
|
+
userToken: undefined,
|
|
1059
|
+
hasValidToken: false,
|
|
1015
1060
|
} },
|
|
1016
1061
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
1017
1062
|
{
|
|
@@ -1031,6 +1076,9 @@ describe("useTamboMcpResourceList - search filtering", () => {
|
|
|
1031
1076
|
client: { baseURL: "https://api.tambo.co" },
|
|
1032
1077
|
queryClient,
|
|
1033
1078
|
isUpdatingToken: false,
|
|
1079
|
+
tokenExchangeError: null,
|
|
1080
|
+
userToken: undefined,
|
|
1081
|
+
hasValidToken: false,
|
|
1034
1082
|
} },
|
|
1035
1083
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
1036
1084
|
{
|
|
@@ -1081,6 +1129,9 @@ describe("useTamboMcpResourceList - search filtering", () => {
|
|
|
1081
1129
|
client: { baseURL: "https://api.tambo.co" },
|
|
1082
1130
|
queryClient,
|
|
1083
1131
|
isUpdatingToken: false,
|
|
1132
|
+
tokenExchangeError: null,
|
|
1133
|
+
userToken: undefined,
|
|
1134
|
+
hasValidToken: false,
|
|
1084
1135
|
} },
|
|
1085
1136
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { listResources: listResources, getResource: getResource },
|
|
1086
1137
|
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
@@ -1100,6 +1151,9 @@ describe("useTamboMcpResourceList - search filtering", () => {
|
|
|
1100
1151
|
client: { baseURL: "https://api.tambo.co" },
|
|
1101
1152
|
queryClient,
|
|
1102
1153
|
isUpdatingToken: false,
|
|
1154
|
+
tokenExchangeError: null,
|
|
1155
|
+
userToken: undefined,
|
|
1156
|
+
hasValidToken: false,
|
|
1103
1157
|
} },
|
|
1104
1158
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { listResources: listResources, getResource: getResource },
|
|
1105
1159
|
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
@@ -1145,6 +1199,9 @@ describe("useTamboMcpResourceList - search filtering", () => {
|
|
|
1145
1199
|
client: { baseURL: "https://api.tambo.co" },
|
|
1146
1200
|
queryClient,
|
|
1147
1201
|
isUpdatingToken: false,
|
|
1202
|
+
tokenExchangeError: null,
|
|
1203
|
+
userToken: undefined,
|
|
1204
|
+
hasValidToken: false,
|
|
1148
1205
|
} },
|
|
1149
1206
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { listResources: listResources, getResource: getResource },
|
|
1150
1207
|
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|
|
@@ -1214,6 +1271,9 @@ describe("useTamboMcpResourceList - search filtering", () => {
|
|
|
1214
1271
|
client: { baseURL: "https://api.tambo.co" },
|
|
1215
1272
|
queryClient,
|
|
1216
1273
|
isUpdatingToken: false,
|
|
1274
|
+
tokenExchangeError: null,
|
|
1275
|
+
userToken: undefined,
|
|
1276
|
+
hasValidToken: false,
|
|
1217
1277
|
} },
|
|
1218
1278
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
1219
1279
|
{
|
|
@@ -1300,6 +1360,9 @@ describe("useTamboMcpResource - read individual resource", () => {
|
|
|
1300
1360
|
client: { baseURL: "https://api.tambo.co" },
|
|
1301
1361
|
queryClient,
|
|
1302
1362
|
isUpdatingToken: false,
|
|
1363
|
+
tokenExchangeError: null,
|
|
1364
|
+
userToken: undefined,
|
|
1365
|
+
hasValidToken: false,
|
|
1303
1366
|
} },
|
|
1304
1367
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
1305
1368
|
{
|
|
@@ -1391,6 +1454,9 @@ describe("useTamboMcpResource - read individual resource", () => {
|
|
|
1391
1454
|
client: { baseURL: "https://api.tambo.co" },
|
|
1392
1455
|
queryClient,
|
|
1393
1456
|
isUpdatingToken: false,
|
|
1457
|
+
tokenExchangeError: null,
|
|
1458
|
+
userToken: undefined,
|
|
1459
|
+
hasValidToken: false,
|
|
1394
1460
|
} },
|
|
1395
1461
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { mcpServers: [
|
|
1396
1462
|
{
|
|
@@ -1442,6 +1508,9 @@ describe("useTamboMcpResource - read individual resource", () => {
|
|
|
1442
1508
|
client: { baseURL: "https://api.tambo.co" },
|
|
1443
1509
|
queryClient,
|
|
1444
1510
|
isUpdatingToken: false,
|
|
1511
|
+
tokenExchangeError: null,
|
|
1512
|
+
userToken: undefined,
|
|
1513
|
+
hasValidToken: false,
|
|
1445
1514
|
} },
|
|
1446
1515
|
react_2.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { listResources: listResources, getResource: getResource },
|
|
1447
1516
|
react_2.default.createElement(tambo_mcp_token_provider_1.TamboMcpTokenProvider, null,
|