@tambo-ai/react 0.74.1 → 1.0.0-rc.3
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 +16 -13
- package/dist/hoc/with-tambo-interactable.js.map +1 -1
- package/dist/hoc/with-tambo-interactable.test.js +15 -3
- 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/index.d.ts +7 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -59
- package/dist/index.js.map +1 -1
- package/dist/mcp/mcp-hooks.js +5 -5
- package/dist/mcp/mcp-hooks.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/tambo-client-provider.d.ts +12 -0
- package/dist/providers/tambo-client-provider.d.ts.map +1 -1
- package/dist/providers/tambo-client-provider.js +8 -3
- package/dist/providers/tambo-client-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.d.ts +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-interactables-additional-context-edge-cases.test.js +2 -10
- package/dist/providers/tambo-interactables-additional-context-edge-cases.test.js.map +1 -1
- package/dist/providers/tambo-interactables-additional-context.test.js +3 -19
- package/dist/providers/tambo-interactables-additional-context.test.js.map +1 -1
- package/dist/providers/tambo-mcp-token-provider.d.ts +8 -17
- package/dist/providers/tambo-mcp-token-provider.d.ts.map +1 -1
- package/dist/providers/tambo-mcp-token-provider.js +20 -97
- package/dist/providers/tambo-mcp-token-provider.js.map +1 -1
- package/dist/testing/tools.d.ts +3 -3
- package/dist/testing/tools.d.ts.map +1 -1
- package/dist/testing/tools.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/__tests__/v1-interactables.test.js +1 -1
- package/dist/v1/__tests__/v1-interactables.test.js.map +1 -1
- package/dist/v1/components/v1-component-renderer.d.ts +9 -9
- package/dist/v1/components/v1-component-renderer.d.ts.map +1 -1
- package/dist/v1/components/v1-component-renderer.js +13 -13
- package/dist/v1/components/v1-component-renderer.js.map +1 -1
- package/dist/v1/components/v1-component-renderer.test.js +15 -15
- package/dist/v1/components/v1-component-renderer.test.js.map +1 -1
- package/{esm/hooks/use-current-message.d.ts → dist/v1/hooks/use-tambo-current-message.d.ts} +30 -9
- package/dist/v1/hooks/use-tambo-current-message.d.ts.map +1 -0
- package/dist/{hooks/use-current-message.js → v1/hooks/use-tambo-current-message.js} +13 -8
- package/dist/v1/hooks/use-tambo-current-message.js.map +1 -0
- 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 +7 -6
- package/dist/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.js +101 -28
- package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js +150 -25
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-messages.d.ts +9 -9
- package/dist/v1/hooks/use-tambo-v1-messages.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-messages.js +4 -4
- package/dist/v1/hooks/use-tambo-v1-messages.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-messages.test.js +14 -6
- package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +21 -3
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.js +92 -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 +315 -42
- 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 +7 -7
- package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.js +14 -16
- package/dist/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js +30 -30
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts +7 -7
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.js +9 -9
- package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js +44 -44
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts +3 -3
- package/dist/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.js +4 -4
- package/dist/v1/hooks/use-tambo-v1-thread-input.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +40 -27
- 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 +4 -4
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.js +8 -4
- package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +18 -16
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.d.ts +3 -3
- package/dist/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.js +7 -3
- package/dist/v1/hooks/use-tambo-v1-thread.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.test.js +10 -4
- package/dist/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.d.ts +16 -5
- package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.js +14 -6
- package/dist/v1/hooks/use-tambo-v1.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.test.js +65 -43
- package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/dist/v1/index.d.ts +34 -27
- package/dist/v1/index.d.ts.map +1 -1
- package/dist/v1/index.js +48 -35
- package/dist/v1/index.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts +35 -20
- package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.js +63 -26
- package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.test.js +40 -23
- package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.d.ts +21 -15
- package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.js +66 -27
- package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.test.js +14 -5
- package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts +9 -9
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.js +11 -7
- package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.test.js +25 -25
- package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +20 -9
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.js +25 -16
- 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/{model/tambo-thread.js → v1/types/auth.js} +1 -1
- package/dist/v1/types/auth.js.map +1 -0
- package/dist/v1/types/component.d.ts +3 -3
- package/dist/v1/types/component.d.ts.map +1 -1
- package/dist/v1/types/component.js +2 -2
- package/dist/v1/types/component.js.map +1 -1
- package/dist/v1/types/event.d.ts +1 -1
- package/dist/v1/types/event.js +1 -1
- package/dist/v1/types/event.js.map +1 -1
- package/dist/v1/types/message.d.ts +19 -12
- package/dist/v1/types/message.d.ts.map +1 -1
- package/dist/v1/types/message.js +1 -1
- package/dist/v1/types/message.js.map +1 -1
- package/dist/v1/types/thread.d.ts +8 -6
- package/dist/v1/types/thread.d.ts.map +1 -1
- package/dist/v1/types/thread.js +1 -1
- package/dist/v1/types/thread.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/component-renderer.d.ts +11 -5
- package/dist/v1/utils/component-renderer.d.ts.map +1 -1
- package/dist/v1/utils/component-renderer.js +16 -7
- package/dist/v1/utils/component-renderer.js.map +1 -1
- package/dist/v1/utils/component-renderer.test.js +7 -7
- package/dist/v1/utils/component-renderer.test.js.map +1 -1
- package/dist/v1/utils/event-accumulator.d.ts +34 -8
- package/dist/v1/utils/event-accumulator.d.ts.map +1 -1
- package/dist/v1/utils/event-accumulator.js +90 -27
- package/dist/v1/utils/event-accumulator.js.map +1 -1
- package/dist/v1/utils/event-accumulator.test.js +149 -8
- 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 +18 -18
- package/dist/v1/utils/registry-conversion.d.ts.map +1 -1
- package/dist/v1/utils/registry-conversion.js +25 -23
- 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/stream-handler.d.ts +1 -1
- package/dist/v1/utils/stream-handler.js +1 -1
- package/dist/v1/utils/stream-handler.js.map +1 -1
- package/dist/v1/utils/thread-utils.d.ts +2 -2
- package/dist/v1/utils/thread-utils.d.ts.map +1 -1
- package/dist/v1/utils/thread-utils.js.map +1 -1
- package/dist/v1/utils/tool-call-tracker.d.ts +11 -1
- package/dist/v1/utils/tool-call-tracker.d.ts.map +1 -1
- package/dist/v1/utils/tool-call-tracker.js +14 -1
- 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 +35 -1
- package/dist/v1/utils/tool-executor.d.ts.map +1 -1
- package/dist/v1/utils/tool-executor.js +57 -2
- 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 +15 -12
- package/esm/hoc/with-tambo-interactable.js.map +1 -1
- package/esm/hoc/with-tambo-interactable.test.js +13 -1
- 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/index.d.ts +7 -25
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +7 -21
- package/esm/index.js.map +1 -1
- package/esm/mcp/mcp-hooks.js +1 -1
- package/esm/mcp/mcp-hooks.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/tambo-client-provider.d.ts +12 -0
- package/esm/providers/tambo-client-provider.d.ts.map +1 -1
- package/esm/providers/tambo-client-provider.js +8 -3
- package/esm/providers/tambo-client-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +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-interactables-additional-context-edge-cases.test.js +2 -10
- package/esm/providers/tambo-interactables-additional-context-edge-cases.test.js.map +1 -1
- package/esm/providers/tambo-interactables-additional-context.test.js +3 -19
- package/esm/providers/tambo-interactables-additional-context.test.js.map +1 -1
- package/esm/providers/tambo-mcp-token-provider.d.ts +8 -17
- package/esm/providers/tambo-mcp-token-provider.d.ts.map +1 -1
- package/esm/providers/tambo-mcp-token-provider.js +20 -97
- package/esm/providers/tambo-mcp-token-provider.js.map +1 -1
- package/esm/testing/tools.d.ts +3 -3
- package/esm/testing/tools.d.ts.map +1 -1
- package/esm/testing/tools.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/__tests__/v1-interactables.test.js +1 -1
- package/esm/v1/__tests__/v1-interactables.test.js.map +1 -1
- package/esm/v1/components/v1-component-renderer.d.ts +9 -9
- package/esm/v1/components/v1-component-renderer.d.ts.map +1 -1
- package/esm/v1/components/v1-component-renderer.js +12 -12
- package/esm/v1/components/v1-component-renderer.js.map +1 -1
- package/esm/v1/components/v1-component-renderer.test.js +16 -16
- package/esm/v1/components/v1-component-renderer.test.js.map +1 -1
- package/{dist/hooks/use-current-message.d.ts → esm/v1/hooks/use-tambo-current-message.d.ts} +30 -9
- package/esm/v1/hooks/use-tambo-current-message.d.ts.map +1 -0
- package/esm/{hooks/use-current-message.js → v1/hooks/use-tambo-current-message.js} +13 -8
- package/esm/v1/hooks/use-tambo-current-message.js.map +1 -0
- 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 +7 -6
- package/esm/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.js +101 -28
- package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js +152 -27
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.d.ts +9 -9
- package/esm/v1/hooks/use-tambo-v1-messages.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.js +3 -3
- package/esm/v1/hooks/use-tambo-v1-messages.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.test.js +16 -8
- package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +21 -3
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.js +93 -18
- package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js +318 -45
- 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 +7 -7
- package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.js +14 -16
- package/esm/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js +32 -32
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts +7 -7
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.js +11 -11
- package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js +48 -48
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts +3 -3
- package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.js +3 -3
- package/esm/v1/hooks/use-tambo-v1-thread-input.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +43 -30
- 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 +4 -4
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.js +8 -4
- package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +20 -18
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.d.ts +3 -3
- package/esm/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.js +6 -2
- package/esm/v1/hooks/use-tambo-v1-thread.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.test.js +11 -5
- package/esm/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.d.ts +16 -5
- package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.js +14 -6
- package/esm/v1/hooks/use-tambo-v1.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.test.js +67 -45
- package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/esm/v1/index.d.ts +34 -27
- package/esm/v1/index.d.ts.map +1 -1
- package/esm/v1/index.js +40 -33
- package/esm/v1/index.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts +35 -20
- package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.js +63 -26
- package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.test.js +41 -24
- package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.d.ts +21 -15
- package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.js +66 -27
- package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.test.js +15 -6
- package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts +9 -9
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.js +13 -9
- package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.test.js +28 -28
- package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +20 -9
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.js +23 -14
- 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/component.d.ts +3 -3
- package/esm/v1/types/component.d.ts.map +1 -1
- package/esm/v1/types/component.js +2 -2
- package/esm/v1/types/component.js.map +1 -1
- package/esm/v1/types/event.d.ts +1 -1
- package/esm/v1/types/event.js +1 -1
- package/esm/v1/types/event.js.map +1 -1
- package/esm/v1/types/message.d.ts +19 -12
- package/esm/v1/types/message.d.ts.map +1 -1
- package/esm/v1/types/message.js +1 -1
- package/esm/v1/types/message.js.map +1 -1
- package/esm/v1/types/thread.d.ts +8 -6
- package/esm/v1/types/thread.d.ts.map +1 -1
- package/esm/v1/types/thread.js +1 -1
- package/esm/v1/types/thread.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/component-renderer.d.ts +11 -5
- package/esm/v1/utils/component-renderer.d.ts.map +1 -1
- package/esm/v1/utils/component-renderer.js +13 -5
- package/esm/v1/utils/component-renderer.js.map +1 -1
- package/esm/v1/utils/component-renderer.test.js +8 -8
- package/esm/v1/utils/component-renderer.test.js.map +1 -1
- package/esm/v1/utils/event-accumulator.d.ts +34 -8
- package/esm/v1/utils/event-accumulator.d.ts.map +1 -1
- package/esm/v1/utils/event-accumulator.js +89 -27
- package/esm/v1/utils/event-accumulator.js.map +1 -1
- package/esm/v1/utils/event-accumulator.test.js +149 -8
- 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 +18 -18
- package/esm/v1/utils/registry-conversion.d.ts.map +1 -1
- package/esm/v1/utils/registry-conversion.js +25 -23
- 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/stream-handler.d.ts +1 -1
- package/esm/v1/utils/stream-handler.js +1 -1
- package/esm/v1/utils/stream-handler.js.map +1 -1
- package/esm/v1/utils/thread-utils.d.ts +2 -2
- package/esm/v1/utils/thread-utils.d.ts.map +1 -1
- package/esm/v1/utils/thread-utils.js.map +1 -1
- package/esm/v1/utils/tool-call-tracker.d.ts +11 -1
- package/esm/v1/utils/tool-call-tracker.d.ts.map +1 -1
- package/esm/v1/utils/tool-call-tracker.js +14 -1
- 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 +35 -1
- package/esm/v1/utils/tool-executor.d.ts.map +1 -1
- package/esm/v1/utils/tool-executor.js +55 -2
- 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 +5 -10
- package/dist/hooks/index.d.ts +0 -9
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js +0 -34
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/use-component-state.d.ts +0 -30
- package/dist/hooks/use-component-state.d.ts.map +0 -1
- package/dist/hooks/use-component-state.js +0 -139
- package/dist/hooks/use-component-state.js.map +0 -1
- package/dist/hooks/use-component-state.test.d.ts +0 -2
- package/dist/hooks/use-component-state.test.d.ts.map +0 -1
- package/dist/hooks/use-component-state.test.js +0 -406
- package/dist/hooks/use-component-state.test.js.map +0 -1
- package/dist/hooks/use-current-message.d.ts.map +0 -1
- package/dist/hooks/use-current-message.js.map +0 -1
- package/dist/hooks/use-current-message.test.d.ts +0 -2
- package/dist/hooks/use-current-message.test.d.ts.map +0 -1
- package/dist/hooks/use-current-message.test.js +0 -269
- package/dist/hooks/use-current-message.test.js.map +0 -1
- package/dist/hooks/use-streaming-props.d.ts +0 -11
- package/dist/hooks/use-streaming-props.d.ts.map +0 -1
- package/dist/hooks/use-streaming-props.js +0 -37
- package/dist/hooks/use-streaming-props.js.map +0 -1
- package/dist/hooks/use-suggestions.d.ts +0 -46
- package/dist/hooks/use-suggestions.d.ts.map +0 -1
- package/dist/hooks/use-suggestions.js +0 -118
- package/dist/hooks/use-suggestions.js.map +0 -1
- package/dist/hooks/use-suggestions.test.d.ts +0 -2
- package/dist/hooks/use-suggestions.test.d.ts.map +0 -1
- package/dist/hooks/use-suggestions.test.js +0 -247
- package/dist/hooks/use-suggestions.test.js.map +0 -1
- package/dist/hooks/use-tambo-stream-status.d.ts +0 -90
- package/dist/hooks/use-tambo-stream-status.d.ts.map +0 -1
- package/dist/hooks/use-tambo-stream-status.js +0 -213
- package/dist/hooks/use-tambo-stream-status.js.map +0 -1
- package/dist/hooks/use-tambo-stream-status.test.d.ts +0 -2
- package/dist/hooks/use-tambo-stream-status.test.d.ts.map +0 -1
- package/dist/hooks/use-tambo-stream-status.test.js +0 -378
- package/dist/hooks/use-tambo-stream-status.test.js.map +0 -1
- package/dist/hooks/use-tambo-threads.d.ts +0 -158
- package/dist/hooks/use-tambo-threads.d.ts.map +0 -1
- package/dist/hooks/use-tambo-threads.js +0 -45
- package/dist/hooks/use-tambo-threads.js.map +0 -1
- package/dist/hooks/use-tambo-threads.test.d.ts +0 -2
- package/dist/hooks/use-tambo-threads.test.d.ts.map +0 -1
- package/dist/hooks/use-tambo-threads.test.js +0 -214
- package/dist/hooks/use-tambo-threads.test.js.map +0 -1
- package/dist/model/generate-component-response.d.ts +0 -37
- package/dist/model/generate-component-response.d.ts.map +0 -1
- package/dist/model/generate-component-response.js +0 -29
- package/dist/model/generate-component-response.js.map +0 -1
- package/dist/model/tambo-thread.d.ts +0 -15
- package/dist/model/tambo-thread.d.ts.map +0 -1
- package/dist/model/tambo-thread.js.map +0 -1
- package/dist/providers/__tests__/thread-input-resource-resolution.test.d.ts +0 -2
- package/dist/providers/__tests__/thread-input-resource-resolution.test.d.ts.map +0 -1
- package/dist/providers/__tests__/thread-input-resource-resolution.test.js +0 -592
- package/dist/providers/__tests__/thread-input-resource-resolution.test.js.map +0 -1
- package/dist/providers/index.d.ts +0 -13
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/index.js +0 -41
- package/dist/providers/index.js.map +0 -1
- package/dist/providers/tambo-component-provider.d.ts +0 -23
- package/dist/providers/tambo-component-provider.d.ts.map +0 -1
- package/dist/providers/tambo-component-provider.js +0 -88
- package/dist/providers/tambo-component-provider.js.map +0 -1
- package/dist/providers/tambo-prop-stream-provider/index.d.ts +0 -19
- package/dist/providers/tambo-prop-stream-provider/index.d.ts.map +0 -1
- package/dist/providers/tambo-prop-stream-provider/index.js +0 -43
- package/dist/providers/tambo-prop-stream-provider/index.js.map +0 -1
- package/dist/providers/tambo-prop-stream-provider/pending.d.ts +0 -12
- package/dist/providers/tambo-prop-stream-provider/pending.d.ts.map +0 -1
- package/dist/providers/tambo-prop-stream-provider/pending.js +0 -31
- package/dist/providers/tambo-prop-stream-provider/pending.js.map +0 -1
- package/dist/providers/tambo-prop-stream-provider/provider.d.ts +0 -17
- package/dist/providers/tambo-prop-stream-provider/provider.d.ts.map +0 -1
- package/dist/providers/tambo-prop-stream-provider/provider.js +0 -107
- package/dist/providers/tambo-prop-stream-provider/provider.js.map +0 -1
- package/dist/providers/tambo-prop-stream-provider/streaming.d.ts +0 -12
- package/dist/providers/tambo-prop-stream-provider/streaming.d.ts.map +0 -1
- package/dist/providers/tambo-prop-stream-provider/streaming.js +0 -28
- package/dist/providers/tambo-prop-stream-provider/streaming.js.map +0 -1
- package/dist/providers/tambo-prop-stream-provider/success.d.ts +0 -12
- package/dist/providers/tambo-prop-stream-provider/success.d.ts.map +0 -1
- package/dist/providers/tambo-prop-stream-provider/success.js +0 -28
- package/dist/providers/tambo-prop-stream-provider/success.js.map +0 -1
- package/dist/providers/tambo-prop-stream-provider/types.d.ts +0 -25
- package/dist/providers/tambo-prop-stream-provider/types.d.ts.map +0 -1
- package/dist/providers/tambo-prop-stream-provider/types.js +0 -6
- package/dist/providers/tambo-prop-stream-provider/types.js.map +0 -1
- package/dist/providers/tambo-prop-stream-provider.test.d.ts +0 -2
- package/dist/providers/tambo-prop-stream-provider.test.d.ts.map +0 -1
- package/dist/providers/tambo-prop-stream-provider.test.js +0 -275
- package/dist/providers/tambo-prop-stream-provider.test.js.map +0 -1
- package/dist/providers/tambo-provider.d.ts +0 -53
- package/dist/providers/tambo-provider.d.ts.map +0 -1
- package/dist/providers/tambo-provider.js +0 -130
- package/dist/providers/tambo-provider.js.map +0 -1
- package/dist/providers/tambo-stubs.d.ts +0 -89
- package/dist/providers/tambo-stubs.d.ts.map +0 -1
- package/dist/providers/tambo-stubs.js +0 -276
- package/dist/providers/tambo-stubs.js.map +0 -1
- package/dist/providers/tambo-stubs.test.d.ts +0 -2
- package/dist/providers/tambo-stubs.test.d.ts.map +0 -1
- package/dist/providers/tambo-stubs.test.js +0 -97
- package/dist/providers/tambo-stubs.test.js.map +0 -1
- package/dist/providers/tambo-thread-input-provider.d.ts +0 -65
- package/dist/providers/tambo-thread-input-provider.d.ts.map +0 -1
- package/dist/providers/tambo-thread-input-provider.js +0 -179
- package/dist/providers/tambo-thread-input-provider.js.map +0 -1
- package/dist/providers/tambo-thread-provider-initial-messages.test.d.ts +0 -2
- package/dist/providers/tambo-thread-provider-initial-messages.test.d.ts.map +0 -1
- package/dist/providers/tambo-thread-provider-initial-messages.test.js +0 -275
- package/dist/providers/tambo-thread-provider-initial-messages.test.js.map +0 -1
- package/dist/providers/tambo-thread-provider.d.ts +0 -126
- package/dist/providers/tambo-thread-provider.d.ts.map +0 -1
- package/dist/providers/tambo-thread-provider.js +0 -931
- package/dist/providers/tambo-thread-provider.js.map +0 -1
- package/dist/providers/tambo-thread-provider.test.d.ts +0 -2
- package/dist/providers/tambo-thread-provider.test.d.ts.map +0 -1
- package/dist/providers/tambo-thread-provider.test.js +0 -1588
- package/dist/providers/tambo-thread-provider.test.js.map +0 -1
- package/dist/util/generate-component.d.ts +0 -12
- package/dist/util/generate-component.d.ts.map +0 -1
- package/dist/util/generate-component.js +0 -58
- package/dist/util/generate-component.js.map +0 -1
- package/dist/util/generate-component.test.d.ts +0 -2
- package/dist/util/generate-component.test.d.ts.map +0 -1
- package/dist/util/generate-component.test.js +0 -340
- package/dist/util/generate-component.test.js.map +0 -1
- package/esm/hooks/index.d.ts +0 -9
- package/esm/hooks/index.d.ts.map +0 -1
- package/esm/hooks/index.js +0 -10
- package/esm/hooks/index.js.map +0 -1
- package/esm/hooks/use-component-state.d.ts +0 -30
- package/esm/hooks/use-component-state.d.ts.map +0 -1
- package/esm/hooks/use-component-state.js +0 -136
- package/esm/hooks/use-component-state.js.map +0 -1
- package/esm/hooks/use-component-state.test.d.ts +0 -2
- package/esm/hooks/use-component-state.test.d.ts.map +0 -1
- package/esm/hooks/use-component-state.test.js +0 -401
- package/esm/hooks/use-component-state.test.js.map +0 -1
- package/esm/hooks/use-current-message.d.ts.map +0 -1
- package/esm/hooks/use-current-message.js.map +0 -1
- package/esm/hooks/use-current-message.test.d.ts +0 -2
- package/esm/hooks/use-current-message.test.d.ts.map +0 -1
- package/esm/hooks/use-current-message.test.js +0 -264
- package/esm/hooks/use-current-message.test.js.map +0 -1
- package/esm/hooks/use-streaming-props.d.ts +0 -11
- package/esm/hooks/use-streaming-props.d.ts.map +0 -1
- package/esm/hooks/use-streaming-props.js +0 -34
- package/esm/hooks/use-streaming-props.js.map +0 -1
- package/esm/hooks/use-suggestions.d.ts +0 -46
- package/esm/hooks/use-suggestions.d.ts.map +0 -1
- package/esm/hooks/use-suggestions.js +0 -115
- package/esm/hooks/use-suggestions.js.map +0 -1
- package/esm/hooks/use-suggestions.test.d.ts +0 -2
- package/esm/hooks/use-suggestions.test.d.ts.map +0 -1
- package/esm/hooks/use-suggestions.test.js +0 -245
- package/esm/hooks/use-suggestions.test.js.map +0 -1
- package/esm/hooks/use-tambo-stream-status.d.ts +0 -90
- package/esm/hooks/use-tambo-stream-status.d.ts.map +0 -1
- package/esm/hooks/use-tambo-stream-status.js +0 -210
- package/esm/hooks/use-tambo-stream-status.js.map +0 -1
- package/esm/hooks/use-tambo-stream-status.test.d.ts +0 -2
- package/esm/hooks/use-tambo-stream-status.test.d.ts.map +0 -1
- package/esm/hooks/use-tambo-stream-status.test.js +0 -376
- package/esm/hooks/use-tambo-stream-status.test.js.map +0 -1
- package/esm/hooks/use-tambo-threads.d.ts +0 -158
- package/esm/hooks/use-tambo-threads.d.ts.map +0 -1
- package/esm/hooks/use-tambo-threads.js +0 -42
- package/esm/hooks/use-tambo-threads.js.map +0 -1
- package/esm/hooks/use-tambo-threads.test.d.ts +0 -2
- package/esm/hooks/use-tambo-threads.test.d.ts.map +0 -1
- package/esm/hooks/use-tambo-threads.test.js +0 -212
- package/esm/hooks/use-tambo-threads.test.js.map +0 -1
- package/esm/model/generate-component-response.d.ts +0 -37
- package/esm/model/generate-component-response.d.ts.map +0 -1
- package/esm/model/generate-component-response.js +0 -25
- package/esm/model/generate-component-response.js.map +0 -1
- package/esm/model/tambo-thread.d.ts +0 -15
- package/esm/model/tambo-thread.d.ts.map +0 -1
- package/esm/model/tambo-thread.js +0 -2
- package/esm/model/tambo-thread.js.map +0 -1
- package/esm/providers/__tests__/thread-input-resource-resolution.test.d.ts +0 -2
- package/esm/providers/__tests__/thread-input-resource-resolution.test.d.ts.map +0 -1
- package/esm/providers/__tests__/thread-input-resource-resolution.test.js +0 -587
- package/esm/providers/__tests__/thread-input-resource-resolution.test.js.map +0 -1
- package/esm/providers/index.d.ts +0 -13
- package/esm/providers/index.d.ts.map +0 -1
- package/esm/providers/index.js +0 -11
- package/esm/providers/index.js.map +0 -1
- package/esm/providers/tambo-component-provider.d.ts +0 -23
- package/esm/providers/tambo-component-provider.d.ts.map +0 -1
- package/esm/providers/tambo-component-provider.js +0 -50
- package/esm/providers/tambo-component-provider.js.map +0 -1
- package/esm/providers/tambo-prop-stream-provider/index.d.ts +0 -19
- package/esm/providers/tambo-prop-stream-provider/index.d.ts.map +0 -1
- package/esm/providers/tambo-prop-stream-provider/index.js +0 -22
- package/esm/providers/tambo-prop-stream-provider/index.js.map +0 -1
- package/esm/providers/tambo-prop-stream-provider/pending.d.ts +0 -12
- package/esm/providers/tambo-prop-stream-provider/pending.d.ts.map +0 -1
- package/esm/providers/tambo-prop-stream-provider/pending.js +0 -24
- package/esm/providers/tambo-prop-stream-provider/pending.js.map +0 -1
- package/esm/providers/tambo-prop-stream-provider/provider.d.ts +0 -17
- package/esm/providers/tambo-prop-stream-provider/provider.d.ts.map +0 -1
- package/esm/providers/tambo-prop-stream-provider/provider.js +0 -70
- package/esm/providers/tambo-prop-stream-provider/provider.js.map +0 -1
- package/esm/providers/tambo-prop-stream-provider/streaming.d.ts +0 -12
- package/esm/providers/tambo-prop-stream-provider/streaming.d.ts.map +0 -1
- package/esm/providers/tambo-prop-stream-provider/streaming.js +0 -21
- package/esm/providers/tambo-prop-stream-provider/streaming.js.map +0 -1
- package/esm/providers/tambo-prop-stream-provider/success.d.ts +0 -12
- package/esm/providers/tambo-prop-stream-provider/success.d.ts.map +0 -1
- package/esm/providers/tambo-prop-stream-provider/success.js +0 -21
- package/esm/providers/tambo-prop-stream-provider/success.js.map +0 -1
- package/esm/providers/tambo-prop-stream-provider/types.d.ts +0 -25
- package/esm/providers/tambo-prop-stream-provider/types.d.ts.map +0 -1
- package/esm/providers/tambo-prop-stream-provider/types.js +0 -3
- package/esm/providers/tambo-prop-stream-provider/types.js.map +0 -1
- package/esm/providers/tambo-prop-stream-provider.test.d.ts +0 -2
- package/esm/providers/tambo-prop-stream-provider.test.d.ts.map +0 -1
- package/esm/providers/tambo-prop-stream-provider.test.js +0 -270
- package/esm/providers/tambo-prop-stream-provider.test.js.map +0 -1
- package/esm/providers/tambo-provider.d.ts +0 -53
- package/esm/providers/tambo-provider.d.ts.map +0 -1
- package/esm/providers/tambo-provider.js +0 -91
- package/esm/providers/tambo-provider.js.map +0 -1
- package/esm/providers/tambo-stubs.d.ts +0 -89
- package/esm/providers/tambo-stubs.d.ts.map +0 -1
- package/esm/providers/tambo-stubs.js +0 -239
- package/esm/providers/tambo-stubs.js.map +0 -1
- package/esm/providers/tambo-stubs.test.d.ts +0 -2
- package/esm/providers/tambo-stubs.test.d.ts.map +0 -1
- package/esm/providers/tambo-stubs.test.js +0 -62
- package/esm/providers/tambo-stubs.test.js.map +0 -1
- package/esm/providers/tambo-thread-input-provider.d.ts +0 -65
- package/esm/providers/tambo-thread-input-provider.d.ts.map +0 -1
- package/esm/providers/tambo-thread-input-provider.js +0 -141
- package/esm/providers/tambo-thread-input-provider.js.map +0 -1
- package/esm/providers/tambo-thread-provider-initial-messages.test.d.ts +0 -2
- package/esm/providers/tambo-thread-provider-initial-messages.test.d.ts.map +0 -1
- package/esm/providers/tambo-thread-provider-initial-messages.test.js +0 -270
- package/esm/providers/tambo-thread-provider-initial-messages.test.js.map +0 -1
- package/esm/providers/tambo-thread-provider.d.ts +0 -126
- package/esm/providers/tambo-thread-provider.d.ts.map +0 -1
- package/esm/providers/tambo-thread-provider.js +0 -891
- package/esm/providers/tambo-thread-provider.js.map +0 -1
- package/esm/providers/tambo-thread-provider.test.d.ts +0 -2
- package/esm/providers/tambo-thread-provider.test.d.ts.map +0 -1
- package/esm/providers/tambo-thread-provider.test.js +0 -1550
- package/esm/providers/tambo-thread-provider.test.js.map +0 -1
- package/esm/util/generate-component.d.ts +0 -12
- package/esm/util/generate-component.d.ts.map +0 -1
- package/esm/util/generate-component.js +0 -52
- package/esm/util/generate-component.js.map +0 -1
- package/esm/util/generate-component.test.d.ts +0 -2
- package/esm/util/generate-component.test.d.ts.map +0 -1
- package/esm/util/generate-component.test.js +0 -302
- package/esm/util/generate-component.test.js.map +0 -1
|
@@ -54,7 +54,7 @@ export function validateTool(tool) {
|
|
|
54
54
|
if ("toolSchema" in tool) {
|
|
55
55
|
throw new Error(`Tool "${toolName}" uses deprecated "toolSchema" property. ` +
|
|
56
56
|
`Migrate to "inputSchema" and "outputSchema" properties. ` +
|
|
57
|
-
`See migration guide: https://tambo.
|
|
57
|
+
`See migration guide: https://docs.tambo.co/reference/react-sdk/migration/toolschema`);
|
|
58
58
|
}
|
|
59
59
|
// Validate required properties exist
|
|
60
60
|
if (!("name" in tool) || typeof tool.name !== "string") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry-validators.js","sourceRoot":"","sources":["../../src/util/registry-validators.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JSONSchema7 } from \"json-schema\";\nimport type { TamboComponent, TamboTool } from \"../model/component-metadata\";\nimport {\n assertNoRecordSchema,\n isStandardSchema,\n looksLikeJSONSchema,\n schemaToJsonSchema,\n} from \"../schema\";\nimport { assertValidName } from \"./validate-component-name\";\n\n/**\n * Checks if a JSON Schema represents an object type.\n * @param schema - The JSON Schema to check\n * @returns True if the schema is an object type\n */\nfunction isObjectSchema(schema: JSONSchema7): boolean {\n return schema.type === \"object\" || schema.properties !== undefined;\n}\n\n/**\n * Validates that a schema is an object type.\n * Throws an error if it's not.\n * @param schema - The schema to validate (Standard Schema or JSON Schema)\n * @param context - Description of where the schema is used (for error messages)\n */\nfunction assertObjectSchema(schema: unknown, context: string): void {\n let jsonSchema: JSONSchema7;\n\n if (isStandardSchema(schema)) {\n try {\n jsonSchema = schemaToJsonSchema(schema);\n } catch {\n // If conversion fails, we can't validate - let it fail later\n return;\n }\n } else if (looksLikeJSONSchema(schema)) {\n jsonSchema = schema;\n } else {\n // Unknown schema type, can't validate\n return;\n }\n\n if (!isObjectSchema(jsonSchema)) {\n throw new Error(\n `${context} must be an object schema (e.g., z.object({...})). ` +\n `Received type: \"${jsonSchema.type ?? \"unknown\"}\". ` +\n `Tool parameters are passed as a single object argument.`,\n );\n }\n}\n\n/**\n * Validates a tool before registration.\n * Throws an error if the tool is invalid.\n * @param tool - The tool to validate\n */\nexport function validateTool(tool: unknown): asserts tool is TamboTool {\n // Basic runtime type checks before narrowing\n if (!tool || typeof tool !== \"object\") {\n throw new Error(\"Tool must be an object\");\n }\n\n // Extract name for error messages (before we know it's valid)\n const toolName =\n \"name\" in tool && typeof tool.name === \"string\" ? tool.name : \"<unknown>\";\n\n // Check for deprecated toolSchema - throw error with migration instructions\n if (\"toolSchema\" in tool) {\n throw new Error(\n `Tool \"${toolName}\" uses deprecated \"toolSchema\" property. ` +\n `Migrate to \"inputSchema\" and \"outputSchema\" properties. ` +\n `See migration guide: https://tambo.ai/docs/migration/toolschema`,\n );\n }\n\n // Validate required properties exist\n if (!(\"name\" in tool) || typeof tool.name !== \"string\") {\n throw new Error(\"Tool must have a 'name' property of type string\");\n }\n\n if (!(\"description\" in tool) || typeof tool.description !== \"string\") {\n throw new Error(\n `Tool \"${tool.name}\" must have a 'description' property of type string`,\n );\n }\n\n if (!(\"tool\" in tool) || typeof tool.tool !== \"function\") {\n throw new Error(\n `Tool \"${tool.name}\" must have a 'tool' property of type function`,\n );\n }\n\n if (!(\"inputSchema\" in tool)) {\n throw new Error(`Tool \"${tool.name}\" must have an 'inputSchema' property`);\n }\n\n if (!(\"outputSchema\" in tool)) {\n throw new Error(`Tool \"${tool.name}\" must have an 'outputSchema' property`);\n }\n\n // Validate tool name format\n assertValidName(tool.name, \"tool\");\n\n // Validate tool schemas - inputSchema must be an object schema\n if (tool.inputSchema) {\n assertObjectSchema(tool.inputSchema, `inputSchema of tool \"${tool.name}\"`);\n assertNoRecordSchema(\n tool.inputSchema,\n `inputSchema of tool \"${tool.name}\"`,\n );\n }\n\n // Validate maxCalls if provided - must be a positive integer\n if (\n \"maxCalls\" in tool &&\n tool.maxCalls !== undefined &&\n tool.maxCalls !== null\n ) {\n const maxCalls = tool.maxCalls;\n if (\n typeof maxCalls !== \"number\" ||\n !Number.isInteger(maxCalls) ||\n maxCalls < 0\n ) {\n throw new Error(\n `maxCalls for tool \"${tool.name}\" must be a positive integer`,\n );\n }\n }\n}\n\n/**\n * Converts a props schema to a serialized JSON Schema format.\n * @param propsDefinition - Deprecated: legacy props definition (will log warning)\n * @param propsSchema - The props schema (Standard Schema or JSON Schema)\n * @param name - Component/tool name for error messages\n * @returns Serialized JSON Schema object\n */\nfunction getSerializedProps(\n propsDefinition: unknown,\n propsSchema: unknown,\n name: string,\n): Record<string, unknown> {\n if (propsDefinition) {\n console.warn(`propsDefinition is deprecated. Use propsSchema instead.`);\n return propsDefinition as Record<string, unknown>;\n }\n\n // Check for Standard Schema (Zod, Valibot, ArkType, etc.)\n if (isStandardSchema(propsSchema)) {\n try {\n return schemaToJsonSchema(propsSchema) as Record<string, unknown>;\n } catch (error) {\n console.error(\n `Error converting ${name} props schema to JSON Schema:`,\n error,\n );\n throw new Error(\n `Error converting ${name} props schema to JSON Schema: ${error}`,\n );\n }\n }\n\n // Check for JSON Schema\n if (looksLikeJSONSchema(propsSchema)) {\n return propsSchema as Record<string, unknown>;\n }\n\n throw new Error(`Invalid props schema for ${name}`);\n}\n\n/**\n * Validates a component and prepares its props for registration.\n * Throws an error if the component is invalid.\n * @param component - The component to validate and prepare\n * @returns Object containing the serialized props\n */\nexport function validateAndPrepareComponent(component: TamboComponent): {\n props: Record<string, unknown>;\n} {\n const { name, propsSchema, propsDefinition } = component;\n\n // Validate component name\n assertValidName(name, \"component\");\n\n // Validate that at least one props definition is provided\n if (!propsSchema && !propsDefinition) {\n throw new Error(\n `Component ${name} must have either propsSchema (recommended) or propsDefinition defined`,\n );\n }\n\n // Validate that only one props definition is provided\n if (propsSchema && propsDefinition) {\n throw new Error(\n `Component ${name} cannot have both propsSchema and propsDefinition defined. Use only one. We recommend using propsSchema.`,\n );\n }\n\n // Validate that the propsSchema does not include record types\n if (propsSchema) {\n assertNoRecordSchema(propsSchema, `propsSchema of component \"${name}\"`);\n }\n\n // Convert propsSchema to JSON Schema if it exists\n const props = getSerializedProps(propsDefinition, propsSchema, name);\n\n return { props };\n}\n\n/**\n * Validates a tool association between a component and tool.\n * Throws an error if the association is invalid.\n * @param componentName - The component name\n * @param toolName - The tool name\n * @param componentExists - Whether the component exists in the registry\n * @param toolExists - Whether the tool exists in the registry\n */\nexport function validateToolAssociation(\n componentName: string,\n toolName: string,\n componentExists: boolean,\n toolExists: boolean,\n): void {\n // Validate component and tool names\n assertValidName(componentName, \"component\");\n assertValidName(toolName, \"tool\");\n\n if (!componentExists) {\n throw new Error(`Component ${componentName} not found in registry`);\n }\n if (!toolExists) {\n throw new Error(`Tool ${toolName} not found in registry`);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"registry-validators.js","sourceRoot":"","sources":["../../src/util/registry-validators.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JSONSchema7 } from \"json-schema\";\nimport type { TamboComponent, TamboTool } from \"../model/component-metadata\";\nimport {\n assertNoRecordSchema,\n isStandardSchema,\n looksLikeJSONSchema,\n schemaToJsonSchema,\n} from \"../schema\";\nimport { assertValidName } from \"./validate-component-name\";\n\n/**\n * Checks if a JSON Schema represents an object type.\n * @param schema - The JSON Schema to check\n * @returns True if the schema is an object type\n */\nfunction isObjectSchema(schema: JSONSchema7): boolean {\n return schema.type === \"object\" || schema.properties !== undefined;\n}\n\n/**\n * Validates that a schema is an object type.\n * Throws an error if it's not.\n * @param schema - The schema to validate (Standard Schema or JSON Schema)\n * @param context - Description of where the schema is used (for error messages)\n */\nfunction assertObjectSchema(schema: unknown, context: string): void {\n let jsonSchema: JSONSchema7;\n\n if (isStandardSchema(schema)) {\n try {\n jsonSchema = schemaToJsonSchema(schema);\n } catch {\n // If conversion fails, we can't validate - let it fail later\n return;\n }\n } else if (looksLikeJSONSchema(schema)) {\n jsonSchema = schema;\n } else {\n // Unknown schema type, can't validate\n return;\n }\n\n if (!isObjectSchema(jsonSchema)) {\n throw new Error(\n `${context} must be an object schema (e.g., z.object({...})). ` +\n `Received type: \"${jsonSchema.type ?? \"unknown\"}\". ` +\n `Tool parameters are passed as a single object argument.`,\n );\n }\n}\n\n/**\n * Validates a tool before registration.\n * Throws an error if the tool is invalid.\n * @param tool - The tool to validate\n */\nexport function validateTool(tool: unknown): asserts tool is TamboTool {\n // Basic runtime type checks before narrowing\n if (!tool || typeof tool !== \"object\") {\n throw new Error(\"Tool must be an object\");\n }\n\n // Extract name for error messages (before we know it's valid)\n const toolName =\n \"name\" in tool && typeof tool.name === \"string\" ? tool.name : \"<unknown>\";\n\n // Check for deprecated toolSchema - throw error with migration instructions\n if (\"toolSchema\" in tool) {\n throw new Error(\n `Tool \"${toolName}\" uses deprecated \"toolSchema\" property. ` +\n `Migrate to \"inputSchema\" and \"outputSchema\" properties. ` +\n `See migration guide: https://docs.tambo.co/reference/react-sdk/migration/toolschema`,\n );\n }\n\n // Validate required properties exist\n if (!(\"name\" in tool) || typeof tool.name !== \"string\") {\n throw new Error(\"Tool must have a 'name' property of type string\");\n }\n\n if (!(\"description\" in tool) || typeof tool.description !== \"string\") {\n throw new Error(\n `Tool \"${tool.name}\" must have a 'description' property of type string`,\n );\n }\n\n if (!(\"tool\" in tool) || typeof tool.tool !== \"function\") {\n throw new Error(\n `Tool \"${tool.name}\" must have a 'tool' property of type function`,\n );\n }\n\n if (!(\"inputSchema\" in tool)) {\n throw new Error(`Tool \"${tool.name}\" must have an 'inputSchema' property`);\n }\n\n if (!(\"outputSchema\" in tool)) {\n throw new Error(`Tool \"${tool.name}\" must have an 'outputSchema' property`);\n }\n\n // Validate tool name format\n assertValidName(tool.name, \"tool\");\n\n // Validate tool schemas - inputSchema must be an object schema\n if (tool.inputSchema) {\n assertObjectSchema(tool.inputSchema, `inputSchema of tool \"${tool.name}\"`);\n assertNoRecordSchema(\n tool.inputSchema,\n `inputSchema of tool \"${tool.name}\"`,\n );\n }\n\n // Validate maxCalls if provided - must be a positive integer\n if (\n \"maxCalls\" in tool &&\n tool.maxCalls !== undefined &&\n tool.maxCalls !== null\n ) {\n const maxCalls = tool.maxCalls;\n if (\n typeof maxCalls !== \"number\" ||\n !Number.isInteger(maxCalls) ||\n maxCalls < 0\n ) {\n throw new Error(\n `maxCalls for tool \"${tool.name}\" must be a positive integer`,\n );\n }\n }\n}\n\n/**\n * Converts a props schema to a serialized JSON Schema format.\n * @param propsDefinition - Deprecated: legacy props definition (will log warning)\n * @param propsSchema - The props schema (Standard Schema or JSON Schema)\n * @param name - Component/tool name for error messages\n * @returns Serialized JSON Schema object\n */\nfunction getSerializedProps(\n propsDefinition: unknown,\n propsSchema: unknown,\n name: string,\n): Record<string, unknown> {\n if (propsDefinition) {\n console.warn(`propsDefinition is deprecated. Use propsSchema instead.`);\n return propsDefinition as Record<string, unknown>;\n }\n\n // Check for Standard Schema (Zod, Valibot, ArkType, etc.)\n if (isStandardSchema(propsSchema)) {\n try {\n return schemaToJsonSchema(propsSchema) as Record<string, unknown>;\n } catch (error) {\n console.error(\n `Error converting ${name} props schema to JSON Schema:`,\n error,\n );\n throw new Error(\n `Error converting ${name} props schema to JSON Schema: ${error}`,\n );\n }\n }\n\n // Check for JSON Schema\n if (looksLikeJSONSchema(propsSchema)) {\n return propsSchema as Record<string, unknown>;\n }\n\n throw new Error(`Invalid props schema for ${name}`);\n}\n\n/**\n * Validates a component and prepares its props for registration.\n * Throws an error if the component is invalid.\n * @param component - The component to validate and prepare\n * @returns Object containing the serialized props\n */\nexport function validateAndPrepareComponent(component: TamboComponent): {\n props: Record<string, unknown>;\n} {\n const { name, propsSchema, propsDefinition } = component;\n\n // Validate component name\n assertValidName(name, \"component\");\n\n // Validate that at least one props definition is provided\n if (!propsSchema && !propsDefinition) {\n throw new Error(\n `Component ${name} must have either propsSchema (recommended) or propsDefinition defined`,\n );\n }\n\n // Validate that only one props definition is provided\n if (propsSchema && propsDefinition) {\n throw new Error(\n `Component ${name} cannot have both propsSchema and propsDefinition defined. Use only one. We recommend using propsSchema.`,\n );\n }\n\n // Validate that the propsSchema does not include record types\n if (propsSchema) {\n assertNoRecordSchema(propsSchema, `propsSchema of component \"${name}\"`);\n }\n\n // Convert propsSchema to JSON Schema if it exists\n const props = getSerializedProps(propsDefinition, propsSchema, name);\n\n return { props };\n}\n\n/**\n * Validates a tool association between a component and tool.\n * Throws an error if the association is invalid.\n * @param componentName - The component name\n * @param toolName - The tool name\n * @param componentExists - Whether the component exists in the registry\n * @param toolExists - Whether the tool exists in the registry\n */\nexport function validateToolAssociation(\n componentName: string,\n toolName: string,\n componentExists: boolean,\n toolExists: boolean,\n): void {\n // Validate component and tool names\n assertValidName(componentName, \"component\");\n assertValidName(toolName, \"tool\");\n\n if (!componentExists) {\n throw new Error(`Component ${componentName} not found in registry`);\n }\n if (!toolExists) {\n throw new Error(`Tool ${toolName} not found in registry`);\n }\n}\n"]}
|
|
@@ -64,7 +64,7 @@ describe("resolveResourceContents", () => {
|
|
|
64
64
|
const createMockInternalServer = (serverKey) => ({
|
|
65
65
|
key: serverKey,
|
|
66
66
|
serverKey,
|
|
67
|
-
url: "https://api.tambo.
|
|
67
|
+
url: "https://api.tambo.co/mcp",
|
|
68
68
|
name: "__tambo_internal_mcp_server__",
|
|
69
69
|
transport: MCPTransport.HTTP,
|
|
70
70
|
serverType: ServerType.TAMBO_INTERNAL,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-content-resolver.test.js","sourceRoot":"","sources":["../../src/util/resource-content-resolver.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReadResourceResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { ServerType } from \"../mcp/mcp-constants\";\nimport type { McpServer } from \"../mcp/tambo-mcp-provider\";\nimport type { ResourceSource } from \"../model/resource-info\";\nimport { MCPTransport } from \"../mcp/mcp-client\";\n\nimport {\n resolveResourceContents,\n extractResourceUris,\n} from \"./resource-content-resolver\";\n\ndescribe(\"extractResourceUris\", () => {\n it(\"should extract a single resource URI\", () => {\n const text = \"Check @registry:file:///path/to/doc.txt\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"registry:file:///path/to/doc.txt\"]);\n });\n\n it(\"should extract multiple resource URIs\", () => {\n const text =\n \"Check @registry:file:///doc1.txt and @server-a:file:///doc2.txt\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\n \"registry:file:///doc1.txt\",\n \"server-a:file:///doc2.txt\",\n ]);\n });\n\n it(\"should extract resource URIs with internal server prefix\", () => {\n const text = \"Check @tambo-abc123:tambo:test://resource/1\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"tambo-abc123:tambo:test://resource/1\"]);\n });\n\n it(\"should extract resource URIs with hyphens in server key\", () => {\n const text = \"@my-mcp-server:file:///path/file.txt\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"my-mcp-server:file:///path/file.txt\"]);\n });\n\n it(\"should return empty array for text without resource references\", () => {\n const text = \"Just some regular text without @mentions\";\n const result = extractResourceUris(text);\n expect(result).toEqual([]);\n });\n\n it(\"should not extract malformed references without colon\", () => {\n const text = \"@server-without-colon is not a resource\";\n const result = extractResourceUris(text);\n expect(result).toEqual([]);\n });\n\n it(\"should handle URIs with multiple colons\", () => {\n const text = \"@server:http://example.com:8080/path\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"server:http://example.com:8080/path\"]);\n });\n});\n\ndescribe(\"resolveResourceContents\", () => {\n const createMockConnectedServer = (\n serverKey: string,\n readResource: jest.Mock,\n serverType: ServerType = ServerType.BROWSER_SIDE,\n ): McpServer =>\n ({\n key: `mcp-${serverKey}`,\n serverKey,\n url: `https://${serverKey}.example.com`,\n name: `MCP Server ${serverKey}`,\n transport: MCPTransport.HTTP,\n serverType,\n client: {\n client: {\n readResource,\n listResources: jest.fn().mockResolvedValue({ resources: [] }),\n listTools: jest.fn().mockResolvedValue({ tools: [] }),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n getPrompt: jest.fn().mockResolvedValue(null),\n callTool: jest.fn().mockResolvedValue(null),\n },\n close: jest.fn().mockResolvedValue(undefined),\n } as unknown as McpServer[\"client\"],\n }) as McpServer;\n\n const createMockInternalServer = (serverKey: string): McpServer =>\n ({\n key: serverKey,\n serverKey,\n url: \"https://api.tambo.ai/mcp\",\n name: \"__tambo_internal_mcp_server__\",\n transport: MCPTransport.HTTP,\n serverType: ServerType.TAMBO_INTERNAL,\n connectionError: undefined, // No client for internal servers\n }) as unknown as McpServer;\n\n const createMockResourceSource = (\n getResource: jest.Mock,\n ): ResourceSource => ({\n listResources: jest.fn().mockResolvedValue([]),\n getResource,\n });\n\n it(\"should resolve registry resources via resourceSource\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: \"file:///local/doc.txt\",\n mimeType: \"text/plain\",\n text: \"Registry document content\",\n },\n ],\n } satisfies ReadResourceResult);\n\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///local/doc.txt\"],\n [], // Registry resources don't need a server - they're handled directly\n resourceSource,\n );\n\n expect(mockGetResource).toHaveBeenCalledWith(\"file:///local/doc.txt\");\n expect(result.size).toBe(1);\n expect(result.get(\"registry:file:///local/doc.txt\")).toEqual({\n contents: [\n {\n uri: \"file:///local/doc.txt\",\n mimeType: \"text/plain\",\n text: \"Registry document content\",\n },\n ],\n });\n });\n\n it(\"should resolve client-side MCP resources via mcpServer\", async () => {\n const mockReadResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: \"file:///mcp/file.txt\",\n mimeType: \"text/plain\",\n text: \"MCP server content\",\n },\n ],\n } satisfies ReadResourceResult);\n\n const mcpServer = createMockConnectedServer(\"linear\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"linear:file:///mcp/file.txt\"],\n [mcpServer],\n undefined,\n );\n\n expect(mockReadResource).toHaveBeenCalledWith({\n uri: \"file:///mcp/file.txt\",\n });\n expect(result.size).toBe(1);\n expect(result.get(\"linear:file:///mcp/file.txt\")).toEqual({\n contents: [\n {\n uri: \"file:///mcp/file.txt\",\n mimeType: \"text/plain\",\n text: \"MCP server content\",\n },\n ],\n });\n });\n\n it(\"should skip internal server resources (serverType: TAMBO_INTERNAL)\", async () => {\n const mockGetResource = jest.fn();\n const resourceSource = createMockResourceSource(mockGetResource);\n const internalServer = createMockInternalServer(\"tambo-abc123\");\n\n const result = await resolveResourceContents(\n [\"tambo-abc123:tambo:test://resource/1\"],\n [internalServer],\n resourceSource,\n );\n\n // Should not call getResource for internal server resources\n expect(mockGetResource).not.toHaveBeenCalled();\n // Should return empty map since internal resources are skipped\n expect(result.size).toBe(0);\n });\n\n it(\"should resolve multiple resources in parallel\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [{ uri: \"file:///doc.txt\", text: \"registry content\" }],\n });\n const mockReadResource = jest.fn().mockResolvedValue({\n contents: [{ uri: \"file:///mcp.txt\", text: \"mcp content\" }],\n });\n\n const resourceSource = createMockResourceSource(mockGetResource);\n const mcpServer = createMockConnectedServer(\"mcp-server\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///doc.txt\", \"mcp-server:file:///mcp.txt\"],\n [mcpServer], // Only MCP server needed - registry handled directly\n resourceSource,\n );\n\n expect(result.size).toBe(2);\n expect(result.has(\"registry:file:///doc.txt\")).toBe(true);\n expect(result.has(\"mcp-server:file:///mcp.txt\")).toBe(true);\n });\n\n it(\"should handle mixed internal and client-side resources\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [{ uri: \"file:///doc.txt\", text: \"registry content\" }],\n });\n const resourceSource = createMockResourceSource(mockGetResource);\n const internalServer = createMockInternalServer(\"tambo-abc123\");\n\n const result = await resolveResourceContents(\n [\n \"registry:file:///doc.txt\", // client-side registry\n \"tambo-abc123:tambo:test://resource/1\", // internal - should skip\n ],\n [internalServer], // Only internal server needed - registry handled directly\n resourceSource,\n );\n\n // Only the registry resource should be resolved\n expect(mockGetResource).toHaveBeenCalledTimes(1);\n expect(result.size).toBe(1);\n expect(result.has(\"registry:file:///doc.txt\")).toBe(true);\n expect(result.has(\"tambo-abc123:tambo:test://resource/1\")).toBe(false);\n });\n\n it(\"should gracefully handle registry resource fetch failure\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n const mockGetResource = jest\n .fn()\n .mockRejectedValue(new Error(\"Resource not found\"));\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///missing.txt\"],\n [], // Registry resources don't need a server\n resourceSource,\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"Failed to fetch resource content for registry:file:///missing.txt:\",\n expect.any(Error),\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should gracefully handle MCP resource fetch failure\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n const mockReadResource = jest\n .fn()\n .mockRejectedValue(new Error(\"MCP server error\"));\n const mcpServer = createMockConnectedServer(\"linear\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"linear:file:///missing.txt\"],\n [mcpServer],\n undefined,\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"Failed to fetch resource content for linear:file:///missing.txt:\",\n expect.any(Error),\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should warn when no resourceSource available for registry resource\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n\n const result = await resolveResourceContents(\n [\"registry:file:///doc.txt\"],\n [], // Registry resources don't need a server\n undefined, // no resourceSource\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"No resource source available to resolve registry resource: registry:file:///doc.txt\",\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should warn when no server found for resource\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n\n const result = await resolveResourceContents(\n [\"unknown-server:file:///doc.txt\"],\n [], // no servers\n undefined,\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"No server found for resource: unknown-server:file:///doc.txt\",\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should handle resource content with blob data\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: \"file:///image.png\",\n mimeType: \"image/png\",\n blob: \"base64encodeddata\",\n },\n ],\n } satisfies ReadResourceResult);\n\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///image.png\"],\n [], // Registry resources don't need a server\n resourceSource,\n );\n\n expect(result.get(\"registry:file:///image.png\")).toEqual({\n contents: [\n {\n uri: \"file:///image.png\",\n mimeType: \"image/png\",\n blob: \"base64encodeddata\",\n },\n ],\n });\n });\n\n it(\"should handle URIs with no colon (invalid format)\", async () => {\n const result = await resolveResourceContents(\n [\"invalid-uri-no-colon\"],\n [],\n undefined,\n );\n\n expect(result.size).toBe(0);\n });\n\n it(\"should handle null content from getResource\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue(null);\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///doc.txt\"],\n [], // Registry resources don't need a server\n resourceSource,\n );\n\n expect(mockGetResource).toHaveBeenCalled();\n expect(result.size).toBe(0);\n });\n\n it(\"should handle null content from readResource\", async () => {\n const mockReadResource = jest.fn().mockResolvedValue(null);\n const mcpServer = createMockConnectedServer(\"linear\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"linear:file:///doc.txt\"],\n [mcpServer],\n undefined,\n );\n\n expect(mockReadResource).toHaveBeenCalled();\n expect(result.size).toBe(0);\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"resource-content-resolver.test.js","sourceRoot":"","sources":["../../src/util/resource-content-resolver.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReadResourceResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { ServerType } from \"../mcp/mcp-constants\";\nimport type { McpServer } from \"../mcp/tambo-mcp-provider\";\nimport type { ResourceSource } from \"../model/resource-info\";\nimport { MCPTransport } from \"../mcp/mcp-client\";\n\nimport {\n resolveResourceContents,\n extractResourceUris,\n} from \"./resource-content-resolver\";\n\ndescribe(\"extractResourceUris\", () => {\n it(\"should extract a single resource URI\", () => {\n const text = \"Check @registry:file:///path/to/doc.txt\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"registry:file:///path/to/doc.txt\"]);\n });\n\n it(\"should extract multiple resource URIs\", () => {\n const text =\n \"Check @registry:file:///doc1.txt and @server-a:file:///doc2.txt\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\n \"registry:file:///doc1.txt\",\n \"server-a:file:///doc2.txt\",\n ]);\n });\n\n it(\"should extract resource URIs with internal server prefix\", () => {\n const text = \"Check @tambo-abc123:tambo:test://resource/1\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"tambo-abc123:tambo:test://resource/1\"]);\n });\n\n it(\"should extract resource URIs with hyphens in server key\", () => {\n const text = \"@my-mcp-server:file:///path/file.txt\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"my-mcp-server:file:///path/file.txt\"]);\n });\n\n it(\"should return empty array for text without resource references\", () => {\n const text = \"Just some regular text without @mentions\";\n const result = extractResourceUris(text);\n expect(result).toEqual([]);\n });\n\n it(\"should not extract malformed references without colon\", () => {\n const text = \"@server-without-colon is not a resource\";\n const result = extractResourceUris(text);\n expect(result).toEqual([]);\n });\n\n it(\"should handle URIs with multiple colons\", () => {\n const text = \"@server:http://example.com:8080/path\";\n const result = extractResourceUris(text);\n expect(result).toEqual([\"server:http://example.com:8080/path\"]);\n });\n});\n\ndescribe(\"resolveResourceContents\", () => {\n const createMockConnectedServer = (\n serverKey: string,\n readResource: jest.Mock,\n serverType: ServerType = ServerType.BROWSER_SIDE,\n ): McpServer =>\n ({\n key: `mcp-${serverKey}`,\n serverKey,\n url: `https://${serverKey}.example.com`,\n name: `MCP Server ${serverKey}`,\n transport: MCPTransport.HTTP,\n serverType,\n client: {\n client: {\n readResource,\n listResources: jest.fn().mockResolvedValue({ resources: [] }),\n listTools: jest.fn().mockResolvedValue({ tools: [] }),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n getPrompt: jest.fn().mockResolvedValue(null),\n callTool: jest.fn().mockResolvedValue(null),\n },\n close: jest.fn().mockResolvedValue(undefined),\n } as unknown as McpServer[\"client\"],\n }) as McpServer;\n\n const createMockInternalServer = (serverKey: string): McpServer =>\n ({\n key: serverKey,\n serverKey,\n url: \"https://api.tambo.co/mcp\",\n name: \"__tambo_internal_mcp_server__\",\n transport: MCPTransport.HTTP,\n serverType: ServerType.TAMBO_INTERNAL,\n connectionError: undefined, // No client for internal servers\n }) as unknown as McpServer;\n\n const createMockResourceSource = (\n getResource: jest.Mock,\n ): ResourceSource => ({\n listResources: jest.fn().mockResolvedValue([]),\n getResource,\n });\n\n it(\"should resolve registry resources via resourceSource\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: \"file:///local/doc.txt\",\n mimeType: \"text/plain\",\n text: \"Registry document content\",\n },\n ],\n } satisfies ReadResourceResult);\n\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///local/doc.txt\"],\n [], // Registry resources don't need a server - they're handled directly\n resourceSource,\n );\n\n expect(mockGetResource).toHaveBeenCalledWith(\"file:///local/doc.txt\");\n expect(result.size).toBe(1);\n expect(result.get(\"registry:file:///local/doc.txt\")).toEqual({\n contents: [\n {\n uri: \"file:///local/doc.txt\",\n mimeType: \"text/plain\",\n text: \"Registry document content\",\n },\n ],\n });\n });\n\n it(\"should resolve client-side MCP resources via mcpServer\", async () => {\n const mockReadResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: \"file:///mcp/file.txt\",\n mimeType: \"text/plain\",\n text: \"MCP server content\",\n },\n ],\n } satisfies ReadResourceResult);\n\n const mcpServer = createMockConnectedServer(\"linear\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"linear:file:///mcp/file.txt\"],\n [mcpServer],\n undefined,\n );\n\n expect(mockReadResource).toHaveBeenCalledWith({\n uri: \"file:///mcp/file.txt\",\n });\n expect(result.size).toBe(1);\n expect(result.get(\"linear:file:///mcp/file.txt\")).toEqual({\n contents: [\n {\n uri: \"file:///mcp/file.txt\",\n mimeType: \"text/plain\",\n text: \"MCP server content\",\n },\n ],\n });\n });\n\n it(\"should skip internal server resources (serverType: TAMBO_INTERNAL)\", async () => {\n const mockGetResource = jest.fn();\n const resourceSource = createMockResourceSource(mockGetResource);\n const internalServer = createMockInternalServer(\"tambo-abc123\");\n\n const result = await resolveResourceContents(\n [\"tambo-abc123:tambo:test://resource/1\"],\n [internalServer],\n resourceSource,\n );\n\n // Should not call getResource for internal server resources\n expect(mockGetResource).not.toHaveBeenCalled();\n // Should return empty map since internal resources are skipped\n expect(result.size).toBe(0);\n });\n\n it(\"should resolve multiple resources in parallel\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [{ uri: \"file:///doc.txt\", text: \"registry content\" }],\n });\n const mockReadResource = jest.fn().mockResolvedValue({\n contents: [{ uri: \"file:///mcp.txt\", text: \"mcp content\" }],\n });\n\n const resourceSource = createMockResourceSource(mockGetResource);\n const mcpServer = createMockConnectedServer(\"mcp-server\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///doc.txt\", \"mcp-server:file:///mcp.txt\"],\n [mcpServer], // Only MCP server needed - registry handled directly\n resourceSource,\n );\n\n expect(result.size).toBe(2);\n expect(result.has(\"registry:file:///doc.txt\")).toBe(true);\n expect(result.has(\"mcp-server:file:///mcp.txt\")).toBe(true);\n });\n\n it(\"should handle mixed internal and client-side resources\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [{ uri: \"file:///doc.txt\", text: \"registry content\" }],\n });\n const resourceSource = createMockResourceSource(mockGetResource);\n const internalServer = createMockInternalServer(\"tambo-abc123\");\n\n const result = await resolveResourceContents(\n [\n \"registry:file:///doc.txt\", // client-side registry\n \"tambo-abc123:tambo:test://resource/1\", // internal - should skip\n ],\n [internalServer], // Only internal server needed - registry handled directly\n resourceSource,\n );\n\n // Only the registry resource should be resolved\n expect(mockGetResource).toHaveBeenCalledTimes(1);\n expect(result.size).toBe(1);\n expect(result.has(\"registry:file:///doc.txt\")).toBe(true);\n expect(result.has(\"tambo-abc123:tambo:test://resource/1\")).toBe(false);\n });\n\n it(\"should gracefully handle registry resource fetch failure\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n const mockGetResource = jest\n .fn()\n .mockRejectedValue(new Error(\"Resource not found\"));\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///missing.txt\"],\n [], // Registry resources don't need a server\n resourceSource,\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"Failed to fetch resource content for registry:file:///missing.txt:\",\n expect.any(Error),\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should gracefully handle MCP resource fetch failure\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n const mockReadResource = jest\n .fn()\n .mockRejectedValue(new Error(\"MCP server error\"));\n const mcpServer = createMockConnectedServer(\"linear\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"linear:file:///missing.txt\"],\n [mcpServer],\n undefined,\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"Failed to fetch resource content for linear:file:///missing.txt:\",\n expect.any(Error),\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should warn when no resourceSource available for registry resource\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n\n const result = await resolveResourceContents(\n [\"registry:file:///doc.txt\"],\n [], // Registry resources don't need a server\n undefined, // no resourceSource\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"No resource source available to resolve registry resource: registry:file:///doc.txt\",\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should warn when no server found for resource\", async () => {\n const consoleSpy = jest.spyOn(console, \"warn\").mockImplementation();\n\n const result = await resolveResourceContents(\n [\"unknown-server:file:///doc.txt\"],\n [], // no servers\n undefined,\n );\n\n expect(consoleSpy).toHaveBeenCalledWith(\n \"No server found for resource: unknown-server:file:///doc.txt\",\n );\n expect(result.size).toBe(0);\n\n consoleSpy.mockRestore();\n });\n\n it(\"should handle resource content with blob data\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: \"file:///image.png\",\n mimeType: \"image/png\",\n blob: \"base64encodeddata\",\n },\n ],\n } satisfies ReadResourceResult);\n\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///image.png\"],\n [], // Registry resources don't need a server\n resourceSource,\n );\n\n expect(result.get(\"registry:file:///image.png\")).toEqual({\n contents: [\n {\n uri: \"file:///image.png\",\n mimeType: \"image/png\",\n blob: \"base64encodeddata\",\n },\n ],\n });\n });\n\n it(\"should handle URIs with no colon (invalid format)\", async () => {\n const result = await resolveResourceContents(\n [\"invalid-uri-no-colon\"],\n [],\n undefined,\n );\n\n expect(result.size).toBe(0);\n });\n\n it(\"should handle null content from getResource\", async () => {\n const mockGetResource = jest.fn().mockResolvedValue(null);\n const resourceSource = createMockResourceSource(mockGetResource);\n\n const result = await resolveResourceContents(\n [\"registry:file:///doc.txt\"],\n [], // Registry resources don't need a server\n resourceSource,\n );\n\n expect(mockGetResource).toHaveBeenCalled();\n expect(result.size).toBe(0);\n });\n\n it(\"should handle null content from readResource\", async () => {\n const mockReadResource = jest.fn().mockResolvedValue(null);\n const mcpServer = createMockConnectedServer(\"linear\", mockReadResource);\n\n const result = await resolveResourceContents(\n [\"linear:file:///doc.txt\"],\n [mcpServer],\n undefined,\n );\n\n expect(mockReadResource).toHaveBeenCalled();\n expect(result.size).toBe(0);\n });\n});\n"]}
|
|
@@ -35,7 +35,7 @@ function createMockRegistry() {
|
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
|
-
* Wrapper that provides the minimal
|
|
38
|
+
* Wrapper that provides the minimal provider tree for interactables:
|
|
39
39
|
* TamboRegistryContext > TamboContextHelpersProvider > TamboInteractableProvider
|
|
40
40
|
*/
|
|
41
41
|
function V1InteractableWrapper({ children, registry, }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v1-interactables.test.js","sourceRoot":"","sources":["../../../src/v1/__tests__/v1-interactables.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { act, render, renderHook, screen } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod/v3\";\nimport { withTamboInteractable } from \"../../hoc/with-tambo-interactable\";\nimport { useTamboInteractable } from \"../../providers/tambo-interactable-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport {\n TamboRegistryContext,\n type TamboRegistryContext as TamboRegistryContextType,\n} from \"../../providers/tambo-registry-provider\";\nimport { TamboContextHelpersProvider } from \"../../providers/tambo-context-helpers-provider\";\nimport { TamboInteractableProvider } from \"../../providers/tambo-interactable-provider\";\n\n// Minimal registry mock that captures registered tools\nfunction createMockRegistry() {\n const toolRegistry: Record<string, unknown> = {};\n return {\n value: {\n componentList: {},\n toolRegistry,\n componentToolAssociations: {},\n mcpServerInfos: [],\n resources: [],\n resourceSource: null,\n onCallUnregisteredTool: undefined,\n registerComponent: jest.fn(),\n registerTool: jest.fn((tool: { name: string }) => {\n toolRegistry[tool.name] = tool;\n }),\n registerTools: jest.fn(),\n addToolAssociation: jest.fn(),\n registerMcpServer: jest.fn(),\n registerMcpServers: jest.fn(),\n registerResource: jest.fn(),\n registerResources: jest.fn(),\n registerResourceSource: jest.fn(),\n } as unknown as TamboRegistryContextType,\n getRegisteredToolNames: () => Object.keys(toolRegistry),\n };\n}\n\n/**\n * Wrapper that provides the minimal V1-compatible provider tree for interactables:\n * TamboRegistryContext > TamboContextHelpersProvider > TamboInteractableProvider\n */\nfunction V1InteractableWrapper({\n children,\n registry,\n}: {\n children: React.ReactNode;\n registry: TamboRegistryContextType;\n}) {\n return (\n <TamboRegistryContext.Provider value={registry}>\n <TamboContextHelpersProvider>\n <TamboInteractableProvider>{children}</TamboInteractableProvider>\n </TamboContextHelpersProvider>\n </TamboRegistryContext.Provider>\n );\n}\n\ndescribe(\"V1 Interactables Integration\", () => {\n it(\"registers update_component_props and update_component_state tools when an interactable is added\", () => {\n const mockRegistry = createMockRegistry();\n\n const { result } = renderHook(() => useTamboInteractable(), {\n wrapper: ({ children }) => (\n <V1InteractableWrapper registry={mockRegistry.value}>\n {children}\n </V1InteractableWrapper>\n ),\n });\n\n act(() => {\n result.current.addInteractableComponent({\n name: \"TestWidget\",\n description: \"A test widget\",\n component: () => <div>widget</div>,\n props: { label: \"hello\" },\n propsSchema: z.object({ label: z.string() }),\n });\n });\n\n const toolNames = mockRegistry.getRegisteredToolNames();\n expect(\n toolNames.some((n) => n.startsWith(\"update_component_props_TestWidget\")),\n ).toBe(true);\n expect(\n toolNames.some((n) => n.startsWith(\"update_component_state_TestWidget\")),\n ).toBe(true);\n });\n\n it(\"registers interactables context helper that includes component info\", async () => {\n const mockRegistry = createMockRegistry();\n\n const { result } = renderHook(\n () => ({\n interactable: useTamboInteractable(),\n helpers: useTamboContextHelpers(),\n }),\n {\n wrapper: ({ children }) => (\n <V1InteractableWrapper registry={mockRegistry.value}>\n {children}\n </V1InteractableWrapper>\n ),\n },\n );\n\n // Add an interactable component\n act(() => {\n result.current.interactable.addInteractableComponent({\n name: \"InfoCard\",\n description: \"An info card\",\n component: () => <div>card</div>,\n props: { title: \"Test\" },\n });\n });\n\n // Get additional context - should include interactable info\n const contexts = await act(async () => {\n return await result.current.helpers.getAdditionalContext();\n });\n\n const interactablesContext = contexts.find(\n (c) => c.name === \"interactables\",\n );\n expect(interactablesContext).toBeDefined();\n expect(interactablesContext?.context).toBeDefined();\n });\n\n it(\"renders an interactable component via withTamboInteractable HOC\", () => {\n const mockRegistry = createMockRegistry();\n\n interface CardProps {\n title: string;\n }\n\n const Card: React.FC<CardProps> = ({ title }) => (\n <div data-testid=\"card-title\">{title}</div>\n );\n\n const InteractableCard = withTamboInteractable(Card, {\n componentName: \"Card\",\n description: \"A card component\",\n propsSchema: z.object({ title: z.string() }),\n });\n\n render(\n <V1InteractableWrapper registry={mockRegistry.value}>\n <InteractableCard title=\"Hello V1\" />\n </V1InteractableWrapper>,\n );\n\n expect(screen.getByTestId(\"card-title\")).toHaveTextContent(\"Hello V1\");\n });\n\n it(\"updates component props via the interactable provider\", () => {\n const mockRegistry = createMockRegistry();\n\n interface CounterProps {\n count: number;\n }\n\n const Counter: React.FC<CounterProps> = ({ count }) => (\n <div data-testid=\"count\">{count}</div>\n );\n\n const InteractableCounter = withTamboInteractable(Counter, {\n componentName: \"Counter\",\n description: \"A counter\",\n propsSchema: z.object({ count: z.number() }),\n });\n\n // Inner component that triggers prop updates\n function TestHarness() {\n const { interactableComponents, updateInteractableComponentProps } =\n useTamboInteractable();\n const component = interactableComponents[0];\n\n return (\n <div>\n <InteractableCounter count={0} />\n {component && (\n <button\n data-testid=\"update-btn\"\n onClick={() =>\n updateInteractableComponentProps(component.id, { count: 42 })\n }\n >\n Update\n </button>\n )}\n </div>\n );\n }\n\n render(\n <V1InteractableWrapper registry={mockRegistry.value}>\n <TestHarness />\n </V1InteractableWrapper>,\n );\n\n // Initial render\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"0\");\n\n // Update props via the interactable provider\n act(() => {\n screen.getByTestId(\"update-btn\").click();\n });\n\n // The interactable should reflect updated props\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"42\");\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"v1-interactables.test.js","sourceRoot":"","sources":["../../../src/v1/__tests__/v1-interactables.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { act, render, renderHook, screen } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod/v3\";\nimport { withTamboInteractable } from \"../../hoc/with-tambo-interactable\";\nimport { useTamboInteractable } from \"../../providers/tambo-interactable-provider\";\nimport { useTamboContextHelpers } from \"../../providers/tambo-context-helpers-provider\";\nimport {\n TamboRegistryContext,\n type TamboRegistryContext as TamboRegistryContextType,\n} from \"../../providers/tambo-registry-provider\";\nimport { TamboContextHelpersProvider } from \"../../providers/tambo-context-helpers-provider\";\nimport { TamboInteractableProvider } from \"../../providers/tambo-interactable-provider\";\n\n// Minimal registry mock that captures registered tools\nfunction createMockRegistry() {\n const toolRegistry: Record<string, unknown> = {};\n return {\n value: {\n componentList: {},\n toolRegistry,\n componentToolAssociations: {},\n mcpServerInfos: [],\n resources: [],\n resourceSource: null,\n onCallUnregisteredTool: undefined,\n registerComponent: jest.fn(),\n registerTool: jest.fn((tool: { name: string }) => {\n toolRegistry[tool.name] = tool;\n }),\n registerTools: jest.fn(),\n addToolAssociation: jest.fn(),\n registerMcpServer: jest.fn(),\n registerMcpServers: jest.fn(),\n registerResource: jest.fn(),\n registerResources: jest.fn(),\n registerResourceSource: jest.fn(),\n } as unknown as TamboRegistryContextType,\n getRegisteredToolNames: () => Object.keys(toolRegistry),\n };\n}\n\n/**\n * Wrapper that provides the minimal provider tree for interactables:\n * TamboRegistryContext > TamboContextHelpersProvider > TamboInteractableProvider\n */\nfunction V1InteractableWrapper({\n children,\n registry,\n}: {\n children: React.ReactNode;\n registry: TamboRegistryContextType;\n}) {\n return (\n <TamboRegistryContext.Provider value={registry}>\n <TamboContextHelpersProvider>\n <TamboInteractableProvider>{children}</TamboInteractableProvider>\n </TamboContextHelpersProvider>\n </TamboRegistryContext.Provider>\n );\n}\n\ndescribe(\"V1 Interactables Integration\", () => {\n it(\"registers update_component_props and update_component_state tools when an interactable is added\", () => {\n const mockRegistry = createMockRegistry();\n\n const { result } = renderHook(() => useTamboInteractable(), {\n wrapper: ({ children }) => (\n <V1InteractableWrapper registry={mockRegistry.value}>\n {children}\n </V1InteractableWrapper>\n ),\n });\n\n act(() => {\n result.current.addInteractableComponent({\n name: \"TestWidget\",\n description: \"A test widget\",\n component: () => <div>widget</div>,\n props: { label: \"hello\" },\n propsSchema: z.object({ label: z.string() }),\n });\n });\n\n const toolNames = mockRegistry.getRegisteredToolNames();\n expect(\n toolNames.some((n) => n.startsWith(\"update_component_props_TestWidget\")),\n ).toBe(true);\n expect(\n toolNames.some((n) => n.startsWith(\"update_component_state_TestWidget\")),\n ).toBe(true);\n });\n\n it(\"registers interactables context helper that includes component info\", async () => {\n const mockRegistry = createMockRegistry();\n\n const { result } = renderHook(\n () => ({\n interactable: useTamboInteractable(),\n helpers: useTamboContextHelpers(),\n }),\n {\n wrapper: ({ children }) => (\n <V1InteractableWrapper registry={mockRegistry.value}>\n {children}\n </V1InteractableWrapper>\n ),\n },\n );\n\n // Add an interactable component\n act(() => {\n result.current.interactable.addInteractableComponent({\n name: \"InfoCard\",\n description: \"An info card\",\n component: () => <div>card</div>,\n props: { title: \"Test\" },\n });\n });\n\n // Get additional context - should include interactable info\n const contexts = await act(async () => {\n return await result.current.helpers.getAdditionalContext();\n });\n\n const interactablesContext = contexts.find(\n (c) => c.name === \"interactables\",\n );\n expect(interactablesContext).toBeDefined();\n expect(interactablesContext?.context).toBeDefined();\n });\n\n it(\"renders an interactable component via withTamboInteractable HOC\", () => {\n const mockRegistry = createMockRegistry();\n\n interface CardProps {\n title: string;\n }\n\n const Card: React.FC<CardProps> = ({ title }) => (\n <div data-testid=\"card-title\">{title}</div>\n );\n\n const InteractableCard = withTamboInteractable(Card, {\n componentName: \"Card\",\n description: \"A card component\",\n propsSchema: z.object({ title: z.string() }),\n });\n\n render(\n <V1InteractableWrapper registry={mockRegistry.value}>\n <InteractableCard title=\"Hello V1\" />\n </V1InteractableWrapper>,\n );\n\n expect(screen.getByTestId(\"card-title\")).toHaveTextContent(\"Hello V1\");\n });\n\n it(\"updates component props via the interactable provider\", () => {\n const mockRegistry = createMockRegistry();\n\n interface CounterProps {\n count: number;\n }\n\n const Counter: React.FC<CounterProps> = ({ count }) => (\n <div data-testid=\"count\">{count}</div>\n );\n\n const InteractableCounter = withTamboInteractable(Counter, {\n componentName: \"Counter\",\n description: \"A counter\",\n propsSchema: z.object({ count: z.number() }),\n });\n\n // Inner component that triggers prop updates\n function TestHarness() {\n const { interactableComponents, updateInteractableComponentProps } =\n useTamboInteractable();\n const component = interactableComponents[0];\n\n return (\n <div>\n <InteractableCounter count={0} />\n {component && (\n <button\n data-testid=\"update-btn\"\n onClick={() =>\n updateInteractableComponentProps(component.id, { count: 42 })\n }\n >\n Update\n </button>\n )}\n </div>\n );\n }\n\n render(\n <V1InteractableWrapper registry={mockRegistry.value}>\n <TestHarness />\n </V1InteractableWrapper>,\n );\n\n // Initial render\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"0\");\n\n // Update props via the interactable provider\n act(() => {\n screen.getByTestId(\"update-btn\").click();\n });\n\n // The interactable should reflect updated props\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"42\");\n });\n});\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React, { type FC } from "react";
|
|
2
|
-
import type {
|
|
3
|
-
export interface
|
|
2
|
+
import type { TamboComponentContent } from "../types/message.js";
|
|
3
|
+
export interface ComponentRendererProps {
|
|
4
4
|
/**
|
|
5
|
-
* The component content block from a
|
|
5
|
+
* The component content block from a message
|
|
6
6
|
*/
|
|
7
|
-
content:
|
|
7
|
+
content: TamboComponentContent;
|
|
8
8
|
/**
|
|
9
9
|
* The thread ID the component belongs to
|
|
10
10
|
*/
|
|
@@ -25,15 +25,15 @@ export interface V1ComponentRendererProps {
|
|
|
25
25
|
* The component instance is preserved across re-renders as long as React's
|
|
26
26
|
* reconciliation keeps this wrapper mounted (use content.id as key).
|
|
27
27
|
*
|
|
28
|
-
* Wraps the rendered component with
|
|
29
|
-
* like
|
|
30
|
-
* @returns The rendered component wrapped in
|
|
28
|
+
* Wraps the rendered component with ComponentContentProvider so that hooks
|
|
29
|
+
* like useTamboComponentState can access component context.
|
|
30
|
+
* @returns The rendered component wrapped in ComponentContentProvider, or fallback if not found
|
|
31
31
|
* @example
|
|
32
32
|
* ```tsx
|
|
33
33
|
* function MessageContent({ content }: { content: Content }) {
|
|
34
34
|
* if (content.type === 'component') {
|
|
35
35
|
* return (
|
|
36
|
-
* <
|
|
36
|
+
* <ComponentRenderer
|
|
37
37
|
* key={content.id}
|
|
38
38
|
* content={content}
|
|
39
39
|
* fallback={<div>Unknown component: {content.name}</div>}
|
|
@@ -44,5 +44,5 @@ export interface V1ComponentRendererProps {
|
|
|
44
44
|
* }
|
|
45
45
|
* ```
|
|
46
46
|
*/
|
|
47
|
-
export declare const
|
|
47
|
+
export declare const ComponentRenderer: FC<ComponentRendererProps>;
|
|
48
48
|
//# sourceMappingURL=v1-component-renderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v1-component-renderer.d.ts","sourceRoot":"","sources":["../../../src/v1/components/v1-component-renderer.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,EAAuB,MAAM,OAAO,CAAC;AAK5D,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"v1-component-renderer.d.ts","sourceRoot":"","sources":["../../../src/v1/components/v1-component-renderer.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,EAAuB,MAAM,OAAO,CAAC;AAK5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAG9D,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,OAAO,EAAE,qBAAqB,CAAC;IAE/B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAoFxD,CAAC"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Component Renderer
|
|
4
4
|
*
|
|
5
5
|
* A wrapper component that renders a component from the registry based on
|
|
6
6
|
* component content block data. Uses React's normal reconciliation to maintain
|
|
7
7
|
* component identity - as long as the key stays stable, the component instance
|
|
8
8
|
* is preserved.
|
|
9
9
|
*
|
|
10
|
-
* Wraps the component with
|
|
11
|
-
*
|
|
10
|
+
* Wraps the component with ComponentContentProvider so that hooks like
|
|
11
|
+
* useTamboComponentState can access component context.
|
|
12
12
|
*/
|
|
13
13
|
import { parse } from "partial-json";
|
|
14
14
|
import React, { useMemo, useContext } from "react";
|
|
@@ -16,7 +16,7 @@ import { TamboRegistryContext } from "../../providers/tambo-registry-provider.js
|
|
|
16
16
|
import { isStandardSchema } from "../../schema/index.js";
|
|
17
17
|
import { isPromise } from "../../util/is-promise.js";
|
|
18
18
|
import { getComponentFromRegistry } from "../../util/registry.js";
|
|
19
|
-
import {
|
|
19
|
+
import { ComponentContentProvider } from "../utils/component-renderer.js";
|
|
20
20
|
/**
|
|
21
21
|
* Renders a component from the registry based on component content block data.
|
|
22
22
|
*
|
|
@@ -24,15 +24,15 @@ import { V1ComponentContentProvider } from "../utils/component-renderer.js";
|
|
|
24
24
|
* The component instance is preserved across re-renders as long as React's
|
|
25
25
|
* reconciliation keeps this wrapper mounted (use content.id as key).
|
|
26
26
|
*
|
|
27
|
-
* Wraps the rendered component with
|
|
28
|
-
* like
|
|
29
|
-
* @returns The rendered component wrapped in
|
|
27
|
+
* Wraps the rendered component with ComponentContentProvider so that hooks
|
|
28
|
+
* like useTamboComponentState can access component context.
|
|
29
|
+
* @returns The rendered component wrapped in ComponentContentProvider, or fallback if not found
|
|
30
30
|
* @example
|
|
31
31
|
* ```tsx
|
|
32
32
|
* function MessageContent({ content }: { content: Content }) {
|
|
33
33
|
* if (content.type === 'component') {
|
|
34
34
|
* return (
|
|
35
|
-
* <
|
|
35
|
+
* <ComponentRenderer
|
|
36
36
|
* key={content.id}
|
|
37
37
|
* content={content}
|
|
38
38
|
* fallback={<div>Unknown component: {content.name}</div>}
|
|
@@ -43,7 +43,7 @@ import { V1ComponentContentProvider } from "../utils/component-renderer.js";
|
|
|
43
43
|
* }
|
|
44
44
|
* ```
|
|
45
45
|
*/
|
|
46
|
-
export const
|
|
46
|
+
export const ComponentRenderer = ({ content, threadId, messageId, fallback = null, }) => {
|
|
47
47
|
const registry = useContext(TamboRegistryContext);
|
|
48
48
|
// Memoize the rendered element - only recreates when props change
|
|
49
49
|
const element = useMemo(() => {
|
|
@@ -71,7 +71,7 @@ export const V1ComponentRenderer = ({ content, threadId, messageId, fallback = n
|
|
|
71
71
|
return React.createElement(registeredComponent.component, validatedProps);
|
|
72
72
|
}
|
|
73
73
|
catch (error) {
|
|
74
|
-
console.error("[
|
|
74
|
+
console.error("[ComponentRenderer] Failed to render component", {
|
|
75
75
|
threadId,
|
|
76
76
|
messageId,
|
|
77
77
|
componentId: content.id,
|
|
@@ -94,7 +94,7 @@ export const V1ComponentRenderer = ({ content, threadId, messageId, fallback = n
|
|
|
94
94
|
if (element === null) {
|
|
95
95
|
return React.createElement(React.Fragment, null, fallback);
|
|
96
96
|
}
|
|
97
|
-
// Wrap with provider so hooks like
|
|
98
|
-
return (React.createElement(
|
|
97
|
+
// Wrap with provider so hooks like useTamboComponentState work
|
|
98
|
+
return (React.createElement(ComponentContentProvider, { componentId: content.id, threadId: threadId, messageId: messageId, componentName: content.name }, element));
|
|
99
99
|
};
|
|
100
100
|
//# sourceMappingURL=v1-component-renderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v1-component-renderer.js","sourceRoot":"","sources":["../../../src/v1/components/v1-component-renderer.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,KAAK,EAAE,EAAW,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"v1-component-renderer.js","sourceRoot":"","sources":["../../../src/v1/components/v1-component-renderer.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * Component Renderer\n *\n * A wrapper component that renders a component from the registry based on\n * component content block data. Uses React's normal reconciliation to maintain\n * component identity - as long as the key stays stable, the component instance\n * is preserved.\n *\n * Wraps the component with ComponentContentProvider so that hooks like\n * useTamboComponentState can access component context.\n */\n\nimport { parse } from \"partial-json\";\nimport React, { type FC, useMemo, useContext } from \"react\";\nimport { TamboRegistryContext } from \"../../providers/tambo-registry-provider\";\nimport { isStandardSchema } from \"../../schema\";\nimport { isPromise } from \"../../util/is-promise\";\nimport { getComponentFromRegistry } from \"../../util/registry\";\nimport type { TamboComponentContent } from \"../types/message\";\nimport { ComponentContentProvider } from \"../utils/component-renderer\";\n\nexport interface ComponentRendererProps {\n /**\n * The component content block from a message\n */\n content: TamboComponentContent;\n\n /**\n * The thread ID the component belongs to\n */\n threadId: string;\n\n /**\n * The message ID the component belongs to\n */\n messageId: string;\n\n /**\n * Optional fallback to render if component is not found in registry\n */\n fallback?: React.ReactNode;\n}\n\n/**\n * Renders a component from the registry based on component content block data.\n *\n * Use this component in your message renderer to display AI-generated components.\n * The component instance is preserved across re-renders as long as React's\n * reconciliation keeps this wrapper mounted (use content.id as key).\n *\n * Wraps the rendered component with ComponentContentProvider so that hooks\n * like useTamboComponentState can access component context.\n * @returns The rendered component wrapped in ComponentContentProvider, or fallback if not found\n * @example\n * ```tsx\n * function MessageContent({ content }: { content: Content }) {\n * if (content.type === 'component') {\n * return (\n * <ComponentRenderer\n * key={content.id}\n * content={content}\n * fallback={<div>Unknown component: {content.name}</div>}\n * />\n * );\n * }\n * // ... handle other content types\n * }\n * ```\n */\nexport const ComponentRenderer: FC<ComponentRendererProps> = ({\n content,\n threadId,\n messageId,\n fallback = null,\n}) => {\n const registry = useContext(TamboRegistryContext);\n\n // Memoize the rendered element - only recreates when props change\n const element = useMemo(() => {\n try {\n const registeredComponent = getComponentFromRegistry(\n content.name,\n registry.componentList,\n );\n\n // Parse props (handles partial JSON during streaming)\n const propsJson = JSON.stringify(content.props ?? {});\n const parsedProps = parse(propsJson);\n\n let validatedProps: Record<string, unknown> = parsedProps as Record<\n string,\n unknown\n >;\n\n // Validate props if schema is present\n if (isStandardSchema(registeredComponent.props)) {\n const result =\n registeredComponent.props[\"~standard\"].validate(parsedProps);\n\n if (isPromise(result)) {\n // Async validation not supported - skip validation\n console.warn(\n `Async schema validation not supported for component ${content.name}`,\n );\n } else if (\"value\" in result) {\n validatedProps = result.value as Record<string, unknown>;\n } else {\n // Validation failed - log warning but still render with raw props\n console.warn(\n `Props validation failed for component ${content.name}:`,\n result.issues?.[0]?.message,\n );\n }\n }\n\n return React.createElement(registeredComponent.component, validatedProps);\n } catch (error) {\n console.error(\"[ComponentRenderer] Failed to render component\", {\n threadId,\n messageId,\n componentId: content.id,\n componentName: content.name,\n streamingState: content.streamingState,\n props: content.props,\n error,\n });\n return null;\n }\n }, [\n content.id,\n content.name,\n content.props,\n content.streamingState,\n messageId,\n threadId,\n registry.componentList,\n ]);\n\n if (element === null) {\n return <>{fallback}</>;\n }\n\n // Wrap with provider so hooks like useTamboComponentState work\n return (\n <ComponentContentProvider\n componentId={content.id}\n threadId={threadId}\n messageId={messageId}\n componentName={content.name}\n >\n {element}\n </ComponentContentProvider>\n );\n};\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { render, screen } from "@testing-library/react";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
-
import {
|
|
4
|
+
import { ComponentRenderer } from "./v1-component-renderer.js";
|
|
5
5
|
import { TamboRegistryContext } from "../../providers/tambo-registry-provider.js";
|
|
6
6
|
// Simple test component
|
|
7
7
|
const TestComponent = ({ title, count, }) => (React.createElement("div", { "data-testid": "test-component" },
|
|
@@ -35,7 +35,7 @@ function createMockRegistry(componentList = {}) {
|
|
|
35
35
|
registerResourceSource: jest.fn(),
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
-
describe("
|
|
38
|
+
describe("ComponentRenderer", () => {
|
|
39
39
|
function withMockedConsoleError(fn) {
|
|
40
40
|
const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation();
|
|
41
41
|
try {
|
|
@@ -63,7 +63,7 @@ describe("V1ComponentRenderer", () => {
|
|
|
63
63
|
},
|
|
64
64
|
});
|
|
65
65
|
render(React.createElement(TamboRegistryContext.Provider, { value: registry },
|
|
66
|
-
React.createElement(
|
|
66
|
+
React.createElement(ComponentRenderer, { content: baseContent, threadId: "thread_123", messageId: "msg_456" })));
|
|
67
67
|
expect(screen.getByTestId("test-component")).toBeInTheDocument();
|
|
68
68
|
expect(screen.getByTestId("title")).toHaveTextContent("Hello World");
|
|
69
69
|
});
|
|
@@ -71,10 +71,10 @@ describe("V1ComponentRenderer", () => {
|
|
|
71
71
|
const registry = createMockRegistry({});
|
|
72
72
|
withMockedConsoleError((consoleErrorSpy) => {
|
|
73
73
|
render(React.createElement(TamboRegistryContext.Provider, { value: registry },
|
|
74
|
-
React.createElement(
|
|
74
|
+
React.createElement(ComponentRenderer, { content: baseContent, threadId: "thread_123", messageId: "msg_456", fallback: React.createElement("div", { "data-testid": "fallback" }, "Not found") })));
|
|
75
75
|
expect(screen.getByTestId("fallback")).toBeInTheDocument();
|
|
76
76
|
expect(screen.queryByTestId("test-component")).not.toBeInTheDocument();
|
|
77
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith("[
|
|
77
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("[ComponentRenderer] Failed to render component", expect.objectContaining({
|
|
78
78
|
componentId: baseContent.id,
|
|
79
79
|
componentName: baseContent.name,
|
|
80
80
|
}));
|
|
@@ -84,9 +84,9 @@ describe("V1ComponentRenderer", () => {
|
|
|
84
84
|
const registry = createMockRegistry({});
|
|
85
85
|
withMockedConsoleError((consoleErrorSpy) => {
|
|
86
86
|
const { container } = render(React.createElement(TamboRegistryContext.Provider, { value: registry },
|
|
87
|
-
React.createElement(
|
|
87
|
+
React.createElement(ComponentRenderer, { content: baseContent, threadId: "thread_123", messageId: "msg_456" })));
|
|
88
88
|
expect(container.firstChild).toBeNull();
|
|
89
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith("[
|
|
89
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith("[ComponentRenderer] Failed to render component", expect.objectContaining({
|
|
90
90
|
componentId: baseContent.id,
|
|
91
91
|
componentName: baseContent.name,
|
|
92
92
|
}));
|
|
@@ -110,7 +110,7 @@ describe("V1ComponentRenderer", () => {
|
|
|
110
110
|
streamingState: "done",
|
|
111
111
|
};
|
|
112
112
|
render(React.createElement(TamboRegistryContext.Provider, { value: registry },
|
|
113
|
-
React.createElement(
|
|
113
|
+
React.createElement(ComponentRenderer, { content: content, threadId: "thread_123", messageId: "msg_456" })));
|
|
114
114
|
expect(screen.getByTestId("title")).toHaveTextContent("Test");
|
|
115
115
|
expect(screen.queryByTestId("count")).not.toBeInTheDocument();
|
|
116
116
|
});
|
|
@@ -132,7 +132,7 @@ describe("V1ComponentRenderer", () => {
|
|
|
132
132
|
streamingState: "done",
|
|
133
133
|
};
|
|
134
134
|
render(React.createElement(TamboRegistryContext.Provider, { value: registry },
|
|
135
|
-
React.createElement(
|
|
135
|
+
React.createElement(ComponentRenderer, { content: content, threadId: "thread_123", messageId: "msg_456" })));
|
|
136
136
|
// Component should render with empty props
|
|
137
137
|
expect(screen.getByTestId("test-component")).toBeInTheDocument();
|
|
138
138
|
});
|
|
@@ -155,7 +155,7 @@ describe("V1ComponentRenderer", () => {
|
|
|
155
155
|
streamingState: "done",
|
|
156
156
|
};
|
|
157
157
|
render(React.createElement(TamboRegistryContext.Provider, { value: registry },
|
|
158
|
-
React.createElement(
|
|
158
|
+
React.createElement(ComponentRenderer, { content: content, threadId: "thread_123", messageId: "msg_456" })));
|
|
159
159
|
expect(screen.getByTestId("name")).toHaveTextContent("Alice");
|
|
160
160
|
expect(screen.getByTestId("age")).toHaveTextContent("30");
|
|
161
161
|
});
|
|
@@ -179,7 +179,7 @@ describe("V1ComponentRenderer", () => {
|
|
|
179
179
|
streamingState: "done",
|
|
180
180
|
};
|
|
181
181
|
render(React.createElement(TamboRegistryContext.Provider, { value: registry },
|
|
182
|
-
React.createElement(
|
|
182
|
+
React.createElement(ComponentRenderer, { content: content, threadId: "thread_123", messageId: "msg_456" })));
|
|
183
183
|
// Should still render with raw props
|
|
184
184
|
expect(screen.getByTestId("name")).toHaveTextContent("Bob");
|
|
185
185
|
expect(screen.getByTestId("age")).toHaveTextContent("not a number");
|
|
@@ -208,7 +208,7 @@ describe("V1ComponentRenderer", () => {
|
|
|
208
208
|
},
|
|
209
209
|
});
|
|
210
210
|
render(React.createElement(TamboRegistryContext.Provider, { value: registry },
|
|
211
|
-
React.createElement(
|
|
211
|
+
React.createElement(ComponentRenderer, { content: baseContent, threadId: "thread_123", messageId: "msg_456" })));
|
|
212
212
|
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Async schema validation not supported"));
|
|
213
213
|
consoleSpy.mockRestore();
|
|
214
214
|
});
|
|
@@ -231,13 +231,13 @@ describe("V1ComponentRenderer", () => {
|
|
|
231
231
|
streamingState: "streaming",
|
|
232
232
|
};
|
|
233
233
|
render(React.createElement(TamboRegistryContext.Provider, { value: registry },
|
|
234
|
-
React.createElement(
|
|
234
|
+
React.createElement(ComponentRenderer, { content: content, threadId: "thread_123", messageId: "msg_456" })));
|
|
235
235
|
expect(screen.getByTestId("title")).toHaveTextContent("Partial");
|
|
236
236
|
});
|
|
237
|
-
it("provides component context to rendered components via
|
|
237
|
+
it("provides component context to rendered components via TamboComponentContentProvider", () => {
|
|
238
238
|
// Create a component that uses the context
|
|
239
239
|
const ContextAwareComponent = () => {
|
|
240
|
-
// We can't directly test the context without importing
|
|
240
|
+
// We can't directly test the context without importing useTamboComponentContent
|
|
241
241
|
// but we can verify the component renders which means the provider works
|
|
242
242
|
return React.createElement("div", { "data-testid": "context-aware" }, "Rendered");
|
|
243
243
|
};
|
|
@@ -258,7 +258,7 @@ describe("V1ComponentRenderer", () => {
|
|
|
258
258
|
streamingState: "done",
|
|
259
259
|
};
|
|
260
260
|
render(React.createElement(TamboRegistryContext.Provider, { value: registry },
|
|
261
|
-
React.createElement(
|
|
261
|
+
React.createElement(ComponentRenderer, { content: content, threadId: "thread_abc", messageId: "msg_def" })));
|
|
262
262
|
expect(screen.getByTestId("context-aware")).toBeInTheDocument();
|
|
263
263
|
});
|
|
264
264
|
});
|