@tambo-ai/react 0.75.0 → 1.0.0-rc.4
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/dist/hoc/with-tambo-interactable.d.ts.map +1 -1
- package/dist/hoc/with-tambo-interactable.js +13 -13
- package/dist/hoc/with-tambo-interactable.js.map +1 -1
- package/dist/hoc/with-tambo-interactable.test.js +3 -3
- package/dist/hoc/with-tambo-interactable.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/model/component-metadata.d.ts +4 -4
- package/dist/model/component-metadata.js.map +1 -1
- package/dist/providers/tambo-client-provider.d.ts +6 -0
- package/dist/providers/tambo-client-provider.d.ts.map +1 -1
- package/dist/providers/tambo-client-provider.js +4 -2
- package/dist/providers/tambo-client-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.d.ts +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/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 +5 -5
- package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-auth-state.js +8 -8
- package/dist/v1/hooks/use-tambo-v1-auth-state.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-auth-state.test.js +12 -12
- package/dist/v1/hooks/use-tambo-v1-auth-state.test.js.map +1 -1
- 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 +50 -24
- package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js +60 -35
- 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 +7 -7
- package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +3 -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 +20 -22
- package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js +51 -51
- 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 +5 -5
- package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.js +12 -14
- package/dist/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js +19 -19
- 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 +29 -29
- 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 +5 -5
- package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +13 -17
- 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 +4 -4
- package/dist/v1/hooks/use-tambo-v1-thread.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.test.js +5 -5
- package/dist/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.d.ts +16 -7
- package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.js +41 -10
- package/dist/v1/hooks/use-tambo-v1.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.test.js +176 -48
- package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/dist/v1/index.d.ts +31 -27
- package/dist/v1/index.d.ts.map +1 -1
- package/dist/v1/index.js +45 -35
- package/dist/v1/index.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts +20 -20
- package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.js +32 -32
- package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.test.js +22 -22
- package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.d.ts +15 -15
- package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.js +17 -17
- package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.test.js +9 -9
- 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 +7 -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 +9 -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 +16 -16
- package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/dist/v1/types/auth.d.ts +2 -2
- package/dist/v1/types/auth.d.ts.map +1 -1
- package/dist/v1/types/auth.js.map +1 -1
- 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 +17 -24
- 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 +10 -8
- 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 +1 -1
- package/dist/v1/types/tool-choice.js.map +1 -1
- 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 +13 -13
- package/dist/v1/utils/event-accumulator.d.ts.map +1 -1
- package/dist/v1/utils/event-accumulator.js +26 -15
- package/dist/v1/utils/event-accumulator.js.map +1 -1
- package/dist/v1/utils/event-accumulator.test.js +54 -19
- package/dist/v1/utils/event-accumulator.test.js.map +1 -1
- package/dist/v1/utils/registry-conversion.d.ts +18 -18
- package/dist/v1/utils/registry-conversion.js +23 -23
- package/dist/v1/utils/registry-conversion.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 +1 -1
- package/dist/v1/utils/tool-call-tracker.js +1 -1
- package/dist/v1/utils/tool-call-tracker.js.map +1 -1
- package/dist/v1/utils/tool-executor.d.ts +1 -1
- package/dist/v1/utils/tool-executor.js +2 -2
- package/dist/v1/utils/tool-executor.js.map +1 -1
- package/esm/hoc/with-tambo-interactable.d.ts.map +1 -1
- package/esm/hoc/with-tambo-interactable.js +13 -13
- package/esm/hoc/with-tambo-interactable.js.map +1 -1
- package/esm/hoc/with-tambo-interactable.test.js +1 -1
- package/esm/hoc/with-tambo-interactable.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/model/component-metadata.d.ts +4 -4
- package/esm/model/component-metadata.js.map +1 -1
- package/esm/providers/tambo-client-provider.d.ts +6 -0
- package/esm/providers/tambo-client-provider.d.ts.map +1 -1
- package/esm/providers/tambo-client-provider.js +4 -2
- package/esm/providers/tambo-client-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +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/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 +5 -5
- package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-auth-state.js +8 -8
- package/esm/v1/hooks/use-tambo-v1-auth-state.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-auth-state.test.js +14 -14
- package/esm/v1/hooks/use-tambo-v1-auth-state.test.js.map +1 -1
- 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 +50 -24
- package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js +62 -37
- 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 +9 -9
- package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +3 -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 +21 -23
- package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js +54 -54
- 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 +5 -5
- package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.js +12 -14
- package/esm/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js +21 -21
- 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 +32 -32
- 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 +6 -6
- package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +15 -19
- 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 +4 -4
- package/esm/v1/hooks/use-tambo-v1-thread.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.test.js +6 -6
- package/esm/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.d.ts +16 -7
- package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.js +43 -12
- package/esm/v1/hooks/use-tambo-v1.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.test.js +178 -50
- package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/esm/v1/index.d.ts +31 -27
- package/esm/v1/index.d.ts.map +1 -1
- package/esm/v1/index.js +38 -33
- package/esm/v1/index.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts +20 -20
- package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.js +32 -32
- package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.test.js +23 -23
- package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.d.ts +15 -15
- package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.js +17 -17
- package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.test.js +10 -10
- 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 +9 -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 +9 -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 +15 -15
- package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/esm/v1/types/auth.d.ts +2 -2
- package/esm/v1/types/auth.d.ts.map +1 -1
- package/esm/v1/types/auth.js.map +1 -1
- 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 +17 -24
- 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 +10 -8
- 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 +1 -1
- package/esm/v1/types/tool-choice.js.map +1 -1
- 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 +13 -13
- package/esm/v1/utils/event-accumulator.d.ts.map +1 -1
- package/esm/v1/utils/event-accumulator.js +26 -15
- package/esm/v1/utils/event-accumulator.js.map +1 -1
- package/esm/v1/utils/event-accumulator.test.js +54 -19
- package/esm/v1/utils/event-accumulator.test.js.map +1 -1
- package/esm/v1/utils/registry-conversion.d.ts +18 -18
- package/esm/v1/utils/registry-conversion.js +23 -23
- package/esm/v1/utils/registry-conversion.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 +1 -1
- package/esm/v1/utils/tool-call-tracker.js +1 -1
- package/esm/v1/utils/tool-call-tracker.js.map +1 -1
- package/esm/v1/utils/tool-executor.d.ts +1 -1
- package/esm/v1/utils/tool-executor.js +2 -2
- package/esm/v1/utils/tool-executor.js.map +1 -1
- package/package.json +4 -9
- 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 +0 -3
- 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 -133
- 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 -279
- 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 -278
- 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 -1591
- 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 -94
- 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 -242
- 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 -273
- 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 -1553
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-stream-status.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-stream-status.ts"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAgOb,wDAgFC;AA9SD;;;;;;;GAOG;AAEH,iCAA6D;AAC7D,oEAAoE;AACpE,kFAAsE;AACtE,wDAA6D;AAsE7D;;;;;;;GAOG;AACH,SAAS,uBAAuB,CAC9B,KAAwB,EACxB,uBAAyE;IAEzE,8CAA8C;IAC9C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,IAAA,gBAAQ,EAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IAEzE,gDAAgD;IAChD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,eAAe,CAAC,CAAC,IAAI,EAAE,EAAE;YACvB,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;YAEjC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjD,MAAM,UAAU,GACd,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;gBACxD,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBACvC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBACpB,OAAO,GAAG,IAAI,CAAC;gBACjB,CAAC;YACH,CAAC;YAED,OAAO,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,kEAAkE;IAClE,OAAO,IAAA,eAAO,EAAC,GAAG,EAAE;QAClB,IAAI,CAAC,KAAK;YAAE,OAAO,EAAqC,CAAC;QAEzD,MAAM,eAAe,GAAG,uBAAuB,KAAK,MAAM,CAAC;QAC3D,MAAM,oBAAoB,GAAG,uBAAuB,KAAK,WAAW,CAAC;QAErE,MAAM,MAAM,GAAG,EAAqC,CAAC;QACrD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACzC,MAAM,UAAU,GAAG,UAAU,IAAI,eAAe,CAAC;YAEjD,MAAM,CAAC,GAAkB,CAAC,GAAG;gBAC3B,SAAS,EAAE,CAAC,UAAU,IAAI,CAAC,UAAU;gBACrC,WAAW,EAAE,UAAU,IAAI,CAAC,UAAU,IAAI,oBAAoB;gBAC9D,SAAS,EAAE,UAAU;gBACrB,KAAK,EAAE,SAAS;aACjB,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,uBAAuB,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,wBAAwB,CAC/B,uBAAyE,EACzE,UAA+C,EAC/C,YAAqB,EACrB,WAAmB;IAEnB,MAAM,YAAY,GAAiB,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CACjE,CAAC,CAAC,EAAmB,EAAE,CAAC,CAAC,KAAK,SAAS,CACxC,CAAC;IACF,MAAM,aAAa,GAAG,CAAC,CAAC,WAAW,CAAC;IAEpC,+FAA+F;IAC/F,MAAM,kBAAkB,GACtB,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEpE,oFAAoF;IACpF,MAAM,oBAAoB,GAAG,uBAAuB,KAAK,WAAW,CAAC;IACrE,MAAM,gBAAgB,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAEjE,+CAA+C;IAC/C,MAAM,UAAU,GAAG,WAAW,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAE3E,OAAO;QACL,oGAAoG;QACpG,SAAS,EACP,CAAC,YAAY;YACb,CAAC,CAAC,aAAa;gBACb,CAAC,oBAAoB;gBACrB,CAAC,kBAAkB;gBACnB,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAE3C,sFAAsF;QACtF,WAAW,EAAE,CAAC,aAAa,IAAI,CAAC,oBAAoB,IAAI,gBAAgB,CAAC;QAEzE,mDAAmD;QACnD,SAAS,EAAE,kBAAkB,IAAI,CAAC,aAAa;QAE/C,8CAA8C;QAC9C,OAAO,EAAE,aAAa,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAE3D,WAAW,EAAE,UAAU;KACxB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,SAAgB,sBAAsB;IAMpC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,IAAA,0CAAqB,GAAE,CAAC;IAC1D,MAAM,WAAW,GAAG,IAAA,wCAAc,GAAE,CAAC;IAErC;;;;;OAKG;IACH,MAAM,qBAAqB,GAAG,IAAA,cAAM,EAAC,WAAW,CAAC,CAAC;IAClD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,WAAW,KAAK,qBAAqB,CAAC,OAAO,EAAE,CAAC;YAClD,OAAO,CAAC,KAAK,CACX,qDAAqD,qBAAqB,CAAC,OAAO,SAAS,WAAW,KAAK;gBACzG,0EAA0E;gBAC1E,mEAAmE;gBACnE,0EAA0E,CAC7E,CAAC;YACF,qBAAqB,CAAC,OAAO,GAAG,WAAW,CAAC;QAC9C,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,mCAAmC;IACnC,MAAM,WAAW,GAAG,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAEpD,iDAAiD;IACjD,MAAM,kBAAkB,GACtB,WAAW,EAAE,SAAS,CAAC,MAAM,KAAK,OAAO;QACvC,CAAC,CAAC,WAAW,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO;QACvC,CAAC,CAAC,SAAS,CAAC;IAEhB,uCAAuC;IACvC,MAAM,gBAAgB,GAAG,IAAA,mCAAoB,EAC3C,WAAW,EACX,QAAQ,EACR,WAAW,CACZ,CAAC;IAEF,sCAAsC;IACtC,MAAM,cAAc,GACjB,gBAAgB,EAAE,KAA2B,IAAK,EAAY,CAAC;IAElE,wCAAwC;IACxC,MAAM,uBAAuB,GAAG,gBAAgB,EAAE,cAAc,CAAC;IAEjE,sCAAsC;IACtC,MAAM,UAAU,GAAG,uBAAuB,CACxC,cAAc,EACd,uBAAuB,CACxB,CAAC;IAEF,mFAAmF;IACnF,MAAM,YAAY,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QAChC,MAAM,YAAY,GAAG,CAAC,CAAC,gBAAgB,CAAC;QACxC,MAAM,WAAW,GAAG,kBAAkB;YACpC,CAAC,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC;YAC/B,CAAC,CAAC,SAAS,CAAC;QACd,OAAO,wBAAwB,CAC7B,uBAAuB,EACvB,UAAU,EACV,YAAY,EACZ,WAAW,CACZ,CAAC;IACJ,CAAC,EAAE;QACD,uBAAuB;QACvB,UAAU;QACV,gBAAgB;QAChB,kBAAkB;KACnB,CAAC,CAAC;IAEH,OAAO;QACL,YAAY;QACZ,UAAU;KACX,CAAC;AACJ,CAAC","sourcesContent":["\"use client\";\n\n/**\n * useTamboV1StreamStatus - Stream Status Hook for v1 API\n *\n * Provides granular streaming status for components being rendered,\n * allowing UI to respond to prop-level streaming states.\n *\n * Must be used within a component rendered via the component renderer.\n */\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useV1ComponentContent } from \"../utils/component-renderer\";\nimport { useStreamState } from \"../providers/tambo-v1-stream-context\";\nimport { findComponentContent } from \"../utils/thread-utils\";\nimport type { V1ComponentContent } from \"../types/message\";\n\n/**\n * Global stream status flags for a specific component in a message.\n * Represents the aggregate state across all props for this component only.\n * Once a component completes, its status remains stable regardless of other generations.\n */\nexport interface StreamStatus {\n /**\n * Indicates no tokens have been received for any prop and generation is not active.\n * Useful for showing initial loading states before any data arrives.\n */\n isPending: boolean;\n\n /**\n * Indicates active streaming - at least one prop is still streaming.\n * Use this to show loading animations or skeleton states during data transmission.\n */\n isStreaming: boolean;\n\n /**\n * Indicates successful completion - component streaming is done AND every prop finished without error.\n * Safe to render the final component when this is true.\n */\n isSuccess: boolean;\n\n /**\n * Indicates a fatal error occurred in any prop or the stream itself.\n * Check streamError for details about what went wrong.\n */\n isError: boolean;\n\n /**\n * The first fatal error encountered during streaming (if any).\n * Will be undefined if no errors occurred.\n */\n streamError?: Error;\n}\n\n/**\n * Streaming status flags for individual component props.\n * Tracks the state of each prop as it streams from the LLM.\n */\nexport interface PropStatus {\n /**\n * Indicates no tokens have been received for this specific prop yet.\n * The prop value is still undefined, null, or empty string.\n */\n isPending: boolean;\n\n /**\n * Indicates at least one token has been received but streaming is not complete.\n * The prop has partial content that may still be updating.\n */\n isStreaming: boolean;\n\n /**\n * Indicates this prop has finished streaming successfully.\n * The prop value is complete and stable.\n */\n isSuccess: boolean;\n\n /**\n * The error that occurred during streaming (if any).\n * Will be undefined if no error occurred for this prop.\n */\n error?: Error;\n}\n\n/**\n * Track streaming status for individual props by monitoring their values.\n * Monitors when props receive their first token and when they complete streaming.\n * @template Props - The type of the component props being tracked\n * @param props - The current component props object\n * @param componentStreamingState - The current streaming state of the component\n * @returns A record mapping each prop key to its PropStatus\n */\nfunction usePropsStreamingStatus<Props extends object>(\n props: Props | undefined,\n componentStreamingState: V1ComponentContent[\"streamingState\"] | undefined,\n): Partial<Record<keyof Props, PropStatus>> {\n /** Track which props have received content */\n const [startedProps, setStartedProps] = useState<Set<string>>(new Set());\n\n /** Update started props when content arrives */\n useEffect(() => {\n if (!props) return;\n\n setStartedProps((prev) => {\n let changed = false;\n const newStarted = new Set(prev);\n\n for (const [key, value] of Object.entries(props)) {\n const hasContent =\n value !== undefined && value !== null && value !== \"\";\n if (hasContent && !newStarted.has(key)) {\n newStarted.add(key);\n changed = true;\n }\n }\n\n return changed ? newStarted : prev;\n });\n }, [props]);\n\n /** Derive prop statuses from started props and streaming state */\n return useMemo(() => {\n if (!props) return {} as Record<keyof Props, PropStatus>;\n\n const isStreamingDone = componentStreamingState === \"done\";\n const isComponentStreaming = componentStreamingState === \"streaming\";\n\n const result = {} as Record<keyof Props, PropStatus>;\n for (const key of Object.keys(props)) {\n const hasStarted = startedProps.has(key);\n const isComplete = hasStarted && isStreamingDone;\n\n result[key as keyof Props] = {\n isPending: !hasStarted && !isComplete,\n isStreaming: hasStarted && !isComplete && isComponentStreaming,\n isSuccess: isComplete,\n error: undefined,\n };\n }\n return result;\n }, [props, startedProps, componentStreamingState]);\n}\n\n/**\n * Derives global StreamStatus from component streaming state and individual prop statuses.\n * Aggregates individual prop states into a unified stream status.\n * @template Props - The type of the component props\n * @param componentStreamingState - The current streaming state of the component\n * @param propStatus - Status record for each individual prop\n * @param hasComponent - Whether a component exists in the current message\n * @param streamError - Any error from the streaming process itself\n * @returns The aggregated StreamStatus for the entire component\n */\nfunction deriveGlobalStreamStatus(\n componentStreamingState: V1ComponentContent[\"streamingState\"] | undefined,\n propStatus: Partial<Record<string, PropStatus>>,\n hasComponent: boolean,\n streamError?: Error,\n): StreamStatus {\n const propStatuses: PropStatus[] = Object.values(propStatus).filter(\n (p): p is PropStatus => p !== undefined,\n );\n const isStreamError = !!streamError;\n\n // If all props are already successful, the component is complete regardless of streaming state\n const allPropsSuccessful =\n propStatuses.length > 0 && propStatuses.every((p) => p.isSuccess);\n\n // Component is streaming if streamingState is \"streaming\" (even before props start)\n const isComponentStreaming = componentStreamingState === \"streaming\";\n const anyPropStreaming = propStatuses.some((p) => p.isStreaming);\n\n /** Find first error from stream or any prop */\n const firstError = streamError ?? propStatuses.find((p) => p.error)?.error;\n\n return {\n /** isPending: no component yet OR (not streaming, not error, not success, and all props pending) */\n isPending:\n !hasComponent ||\n (!isStreamError &&\n !isComponentStreaming &&\n !allPropsSuccessful &&\n propStatuses.every((p) => p.isPending)),\n\n /** isStreaming: component is streaming OR any prop is streaming (but not if error) */\n isStreaming: !isStreamError && (isComponentStreaming || anyPropStreaming),\n\n /** isSuccess: all props successful and no error */\n isSuccess: allPropsSuccessful && !isStreamError,\n\n /** isError: stream error OR any prop error */\n isError: isStreamError || propStatuses.some((p) => p.error),\n\n streamError: firstError,\n };\n}\n\n/**\n * Track streaming status for Tambo v1 component props.\n *\n * **Important**: Props update repeatedly during streaming and may be partial.\n * Use `propStatus.<field>?.isSuccess` before treating a prop as complete.\n *\n * Pair with `useTamboV1ComponentState` to disable inputs while streaming.\n * @see {@link https://docs.tambo.co/concepts/generative-interfaces/component-state}\n * @template Props - Component props type\n * @returns `streamStatus` (overall) and `propStatus` (per-prop) flags\n * @throws {Error} When used outside a rendered component\n * @example\n * ```tsx\n * // Wait for entire stream\n * const { streamStatus } = useTamboV1StreamStatus();\n * if (!streamStatus.isSuccess) return <Spinner />;\n * return <Card {...props} />;\n * ```\n * @example\n * ```tsx\n * // Highlight in-flight props\n * const { propStatus } = useTamboV1StreamStatus<Props>();\n * <h2 className={propStatus.title?.isStreaming ? \"animate-pulse\" : \"\"}>\n * {title}\n * </h2>\n * ```\n */\nexport function useTamboV1StreamStatus<\n Props extends object = Record<string, unknown>,\n>(): {\n streamStatus: StreamStatus;\n propStatus: Partial<Record<keyof Props, PropStatus>>;\n} {\n const { componentId, threadId } = useV1ComponentContent();\n const streamState = useStreamState();\n\n /**\n * Error if componentId changes - this indicates the provider hierarchy is broken.\n * The componentId should remain stable for the lifetime of the component.\n * If this fires, the TamboV1ComponentRenderer is likely being used incorrectly,\n * or the component tree is being remounted in unexpected ways.\n */\n const initialComponentIdRef = useRef(componentId);\n useEffect(() => {\n if (componentId !== initialComponentIdRef.current) {\n console.error(\n `useTamboV1StreamStatus: componentId changed from \"${initialComponentIdRef.current}\" to \"${componentId}\". ` +\n \"This indicates a bug in the component tree or incorrect provider usage. \" +\n \"The componentId must remain stable for the component's lifetime. \" +\n \"Check that TamboV1ComponentRenderer is not being remounted unexpectedly.\",\n );\n initialComponentIdRef.current = componentId;\n }\n }, [componentId]);\n\n /** Get the current thread state */\n const threadState = streamState.threadMap[threadId];\n\n /** Get error message from stream state if any */\n const streamErrorMessage =\n threadState?.streaming.status === \"error\"\n ? threadState?.streaming.error?.message\n : undefined;\n\n /** Find the component content block */\n const componentContent = findComponentContent(\n streamState,\n threadId,\n componentId,\n );\n\n /** Get the current component props */\n const componentProps =\n (componentContent?.props as Props | undefined) ?? ({} as Props);\n\n /** Get the component streaming state */\n const componentStreamingState = componentContent?.streamingState;\n\n /** Track per-prop streaming status */\n const propStatus = usePropsStreamingStatus(\n componentProps,\n componentStreamingState,\n );\n\n /** Derive global stream status from prop statuses and component streaming state */\n const streamStatus = useMemo(() => {\n const hasComponent = !!componentContent;\n const streamError = streamErrorMessage\n ? new Error(streamErrorMessage)\n : undefined;\n return deriveGlobalStreamStatus(\n componentStreamingState,\n propStatus,\n hasComponent,\n streamError,\n );\n }, [\n componentStreamingState,\n propStatus,\n componentContent,\n streamErrorMessage,\n ]);\n\n return {\n streamStatus,\n propStatus,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-stream-status.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-stream-status.ts"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAgOb,oDA6EC;AA3SD;;;;;;;GAOG;AAEH,iCAA6D;AAC7D,oEAAkE;AAClE,kFAAsE;AACtE,wDAA6D;AAsE7D;;;;;;;GAOG;AACH,SAAS,uBAAuB,CAC9B,KAAwB,EACxB,uBAA4E;IAE5E,8CAA8C;IAC9C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,IAAA,gBAAQ,EAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IAEzE,gDAAgD;IAChD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,eAAe,CAAC,CAAC,IAAI,EAAE,EAAE;YACvB,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;YAEjC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjD,MAAM,UAAU,GACd,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;gBACxD,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBACvC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBACpB,OAAO,GAAG,IAAI,CAAC;gBACjB,CAAC;YACH,CAAC;YAED,OAAO,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,kEAAkE;IAClE,OAAO,IAAA,eAAO,EAAC,GAAG,EAAE;QAClB,IAAI,CAAC,KAAK;YAAE,OAAO,EAAqC,CAAC;QAEzD,MAAM,eAAe,GAAG,uBAAuB,KAAK,MAAM,CAAC;QAC3D,MAAM,oBAAoB,GAAG,uBAAuB,KAAK,WAAW,CAAC;QAErE,MAAM,MAAM,GAAG,EAAqC,CAAC;QACrD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACzC,MAAM,UAAU,GAAG,UAAU,IAAI,eAAe,CAAC;YAEjD,MAAM,CAAC,GAAkB,CAAC,GAAG;gBAC3B,SAAS,EAAE,CAAC,UAAU,IAAI,CAAC,UAAU;gBACrC,WAAW,EAAE,UAAU,IAAI,CAAC,UAAU,IAAI,oBAAoB;gBAC9D,SAAS,EAAE,UAAU;gBACrB,KAAK,EAAE,SAAS;aACjB,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,uBAAuB,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,wBAAwB,CAC/B,uBAA4E,EAC5E,UAA+C,EAC/C,YAAqB,EACrB,WAAmB;IAEnB,MAAM,YAAY,GAAiB,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CACjE,CAAC,CAAC,EAAmB,EAAE,CAAC,CAAC,KAAK,SAAS,CACxC,CAAC;IACF,MAAM,aAAa,GAAG,CAAC,CAAC,WAAW,CAAC;IAEpC,+FAA+F;IAC/F,MAAM,kBAAkB,GACtB,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEpE,oFAAoF;IACpF,MAAM,oBAAoB,GAAG,uBAAuB,KAAK,WAAW,CAAC;IACrE,MAAM,gBAAgB,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAEjE,+CAA+C;IAC/C,MAAM,UAAU,GAAG,WAAW,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAE3E,OAAO;QACL,oGAAoG;QACpG,SAAS,EACP,CAAC,YAAY;YACb,CAAC,CAAC,aAAa;gBACb,CAAC,oBAAoB;gBACrB,CAAC,kBAAkB;gBACnB,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAE3C,sFAAsF;QACtF,WAAW,EAAE,CAAC,aAAa,IAAI,CAAC,oBAAoB,IAAI,gBAAgB,CAAC;QAEzE,mDAAmD;QACnD,SAAS,EAAE,kBAAkB,IAAI,CAAC,aAAa;QAE/C,8CAA8C;QAC9C,OAAO,EAAE,aAAa,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAE3D,WAAW,EAAE,UAAU;KACxB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,SAAgB,oBAAoB;IAMlC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,IAAA,wCAAmB,GAAE,CAAC;IACxD,MAAM,WAAW,GAAG,IAAA,wCAAc,GAAE,CAAC;IAErC;;;;;OAKG;IACH,MAAM,qBAAqB,GAAG,IAAA,cAAM,EAAC,WAAW,CAAC,CAAC;IAClD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,WAAW,KAAK,qBAAqB,CAAC,OAAO,EAAE,CAAC;YAClD,OAAO,CAAC,KAAK,CACX,mDAAmD,qBAAqB,CAAC,OAAO,SAAS,WAAW,KAAK;gBACvG,0EAA0E;gBAC1E,mEAAmE;gBACnE,mEAAmE,CACtE,CAAC;YACF,qBAAqB,CAAC,OAAO,GAAG,WAAW,CAAC;QAC9C,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,mCAAmC;IACnC,MAAM,WAAW,GAAG,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAEpD,iDAAiD;IACjD,MAAM,kBAAkB,GAAG,WAAW,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC;IAEjE,uCAAuC;IACvC,MAAM,gBAAgB,GAAG,IAAA,mCAAoB,EAC3C,WAAW,EACX,QAAQ,EACR,WAAW,CACZ,CAAC;IAEF,sCAAsC;IACtC,MAAM,cAAc,GACjB,gBAAgB,EAAE,KAA2B,IAAK,EAAY,CAAC;IAElE,wCAAwC;IACxC,MAAM,uBAAuB,GAAG,gBAAgB,EAAE,cAAc,CAAC;IAEjE,sCAAsC;IACtC,MAAM,UAAU,GAAG,uBAAuB,CACxC,cAAc,EACd,uBAAuB,CACxB,CAAC;IAEF,mFAAmF;IACnF,MAAM,YAAY,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QAChC,MAAM,YAAY,GAAG,CAAC,CAAC,gBAAgB,CAAC;QACxC,MAAM,WAAW,GAAG,kBAAkB;YACpC,CAAC,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC;YAC/B,CAAC,CAAC,SAAS,CAAC;QACd,OAAO,wBAAwB,CAC7B,uBAAuB,EACvB,UAAU,EACV,YAAY,EACZ,WAAW,CACZ,CAAC;IACJ,CAAC,EAAE;QACD,uBAAuB;QACvB,UAAU;QACV,gBAAgB;QAChB,kBAAkB;KACnB,CAAC,CAAC;IAEH,OAAO;QACL,YAAY;QACZ,UAAU;KACX,CAAC;AACJ,CAAC","sourcesContent":["\"use client\";\n\n/**\n * useTamboStreamStatus - Stream Status Hook\n *\n * Provides granular streaming status for components being rendered,\n * allowing UI to respond to prop-level streaming states.\n *\n * Must be used within a component rendered via the component renderer.\n */\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useComponentContent } from \"../utils/component-renderer\";\nimport { useStreamState } from \"../providers/tambo-v1-stream-context\";\nimport { findComponentContent } from \"../utils/thread-utils\";\nimport type { TamboComponentContent } from \"../types/message\";\n\n/**\n * Global stream status flags for a specific component in a message.\n * Represents the aggregate state across all props for this component only.\n * Once a component completes, its status remains stable regardless of other generations.\n */\nexport interface StreamStatus {\n /**\n * Indicates no tokens have been received for any prop and generation is not active.\n * Useful for showing initial loading states before any data arrives.\n */\n isPending: boolean;\n\n /**\n * Indicates active streaming - at least one prop is still streaming.\n * Use this to show loading animations or skeleton states during data transmission.\n */\n isStreaming: boolean;\n\n /**\n * Indicates successful completion - component streaming is done AND every prop finished without error.\n * Safe to render the final component when this is true.\n */\n isSuccess: boolean;\n\n /**\n * Indicates a fatal error occurred in any prop or the stream itself.\n * Check streamError for details about what went wrong.\n */\n isError: boolean;\n\n /**\n * The first fatal error encountered during streaming (if any).\n * Will be undefined if no errors occurred.\n */\n streamError?: Error;\n}\n\n/**\n * Streaming status flags for individual component props.\n * Tracks the state of each prop as it streams from the LLM.\n */\nexport interface PropStatus {\n /**\n * Indicates no tokens have been received for this specific prop yet.\n * The prop value is still undefined, null, or empty string.\n */\n isPending: boolean;\n\n /**\n * Indicates at least one token has been received but streaming is not complete.\n * The prop has partial content that may still be updating.\n */\n isStreaming: boolean;\n\n /**\n * Indicates this prop has finished streaming successfully.\n * The prop value is complete and stable.\n */\n isSuccess: boolean;\n\n /**\n * The error that occurred during streaming (if any).\n * Will be undefined if no error occurred for this prop.\n */\n error?: Error;\n}\n\n/**\n * Track streaming status for individual props by monitoring their values.\n * Monitors when props receive their first token and when they complete streaming.\n * @template Props - The type of the component props being tracked\n * @param props - The current component props object\n * @param componentStreamingState - The current streaming state of the component\n * @returns A record mapping each prop key to its PropStatus\n */\nfunction usePropsStreamingStatus<Props extends object>(\n props: Props | undefined,\n componentStreamingState: TamboComponentContent[\"streamingState\"] | undefined,\n): Partial<Record<keyof Props, PropStatus>> {\n /** Track which props have received content */\n const [startedProps, setStartedProps] = useState<Set<string>>(new Set());\n\n /** Update started props when content arrives */\n useEffect(() => {\n if (!props) return;\n\n setStartedProps((prev) => {\n let changed = false;\n const newStarted = new Set(prev);\n\n for (const [key, value] of Object.entries(props)) {\n const hasContent =\n value !== undefined && value !== null && value !== \"\";\n if (hasContent && !newStarted.has(key)) {\n newStarted.add(key);\n changed = true;\n }\n }\n\n return changed ? newStarted : prev;\n });\n }, [props]);\n\n /** Derive prop statuses from started props and streaming state */\n return useMemo(() => {\n if (!props) return {} as Record<keyof Props, PropStatus>;\n\n const isStreamingDone = componentStreamingState === \"done\";\n const isComponentStreaming = componentStreamingState === \"streaming\";\n\n const result = {} as Record<keyof Props, PropStatus>;\n for (const key of Object.keys(props)) {\n const hasStarted = startedProps.has(key);\n const isComplete = hasStarted && isStreamingDone;\n\n result[key as keyof Props] = {\n isPending: !hasStarted && !isComplete,\n isStreaming: hasStarted && !isComplete && isComponentStreaming,\n isSuccess: isComplete,\n error: undefined,\n };\n }\n return result;\n }, [props, startedProps, componentStreamingState]);\n}\n\n/**\n * Derives global StreamStatus from component streaming state and individual prop statuses.\n * Aggregates individual prop states into a unified stream status.\n * @template Props - The type of the component props\n * @param componentStreamingState - The current streaming state of the component\n * @param propStatus - Status record for each individual prop\n * @param hasComponent - Whether a component exists in the current message\n * @param streamError - Any error from the streaming process itself\n * @returns The aggregated StreamStatus for the entire component\n */\nfunction deriveGlobalStreamStatus(\n componentStreamingState: TamboComponentContent[\"streamingState\"] | undefined,\n propStatus: Partial<Record<string, PropStatus>>,\n hasComponent: boolean,\n streamError?: Error,\n): StreamStatus {\n const propStatuses: PropStatus[] = Object.values(propStatus).filter(\n (p): p is PropStatus => p !== undefined,\n );\n const isStreamError = !!streamError;\n\n // If all props are already successful, the component is complete regardless of streaming state\n const allPropsSuccessful =\n propStatuses.length > 0 && propStatuses.every((p) => p.isSuccess);\n\n // Component is streaming if streamingState is \"streaming\" (even before props start)\n const isComponentStreaming = componentStreamingState === \"streaming\";\n const anyPropStreaming = propStatuses.some((p) => p.isStreaming);\n\n /** Find first error from stream or any prop */\n const firstError = streamError ?? propStatuses.find((p) => p.error)?.error;\n\n return {\n /** isPending: no component yet OR (not streaming, not error, not success, and all props pending) */\n isPending:\n !hasComponent ||\n (!isStreamError &&\n !isComponentStreaming &&\n !allPropsSuccessful &&\n propStatuses.every((p) => p.isPending)),\n\n /** isStreaming: component is streaming OR any prop is streaming (but not if error) */\n isStreaming: !isStreamError && (isComponentStreaming || anyPropStreaming),\n\n /** isSuccess: all props successful and no error */\n isSuccess: allPropsSuccessful && !isStreamError,\n\n /** isError: stream error OR any prop error */\n isError: isStreamError || propStatuses.some((p) => p.error),\n\n streamError: firstError,\n };\n}\n\n/**\n * Track streaming status for Tambo component props.\n *\n * **Important**: Props update repeatedly during streaming and may be partial.\n * Use `propStatus.<field>?.isSuccess` before treating a prop as complete.\n *\n * Pair with `useTamboComponentState` to disable inputs while streaming.\n * @see {@link https://docs.tambo.co/concepts/generative-interfaces/component-state}\n * @template Props - Component props type\n * @returns `streamStatus` (overall) and `propStatus` (per-prop) flags\n * @throws {Error} When used outside a rendered component\n * @example\n * ```tsx\n * // Wait for entire stream\n * const { streamStatus } = useTamboStreamStatus();\n * if (!streamStatus.isSuccess) return <Spinner />;\n * return <Card {...props} />;\n * ```\n * @example\n * ```tsx\n * // Highlight in-flight props\n * const { propStatus } = useTamboStreamStatus<Props>();\n * <h2 className={propStatus.title?.isStreaming ? \"animate-pulse\" : \"\"}>\n * {title}\n * </h2>\n * ```\n */\nexport function useTamboStreamStatus<\n Props extends object = Record<string, unknown>,\n>(): {\n streamStatus: StreamStatus;\n propStatus: Partial<Record<keyof Props, PropStatus>>;\n} {\n const { componentId, threadId } = useComponentContent();\n const streamState = useStreamState();\n\n /**\n * Error if componentId changes - this indicates the provider hierarchy is broken.\n * The componentId should remain stable for the lifetime of the component.\n * If this fires, the ComponentRenderer is likely being used incorrectly,\n * or the component tree is being remounted in unexpected ways.\n */\n const initialComponentIdRef = useRef(componentId);\n useEffect(() => {\n if (componentId !== initialComponentIdRef.current) {\n console.error(\n `useTamboStreamStatus: componentId changed from \"${initialComponentIdRef.current}\" to \"${componentId}\". ` +\n \"This indicates a bug in the component tree or incorrect provider usage. \" +\n \"The componentId must remain stable for the component's lifetime. \" +\n \"Check that ComponentRenderer is not being remounted unexpectedly.\",\n );\n initialComponentIdRef.current = componentId;\n }\n }, [componentId]);\n\n /** Get the current thread state */\n const threadState = streamState.threadMap[threadId];\n\n /** Get error message from stream state if any */\n const streamErrorMessage = threadState?.streaming.error?.message;\n\n /** Find the component content block */\n const componentContent = findComponentContent(\n streamState,\n threadId,\n componentId,\n );\n\n /** Get the current component props */\n const componentProps =\n (componentContent?.props as Props | undefined) ?? ({} as Props);\n\n /** Get the component streaming state */\n const componentStreamingState = componentContent?.streamingState;\n\n /** Track per-prop streaming status */\n const propStatus = usePropsStreamingStatus(\n componentProps,\n componentStreamingState,\n );\n\n /** Derive global stream status from prop statuses and component streaming state */\n const streamStatus = useMemo(() => {\n const hasComponent = !!componentContent;\n const streamError = streamErrorMessage\n ? new Error(streamErrorMessage)\n : undefined;\n return deriveGlobalStreamStatus(\n componentStreamingState,\n propStatus,\n hasComponent,\n streamError,\n );\n }, [\n componentStreamingState,\n propStatus,\n componentContent,\n streamErrorMessage,\n ]);\n\n return {\n streamStatus,\n propStatus,\n };\n}\n"]}
|
|
@@ -4,7 +4,7 @@ const react_1 = require("@testing-library/react");
|
|
|
4
4
|
const use_tambo_v1_stream_status_1 = require("./use-tambo-v1-stream-status");
|
|
5
5
|
// Mock the required hooks
|
|
6
6
|
jest.mock("../utils/component-renderer", () => ({
|
|
7
|
-
|
|
7
|
+
useComponentContent: jest.fn(),
|
|
8
8
|
}));
|
|
9
9
|
jest.mock("../providers/tambo-v1-stream-context", () => ({
|
|
10
10
|
useStreamState: jest.fn(),
|
|
@@ -15,7 +15,7 @@ const tambo_v1_stream_context_1 = require("../providers/tambo-v1-stream-context"
|
|
|
15
15
|
// Mock window for SSR tests
|
|
16
16
|
const originalWindow = global.window;
|
|
17
17
|
// Get the mocked functions
|
|
18
|
-
const
|
|
18
|
+
const mockUseTamboComponentContent = jest.mocked(component_renderer_1.useComponentContent);
|
|
19
19
|
const mockUseStreamState = jest.mocked(tambo_v1_stream_context_1.useStreamState);
|
|
20
20
|
/**
|
|
21
21
|
* Helper to create a component content block
|
|
@@ -73,12 +73,12 @@ function createStreamState(threadState, threadId = "test-thread") {
|
|
|
73
73
|
currentThreadId: threadId,
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
|
-
describe("
|
|
76
|
+
describe("useTamboStreamStatus", () => {
|
|
77
77
|
beforeEach(() => {
|
|
78
78
|
// Restore window for client-side tests
|
|
79
79
|
global.window = originalWindow;
|
|
80
80
|
// Default mock implementations
|
|
81
|
-
|
|
81
|
+
mockUseTamboComponentContent.mockReturnValue({
|
|
82
82
|
componentId: "test-component",
|
|
83
83
|
threadId: "test-thread",
|
|
84
84
|
messageId: "test-message",
|
|
@@ -103,7 +103,7 @@ describe("useTamboV1StreamStatus", () => {
|
|
|
103
103
|
const message = createMessage(componentContent);
|
|
104
104
|
const threadState = createThreadState([message]);
|
|
105
105
|
mockUseStreamState.mockReturnValue(createStreamState(threadState));
|
|
106
|
-
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.
|
|
106
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.useTamboStreamStatus)());
|
|
107
107
|
expect(result.current.streamStatus).toEqual({
|
|
108
108
|
isPending: true,
|
|
109
109
|
isStreaming: false,
|
|
@@ -135,7 +135,7 @@ describe("useTamboV1StreamStatus", () => {
|
|
|
135
135
|
const message = createMessage(componentContent);
|
|
136
136
|
const threadState = createThreadState([message]);
|
|
137
137
|
mockUseStreamState.mockReturnValue(createStreamState(threadState));
|
|
138
|
-
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.
|
|
138
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.useTamboStreamStatus)());
|
|
139
139
|
// Global should be streaming even though no props have content yet
|
|
140
140
|
expect(result.current.streamStatus.isStreaming).toBe(true);
|
|
141
141
|
expect(result.current.streamStatus.isPending).toBe(false);
|
|
@@ -151,7 +151,7 @@ describe("useTamboV1StreamStatus", () => {
|
|
|
151
151
|
const message = createMessage(componentContent);
|
|
152
152
|
const threadState = createThreadState([message]);
|
|
153
153
|
mockUseStreamState.mockReturnValue(createStreamState(threadState));
|
|
154
|
-
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.
|
|
154
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.useTamboStreamStatus)());
|
|
155
155
|
// Title prop should be streaming since it has content
|
|
156
156
|
expect(result.current.propStatus.title?.isStreaming).toBe(true);
|
|
157
157
|
expect(result.current.propStatus.title?.isPending).toBe(false);
|
|
@@ -170,7 +170,7 @@ describe("useTamboV1StreamStatus", () => {
|
|
|
170
170
|
const message = createMessage(componentContent);
|
|
171
171
|
let threadState = createThreadState([message]);
|
|
172
172
|
mockUseStreamState.mockReturnValue(createStreamState(threadState));
|
|
173
|
-
const { result, rerender } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.
|
|
173
|
+
const { result, rerender } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.useTamboStreamStatus)());
|
|
174
174
|
// Phase 1: Init - isPending = true
|
|
175
175
|
expect(result.current.streamStatus.isPending).toBe(true);
|
|
176
176
|
expect(result.current.streamStatus.isStreaming).toBe(false);
|
|
@@ -210,12 +210,12 @@ describe("useTamboV1StreamStatus", () => {
|
|
|
210
210
|
const message = createMessage(componentContent);
|
|
211
211
|
const threadState = createThreadState([message], {
|
|
212
212
|
streaming: {
|
|
213
|
-
status: "
|
|
213
|
+
status: "idle",
|
|
214
214
|
error: { message: "Generation failed", code: "GENERATION_ERROR" },
|
|
215
215
|
},
|
|
216
216
|
});
|
|
217
217
|
mockUseStreamState.mockReturnValue(createStreamState(threadState));
|
|
218
|
-
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.
|
|
218
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.useTamboStreamStatus)());
|
|
219
219
|
// Error state: isPending=false (error overrides pending), isStreaming=false (error stops streaming)
|
|
220
220
|
expect(result.current.streamStatus.isPending).toBe(false);
|
|
221
221
|
expect(result.current.streamStatus.isStreaming).toBe(false);
|
|
@@ -233,7 +233,7 @@ describe("useTamboV1StreamStatus", () => {
|
|
|
233
233
|
const message = createMessage(componentContent);
|
|
234
234
|
const threadState = createThreadState([message]);
|
|
235
235
|
mockUseStreamState.mockReturnValue(createStreamState(threadState));
|
|
236
|
-
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.
|
|
236
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.useTamboStreamStatus)());
|
|
237
237
|
// All props are pending and no streaming activity
|
|
238
238
|
expect(result.current.streamStatus.isPending).toBe(true);
|
|
239
239
|
expect(result.current.propStatus.title?.isPending).toBe(true);
|
|
@@ -249,7 +249,7 @@ describe("useTamboV1StreamStatus", () => {
|
|
|
249
249
|
const startMessage = createMessage(startComponent);
|
|
250
250
|
let threadState = createThreadState([startMessage]);
|
|
251
251
|
mockUseStreamState.mockReturnValue(createStreamState(threadState));
|
|
252
|
-
const { result, rerender } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.
|
|
252
|
+
const { result, rerender } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.useTamboStreamStatus)());
|
|
253
253
|
// Step 2: Simulate streaming in title
|
|
254
254
|
const titleComponent = createComponentContent({
|
|
255
255
|
props: { title: "Complete Title", body: "" },
|
|
@@ -292,7 +292,7 @@ describe("useTamboV1StreamStatus", () => {
|
|
|
292
292
|
const message = createMessage(componentContent);
|
|
293
293
|
const threadState = createThreadState([message]);
|
|
294
294
|
mockUseStreamState.mockReturnValue(createStreamState(threadState));
|
|
295
|
-
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.
|
|
295
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.useTamboStreamStatus)());
|
|
296
296
|
// TypeScript should infer these keys correctly
|
|
297
297
|
expect(result.current.propStatus.title).toBeDefined();
|
|
298
298
|
expect(result.current.propStatus.description).toBeDefined();
|
|
@@ -306,7 +306,7 @@ describe("useTamboV1StreamStatus", () => {
|
|
|
306
306
|
const message = createMessage(componentContent);
|
|
307
307
|
const threadState = createThreadState([message]);
|
|
308
308
|
mockUseStreamState.mockReturnValue(createStreamState(threadState));
|
|
309
|
-
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.
|
|
309
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.useTamboStreamStatus)());
|
|
310
310
|
expect(result.current.streamStatus).toBeDefined();
|
|
311
311
|
expect(result.current.propStatus).toBeDefined();
|
|
312
312
|
});
|
|
@@ -322,7 +322,7 @@ describe("useTamboV1StreamStatus", () => {
|
|
|
322
322
|
},
|
|
323
323
|
]);
|
|
324
324
|
mockUseStreamState.mockReturnValue(createStreamState(threadState));
|
|
325
|
-
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.
|
|
325
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.useTamboStreamStatus)());
|
|
326
326
|
expect(result.current.streamStatus.isPending).toBe(true);
|
|
327
327
|
expect(result.current.propStatus).toEqual({});
|
|
328
328
|
});
|
|
@@ -331,7 +331,7 @@ describe("useTamboV1StreamStatus", () => {
|
|
|
331
331
|
threadMap: {},
|
|
332
332
|
currentThreadId: "non-existent",
|
|
333
333
|
});
|
|
334
|
-
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.
|
|
334
|
+
const { result } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.useTamboStreamStatus)());
|
|
335
335
|
expect(result.current.streamStatus.isPending).toBe(true);
|
|
336
336
|
expect(result.current.propStatus).toEqual({});
|
|
337
337
|
});
|
|
@@ -345,17 +345,17 @@ describe("useTamboV1StreamStatus", () => {
|
|
|
345
345
|
const message = createMessage(componentContent);
|
|
346
346
|
const threadState = createThreadState([message]);
|
|
347
347
|
mockUseStreamState.mockReturnValue(createStreamState(threadState));
|
|
348
|
-
|
|
348
|
+
mockUseTamboComponentContent.mockReturnValue({
|
|
349
349
|
componentId: "first-component",
|
|
350
350
|
threadId: "test-thread",
|
|
351
351
|
messageId: "test-message",
|
|
352
352
|
componentName: "TestComponent",
|
|
353
353
|
});
|
|
354
|
-
const { rerender } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.
|
|
354
|
+
const { rerender } = (0, react_1.renderHook)(() => (0, use_tambo_v1_stream_status_1.useTamboStreamStatus)());
|
|
355
355
|
// No error initially
|
|
356
356
|
expect(consoleSpy).not.toHaveBeenCalled();
|
|
357
357
|
// Change componentId (this should not happen in practice)
|
|
358
|
-
|
|
358
|
+
mockUseTamboComponentContent.mockReturnValue({
|
|
359
359
|
componentId: "second-component",
|
|
360
360
|
threadId: "test-thread",
|
|
361
361
|
messageId: "test-message",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-stream-status.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-stream-status.test.tsx"],"names":[],"mappings":";;AAAA,kDAAoD;AACpD,6EAAsE;AAEtE,0BAA0B;AAC1B,IAAI,CAAC,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9C,qBAAqB,EAAE,IAAI,CAAC,EAAE,EAAE;CACjC,CAAC,CAAC,CAAC;AAEJ,IAAI,CAAC,IAAI,CAAC,sCAAsC,EAAE,GAAG,EAAE,CAAC,CAAC;IACvD,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;CAC1B,CAAC,CAAC,CAAC;AAEJ,8BAA8B;AAC9B,oEAAoE;AACpE,kFAAsE;AAItE,4BAA4B;AAC5B,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;AAErC,2BAA2B;AAC3B,MAAM,yBAAyB,GAAG,IAAI,CAAC,MAAM,CAAC,0CAAqB,CAAC,CAAC;AACrE,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC,wCAAc,CAAC,CAAC;AAEvD;;GAEG;AACH,SAAS,sBAAsB,CAC7B,YAAyC,EAAE;IAE3C,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,EAAE,EAAE,gBAAgB;QACpB,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,EAAE;QACT,cAAc,EAAE,SAAS;QACzB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CACpB,gBAAoC,EACpC,YAAqC,EAAE;IAEvC,OAAO;QACL,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,CAAC,gBAAgB,CAAC;QAC3B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CACxB,QAA0B,EAC1B,YAAkC,EAAE;IAEpC,OAAO;QACL,MAAM,EAAE;YACN,EAAE,EAAE,aAAa;YACjB,QAAQ;YACR,MAAM,EAAE,MAAM;YACd,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,gBAAgB,EAAE,KAAK;SACxB;QACD,SAAS,EAAE;YACT,MAAM,EAAE,MAAM;SACf;QACD,oBAAoB,EAAE,IAAI,GAAG,EAAE;QAC/B,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CACxB,WAAwB,EACxB,QAAQ,GAAG,aAAa;IAExB,OAAO;QACL,SAAS,EAAE;YACT,CAAC,QAAQ,CAAC,EAAE,WAAW;SACxB;QACD,eAAe,EAAE,QAAQ;KAC1B,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,UAAU,CAAC,GAAG,EAAE;QACd,uCAAuC;QACvC,MAAM,CAAC,MAAM,GAAG,cAAc,CAAC;QAE/B,+BAA+B;QAC/B,yBAAyB,CAAC,eAAe,CAAC;YACxC,WAAW,EAAE,gBAAgB;YAC7B,QAAQ,EAAE,aAAa;YACvB,SAAS,EAAE,cAAc;YACzB,aAAa,EAAE,eAAe;SAC/B,CAAC,CAAC;QAEH,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;QAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,iCAAiC;QACjC,MAAM,CAAC,MAAM,GAAG,cAAc,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,2FAA2F,EAAE,GAAG,EAAE;YACnG,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;gBAC9C,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC9B,cAAc,EAAE,SAAS;aAC1B,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;YAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACjD,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CACjC,IAAA,mDAAsB,GAAmC,CAC1D,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC;gBAC1C,SAAS,EAAE,IAAI;gBACf,WAAW,EAAE,KAAK;gBAClB,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,SAAS;aACvB,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC;gBAC9C,SAAS,EAAE,IAAI;gBACf,WAAW,EAAE,KAAK;gBAClB,SAAS,EAAE,KAAK;gBAChB,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;gBAC7C,SAAS,EAAE,IAAI;gBACf,WAAW,EAAE,KAAK;gBAClB,SAAS,EAAE,KAAK;gBAChB,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAC3C,EAAE,CAAC,uFAAuF,EAAE,GAAG,EAAE;YAC/F,mDAAmD;YACnD,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;gBAC9C,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC9B,cAAc,EAAE,WAAW;aAC5B,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;YAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACjD,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CACjC,IAAA,mDAAsB,GAAmC,CAC1D,CAAC;YAEF,mEAAmE;YACnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAE1D,2CAA2C;YAC3C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;YAChF,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;gBAC9C,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;gBACnC,cAAc,EAAE,WAAW;aAC5B,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;YAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACjD,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CACjC,IAAA,mDAAsB,GAAmC,CAC1D,CAAC;YAEF,sDAAsD;YACtD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAE/D,4DAA4D;YAC5D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE7D,oEAAoE;YACpE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;YAC1E,oCAAoC;YACpC,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;gBAC9C,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC9B,cAAc,EAAE,SAAS;aAC1B,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;YAChD,IAAI,WAAW,GAAG,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YAC/C,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAC3C,IAAA,mDAAsB,GAAmC,CAC1D,CAAC;YAEF,mCAAmC;YACnC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAE1D,wDAAwD;YACxD,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;gBAChD,KAAK,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE;gBACrD,cAAc,EAAE,WAAW;aAC5B,CAAC,CAAC;YACH,MAAM,gBAAgB,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAAC;YAC3D,WAAW,GAAG,iBAAiB,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACpD,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,QAAQ,EAAE,CAAC;YAEX,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAE1D,qCAAqC;YACrC,MAAM,aAAa,GAAG,sBAAsB,CAAC;gBAC3C,KAAK,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE;gBACrD,cAAc,EAAE,MAAM;aACvB,CAAC,CAAC;YACH,MAAM,WAAW,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;YACjD,WAAW,GAAG,iBAAiB,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YAC/C,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,QAAQ,EAAE,CAAC;YAEX,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;gBAC9C,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC9B,cAAc,EAAE,SAAS;aAC1B,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;YAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,CAAC,OAAO,CAAC,EAAE;gBAC/C,SAAS,EAAE;oBACT,MAAM,EAAE,OAAO;oBACf,KAAK,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,kBAAkB,EAAE;iBAClE;aACF,CAAC,CAAC;YACH,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CACjC,IAAA,mDAAsB,GAAmC,CAC1D,CAAC;YAEF,oGAAoG;YACpG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,IAAI,CAC3D,mBAAmB,CACpB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;YACzF,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;gBAC9C,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;gBAC1C,cAAc,EAAE,SAAS;aAC1B,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;YAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACjD,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CACjC,IAAA,mDAAsB,GAIlB,CACL,CAAC;YAEF,kDAAkD;YAClD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;YACrF,4CAA4C;YAC5C,MAAM,cAAc,GAAG,sBAAsB,CAAC;gBAC5C,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC9B,cAAc,EAAE,WAAW;aAC5B,CAAC,CAAC;YACH,MAAM,YAAY,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;YACnD,IAAI,WAAW,GAAG,iBAAiB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;YACpD,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAC3C,IAAA,mDAAsB,GAAmC,CAC1D,CAAC;YAEF,sCAAsC;YACtC,MAAM,cAAc,GAAG,sBAAsB,CAAC;gBAC5C,KAAK,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC5C,cAAc,EAAE,WAAW;aAC5B,CAAC,CAAC;YACH,MAAM,YAAY,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;YACnD,WAAW,GAAG,iBAAiB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;YAChD,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YACnE,QAAQ,EAAE,CAAC;YAEX,qCAAqC;YACrC,MAAM,aAAa,GAAG,sBAAsB,CAAC;gBAC3C,KAAK,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,eAAe,EAAE;gBACzD,cAAc,EAAE,WAAW;aAC5B,CAAC,CAAC;YACH,MAAM,WAAW,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;YACjD,WAAW,GAAG,iBAAiB,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YAC/C,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YACnE,QAAQ,EAAE,CAAC;YAEX,mCAAmC;YACnC,MAAM,aAAa,GAAG,sBAAsB,CAAC;gBAC3C,KAAK,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,eAAe,EAAE;gBACzD,cAAc,EAAE,MAAM;aACvB,CAAC,CAAC;YACH,MAAM,WAAW,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;YACjD,WAAW,GAAG,iBAAiB,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YAC/C,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YACnE,QAAQ,EAAE,CAAC;YAEX,sCAAsC;YACtC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YAOpE,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;gBAC9C,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE;gBAC7D,cAAc,EAAE,MAAM;aACvB,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;YAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACjD,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,mDAAsB,GAAa,CAAC,CAAC;YAEzE,+CAA+C;YAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;YACtD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;YAC5D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;gBAC9C,KAAK,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE;gBAC/B,cAAc,EAAE,MAAM;aACvB,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;YAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACjD,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,mDAAsB,GAAE,CAAC,CAAC;YAE9D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;YAClD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,WAAW,GAAG,iBAAiB,CAAC;gBACpC;oBACE,EAAE,EAAE,cAAc;oBAClB,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;oBAC1C,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC;aACF,CAAC,CAAC;YACH,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,mDAAsB,GAAE,CAAC,CAAC;YAE9D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,kBAAkB,CAAC,eAAe,CAAC;gBACjC,SAAS,EAAE,EAAE;gBACb,eAAe,EAAE,cAAc;aAChC,CAAC,CAAC;YAEH,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,mDAAsB,GAAE,CAAC,CAAC;YAE9D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,EAAE,CAAC;YAErE,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;gBAC9C,EAAE,EAAE,iBAAiB;gBACrB,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;gBACzB,cAAc,EAAE,WAAW;aAC5B,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAAC;YAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACjD,kBAAkB,CAAC,eAAe,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;YAEnE,yBAAyB,CAAC,eAAe,CAAC;gBACxC,WAAW,EAAE,iBAAiB;gBAC9B,QAAQ,EAAE,aAAa;gBACvB,SAAS,EAAE,cAAc;gBACzB,aAAa,EAAE,eAAe;aAC/B,CAAC,CAAC;YAEH,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAA,kBAAU,EAAC,GAAG,EAAE,CACnC,IAAA,mDAAsB,GAAqB,CAC5C,CAAC;YAEF,qBAAqB;YACrB,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAE1C,0DAA0D;YAC1D,yBAAyB,CAAC,eAAe,CAAC;gBACxC,WAAW,EAAE,kBAAkB;gBAC/B,QAAQ,EAAE,aAAa;gBACvB,SAAS,EAAE,cAAc;gBACzB,aAAa,EAAE,eAAe;aAC/B,CAAC,CAAC;YAEH,QAAQ,EAAE,CAAC;YAEX,0DAA0D;YAC1D,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAC/C,CAAC;YAEF,UAAU,CAAC,WAAW,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { renderHook } from \"@testing-library/react\";\nimport { useTamboV1StreamStatus } from \"./use-tambo-v1-stream-status\";\n\n// Mock the required hooks\njest.mock(\"../utils/component-renderer\", () => ({\n useV1ComponentContent: jest.fn(),\n}));\n\njest.mock(\"../providers/tambo-v1-stream-context\", () => ({\n useStreamState: jest.fn(),\n}));\n\n// Import the mocked functions\nimport { useV1ComponentContent } from \"../utils/component-renderer\";\nimport { useStreamState } from \"../providers/tambo-v1-stream-context\";\nimport type { StreamState, ThreadState } from \"../utils/event-accumulator\";\nimport type { V1ComponentContent, TamboV1Message } from \"../types/message\";\n\n// Mock window for SSR tests\nconst originalWindow = global.window;\n\n// Get the mocked functions\nconst mockUseV1ComponentContent = jest.mocked(useV1ComponentContent);\nconst mockUseStreamState = jest.mocked(useStreamState);\n\n/**\n * Helper to create a component content block\n */\nfunction createComponentContent(\n overrides: Partial<V1ComponentContent> = {},\n): V1ComponentContent {\n return {\n type: \"component\",\n id: \"test-component\",\n name: \"TestComponent\",\n props: {},\n streamingState: \"started\",\n ...overrides,\n };\n}\n\n/**\n * Helper to create a message with a component\n */\nfunction createMessage(\n componentContent: V1ComponentContent,\n overrides: Partial<TamboV1Message> = {},\n): TamboV1Message {\n return {\n id: \"test-message\",\n role: \"assistant\",\n content: [componentContent],\n createdAt: new Date().toISOString(),\n ...overrides,\n };\n}\n\n/**\n * Helper to create a thread state\n */\nfunction createThreadState(\n messages: TamboV1Message[],\n overrides: Partial<ThreadState> = {},\n): ThreadState {\n return {\n thread: {\n id: \"test-thread\",\n messages,\n status: \"idle\",\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n lastRunCancelled: false,\n },\n streaming: {\n status: \"idle\",\n },\n accumulatingToolArgs: new Map(),\n ...overrides,\n };\n}\n\n/**\n * Helper to create a stream state\n */\nfunction createStreamState(\n threadState: ThreadState,\n threadId = \"test-thread\",\n): StreamState {\n return {\n threadMap: {\n [threadId]: threadState,\n },\n currentThreadId: threadId,\n };\n}\n\ndescribe(\"useTamboV1StreamStatus\", () => {\n beforeEach(() => {\n // Restore window for client-side tests\n global.window = originalWindow;\n\n // Default mock implementations\n mockUseV1ComponentContent.mockReturnValue({\n componentId: \"test-component\",\n threadId: \"test-thread\",\n messageId: \"test-message\",\n componentName: \"TestComponent\",\n });\n\n const componentContent = createComponentContent({ props: {} });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n });\n\n afterEach(() => {\n jest.clearAllMocks();\n // Restore window after each test\n global.window = originalWindow;\n });\n\n describe(\"Initial State\", () => {\n it(\"should start with all flags as pending when component streaming is 'started' and no props\", () => {\n const componentContent = createComponentContent({\n props: { title: \"\", body: \"\" },\n streamingState: \"started\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() =>\n useTamboV1StreamStatus<{ title: string; body: string }>(),\n );\n\n expect(result.current.streamStatus).toEqual({\n isPending: true,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n streamError: undefined,\n });\n\n expect(result.current.propStatus.title).toEqual({\n isPending: true,\n isStreaming: false,\n isSuccess: false,\n error: undefined,\n });\n\n expect(result.current.propStatus.body).toEqual({\n isPending: true,\n isStreaming: false,\n isSuccess: false,\n error: undefined,\n });\n });\n });\n\n describe(\"Streaming State Transitions\", () => {\n it(\"should show isStreaming when component is streaming even before props receive content\", () => {\n // Component is streaming but props are still empty\n const componentContent = createComponentContent({\n props: { title: \"\", body: \"\" },\n streamingState: \"streaming\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() =>\n useTamboV1StreamStatus<{ title: string; body: string }>(),\n );\n\n // Global should be streaming even though no props have content yet\n expect(result.current.streamStatus.isStreaming).toBe(true);\n expect(result.current.streamStatus.isPending).toBe(false);\n\n // Individual props should still be pending\n expect(result.current.propStatus.title?.isPending).toBe(true);\n expect(result.current.propStatus.title?.isStreaming).toBe(false);\n });\n\n it(\"should show prop streaming when props receive content during streaming\", () => {\n const componentContent = createComponentContent({\n props: { title: \"Hello\", body: \"\" },\n streamingState: \"streaming\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() =>\n useTamboV1StreamStatus<{ title: string; body: string }>(),\n );\n\n // Title prop should be streaming since it has content\n expect(result.current.propStatus.title?.isStreaming).toBe(true);\n expect(result.current.propStatus.title?.isPending).toBe(false);\n\n // Body prop should still be pending since it has no content\n expect(result.current.propStatus.body?.isStreaming).toBe(false);\n expect(result.current.propStatus.body?.isPending).toBe(true);\n\n // Global should be streaming because at least one prop is streaming\n expect(result.current.streamStatus.isStreaming).toBe(true);\n });\n\n it(\"should transition through Init -> Streaming -> Success lifecycle\", () => {\n // Start with \"started\" (Init phase)\n const componentContent = createComponentContent({\n props: { title: \"\", body: \"\" },\n streamingState: \"started\",\n });\n const message = createMessage(componentContent);\n let threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result, rerender } = renderHook(() =>\n useTamboV1StreamStatus<{ title: string; body: string }>(),\n );\n\n // Phase 1: Init - isPending = true\n expect(result.current.streamStatus.isPending).toBe(true);\n expect(result.current.streamStatus.isStreaming).toBe(false);\n expect(result.current.streamStatus.isSuccess).toBe(false);\n\n // Phase 2: Streaming - move to \"streaming\" with content\n const streamingComponent = createComponentContent({\n props: { title: \"Hello World\", body: \"Some content\" },\n streamingState: \"streaming\",\n });\n const streamingMessage = createMessage(streamingComponent);\n threadState = createThreadState([streamingMessage]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n rerender();\n\n expect(result.current.streamStatus.isPending).toBe(false);\n expect(result.current.streamStatus.isStreaming).toBe(true);\n expect(result.current.streamStatus.isSuccess).toBe(false);\n\n // Phase 3: Complete - move to \"done\"\n const doneComponent = createComponentContent({\n props: { title: \"Hello World\", body: \"Some content\" },\n streamingState: \"done\",\n });\n const doneMessage = createMessage(doneComponent);\n threadState = createThreadState([doneMessage]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n rerender();\n\n expect(result.current.streamStatus.isPending).toBe(false);\n expect(result.current.streamStatus.isStreaming).toBe(false);\n expect(result.current.streamStatus.isSuccess).toBe(true);\n });\n });\n\n describe(\"Error Handling\", () => {\n it(\"should handle error state correctly\", () => {\n const componentContent = createComponentContent({\n props: { title: \"\", body: \"\" },\n streamingState: \"started\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message], {\n streaming: {\n status: \"error\",\n error: { message: \"Generation failed\", code: \"GENERATION_ERROR\" },\n },\n });\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() =>\n useTamboV1StreamStatus<{ title: string; body: string }>(),\n );\n\n // Error state: isPending=false (error overrides pending), isStreaming=false (error stops streaming)\n expect(result.current.streamStatus.isPending).toBe(false);\n expect(result.current.streamStatus.isStreaming).toBe(false);\n expect(result.current.streamStatus.isSuccess).toBe(false);\n expect(result.current.streamStatus.isError).toBe(true);\n expect(result.current.streamStatus.streamError?.message).toBe(\n \"Generation failed\",\n );\n });\n });\n\n describe(\"Derivation Rules\", () => {\n it(\"should derive isPending correctly (no streaming activity AND all props pending)\", () => {\n const componentContent = createComponentContent({\n props: { title: \"\", body: \"\", footer: \"\" },\n streamingState: \"started\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() =>\n useTamboV1StreamStatus<{\n title: string;\n body: string;\n footer: string;\n }>(),\n );\n\n // All props are pending and no streaming activity\n expect(result.current.streamStatus.isPending).toBe(true);\n expect(result.current.propStatus.title?.isPending).toBe(true);\n expect(result.current.propStatus.body?.isPending).toBe(true);\n expect(result.current.propStatus.footer?.isPending).toBe(true);\n });\n\n it(\"should derive isSuccess correctly (streaming done AND all props successful)\", () => {\n // Step 1: Start with streaming, props empty\n const startComponent = createComponentContent({\n props: { title: \"\", body: \"\" },\n streamingState: \"streaming\",\n });\n const startMessage = createMessage(startComponent);\n let threadState = createThreadState([startMessage]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result, rerender } = renderHook(() =>\n useTamboV1StreamStatus<{ title: string; body: string }>(),\n );\n\n // Step 2: Simulate streaming in title\n const titleComponent = createComponentContent({\n props: { title: \"Complete Title\", body: \"\" },\n streamingState: \"streaming\",\n });\n const titleMessage = createMessage(titleComponent);\n threadState = createThreadState([titleMessage]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n rerender();\n\n // Step 3: Simulate streaming in body\n const bodyComponent = createComponentContent({\n props: { title: \"Complete Title\", body: \"Complete Body\" },\n streamingState: \"streaming\",\n });\n const bodyMessage = createMessage(bodyComponent);\n threadState = createThreadState([bodyMessage]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n rerender();\n\n // Step 4: Component streaming done\n const doneComponent = createComponentContent({\n props: { title: \"Complete Title\", body: \"Complete Body\" },\n streamingState: \"done\",\n });\n const doneMessage = createMessage(doneComponent);\n threadState = createThreadState([doneMessage]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n rerender();\n\n // Now both props should be successful\n expect(result.current.propStatus.title?.isSuccess).toBe(true);\n expect(result.current.propStatus.body?.isSuccess).toBe(true);\n expect(result.current.streamStatus.isSuccess).toBe(true);\n });\n });\n\n describe(\"Type Safety\", () => {\n it(\"should provide strongly typed prop status based on generic\", () => {\n interface TestProps {\n title: string;\n description: string;\n count: number;\n }\n\n const componentContent = createComponentContent({\n props: { title: \"Test\", description: \"Test desc\", count: 42 },\n streamingState: \"done\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() => useTamboV1StreamStatus<TestProps>());\n\n // TypeScript should infer these keys correctly\n expect(result.current.propStatus.title).toBeDefined();\n expect(result.current.propStatus.description).toBeDefined();\n expect(result.current.propStatus.count).toBeDefined();\n });\n\n it(\"should work without generic type parameter\", () => {\n const componentContent = createComponentContent({\n props: { dynamicProp: \"value\" },\n streamingState: \"done\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() => useTamboV1StreamStatus());\n\n expect(result.current.streamStatus).toBeDefined();\n expect(result.current.propStatus).toBeDefined();\n });\n });\n\n describe(\"Edge Cases\", () => {\n it(\"should handle missing component gracefully\", () => {\n const threadState = createThreadState([\n {\n id: \"test-message\",\n role: \"assistant\",\n content: [{ type: \"text\", text: \"Hello\" }],\n createdAt: new Date().toISOString(),\n },\n ]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() => useTamboV1StreamStatus());\n\n expect(result.current.streamStatus.isPending).toBe(true);\n expect(result.current.propStatus).toEqual({});\n });\n\n it(\"should handle missing thread gracefully\", () => {\n mockUseStreamState.mockReturnValue({\n threadMap: {},\n currentThreadId: \"non-existent\",\n });\n\n const { result } = renderHook(() => useTamboV1StreamStatus());\n\n expect(result.current.streamStatus.isPending).toBe(true);\n expect(result.current.propStatus).toEqual({});\n });\n\n it(\"should error when component ID changes unexpectedly\", () => {\n const consoleSpy = jest.spyOn(console, \"error\").mockImplementation();\n\n const componentContent = createComponentContent({\n id: \"first-component\",\n props: { title: \"Title\" },\n streamingState: \"streaming\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n mockUseV1ComponentContent.mockReturnValue({\n componentId: \"first-component\",\n threadId: \"test-thread\",\n messageId: \"test-message\",\n componentName: \"TestComponent\",\n });\n\n const { rerender } = renderHook(() =>\n useTamboV1StreamStatus<{ title: string }>(),\n );\n\n // No error initially\n expect(consoleSpy).not.toHaveBeenCalled();\n\n // Change componentId (this should not happen in practice)\n mockUseV1ComponentContent.mockReturnValue({\n componentId: \"second-component\",\n threadId: \"test-thread\",\n messageId: \"test-message\",\n componentName: \"TestComponent\",\n });\n\n rerender();\n\n // Should log an error indicating incorrect provider usage\n expect(consoleSpy).toHaveBeenCalledWith(\n expect.stringContaining(\"componentId changed\"),\n );\n\n consoleSpy.mockRestore();\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-stream-status.test.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-stream-status.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { renderHook } from \"@testing-library/react\";\nimport { useTamboStreamStatus } from \"./use-tambo-v1-stream-status\";\n\n// Mock the required hooks\njest.mock(\"../utils/component-renderer\", () => ({\n useComponentContent: jest.fn(),\n}));\n\njest.mock(\"../providers/tambo-v1-stream-context\", () => ({\n useStreamState: jest.fn(),\n}));\n\n// Import the mocked functions\nimport { useComponentContent } from \"../utils/component-renderer\";\nimport { useStreamState } from \"../providers/tambo-v1-stream-context\";\nimport type { StreamState, ThreadState } from \"../utils/event-accumulator\";\nimport type {\n TamboComponentContent,\n TamboThreadMessage,\n} from \"../types/message\";\n\n// Mock window for SSR tests\nconst originalWindow = global.window;\n\n// Get the mocked functions\nconst mockUseTamboComponentContent = jest.mocked(useComponentContent);\nconst mockUseStreamState = jest.mocked(useStreamState);\n\n/**\n * Helper to create a component content block\n */\nfunction createComponentContent(\n overrides: Partial<TamboComponentContent> = {},\n): TamboComponentContent {\n return {\n type: \"component\",\n id: \"test-component\",\n name: \"TestComponent\",\n props: {},\n streamingState: \"started\",\n ...overrides,\n };\n}\n\n/**\n * Helper to create a message with a component\n */\nfunction createMessage(\n componentContent: TamboComponentContent,\n overrides: Partial<TamboThreadMessage> = {},\n): TamboThreadMessage {\n return {\n id: \"test-message\",\n role: \"assistant\",\n content: [componentContent],\n createdAt: new Date().toISOString(),\n ...overrides,\n };\n}\n\n/**\n * Helper to create a thread state\n */\nfunction createThreadState(\n messages: TamboThreadMessage[],\n overrides: Partial<ThreadState> = {},\n): ThreadState {\n return {\n thread: {\n id: \"test-thread\",\n messages,\n status: \"idle\",\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n lastRunCancelled: false,\n },\n streaming: {\n status: \"idle\",\n },\n accumulatingToolArgs: new Map(),\n ...overrides,\n };\n}\n\n/**\n * Helper to create a stream state\n */\nfunction createStreamState(\n threadState: ThreadState,\n threadId = \"test-thread\",\n): StreamState {\n return {\n threadMap: {\n [threadId]: threadState,\n },\n currentThreadId: threadId,\n };\n}\n\ndescribe(\"useTamboStreamStatus\", () => {\n beforeEach(() => {\n // Restore window for client-side tests\n global.window = originalWindow;\n\n // Default mock implementations\n mockUseTamboComponentContent.mockReturnValue({\n componentId: \"test-component\",\n threadId: \"test-thread\",\n messageId: \"test-message\",\n componentName: \"TestComponent\",\n });\n\n const componentContent = createComponentContent({ props: {} });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n });\n\n afterEach(() => {\n jest.clearAllMocks();\n // Restore window after each test\n global.window = originalWindow;\n });\n\n describe(\"Initial State\", () => {\n it(\"should start with all flags as pending when component streaming is 'started' and no props\", () => {\n const componentContent = createComponentContent({\n props: { title: \"\", body: \"\" },\n streamingState: \"started\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() =>\n useTamboStreamStatus<{ title: string; body: string }>(),\n );\n\n expect(result.current.streamStatus).toEqual({\n isPending: true,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n streamError: undefined,\n });\n\n expect(result.current.propStatus.title).toEqual({\n isPending: true,\n isStreaming: false,\n isSuccess: false,\n error: undefined,\n });\n\n expect(result.current.propStatus.body).toEqual({\n isPending: true,\n isStreaming: false,\n isSuccess: false,\n error: undefined,\n });\n });\n });\n\n describe(\"Streaming State Transitions\", () => {\n it(\"should show isStreaming when component is streaming even before props receive content\", () => {\n // Component is streaming but props are still empty\n const componentContent = createComponentContent({\n props: { title: \"\", body: \"\" },\n streamingState: \"streaming\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() =>\n useTamboStreamStatus<{ title: string; body: string }>(),\n );\n\n // Global should be streaming even though no props have content yet\n expect(result.current.streamStatus.isStreaming).toBe(true);\n expect(result.current.streamStatus.isPending).toBe(false);\n\n // Individual props should still be pending\n expect(result.current.propStatus.title?.isPending).toBe(true);\n expect(result.current.propStatus.title?.isStreaming).toBe(false);\n });\n\n it(\"should show prop streaming when props receive content during streaming\", () => {\n const componentContent = createComponentContent({\n props: { title: \"Hello\", body: \"\" },\n streamingState: \"streaming\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() =>\n useTamboStreamStatus<{ title: string; body: string }>(),\n );\n\n // Title prop should be streaming since it has content\n expect(result.current.propStatus.title?.isStreaming).toBe(true);\n expect(result.current.propStatus.title?.isPending).toBe(false);\n\n // Body prop should still be pending since it has no content\n expect(result.current.propStatus.body?.isStreaming).toBe(false);\n expect(result.current.propStatus.body?.isPending).toBe(true);\n\n // Global should be streaming because at least one prop is streaming\n expect(result.current.streamStatus.isStreaming).toBe(true);\n });\n\n it(\"should transition through Init -> Streaming -> Success lifecycle\", () => {\n // Start with \"started\" (Init phase)\n const componentContent = createComponentContent({\n props: { title: \"\", body: \"\" },\n streamingState: \"started\",\n });\n const message = createMessage(componentContent);\n let threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result, rerender } = renderHook(() =>\n useTamboStreamStatus<{ title: string; body: string }>(),\n );\n\n // Phase 1: Init - isPending = true\n expect(result.current.streamStatus.isPending).toBe(true);\n expect(result.current.streamStatus.isStreaming).toBe(false);\n expect(result.current.streamStatus.isSuccess).toBe(false);\n\n // Phase 2: Streaming - move to \"streaming\" with content\n const streamingComponent = createComponentContent({\n props: { title: \"Hello World\", body: \"Some content\" },\n streamingState: \"streaming\",\n });\n const streamingMessage = createMessage(streamingComponent);\n threadState = createThreadState([streamingMessage]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n rerender();\n\n expect(result.current.streamStatus.isPending).toBe(false);\n expect(result.current.streamStatus.isStreaming).toBe(true);\n expect(result.current.streamStatus.isSuccess).toBe(false);\n\n // Phase 3: Complete - move to \"done\"\n const doneComponent = createComponentContent({\n props: { title: \"Hello World\", body: \"Some content\" },\n streamingState: \"done\",\n });\n const doneMessage = createMessage(doneComponent);\n threadState = createThreadState([doneMessage]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n rerender();\n\n expect(result.current.streamStatus.isPending).toBe(false);\n expect(result.current.streamStatus.isStreaming).toBe(false);\n expect(result.current.streamStatus.isSuccess).toBe(true);\n });\n });\n\n describe(\"Error Handling\", () => {\n it(\"should handle error state correctly\", () => {\n const componentContent = createComponentContent({\n props: { title: \"\", body: \"\" },\n streamingState: \"started\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message], {\n streaming: {\n status: \"idle\",\n error: { message: \"Generation failed\", code: \"GENERATION_ERROR\" },\n },\n });\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() =>\n useTamboStreamStatus<{ title: string; body: string }>(),\n );\n\n // Error state: isPending=false (error overrides pending), isStreaming=false (error stops streaming)\n expect(result.current.streamStatus.isPending).toBe(false);\n expect(result.current.streamStatus.isStreaming).toBe(false);\n expect(result.current.streamStatus.isSuccess).toBe(false);\n expect(result.current.streamStatus.isError).toBe(true);\n expect(result.current.streamStatus.streamError?.message).toBe(\n \"Generation failed\",\n );\n });\n });\n\n describe(\"Derivation Rules\", () => {\n it(\"should derive isPending correctly (no streaming activity AND all props pending)\", () => {\n const componentContent = createComponentContent({\n props: { title: \"\", body: \"\", footer: \"\" },\n streamingState: \"started\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() =>\n useTamboStreamStatus<{\n title: string;\n body: string;\n footer: string;\n }>(),\n );\n\n // All props are pending and no streaming activity\n expect(result.current.streamStatus.isPending).toBe(true);\n expect(result.current.propStatus.title?.isPending).toBe(true);\n expect(result.current.propStatus.body?.isPending).toBe(true);\n expect(result.current.propStatus.footer?.isPending).toBe(true);\n });\n\n it(\"should derive isSuccess correctly (streaming done AND all props successful)\", () => {\n // Step 1: Start with streaming, props empty\n const startComponent = createComponentContent({\n props: { title: \"\", body: \"\" },\n streamingState: \"streaming\",\n });\n const startMessage = createMessage(startComponent);\n let threadState = createThreadState([startMessage]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result, rerender } = renderHook(() =>\n useTamboStreamStatus<{ title: string; body: string }>(),\n );\n\n // Step 2: Simulate streaming in title\n const titleComponent = createComponentContent({\n props: { title: \"Complete Title\", body: \"\" },\n streamingState: \"streaming\",\n });\n const titleMessage = createMessage(titleComponent);\n threadState = createThreadState([titleMessage]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n rerender();\n\n // Step 3: Simulate streaming in body\n const bodyComponent = createComponentContent({\n props: { title: \"Complete Title\", body: \"Complete Body\" },\n streamingState: \"streaming\",\n });\n const bodyMessage = createMessage(bodyComponent);\n threadState = createThreadState([bodyMessage]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n rerender();\n\n // Step 4: Component streaming done\n const doneComponent = createComponentContent({\n props: { title: \"Complete Title\", body: \"Complete Body\" },\n streamingState: \"done\",\n });\n const doneMessage = createMessage(doneComponent);\n threadState = createThreadState([doneMessage]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n rerender();\n\n // Now both props should be successful\n expect(result.current.propStatus.title?.isSuccess).toBe(true);\n expect(result.current.propStatus.body?.isSuccess).toBe(true);\n expect(result.current.streamStatus.isSuccess).toBe(true);\n });\n });\n\n describe(\"Type Safety\", () => {\n it(\"should provide strongly typed prop status based on generic\", () => {\n interface TestProps {\n title: string;\n description: string;\n count: number;\n }\n\n const componentContent = createComponentContent({\n props: { title: \"Test\", description: \"Test desc\", count: 42 },\n streamingState: \"done\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() => useTamboStreamStatus<TestProps>());\n\n // TypeScript should infer these keys correctly\n expect(result.current.propStatus.title).toBeDefined();\n expect(result.current.propStatus.description).toBeDefined();\n expect(result.current.propStatus.count).toBeDefined();\n });\n\n it(\"should work without generic type parameter\", () => {\n const componentContent = createComponentContent({\n props: { dynamicProp: \"value\" },\n streamingState: \"done\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() => useTamboStreamStatus());\n\n expect(result.current.streamStatus).toBeDefined();\n expect(result.current.propStatus).toBeDefined();\n });\n });\n\n describe(\"Edge Cases\", () => {\n it(\"should handle missing component gracefully\", () => {\n const threadState = createThreadState([\n {\n id: \"test-message\",\n role: \"assistant\",\n content: [{ type: \"text\", text: \"Hello\" }],\n createdAt: new Date().toISOString(),\n },\n ]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n const { result } = renderHook(() => useTamboStreamStatus());\n\n expect(result.current.streamStatus.isPending).toBe(true);\n expect(result.current.propStatus).toEqual({});\n });\n\n it(\"should handle missing thread gracefully\", () => {\n mockUseStreamState.mockReturnValue({\n threadMap: {},\n currentThreadId: \"non-existent\",\n });\n\n const { result } = renderHook(() => useTamboStreamStatus());\n\n expect(result.current.streamStatus.isPending).toBe(true);\n expect(result.current.propStatus).toEqual({});\n });\n\n it(\"should error when component ID changes unexpectedly\", () => {\n const consoleSpy = jest.spyOn(console, \"error\").mockImplementation();\n\n const componentContent = createComponentContent({\n id: \"first-component\",\n props: { title: \"Title\" },\n streamingState: \"streaming\",\n });\n const message = createMessage(componentContent);\n const threadState = createThreadState([message]);\n mockUseStreamState.mockReturnValue(createStreamState(threadState));\n\n mockUseTamboComponentContent.mockReturnValue({\n componentId: \"first-component\",\n threadId: \"test-thread\",\n messageId: \"test-message\",\n componentName: \"TestComponent\",\n });\n\n const { rerender } = renderHook(() =>\n useTamboStreamStatus<{ title: string }>(),\n );\n\n // No error initially\n expect(consoleSpy).not.toHaveBeenCalled();\n\n // Change componentId (this should not happen in practice)\n mockUseTamboComponentContent.mockReturnValue({\n componentId: \"second-component\",\n threadId: \"test-thread\",\n messageId: \"test-message\",\n componentName: \"TestComponent\",\n });\n\n rerender();\n\n // Should log an error indicating incorrect provider usage\n expect(consoleSpy).toHaveBeenCalledWith(\n expect.stringContaining(\"componentId changed\"),\n );\n\n consoleSpy.mockRestore();\n });\n });\n});\n"]}
|
|
@@ -6,9 +6,9 @@ import type { Suggestion } from "@tambo-ai/typescript-sdk/resources/beta/threads
|
|
|
6
6
|
*/
|
|
7
7
|
type SuggestionsQueryResponse = SuggestionListResponse | SuggestionCreateResponse;
|
|
8
8
|
/**
|
|
9
|
-
* Configuration options for the
|
|
9
|
+
* Configuration options for the useTamboSuggestions hook
|
|
10
10
|
*/
|
|
11
|
-
export interface
|
|
11
|
+
export interface UseTamboSuggestionsOptions {
|
|
12
12
|
/** Maximum number of suggestions to generate (1-10, default 3) */
|
|
13
13
|
maxSuggestions?: number;
|
|
14
14
|
/**
|
|
@@ -32,9 +32,9 @@ export interface AcceptSuggestionOptions {
|
|
|
32
32
|
shouldSubmit?: boolean;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* Return type for
|
|
35
|
+
* Return type for useTamboSuggestions hook
|
|
36
36
|
*/
|
|
37
|
-
export interface
|
|
37
|
+
export interface UseTamboSuggestionsReturn {
|
|
38
38
|
/**
|
|
39
39
|
* The raw response data from the suggestions query.
|
|
40
40
|
* Use this for direct access to the API response shape.
|
|
@@ -74,7 +74,7 @@ export interface UseTamboV1SuggestionsReturn {
|
|
|
74
74
|
selectedSuggestionId: string | null;
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
|
-
* Hook for managing AI-powered suggestions in a
|
|
77
|
+
* Hook for managing AI-powered suggestions in a thread.
|
|
78
78
|
*
|
|
79
79
|
* Provides functionality to:
|
|
80
80
|
* - Automatically generate suggestions when an assistant message arrives
|
|
@@ -90,7 +90,7 @@ export interface UseTamboV1SuggestionsReturn {
|
|
|
90
90
|
* accept,
|
|
91
91
|
* isLoading,
|
|
92
92
|
* selectedSuggestionId,
|
|
93
|
-
* } =
|
|
93
|
+
* } = useTamboSuggestions();
|
|
94
94
|
*
|
|
95
95
|
* if (isLoading) return <Spinner />;
|
|
96
96
|
*
|
|
@@ -110,6 +110,6 @@ export interface UseTamboV1SuggestionsReturn {
|
|
|
110
110
|
* }
|
|
111
111
|
* ```
|
|
112
112
|
*/
|
|
113
|
-
export declare function
|
|
113
|
+
export declare function useTamboSuggestions(options?: UseTamboSuggestionsOptions): UseTamboSuggestionsReturn;
|
|
114
114
|
export {};
|
|
115
115
|
//# sourceMappingURL=use-tambo-v1-suggestions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-suggestions.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EACV,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,wDAAwD,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6DAA6D,CAAC;AAY9F;;GAEG;AACH,KAAK,wBAAwB,GACzB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-suggestions.d.ts","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EACV,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,wDAAwD,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6DAA6D,CAAC;AAY9F;;GAEG;AACH,KAAK,wBAAwB,GACzB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,YAAY,CAAC,EAAE,IAAI,CACjB,eAAe,CAAC,wBAAwB,CAAC,EACzC,UAAU,GAAG,SAAS,GAAG,SAAS,CACnC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,+BAA+B;IAC/B,UAAU,EAAE,UAAU,CAAC;IACvB,sFAAsF;IACtF,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IAKxC;;;OAGG;IACH,IAAI,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAE3C,mFAAmF;IACnF,WAAW,EAAE,UAAU,EAAE,CAAC;IAM1B,6DAA6D;IAC7D,SAAS,EAAE,OAAO,CAAC;IAEnB,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IAEnB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;IAEjB,6CAA6C;IAC7C,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEpB,8EAA8E;IAC9E,UAAU,EAAE,OAAO,CAAC;IAMpB;;;OAGG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAAC;IAE9D,iEAAiE;IACjE,YAAY,EAAE,OAAO,CAAC;IAEtB,gDAAgD;IAChD,aAAa,EAAE,KAAK,GAAG,IAAI,CAAC;IAM5B;;;OAGG;IACH,MAAM,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5D,oDAAoD;IACpD,WAAW,EAAE,OAAO,CAAC;IAErB,gDAAgD;IAChD,WAAW,EAAE,KAAK,GAAG,IAAI,CAAC;IAM1B,8CAA8C;IAC9C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,0BAA+B,GACvC,yBAAyB,CA4M3B"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
"use client";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.
|
|
4
|
+
exports.useTamboSuggestions = useTamboSuggestions;
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* useTamboSuggestions - Suggestions Hook
|
|
7
7
|
*
|
|
8
8
|
* Manages AI-powered suggestions for thread messages.
|
|
9
|
-
* Uses the
|
|
9
|
+
* Uses the API endpoints for listing and creating suggestions.
|
|
10
10
|
*/
|
|
11
11
|
const react_1 = require("react");
|
|
12
12
|
const tambo_client_provider_1 = require("../../providers/tambo-client-provider");
|
|
@@ -17,7 +17,7 @@ const use_tambo_v1_1 = require("./use-tambo-v1");
|
|
|
17
17
|
const use_tambo_v1_thread_input_1 = require("./use-tambo-v1-thread-input");
|
|
18
18
|
const registry_conversion_1 = require("../utils/registry-conversion");
|
|
19
19
|
/**
|
|
20
|
-
* Hook for managing AI-powered suggestions in a
|
|
20
|
+
* Hook for managing AI-powered suggestions in a thread.
|
|
21
21
|
*
|
|
22
22
|
* Provides functionality to:
|
|
23
23
|
* - Automatically generate suggestions when an assistant message arrives
|
|
@@ -33,7 +33,7 @@ const registry_conversion_1 = require("../utils/registry-conversion");
|
|
|
33
33
|
* accept,
|
|
34
34
|
* isLoading,
|
|
35
35
|
* selectedSuggestionId,
|
|
36
|
-
* } =
|
|
36
|
+
* } = useTamboSuggestions();
|
|
37
37
|
*
|
|
38
38
|
* if (isLoading) return <Spinner />;
|
|
39
39
|
*
|
|
@@ -53,14 +53,14 @@ const registry_conversion_1 = require("../utils/registry-conversion");
|
|
|
53
53
|
* }
|
|
54
54
|
* ```
|
|
55
55
|
*/
|
|
56
|
-
function
|
|
56
|
+
function useTamboSuggestions(options = {}) {
|
|
57
57
|
const { maxSuggestions = 3, autoGenerate = true, queryOptions } = options;
|
|
58
58
|
const client = (0, tambo_client_provider_1.useTamboClient)();
|
|
59
|
-
const { userKey } = (0, tambo_v1_provider_1.
|
|
59
|
+
const { userKey } = (0, tambo_v1_provider_1.useTamboConfig)();
|
|
60
60
|
const { componentList } = (0, tambo_registry_provider_1.useTamboRegistry)();
|
|
61
61
|
const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
|
|
62
|
-
const { messages, isIdle, currentThreadId } = (0, use_tambo_v1_1.
|
|
63
|
-
const { setValue: setInputValue, submit } = (0, use_tambo_v1_thread_input_1.
|
|
62
|
+
const { messages, isIdle, currentThreadId } = (0, use_tambo_v1_1.useTambo)();
|
|
63
|
+
const { setValue: setInputValue, submit } = (0, use_tambo_v1_thread_input_1.useTamboThreadInput)();
|
|
64
64
|
const [selectedSuggestionId, setSelectedSuggestionId] = (0, react_1.useState)(null);
|
|
65
65
|
// Get the latest message info
|
|
66
66
|
const latestMessage = messages[messages.length - 1];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-tambo-v1-suggestions.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * useTamboV1Suggestions - Suggestions Hook for v1 API\n *\n * Manages AI-powered suggestions for thread messages.\n * Uses the v1 API endpoints for listing and creating suggestions.\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { UseQueryOptions } from \"@tanstack/react-query\";\nimport type {\n SuggestionCreateResponse,\n SuggestionListResponse,\n} from \"@tambo-ai/typescript-sdk/resources/threads/suggestions\";\nimport type { Suggestion } from \"@tambo-ai/typescript-sdk/resources/beta/threads/suggestions\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboQuery, useTamboMutation } from \"../../hooks/react-query-hooks\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboV1Config } from \"../providers/tambo-v1-provider\";\nimport { useTamboV1 } from \"./use-tambo-v1\";\nimport { useTamboV1ThreadInput } from \"./use-tambo-v1-thread-input\";\nimport { toAvailableComponents } from \"../utils/registry-conversion\";\n\n/**\n * Response type for suggestions queries (union of list and create responses)\n */\ntype SuggestionsQueryResponse =\n | SuggestionListResponse\n | SuggestionCreateResponse;\n\n/**\n * Configuration options for the useTamboV1Suggestions hook\n */\nexport interface UseTamboV1SuggestionsOptions {\n /** Maximum number of suggestions to generate (1-10, default 3) */\n maxSuggestions?: number;\n /**\n * Whether to automatically generate suggestions when the latest message is from the assistant.\n * Default: true\n */\n autoGenerate?: boolean;\n /**\n * Additional React Query options for the suggestions query.\n * Allows customizing caching, refetching behavior, etc.\n */\n queryOptions?: Omit<\n UseQueryOptions<SuggestionsQueryResponse>,\n \"queryKey\" | \"queryFn\" | \"enabled\"\n >;\n}\n\n/**\n * Options for accepting a suggestion\n */\nexport interface AcceptSuggestionOptions {\n /** The suggestion to accept */\n suggestion: Suggestion;\n /** Whether to automatically submit the suggestion after accepting (default: false) */\n shouldSubmit?: boolean;\n}\n\n/**\n * Return type for useTamboV1Suggestions hook\n */\nexport interface UseTamboV1SuggestionsReturn {\n // ---------------------------------------------------------------------------\n // Data (mirrors react-query patterns)\n // ---------------------------------------------------------------------------\n\n /**\n * The raw response data from the suggestions query.\n * Use this for direct access to the API response shape.\n */\n data: SuggestionsQueryResponse | undefined;\n\n /** List of available suggestions for the current message (convenience accessor) */\n suggestions: Suggestion[];\n\n // ---------------------------------------------------------------------------\n // Query state (matches react-query UseQueryResult)\n // ---------------------------------------------------------------------------\n\n /** Whether the suggestions query is loading (first fetch) */\n isLoading: boolean;\n\n /** Whether suggestions have been successfully loaded */\n isSuccess: boolean;\n\n /** Whether there was an error loading suggestions */\n isError: boolean;\n\n /** Error from loading suggestions, if any */\n error: Error | null;\n\n /** Whether the query is currently fetching (includes background refetches) */\n isFetching: boolean;\n\n // ---------------------------------------------------------------------------\n // Generate mutation (for manual suggestion generation)\n // ---------------------------------------------------------------------------\n\n /**\n * Manually generate new suggestions for the current message.\n * Use this when autoGenerate is false or to refresh suggestions.\n */\n generate: () => Promise<SuggestionCreateResponse | undefined>;\n\n /** Whether suggestions are being generated (mutation pending) */\n isGenerating: boolean;\n\n /** Error from generating suggestions, if any */\n generateError: Error | null;\n\n // ---------------------------------------------------------------------------\n // Accept mutation (for applying a suggestion)\n // ---------------------------------------------------------------------------\n\n /**\n * Accept and apply a suggestion.\n * Sets the suggestion text as input value, optionally submitting it.\n */\n accept: (options: AcceptSuggestionOptions) => Promise<void>;\n\n /** Whether accepting a suggestion is in progress */\n isAccepting: boolean;\n\n /** Error from accepting a suggestion, if any */\n acceptError: Error | null;\n\n // ---------------------------------------------------------------------------\n // UI state\n // ---------------------------------------------------------------------------\n\n /** ID of the currently selected suggestion */\n selectedSuggestionId: string | null;\n}\n\n/**\n * Hook for managing AI-powered suggestions in a v1 thread.\n *\n * Provides functionality to:\n * - Automatically generate suggestions when an assistant message arrives\n * - Manually generate suggestions on demand\n * - Accept suggestions by setting them as input or auto-submitting\n * @param options - Configuration options\n * @returns Suggestions state and control functions\n * @example\n * ```tsx\n * function SuggestionsPanel() {\n * const {\n * suggestions,\n * accept,\n * isLoading,\n * selectedSuggestionId,\n * } = useTamboV1Suggestions();\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * {suggestions.map((suggestion) => (\n * <button\n * key={suggestion.id}\n * onClick={() => accept({ suggestion })}\n * className={selectedSuggestionId === suggestion.id ? 'selected' : ''}\n * >\n * {suggestion.title}\n * </button>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useTamboV1Suggestions(\n options: UseTamboV1SuggestionsOptions = {},\n): UseTamboV1SuggestionsReturn {\n const { maxSuggestions = 3, autoGenerate = true, queryOptions } = options;\n\n const client = useTamboClient();\n const { userKey } = useTamboV1Config();\n const { componentList } = useTamboRegistry();\n const queryClient = useTamboQueryClient();\n\n const { messages, isIdle, currentThreadId } = useTamboV1();\n const { setValue: setInputValue, submit } = useTamboV1ThreadInput();\n\n const [selectedSuggestionId, setSelectedSuggestionId] = useState<\n string | null\n >(null);\n\n // Get the latest message info\n const latestMessage = messages[messages.length - 1];\n const isLatestFromAssistant = latestMessage?.role === \"assistant\";\n const latestMessageId = latestMessage?.id;\n\n // Reset selected suggestion when the message changes\n useEffect(() => {\n setSelectedSuggestionId(null);\n }, [latestMessageId]);\n\n // Determine if we should fetch/generate suggestions\n const shouldFetchSuggestions =\n currentThreadId &&\n latestMessageId &&\n isLatestFromAssistant &&\n isIdle &&\n autoGenerate;\n\n const suggestionsQueryKey = [\n \"v1-suggestions\",\n currentThreadId ?? null,\n latestMessageId ?? null,\n ] as const;\n\n // Query to list existing suggestions\n const suggestionsQuery = useTamboQuery({\n queryKey: suggestionsQueryKey,\n queryFn: async (): Promise<SuggestionsQueryResponse> => {\n if (!shouldFetchSuggestions || !latestMessageId || !currentThreadId) {\n return { suggestions: [], hasMore: false };\n }\n\n return await client.threads.suggestions.list(latestMessageId, {\n threadId: currentThreadId,\n userKey,\n });\n },\n ...queryOptions,\n enabled: Boolean(shouldFetchSuggestions),\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n retry: false,\n });\n\n // Mutation to manually generate suggestions\n const generateMutation = useTamboMutation({\n mutationFn: async () => {\n if (!currentThreadId || !latestMessageId || !isLatestFromAssistant) {\n return undefined;\n }\n\n const availableComponents = toAvailableComponents(componentList);\n\n return await client.threads.suggestions.create(latestMessageId, {\n threadId: currentThreadId,\n maxSuggestions,\n availableComponents,\n userKey,\n });\n },\n onSuccess: (data) => {\n if (data && currentThreadId && latestMessageId) {\n // Update the query cache with new suggestions\n queryClient.setQueryData(suggestionsQueryKey, data);\n }\n },\n });\n\n const lastAutoGenerateMessageIdRef = useRef<string | null>(null);\n\n useEffect(() => {\n lastAutoGenerateMessageIdRef.current = null;\n }, [latestMessageId]);\n\n const listSuggestionsCount = suggestionsQuery.data?.suggestions.length ?? 0;\n const generateMutate = generateMutation.mutate;\n const isGenerating = generateMutation.isPending;\n const isListError = suggestionsQuery.isError;\n const isListSuccess = suggestionsQuery.isSuccess;\n\n useEffect(() => {\n if (!shouldFetchSuggestions || !latestMessageId) {\n return;\n }\n\n if (listSuggestionsCount > 0) {\n return;\n }\n\n const shouldAutoGenerate =\n (isListSuccess && listSuggestionsCount === 0) || isListError;\n\n if (!shouldAutoGenerate) {\n return;\n }\n\n if (isGenerating) {\n return;\n }\n\n if (lastAutoGenerateMessageIdRef.current === latestMessageId) {\n return;\n }\n\n lastAutoGenerateMessageIdRef.current = latestMessageId;\n generateMutate();\n }, [\n generateMutate,\n isGenerating,\n isListError,\n isListSuccess,\n latestMessageId,\n listSuggestionsCount,\n shouldFetchSuggestions,\n ]);\n\n // Mutation to accept a suggestion\n const acceptMutation = useTamboMutation({\n mutationFn: async ({\n suggestion,\n shouldSubmit = false,\n }: AcceptSuggestionOptions) => {\n const text = suggestion.detailedSuggestion?.trim();\n if (!text) {\n throw new Error(\"Suggestion has no content\");\n }\n\n if (shouldSubmit) {\n // Set value and submit\n setInputValue(text);\n await submit();\n } else {\n // Just set the input value\n setInputValue(text);\n }\n\n setSelectedSuggestionId(suggestion.id);\n },\n });\n\n // Generate callback\n const generateMutateAsync = generateMutation.mutateAsync;\n const generate = useCallback(async () => {\n return await generateMutateAsync();\n }, [generateMutateAsync]);\n\n // Accept callback\n const accept = useCallback(\n async (acceptOptions: AcceptSuggestionOptions) => {\n await acceptMutation.mutateAsync(acceptOptions);\n },\n [acceptMutation],\n );\n\n // Get suggestions from query or mutation result\n const queryData = suggestionsQuery.data;\n const mutationData = generateMutation.data;\n\n // Use mutation data if available (more recent), otherwise query data\n const currentData = mutationData ?? queryData;\n const suggestions = isLatestFromAssistant\n ? (currentData?.suggestions ?? [])\n : [];\n\n return {\n // Data\n data: currentData,\n suggestions,\n\n // Query state (matches react-query patterns)\n isLoading: suggestionsQuery.isLoading,\n isSuccess: suggestionsQuery.isSuccess,\n isError: suggestionsQuery.isError,\n error: suggestionsQuery.error,\n isFetching: suggestionsQuery.isFetching,\n\n // Generate mutation\n generate,\n isGenerating: generateMutation.isPending,\n generateError: generateMutation.error,\n\n // Accept mutation\n accept,\n isAccepting: acceptMutation.isPending,\n acceptError: acceptMutation.error,\n\n // UI state\n selectedSuggestionId,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-tambo-v1-suggestions.js","sourceRoot":"","sources":["../../../src/v1/hooks/use-tambo-v1-suggestions.ts"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n/**\n * useTamboSuggestions - Suggestions Hook\n *\n * Manages AI-powered suggestions for thread messages.\n * Uses the API endpoints for listing and creating suggestions.\n */\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { UseQueryOptions } from \"@tanstack/react-query\";\nimport type {\n SuggestionCreateResponse,\n SuggestionListResponse,\n} from \"@tambo-ai/typescript-sdk/resources/threads/suggestions\";\nimport type { Suggestion } from \"@tambo-ai/typescript-sdk/resources/beta/threads/suggestions\";\nimport {\n useTamboClient,\n useTamboQueryClient,\n} from \"../../providers/tambo-client-provider\";\nimport { useTamboQuery, useTamboMutation } from \"../../hooks/react-query-hooks\";\nimport { useTamboRegistry } from \"../../providers/tambo-registry-provider\";\nimport { useTamboConfig } from \"../providers/tambo-v1-provider\";\nimport { useTambo } from \"./use-tambo-v1\";\nimport { useTamboThreadInput } from \"./use-tambo-v1-thread-input\";\nimport { toAvailableComponents } from \"../utils/registry-conversion\";\n\n/**\n * Response type for suggestions queries (union of list and create responses)\n */\ntype SuggestionsQueryResponse =\n | SuggestionListResponse\n | SuggestionCreateResponse;\n\n/**\n * Configuration options for the useTamboSuggestions hook\n */\nexport interface UseTamboSuggestionsOptions {\n /** Maximum number of suggestions to generate (1-10, default 3) */\n maxSuggestions?: number;\n /**\n * Whether to automatically generate suggestions when the latest message is from the assistant.\n * Default: true\n */\n autoGenerate?: boolean;\n /**\n * Additional React Query options for the suggestions query.\n * Allows customizing caching, refetching behavior, etc.\n */\n queryOptions?: Omit<\n UseQueryOptions<SuggestionsQueryResponse>,\n \"queryKey\" | \"queryFn\" | \"enabled\"\n >;\n}\n\n/**\n * Options for accepting a suggestion\n */\nexport interface AcceptSuggestionOptions {\n /** The suggestion to accept */\n suggestion: Suggestion;\n /** Whether to automatically submit the suggestion after accepting (default: false) */\n shouldSubmit?: boolean;\n}\n\n/**\n * Return type for useTamboSuggestions hook\n */\nexport interface UseTamboSuggestionsReturn {\n // ---------------------------------------------------------------------------\n // Data (mirrors react-query patterns)\n // ---------------------------------------------------------------------------\n\n /**\n * The raw response data from the suggestions query.\n * Use this for direct access to the API response shape.\n */\n data: SuggestionsQueryResponse | undefined;\n\n /** List of available suggestions for the current message (convenience accessor) */\n suggestions: Suggestion[];\n\n // ---------------------------------------------------------------------------\n // Query state (matches react-query UseQueryResult)\n // ---------------------------------------------------------------------------\n\n /** Whether the suggestions query is loading (first fetch) */\n isLoading: boolean;\n\n /** Whether suggestions have been successfully loaded */\n isSuccess: boolean;\n\n /** Whether there was an error loading suggestions */\n isError: boolean;\n\n /** Error from loading suggestions, if any */\n error: Error | null;\n\n /** Whether the query is currently fetching (includes background refetches) */\n isFetching: boolean;\n\n // ---------------------------------------------------------------------------\n // Generate mutation (for manual suggestion generation)\n // ---------------------------------------------------------------------------\n\n /**\n * Manually generate new suggestions for the current message.\n * Use this when autoGenerate is false or to refresh suggestions.\n */\n generate: () => Promise<SuggestionCreateResponse | undefined>;\n\n /** Whether suggestions are being generated (mutation pending) */\n isGenerating: boolean;\n\n /** Error from generating suggestions, if any */\n generateError: Error | null;\n\n // ---------------------------------------------------------------------------\n // Accept mutation (for applying a suggestion)\n // ---------------------------------------------------------------------------\n\n /**\n * Accept and apply a suggestion.\n * Sets the suggestion text as input value, optionally submitting it.\n */\n accept: (options: AcceptSuggestionOptions) => Promise<void>;\n\n /** Whether accepting a suggestion is in progress */\n isAccepting: boolean;\n\n /** Error from accepting a suggestion, if any */\n acceptError: Error | null;\n\n // ---------------------------------------------------------------------------\n // UI state\n // ---------------------------------------------------------------------------\n\n /** ID of the currently selected suggestion */\n selectedSuggestionId: string | null;\n}\n\n/**\n * Hook for managing AI-powered suggestions in a thread.\n *\n * Provides functionality to:\n * - Automatically generate suggestions when an assistant message arrives\n * - Manually generate suggestions on demand\n * - Accept suggestions by setting them as input or auto-submitting\n * @param options - Configuration options\n * @returns Suggestions state and control functions\n * @example\n * ```tsx\n * function SuggestionsPanel() {\n * const {\n * suggestions,\n * accept,\n * isLoading,\n * selectedSuggestionId,\n * } = useTamboSuggestions();\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <div>\n * {suggestions.map((suggestion) => (\n * <button\n * key={suggestion.id}\n * onClick={() => accept({ suggestion })}\n * className={selectedSuggestionId === suggestion.id ? 'selected' : ''}\n * >\n * {suggestion.title}\n * </button>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function useTamboSuggestions(\n options: UseTamboSuggestionsOptions = {},\n): UseTamboSuggestionsReturn {\n const { maxSuggestions = 3, autoGenerate = true, queryOptions } = options;\n\n const client = useTamboClient();\n const { userKey } = useTamboConfig();\n const { componentList } = useTamboRegistry();\n const queryClient = useTamboQueryClient();\n\n const { messages, isIdle, currentThreadId } = useTambo();\n const { setValue: setInputValue, submit } = useTamboThreadInput();\n\n const [selectedSuggestionId, setSelectedSuggestionId] = useState<\n string | null\n >(null);\n\n // Get the latest message info\n const latestMessage = messages[messages.length - 1];\n const isLatestFromAssistant = latestMessage?.role === \"assistant\";\n const latestMessageId = latestMessage?.id;\n\n // Reset selected suggestion when the message changes\n useEffect(() => {\n setSelectedSuggestionId(null);\n }, [latestMessageId]);\n\n // Determine if we should fetch/generate suggestions\n const shouldFetchSuggestions =\n currentThreadId &&\n latestMessageId &&\n isLatestFromAssistant &&\n isIdle &&\n autoGenerate;\n\n const suggestionsQueryKey = [\n \"v1-suggestions\",\n currentThreadId ?? null,\n latestMessageId ?? null,\n ] as const;\n\n // Query to list existing suggestions\n const suggestionsQuery = useTamboQuery({\n queryKey: suggestionsQueryKey,\n queryFn: async (): Promise<SuggestionsQueryResponse> => {\n if (!shouldFetchSuggestions || !latestMessageId || !currentThreadId) {\n return { suggestions: [], hasMore: false };\n }\n\n return await client.threads.suggestions.list(latestMessageId, {\n threadId: currentThreadId,\n userKey,\n });\n },\n ...queryOptions,\n enabled: Boolean(shouldFetchSuggestions),\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n retry: false,\n });\n\n // Mutation to manually generate suggestions\n const generateMutation = useTamboMutation({\n mutationFn: async () => {\n if (!currentThreadId || !latestMessageId || !isLatestFromAssistant) {\n return undefined;\n }\n\n const availableComponents = toAvailableComponents(componentList);\n\n return await client.threads.suggestions.create(latestMessageId, {\n threadId: currentThreadId,\n maxSuggestions,\n availableComponents,\n userKey,\n });\n },\n onSuccess: (data) => {\n if (data && currentThreadId && latestMessageId) {\n // Update the query cache with new suggestions\n queryClient.setQueryData(suggestionsQueryKey, data);\n }\n },\n });\n\n const lastAutoGenerateMessageIdRef = useRef<string | null>(null);\n\n useEffect(() => {\n lastAutoGenerateMessageIdRef.current = null;\n }, [latestMessageId]);\n\n const listSuggestionsCount = suggestionsQuery.data?.suggestions.length ?? 0;\n const generateMutate = generateMutation.mutate;\n const isGenerating = generateMutation.isPending;\n const isListError = suggestionsQuery.isError;\n const isListSuccess = suggestionsQuery.isSuccess;\n\n useEffect(() => {\n if (!shouldFetchSuggestions || !latestMessageId) {\n return;\n }\n\n if (listSuggestionsCount > 0) {\n return;\n }\n\n const shouldAutoGenerate =\n (isListSuccess && listSuggestionsCount === 0) || isListError;\n\n if (!shouldAutoGenerate) {\n return;\n }\n\n if (isGenerating) {\n return;\n }\n\n if (lastAutoGenerateMessageIdRef.current === latestMessageId) {\n return;\n }\n\n lastAutoGenerateMessageIdRef.current = latestMessageId;\n generateMutate();\n }, [\n generateMutate,\n isGenerating,\n isListError,\n isListSuccess,\n latestMessageId,\n listSuggestionsCount,\n shouldFetchSuggestions,\n ]);\n\n // Mutation to accept a suggestion\n const acceptMutation = useTamboMutation({\n mutationFn: async ({\n suggestion,\n shouldSubmit = false,\n }: AcceptSuggestionOptions) => {\n const text = suggestion.detailedSuggestion?.trim();\n if (!text) {\n throw new Error(\"Suggestion has no content\");\n }\n\n if (shouldSubmit) {\n // Set value and submit\n setInputValue(text);\n await submit();\n } else {\n // Just set the input value\n setInputValue(text);\n }\n\n setSelectedSuggestionId(suggestion.id);\n },\n });\n\n // Generate callback\n const generateMutateAsync = generateMutation.mutateAsync;\n const generate = useCallback(async () => {\n return await generateMutateAsync();\n }, [generateMutateAsync]);\n\n // Accept callback\n const accept = useCallback(\n async (acceptOptions: AcceptSuggestionOptions) => {\n await acceptMutation.mutateAsync(acceptOptions);\n },\n [acceptMutation],\n );\n\n // Get suggestions from query or mutation result\n const queryData = suggestionsQuery.data;\n const mutationData = generateMutation.data;\n\n // Use mutation data if available (more recent), otherwise query data\n const currentData = mutationData ?? queryData;\n const suggestions = isLatestFromAssistant\n ? (currentData?.suggestions ?? [])\n : [];\n\n return {\n // Data\n data: currentData,\n suggestions,\n\n // Query state (matches react-query patterns)\n isLoading: suggestionsQuery.isLoading,\n isSuccess: suggestionsQuery.isSuccess,\n isError: suggestionsQuery.isError,\n error: suggestionsQuery.error,\n isFetching: suggestionsQuery.isFetching,\n\n // Generate mutation\n generate,\n isGenerating: generateMutation.isPending,\n generateError: generateMutation.error,\n\n // Accept mutation\n accept,\n isAccepting: acceptMutation.isPending,\n acceptError: acceptMutation.error,\n\n // UI state\n selectedSuggestionId,\n };\n}\n"]}
|