@tambo-ai/react 0.73.0 → 0.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -12
- package/dist/hooks/use-component-state.d.ts +1 -1
- package/dist/hooks/use-component-state.js.map +1 -1
- package/dist/hooks/use-streaming-props.d.ts +1 -1
- package/dist/hooks/use-streaming-props.js +1 -1
- package/dist/hooks/use-streaming-props.js.map +1 -1
- package/dist/hooks/use-tambo-stream-status.d.ts +1 -1
- package/dist/hooks/use-tambo-stream-status.js +1 -1
- package/dist/hooks/use-tambo-stream-status.js.map +1 -1
- package/dist/mcp/mcp-hooks.d.ts +4 -0
- package/dist/mcp/mcp-hooks.d.ts.map +1 -1
- package/dist/mcp/mcp-hooks.js +4 -0
- package/dist/mcp/mcp-hooks.js.map +1 -1
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js +3 -3
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.js +2 -2
- package/dist/providers/tambo-interactable-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.test.js +3 -3
- package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
- package/dist/providers/tambo-provider.d.ts +3 -0
- package/dist/providers/tambo-provider.d.ts.map +1 -1
- package/dist/providers/tambo-provider.js +3 -0
- package/dist/providers/tambo-provider.js.map +1 -1
- package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-input-provider.js +1 -0
- package/dist/providers/tambo-thread-input-provider.js.map +1 -1
- package/dist/util/resource-content-resolver.d.ts.map +1 -1
- package/dist/util/resource-content-resolver.js +2 -0
- package/dist/util/resource-content-resolver.js.map +1 -1
- package/dist/v1/__tests__/v1-interactables.test.d.ts +2 -0
- package/dist/v1/__tests__/v1-interactables.test.d.ts.map +1 -0
- package/dist/v1/__tests__/v1-interactables.test.js +135 -0
- package/dist/v1/__tests__/v1-interactables.test.js.map +1 -0
- package/dist/v1/components/v1-component-renderer.d.ts +48 -0
- package/dist/v1/components/v1-component-renderer.d.ts.map +1 -0
- package/dist/v1/components/v1-component-renderer.js +137 -0
- package/dist/v1/components/v1-component-renderer.js.map +1 -0
- package/dist/v1/components/v1-component-renderer.test.d.ts +2 -0
- package/dist/v1/components/v1-component-renderer.test.d.ts.map +1 -0
- package/dist/v1/components/v1-component-renderer.test.js +270 -0
- package/dist/v1/components/v1-component-renderer.test.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.js +2 -25
- package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js +2 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-messages.test.js +25 -1
- package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +18 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.js +204 -17
- package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js +261 -7
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts +90 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.js +179 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.d.ts +2 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js +371 -0
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts +78 -54
- package/dist/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.js +153 -87
- package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js +213 -134
- package/dist/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +148 -13
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts +8 -21
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.js +11 -10
- package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +37 -2
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.d.ts +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.js +2 -7
- package/dist/v1/hooks/use-tambo-v1-thread.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread.test.js +2 -0
- package/dist/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.d.ts +12 -28
- package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.js +164 -31
- package/dist/v1/hooks/use-tambo-v1.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.test.js +891 -18
- package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/dist/v1/index.d.ts +7 -1
- package/dist/v1/index.d.ts.map +1 -1
- package/dist/v1/index.js +18 -1
- package/dist/v1/index.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts +16 -6
- package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.js +14 -19
- package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.test.js +34 -20
- package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.d.ts +3 -3
- package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.js +60 -12
- package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.test.js +49 -20
- package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.js +2 -0
- package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.test.js +7 -6
- package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +1 -6
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.js +14 -12
- package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/dist/v1/types/event.d.ts +9 -1
- package/dist/v1/types/event.d.ts.map +1 -1
- package/dist/v1/types/event.js.map +1 -1
- package/dist/v1/types/event.test.js +5 -1
- package/dist/v1/types/event.test.js.map +1 -1
- package/dist/v1/types/message.d.ts +65 -7
- package/dist/v1/types/message.d.ts.map +1 -1
- package/dist/v1/types/message.js.map +1 -1
- package/dist/v1/types/thread.d.ts +4 -0
- package/dist/v1/types/thread.d.ts.map +1 -1
- package/dist/v1/types/thread.js.map +1 -1
- package/dist/v1/utils/event-accumulator.d.ts +40 -4
- package/dist/v1/utils/event-accumulator.d.ts.map +1 -1
- package/dist/v1/utils/event-accumulator.js +444 -35
- package/dist/v1/utils/event-accumulator.js.map +1 -1
- package/dist/v1/utils/event-accumulator.test.js +1041 -28
- package/dist/v1/utils/event-accumulator.test.js.map +1 -1
- package/dist/v1/utils/registry-conversion.d.ts +9 -9
- package/dist/v1/utils/registry-conversion.d.ts.map +1 -1
- package/dist/v1/utils/registry-conversion.js +10 -11
- package/dist/v1/utils/registry-conversion.js.map +1 -1
- package/dist/v1/utils/registry-conversion.test.js +39 -11
- package/dist/v1/utils/registry-conversion.test.js.map +1 -1
- package/dist/v1/utils/thread-utils.d.ts +16 -0
- package/dist/v1/utils/thread-utils.d.ts.map +1 -0
- package/dist/v1/utils/thread-utils.js +34 -0
- package/dist/v1/utils/thread-utils.js.map +1 -0
- package/dist/v1/utils/tool-executor.d.ts.map +1 -1
- package/dist/v1/utils/tool-executor.js +2 -0
- package/dist/v1/utils/tool-executor.js.map +1 -1
- package/dist/v1/utils/tool-executor.test.js +5 -0
- package/dist/v1/utils/tool-executor.test.js.map +1 -1
- package/esm/context-helpers/context-helpers-provider.test.js +2 -2
- package/esm/context-helpers/context-helpers.test.js +1 -1
- package/esm/context-helpers/current-interactables-context-helper.d.ts +1 -1
- package/esm/context-helpers/current-page-context-helper.d.ts +1 -1
- package/esm/context-helpers/current-time-context-helper.d.ts +1 -1
- package/esm/context-helpers/index.d.ts +4 -4
- package/esm/context-helpers/index.js +4 -4
- package/esm/hoc/with-tambo-interactable.d.ts +1 -1
- package/esm/hoc/with-tambo-interactable.js +2 -2
- package/esm/hoc/with-tambo-interactable.test.js +3 -3
- package/esm/hooks/index.d.ts +8 -8
- package/esm/hooks/index.js +8 -8
- package/esm/hooks/react-query-hooks.js +1 -1
- package/esm/hooks/use-component-state.d.ts +1 -1
- package/esm/hooks/use-component-state.js +3 -3
- package/esm/hooks/use-component-state.js.map +1 -1
- package/esm/hooks/use-component-state.test.js +5 -5
- package/esm/hooks/use-current-message.d.ts +1 -1
- package/esm/hooks/use-current-message.test.js +1 -1
- package/esm/hooks/use-message-images.test.js +1 -1
- package/esm/hooks/use-streaming-props.d.ts +1 -1
- package/esm/hooks/use-streaming-props.js +1 -1
- package/esm/hooks/use-streaming-props.js.map +1 -1
- package/esm/hooks/use-suggestions.d.ts +2 -2
- package/esm/hooks/use-suggestions.js +10 -10
- package/esm/hooks/use-suggestions.test.js +7 -7
- package/esm/hooks/use-tambo-stream-status.d.ts +1 -1
- package/esm/hooks/use-tambo-stream-status.js +4 -4
- package/esm/hooks/use-tambo-stream-status.js.map +1 -1
- package/esm/hooks/use-tambo-stream-status.test.js +4 -4
- package/esm/hooks/use-tambo-threads.js +3 -3
- package/esm/hooks/use-tambo-threads.test.js +3 -3
- package/esm/hooks/use-tambo-voice.js +2 -2
- package/esm/hooks/use-tambo-voice.test.js +3 -3
- package/esm/index.d.ts +22 -22
- package/esm/index.js +15 -15
- package/esm/mcp/elicitation.d.ts +1 -1
- package/esm/mcp/elicitation.test.js +1 -1
- package/esm/mcp/index.d.ts +7 -7
- package/esm/mcp/index.js +3 -3
- package/esm/mcp/mcp-client.d.ts +1 -1
- package/esm/mcp/mcp-client.js +1 -1
- package/esm/mcp/mcp-client.test.js +1 -1
- package/esm/mcp/mcp-hooks.d.ts +5 -1
- package/esm/mcp/mcp-hooks.d.ts.map +1 -1
- package/esm/mcp/mcp-hooks.js +8 -4
- package/esm/mcp/mcp-hooks.js.map +1 -1
- package/esm/mcp/mcp-hooks.test.js +6 -6
- package/esm/mcp/tambo-mcp-provider.d.ts +4 -4
- package/esm/mcp/tambo-mcp-provider.js +7 -7
- package/esm/mcp/tambo-mcp-provider.test.js +5 -5
- package/esm/mcp/use-mcp-servers.test.js +4 -4
- package/esm/model/generate-component-response.d.ts +1 -1
- package/esm/model/tambo-interactable.d.ts +1 -1
- package/esm/model/tambo-thread.d.ts +1 -1
- package/esm/providers/__tests__/thread-input-resource-resolution.test.js +3 -3
- package/esm/providers/hooks/use-tambo-session-token.test.js +1 -1
- package/esm/providers/index.d.ts +12 -12
- package/esm/providers/index.js +10 -10
- package/esm/providers/tambo-client-provider.js +1 -1
- package/esm/providers/tambo-client-provider.test.js +2 -2
- package/esm/providers/tambo-component-provider.d.ts +1 -1
- package/esm/providers/tambo-component-provider.js +2 -2
- package/esm/providers/tambo-context-attachment-provider.js +1 -1
- package/esm/providers/tambo-context-attachment-provider.test.js +2 -2
- package/esm/providers/tambo-context-helpers-provider.d.ts +1 -1
- package/esm/providers/tambo-context-helpers-provider.js +1 -1
- package/esm/providers/tambo-context-helpers-provider.test.js +2 -2
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js +4 -4
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +5 -5
- package/esm/providers/tambo-interactable-provider.js +6 -6
- package/esm/providers/tambo-interactable-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.test.js +4 -4
- package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
- package/esm/providers/tambo-interactables-additional-context-edge-cases.test.js +4 -4
- package/esm/providers/tambo-interactables-additional-context.test.js +4 -4
- package/esm/providers/tambo-mcp-token-provider.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/index.d.ts +8 -8
- package/esm/providers/tambo-prop-stream-provider/index.js +9 -9
- package/esm/providers/tambo-prop-stream-provider/pending.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/pending.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/provider.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/provider.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/streaming.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/streaming.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/success.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider/success.js +2 -2
- package/esm/providers/tambo-prop-stream-provider/types.d.ts +1 -1
- package/esm/providers/tambo-prop-stream-provider.test.js +4 -4
- package/esm/providers/tambo-provider.d.ts +10 -7
- package/esm/providers/tambo-provider.d.ts.map +1 -1
- package/esm/providers/tambo-provider.js +13 -10
- package/esm/providers/tambo-provider.js.map +1 -1
- package/esm/providers/tambo-registry-provider.d.ts +3 -3
- package/esm/providers/tambo-registry-provider.js +3 -3
- package/esm/providers/tambo-registry-provider.test.js +2 -2
- package/esm/providers/tambo-registry-schema-compat.test.js +2 -2
- package/esm/providers/tambo-stubs.d.ts +4 -4
- package/esm/providers/tambo-stubs.js +9 -9
- package/esm/providers/tambo-stubs.test.js +2 -2
- package/esm/providers/tambo-thread-input-provider.d.ts +2 -2
- package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-input-provider.js +11 -10
- package/esm/providers/tambo-thread-input-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider-initial-messages.test.js +6 -6
- package/esm/providers/tambo-thread-provider.d.ts +2 -2
- package/esm/providers/tambo-thread-provider.js +8 -8
- package/esm/providers/tambo-thread-provider.test.js +7 -7
- package/esm/schema/index.d.ts +4 -4
- package/esm/schema/index.js +4 -4
- package/esm/schema/json-schema.test.js +1 -1
- package/esm/schema/schema.d.ts +1 -1
- package/esm/schema/schema.js +2 -2
- package/esm/schema/schema.test.js +3 -3
- package/esm/schema/standard-schema.test.js +1 -1
- package/esm/schema/validate.js +2 -2
- package/esm/schema/validate.test.js +1 -1
- package/esm/testing/tools.d.ts +3 -3
- package/esm/testing/tools.js +2 -2
- package/esm/util/content-parts.test.js +1 -1
- package/esm/util/generate-component.d.ts +2 -2
- package/esm/util/generate-component.js +4 -4
- package/esm/util/generate-component.test.js +2 -2
- package/esm/util/is-promise.test.js +1 -1
- package/esm/util/mcp-server-utils.d.ts +1 -1
- package/esm/util/mcp-server-utils.js +1 -1
- package/esm/util/mcp-server-utils.test.js +2 -2
- package/esm/util/message-builder.d.ts +1 -1
- package/esm/util/message-builder.test.js +1 -1
- package/esm/util/query-utils.test.js +1 -1
- package/esm/util/registry-validators.d.ts +1 -1
- package/esm/util/registry-validators.js +2 -2
- package/esm/util/registry-validators.test.js +1 -1
- package/esm/util/registry.d.ts +1 -1
- package/esm/util/registry.js +1 -1
- package/esm/util/registry.test.js +2 -2
- package/esm/util/resource-content-resolver.d.ts +2 -2
- package/esm/util/resource-content-resolver.d.ts.map +1 -1
- package/esm/util/resource-content-resolver.js +3 -1
- package/esm/util/resource-content-resolver.js.map +1 -1
- package/esm/util/resource-content-resolver.test.js +3 -3
- package/esm/util/resource-validators.d.ts +1 -1
- package/esm/util/resource-validators.test.js +1 -1
- package/esm/util/tool-caller.d.ts +1 -1
- package/esm/util/tool-caller.js +1 -1
- package/esm/util/validate-component-name.test.js +1 -1
- package/esm/v1/__tests__/v1-interactables.test.d.ts +2 -0
- package/esm/v1/__tests__/v1-interactables.test.d.ts.map +1 -0
- package/esm/v1/__tests__/v1-interactables.test.js +130 -0
- package/esm/v1/__tests__/v1-interactables.test.js.map +1 -0
- package/esm/v1/components/v1-component-renderer.d.ts +48 -0
- package/esm/v1/components/v1-component-renderer.d.ts.map +1 -0
- package/esm/v1/components/v1-component-renderer.js +100 -0
- package/esm/v1/components/v1-component-renderer.js.map +1 -0
- package/esm/v1/components/v1-component-renderer.test.d.ts +2 -0
- package/esm/v1/components/v1-component-renderer.test.d.ts.map +1 -0
- package/esm/v1/components/v1-component-renderer.test.js +265 -0
- package/esm/v1/components/v1-component-renderer.test.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-component-state.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.js +4 -27
- package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js +6 -5
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.test.js +27 -3
- package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +20 -2
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.js +213 -26
- package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js +266 -12
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts +90 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.js +176 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.d.ts +2 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js +369 -0
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts +78 -54
- package/esm/v1/hooks/use-tambo-v1-suggestions.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.js +157 -91
- package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js +218 -139
- package/esm/v1/hooks/use-tambo-v1-suggestions.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +151 -16
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts +8 -21
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.js +12 -11
- package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +39 -4
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.js +3 -8
- package/esm/v1/hooks/use-tambo-v1-thread.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread.test.js +4 -2
- package/esm/v1/hooks/use-tambo-v1-thread.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.d.ts +15 -31
- package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.js +134 -34
- package/esm/v1/hooks/use-tambo-v1.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.test.js +862 -19
- package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/esm/v1/index.d.ts +28 -22
- package/esm/v1/index.d.ts.map +1 -1
- package/esm/v1/index.js +30 -18
- package/esm/v1/index.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts +21 -11
- package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.js +20 -25
- package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.test.js +40 -26
- package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.d.ts +4 -4
- package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.js +62 -14
- package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.test.js +50 -21
- package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts +3 -3
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.js +7 -5
- package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.test.js +12 -11
- package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +3 -8
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.js +18 -16
- package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/esm/v1/types/event.d.ts +9 -1
- package/esm/v1/types/event.d.ts.map +1 -1
- package/esm/v1/types/event.js.map +1 -1
- package/esm/v1/types/event.test.js +6 -2
- package/esm/v1/types/event.test.js.map +1 -1
- package/esm/v1/types/message.d.ts +65 -7
- package/esm/v1/types/message.d.ts.map +1 -1
- package/esm/v1/types/message.js.map +1 -1
- package/esm/v1/types/thread.d.ts +5 -1
- package/esm/v1/types/thread.d.ts.map +1 -1
- package/esm/v1/types/thread.js.map +1 -1
- package/esm/v1/utils/component-renderer.test.js +1 -1
- package/esm/v1/utils/event-accumulator.d.ts +41 -5
- package/esm/v1/utils/event-accumulator.d.ts.map +1 -1
- package/esm/v1/utils/event-accumulator.js +444 -36
- package/esm/v1/utils/event-accumulator.js.map +1 -1
- package/esm/v1/utils/event-accumulator.test.js +1042 -29
- package/esm/v1/utils/event-accumulator.test.js.map +1 -1
- package/esm/v1/utils/json-patch.test.js +1 -1
- package/esm/v1/utils/registry-conversion.d.ts +9 -9
- package/esm/v1/utils/registry-conversion.d.ts.map +1 -1
- package/esm/v1/utils/registry-conversion.js +11 -12
- package/esm/v1/utils/registry-conversion.js.map +1 -1
- package/esm/v1/utils/registry-conversion.test.js +40 -12
- package/esm/v1/utils/registry-conversion.test.js.map +1 -1
- package/esm/v1/utils/stream-handler.test.js +1 -1
- package/esm/v1/utils/thread-utils.d.ts +16 -0
- package/esm/v1/utils/thread-utils.d.ts.map +1 -0
- package/esm/v1/utils/thread-utils.js +31 -0
- package/esm/v1/utils/thread-utils.js.map +1 -0
- package/esm/v1/utils/tool-call-tracker.d.ts +1 -1
- package/esm/v1/utils/tool-executor.d.ts +1 -1
- package/esm/v1/utils/tool-executor.d.ts.map +1 -1
- package/esm/v1/utils/tool-executor.js +2 -0
- package/esm/v1/utils/tool-executor.js.map +1 -1
- package/esm/v1/utils/tool-executor.test.js +6 -1
- package/esm/v1/utils/tool-executor.test.js.map +1 -1
- package/package.json +11 -10
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
* Used with useReducer to accumulate events into thread state.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.UnreachableCaseError = void 0;
|
|
9
|
+
exports.PLACEHOLDER_THREAD_ID = exports.UnreachableCaseError = void 0;
|
|
10
10
|
exports.createInitialThreadState = createInitialThreadState;
|
|
11
|
+
exports.isPlaceholderThreadId = isPlaceholderThreadId;
|
|
11
12
|
exports.createInitialState = createInitialState;
|
|
12
13
|
exports.streamReducer = streamReducer;
|
|
13
14
|
const core_1 = require("@ag-ui/core");
|
|
14
15
|
const event_1 = require("../types/event");
|
|
16
|
+
const partial_json_1 = require("partial-json");
|
|
15
17
|
const json_patch_1 = require("./json-patch");
|
|
16
18
|
/**
|
|
17
19
|
* Error thrown when an unreachable case is reached in a switch statement.
|
|
@@ -44,19 +46,36 @@ function createInitialThreadState(threadId) {
|
|
|
44
46
|
status: "idle",
|
|
45
47
|
createdAt: now,
|
|
46
48
|
updatedAt: now,
|
|
49
|
+
lastRunCancelled: false,
|
|
47
50
|
},
|
|
48
51
|
streaming: initialStreamingState,
|
|
49
52
|
accumulatingToolArgs: new Map(),
|
|
50
53
|
};
|
|
51
54
|
}
|
|
52
55
|
/**
|
|
53
|
-
*
|
|
56
|
+
* Placeholder thread ID used for new threads before they get a real ID from the server.
|
|
57
|
+
* This allows optimistic UI updates (showing user messages immediately) before the
|
|
58
|
+
* server responds with the actual thread ID.
|
|
59
|
+
*/
|
|
60
|
+
exports.PLACEHOLDER_THREAD_ID = "placeholder";
|
|
61
|
+
/**
|
|
62
|
+
* Check if a thread ID is a placeholder (not a real API thread ID).
|
|
63
|
+
* @param threadId - Thread ID to check
|
|
64
|
+
* @returns True if this is a placeholder thread ID
|
|
65
|
+
*/
|
|
66
|
+
function isPlaceholderThreadId(threadId) {
|
|
67
|
+
return threadId === exports.PLACEHOLDER_THREAD_ID;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Create initial stream state with placeholder thread.
|
|
54
71
|
* @returns Initial stream state
|
|
55
72
|
*/
|
|
56
73
|
function createInitialState() {
|
|
57
74
|
return {
|
|
58
|
-
threadMap: {
|
|
59
|
-
|
|
75
|
+
threadMap: {
|
|
76
|
+
[exports.PLACEHOLDER_THREAD_ID]: createInitialThreadState(exports.PLACEHOLDER_THREAD_ID),
|
|
77
|
+
},
|
|
78
|
+
currentThreadId: exports.PLACEHOLDER_THREAD_ID,
|
|
60
79
|
};
|
|
61
80
|
}
|
|
62
81
|
/**
|
|
@@ -200,28 +219,85 @@ function streamReducer(state, action) {
|
|
|
200
219
|
currentThreadId: threadId,
|
|
201
220
|
};
|
|
202
221
|
}
|
|
222
|
+
case "LOAD_THREAD_MESSAGES": {
|
|
223
|
+
return handleLoadThreadMessages(state, action);
|
|
224
|
+
}
|
|
225
|
+
case "UPDATE_THREAD_TITLE": {
|
|
226
|
+
const threadState = state.threadMap[action.threadId];
|
|
227
|
+
if (!threadState) {
|
|
228
|
+
return state;
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
...state,
|
|
232
|
+
threadMap: {
|
|
233
|
+
...state.threadMap,
|
|
234
|
+
[action.threadId]: {
|
|
235
|
+
...threadState,
|
|
236
|
+
thread: {
|
|
237
|
+
...threadState.thread,
|
|
238
|
+
title: action.title,
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
}
|
|
203
244
|
case "EVENT":
|
|
204
245
|
// Fall through to event handling below
|
|
205
246
|
break;
|
|
206
247
|
}
|
|
207
248
|
// Handle EVENT action
|
|
208
249
|
const { event, threadId } = action;
|
|
250
|
+
const effectiveThreadId = event.type === core_1.EventType.RUN_STARTED ? event.threadId : threadId;
|
|
209
251
|
// Get the current thread state, auto-initializing if needed
|
|
210
252
|
// Auto-initialization handles the case where events arrive before explicit thread init
|
|
211
253
|
// (e.g., when creating a new thread and RUN_STARTED is the first event)
|
|
212
|
-
let threadState = state.threadMap[
|
|
254
|
+
let threadState = state.threadMap[effectiveThreadId];
|
|
213
255
|
let updatedState = state;
|
|
214
256
|
if (!threadState) {
|
|
215
257
|
// Auto-initialize the thread to avoid dropping events
|
|
216
|
-
threadState = createInitialThreadState(
|
|
258
|
+
threadState = createInitialThreadState(effectiveThreadId);
|
|
217
259
|
updatedState = {
|
|
218
260
|
...state,
|
|
219
261
|
threadMap: {
|
|
220
262
|
...state.threadMap,
|
|
221
|
-
[
|
|
263
|
+
[effectiveThreadId]: threadState,
|
|
222
264
|
},
|
|
223
265
|
};
|
|
224
266
|
}
|
|
267
|
+
// Handle placeholder thread migration for RUN_STARTED events
|
|
268
|
+
// When a new thread is created, messages may have been added to the placeholder thread
|
|
269
|
+
// for immediate UI feedback. Now that we have the real threadId, migrate those messages.
|
|
270
|
+
if (event.type === core_1.EventType.RUN_STARTED &&
|
|
271
|
+
effectiveThreadId !== exports.PLACEHOLDER_THREAD_ID) {
|
|
272
|
+
const placeholderState = updatedState.threadMap[exports.PLACEHOLDER_THREAD_ID];
|
|
273
|
+
if (placeholderState?.thread.messages.length) {
|
|
274
|
+
// Prepend placeholder thread messages to the real thread
|
|
275
|
+
threadState = {
|
|
276
|
+
...threadState,
|
|
277
|
+
thread: {
|
|
278
|
+
...threadState.thread,
|
|
279
|
+
messages: [
|
|
280
|
+
...placeholderState.thread.messages,
|
|
281
|
+
...threadState.thread.messages,
|
|
282
|
+
],
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
// Reset placeholder thread to empty state
|
|
286
|
+
const resetPlaceholder = createInitialThreadState(exports.PLACEHOLDER_THREAD_ID);
|
|
287
|
+
updatedState = {
|
|
288
|
+
...updatedState,
|
|
289
|
+
threadMap: {
|
|
290
|
+
...updatedState.threadMap,
|
|
291
|
+
[exports.PLACEHOLDER_THREAD_ID]: resetPlaceholder,
|
|
292
|
+
[effectiveThreadId]: threadState,
|
|
293
|
+
},
|
|
294
|
+
// Only switch selection if the user is currently on the placeholder thread
|
|
295
|
+
currentThreadId: isPlaceholderThreadId(updatedState.currentThreadId)
|
|
296
|
+
? effectiveThreadId
|
|
297
|
+
: updatedState.currentThreadId,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
225
301
|
// Process the event for this specific thread
|
|
226
302
|
let updatedThreadState;
|
|
227
303
|
// Switch on event.type - AGUIEvent is a discriminated union so TypeScript
|
|
@@ -260,11 +336,17 @@ function streamReducer(state, action) {
|
|
|
260
336
|
case core_1.EventType.CUSTOM:
|
|
261
337
|
updatedThreadState = handleCustomEvent(threadState, event);
|
|
262
338
|
break;
|
|
263
|
-
// Unsupported AG-UI event types - may be added in future phases
|
|
264
|
-
case core_1.EventType.TEXT_MESSAGE_CHUNK:
|
|
265
339
|
case core_1.EventType.THINKING_TEXT_MESSAGE_START:
|
|
340
|
+
updatedThreadState = handleThinkingTextMessageStart(threadState, event);
|
|
341
|
+
break;
|
|
266
342
|
case core_1.EventType.THINKING_TEXT_MESSAGE_CONTENT:
|
|
343
|
+
updatedThreadState = handleThinkingTextMessageContent(threadState, event);
|
|
344
|
+
break;
|
|
267
345
|
case core_1.EventType.THINKING_TEXT_MESSAGE_END:
|
|
346
|
+
updatedThreadState = handleThinkingTextMessageEnd(threadState, event);
|
|
347
|
+
break;
|
|
348
|
+
// Unsupported AG-UI event types - may be added in future phases
|
|
349
|
+
case core_1.EventType.TEXT_MESSAGE_CHUNK:
|
|
268
350
|
case core_1.EventType.TOOL_CALL_CHUNK:
|
|
269
351
|
case core_1.EventType.THINKING_START:
|
|
270
352
|
case core_1.EventType.THINKING_END:
|
|
@@ -292,7 +374,7 @@ function streamReducer(state, action) {
|
|
|
292
374
|
...updatedState,
|
|
293
375
|
threadMap: {
|
|
294
376
|
...updatedState.threadMap,
|
|
295
|
-
[
|
|
377
|
+
[effectiveThreadId]: updatedThreadState,
|
|
296
378
|
},
|
|
297
379
|
};
|
|
298
380
|
}
|
|
@@ -309,6 +391,8 @@ function handleRunStarted(threadState, event) {
|
|
|
309
391
|
...threadState.thread,
|
|
310
392
|
status: "streaming",
|
|
311
393
|
updatedAt: new Date().toISOString(),
|
|
394
|
+
// Reset lastRunCancelled when a new run starts
|
|
395
|
+
lastRunCancelled: false,
|
|
312
396
|
},
|
|
313
397
|
streaming: {
|
|
314
398
|
status: "streaming",
|
|
@@ -339,39 +423,78 @@ function handleRunFinished(threadState, _event) {
|
|
|
339
423
|
}
|
|
340
424
|
/**
|
|
341
425
|
* Handle RUN_ERROR event.
|
|
426
|
+
* Sets lastRunCancelled if the error code is "CANCELLED".
|
|
342
427
|
* @param threadState - Current thread state
|
|
343
428
|
* @param event - Run error event
|
|
344
429
|
* @returns Updated thread state
|
|
345
430
|
*/
|
|
346
431
|
function handleRunError(threadState, event) {
|
|
432
|
+
const isCancelled = event.code === "CANCELLED";
|
|
347
433
|
return {
|
|
348
434
|
...threadState,
|
|
349
435
|
thread: {
|
|
350
436
|
...threadState.thread,
|
|
351
|
-
status
|
|
437
|
+
// Use "idle" status for cancelled runs (not a real error from user perspective)
|
|
438
|
+
status: isCancelled ? "idle" : "error",
|
|
352
439
|
updatedAt: new Date().toISOString(),
|
|
440
|
+
lastRunCancelled: isCancelled,
|
|
353
441
|
},
|
|
354
442
|
streaming: {
|
|
355
443
|
...threadState.streaming,
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
444
|
+
// Use "idle" status for cancelled runs so UI shows as not streaming
|
|
445
|
+
status: isCancelled ? "idle" : "error",
|
|
446
|
+
error: isCancelled
|
|
447
|
+
? undefined
|
|
448
|
+
: {
|
|
449
|
+
message: event.message,
|
|
450
|
+
code: event.code,
|
|
451
|
+
},
|
|
361
452
|
},
|
|
362
453
|
};
|
|
363
454
|
}
|
|
364
455
|
/**
|
|
365
456
|
* Handle TEXT_MESSAGE_START event.
|
|
366
|
-
* Creates a new message
|
|
457
|
+
* Creates a new message or reuses an ephemeral reasoning message.
|
|
367
458
|
* @param threadState - Current thread state
|
|
368
459
|
* @param event - Text message start event
|
|
369
460
|
* @returns Updated thread state
|
|
370
461
|
*/
|
|
371
462
|
function handleTextMessageStart(threadState, event) {
|
|
463
|
+
const isAssistant = event.role !== "user";
|
|
464
|
+
const messages = threadState.thread.messages;
|
|
465
|
+
// For assistant messages, check if there's an ephemeral message with reasoning
|
|
466
|
+
// that we should merge into instead of creating a new message.
|
|
467
|
+
if (isAssistant) {
|
|
468
|
+
const ephemeralIndex = messages.findIndex((m) => m.role === "assistant" &&
|
|
469
|
+
m.id.startsWith("ephemeral_") &&
|
|
470
|
+
m.reasoning &&
|
|
471
|
+
m.reasoning.length > 0);
|
|
472
|
+
if (ephemeralIndex !== -1) {
|
|
473
|
+
// Update the ephemeral message with the real ID
|
|
474
|
+
const ephemeralMessage = messages[ephemeralIndex];
|
|
475
|
+
const updatedMessages = [...messages];
|
|
476
|
+
updatedMessages[ephemeralIndex] = {
|
|
477
|
+
...ephemeralMessage,
|
|
478
|
+
id: event.messageId,
|
|
479
|
+
};
|
|
480
|
+
return {
|
|
481
|
+
...threadState,
|
|
482
|
+
thread: {
|
|
483
|
+
...threadState.thread,
|
|
484
|
+
messages: updatedMessages,
|
|
485
|
+
updatedAt: new Date().toISOString(),
|
|
486
|
+
},
|
|
487
|
+
streaming: {
|
|
488
|
+
...threadState.streaming,
|
|
489
|
+
messageId: event.messageId,
|
|
490
|
+
},
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
// No ephemeral message to reuse - create a new message
|
|
372
495
|
const newMessage = {
|
|
373
496
|
id: event.messageId,
|
|
374
|
-
role:
|
|
497
|
+
role: isAssistant ? "assistant" : "user",
|
|
375
498
|
content: [],
|
|
376
499
|
createdAt: new Date().toISOString(),
|
|
377
500
|
};
|
|
@@ -379,7 +502,7 @@ function handleTextMessageStart(threadState, event) {
|
|
|
379
502
|
...threadState,
|
|
380
503
|
thread: {
|
|
381
504
|
...threadState.thread,
|
|
382
|
-
messages: [...
|
|
505
|
+
messages: [...messages, newMessage],
|
|
383
506
|
updatedAt: new Date().toISOString(),
|
|
384
507
|
},
|
|
385
508
|
streaming: {
|
|
@@ -452,6 +575,7 @@ function handleTextMessageEnd(threadState, event) {
|
|
|
452
575
|
/**
|
|
453
576
|
* Handle TOOL_CALL_START event.
|
|
454
577
|
* Adds a tool use content block to the current message.
|
|
578
|
+
* If no message exists, creates a synthetic assistant message to hold the tool call.
|
|
455
579
|
* @param threadState - Current thread state
|
|
456
580
|
* @param event - Tool call start event
|
|
457
581
|
* @returns Updated thread state
|
|
@@ -463,18 +587,35 @@ function handleToolCallStart(threadState, event) {
|
|
|
463
587
|
const messageIndex = messageId
|
|
464
588
|
? messages.findIndex((m) => m.id === messageId)
|
|
465
589
|
: messages.length - 1;
|
|
466
|
-
if (messageIndex === -1) {
|
|
467
|
-
throw new Error(messageId
|
|
468
|
-
? `Message ${messageId} not found for TOOL_CALL_START event`
|
|
469
|
-
: `No messages exist for TOOL_CALL_START event`);
|
|
470
|
-
}
|
|
471
|
-
const message = messages[messageIndex];
|
|
472
590
|
const newContent = {
|
|
473
591
|
type: "tool_use",
|
|
474
592
|
id: event.toolCallId,
|
|
475
593
|
name: event.toolCallName,
|
|
476
594
|
input: {},
|
|
477
595
|
};
|
|
596
|
+
// If no message found, create a synthetic assistant message for the tool call
|
|
597
|
+
if (messageIndex === -1) {
|
|
598
|
+
const syntheticMessageId = messageId ?? `msg_tool_${event.toolCallId}`;
|
|
599
|
+
const syntheticMessage = {
|
|
600
|
+
id: syntheticMessageId,
|
|
601
|
+
role: "assistant",
|
|
602
|
+
content: [newContent],
|
|
603
|
+
createdAt: new Date().toISOString(),
|
|
604
|
+
};
|
|
605
|
+
return {
|
|
606
|
+
...threadState,
|
|
607
|
+
thread: {
|
|
608
|
+
...threadState.thread,
|
|
609
|
+
messages: [...messages, syntheticMessage],
|
|
610
|
+
updatedAt: new Date().toISOString(),
|
|
611
|
+
},
|
|
612
|
+
streaming: {
|
|
613
|
+
...threadState.streaming,
|
|
614
|
+
messageId: syntheticMessageId,
|
|
615
|
+
},
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
const message = messages[messageIndex];
|
|
478
619
|
const updatedMessage = {
|
|
479
620
|
...message,
|
|
480
621
|
content: [...message.content, newContent],
|
|
@@ -483,8 +624,9 @@ function handleToolCallStart(threadState, event) {
|
|
|
483
624
|
}
|
|
484
625
|
/**
|
|
485
626
|
* Handle TOOL_CALL_ARGS event.
|
|
486
|
-
* Accumulates JSON string deltas for tool call arguments
|
|
487
|
-
*
|
|
627
|
+
* Accumulates JSON string deltas for tool call arguments and optimistically
|
|
628
|
+
* parses the partial JSON to update the tool_use content block in real-time.
|
|
629
|
+
* The final authoritative parse still happens at TOOL_CALL_END.
|
|
488
630
|
* @param threadState - Current thread state
|
|
489
631
|
* @param event - Tool call args event
|
|
490
632
|
* @returns Updated thread state
|
|
@@ -494,10 +636,46 @@ function handleToolCallArgs(threadState, event) {
|
|
|
494
636
|
// Accumulate the JSON string delta
|
|
495
637
|
const accumulatedArgs = threadState.accumulatingToolArgs;
|
|
496
638
|
const existingArgs = accumulatedArgs.get(toolCallId) ?? "";
|
|
639
|
+
const newAccumulatedJson = existingArgs + event.delta;
|
|
497
640
|
const newAccumulatedArgs = new Map(accumulatedArgs);
|
|
498
|
-
newAccumulatedArgs.set(toolCallId,
|
|
641
|
+
newAccumulatedArgs.set(toolCallId, newAccumulatedJson);
|
|
642
|
+
// Optimistically parse partial JSON to update the tool_use content block
|
|
643
|
+
let parsedInput;
|
|
644
|
+
try {
|
|
645
|
+
const parsed = (0, partial_json_1.parse)(newAccumulatedJson);
|
|
646
|
+
if (typeof parsed === "object" &&
|
|
647
|
+
parsed !== null &&
|
|
648
|
+
!Array.isArray(parsed)) {
|
|
649
|
+
parsedInput = parsed;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
catch {
|
|
653
|
+
// Partial JSON not parseable yet — leave input unchanged
|
|
654
|
+
}
|
|
655
|
+
if (!parsedInput) {
|
|
656
|
+
return {
|
|
657
|
+
...threadState,
|
|
658
|
+
accumulatingToolArgs: newAccumulatedArgs,
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
// Update the tool_use content block with partially parsed input
|
|
662
|
+
const messages = threadState.thread.messages;
|
|
663
|
+
const { messageIndex, contentIndex } = findContentById(messages, "tool_use", toolCallId, "TOOL_CALL_ARGS event");
|
|
664
|
+
const message = messages[messageIndex];
|
|
665
|
+
const toolUseContent = message.content[contentIndex];
|
|
666
|
+
if (toolUseContent.type !== "tool_use") {
|
|
667
|
+
throw new Error(`Content at index ${contentIndex} is not a tool_use block for TOOL_CALL_ARGS event`);
|
|
668
|
+
}
|
|
669
|
+
const updatedContent = {
|
|
670
|
+
...toolUseContent,
|
|
671
|
+
input: parsedInput,
|
|
672
|
+
};
|
|
673
|
+
const updatedMessage = {
|
|
674
|
+
...message,
|
|
675
|
+
content: updateContentAtIndex(message.content, contentIndex, updatedContent),
|
|
676
|
+
};
|
|
499
677
|
return {
|
|
500
|
-
...threadState,
|
|
678
|
+
...updateThreadMessages(threadState, updateMessageAtIndex(messages, messageIndex, updatedMessage)),
|
|
501
679
|
accumulatingToolArgs: newAccumulatedArgs,
|
|
502
680
|
};
|
|
503
681
|
}
|
|
@@ -517,7 +695,7 @@ function handleToolCallEnd(threadState, event) {
|
|
|
517
695
|
// No args accumulated - tool call has empty input
|
|
518
696
|
return threadState;
|
|
519
697
|
}
|
|
520
|
-
// Parse the accumulated JSON
|
|
698
|
+
// Parse the accumulated JSON - tool inputs are always objects
|
|
521
699
|
let parsedInput;
|
|
522
700
|
try {
|
|
523
701
|
parsedInput = JSON.parse(accumulatedJson);
|
|
@@ -551,7 +729,7 @@ function handleToolCallEnd(threadState, event) {
|
|
|
551
729
|
}
|
|
552
730
|
/**
|
|
553
731
|
* Handle TOOL_CALL_RESULT event.
|
|
554
|
-
* Adds tool result to the message.
|
|
732
|
+
* Adds tool result to the specified message.
|
|
555
733
|
* @param threadState - Current thread state
|
|
556
734
|
* @param event - Tool call result event
|
|
557
735
|
* @returns Updated thread state
|
|
@@ -624,11 +802,23 @@ function handleCustomEvent(threadState, event) {
|
|
|
624
802
|
*/
|
|
625
803
|
function handleComponentStart(threadState, event) {
|
|
626
804
|
const messageId = event.value.messageId;
|
|
627
|
-
|
|
628
|
-
// Find the message
|
|
629
|
-
|
|
805
|
+
let messages = threadState.thread.messages;
|
|
806
|
+
// Find the message, or create it if it doesn't exist.
|
|
807
|
+
// The backend may emit component events before TEXT_MESSAGE_START when
|
|
808
|
+
// the LLM outputs a component tool call without preceding text.
|
|
809
|
+
let messageIndex = messages.findIndex((m) => m.id === messageId);
|
|
630
810
|
if (messageIndex === -1) {
|
|
631
|
-
|
|
811
|
+
// Create a new assistant message for this component
|
|
812
|
+
const newMessage = {
|
|
813
|
+
id: messageId,
|
|
814
|
+
role: "assistant",
|
|
815
|
+
content: [],
|
|
816
|
+
createdAt: new Date().toISOString(),
|
|
817
|
+
};
|
|
818
|
+
messages = [...messages, newMessage];
|
|
819
|
+
messageIndex = messages.length - 1;
|
|
820
|
+
// Update thread state with the new message before adding the component
|
|
821
|
+
threadState = updateThreadMessages(threadState, messages);
|
|
632
822
|
}
|
|
633
823
|
const message = messages[messageIndex];
|
|
634
824
|
// Add component content block with 'started' streaming state
|
|
@@ -732,4 +922,223 @@ function handleRunAwaitingInput(threadState, _event) {
|
|
|
732
922
|
},
|
|
733
923
|
};
|
|
734
924
|
}
|
|
925
|
+
// ============================================================================
|
|
926
|
+
// Reasoning Event Handlers (currently mapped from THINKING_TEXT_MESSAGE_* events)
|
|
927
|
+
// ============================================================================
|
|
928
|
+
/**
|
|
929
|
+
* Generate an ephemeral message ID for reasoning messages that arrive before TEXT_MESSAGE_START.
|
|
930
|
+
* Uses crypto.randomUUID() which is available in Node.js 19+ and modern browsers.
|
|
931
|
+
*/
|
|
932
|
+
function generateEphemeralMessageId() {
|
|
933
|
+
return `ephemeral_${crypto.randomUUID()}`;
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* Find or create an assistant message for reasoning events.
|
|
937
|
+
* Reasoning should only be attached to assistant messages.
|
|
938
|
+
* If no suitable assistant message exists, creates an ephemeral one.
|
|
939
|
+
* @param threadState - Current thread state
|
|
940
|
+
* @returns Object with messageIndex, messages array, and updated threadState
|
|
941
|
+
*/
|
|
942
|
+
function findOrCreateMessageForReasoning(threadState) {
|
|
943
|
+
const messageId = threadState.streaming.messageId;
|
|
944
|
+
let messages = threadState.thread.messages;
|
|
945
|
+
// If we have an active streaming messageId, try to find it
|
|
946
|
+
if (messageId) {
|
|
947
|
+
const messageIndex = messages.findIndex((m) => m.id === messageId);
|
|
948
|
+
if (messageIndex !== -1 && messages[messageIndex].role === "assistant") {
|
|
949
|
+
return { messageIndex, messages, threadState };
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
// Look for the last assistant message
|
|
953
|
+
const lastAssistantIndex = messages.findLastIndex((m) => m.role === "assistant");
|
|
954
|
+
// If there's an assistant message and it's the most recent message, use it
|
|
955
|
+
// (Don't attach reasoning to an old assistant message if user message came after)
|
|
956
|
+
if (lastAssistantIndex !== -1 && lastAssistantIndex === messages.length - 1) {
|
|
957
|
+
return { messageIndex: lastAssistantIndex, messages, threadState };
|
|
958
|
+
}
|
|
959
|
+
// No suitable assistant message - create an ephemeral one
|
|
960
|
+
const ephemeralId = generateEphemeralMessageId();
|
|
961
|
+
const newMessage = {
|
|
962
|
+
id: ephemeralId,
|
|
963
|
+
role: "assistant",
|
|
964
|
+
content: [],
|
|
965
|
+
createdAt: new Date().toISOString(),
|
|
966
|
+
};
|
|
967
|
+
messages = [...messages, newMessage];
|
|
968
|
+
const messageIndex = messages.length - 1;
|
|
969
|
+
// Update thread state with new message
|
|
970
|
+
threadState = {
|
|
971
|
+
...threadState,
|
|
972
|
+
thread: {
|
|
973
|
+
...threadState.thread,
|
|
974
|
+
messages,
|
|
975
|
+
updatedAt: new Date().toISOString(),
|
|
976
|
+
},
|
|
977
|
+
streaming: {
|
|
978
|
+
...threadState.streaming,
|
|
979
|
+
messageId: ephemeralId,
|
|
980
|
+
},
|
|
981
|
+
};
|
|
982
|
+
return { messageIndex, messages, threadState };
|
|
983
|
+
}
|
|
984
|
+
/**
|
|
985
|
+
* Handle THINKING_TEXT_MESSAGE_START event (will become REASONING_MESSAGE_START).
|
|
986
|
+
* Starts a new reasoning chunk by appending an empty string to the message's reasoning array.
|
|
987
|
+
* Records the start time for duration calculation.
|
|
988
|
+
* @param threadState - Current thread state
|
|
989
|
+
* @param event - Thinking text message start event
|
|
990
|
+
* @returns Updated thread state
|
|
991
|
+
*/
|
|
992
|
+
function handleThinkingTextMessageStart(threadState, event) {
|
|
993
|
+
const { messageIndex, messages, threadState: updatedThreadState, } = findOrCreateMessageForReasoning(threadState);
|
|
994
|
+
threadState = updatedThreadState;
|
|
995
|
+
const message = messages[messageIndex];
|
|
996
|
+
const existingReasoning = message.reasoning ?? [];
|
|
997
|
+
const updatedMessage = {
|
|
998
|
+
...message,
|
|
999
|
+
reasoning: [...existingReasoning, ""],
|
|
1000
|
+
};
|
|
1001
|
+
// Record reasoning start time if this is the first reasoning chunk
|
|
1002
|
+
const reasoningStartTime = threadState.streaming.reasoningStartTime ?? event.timestamp ?? Date.now();
|
|
1003
|
+
return {
|
|
1004
|
+
...updateThreadMessages(threadState, updateMessageAtIndex(messages, messageIndex, updatedMessage)),
|
|
1005
|
+
streaming: {
|
|
1006
|
+
...threadState.streaming,
|
|
1007
|
+
reasoningStartTime,
|
|
1008
|
+
},
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
/**
|
|
1012
|
+
* Handle THINKING_TEXT_MESSAGE_CONTENT event (will become REASONING_MESSAGE_CONTENT).
|
|
1013
|
+
* Appends delta text to the last reasoning chunk.
|
|
1014
|
+
* @param threadState - Current thread state
|
|
1015
|
+
* @param event - Thinking text message content event
|
|
1016
|
+
* @returns Updated thread state
|
|
1017
|
+
*/
|
|
1018
|
+
function handleThinkingTextMessageContent(threadState, event) {
|
|
1019
|
+
const { messageIndex, messages, threadState: updatedThreadState, } = findOrCreateMessageForReasoning(threadState);
|
|
1020
|
+
threadState = updatedThreadState;
|
|
1021
|
+
const message = messages[messageIndex];
|
|
1022
|
+
const existingReasoning = message.reasoning ?? [];
|
|
1023
|
+
if (existingReasoning.length === 0) {
|
|
1024
|
+
// No reasoning chunk started - start one implicitly
|
|
1025
|
+
const updatedMessage = {
|
|
1026
|
+
...message,
|
|
1027
|
+
reasoning: [event.delta],
|
|
1028
|
+
};
|
|
1029
|
+
return {
|
|
1030
|
+
...updateThreadMessages(threadState, updateMessageAtIndex(messages, messageIndex, updatedMessage)),
|
|
1031
|
+
streaming: {
|
|
1032
|
+
...threadState.streaming,
|
|
1033
|
+
reasoningStartTime: threadState.streaming.reasoningStartTime ??
|
|
1034
|
+
event.timestamp ??
|
|
1035
|
+
Date.now(),
|
|
1036
|
+
},
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
// Append to the last reasoning chunk
|
|
1040
|
+
const updatedReasoning = [
|
|
1041
|
+
...existingReasoning.slice(0, -1),
|
|
1042
|
+
existingReasoning[existingReasoning.length - 1] + event.delta,
|
|
1043
|
+
];
|
|
1044
|
+
const updatedMessage = {
|
|
1045
|
+
...message,
|
|
1046
|
+
reasoning: updatedReasoning,
|
|
1047
|
+
};
|
|
1048
|
+
return updateThreadMessages(threadState, updateMessageAtIndex(messages, messageIndex, updatedMessage));
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Handle THINKING_TEXT_MESSAGE_END event (will become REASONING_MESSAGE_END).
|
|
1052
|
+
* Calculates and stores the reasoning duration.
|
|
1053
|
+
* @param threadState - Current thread state
|
|
1054
|
+
* @param event - Thinking text message end event
|
|
1055
|
+
* @returns Updated thread state
|
|
1056
|
+
*/
|
|
1057
|
+
function handleThinkingTextMessageEnd(threadState, event) {
|
|
1058
|
+
const { messageIndex, messages, threadState: updatedThreadState, } = findOrCreateMessageForReasoning(threadState);
|
|
1059
|
+
threadState = updatedThreadState;
|
|
1060
|
+
const message = messages[messageIndex];
|
|
1061
|
+
// Calculate duration if we have a start time
|
|
1062
|
+
const reasoningStartTime = threadState.streaming.reasoningStartTime;
|
|
1063
|
+
const endTime = event.timestamp ?? Date.now();
|
|
1064
|
+
const reasoningDurationMS = reasoningStartTime
|
|
1065
|
+
? endTime - reasoningStartTime
|
|
1066
|
+
: undefined;
|
|
1067
|
+
const updatedMessage = {
|
|
1068
|
+
...message,
|
|
1069
|
+
reasoningDurationMS: reasoningDurationMS ?? message.reasoningDurationMS ?? undefined,
|
|
1070
|
+
};
|
|
1071
|
+
return updateThreadMessages(threadState, updateMessageAtIndex(messages, messageIndex, updatedMessage));
|
|
1072
|
+
}
|
|
1073
|
+
/**
|
|
1074
|
+
* Handle LOAD_THREAD_MESSAGES action.
|
|
1075
|
+
* Loads messages from API into stream state for an existing thread.
|
|
1076
|
+
* Deduplicates by message ID, keeping existing messages (they may have in-flight updates).
|
|
1077
|
+
* Sorts merged messages by createdAt to ensure chronological order.
|
|
1078
|
+
* @param state - Current stream state
|
|
1079
|
+
* @param action - Load thread messages action
|
|
1080
|
+
* @returns Updated stream state
|
|
1081
|
+
*/
|
|
1082
|
+
function handleLoadThreadMessages(state, action) {
|
|
1083
|
+
const { threadId, messages, skipIfStreaming } = action;
|
|
1084
|
+
// Get or create thread state
|
|
1085
|
+
let threadState = state.threadMap[threadId];
|
|
1086
|
+
if (!threadState) {
|
|
1087
|
+
threadState = createInitialThreadState(threadId);
|
|
1088
|
+
}
|
|
1089
|
+
// Skip if streaming and skipIfStreaming is true
|
|
1090
|
+
if (skipIfStreaming && threadState.streaming.status === "streaming") {
|
|
1091
|
+
return state;
|
|
1092
|
+
}
|
|
1093
|
+
const existingMessages = threadState.thread.messages;
|
|
1094
|
+
// Build a set of existing message IDs for fast lookup
|
|
1095
|
+
const existingIds = new Set(existingMessages.map((m) => m.id));
|
|
1096
|
+
// Filter out messages that already exist (keep existing, add new).
|
|
1097
|
+
// API-loaded messages are by definition fully complete, so stamp
|
|
1098
|
+
// streamingState: "done" on all component content blocks. This is
|
|
1099
|
+
// required by downstream hooks (usePropsStreamingStatus) which check
|
|
1100
|
+
// streamingState === "done" to report isSuccess: true.
|
|
1101
|
+
const newMessages = messages
|
|
1102
|
+
.filter((m) => !existingIds.has(m.id))
|
|
1103
|
+
.map((m) => ({
|
|
1104
|
+
...m,
|
|
1105
|
+
content: m.content.map((block) => {
|
|
1106
|
+
if (block.type !== "component")
|
|
1107
|
+
return block;
|
|
1108
|
+
if (block.streamingState !== undefined &&
|
|
1109
|
+
block.streamingState !== "done") {
|
|
1110
|
+
console.warn(`LOAD_THREAD_MESSAGES: component "${block.id}" has unexpected ` +
|
|
1111
|
+
`streamingState "${block.streamingState}". API-loaded messages ` +
|
|
1112
|
+
`should not have in-flight streaming state.`);
|
|
1113
|
+
}
|
|
1114
|
+
return { ...block, streamingState: "done" };
|
|
1115
|
+
}),
|
|
1116
|
+
}));
|
|
1117
|
+
// Merge and sort by createdAt
|
|
1118
|
+
const mergedMessages = [...existingMessages, ...newMessages].toSorted((a, b) => {
|
|
1119
|
+
// Messages without createdAt go to the end
|
|
1120
|
+
if (!a.createdAt && !b.createdAt)
|
|
1121
|
+
return 0;
|
|
1122
|
+
if (!a.createdAt)
|
|
1123
|
+
return 1;
|
|
1124
|
+
if (!b.createdAt)
|
|
1125
|
+
return -1;
|
|
1126
|
+
return a.createdAt.localeCompare(b.createdAt);
|
|
1127
|
+
});
|
|
1128
|
+
const updatedThreadState = {
|
|
1129
|
+
...threadState,
|
|
1130
|
+
thread: {
|
|
1131
|
+
...threadState.thread,
|
|
1132
|
+
messages: mergedMessages,
|
|
1133
|
+
updatedAt: new Date().toISOString(),
|
|
1134
|
+
},
|
|
1135
|
+
};
|
|
1136
|
+
return {
|
|
1137
|
+
...state,
|
|
1138
|
+
threadMap: {
|
|
1139
|
+
...state.threadMap,
|
|
1140
|
+
[threadId]: updatedThreadState,
|
|
1141
|
+
},
|
|
1142
|
+
};
|
|
1143
|
+
}
|
|
735
1144
|
//# sourceMappingURL=event-accumulator.js.map
|