@tambo-ai/react 0.69.1 → 0.71.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 +7 -7
- package/dist/hooks/use-tambo-threads.test.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts +4 -5
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +4 -5
- package/dist/mcp/index.js.map +1 -1
- package/dist/model/component-metadata.d.ts +88 -241
- package/dist/model/component-metadata.d.ts.map +1 -1
- package/dist/model/component-metadata.js.map +1 -1
- package/dist/model/mcp-server-info.d.ts +3 -3
- package/dist/model/mcp-server-info.js.map +1 -1
- package/dist/providers/hooks/use-tambo-session-token.test.js.map +1 -1
- package/dist/providers/tambo-component-provider.d.ts +2 -2
- package/dist/providers/tambo-component-provider.d.ts.map +1 -1
- package/dist/providers/tambo-component-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.d.ts +1 -1
- package/dist/providers/tambo-registry-provider.d.ts +4 -4
- package/dist/providers/tambo-registry-provider.d.ts.map +1 -1
- package/dist/providers/tambo-registry-provider.js +11 -8
- package/dist/providers/tambo-registry-provider.js.map +1 -1
- package/dist/providers/tambo-registry-provider.test.js +31 -0
- package/dist/providers/tambo-registry-provider.test.js.map +1 -1
- package/dist/providers/tambo-registry-schema-compat.test.js +42 -52
- package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -1
- package/dist/providers/tambo-stubs.d.ts +2 -2
- package/dist/providers/tambo-stubs.d.ts.map +1 -1
- package/dist/providers/tambo-stubs.js.map +1 -1
- package/dist/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
- package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-provider.js +107 -141
- package/dist/providers/tambo-thread-provider.js.map +1 -1
- package/dist/providers/tambo-thread-provider.test.js +274 -445
- package/dist/providers/tambo-thread-provider.test.js.map +1 -1
- package/dist/schema/index.d.ts +1 -2
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +1 -5
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/schema.d.ts +7 -24
- package/dist/schema/schema.d.ts.map +1 -1
- package/dist/schema/schema.js +34 -105
- package/dist/schema/schema.js.map +1 -1
- package/dist/schema/schema.test.js +26 -124
- package/dist/schema/schema.test.js.map +1 -1
- package/dist/testing/tools.d.ts +2 -12
- package/dist/testing/tools.d.ts.map +1 -1
- package/dist/testing/tools.js +1 -20
- package/dist/testing/tools.js.map +1 -1
- package/dist/testing/types.d.ts +2 -2
- package/dist/testing/types.d.ts.map +1 -1
- package/dist/testing/types.js.map +1 -1
- package/dist/util/registry-validators.d.ts +2 -2
- package/dist/util/registry-validators.d.ts.map +1 -1
- package/dist/util/registry-validators.js +37 -17
- package/dist/util/registry-validators.js.map +1 -1
- package/dist/util/registry-validators.test.js +64 -25
- package/dist/util/registry-validators.test.js.map +1 -1
- package/dist/util/registry.d.ts +4 -10
- package/dist/util/registry.d.ts.map +1 -1
- package/dist/util/registry.js +6 -22
- package/dist/util/registry.js.map +1 -1
- package/dist/util/registry.test.js +1 -47
- package/dist/util/registry.test.js.map +1 -1
- package/dist/util/tool-caller.d.ts +2 -2
- package/dist/util/tool-caller.d.ts.map +1 -1
- package/dist/util/tool-caller.js +5 -12
- package/dist/util/tool-caller.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-messages.d.ts +58 -0
- package/dist/v1/hooks/use-tambo-v1-messages.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-messages.js +54 -0
- package/dist/v1/hooks/use-tambo-v1-messages.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-messages.test.d.ts +2 -0
- package/dist/v1/hooks/use-tambo-v1-messages.test.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-messages.test.js +137 -0
- package/dist/v1/hooks/use-tambo-v1-messages.test.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +96 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.js +227 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.test.d.ts +2 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.test.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js +827 -0
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts +61 -0
- package/dist/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-thread-list.js +56 -0
- package/dist/v1/hooks/use-tambo-v1-thread-list.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.d.ts +2 -0
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js +98 -0
- package/dist/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-thread.d.ts +37 -0
- package/dist/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-thread.js +49 -0
- package/dist/v1/hooks/use-tambo-v1-thread.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-thread.test.d.ts +2 -0
- package/dist/v1/hooks/use-tambo-v1-thread.test.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1-thread.test.js +83 -0
- package/dist/v1/hooks/use-tambo-v1-thread.test.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1.d.ts +107 -0
- package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1.js +87 -0
- package/dist/v1/hooks/use-tambo-v1.js.map +1 -0
- package/dist/v1/hooks/use-tambo-v1.test.d.ts +2 -0
- package/dist/v1/hooks/use-tambo-v1.test.d.ts.map +1 -0
- package/dist/v1/hooks/use-tambo-v1.test.js +150 -0
- package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -0
- package/dist/v1/index.d.ts +73 -0
- package/dist/v1/index.d.ts.map +1 -0
- package/dist/v1/index.js +106 -0
- package/dist/v1/index.js.map +1 -0
- package/dist/v1/providers/tambo-v1-provider.d.ts +91 -0
- package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -0
- package/dist/v1/providers/tambo-v1-provider.js +110 -0
- package/dist/v1/providers/tambo-v1-provider.js.map +1 -0
- package/dist/v1/providers/tambo-v1-provider.test.d.ts +2 -0
- package/dist/v1/providers/tambo-v1-provider.test.d.ts.map +1 -0
- package/dist/v1/providers/tambo-v1-provider.test.js +123 -0
- package/dist/v1/providers/tambo-v1-provider.test.js.map +1 -0
- package/dist/v1/providers/tambo-v1-stream-context.d.ts +136 -0
- package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -0
- package/dist/v1/providers/tambo-v1-stream-context.js +230 -0
- package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -0
- package/dist/v1/providers/tambo-v1-stream-context.test.d.ts +2 -0
- package/dist/v1/providers/tambo-v1-stream-context.test.d.ts.map +1 -0
- package/dist/v1/providers/tambo-v1-stream-context.test.js +85 -0
- package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -0
- package/dist/v1/types/component.d.ts +50 -0
- package/dist/v1/types/component.d.ts.map +1 -0
- package/dist/v1/types/component.js +14 -0
- package/dist/v1/types/component.js.map +1 -0
- package/dist/v1/types/event.d.ts +72 -0
- package/dist/v1/types/event.d.ts.map +1 -0
- package/dist/v1/types/event.js +54 -0
- package/dist/v1/types/event.js.map +1 -0
- package/dist/v1/types/event.test.d.ts +2 -0
- package/dist/v1/types/event.test.d.ts.map +1 -0
- package/dist/v1/types/event.test.js +70 -0
- package/dist/v1/types/event.test.js.map +1 -0
- package/dist/v1/types/message.d.ts +35 -0
- package/dist/v1/types/message.d.ts.map +1 -0
- package/dist/v1/types/message.js +10 -0
- package/dist/v1/types/message.js.map +1 -0
- package/dist/v1/types/thread.d.ts +52 -0
- package/dist/v1/types/thread.d.ts.map +1 -0
- package/dist/v1/types/thread.js +9 -0
- package/dist/v1/types/thread.js.map +1 -0
- package/dist/v1/utils/event-accumulator.d.ts +100 -0
- package/dist/v1/utils/event-accumulator.d.ts.map +1 -0
- package/dist/v1/utils/event-accumulator.js +715 -0
- package/dist/v1/utils/event-accumulator.js.map +1 -0
- package/dist/v1/utils/event-accumulator.test.d.ts +2 -0
- package/dist/v1/utils/event-accumulator.test.d.ts.map +1 -0
- package/dist/v1/utils/event-accumulator.test.js +1010 -0
- package/dist/v1/utils/event-accumulator.test.js.map +1 -0
- package/dist/v1/utils/json-patch.d.ts +18 -0
- package/dist/v1/utils/json-patch.d.ts.map +1 -0
- package/dist/v1/utils/json-patch.js +35 -0
- package/dist/v1/utils/json-patch.js.map +1 -0
- package/dist/v1/utils/json-patch.test.d.ts +2 -0
- package/dist/v1/utils/json-patch.test.d.ts.map +1 -0
- package/dist/v1/utils/json-patch.test.js +28 -0
- package/dist/v1/utils/json-patch.test.js.map +1 -0
- package/dist/v1/utils/registry-conversion.d.ts +53 -0
- package/dist/v1/utils/registry-conversion.d.ts.map +1 -0
- package/dist/v1/utils/registry-conversion.js +114 -0
- package/dist/v1/utils/registry-conversion.js.map +1 -0
- package/dist/v1/utils/registry-conversion.test.d.ts +2 -0
- package/dist/v1/utils/registry-conversion.test.d.ts.map +1 -0
- package/dist/v1/utils/registry-conversion.test.js +179 -0
- package/dist/v1/utils/registry-conversion.test.js.map +1 -0
- package/dist/v1/utils/stream-handler.d.ts +45 -0
- package/dist/v1/utils/stream-handler.d.ts.map +1 -0
- package/dist/v1/utils/stream-handler.js +47 -0
- package/dist/v1/utils/stream-handler.js.map +1 -0
- package/dist/v1/utils/stream-handler.test.d.ts +2 -0
- package/dist/v1/utils/stream-handler.test.d.ts.map +1 -0
- package/dist/v1/utils/stream-handler.test.js +74 -0
- package/dist/v1/utils/stream-handler.test.js.map +1 -0
- package/dist/v1/utils/tool-call-tracker.d.ts +41 -0
- package/dist/v1/utils/tool-call-tracker.d.ts.map +1 -0
- package/dist/v1/utils/tool-call-tracker.js +90 -0
- package/dist/v1/utils/tool-call-tracker.js.map +1 -0
- package/dist/v1/utils/tool-executor.d.ts +33 -0
- package/dist/v1/utils/tool-executor.d.ts.map +1 -0
- package/dist/v1/utils/tool-executor.js +103 -0
- package/dist/v1/utils/tool-executor.js.map +1 -0
- package/dist/v1/utils/tool-executor.test.d.ts +2 -0
- package/dist/v1/utils/tool-executor.test.d.ts.map +1 -0
- package/dist/v1/utils/tool-executor.test.js +222 -0
- package/dist/v1/utils/tool-executor.test.js.map +1 -0
- package/esm/hooks/use-tambo-threads.test.js.map +1 -1
- package/esm/index.d.ts +1 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js.map +1 -1
- package/esm/mcp/index.d.ts +4 -5
- package/esm/mcp/index.d.ts.map +1 -1
- package/esm/mcp/index.js +4 -5
- package/esm/mcp/index.js.map +1 -1
- package/esm/model/component-metadata.d.ts +88 -241
- package/esm/model/component-metadata.d.ts.map +1 -1
- package/esm/model/component-metadata.js.map +1 -1
- package/esm/model/mcp-server-info.d.ts +3 -3
- package/esm/model/mcp-server-info.js.map +1 -1
- package/esm/providers/hooks/use-tambo-session-token.test.js.map +1 -1
- package/esm/providers/tambo-component-provider.d.ts +2 -2
- package/esm/providers/tambo-component-provider.d.ts.map +1 -1
- package/esm/providers/tambo-component-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +1 -1
- package/esm/providers/tambo-registry-provider.d.ts +4 -4
- package/esm/providers/tambo-registry-provider.d.ts.map +1 -1
- package/esm/providers/tambo-registry-provider.js +11 -8
- package/esm/providers/tambo-registry-provider.js.map +1 -1
- package/esm/providers/tambo-registry-provider.test.js +31 -0
- package/esm/providers/tambo-registry-provider.test.js.map +1 -1
- package/esm/providers/tambo-registry-schema-compat.test.js +42 -52
- package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -1
- package/esm/providers/tambo-stubs.d.ts +2 -2
- package/esm/providers/tambo-stubs.d.ts.map +1 -1
- package/esm/providers/tambo-stubs.js.map +1 -1
- package/esm/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
- package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-provider.js +107 -141
- package/esm/providers/tambo-thread-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider.test.js +241 -445
- package/esm/providers/tambo-thread-provider.test.js.map +1 -1
- package/esm/schema/index.d.ts +1 -2
- package/esm/schema/index.d.ts.map +1 -1
- package/esm/schema/index.js +1 -2
- package/esm/schema/index.js.map +1 -1
- package/esm/schema/schema.d.ts +7 -24
- package/esm/schema/schema.d.ts.map +1 -1
- package/esm/schema/schema.js +34 -103
- package/esm/schema/schema.js.map +1 -1
- package/esm/schema/schema.test.js +27 -125
- package/esm/schema/schema.test.js.map +1 -1
- package/esm/testing/tools.d.ts +2 -12
- package/esm/testing/tools.d.ts.map +1 -1
- package/esm/testing/tools.js +2 -20
- package/esm/testing/tools.js.map +1 -1
- package/esm/testing/types.d.ts +2 -2
- package/esm/testing/types.d.ts.map +1 -1
- package/esm/testing/types.js.map +1 -1
- package/esm/util/registry-validators.d.ts +2 -2
- package/esm/util/registry-validators.d.ts.map +1 -1
- package/esm/util/registry-validators.js +38 -18
- package/esm/util/registry-validators.js.map +1 -1
- package/esm/util/registry-validators.test.js +64 -25
- package/esm/util/registry-validators.test.js.map +1 -1
- package/esm/util/registry.d.ts +4 -10
- package/esm/util/registry.d.ts.map +1 -1
- package/esm/util/registry.js +7 -22
- package/esm/util/registry.js.map +1 -1
- package/esm/util/registry.test.js +3 -49
- package/esm/util/registry.test.js.map +1 -1
- package/esm/util/tool-caller.d.ts +2 -2
- package/esm/util/tool-caller.d.ts.map +1 -1
- package/esm/util/tool-caller.js +5 -12
- package/esm/util/tool-caller.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-messages.d.ts +58 -0
- package/esm/v1/hooks/use-tambo-v1-messages.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-messages.js +51 -0
- package/esm/v1/hooks/use-tambo-v1-messages.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-messages.test.d.ts +2 -0
- package/esm/v1/hooks/use-tambo-v1-messages.test.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-messages.test.js +132 -0
- package/esm/v1/hooks/use-tambo-v1-messages.test.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +96 -0
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-send-message.js +223 -0
- package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-send-message.test.d.ts +2 -0
- package/esm/v1/hooks/use-tambo-v1-send-message.test.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js +822 -0
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts +61 -0
- package/esm/v1/hooks/use-tambo-v1-thread-list.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-thread-list.js +53 -0
- package/esm/v1/hooks/use-tambo-v1-thread-list.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.d.ts +2 -0
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js +93 -0
- package/esm/v1/hooks/use-tambo-v1-thread-list.test.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-thread.d.ts +37 -0
- package/esm/v1/hooks/use-tambo-v1-thread.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-thread.js +46 -0
- package/esm/v1/hooks/use-tambo-v1-thread.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-thread.test.d.ts +2 -0
- package/esm/v1/hooks/use-tambo-v1-thread.test.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1-thread.test.js +78 -0
- package/esm/v1/hooks/use-tambo-v1-thread.test.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1.d.ts +107 -0
- package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1.js +84 -0
- package/esm/v1/hooks/use-tambo-v1.js.map +1 -0
- package/esm/v1/hooks/use-tambo-v1.test.d.ts +2 -0
- package/esm/v1/hooks/use-tambo-v1.test.d.ts.map +1 -0
- package/esm/v1/hooks/use-tambo-v1.test.js +145 -0
- package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -0
- package/esm/v1/index.d.ts +73 -0
- package/esm/v1/index.d.ts.map +1 -0
- package/esm/v1/index.js +83 -0
- package/esm/v1/index.js.map +1 -0
- package/esm/v1/providers/tambo-v1-provider.d.ts +91 -0
- package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -0
- package/esm/v1/providers/tambo-v1-provider.js +74 -0
- package/esm/v1/providers/tambo-v1-provider.js.map +1 -0
- package/esm/v1/providers/tambo-v1-provider.test.d.ts +2 -0
- package/esm/v1/providers/tambo-v1-provider.test.d.ts.map +1 -0
- package/esm/v1/providers/tambo-v1-provider.test.js +118 -0
- package/esm/v1/providers/tambo-v1-provider.test.js.map +1 -0
- package/esm/v1/providers/tambo-v1-stream-context.d.ts +136 -0
- package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -0
- package/esm/v1/providers/tambo-v1-stream-context.js +191 -0
- package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -0
- package/esm/v1/providers/tambo-v1-stream-context.test.d.ts +2 -0
- package/esm/v1/providers/tambo-v1-stream-context.test.d.ts.map +1 -0
- package/esm/v1/providers/tambo-v1-stream-context.test.js +80 -0
- package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -0
- package/esm/v1/types/component.d.ts +50 -0
- package/esm/v1/types/component.d.ts.map +1 -0
- package/esm/v1/types/component.js +13 -0
- package/esm/v1/types/component.js.map +1 -0
- package/esm/v1/types/event.d.ts +72 -0
- package/esm/v1/types/event.d.ts.map +1 -0
- package/esm/v1/types/event.js +50 -0
- package/esm/v1/types/event.js.map +1 -0
- package/esm/v1/types/event.test.d.ts +2 -0
- package/esm/v1/types/event.test.d.ts.map +1 -0
- package/esm/v1/types/event.test.js +68 -0
- package/esm/v1/types/event.test.js.map +1 -0
- package/esm/v1/types/message.d.ts +35 -0
- package/esm/v1/types/message.d.ts.map +1 -0
- package/esm/v1/types/message.js +9 -0
- package/esm/v1/types/message.js.map +1 -0
- package/esm/v1/types/thread.d.ts +52 -0
- package/esm/v1/types/thread.d.ts.map +1 -0
- package/esm/v1/types/thread.js +8 -0
- package/esm/v1/types/thread.js.map +1 -0
- package/esm/v1/utils/event-accumulator.d.ts +100 -0
- package/esm/v1/utils/event-accumulator.d.ts.map +1 -0
- package/esm/v1/utils/event-accumulator.js +708 -0
- package/esm/v1/utils/event-accumulator.js.map +1 -0
- package/esm/v1/utils/event-accumulator.test.d.ts +2 -0
- package/esm/v1/utils/event-accumulator.test.d.ts.map +1 -0
- package/esm/v1/utils/event-accumulator.test.js +1008 -0
- package/esm/v1/utils/event-accumulator.test.js.map +1 -0
- package/esm/v1/utils/json-patch.d.ts +18 -0
- package/esm/v1/utils/json-patch.d.ts.map +1 -0
- package/esm/v1/utils/json-patch.js +32 -0
- package/esm/v1/utils/json-patch.js.map +1 -0
- package/esm/v1/utils/json-patch.test.d.ts +2 -0
- package/esm/v1/utils/json-patch.test.d.ts.map +1 -0
- package/esm/v1/utils/json-patch.test.js +26 -0
- package/esm/v1/utils/json-patch.test.js.map +1 -0
- package/esm/v1/utils/registry-conversion.d.ts +53 -0
- package/esm/v1/utils/registry-conversion.d.ts.map +1 -0
- package/esm/v1/utils/registry-conversion.js +108 -0
- package/esm/v1/utils/registry-conversion.js.map +1 -0
- package/esm/v1/utils/registry-conversion.test.d.ts +2 -0
- package/esm/v1/utils/registry-conversion.test.d.ts.map +1 -0
- package/esm/v1/utils/registry-conversion.test.js +177 -0
- package/esm/v1/utils/registry-conversion.test.js.map +1 -0
- package/esm/v1/utils/stream-handler.d.ts +45 -0
- package/esm/v1/utils/stream-handler.d.ts.map +1 -0
- package/esm/v1/utils/stream-handler.js +44 -0
- package/esm/v1/utils/stream-handler.js.map +1 -0
- package/esm/v1/utils/stream-handler.test.d.ts +2 -0
- package/esm/v1/utils/stream-handler.test.d.ts.map +1 -0
- package/esm/v1/utils/stream-handler.test.js +72 -0
- package/esm/v1/utils/stream-handler.test.js.map +1 -0
- package/esm/v1/utils/tool-call-tracker.d.ts +41 -0
- package/esm/v1/utils/tool-call-tracker.d.ts.map +1 -0
- package/esm/v1/utils/tool-call-tracker.js +86 -0
- package/esm/v1/utils/tool-call-tracker.js.map +1 -0
- package/esm/v1/utils/tool-executor.d.ts +33 -0
- package/esm/v1/utils/tool-executor.d.ts.map +1 -0
- package/esm/v1/utils/tool-executor.js +99 -0
- package/esm/v1/utils/tool-executor.js.map +1 -0
- package/esm/v1/utils/tool-executor.test.d.ts +2 -0
- package/esm/v1/utils/tool-executor.test.d.ts.map +1 -0
- package/esm/v1/utils/tool-executor.test.js +220 -0
- package/esm/v1/utils/tool-executor.test.js.map +1 -0
- package/package.json +20 -9
- package/dist/schema/zod.d.ts +0 -57
- package/dist/schema/zod.d.ts.map +0 -1
- package/dist/schema/zod.js +0 -191
- package/dist/schema/zod.js.map +0 -1
- package/dist/schema/zod.test.d.ts +0 -2
- package/dist/schema/zod.test.d.ts.map +0 -1
- package/dist/schema/zod.test.js +0 -663
- package/dist/schema/zod.test.js.map +0 -1
- package/esm/schema/zod.d.ts +0 -57
- package/esm/schema/zod.d.ts.map +0 -1
- package/esm/schema/zod.js +0 -180
- package/esm/schema/zod.js.map +0 -1
- package/esm/schema/zod.test.d.ts +0 -2
- package/esm/schema/zod.test.d.ts.map +0 -1
- package/esm/schema/zod.test.js +0 -628
- package/esm/schema/zod.test.js.map +0 -1
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event Accumulation Logic for v1 Streaming API
|
|
3
|
+
*
|
|
4
|
+
* Implements a reducer that transforms AG-UI event streams into React state.
|
|
5
|
+
* Used with useReducer to accumulate events into thread state.
|
|
6
|
+
*/
|
|
7
|
+
import { EventType } from "@ag-ui/core";
|
|
8
|
+
import { asTamboCustomEvent, } from "../types/event";
|
|
9
|
+
import { applyJsonPatch } from "./json-patch";
|
|
10
|
+
/**
|
|
11
|
+
* Error thrown when an unreachable case is reached in a switch statement.
|
|
12
|
+
* This indicates a programming error where not all cases were handled.
|
|
13
|
+
*/
|
|
14
|
+
export class UnreachableCaseError extends Error {
|
|
15
|
+
constructor(value) {
|
|
16
|
+
super(`Unreachable case: ${JSON.stringify(value)}`);
|
|
17
|
+
this.name = "UnreachableCaseError";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Initial streaming state.
|
|
22
|
+
*/
|
|
23
|
+
const initialStreamingState = {
|
|
24
|
+
status: "idle",
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Create initial thread state for a new thread.
|
|
28
|
+
* @param threadId - Unique thread identifier
|
|
29
|
+
* @returns Initial thread state
|
|
30
|
+
*/
|
|
31
|
+
export function createInitialThreadState(threadId) {
|
|
32
|
+
const now = new Date().toISOString();
|
|
33
|
+
return {
|
|
34
|
+
thread: {
|
|
35
|
+
id: threadId,
|
|
36
|
+
messages: [],
|
|
37
|
+
status: "idle",
|
|
38
|
+
createdAt: now,
|
|
39
|
+
updatedAt: now,
|
|
40
|
+
},
|
|
41
|
+
streaming: initialStreamingState,
|
|
42
|
+
accumulatingToolArgs: new Map(),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Create initial stream state with empty threadMap.
|
|
47
|
+
* @returns Initial stream state
|
|
48
|
+
*/
|
|
49
|
+
export function createInitialState() {
|
|
50
|
+
return {
|
|
51
|
+
threadMap: {},
|
|
52
|
+
currentThreadId: null,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Replace a message at a specific index immutably.
|
|
57
|
+
* @param messages - Current messages array
|
|
58
|
+
* @param index - Index of message to replace
|
|
59
|
+
* @param updatedMessage - New message to insert
|
|
60
|
+
* @returns New messages array with the message replaced
|
|
61
|
+
*/
|
|
62
|
+
function updateMessageAtIndex(messages, index, updatedMessage) {
|
|
63
|
+
return [
|
|
64
|
+
...messages.slice(0, index),
|
|
65
|
+
updatedMessage,
|
|
66
|
+
...messages.slice(index + 1),
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Replace a content block at a specific index within a message's content immutably.
|
|
71
|
+
* @param content - Current content array
|
|
72
|
+
* @param index - Index of content to replace
|
|
73
|
+
* @param updatedContent - New content to insert
|
|
74
|
+
* @returns New content array with the content replaced
|
|
75
|
+
*/
|
|
76
|
+
function updateContentAtIndex(content, index, updatedContent) {
|
|
77
|
+
return [
|
|
78
|
+
...content.slice(0, index),
|
|
79
|
+
updatedContent,
|
|
80
|
+
...content.slice(index + 1),
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Find a content block by ID across all messages, searching from most recent.
|
|
85
|
+
*
|
|
86
|
+
* TODO: This is O(n*m) where n = messages and m = content blocks per message.
|
|
87
|
+
* For high-frequency streaming with many messages, consider maintaining an
|
|
88
|
+
* index map of contentId -> {messageIndex, contentIndex} that gets updated
|
|
89
|
+
* when content blocks are created.
|
|
90
|
+
* @param messages - Messages to search
|
|
91
|
+
* @param contentType - Type of content to find ("component" or "tool_use")
|
|
92
|
+
* @param contentId - ID of the content block
|
|
93
|
+
* @param eventName - Name of the event (for error messages)
|
|
94
|
+
* @returns Location of the content block
|
|
95
|
+
* @throws {Error} If content not found
|
|
96
|
+
*/
|
|
97
|
+
function findContentById(messages, contentType, contentId, eventName) {
|
|
98
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
99
|
+
const idx = messages[i].content.findIndex((c) => c.type === contentType && c.id === contentId);
|
|
100
|
+
if (idx !== -1) {
|
|
101
|
+
return { messageIndex: i, contentIndex: idx };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
throw new Error(`${contentType} ${contentId} not found for ${eventName}`);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Create updated thread state with new messages.
|
|
108
|
+
* @param threadState - Current thread state
|
|
109
|
+
* @param messages - New messages array
|
|
110
|
+
* @returns Updated thread state
|
|
111
|
+
*/
|
|
112
|
+
function updateThreadMessages(threadState, messages) {
|
|
113
|
+
return {
|
|
114
|
+
...threadState,
|
|
115
|
+
thread: {
|
|
116
|
+
...threadState.thread,
|
|
117
|
+
messages,
|
|
118
|
+
updatedAt: new Date().toISOString(),
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Stream reducer that accumulates events into thread state.
|
|
124
|
+
*
|
|
125
|
+
* This reducer handles all AG-UI events and Tambo custom events,
|
|
126
|
+
* transforming them into immutable state updates per thread.
|
|
127
|
+
* @param state - Current stream state
|
|
128
|
+
* @param action - Action to process
|
|
129
|
+
* @returns Updated stream state
|
|
130
|
+
*/
|
|
131
|
+
export function streamReducer(state, action) {
|
|
132
|
+
// Handle non-event actions first
|
|
133
|
+
switch (action.type) {
|
|
134
|
+
case "INIT_THREAD": {
|
|
135
|
+
const { threadId, initialThread } = action;
|
|
136
|
+
// Don't overwrite existing thread
|
|
137
|
+
if (state.threadMap[threadId]) {
|
|
138
|
+
return state;
|
|
139
|
+
}
|
|
140
|
+
const baseState = createInitialThreadState(threadId);
|
|
141
|
+
const threadState = initialThread
|
|
142
|
+
? {
|
|
143
|
+
...baseState,
|
|
144
|
+
thread: {
|
|
145
|
+
...baseState.thread,
|
|
146
|
+
...initialThread,
|
|
147
|
+
id: threadId,
|
|
148
|
+
},
|
|
149
|
+
}
|
|
150
|
+
: baseState;
|
|
151
|
+
return {
|
|
152
|
+
...state,
|
|
153
|
+
threadMap: {
|
|
154
|
+
...state.threadMap,
|
|
155
|
+
[threadId]: threadState,
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
case "SET_CURRENT_THREAD": {
|
|
160
|
+
return {
|
|
161
|
+
...state,
|
|
162
|
+
currentThreadId: action.threadId,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
case "START_NEW_THREAD": {
|
|
166
|
+
// Atomic action: initialize thread AND set as current in one reducer pass
|
|
167
|
+
// This prevents race conditions when multiple startNewThread() calls happen
|
|
168
|
+
const { threadId, initialThread } = action;
|
|
169
|
+
// Don't overwrite existing thread
|
|
170
|
+
if (state.threadMap[threadId]) {
|
|
171
|
+
return {
|
|
172
|
+
...state,
|
|
173
|
+
currentThreadId: threadId,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
const baseState = createInitialThreadState(threadId);
|
|
177
|
+
const threadState = initialThread
|
|
178
|
+
? {
|
|
179
|
+
...baseState,
|
|
180
|
+
thread: {
|
|
181
|
+
...baseState.thread,
|
|
182
|
+
...initialThread,
|
|
183
|
+
id: threadId,
|
|
184
|
+
},
|
|
185
|
+
}
|
|
186
|
+
: baseState;
|
|
187
|
+
return {
|
|
188
|
+
...state,
|
|
189
|
+
threadMap: {
|
|
190
|
+
...state.threadMap,
|
|
191
|
+
[threadId]: threadState,
|
|
192
|
+
},
|
|
193
|
+
currentThreadId: threadId,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
case "EVENT":
|
|
197
|
+
// Fall through to event handling below
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
// Handle EVENT action
|
|
201
|
+
const { event, threadId } = action;
|
|
202
|
+
// Get the current thread state, auto-initializing if needed
|
|
203
|
+
// Auto-initialization handles the case where events arrive before explicit thread init
|
|
204
|
+
// (e.g., when creating a new thread and RUN_STARTED is the first event)
|
|
205
|
+
let threadState = state.threadMap[threadId];
|
|
206
|
+
let updatedState = state;
|
|
207
|
+
if (!threadState) {
|
|
208
|
+
// Auto-initialize the thread to avoid dropping events
|
|
209
|
+
threadState = createInitialThreadState(threadId);
|
|
210
|
+
updatedState = {
|
|
211
|
+
...state,
|
|
212
|
+
threadMap: {
|
|
213
|
+
...state.threadMap,
|
|
214
|
+
[threadId]: threadState,
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
// Process the event for this specific thread
|
|
219
|
+
let updatedThreadState;
|
|
220
|
+
// Switch on event.type - AGUIEvent is a discriminated union so TypeScript
|
|
221
|
+
// automatically narrows the type in each case branch
|
|
222
|
+
switch (event.type) {
|
|
223
|
+
case EventType.RUN_STARTED:
|
|
224
|
+
updatedThreadState = handleRunStarted(threadState, event);
|
|
225
|
+
break;
|
|
226
|
+
case EventType.RUN_FINISHED:
|
|
227
|
+
updatedThreadState = handleRunFinished(threadState, event);
|
|
228
|
+
break;
|
|
229
|
+
case EventType.RUN_ERROR:
|
|
230
|
+
updatedThreadState = handleRunError(threadState, event);
|
|
231
|
+
break;
|
|
232
|
+
case EventType.TEXT_MESSAGE_START:
|
|
233
|
+
updatedThreadState = handleTextMessageStart(threadState, event);
|
|
234
|
+
break;
|
|
235
|
+
case EventType.TEXT_MESSAGE_CONTENT:
|
|
236
|
+
updatedThreadState = handleTextMessageContent(threadState, event);
|
|
237
|
+
break;
|
|
238
|
+
case EventType.TEXT_MESSAGE_END:
|
|
239
|
+
updatedThreadState = handleTextMessageEnd(threadState, event);
|
|
240
|
+
break;
|
|
241
|
+
case EventType.TOOL_CALL_START:
|
|
242
|
+
updatedThreadState = handleToolCallStart(threadState, event);
|
|
243
|
+
break;
|
|
244
|
+
case EventType.TOOL_CALL_ARGS:
|
|
245
|
+
updatedThreadState = handleToolCallArgs(threadState, event);
|
|
246
|
+
break;
|
|
247
|
+
case EventType.TOOL_CALL_END:
|
|
248
|
+
updatedThreadState = handleToolCallEnd(threadState, event);
|
|
249
|
+
break;
|
|
250
|
+
case EventType.TOOL_CALL_RESULT:
|
|
251
|
+
updatedThreadState = handleToolCallResult(threadState, event);
|
|
252
|
+
break;
|
|
253
|
+
case EventType.CUSTOM:
|
|
254
|
+
updatedThreadState = handleCustomEvent(threadState, event);
|
|
255
|
+
break;
|
|
256
|
+
// Unsupported AG-UI event types - may be added in future phases
|
|
257
|
+
case EventType.TEXT_MESSAGE_CHUNK:
|
|
258
|
+
case EventType.THINKING_TEXT_MESSAGE_START:
|
|
259
|
+
case EventType.THINKING_TEXT_MESSAGE_CONTENT:
|
|
260
|
+
case EventType.THINKING_TEXT_MESSAGE_END:
|
|
261
|
+
case EventType.TOOL_CALL_CHUNK:
|
|
262
|
+
case EventType.THINKING_START:
|
|
263
|
+
case EventType.THINKING_END:
|
|
264
|
+
case EventType.STATE_SNAPSHOT:
|
|
265
|
+
case EventType.STATE_DELTA:
|
|
266
|
+
case EventType.MESSAGES_SNAPSHOT:
|
|
267
|
+
case EventType.ACTIVITY_SNAPSHOT:
|
|
268
|
+
case EventType.ACTIVITY_DELTA:
|
|
269
|
+
case EventType.RAW:
|
|
270
|
+
case EventType.STEP_STARTED:
|
|
271
|
+
case EventType.STEP_FINISHED:
|
|
272
|
+
// Log warning - these events are being ignored
|
|
273
|
+
console.warn(`[StreamReducer] Received unsupported event type: ${event.type}. ` +
|
|
274
|
+
`This event will be ignored.`);
|
|
275
|
+
return updatedState;
|
|
276
|
+
default: {
|
|
277
|
+
// Exhaustiveness check: if a new event type is added to AGUIEvent
|
|
278
|
+
// and not handled above, TypeScript will error here
|
|
279
|
+
const _exhaustiveCheck = event;
|
|
280
|
+
throw new UnreachableCaseError(_exhaustiveCheck);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// Return updated state with modified thread
|
|
284
|
+
return {
|
|
285
|
+
...updatedState,
|
|
286
|
+
threadMap: {
|
|
287
|
+
...updatedState.threadMap,
|
|
288
|
+
[threadId]: updatedThreadState,
|
|
289
|
+
},
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Handle RUN_STARTED event.
|
|
294
|
+
* @param threadState - Current thread state
|
|
295
|
+
* @param event - Run started event
|
|
296
|
+
* @returns Updated thread state
|
|
297
|
+
*/
|
|
298
|
+
function handleRunStarted(threadState, event) {
|
|
299
|
+
return {
|
|
300
|
+
...threadState,
|
|
301
|
+
thread: {
|
|
302
|
+
...threadState.thread,
|
|
303
|
+
status: "streaming",
|
|
304
|
+
updatedAt: new Date().toISOString(),
|
|
305
|
+
},
|
|
306
|
+
streaming: {
|
|
307
|
+
status: "streaming",
|
|
308
|
+
runId: event.runId,
|
|
309
|
+
startTime: event.timestamp ?? Date.now(),
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Handle RUN_FINISHED event.
|
|
315
|
+
* @param threadState - Current thread state
|
|
316
|
+
* @param _event - Run finished event (unused)
|
|
317
|
+
* @returns Updated thread state
|
|
318
|
+
*/
|
|
319
|
+
function handleRunFinished(threadState, _event) {
|
|
320
|
+
return {
|
|
321
|
+
...threadState,
|
|
322
|
+
thread: {
|
|
323
|
+
...threadState.thread,
|
|
324
|
+
status: "complete",
|
|
325
|
+
updatedAt: new Date().toISOString(),
|
|
326
|
+
},
|
|
327
|
+
streaming: {
|
|
328
|
+
...threadState.streaming,
|
|
329
|
+
status: "complete",
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Handle RUN_ERROR event.
|
|
335
|
+
* @param threadState - Current thread state
|
|
336
|
+
* @param event - Run error event
|
|
337
|
+
* @returns Updated thread state
|
|
338
|
+
*/
|
|
339
|
+
function handleRunError(threadState, event) {
|
|
340
|
+
return {
|
|
341
|
+
...threadState,
|
|
342
|
+
thread: {
|
|
343
|
+
...threadState.thread,
|
|
344
|
+
status: "error",
|
|
345
|
+
updatedAt: new Date().toISOString(),
|
|
346
|
+
},
|
|
347
|
+
streaming: {
|
|
348
|
+
...threadState.streaming,
|
|
349
|
+
status: "error",
|
|
350
|
+
error: {
|
|
351
|
+
message: event.message,
|
|
352
|
+
code: event.code,
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Handle TEXT_MESSAGE_START event.
|
|
359
|
+
* Creates a new message in the thread.
|
|
360
|
+
* @param threadState - Current thread state
|
|
361
|
+
* @param event - Text message start event
|
|
362
|
+
* @returns Updated thread state
|
|
363
|
+
*/
|
|
364
|
+
function handleTextMessageStart(threadState, event) {
|
|
365
|
+
const newMessage = {
|
|
366
|
+
id: event.messageId,
|
|
367
|
+
role: event.role === "user" ? "user" : "assistant",
|
|
368
|
+
content: [],
|
|
369
|
+
createdAt: new Date().toISOString(),
|
|
370
|
+
};
|
|
371
|
+
return {
|
|
372
|
+
...threadState,
|
|
373
|
+
thread: {
|
|
374
|
+
...threadState.thread,
|
|
375
|
+
messages: [...threadState.thread.messages, newMessage],
|
|
376
|
+
updatedAt: new Date().toISOString(),
|
|
377
|
+
},
|
|
378
|
+
streaming: {
|
|
379
|
+
...threadState.streaming,
|
|
380
|
+
messageId: event.messageId,
|
|
381
|
+
},
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Handle TEXT_MESSAGE_CONTENT event.
|
|
386
|
+
* Appends text content to the current message.
|
|
387
|
+
* @param threadState - Current thread state
|
|
388
|
+
* @param event - Text message content event
|
|
389
|
+
* @returns Updated thread state
|
|
390
|
+
*/
|
|
391
|
+
function handleTextMessageContent(threadState, event) {
|
|
392
|
+
const messageId = event.messageId;
|
|
393
|
+
const messages = threadState.thread.messages;
|
|
394
|
+
// Find the message to update
|
|
395
|
+
const messageIndex = messages.findIndex((m) => m.id === messageId);
|
|
396
|
+
if (messageIndex === -1) {
|
|
397
|
+
throw new Error(`Message ${messageId} not found for TEXT_MESSAGE_CONTENT event`);
|
|
398
|
+
}
|
|
399
|
+
const message = messages[messageIndex];
|
|
400
|
+
const content = message.content;
|
|
401
|
+
// Find or create text content block
|
|
402
|
+
const lastContent = content[content.length - 1];
|
|
403
|
+
const isTextBlock = lastContent?.type === "text";
|
|
404
|
+
const updatedContent = isTextBlock
|
|
405
|
+
? [
|
|
406
|
+
...content.slice(0, -1),
|
|
407
|
+
{
|
|
408
|
+
...lastContent,
|
|
409
|
+
text: lastContent.text + event.delta,
|
|
410
|
+
},
|
|
411
|
+
]
|
|
412
|
+
: [
|
|
413
|
+
...content,
|
|
414
|
+
{
|
|
415
|
+
type: "text",
|
|
416
|
+
text: event.delta,
|
|
417
|
+
},
|
|
418
|
+
];
|
|
419
|
+
const updatedMessage = {
|
|
420
|
+
...message,
|
|
421
|
+
content: updatedContent,
|
|
422
|
+
};
|
|
423
|
+
return updateThreadMessages(threadState, updateMessageAtIndex(messages, messageIndex, updatedMessage));
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Handle TEXT_MESSAGE_END event.
|
|
427
|
+
* Marks the message as complete.
|
|
428
|
+
* @param threadState - Current thread state
|
|
429
|
+
* @param event - Text message end event
|
|
430
|
+
* @returns Updated thread state
|
|
431
|
+
*/
|
|
432
|
+
function handleTextMessageEnd(threadState, event) {
|
|
433
|
+
const activeMessageId = threadState.streaming.messageId;
|
|
434
|
+
if (activeMessageId && event.messageId !== activeMessageId) {
|
|
435
|
+
throw new Error(`TEXT_MESSAGE_END messageId mismatch (thread ${threadState.thread.id}): expected ${activeMessageId}, got ${event.messageId}`);
|
|
436
|
+
}
|
|
437
|
+
return {
|
|
438
|
+
...threadState,
|
|
439
|
+
streaming: {
|
|
440
|
+
...threadState.streaming,
|
|
441
|
+
messageId: undefined,
|
|
442
|
+
},
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Handle TOOL_CALL_START event.
|
|
447
|
+
* Adds a tool use content block to the current message.
|
|
448
|
+
* @param threadState - Current thread state
|
|
449
|
+
* @param event - Tool call start event
|
|
450
|
+
* @returns Updated thread state
|
|
451
|
+
*/
|
|
452
|
+
function handleToolCallStart(threadState, event) {
|
|
453
|
+
const messageId = event.parentMessageId;
|
|
454
|
+
const messages = threadState.thread.messages;
|
|
455
|
+
// If no parent message ID, use the last message
|
|
456
|
+
const messageIndex = messageId
|
|
457
|
+
? messages.findIndex((m) => m.id === messageId)
|
|
458
|
+
: messages.length - 1;
|
|
459
|
+
if (messageIndex === -1) {
|
|
460
|
+
throw new Error(messageId
|
|
461
|
+
? `Message ${messageId} not found for TOOL_CALL_START event`
|
|
462
|
+
: `No messages exist for TOOL_CALL_START event`);
|
|
463
|
+
}
|
|
464
|
+
const message = messages[messageIndex];
|
|
465
|
+
const newContent = {
|
|
466
|
+
type: "tool_use",
|
|
467
|
+
id: event.toolCallId,
|
|
468
|
+
name: event.toolCallName,
|
|
469
|
+
input: {},
|
|
470
|
+
};
|
|
471
|
+
const updatedMessage = {
|
|
472
|
+
...message,
|
|
473
|
+
content: [...message.content, newContent],
|
|
474
|
+
};
|
|
475
|
+
return updateThreadMessages(threadState, updateMessageAtIndex(messages, messageIndex, updatedMessage));
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Handle TOOL_CALL_ARGS event.
|
|
479
|
+
* Accumulates JSON string deltas for tool call arguments.
|
|
480
|
+
* The accumulated string will be parsed at TOOL_CALL_END.
|
|
481
|
+
* @param threadState - Current thread state
|
|
482
|
+
* @param event - Tool call args event
|
|
483
|
+
* @returns Updated thread state
|
|
484
|
+
*/
|
|
485
|
+
function handleToolCallArgs(threadState, event) {
|
|
486
|
+
const toolCallId = event.toolCallId;
|
|
487
|
+
// Accumulate the JSON string delta
|
|
488
|
+
const accumulatedArgs = threadState.accumulatingToolArgs;
|
|
489
|
+
const existingArgs = accumulatedArgs.get(toolCallId) ?? "";
|
|
490
|
+
const newAccumulatedArgs = new Map(accumulatedArgs);
|
|
491
|
+
newAccumulatedArgs.set(toolCallId, existingArgs + event.delta);
|
|
492
|
+
return {
|
|
493
|
+
...threadState,
|
|
494
|
+
accumulatingToolArgs: newAccumulatedArgs,
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Handle TOOL_CALL_END event.
|
|
499
|
+
* Parses the accumulated JSON arguments and updates the tool_use content block.
|
|
500
|
+
* @param threadState - Current thread state
|
|
501
|
+
* @param event - Tool call end event
|
|
502
|
+
* @returns Updated thread state
|
|
503
|
+
*/
|
|
504
|
+
function handleToolCallEnd(threadState, event) {
|
|
505
|
+
const toolCallId = event.toolCallId;
|
|
506
|
+
const messages = threadState.thread.messages;
|
|
507
|
+
// Get accumulated JSON args string
|
|
508
|
+
const accumulatedJson = threadState.accumulatingToolArgs.get(toolCallId);
|
|
509
|
+
if (!accumulatedJson) {
|
|
510
|
+
// No args accumulated - tool call has empty input
|
|
511
|
+
return threadState;
|
|
512
|
+
}
|
|
513
|
+
// Parse the accumulated JSON
|
|
514
|
+
let parsedInput;
|
|
515
|
+
try {
|
|
516
|
+
parsedInput = JSON.parse(accumulatedJson);
|
|
517
|
+
}
|
|
518
|
+
catch (error) {
|
|
519
|
+
throw new Error(`Failed to parse tool call arguments for ${toolCallId}: ${error instanceof Error ? error.message : String(error)}. JSON: ${accumulatedJson}`);
|
|
520
|
+
}
|
|
521
|
+
// Find the tool_use content block
|
|
522
|
+
const { messageIndex, contentIndex } = findContentById(messages, "tool_use", toolCallId, "TOOL_CALL_END event");
|
|
523
|
+
const message = messages[messageIndex];
|
|
524
|
+
const toolUseContent = message.content[contentIndex];
|
|
525
|
+
if (toolUseContent.type !== "tool_use") {
|
|
526
|
+
throw new Error(`Content at index ${contentIndex} is not a tool_use block for TOOL_CALL_END event`);
|
|
527
|
+
}
|
|
528
|
+
// Update the tool_use content with parsed input
|
|
529
|
+
const updatedContent = {
|
|
530
|
+
...toolUseContent,
|
|
531
|
+
input: parsedInput,
|
|
532
|
+
};
|
|
533
|
+
const updatedMessage = {
|
|
534
|
+
...message,
|
|
535
|
+
content: updateContentAtIndex(message.content, contentIndex, updatedContent),
|
|
536
|
+
};
|
|
537
|
+
// Clear accumulated args for this tool call
|
|
538
|
+
const newAccumulatingToolArgs = new Map(threadState.accumulatingToolArgs);
|
|
539
|
+
newAccumulatingToolArgs.delete(toolCallId);
|
|
540
|
+
return {
|
|
541
|
+
...updateThreadMessages(threadState, updateMessageAtIndex(messages, messageIndex, updatedMessage)),
|
|
542
|
+
accumulatingToolArgs: newAccumulatingToolArgs,
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Handle TOOL_CALL_RESULT event.
|
|
547
|
+
* Adds tool result to the message.
|
|
548
|
+
* @param threadState - Current thread state
|
|
549
|
+
* @param event - Tool call result event
|
|
550
|
+
* @returns Updated thread state
|
|
551
|
+
*/
|
|
552
|
+
function handleToolCallResult(threadState, event) {
|
|
553
|
+
const messageId = event.messageId;
|
|
554
|
+
const messages = threadState.thread.messages;
|
|
555
|
+
// Find the message
|
|
556
|
+
const messageIndex = messages.findIndex((m) => m.id === messageId);
|
|
557
|
+
if (messageIndex === -1) {
|
|
558
|
+
throw new Error(`Message ${messageId} not found for TOOL_CALL_RESULT event`);
|
|
559
|
+
}
|
|
560
|
+
const message = messages[messageIndex];
|
|
561
|
+
// Add tool result content
|
|
562
|
+
const newContent = {
|
|
563
|
+
type: "tool_result",
|
|
564
|
+
toolUseId: event.toolCallId,
|
|
565
|
+
content: [
|
|
566
|
+
{
|
|
567
|
+
type: "text",
|
|
568
|
+
text: event.content,
|
|
569
|
+
},
|
|
570
|
+
],
|
|
571
|
+
};
|
|
572
|
+
const updatedMessage = {
|
|
573
|
+
...message,
|
|
574
|
+
content: [...message.content, newContent],
|
|
575
|
+
};
|
|
576
|
+
return updateThreadMessages(threadState, updateMessageAtIndex(messages, messageIndex, updatedMessage));
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Handle custom events (Tambo-specific).
|
|
580
|
+
* @param threadState - Current thread state
|
|
581
|
+
* @param event - Custom event (already narrowed from AGUIEvent)
|
|
582
|
+
* @returns Updated thread state
|
|
583
|
+
*/
|
|
584
|
+
function handleCustomEvent(threadState, event) {
|
|
585
|
+
// Use centralized casting function to get properly typed Tambo event
|
|
586
|
+
const customEvent = asTamboCustomEvent(event);
|
|
587
|
+
if (!customEvent) {
|
|
588
|
+
// Unknown custom event - log and return unchanged
|
|
589
|
+
console.warn(`[StreamReducer] Unknown custom event name: ${event.name}`);
|
|
590
|
+
return threadState;
|
|
591
|
+
}
|
|
592
|
+
switch (customEvent.name) {
|
|
593
|
+
case "tambo.component.start":
|
|
594
|
+
return handleComponentStart(threadState, customEvent);
|
|
595
|
+
case "tambo.component.props_delta":
|
|
596
|
+
return handleComponentDelta(threadState, customEvent, "props");
|
|
597
|
+
case "tambo.component.state_delta":
|
|
598
|
+
return handleComponentDelta(threadState, customEvent, "state");
|
|
599
|
+
case "tambo.component.end":
|
|
600
|
+
return handleComponentEnd(threadState, customEvent);
|
|
601
|
+
case "tambo.run.awaiting_input":
|
|
602
|
+
return handleRunAwaitingInput(threadState, customEvent);
|
|
603
|
+
default: {
|
|
604
|
+
// Exhaustiveness check: if a new event type is added to TamboCustomEvent
|
|
605
|
+
// and not handled here, TypeScript will error
|
|
606
|
+
const _exhaustiveCheck = customEvent;
|
|
607
|
+
throw new UnreachableCaseError(_exhaustiveCheck);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Handle tambo.component.start event.
|
|
613
|
+
* Adds a component content block to the message.
|
|
614
|
+
* @param threadState - Current thread state
|
|
615
|
+
* @param event - Component start event
|
|
616
|
+
* @returns Updated thread state
|
|
617
|
+
*/
|
|
618
|
+
function handleComponentStart(threadState, event) {
|
|
619
|
+
const messageId = event.value.messageId;
|
|
620
|
+
const messages = threadState.thread.messages;
|
|
621
|
+
// Find the message
|
|
622
|
+
const messageIndex = messages.findIndex((m) => m.id === messageId);
|
|
623
|
+
if (messageIndex === -1) {
|
|
624
|
+
throw new Error(`Message ${messageId} not found for tambo.component.start event`);
|
|
625
|
+
}
|
|
626
|
+
const message = messages[messageIndex];
|
|
627
|
+
// Add component content block
|
|
628
|
+
const newContent = {
|
|
629
|
+
type: "component",
|
|
630
|
+
id: event.value.componentId,
|
|
631
|
+
name: event.value.componentName,
|
|
632
|
+
props: {},
|
|
633
|
+
};
|
|
634
|
+
const updatedMessage = {
|
|
635
|
+
...message,
|
|
636
|
+
content: [...message.content, newContent],
|
|
637
|
+
};
|
|
638
|
+
return updateThreadMessages(threadState, updateMessageAtIndex(messages, messageIndex, updatedMessage));
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Handle component delta events (both props_delta and state_delta).
|
|
642
|
+
* Applies JSON Patch to the specified field.
|
|
643
|
+
* @param threadState - Current thread state
|
|
644
|
+
* @param event - Component delta event (props or state)
|
|
645
|
+
* @param field - Which field to update ('props' or 'state')
|
|
646
|
+
* @returns Updated thread state
|
|
647
|
+
*/
|
|
648
|
+
function handleComponentDelta(threadState, event, field) {
|
|
649
|
+
const componentId = event.value.componentId;
|
|
650
|
+
const operations = event.value.operations;
|
|
651
|
+
const messages = threadState.thread.messages;
|
|
652
|
+
const eventName = `tambo.component.${field}_delta`;
|
|
653
|
+
// Find the component content block
|
|
654
|
+
const { messageIndex, contentIndex } = findContentById(messages, "component", componentId, `${eventName} event`);
|
|
655
|
+
const message = messages[messageIndex];
|
|
656
|
+
const componentContent = message.content[contentIndex];
|
|
657
|
+
if (componentContent.type !== "component") {
|
|
658
|
+
throw new Error(`Content at index ${contentIndex} is not a component block for ${eventName} event`);
|
|
659
|
+
}
|
|
660
|
+
// Get current value (state defaults to {} if undefined)
|
|
661
|
+
const currentValue = field === "props"
|
|
662
|
+
? componentContent.props
|
|
663
|
+
: (componentContent.state ?? {});
|
|
664
|
+
// Apply JSON Patch
|
|
665
|
+
const updatedValue = applyJsonPatch(currentValue, operations);
|
|
666
|
+
const updatedContent = {
|
|
667
|
+
...componentContent,
|
|
668
|
+
[field]: updatedValue,
|
|
669
|
+
};
|
|
670
|
+
const updatedMessage = {
|
|
671
|
+
...message,
|
|
672
|
+
content: updateContentAtIndex(message.content, contentIndex, updatedContent),
|
|
673
|
+
};
|
|
674
|
+
return updateThreadMessages(threadState, updateMessageAtIndex(messages, messageIndex, updatedMessage));
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Handle tambo.component.end event.
|
|
678
|
+
* Marks component as complete.
|
|
679
|
+
* @param threadState - Current thread state
|
|
680
|
+
* @param _event - Component end event (unused)
|
|
681
|
+
* @returns Updated thread state
|
|
682
|
+
*/
|
|
683
|
+
function handleComponentEnd(threadState, _event) {
|
|
684
|
+
// For now, this doesn't change state
|
|
685
|
+
return threadState;
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Handle tambo.run.awaiting_input event.
|
|
689
|
+
* Sets thread status to waiting for client-side tool execution.
|
|
690
|
+
* @param threadState - Current thread state
|
|
691
|
+
* @param _event - Run awaiting input event (unused)
|
|
692
|
+
* @returns Updated thread state
|
|
693
|
+
*/
|
|
694
|
+
function handleRunAwaitingInput(threadState, _event) {
|
|
695
|
+
return {
|
|
696
|
+
...threadState,
|
|
697
|
+
thread: {
|
|
698
|
+
...threadState.thread,
|
|
699
|
+
status: "waiting",
|
|
700
|
+
updatedAt: new Date().toISOString(),
|
|
701
|
+
},
|
|
702
|
+
streaming: {
|
|
703
|
+
...threadState.streaming,
|
|
704
|
+
status: "waiting",
|
|
705
|
+
},
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
//# sourceMappingURL=event-accumulator.js.map
|