@tambo-ai/react 0.73.1 → 0.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -12
- package/dist/hooks/use-component-state.d.ts +1 -1
- package/dist/hooks/use-component-state.js.map +1 -1
- package/dist/hooks/use-streaming-props.d.ts +1 -1
- package/dist/hooks/use-streaming-props.js +1 -1
- package/dist/hooks/use-streaming-props.js.map +1 -1
- package/dist/hooks/use-tambo-stream-status.d.ts +1 -1
- package/dist/hooks/use-tambo-stream-status.js +1 -1
- package/dist/hooks/use-tambo-stream-status.js.map +1 -1
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js +3 -3
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.js +2 -2
- package/dist/providers/tambo-interactable-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.test.js +3 -3
- package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
- package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-input-provider.js +1 -0
- package/dist/providers/tambo-thread-input-provider.js.map +1 -1
- package/dist/v1/__tests__/v1-interactables.test.d.ts +2 -0
- package/dist/v1/__tests__/v1-interactables.test.d.ts.map +1 -0
- package/dist/v1/__tests__/v1-interactables.test.js +135 -0
- package/dist/v1/__tests__/v1-interactables.test.js.map +1 -0
- package/dist/v1/components/v1-component-renderer.d.ts +48 -0
- package/dist/v1/components/v1-component-renderer.d.ts.map +1 -0
- package/dist/v1/components/v1-component-renderer.js +137 -0
- package/dist/v1/components/v1-component-renderer.js.map +1 -0
- package/dist/v1/components/v1-component-renderer.test.d.ts +2 -0
- package/dist/v1/components/v1-component-renderer.test.d.ts.map +1 -0
- package/dist/v1/components/v1-component-renderer.test.js +270 -0
- package/dist/v1/components/v1-component-renderer.test.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.js +2 -25
- package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js +2 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-messages.test.js +25 -1
- package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +18 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.js +204 -17
- package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js +261 -7
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts +90 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.js +179 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.d.ts +2 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js +371 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts +78 -54
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.js +153 -87
- package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js +213 -134
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +148 -13
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts +8 -21
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.js +11 -10
- package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +37 -2
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.d.ts +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.js +2 -7
- package/dist/v1/hooks/use-tambo-v1-thread.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.test.js +2 -0
- package/dist/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.d.ts +12 -28
- package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.js +164 -31
- package/dist/v1/hooks/use-tambo-v1.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.test.js +891 -18
- package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/dist/v1/index.d.ts +7 -1
- package/dist/v1/index.d.ts.map +1 -1
- package/dist/v1/index.js +18 -1
- package/dist/v1/index.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts +16 -6
- package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.js +14 -19
- package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.test.js +34 -20
- package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.d.ts +3 -3
- package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.js +60 -12
- package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.test.js +49 -20
- package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.js +2 -0
- package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.test.js +7 -6
- package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +1 -6
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.js +14 -12
- package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/dist/v1/types/event.d.ts +9 -1
- package/dist/v1/types/event.d.ts.map +1 -1
- package/dist/v1/types/event.js.map +1 -1
- package/dist/v1/types/event.test.js +5 -1
- package/dist/v1/types/event.test.js.map +1 -1
- package/dist/v1/types/message.d.ts +65 -7
- package/dist/v1/types/message.d.ts.map +1 -1
- package/dist/v1/types/message.js.map +1 -1
- package/dist/v1/types/thread.d.ts +4 -0
- package/dist/v1/types/thread.d.ts.map +1 -1
- package/dist/v1/types/thread.js.map +1 -1
- package/dist/v1/utils/event-accumulator.d.ts +40 -4
- package/dist/v1/utils/event-accumulator.d.ts.map +1 -1
- package/dist/v1/utils/event-accumulator.js +444 -35
- package/dist/v1/utils/event-accumulator.js.map +1 -1
- package/dist/v1/utils/event-accumulator.test.js +1041 -28
- package/dist/v1/utils/event-accumulator.test.js.map +1 -1
- package/dist/v1/utils/registry-conversion.d.ts +9 -9
- package/dist/v1/utils/registry-conversion.d.ts.map +1 -1
- package/dist/v1/utils/registry-conversion.js +10 -11
- package/dist/v1/utils/registry-conversion.js.map +1 -1
- package/dist/v1/utils/registry-conversion.test.js +39 -11
- package/dist/v1/utils/registry-conversion.test.js.map +1 -1
- package/dist/v1/utils/thread-utils.d.ts +16 -0
- package/dist/v1/utils/thread-utils.d.ts.map +1 -0
- package/dist/v1/utils/thread-utils.js +34 -0
- package/dist/v1/utils/thread-utils.js.map +1 -0
- package/dist/v1/utils/tool-executor.d.ts.map +1 -1
- package/dist/v1/utils/tool-executor.js +2 -0
- package/dist/v1/utils/tool-executor.js.map +1 -1
- package/dist/v1/utils/tool-executor.test.js +5 -0
- package/dist/v1/utils/tool-executor.test.js.map +1 -1
- package/esm/context-helpers/context-helpers-provider.test.js +2 -2
- package/esm/context-helpers/context-helpers.test.js +1 -1
- package/esm/context-helpers/current-interactables-context-helper.d.ts +1 -1
- package/esm/context-helpers/current-page-context-helper.d.ts +1 -1
- package/esm/context-helpers/current-time-context-helper.d.ts +1 -1
- package/esm/context-helpers/index.d.ts +4 -4
- package/esm/context-helpers/index.js +4 -4
- package/esm/hoc/with-tambo-interactable.d.ts +1 -1
- package/esm/hoc/with-tambo-interactable.js +2 -2
- package/esm/hoc/with-tambo-interactable.test.js +3 -3
- package/esm/hooks/index.d.ts +8 -8
- package/esm/hooks/index.js +8 -8
- package/esm/hooks/react-query-hooks.js +1 -1
- package/esm/hooks/use-component-state.d.ts +1 -1
- package/esm/hooks/use-component-state.js +3 -3
- package/esm/hooks/use-component-state.js.map +1 -1
- package/esm/hooks/use-component-state.test.js +5 -5
- package/esm/hooks/use-current-message.d.ts +1 -1
- package/esm/hooks/use-current-message.test.js +1 -1
- package/esm/hooks/use-message-images.test.js +1 -1
- package/esm/hooks/use-streaming-props.d.ts +1 -1
- package/esm/hooks/use-streaming-props.js +1 -1
- package/esm/hooks/use-streaming-props.js.map +1 -1
- package/esm/hooks/use-suggestions.d.ts +2 -2
- package/esm/hooks/use-suggestions.js +10 -10
- package/esm/hooks/use-suggestions.test.js +7 -7
- package/esm/hooks/use-tambo-stream-status.d.ts +1 -1
- package/esm/hooks/use-tambo-stream-status.js +4 -4
- package/esm/hooks/use-tambo-stream-status.js.map +1 -1
- package/esm/hooks/use-tambo-stream-status.test.js +4 -4
- package/esm/hooks/use-tambo-threads.js +3 -3
- package/esm/hooks/use-tambo-threads.test.js +3 -3
- package/esm/hooks/use-tambo-voice.js +2 -2
- package/esm/hooks/use-tambo-voice.test.js +3 -3
- package/esm/index.d.ts +22 -22
- package/esm/index.js +15 -15
- package/esm/mcp/elicitation.d.ts +1 -1
- package/esm/mcp/elicitation.test.js +1 -1
- package/esm/mcp/index.d.ts +7 -7
- package/esm/mcp/index.js +3 -3
- package/esm/mcp/mcp-client.d.ts +1 -1
- package/esm/mcp/mcp-client.js +1 -1
- package/esm/mcp/mcp-client.test.js +1 -1
- package/esm/mcp/mcp-hooks.d.ts +1 -1
- package/esm/mcp/mcp-hooks.js +4 -4
- package/esm/mcp/mcp-hooks.test.js +6 -6
- package/esm/mcp/tambo-mcp-provider.d.ts +4 -4
- package/esm/mcp/tambo-mcp-provider.js +7 -7
- package/esm/mcp/tambo-mcp-provider.test.js +5 -5
- package/esm/mcp/use-mcp-servers.test.js +4 -4
- package/esm/model/generate-component-response.d.ts +1 -1
- package/esm/model/tambo-interactable.d.ts +1 -1
- package/esm/model/tambo-thread.d.ts +1 -1
- package/esm/providers/__tests__/thread-input-resource-resolution.test.js +3 -3
- package/esm/providers/hooks/use-tambo-session-token.test.js +1 -1
- package/esm/providers/index.d.ts +12 -12
- package/esm/providers/index.js +10 -10
- package/esm/providers/tambo-client-provider.js +1 -1
- package/esm/providers/tambo-client-provider.test.js +2 -2
- package/esm/providers/tambo-component-provider.d.ts +1 -1
- package/esm/providers/tambo-component-provider.js +2 -2
- package/esm/providers/tambo-context-attachment-provider.js +1 -1
- package/esm/providers/tambo-context-attachment-provider.test.js +2 -2
- package/esm/providers/tambo-context-helpers-provider.d.ts +1 -1
- package/esm/providers/tambo-context-helpers-provider.js +1 -1
- package/esm/providers/tambo-context-helpers-provider.test.js +2 -2
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js +4 -4
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +5 -5
- package/esm/providers/tambo-interactable-provider.js +6 -6
- package/esm/providers/tambo-interactable-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.test.js +4 -4
- package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
- package/esm/providers/tambo-interactables-additional-context-edge-cases.test.js +4 -4
- package/esm/providers/tambo-interactables-additional-context.test.js +4 -4
- package/esm/providers/tambo-mcp-token-provider.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/index.d.ts +8 -8
- package/esm/providers/tambo-prop-stream-provider/index.js +9 -9
- package/esm/providers/tambo-prop-stream-provider/pending.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/pending.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/provider.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/provider.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/streaming.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/streaming.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/success.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/success.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/types.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider.test.js +4 -4
- package/esm/providers/tambo-provider.d.ts +7 -7
- package/esm/providers/tambo-provider.js +10 -10
- package/esm/providers/tambo-registry-provider.d.ts +3 -3
- package/esm/providers/tambo-registry-provider.js +3 -3
- package/esm/providers/tambo-registry-provider.test.js +2 -2
- package/esm/providers/tambo-registry-schema-compat.test.js +2 -2
- package/esm/providers/tambo-stubs.d.ts +4 -4
- package/esm/providers/tambo-stubs.js +9 -9
- package/esm/providers/tambo-stubs.test.js +2 -2
- package/esm/providers/tambo-thread-input-provider.d.ts +2 -2
- package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-input-provider.js +11 -10
- package/esm/providers/tambo-thread-input-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider-initial-messages.test.js +6 -6
- package/esm/providers/tambo-thread-provider.d.ts +2 -2
- package/esm/providers/tambo-thread-provider.js +8 -8
- package/esm/providers/tambo-thread-provider.test.js +7 -7
- package/esm/schema/index.d.ts +4 -4
- package/esm/schema/index.js +4 -4
- package/esm/schema/json-schema.test.js +1 -1
- package/esm/schema/schema.d.ts +1 -1
- package/esm/schema/schema.js +2 -2
- package/esm/schema/schema.test.js +3 -3
- package/esm/schema/standard-schema.test.js +1 -1
- package/esm/schema/validate.js +2 -2
- package/esm/schema/validate.test.js +1 -1
- package/esm/testing/tools.d.ts +3 -3
- package/esm/testing/tools.js +2 -2
- package/esm/util/content-parts.test.js +1 -1
- package/esm/util/generate-component.d.ts +2 -2
- package/esm/util/generate-component.js +4 -4
- package/esm/util/generate-component.test.js +2 -2
- package/esm/util/is-promise.test.js +1 -1
- package/esm/util/mcp-server-utils.d.ts +1 -1
- package/esm/util/mcp-server-utils.js +1 -1
- package/esm/util/mcp-server-utils.test.js +2 -2
- package/esm/util/message-builder.d.ts +1 -1
- package/esm/util/message-builder.test.js +1 -1
- package/esm/util/query-utils.test.js +1 -1
- package/esm/util/registry-validators.d.ts +1 -1
- package/esm/util/registry-validators.js +2 -2
- package/esm/util/registry-validators.test.js +1 -1
- package/esm/util/registry.d.ts +1 -1
- package/esm/util/registry.js +1 -1
- package/esm/util/registry.test.js +2 -2
- package/esm/util/resource-content-resolver.d.ts +2 -2
- package/esm/util/resource-content-resolver.js +1 -1
- package/esm/util/resource-content-resolver.test.js +3 -3
- package/esm/util/resource-validators.d.ts +1 -1
- package/esm/util/resource-validators.test.js +1 -1
- package/esm/util/tool-caller.d.ts +1 -1
- package/esm/util/tool-caller.js +1 -1
- package/esm/util/validate-component-name.test.js +1 -1
- package/esm/v1/__tests__/v1-interactables.test.d.ts +2 -0
- package/esm/v1/__tests__/v1-interactables.test.d.ts.map +1 -0
- package/esm/v1/__tests__/v1-interactables.test.js +130 -0
- package/esm/v1/__tests__/v1-interactables.test.js.map +1 -0
- package/esm/v1/components/v1-component-renderer.d.ts +48 -0
- package/esm/v1/components/v1-component-renderer.d.ts.map +1 -0
- package/esm/v1/components/v1-component-renderer.js +100 -0
- package/esm/v1/components/v1-component-renderer.js.map +1 -0
- package/esm/v1/components/v1-component-renderer.test.d.ts +2 -0
- package/esm/v1/components/v1-component-renderer.test.d.ts.map +1 -0
- package/esm/v1/components/v1-component-renderer.test.js +265 -0
- package/esm/v1/components/v1-component-renderer.test.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.js +4 -27
- package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js +6 -5
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.test.js +27 -3
- package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +20 -2
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.js +213 -26
- package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js +266 -12
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts +90 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.js +176 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.d.ts +2 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js +369 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts +78 -54
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.js +157 -91
- package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js +218 -139
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +151 -16
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts +8 -21
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.js +12 -11
- package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +39 -4
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.js +3 -8
- package/esm/v1/hooks/use-tambo-v1-thread.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.test.js +4 -2
- package/esm/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.d.ts +15 -31
- package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.js +134 -34
- package/esm/v1/hooks/use-tambo-v1.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.test.js +862 -19
- package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/esm/v1/index.d.ts +28 -22
- package/esm/v1/index.d.ts.map +1 -1
- package/esm/v1/index.js +30 -18
- package/esm/v1/index.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts +21 -11
- package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.js +20 -25
- package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.test.js +40 -26
- package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.d.ts +4 -4
- package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.js +62 -14
- package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.test.js +50 -21
- package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts +3 -3
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.js +7 -5
- package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.test.js +12 -11
- package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +3 -8
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.js +18 -16
- package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/esm/v1/types/event.d.ts +9 -1
- package/esm/v1/types/event.d.ts.map +1 -1
- package/esm/v1/types/event.js.map +1 -1
- package/esm/v1/types/event.test.js +6 -2
- package/esm/v1/types/event.test.js.map +1 -1
- package/esm/v1/types/message.d.ts +65 -7
- package/esm/v1/types/message.d.ts.map +1 -1
- package/esm/v1/types/message.js.map +1 -1
- package/esm/v1/types/thread.d.ts +5 -1
- package/esm/v1/types/thread.d.ts.map +1 -1
- package/esm/v1/types/thread.js.map +1 -1
- package/esm/v1/utils/component-renderer.test.js +1 -1
- package/esm/v1/utils/event-accumulator.d.ts +41 -5
- package/esm/v1/utils/event-accumulator.d.ts.map +1 -1
- package/esm/v1/utils/event-accumulator.js +444 -36
- package/esm/v1/utils/event-accumulator.js.map +1 -1
- package/esm/v1/utils/event-accumulator.test.js +1042 -29
- package/esm/v1/utils/event-accumulator.test.js.map +1 -1
- package/esm/v1/utils/json-patch.test.js +1 -1
- package/esm/v1/utils/registry-conversion.d.ts +9 -9
- package/esm/v1/utils/registry-conversion.d.ts.map +1 -1
- package/esm/v1/utils/registry-conversion.js +11 -12
- package/esm/v1/utils/registry-conversion.js.map +1 -1
- package/esm/v1/utils/registry-conversion.test.js +40 -12
- package/esm/v1/utils/registry-conversion.test.js.map +1 -1
- package/esm/v1/utils/stream-handler.test.js +1 -1
- package/esm/v1/utils/thread-utils.d.ts +16 -0
- package/esm/v1/utils/thread-utils.d.ts.map +1 -0
- package/esm/v1/utils/thread-utils.js +31 -0
- package/esm/v1/utils/thread-utils.js.map +1 -0
- package/esm/v1/utils/tool-call-tracker.d.ts +1 -1
- package/esm/v1/utils/tool-executor.d.ts +1 -1
- package/esm/v1/utils/tool-executor.d.ts.map +1 -1
- package/esm/v1/utils/tool-executor.js +2 -0
- package/esm/v1/utils/tool-executor.js.map +1 -1
- package/esm/v1/utils/tool-executor.test.js +6 -1
- package/esm/v1/utils/tool-executor.test.js.map +1 -1
- package/package.json +11 -10
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as z3 from "zod/v3";
|
|
2
2
|
import * as z4 from "zod/v4";
|
|
3
|
-
import { looksLikeJSONSchema } from "./json-schema";
|
|
4
|
-
import { getParametersFromToolSchema, safeSchemaToJsonSchema, schemaToJsonSchema, } from "./schema";
|
|
5
|
-
import { isStandardSchema } from "./standard-schema";
|
|
3
|
+
import { looksLikeJSONSchema } from "./json-schema.js";
|
|
4
|
+
import { getParametersFromToolSchema, safeSchemaToJsonSchema, schemaToJsonSchema, } from "./schema.js";
|
|
5
|
+
import { isStandardSchema } from "./standard-schema.js";
|
|
6
6
|
describe("schema utilities", () => {
|
|
7
7
|
describe("looksLikeJSONSchema", () => {
|
|
8
8
|
it("returns true for a basic JSON Schema object", () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as z3 from "zod/v3";
|
|
2
2
|
import * as z4 from "zod/v4";
|
|
3
|
-
import { isStandardSchema } from "./standard-schema";
|
|
3
|
+
import { isStandardSchema } from "./standard-schema.js";
|
|
4
4
|
describe("isStandardSchema", () => {
|
|
5
5
|
describe("returns true for valid Standard Schema implementations", () => {
|
|
6
6
|
it("recognizes Zod 4 object schema", () => {
|
package/esm/schema/validate.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { schemaToJsonSchema } from "./schema";
|
|
2
|
-
import { isStandardSchema } from "./standard-schema";
|
|
1
|
+
import { schemaToJsonSchema } from "./schema.js";
|
|
2
|
+
import { isStandardSchema } from "./standard-schema.js";
|
|
3
3
|
/*
|
|
4
4
|
* Check if a JSON Schema represents a record type (map with dynamic keys).
|
|
5
5
|
*
|
package/esm/testing/tools.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TamboComponent, TamboTool } from "../providers";
|
|
1
|
+
import { TamboComponent, TamboTool } from "../providers/index.js";
|
|
2
2
|
/**
|
|
3
3
|
* Serializes the registry for testing purposes.
|
|
4
4
|
* Converts Standard Schema validators to JSON Schema format.
|
|
@@ -8,12 +8,12 @@ import { TamboComponent, TamboTool } from "../providers";
|
|
|
8
8
|
*/
|
|
9
9
|
export declare function serializeRegistry(mockRegistry: TamboComponent[]): {
|
|
10
10
|
props: import("json-schema").JSONSchema7 | undefined;
|
|
11
|
-
contextTools: import("
|
|
11
|
+
contextTools: import("../index.js").ComponentContextToolMetadata[] | undefined;
|
|
12
12
|
name: string;
|
|
13
13
|
description: string;
|
|
14
14
|
propsDefinition?: any;
|
|
15
15
|
loadingComponent?: import("react").ComponentType<any>;
|
|
16
|
-
annotations?: import("
|
|
16
|
+
annotations?: import("../index.js").ToolAnnotations;
|
|
17
17
|
}[];
|
|
18
18
|
interface CreateMockToolOptions {
|
|
19
19
|
inputSchema: TamboTool["inputSchema"];
|
package/esm/testing/tools.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isStandardSchema, safeSchemaToJsonSchema } from "../schema";
|
|
2
|
-
import { mapTamboToolToContextTool } from "../util/registry";
|
|
1
|
+
import { isStandardSchema, safeSchemaToJsonSchema } from "../schema/index.js";
|
|
2
|
+
import { mapTamboToolToContextTool } from "../util/registry.js";
|
|
3
3
|
/**
|
|
4
4
|
* Serializes the registry for testing purposes.
|
|
5
5
|
* Converts Standard Schema validators to JSON Schema format.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isContentPartArray, isContentPart, toText } from "./content-parts";
|
|
1
|
+
import { isContentPartArray, isContentPart, toText } from "./content-parts.js";
|
|
2
2
|
describe("content-parts type guards", () => {
|
|
3
3
|
it("returns true for a valid text content part array", () => {
|
|
4
4
|
const parts = [{ type: "text", text: "hello" }];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import TamboAI from "@tambo-ai/typescript-sdk";
|
|
2
|
-
import { ComponentRegistry } from "../model/component-metadata";
|
|
3
|
-
import { TamboThreadMessage } from "../model/generate-component-response";
|
|
2
|
+
import { ComponentRegistry } from "../model/component-metadata.js";
|
|
3
|
+
import { TamboThreadMessage } from "../model/generate-component-response.js";
|
|
4
4
|
/**
|
|
5
5
|
* Generate a message that has a component rendered into it, if the message
|
|
6
6
|
* came with one.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { parse } from "partial-json";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import { wrapWithTamboMessageProvider } from "../hooks/use-current-message";
|
|
4
|
-
import { isStandardSchema } from "../schema";
|
|
5
|
-
import { isPromise } from "../util/is-promise";
|
|
6
|
-
import { getComponentFromRegistry } from "../util/registry";
|
|
3
|
+
import { wrapWithTamboMessageProvider } from "../hooks/use-current-message.js";
|
|
4
|
+
import { isStandardSchema } from "../schema/index.js";
|
|
5
|
+
import { isPromise } from "../util/is-promise.js";
|
|
6
|
+
import { getComponentFromRegistry } from "../util/registry.js";
|
|
7
7
|
/**
|
|
8
8
|
* Generate a message that has a component rendered into it, if the message
|
|
9
9
|
* came with one.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import * as useCurrentMessage from "../hooks/use-current-message";
|
|
3
|
-
import { renderComponentIntoMessage } from "./generate-component";
|
|
2
|
+
import * as useCurrentMessage from "../hooks/use-current-message.js";
|
|
3
|
+
import { renderComponentIntoMessage } from "./generate-component.js";
|
|
4
4
|
// Track calls to wrapWithTamboMessageProvider
|
|
5
5
|
let wrapWithTamboMessageProviderSpy;
|
|
6
6
|
beforeEach(() => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { McpServerInfo, NormalizedMcpServerInfo } from "../model/mcp-server-info";
|
|
1
|
+
import type { McpServerInfo, NormalizedMcpServerInfo } from "../model/mcp-server-info.js";
|
|
2
2
|
/**
|
|
3
3
|
* Derives a short, meaningful key from a server URL.
|
|
4
4
|
* Strips TLDs and common prefixes to get a human-readable identifier.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getMcpServerUniqueKey, MCPTransport } from "../model/mcp-server-info";
|
|
1
|
+
import { getMcpServerUniqueKey, MCPTransport } from "../model/mcp-server-info.js";
|
|
2
2
|
/**
|
|
3
3
|
* Derives a short, meaningful key from a server URL.
|
|
4
4
|
* Strips TLDs and common prefixes to get a human-readable identifier.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { MCPTransport } from "../model/mcp-server-info";
|
|
2
|
-
import { deduplicateMcpServers, deriveServerKey, normalizeServerInfo, } from "./mcp-server-utils";
|
|
1
|
+
import { MCPTransport } from "../model/mcp-server-info.js";
|
|
2
|
+
import { deduplicateMcpServers, deriveServerKey, normalizeServerInfo, } from "./mcp-server-utils.js";
|
|
3
3
|
describe("deriveServerKey", () => {
|
|
4
4
|
it("should extract key from simple domain", () => {
|
|
5
5
|
expect(deriveServerKey("https://linear.app/mcp")).toBe("linear");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import type TamboAI from "@tambo-ai/typescript-sdk";
|
|
3
|
-
import { StagedImage } from "../hooks/use-message-images";
|
|
3
|
+
import { StagedImage } from "../hooks/use-message-images.js";
|
|
4
4
|
/**
|
|
5
5
|
* Builds message content with text, MCP resource references, and images
|
|
6
6
|
* @param text - The text content, may include \@serverKey:uri resource references
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { assertNoRecordSchema, isStandardSchema, looksLikeJSONSchema, schemaToJsonSchema, } from "../schema";
|
|
2
|
-
import { assertValidName } from "./validate-component-name";
|
|
1
|
+
import { assertNoRecordSchema, isStandardSchema, looksLikeJSONSchema, schemaToJsonSchema, } from "../schema/index.js";
|
|
2
|
+
import { assertValidName } from "./validate-component-name.js";
|
|
3
3
|
/**
|
|
4
4
|
* Checks if a JSON Schema represents an object type.
|
|
5
5
|
* @param schema - The JSON Schema to check
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod/v3";
|
|
2
|
-
import { validateAndPrepareComponent, validateTool, validateToolAssociation, } from "./registry-validators";
|
|
2
|
+
import { validateAndPrepareComponent, validateTool, validateToolAssociation, } from "./registry-validators.js";
|
|
3
3
|
describe("validateTool", () => {
|
|
4
4
|
it("should validate tool with valid name", () => {
|
|
5
5
|
const tool = {
|
package/esm/util/registry.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import TamboAI from "@tambo-ai/typescript-sdk";
|
|
2
|
-
import { ComponentContextToolMetadata, ComponentRegistry, DefineToolFn, RegisteredComponent, TamboTool, TamboToolAssociations, TamboToolRegistry } from "../model/component-metadata";
|
|
2
|
+
import { ComponentContextToolMetadata, ComponentRegistry, DefineToolFn, RegisteredComponent, TamboTool, TamboToolAssociations, TamboToolRegistry } from "../model/component-metadata.js";
|
|
3
3
|
/**
|
|
4
4
|
* Get all the available components from the component registry
|
|
5
5
|
* @param componentRegistry - The component registry
|
package/esm/util/registry.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getParametersFromToolSchema, isStandardSchema, schemaToJsonSchema, } from "../schema";
|
|
1
|
+
import { getParametersFromToolSchema, isStandardSchema, schemaToJsonSchema, } from "../schema/index.js";
|
|
2
2
|
/**
|
|
3
3
|
* Get all the available components from the component registry
|
|
4
4
|
* @param componentRegistry - The component registry
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as z3 from "zod/v3";
|
|
2
2
|
import * as z4 from "zod/v4";
|
|
3
|
-
import { createMockTool } from "../testing/tools";
|
|
4
|
-
import { convertPropsToJsonSchema, getAvailableComponents, getComponentFromRegistry, getUnassociatedTools, mapTamboToolToContextTool, } from "./registry";
|
|
3
|
+
import { createMockTool } from "../testing/tools.js";
|
|
4
|
+
import { convertPropsToJsonSchema, getAvailableComponents, getComponentFromRegistry, getUnassociatedTools, mapTamboToolToContextTool, } from "./registry.js";
|
|
5
5
|
describe("getParametersFromToolSchema (via mapTamboToolToContextTool)", () => {
|
|
6
6
|
describe("inputSchema interface (object schemas)", () => {
|
|
7
7
|
describe("Zod 4 object schemas", () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
-
import type { McpServer } from "../mcp/tambo-mcp-provider";
|
|
3
|
-
import type { ResourceSource } from "../model/resource-info";
|
|
2
|
+
import type { McpServer } from "../mcp/tambo-mcp-provider.js";
|
|
3
|
+
import type { ResourceSource } from "../model/resource-info.js";
|
|
4
4
|
/**
|
|
5
5
|
* Resolves content for client-side resources (MCP and registry).
|
|
6
6
|
* Server-side (internal Tambo) resources are skipped - the backend can resolve them.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ServerType } from "../mcp/mcp-constants";
|
|
2
|
-
import { MCPTransport } from "../mcp/mcp-client";
|
|
3
|
-
import { resolveResourceContents, extractResourceUris, } from "./resource-content-resolver";
|
|
1
|
+
import { ServerType } from "../mcp/mcp-constants.js";
|
|
2
|
+
import { MCPTransport } from "../mcp/mcp-client.js";
|
|
3
|
+
import { resolveResourceContents, extractResourceUris, } from "./resource-content-resolver.js";
|
|
4
4
|
describe("extractResourceUris", () => {
|
|
5
5
|
it("should extract a single resource URI", () => {
|
|
6
6
|
const text = "Check @registry:file:///path/to/doc.txt";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ListResourceItem, ResourceSource } from "../model/resource-info";
|
|
1
|
+
import type { ListResourceItem, ResourceSource } from "../model/resource-info.js";
|
|
2
2
|
/**
|
|
3
3
|
* Validates that a ResourceSource has both listResources and getResource defined,
|
|
4
4
|
* or neither defined. You cannot provide one without the other.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { validateResource, validateResourceSource, } from "./resource-validators";
|
|
1
|
+
import { validateResource, validateResourceSource, } from "./resource-validators.js";
|
|
2
2
|
describe("validateResourceSource", () => {
|
|
3
3
|
it("should throw when has listResources but not getResource", () => {
|
|
4
4
|
const listResources = async () => [];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import TamboAI from "@tambo-ai/typescript-sdk";
|
|
2
|
-
import { TamboTool, TamboToolRegistry } from "../model/component-metadata";
|
|
2
|
+
import { TamboTool, TamboToolRegistry } from "../model/component-metadata.js";
|
|
3
3
|
/**
|
|
4
4
|
* Process a message from the thread, invoking the appropriate tool and returning the result.
|
|
5
5
|
* @param toolCallRequest - The message to handle
|
package/esm/util/tool-caller.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v1-interactables.test.d.ts","sourceRoot":"","sources":["../../../src/v1/__tests__/v1-interactables.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { act, render, renderHook, screen } from "@testing-library/react";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { z } from "zod/v3";
|
|
4
|
+
import { withTamboInteractable } from "../../hoc/with-tambo-interactable.js";
|
|
5
|
+
import { useTamboInteractable } from "../../providers/tambo-interactable-provider.js";
|
|
6
|
+
import { useTamboContextHelpers } from "../../providers/tambo-context-helpers-provider.js";
|
|
7
|
+
import { TamboRegistryContext, } from "../../providers/tambo-registry-provider.js";
|
|
8
|
+
import { TamboContextHelpersProvider } from "../../providers/tambo-context-helpers-provider.js";
|
|
9
|
+
import { TamboInteractableProvider } from "../../providers/tambo-interactable-provider.js";
|
|
10
|
+
// Minimal registry mock that captures registered tools
|
|
11
|
+
function createMockRegistry() {
|
|
12
|
+
const toolRegistry = {};
|
|
13
|
+
return {
|
|
14
|
+
value: {
|
|
15
|
+
componentList: {},
|
|
16
|
+
toolRegistry,
|
|
17
|
+
componentToolAssociations: {},
|
|
18
|
+
mcpServerInfos: [],
|
|
19
|
+
resources: [],
|
|
20
|
+
resourceSource: null,
|
|
21
|
+
onCallUnregisteredTool: undefined,
|
|
22
|
+
registerComponent: jest.fn(),
|
|
23
|
+
registerTool: jest.fn((tool) => {
|
|
24
|
+
toolRegistry[tool.name] = tool;
|
|
25
|
+
}),
|
|
26
|
+
registerTools: jest.fn(),
|
|
27
|
+
addToolAssociation: jest.fn(),
|
|
28
|
+
registerMcpServer: jest.fn(),
|
|
29
|
+
registerMcpServers: jest.fn(),
|
|
30
|
+
registerResource: jest.fn(),
|
|
31
|
+
registerResources: jest.fn(),
|
|
32
|
+
registerResourceSource: jest.fn(),
|
|
33
|
+
},
|
|
34
|
+
getRegisteredToolNames: () => Object.keys(toolRegistry),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Wrapper that provides the minimal V1-compatible provider tree for interactables:
|
|
39
|
+
* TamboRegistryContext > TamboContextHelpersProvider > TamboInteractableProvider
|
|
40
|
+
*/
|
|
41
|
+
function V1InteractableWrapper({ children, registry, }) {
|
|
42
|
+
return (React.createElement(TamboRegistryContext.Provider, { value: registry },
|
|
43
|
+
React.createElement(TamboContextHelpersProvider, null,
|
|
44
|
+
React.createElement(TamboInteractableProvider, null, children))));
|
|
45
|
+
}
|
|
46
|
+
describe("V1 Interactables Integration", () => {
|
|
47
|
+
it("registers update_component_props and update_component_state tools when an interactable is added", () => {
|
|
48
|
+
const mockRegistry = createMockRegistry();
|
|
49
|
+
const { result } = renderHook(() => useTamboInteractable(), {
|
|
50
|
+
wrapper: ({ children }) => (React.createElement(V1InteractableWrapper, { registry: mockRegistry.value }, children)),
|
|
51
|
+
});
|
|
52
|
+
act(() => {
|
|
53
|
+
result.current.addInteractableComponent({
|
|
54
|
+
name: "TestWidget",
|
|
55
|
+
description: "A test widget",
|
|
56
|
+
component: () => React.createElement("div", null, "widget"),
|
|
57
|
+
props: { label: "hello" },
|
|
58
|
+
propsSchema: z.object({ label: z.string() }),
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
const toolNames = mockRegistry.getRegisteredToolNames();
|
|
62
|
+
expect(toolNames.some((n) => n.startsWith("update_component_props_TestWidget"))).toBe(true);
|
|
63
|
+
expect(toolNames.some((n) => n.startsWith("update_component_state_TestWidget"))).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
it("registers interactables context helper that includes component info", async () => {
|
|
66
|
+
const mockRegistry = createMockRegistry();
|
|
67
|
+
const { result } = renderHook(() => ({
|
|
68
|
+
interactable: useTamboInteractable(),
|
|
69
|
+
helpers: useTamboContextHelpers(),
|
|
70
|
+
}), {
|
|
71
|
+
wrapper: ({ children }) => (React.createElement(V1InteractableWrapper, { registry: mockRegistry.value }, children)),
|
|
72
|
+
});
|
|
73
|
+
// Add an interactable component
|
|
74
|
+
act(() => {
|
|
75
|
+
result.current.interactable.addInteractableComponent({
|
|
76
|
+
name: "InfoCard",
|
|
77
|
+
description: "An info card",
|
|
78
|
+
component: () => React.createElement("div", null, "card"),
|
|
79
|
+
props: { title: "Test" },
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
// Get additional context - should include interactable info
|
|
83
|
+
const contexts = await act(async () => {
|
|
84
|
+
return await result.current.helpers.getAdditionalContext();
|
|
85
|
+
});
|
|
86
|
+
const interactablesContext = contexts.find((c) => c.name === "interactables");
|
|
87
|
+
expect(interactablesContext).toBeDefined();
|
|
88
|
+
expect(interactablesContext?.context).toBeDefined();
|
|
89
|
+
});
|
|
90
|
+
it("renders an interactable component via withTamboInteractable HOC", () => {
|
|
91
|
+
const mockRegistry = createMockRegistry();
|
|
92
|
+
const Card = ({ title }) => (React.createElement("div", { "data-testid": "card-title" }, title));
|
|
93
|
+
const InteractableCard = withTamboInteractable(Card, {
|
|
94
|
+
componentName: "Card",
|
|
95
|
+
description: "A card component",
|
|
96
|
+
propsSchema: z.object({ title: z.string() }),
|
|
97
|
+
});
|
|
98
|
+
render(React.createElement(V1InteractableWrapper, { registry: mockRegistry.value },
|
|
99
|
+
React.createElement(InteractableCard, { title: "Hello V1" })));
|
|
100
|
+
expect(screen.getByTestId("card-title")).toHaveTextContent("Hello V1");
|
|
101
|
+
});
|
|
102
|
+
it("updates component props via the interactable provider", () => {
|
|
103
|
+
const mockRegistry = createMockRegistry();
|
|
104
|
+
const Counter = ({ count }) => (React.createElement("div", { "data-testid": "count" }, count));
|
|
105
|
+
const InteractableCounter = withTamboInteractable(Counter, {
|
|
106
|
+
componentName: "Counter",
|
|
107
|
+
description: "A counter",
|
|
108
|
+
propsSchema: z.object({ count: z.number() }),
|
|
109
|
+
});
|
|
110
|
+
// Inner component that triggers prop updates
|
|
111
|
+
function TestHarness() {
|
|
112
|
+
const { interactableComponents, updateInteractableComponentProps } = useTamboInteractable();
|
|
113
|
+
const component = interactableComponents[0];
|
|
114
|
+
return (React.createElement("div", null,
|
|
115
|
+
React.createElement(InteractableCounter, { count: 0 }),
|
|
116
|
+
component && (React.createElement("button", { "data-testid": "update-btn", onClick: () => updateInteractableComponentProps(component.id, { count: 42 }) }, "Update"))));
|
|
117
|
+
}
|
|
118
|
+
render(React.createElement(V1InteractableWrapper, { registry: mockRegistry.value },
|
|
119
|
+
React.createElement(TestHarness, null)));
|
|
120
|
+
// Initial render
|
|
121
|
+
expect(screen.getByTestId("count")).toHaveTextContent("0");
|
|
122
|
+
// Update props via the interactable provider
|
|
123
|
+
act(() => {
|
|
124
|
+
screen.getByTestId("update-btn").click();
|
|
125
|
+
});
|
|
126
|
+
// The interactable should reflect updated props
|
|
127
|
+
expect(screen.getByTestId("count")).toHaveTextContent("42");
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
//# sourceMappingURL=v1-interactables.test.js.map
|
|
@@ -0,0 +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"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React, { type FC } from "react";
|
|
2
|
+
import type { V1ComponentContent } from "../types/message.js";
|
|
3
|
+
export interface V1ComponentRendererProps {
|
|
4
|
+
/**
|
|
5
|
+
* The component content block from a v1 message
|
|
6
|
+
*/
|
|
7
|
+
content: V1ComponentContent;
|
|
8
|
+
/**
|
|
9
|
+
* The thread ID the component belongs to
|
|
10
|
+
*/
|
|
11
|
+
threadId: string;
|
|
12
|
+
/**
|
|
13
|
+
* The message ID the component belongs to
|
|
14
|
+
*/
|
|
15
|
+
messageId: string;
|
|
16
|
+
/**
|
|
17
|
+
* Optional fallback to render if component is not found in registry
|
|
18
|
+
*/
|
|
19
|
+
fallback?: React.ReactNode;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Renders a component from the registry based on component content block data.
|
|
23
|
+
*
|
|
24
|
+
* Use this component in your message renderer to display AI-generated components.
|
|
25
|
+
* The component instance is preserved across re-renders as long as React's
|
|
26
|
+
* reconciliation keeps this wrapper mounted (use content.id as key).
|
|
27
|
+
*
|
|
28
|
+
* Wraps the rendered component with V1ComponentContentProvider so that hooks
|
|
29
|
+
* like useTamboV1ComponentState can access component context.
|
|
30
|
+
* @returns The rendered component wrapped in V1ComponentContentProvider, or fallback if not found
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* function MessageContent({ content }: { content: Content }) {
|
|
34
|
+
* if (content.type === 'component') {
|
|
35
|
+
* return (
|
|
36
|
+
* <V1ComponentRenderer
|
|
37
|
+
* key={content.id}
|
|
38
|
+
* content={content}
|
|
39
|
+
* fallback={<div>Unknown component: {content.name}</div>}
|
|
40
|
+
* />
|
|
41
|
+
* );
|
|
42
|
+
* }
|
|
43
|
+
* // ... handle other content types
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare const V1ComponentRenderer: FC<V1ComponentRendererProps>;
|
|
48
|
+
//# sourceMappingURL=v1-component-renderer.d.ts.map
|
|
@@ -0,0 +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,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAG3D,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,OAAO,EAAE,kBAAkB,CAAC;IAE5B;;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,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CAoF5D,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/**
|
|
3
|
+
* V1 Component Renderer
|
|
4
|
+
*
|
|
5
|
+
* A wrapper component that renders a component from the registry based on
|
|
6
|
+
* component content block data. Uses React's normal reconciliation to maintain
|
|
7
|
+
* component identity - as long as the key stays stable, the component instance
|
|
8
|
+
* is preserved.
|
|
9
|
+
*
|
|
10
|
+
* Wraps the component with V1ComponentContentProvider so that hooks like
|
|
11
|
+
* useTamboV1ComponentState can access component context.
|
|
12
|
+
*/
|
|
13
|
+
import { parse } from "partial-json";
|
|
14
|
+
import React, { useMemo, useContext } from "react";
|
|
15
|
+
import { TamboRegistryContext } from "../../providers/tambo-registry-provider.js";
|
|
16
|
+
import { isStandardSchema } from "../../schema/index.js";
|
|
17
|
+
import { isPromise } from "../../util/is-promise.js";
|
|
18
|
+
import { getComponentFromRegistry } from "../../util/registry.js";
|
|
19
|
+
import { V1ComponentContentProvider } from "../utils/component-renderer.js";
|
|
20
|
+
/**
|
|
21
|
+
* Renders a component from the registry based on component content block data.
|
|
22
|
+
*
|
|
23
|
+
* Use this component in your message renderer to display AI-generated components.
|
|
24
|
+
* The component instance is preserved across re-renders as long as React's
|
|
25
|
+
* reconciliation keeps this wrapper mounted (use content.id as key).
|
|
26
|
+
*
|
|
27
|
+
* Wraps the rendered component with V1ComponentContentProvider so that hooks
|
|
28
|
+
* like useTamboV1ComponentState can access component context.
|
|
29
|
+
* @returns The rendered component wrapped in V1ComponentContentProvider, or fallback if not found
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* function MessageContent({ content }: { content: Content }) {
|
|
33
|
+
* if (content.type === 'component') {
|
|
34
|
+
* return (
|
|
35
|
+
* <V1ComponentRenderer
|
|
36
|
+
* key={content.id}
|
|
37
|
+
* content={content}
|
|
38
|
+
* fallback={<div>Unknown component: {content.name}</div>}
|
|
39
|
+
* />
|
|
40
|
+
* );
|
|
41
|
+
* }
|
|
42
|
+
* // ... handle other content types
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export const V1ComponentRenderer = ({ content, threadId, messageId, fallback = null, }) => {
|
|
47
|
+
const registry = useContext(TamboRegistryContext);
|
|
48
|
+
// Memoize the rendered element - only recreates when props change
|
|
49
|
+
const element = useMemo(() => {
|
|
50
|
+
try {
|
|
51
|
+
const registeredComponent = getComponentFromRegistry(content.name, registry.componentList);
|
|
52
|
+
// Parse props (handles partial JSON during streaming)
|
|
53
|
+
const propsJson = JSON.stringify(content.props ?? {});
|
|
54
|
+
const parsedProps = parse(propsJson);
|
|
55
|
+
let validatedProps = parsedProps;
|
|
56
|
+
// Validate props if schema is present
|
|
57
|
+
if (isStandardSchema(registeredComponent.props)) {
|
|
58
|
+
const result = registeredComponent.props["~standard"].validate(parsedProps);
|
|
59
|
+
if (isPromise(result)) {
|
|
60
|
+
// Async validation not supported - skip validation
|
|
61
|
+
console.warn(`Async schema validation not supported for component ${content.name}`);
|
|
62
|
+
}
|
|
63
|
+
else if ("value" in result) {
|
|
64
|
+
validatedProps = result.value;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// Validation failed - log warning but still render with raw props
|
|
68
|
+
console.warn(`Props validation failed for component ${content.name}:`, result.issues?.[0]?.message);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return React.createElement(registeredComponent.component, validatedProps);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error("[V1ComponentRenderer] Failed to render component", {
|
|
75
|
+
threadId,
|
|
76
|
+
messageId,
|
|
77
|
+
componentId: content.id,
|
|
78
|
+
componentName: content.name,
|
|
79
|
+
streamingState: content.streamingState,
|
|
80
|
+
props: content.props,
|
|
81
|
+
error,
|
|
82
|
+
});
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}, [
|
|
86
|
+
content.id,
|
|
87
|
+
content.name,
|
|
88
|
+
content.props,
|
|
89
|
+
content.streamingState,
|
|
90
|
+
messageId,
|
|
91
|
+
threadId,
|
|
92
|
+
registry.componentList,
|
|
93
|
+
]);
|
|
94
|
+
if (element === null) {
|
|
95
|
+
return React.createElement(React.Fragment, null, fallback);
|
|
96
|
+
}
|
|
97
|
+
// Wrap with provider so hooks like useTamboV1ComponentState work
|
|
98
|
+
return (React.createElement(V1ComponentContentProvider, { componentId: content.id, threadId: threadId, messageId: messageId, componentName: content.name }, element));
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=v1-component-renderer.js.map
|