@tambo-ai/react 0.67.1 → 0.69.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 +3 -5
- package/dist/context-helpers/context-helpers.test.js +16 -4
- package/dist/context-helpers/context-helpers.test.js.map +1 -1
- package/dist/context-helpers/current-interactables-context-helper.d.ts +2 -2
- package/dist/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
- package/dist/context-helpers/current-interactables-context-helper.js +31 -12
- package/dist/context-helpers/current-interactables-context-helper.js.map +1 -1
- package/dist/context-helpers/registry.d.ts +2 -2
- package/dist/context-helpers/registry.d.ts.map +1 -1
- package/dist/context-helpers/registry.js.map +1 -1
- package/dist/context-helpers/types.d.ts +2 -2
- package/dist/context-helpers/types.d.ts.map +1 -1
- package/dist/context-helpers/types.js.map +1 -1
- package/dist/hoc/with-tambo-interactable.d.ts +50 -4
- package/dist/hoc/with-tambo-interactable.d.ts.map +1 -1
- package/dist/hoc/with-tambo-interactable.js +20 -5
- package/dist/hoc/with-tambo-interactable.js.map +1 -1
- package/dist/hooks/use-component-state.d.ts +3 -8
- package/dist/hooks/use-component-state.d.ts.map +1 -1
- package/dist/hooks/use-component-state.js +8 -0
- package/dist/hooks/use-component-state.js.map +1 -1
- package/dist/hooks/use-component-state.test.js +37 -0
- package/dist/hooks/use-component-state.test.js.map +1 -1
- package/dist/hooks/use-message-images.test.js +174 -37
- package/dist/hooks/use-message-images.test.js.map +1 -1
- package/dist/hooks/use-tambo-threads.js +1 -1
- package/dist/hooks/use-tambo-threads.js.map +1 -1
- package/dist/hooks/use-tambo-voice.d.ts +1 -1
- package/dist/hooks/use-tambo-voice.js +1 -1
- package/dist/hooks/use-tambo-voice.js.map +1 -1
- package/dist/hooks/use-tambo-voice.test.d.ts +2 -0
- package/dist/hooks/use-tambo-voice.test.d.ts.map +1 -0
- package/dist/hooks/use-tambo-voice.test.js +239 -0
- package/dist/hooks/use-tambo-voice.test.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/elicitation.d.ts.map +1 -1
- package/dist/mcp/elicitation.js +12 -0
- package/dist/mcp/elicitation.js.map +1 -1
- package/dist/mcp/elicitation.test.js +8 -1
- package/dist/mcp/elicitation.test.js.map +1 -1
- package/dist/mcp/mcp-client.d.ts +6 -10
- package/dist/mcp/mcp-client.d.ts.map +1 -1
- package/dist/mcp/mcp-client.js.map +1 -1
- package/dist/mcp/mcp-constants.d.ts +19 -0
- package/dist/mcp/mcp-constants.d.ts.map +1 -0
- package/dist/mcp/mcp-constants.js +21 -0
- package/dist/mcp/mcp-constants.js.map +1 -0
- package/dist/mcp/mcp-hooks.d.ts +21 -40
- package/dist/mcp/mcp-hooks.d.ts.map +1 -1
- package/dist/mcp/mcp-hooks.js +130 -39
- package/dist/mcp/mcp-hooks.js.map +1 -1
- package/dist/mcp/mcp-hooks.test.js +431 -5
- package/dist/mcp/mcp-hooks.test.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.d.ts +7 -0
- package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/dist/mcp/tambo-mcp-provider.js +205 -155
- package/dist/mcp/tambo-mcp-provider.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.test.js +37 -0
- package/dist/mcp/tambo-mcp-provider.test.js.map +1 -1
- package/dist/model/component-metadata.d.ts +54 -21
- package/dist/model/component-metadata.d.ts.map +1 -1
- package/dist/model/component-metadata.js.map +1 -1
- package/dist/model/tambo-interactable.d.ts +13 -5
- package/dist/model/tambo-interactable.d.ts.map +1 -1
- package/dist/model/tambo-interactable.js.map +1 -1
- package/dist/providers/__tests__/thread-input-resource-resolution.test.d.ts +2 -0
- package/dist/providers/__tests__/thread-input-resource-resolution.test.d.ts.map +1 -0
- package/dist/providers/__tests__/thread-input-resource-resolution.test.js +592 -0
- package/dist/providers/__tests__/thread-input-resource-resolution.test.js.map +1 -0
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/tambo-client-provider.d.ts +8 -0
- package/dist/providers/tambo-client-provider.d.ts.map +1 -1
- package/dist/providers/tambo-client-provider.js +10 -11
- package/dist/providers/tambo-client-provider.js.map +1 -1
- package/dist/providers/tambo-client-provider.test.d.ts +2 -0
- package/dist/providers/tambo-client-provider.test.d.ts.map +1 -0
- package/dist/providers/tambo-client-provider.test.js +208 -0
- package/dist/providers/tambo-client-provider.test.js.map +1 -0
- package/dist/providers/tambo-context-attachment-provider.d.ts +34 -92
- package/dist/providers/tambo-context-attachment-provider.d.ts.map +1 -1
- package/dist/providers/tambo-context-attachment-provider.js +62 -105
- package/dist/providers/tambo-context-attachment-provider.js.map +1 -1
- package/dist/providers/tambo-context-attachment-provider.test.js +229 -463
- package/dist/providers/tambo-context-attachment-provider.test.js.map +1 -1
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js +22 -21
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.d.ts +5 -2
- package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/dist/providers/tambo-interactable-provider.js +126 -17
- package/dist/providers/tambo-interactable-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.test.js +242 -0
- package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
- package/dist/providers/tambo-interactables-additional-context.test.js +2 -5
- package/dist/providers/tambo-interactables-additional-context.test.js.map +1 -1
- package/dist/providers/tambo-provider.d.ts +2 -3
- package/dist/providers/tambo-provider.d.ts.map +1 -1
- package/dist/providers/tambo-provider.js +6 -5
- package/dist/providers/tambo-provider.js.map +1 -1
- package/dist/providers/tambo-registry-provider.test.js +16 -0
- package/dist/providers/tambo-registry-provider.test.js.map +1 -1
- package/dist/providers/tambo-registry-schema-compat.test.js +31 -0
- package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -1
- package/dist/providers/tambo-thread-input-provider.d.ts +1 -1
- package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-input-provider.js +26 -4
- package/dist/providers/tambo-thread-input-provider.js.map +1 -1
- package/dist/providers/tambo-thread-provider-initial-messages.test.js +84 -2
- 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 +53 -42
- package/dist/providers/tambo-thread-provider.js.map +1 -1
- package/dist/providers/tambo-thread-provider.test.js +368 -262
- package/dist/providers/tambo-thread-provider.test.js.map +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +2 -1
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/json-schema.d.ts +7 -0
- package/dist/schema/json-schema.d.ts.map +1 -1
- package/dist/schema/json-schema.js +40 -29
- package/dist/schema/json-schema.js.map +1 -1
- package/dist/schema/json-schema.test.d.ts +2 -0
- package/dist/schema/json-schema.test.d.ts.map +1 -0
- package/dist/schema/json-schema.test.js +204 -0
- package/dist/schema/json-schema.test.js.map +1 -0
- package/dist/schema/schema.test.js +237 -0
- package/dist/schema/schema.test.js.map +1 -1
- package/dist/schema/standard-schema.d.ts +1 -0
- package/dist/schema/standard-schema.d.ts.map +1 -1
- package/dist/schema/standard-schema.js +18 -13
- package/dist/schema/standard-schema.js.map +1 -1
- package/dist/schema/standard-schema.test.d.ts +2 -0
- package/dist/schema/standard-schema.test.d.ts.map +1 -0
- package/dist/schema/standard-schema.test.js +165 -0
- package/dist/schema/standard-schema.test.js.map +1 -0
- package/dist/schema/validate.test.js +149 -0
- package/dist/schema/validate.test.js.map +1 -1
- package/dist/schema/zod.d.ts +7 -4
- package/dist/schema/zod.d.ts.map +1 -1
- package/dist/schema/zod.js +65 -22
- package/dist/schema/zod.js.map +1 -1
- package/dist/schema/zod.test.js +112 -0
- package/dist/schema/zod.test.js.map +1 -1
- package/dist/setupTests.js +3 -0
- package/dist/setupTests.js.map +1 -1
- package/dist/testing/tools.d.ts +4 -1
- package/dist/testing/tools.d.ts.map +1 -1
- package/dist/testing/tools.js +6 -1
- package/dist/testing/tools.js.map +1 -1
- package/dist/util/generate-component.d.ts.map +1 -1
- package/dist/util/generate-component.js +18 -3
- package/dist/util/generate-component.js.map +1 -1
- package/dist/util/generate-component.test.d.ts +2 -0
- package/dist/util/generate-component.test.d.ts.map +1 -0
- package/dist/util/generate-component.test.js +340 -0
- package/dist/util/generate-component.test.js.map +1 -0
- package/dist/util/is-promise.d.ts +9 -0
- package/dist/util/is-promise.d.ts.map +1 -0
- package/dist/util/is-promise.js +20 -0
- package/dist/util/is-promise.js.map +1 -0
- package/dist/util/is-promise.test.d.ts +2 -0
- package/dist/util/is-promise.test.d.ts.map +1 -0
- package/dist/util/is-promise.test.js +48 -0
- package/dist/util/is-promise.test.js.map +1 -0
- package/dist/util/message-builder.d.ts +3 -1
- package/dist/util/message-builder.d.ts.map +1 -1
- package/dist/util/message-builder.js +20 -3
- package/dist/util/message-builder.js.map +1 -1
- package/dist/util/message-builder.test.js +269 -0
- package/dist/util/message-builder.test.js.map +1 -1
- package/dist/util/query-utils.test.d.ts +2 -0
- package/dist/util/query-utils.test.d.ts.map +1 -0
- package/dist/util/query-utils.test.js +382 -0
- package/dist/util/query-utils.test.js.map +1 -0
- package/dist/util/registry-validators.d.ts.map +1 -1
- package/dist/util/registry-validators.js +7 -0
- package/dist/util/registry-validators.js.map +1 -1
- package/dist/util/registry-validators.test.js +57 -0
- package/dist/util/registry-validators.test.js.map +1 -1
- package/dist/util/registry.d.ts.map +1 -1
- package/dist/util/registry.js +9 -0
- package/dist/util/registry.js.map +1 -1
- package/dist/util/registry.test.js +323 -1
- package/dist/util/registry.test.js.map +1 -1
- package/dist/util/resource-content-resolver.d.ts +20 -0
- package/dist/util/resource-content-resolver.d.ts.map +1 -0
- package/dist/util/resource-content-resolver.js +93 -0
- package/dist/util/resource-content-resolver.js.map +1 -0
- package/dist/util/resource-content-resolver.test.d.ts +2 -0
- package/dist/util/resource-content-resolver.test.d.ts.map +1 -0
- package/dist/util/resource-content-resolver.test.js +254 -0
- package/dist/util/resource-content-resolver.test.js.map +1 -0
- package/dist/util/resource-validators.test.d.ts +2 -0
- package/dist/util/resource-validators.test.d.ts.map +1 -0
- package/dist/util/resource-validators.test.js +90 -0
- package/dist/util/resource-validators.test.js.map +1 -0
- 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 +8 -8
- package/dist/util/tool-caller.js.map +1 -1
- package/dist/util/validate-component-name.test.d.ts +2 -0
- package/dist/util/validate-component-name.test.d.ts.map +1 -0
- package/dist/util/validate-component-name.test.js +35 -0
- package/dist/util/validate-component-name.test.js.map +1 -0
- package/esm/context-helpers/context-helpers.test.js +16 -4
- package/esm/context-helpers/context-helpers.test.js.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.d.ts +2 -2
- package/esm/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.js +31 -12
- package/esm/context-helpers/current-interactables-context-helper.js.map +1 -1
- package/esm/context-helpers/registry.d.ts +2 -2
- package/esm/context-helpers/registry.d.ts.map +1 -1
- package/esm/context-helpers/registry.js.map +1 -1
- package/esm/context-helpers/types.d.ts +2 -2
- package/esm/context-helpers/types.d.ts.map +1 -1
- package/esm/context-helpers/types.js.map +1 -1
- package/esm/hoc/with-tambo-interactable.d.ts +50 -4
- package/esm/hoc/with-tambo-interactable.d.ts.map +1 -1
- package/esm/hoc/with-tambo-interactable.js +20 -5
- package/esm/hoc/with-tambo-interactable.js.map +1 -1
- package/esm/hooks/use-component-state.d.ts +3 -8
- package/esm/hooks/use-component-state.d.ts.map +1 -1
- package/esm/hooks/use-component-state.js +8 -0
- package/esm/hooks/use-component-state.js.map +1 -1
- package/esm/hooks/use-component-state.test.js +37 -0
- package/esm/hooks/use-component-state.test.js.map +1 -1
- package/esm/hooks/use-message-images.test.js +174 -37
- package/esm/hooks/use-message-images.test.js.map +1 -1
- package/esm/hooks/use-tambo-threads.js +1 -1
- package/esm/hooks/use-tambo-threads.js.map +1 -1
- package/esm/hooks/use-tambo-voice.d.ts +1 -1
- package/esm/hooks/use-tambo-voice.js +1 -1
- package/esm/hooks/use-tambo-voice.js.map +1 -1
- package/esm/hooks/use-tambo-voice.test.d.ts +2 -0
- package/esm/hooks/use-tambo-voice.test.d.ts.map +1 -0
- package/esm/hooks/use-tambo-voice.test.js +234 -0
- package/esm/hooks/use-tambo-voice.test.js.map +1 -0
- package/esm/index.d.ts +2 -2
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js.map +1 -1
- package/esm/mcp/elicitation.d.ts.map +1 -1
- package/esm/mcp/elicitation.js +12 -0
- package/esm/mcp/elicitation.js.map +1 -1
- package/esm/mcp/elicitation.test.js +8 -1
- package/esm/mcp/elicitation.test.js.map +1 -1
- package/esm/mcp/mcp-client.d.ts +6 -10
- package/esm/mcp/mcp-client.d.ts.map +1 -1
- package/esm/mcp/mcp-client.js.map +1 -1
- package/esm/mcp/mcp-constants.d.ts +19 -0
- package/esm/mcp/mcp-constants.d.ts.map +1 -0
- package/esm/mcp/mcp-constants.js +18 -0
- package/esm/mcp/mcp-constants.js.map +1 -0
- package/esm/mcp/mcp-hooks.d.ts +21 -40
- package/esm/mcp/mcp-hooks.d.ts.map +1 -1
- package/esm/mcp/mcp-hooks.js +97 -40
- package/esm/mcp/mcp-hooks.js.map +1 -1
- package/esm/mcp/mcp-hooks.test.js +431 -5
- package/esm/mcp/mcp-hooks.test.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.d.ts +7 -0
- package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/esm/mcp/tambo-mcp-provider.js +204 -154
- package/esm/mcp/tambo-mcp-provider.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.test.js +37 -0
- package/esm/mcp/tambo-mcp-provider.test.js.map +1 -1
- package/esm/model/component-metadata.d.ts +54 -21
- package/esm/model/component-metadata.d.ts.map +1 -1
- package/esm/model/component-metadata.js.map +1 -1
- package/esm/model/tambo-interactable.d.ts +13 -5
- package/esm/model/tambo-interactable.d.ts.map +1 -1
- package/esm/model/tambo-interactable.js.map +1 -1
- package/esm/providers/__tests__/thread-input-resource-resolution.test.d.ts +2 -0
- package/esm/providers/__tests__/thread-input-resource-resolution.test.d.ts.map +1 -0
- package/esm/providers/__tests__/thread-input-resource-resolution.test.js +587 -0
- package/esm/providers/__tests__/thread-input-resource-resolution.test.js.map +1 -0
- package/esm/providers/index.d.ts +1 -1
- package/esm/providers/index.d.ts.map +1 -1
- package/esm/providers/index.js.map +1 -1
- package/esm/providers/tambo-client-provider.d.ts +8 -0
- package/esm/providers/tambo-client-provider.d.ts.map +1 -1
- package/esm/providers/tambo-client-provider.js +11 -12
- package/esm/providers/tambo-client-provider.js.map +1 -1
- package/esm/providers/tambo-client-provider.test.d.ts +2 -0
- package/esm/providers/tambo-client-provider.test.d.ts.map +1 -0
- package/esm/providers/tambo-client-provider.test.js +203 -0
- package/esm/providers/tambo-client-provider.test.js.map +1 -0
- package/esm/providers/tambo-context-attachment-provider.d.ts +34 -92
- package/esm/providers/tambo-context-attachment-provider.d.ts.map +1 -1
- package/esm/providers/tambo-context-attachment-provider.js +63 -106
- package/esm/providers/tambo-context-attachment-provider.js.map +1 -1
- package/esm/providers/tambo-context-attachment-provider.test.js +230 -464
- package/esm/providers/tambo-context-attachment-provider.test.js.map +1 -1
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js +22 -21
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +5 -2
- package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/esm/providers/tambo-interactable-provider.js +126 -17
- package/esm/providers/tambo-interactable-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.test.js +242 -0
- package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
- package/esm/providers/tambo-interactables-additional-context.test.js +2 -5
- package/esm/providers/tambo-interactables-additional-context.test.js.map +1 -1
- package/esm/providers/tambo-provider.d.ts +2 -3
- package/esm/providers/tambo-provider.d.ts.map +1 -1
- package/esm/providers/tambo-provider.js +6 -5
- package/esm/providers/tambo-provider.js.map +1 -1
- package/esm/providers/tambo-registry-provider.test.js +16 -0
- package/esm/providers/tambo-registry-provider.test.js.map +1 -1
- package/esm/providers/tambo-registry-schema-compat.test.js +31 -0
- package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -1
- package/esm/providers/tambo-thread-input-provider.d.ts +1 -1
- package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-input-provider.js +26 -4
- package/esm/providers/tambo-thread-input-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider-initial-messages.test.js +84 -2
- 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 +53 -42
- package/esm/providers/tambo-thread-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider.test.js +368 -262
- package/esm/providers/tambo-thread-provider.test.js.map +1 -1
- package/esm/schema/index.d.ts +1 -1
- package/esm/schema/index.d.ts.map +1 -1
- package/esm/schema/index.js +1 -1
- package/esm/schema/index.js.map +1 -1
- package/esm/schema/json-schema.d.ts +7 -0
- package/esm/schema/json-schema.d.ts.map +1 -1
- package/esm/schema/json-schema.js +11 -1
- package/esm/schema/json-schema.js.map +1 -1
- package/esm/schema/json-schema.test.d.ts +2 -0
- package/esm/schema/json-schema.test.d.ts.map +1 -0
- package/esm/schema/json-schema.test.js +202 -0
- package/esm/schema/json-schema.test.js.map +1 -0
- package/esm/schema/schema.test.js +238 -1
- package/esm/schema/schema.test.js.map +1 -1
- package/esm/schema/standard-schema.d.ts +1 -0
- package/esm/schema/standard-schema.d.ts.map +1 -1
- package/esm/schema/standard-schema.js +18 -13
- package/esm/schema/standard-schema.js.map +1 -1
- package/esm/schema/standard-schema.test.d.ts +2 -0
- package/esm/schema/standard-schema.test.d.ts.map +1 -0
- package/esm/schema/standard-schema.test.js +130 -0
- package/esm/schema/standard-schema.test.js.map +1 -0
- package/esm/schema/validate.test.js +149 -0
- package/esm/schema/validate.test.js.map +1 -1
- package/esm/schema/zod.d.ts +7 -4
- package/esm/schema/zod.d.ts.map +1 -1
- package/esm/schema/zod.js +65 -22
- package/esm/schema/zod.js.map +1 -1
- package/esm/schema/zod.test.js +113 -1
- package/esm/schema/zod.test.js.map +1 -1
- package/esm/setupTests.js +3 -0
- package/esm/setupTests.js.map +1 -1
- package/esm/testing/tools.d.ts +4 -1
- package/esm/testing/tools.d.ts.map +1 -1
- package/esm/testing/tools.js +6 -1
- package/esm/testing/tools.js.map +1 -1
- package/esm/util/generate-component.d.ts.map +1 -1
- package/esm/util/generate-component.js +18 -3
- package/esm/util/generate-component.js.map +1 -1
- package/esm/util/generate-component.test.d.ts +2 -0
- package/esm/util/generate-component.test.d.ts.map +1 -0
- package/esm/util/generate-component.test.js +302 -0
- package/esm/util/generate-component.test.js.map +1 -0
- package/esm/util/is-promise.d.ts +9 -0
- package/esm/util/is-promise.d.ts.map +1 -0
- package/esm/util/is-promise.js +17 -0
- package/esm/util/is-promise.js.map +1 -0
- package/esm/util/is-promise.test.d.ts +2 -0
- package/esm/util/is-promise.test.d.ts.map +1 -0
- package/esm/util/is-promise.test.js +46 -0
- package/esm/util/is-promise.test.js.map +1 -0
- package/esm/util/message-builder.d.ts +3 -1
- package/esm/util/message-builder.d.ts.map +1 -1
- package/esm/util/message-builder.js +20 -3
- package/esm/util/message-builder.js.map +1 -1
- package/esm/util/message-builder.test.js +269 -0
- package/esm/util/message-builder.test.js.map +1 -1
- package/esm/util/query-utils.test.d.ts +2 -0
- package/esm/util/query-utils.test.d.ts.map +1 -0
- package/esm/util/query-utils.test.js +380 -0
- package/esm/util/query-utils.test.js.map +1 -0
- package/esm/util/registry-validators.d.ts.map +1 -1
- package/esm/util/registry-validators.js +7 -0
- package/esm/util/registry-validators.js.map +1 -1
- package/esm/util/registry-validators.test.js +57 -0
- package/esm/util/registry-validators.test.js.map +1 -1
- package/esm/util/registry.d.ts.map +1 -1
- package/esm/util/registry.js +9 -0
- package/esm/util/registry.js.map +1 -1
- package/esm/util/registry.test.js +324 -2
- package/esm/util/registry.test.js.map +1 -1
- package/esm/util/resource-content-resolver.d.ts +20 -0
- package/esm/util/resource-content-resolver.d.ts.map +1 -0
- package/esm/util/resource-content-resolver.js +89 -0
- package/esm/util/resource-content-resolver.js.map +1 -0
- package/esm/util/resource-content-resolver.test.d.ts +2 -0
- package/esm/util/resource-content-resolver.test.d.ts.map +1 -0
- package/esm/util/resource-content-resolver.test.js +252 -0
- package/esm/util/resource-content-resolver.test.js.map +1 -0
- package/esm/util/resource-validators.test.d.ts +2 -0
- package/esm/util/resource-validators.test.d.ts.map +1 -0
- package/esm/util/resource-validators.test.js +88 -0
- package/esm/util/resource-validators.test.js.map +1 -0
- 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 +8 -8
- package/esm/util/tool-caller.js.map +1 -1
- package/esm/util/validate-component-name.test.d.ts +2 -0
- package/esm/util/validate-component-name.test.d.ts.map +1 -0
- package/esm/util/validate-component-name.test.js +33 -0
- package/esm/util/validate-component-name.test.js.map +1 -0
- package/package.json +15 -23
- package/dist/schema/alias.d.ts +0 -3
- package/dist/schema/alias.d.ts.map +0 -1
- package/dist/schema/alias.js +0 -6
- package/dist/schema/alias.js.map +0 -1
- package/esm/schema/alias.d.ts +0 -3
- package/esm/schema/alias.d.ts.map +0 -1
- package/esm/schema/alias.js +0 -13
- package/esm/schema/alias.js.map +0 -1
|
@@ -7,28 +7,32 @@ const react_1 = require("@testing-library/react");
|
|
|
7
7
|
const react_2 = __importDefault(require("react"));
|
|
8
8
|
const tambo_context_attachment_provider_1 = require("./tambo-context-attachment-provider");
|
|
9
9
|
const tambo_context_helpers_provider_1 = require("./tambo-context-helpers-provider");
|
|
10
|
+
// Mock the context helpers provider
|
|
11
|
+
jest.mock("./tambo-context-helpers-provider");
|
|
12
|
+
const mockAddContextHelper = jest.fn();
|
|
13
|
+
const mockRemoveContextHelper = jest.fn();
|
|
14
|
+
const CONTEXT_ATTACHMENTS_HELPER_KEY = "contextAttachments";
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
jest.clearAllMocks();
|
|
17
|
+
tambo_context_helpers_provider_1.useTamboContextHelpers.mockReturnValue({
|
|
18
|
+
addContextHelper: mockAddContextHelper,
|
|
19
|
+
removeContextHelper: mockRemoveContextHelper,
|
|
20
|
+
});
|
|
21
|
+
});
|
|
10
22
|
/**
|
|
11
23
|
* Test suite for TamboContextAttachmentProvider
|
|
12
24
|
*
|
|
13
25
|
* Tests the context attachment feature which allows:
|
|
14
|
-
* -
|
|
15
|
-
* - Automatic context
|
|
16
|
-
* - Custom suggestions that override auto-generated ones
|
|
17
|
-
* - Dynamic context data customization via getContextHelperData
|
|
26
|
+
* - Adding context attachments that will be sent with the next message
|
|
27
|
+
* - Automatic registration/deregistration of context helpers
|
|
18
28
|
*/
|
|
19
29
|
describe("TamboContextAttachmentProvider", () => {
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
jest.clearAllMocks();
|
|
22
|
-
});
|
|
23
30
|
/**
|
|
24
|
-
* Base wrapper with
|
|
25
|
-
*
|
|
26
|
-
* @param getContextHelperData - Optional custom function to get context helper data
|
|
27
|
-
* @returns A React component that wraps children with the necessary providers
|
|
31
|
+
* Base wrapper with TamboContextAttachmentProvider
|
|
32
|
+
* @returns A React component that wraps children with the provider
|
|
28
33
|
*/
|
|
29
|
-
const createWrapper = (
|
|
30
|
-
const Wrapper = ({ children }) => (react_2.default.createElement(
|
|
31
|
-
react_2.default.createElement(tambo_context_attachment_provider_1.TamboContextAttachmentProvider, { getContextHelperData: getContextHelperData }, children)));
|
|
34
|
+
const createWrapper = () => {
|
|
35
|
+
const Wrapper = ({ children }) => (react_2.default.createElement(tambo_context_attachment_provider_1.TamboContextAttachmentProvider, null, children));
|
|
32
36
|
Wrapper.displayName = "TestWrapper";
|
|
33
37
|
return Wrapper;
|
|
34
38
|
};
|
|
@@ -44,8 +48,6 @@ describe("TamboContextAttachmentProvider", () => {
|
|
|
44
48
|
expect(result.current).toHaveProperty("addContextAttachment");
|
|
45
49
|
expect(result.current).toHaveProperty("removeContextAttachment");
|
|
46
50
|
expect(result.current).toHaveProperty("clearContextAttachments");
|
|
47
|
-
expect(result.current).toHaveProperty("customSuggestions");
|
|
48
|
-
expect(result.current).toHaveProperty("setCustomSuggestions");
|
|
49
51
|
});
|
|
50
52
|
/**
|
|
51
53
|
* Hook should throw error when used outside of provider
|
|
@@ -63,154 +65,318 @@ describe("TamboContextAttachmentProvider", () => {
|
|
|
63
65
|
});
|
|
64
66
|
describe("Adding Context Attachments", () => {
|
|
65
67
|
/**
|
|
66
|
-
* Should add a context attachment
|
|
68
|
+
* Should add a context attachment and register/update the merged context helper
|
|
67
69
|
*/
|
|
68
|
-
it("should add a context attachment", () => {
|
|
70
|
+
it("should add a context attachment", async () => {
|
|
69
71
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
70
72
|
wrapper: createWrapper(),
|
|
71
73
|
});
|
|
74
|
+
let attachment;
|
|
72
75
|
(0, react_1.act)(() => {
|
|
73
|
-
result.current.addContextAttachment({
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
attachment = result.current.addContextAttachment({
|
|
77
|
+
context: "selectedFile",
|
|
78
|
+
displayName: "Button.tsx",
|
|
79
|
+
type: "file",
|
|
76
80
|
});
|
|
77
81
|
});
|
|
78
82
|
expect(result.current.attachments).toHaveLength(1);
|
|
79
83
|
expect(result.current.attachments[0]).toMatchObject({
|
|
80
|
-
|
|
81
|
-
|
|
84
|
+
displayName: "Button.tsx",
|
|
85
|
+
context: "selectedFile",
|
|
86
|
+
type: "file",
|
|
82
87
|
});
|
|
83
88
|
expect(result.current.attachments[0].id).toBeDefined();
|
|
89
|
+
expect(attachment.id).toBe(result.current.attachments[0].id);
|
|
90
|
+
// Wait for useEffect to run and register the merged helper with the attachment
|
|
91
|
+
await (0, react_1.waitFor)(() => {
|
|
92
|
+
const lastCall = mockAddContextHelper.mock.calls
|
|
93
|
+
.filter((call) => call[0] === CONTEXT_ATTACHMENTS_HELPER_KEY)
|
|
94
|
+
.pop();
|
|
95
|
+
if (lastCall) {
|
|
96
|
+
const helperFn = lastCall[1];
|
|
97
|
+
const helperResult = helperFn();
|
|
98
|
+
expect(helperResult).not.toBeNull();
|
|
99
|
+
expect(helperResult).toHaveLength(1);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
throw new Error("Helper not registered");
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
// Verify the helper function returns the merged attachments array
|
|
106
|
+
const helperFn = mockAddContextHelper.mock.calls
|
|
107
|
+
.filter((call) => call[0] === CONTEXT_ATTACHMENTS_HELPER_KEY)
|
|
108
|
+
.pop()?.[1];
|
|
109
|
+
expect(helperFn).toBeDefined();
|
|
110
|
+
const helperResult = helperFn();
|
|
111
|
+
expect(helperResult).toEqual([
|
|
112
|
+
{
|
|
113
|
+
id: attachment.id,
|
|
114
|
+
displayName: "Button.tsx",
|
|
115
|
+
context: "selectedFile",
|
|
116
|
+
type: "file",
|
|
117
|
+
},
|
|
118
|
+
]);
|
|
84
119
|
});
|
|
85
120
|
/**
|
|
86
|
-
* Should add
|
|
121
|
+
* Should add a context attachment without displayName
|
|
87
122
|
*/
|
|
88
|
-
it("should add
|
|
123
|
+
it("should add a context attachment without displayName", () => {
|
|
124
|
+
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
125
|
+
wrapper: createWrapper(),
|
|
126
|
+
});
|
|
127
|
+
let attachment;
|
|
128
|
+
(0, react_1.act)(() => {
|
|
129
|
+
attachment = result.current.addContextAttachment({
|
|
130
|
+
context: "selectedFile",
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
expect(result.current.attachments).toHaveLength(1);
|
|
134
|
+
expect(result.current.attachments[0]).toMatchObject({
|
|
135
|
+
context: "selectedFile",
|
|
136
|
+
});
|
|
137
|
+
expect(result.current.attachments[0].displayName).toBeUndefined();
|
|
138
|
+
expect(attachment.id).toBe(result.current.attachments[0].id);
|
|
139
|
+
});
|
|
140
|
+
/**
|
|
141
|
+
* Should add multiple different context attachments and update the merged helper
|
|
142
|
+
*/
|
|
143
|
+
it("should add multiple context attachments", async () => {
|
|
89
144
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
90
145
|
wrapper: createWrapper(),
|
|
91
146
|
});
|
|
92
147
|
(0, react_1.act)(() => {
|
|
93
148
|
result.current.addContextAttachment({
|
|
94
|
-
|
|
149
|
+
context: "file1",
|
|
150
|
+
displayName: "Button.tsx",
|
|
151
|
+
type: "file",
|
|
95
152
|
});
|
|
96
153
|
result.current.addContextAttachment({
|
|
97
|
-
|
|
154
|
+
context: "file2",
|
|
155
|
+
displayName: "Card.tsx",
|
|
156
|
+
type: "file",
|
|
98
157
|
});
|
|
99
158
|
});
|
|
100
159
|
expect(result.current.attachments).toHaveLength(2);
|
|
101
|
-
expect(result.current.attachments[0].
|
|
102
|
-
expect(result.current.attachments[1].
|
|
160
|
+
expect(result.current.attachments[0].displayName).toBe("Button.tsx");
|
|
161
|
+
expect(result.current.attachments[1].displayName).toBe("Card.tsx");
|
|
162
|
+
// Wait for useEffect to run and update the merged helper
|
|
163
|
+
await (0, react_1.waitFor)(() => {
|
|
164
|
+
// The helper should be called/updated for each attachment change
|
|
165
|
+
expect(mockAddContextHelper).toHaveBeenCalledWith(CONTEXT_ATTACHMENTS_HELPER_KEY, expect.any(Function));
|
|
166
|
+
});
|
|
167
|
+
// Verify the helper function returns all attachments
|
|
168
|
+
const helperFn = mockAddContextHelper.mock.calls
|
|
169
|
+
.filter((call) => call[0] === CONTEXT_ATTACHMENTS_HELPER_KEY)
|
|
170
|
+
.pop()?.[1];
|
|
171
|
+
expect(helperFn).toBeDefined();
|
|
172
|
+
const helperResult = helperFn();
|
|
173
|
+
expect(helperResult).toHaveLength(2);
|
|
174
|
+
expect(helperResult[0].displayName).toBe("Button.tsx");
|
|
175
|
+
expect(helperResult[1].displayName).toBe("Card.tsx");
|
|
103
176
|
});
|
|
104
177
|
/**
|
|
105
|
-
* Should
|
|
178
|
+
* Should allow multiple attachments with the same context value
|
|
106
179
|
*/
|
|
107
|
-
it("should
|
|
180
|
+
it("should allow multiple attachments with same context value", async () => {
|
|
108
181
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
109
182
|
wrapper: createWrapper(),
|
|
110
183
|
});
|
|
111
184
|
(0, react_1.act)(() => {
|
|
112
185
|
result.current.addContextAttachment({
|
|
113
|
-
|
|
186
|
+
context: "selectedFile",
|
|
187
|
+
displayName: "Button.tsx",
|
|
188
|
+
type: "file",
|
|
114
189
|
});
|
|
115
190
|
result.current.addContextAttachment({
|
|
116
|
-
|
|
191
|
+
context: "selectedFile",
|
|
192
|
+
displayName: "Card.tsx",
|
|
193
|
+
type: "file",
|
|
117
194
|
});
|
|
118
195
|
});
|
|
119
|
-
expect(result.current.attachments).toHaveLength(
|
|
196
|
+
expect(result.current.attachments).toHaveLength(2);
|
|
197
|
+
// Wait for useEffect to update the merged helper
|
|
198
|
+
await (0, react_1.waitFor)(() => {
|
|
199
|
+
expect(mockAddContextHelper).toHaveBeenCalledWith(CONTEXT_ATTACHMENTS_HELPER_KEY, expect.any(Function));
|
|
200
|
+
});
|
|
201
|
+
// Verify both attachments are included in the merged result
|
|
202
|
+
const helperFn = mockAddContextHelper.mock.calls
|
|
203
|
+
.filter((call) => call[0] === CONTEXT_ATTACHMENTS_HELPER_KEY)
|
|
204
|
+
.pop()?.[1];
|
|
205
|
+
expect(helperFn).toBeDefined();
|
|
206
|
+
const helperResult = helperFn();
|
|
207
|
+
expect(helperResult).toHaveLength(2);
|
|
120
208
|
});
|
|
121
209
|
/**
|
|
122
|
-
* Should support optional
|
|
210
|
+
* Should support optional type property
|
|
123
211
|
*/
|
|
124
|
-
it("should support
|
|
212
|
+
it("should support optional type property", () => {
|
|
125
213
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
126
214
|
wrapper: createWrapper(),
|
|
127
215
|
});
|
|
128
|
-
const icon = react_2.default.createElement("span", null, "\uD83D\uDCC4");
|
|
129
216
|
(0, react_1.act)(() => {
|
|
130
217
|
result.current.addContextAttachment({
|
|
131
|
-
|
|
132
|
-
|
|
218
|
+
context: "file1",
|
|
219
|
+
displayName: "Button.tsx",
|
|
220
|
+
type: "file",
|
|
221
|
+
});
|
|
222
|
+
result.current.addContextAttachment({
|
|
223
|
+
context: "page1",
|
|
224
|
+
displayName: "Dashboard",
|
|
225
|
+
type: "page",
|
|
133
226
|
});
|
|
134
227
|
});
|
|
135
|
-
expect(result.current.attachments[0].
|
|
228
|
+
expect(result.current.attachments[0].type).toBe("file");
|
|
229
|
+
expect(result.current.attachments[1].type).toBe("page");
|
|
136
230
|
});
|
|
137
231
|
});
|
|
138
232
|
describe("Removing Context Attachments", () => {
|
|
139
233
|
/**
|
|
140
|
-
* Should remove a specific attachment by ID
|
|
234
|
+
* Should remove a specific context attachment by ID and update the merged helper
|
|
141
235
|
*/
|
|
142
|
-
it("should remove context attachment by ID", () => {
|
|
236
|
+
it("should remove context attachment by ID", async () => {
|
|
143
237
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
144
238
|
wrapper: createWrapper(),
|
|
145
239
|
});
|
|
240
|
+
let attachmentId = "";
|
|
146
241
|
(0, react_1.act)(() => {
|
|
147
|
-
result.current.addContextAttachment({
|
|
148
|
-
|
|
242
|
+
const attachment = result.current.addContextAttachment({
|
|
243
|
+
context: "selectedFile",
|
|
244
|
+
displayName: "Button.tsx",
|
|
149
245
|
});
|
|
246
|
+
attachmentId = attachment.id;
|
|
150
247
|
});
|
|
151
248
|
expect(result.current.attachments).toHaveLength(1);
|
|
152
|
-
|
|
249
|
+
// Wait for initial helper registration
|
|
250
|
+
await (0, react_1.waitFor)(() => {
|
|
251
|
+
expect(mockAddContextHelper).toHaveBeenCalledWith(CONTEXT_ATTACHMENTS_HELPER_KEY, expect.any(Function));
|
|
252
|
+
});
|
|
153
253
|
(0, react_1.act)(() => {
|
|
154
254
|
result.current.removeContextAttachment(attachmentId);
|
|
155
255
|
});
|
|
156
256
|
expect(result.current.attachments).toHaveLength(0);
|
|
257
|
+
// Wait for useEffect to update the helper (should return null when empty)
|
|
258
|
+
await (0, react_1.waitFor)(() => {
|
|
259
|
+
const lastCall = mockAddContextHelper.mock.calls
|
|
260
|
+
.filter((call) => call[0] === CONTEXT_ATTACHMENTS_HELPER_KEY)
|
|
261
|
+
.pop();
|
|
262
|
+
if (lastCall) {
|
|
263
|
+
const helperFn = lastCall[1];
|
|
264
|
+
expect(helperFn()).toBeNull();
|
|
265
|
+
}
|
|
266
|
+
});
|
|
157
267
|
});
|
|
158
268
|
/**
|
|
159
269
|
* Should only remove the specified attachment when multiple exist
|
|
160
270
|
*/
|
|
161
|
-
it("should only remove specified attachment", () => {
|
|
271
|
+
it("should only remove specified attachment", async () => {
|
|
162
272
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
163
273
|
wrapper: createWrapper(),
|
|
164
274
|
});
|
|
275
|
+
let firstId = "";
|
|
165
276
|
(0, react_1.act)(() => {
|
|
166
|
-
result.current.addContextAttachment({
|
|
167
|
-
|
|
277
|
+
const first = result.current.addContextAttachment({
|
|
278
|
+
context: "file1",
|
|
279
|
+
displayName: "First.tsx",
|
|
280
|
+
});
|
|
281
|
+
result.current.addContextAttachment({
|
|
282
|
+
context: "file2",
|
|
283
|
+
displayName: "Second.tsx",
|
|
284
|
+
});
|
|
285
|
+
firstId = first.id;
|
|
168
286
|
});
|
|
169
287
|
expect(result.current.attachments).toHaveLength(2);
|
|
170
|
-
|
|
288
|
+
// Wait for initial helper registration
|
|
289
|
+
await (0, react_1.waitFor)(() => {
|
|
290
|
+
expect(mockAddContextHelper).toHaveBeenCalledWith(CONTEXT_ATTACHMENTS_HELPER_KEY, expect.any(Function));
|
|
291
|
+
});
|
|
171
292
|
(0, react_1.act)(() => {
|
|
172
293
|
result.current.removeContextAttachment(firstId);
|
|
173
294
|
});
|
|
174
295
|
expect(result.current.attachments).toHaveLength(1);
|
|
175
|
-
expect(result.current.attachments[0].
|
|
296
|
+
expect(result.current.attachments[0].displayName).toBe("Second.tsx");
|
|
297
|
+
// Wait for useEffect to update the helper with remaining attachment
|
|
298
|
+
await (0, react_1.waitFor)(() => {
|
|
299
|
+
const lastCall = mockAddContextHelper.mock.calls
|
|
300
|
+
.filter((call) => call[0] === CONTEXT_ATTACHMENTS_HELPER_KEY)
|
|
301
|
+
.pop();
|
|
302
|
+
if (lastCall) {
|
|
303
|
+
const helperFn = lastCall[1];
|
|
304
|
+
const helperResult = helperFn();
|
|
305
|
+
expect(helperResult).toHaveLength(1);
|
|
306
|
+
expect(helperResult[0].displayName).toBe("Second.tsx");
|
|
307
|
+
}
|
|
308
|
+
});
|
|
176
309
|
});
|
|
177
310
|
/**
|
|
178
311
|
* Should handle removing non-existent attachment gracefully
|
|
179
312
|
*/
|
|
180
|
-
it("should handle removing non-existent attachment gracefully", () => {
|
|
313
|
+
it("should handle removing non-existent attachment gracefully", async () => {
|
|
181
314
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
182
315
|
wrapper: createWrapper(),
|
|
183
316
|
});
|
|
317
|
+
// Wait for initial helper registration (useEffect runs on mount)
|
|
318
|
+
await (0, react_1.waitFor)(() => {
|
|
319
|
+
expect(mockAddContextHelper).toHaveBeenCalledWith(CONTEXT_ATTACHMENTS_HELPER_KEY, expect.any(Function));
|
|
320
|
+
});
|
|
184
321
|
expect(() => {
|
|
185
322
|
(0, react_1.act)(() => {
|
|
186
323
|
result.current.removeContextAttachment("non-existent-id");
|
|
187
324
|
});
|
|
188
325
|
}).not.toThrow();
|
|
326
|
+
// The helper is registered on mount, so removeContextHelper will be called
|
|
327
|
+
// when the component unmounts or when attachments change, but not for
|
|
328
|
+
// removing a non-existent attachment since attachments didn't change
|
|
329
|
+
// However, the cleanup function from the initial useEffect registration
|
|
330
|
+
// may be called. Let's just verify the attachment list is still empty.
|
|
331
|
+
expect(result.current.attachments).toHaveLength(0);
|
|
189
332
|
});
|
|
190
333
|
});
|
|
191
|
-
describe("Clearing All Attachments", () => {
|
|
334
|
+
describe("Clearing All Context Attachments", () => {
|
|
192
335
|
/**
|
|
193
|
-
* Should clear all attachments
|
|
336
|
+
* Should clear all context attachments and update the merged helper to return null
|
|
194
337
|
*/
|
|
195
|
-
it("should clear all context attachments", () => {
|
|
338
|
+
it("should clear all context attachments", async () => {
|
|
196
339
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
197
340
|
wrapper: createWrapper(),
|
|
198
341
|
});
|
|
199
342
|
(0, react_1.act)(() => {
|
|
200
|
-
result.current.addContextAttachment({
|
|
201
|
-
|
|
202
|
-
|
|
343
|
+
result.current.addContextAttachment({
|
|
344
|
+
context: "file1",
|
|
345
|
+
displayName: "First.tsx",
|
|
346
|
+
});
|
|
347
|
+
result.current.addContextAttachment({
|
|
348
|
+
context: "file2",
|
|
349
|
+
displayName: "Second.tsx",
|
|
350
|
+
});
|
|
351
|
+
result.current.addContextAttachment({
|
|
352
|
+
context: "file3",
|
|
353
|
+
displayName: "Third.tsx",
|
|
354
|
+
});
|
|
203
355
|
});
|
|
204
356
|
expect(result.current.attachments).toHaveLength(3);
|
|
357
|
+
// Wait for initial helper registration
|
|
358
|
+
await (0, react_1.waitFor)(() => {
|
|
359
|
+
expect(mockAddContextHelper).toHaveBeenCalledWith(CONTEXT_ATTACHMENTS_HELPER_KEY, expect.any(Function));
|
|
360
|
+
});
|
|
205
361
|
(0, react_1.act)(() => {
|
|
206
362
|
result.current.clearContextAttachments();
|
|
207
363
|
});
|
|
208
364
|
expect(result.current.attachments).toHaveLength(0);
|
|
365
|
+
// Wait for useEffect to update the helper (should return null when empty)
|
|
366
|
+
await (0, react_1.waitFor)(() => {
|
|
367
|
+
const lastCall = mockAddContextHelper.mock.calls
|
|
368
|
+
.filter((call) => call[0] === CONTEXT_ATTACHMENTS_HELPER_KEY)
|
|
369
|
+
.pop();
|
|
370
|
+
if (lastCall) {
|
|
371
|
+
const helperFn = lastCall[1];
|
|
372
|
+
expect(helperFn()).toBeNull();
|
|
373
|
+
}
|
|
374
|
+
});
|
|
209
375
|
});
|
|
210
376
|
/**
|
|
211
377
|
* Should handle clearing when no attachments exist
|
|
212
378
|
*/
|
|
213
|
-
it("should handle clearing when no attachments exist", () => {
|
|
379
|
+
it("should handle clearing when no attachments exist", async () => {
|
|
214
380
|
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
215
381
|
wrapper: createWrapper(),
|
|
216
382
|
});
|
|
@@ -220,413 +386,13 @@ describe("TamboContextAttachmentProvider", () => {
|
|
|
220
386
|
});
|
|
221
387
|
}).not.toThrow();
|
|
222
388
|
expect(result.current.attachments).toHaveLength(0);
|
|
223
|
-
|
|
224
|
-
});
|
|
225
|
-
describe("Context Helpers Integration", () => {
|
|
226
|
-
/**
|
|
227
|
-
* Should automatically register context helpers when attachments are added
|
|
228
|
-
*/
|
|
229
|
-
it("should register context helpers for attachments", async () => {
|
|
230
|
-
const wrapper = ({ children }) => (react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, null,
|
|
231
|
-
react_2.default.createElement(tambo_context_attachment_provider_1.TamboContextAttachmentProvider, null, children)));
|
|
232
|
-
const { result } = (0, react_1.renderHook)(() => ({
|
|
233
|
-
attachment: (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(),
|
|
234
|
-
helpers: (0, tambo_context_helpers_provider_1.useTamboContextHelpers)(),
|
|
235
|
-
}), { wrapper });
|
|
236
|
-
// Add attachment
|
|
237
|
-
(0, react_1.act)(() => {
|
|
238
|
-
result.current.attachment.addContextAttachment({
|
|
239
|
-
name: "Button.tsx",
|
|
240
|
-
metadata: { filePath: "/src/Button.tsx" },
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
// Wait for effect to run
|
|
244
|
-
await (0, react_1.waitFor)(async () => {
|
|
245
|
-
const contexts = await result.current.helpers.getAdditionalContext();
|
|
246
|
-
expect(contexts.length).toBeGreaterThan(0);
|
|
247
|
-
});
|
|
248
|
-
const contexts = await result.current.helpers.getAdditionalContext();
|
|
249
|
-
const attachmentContext = contexts.find((c) => c.name.includes(result.current.attachment.attachments[0].id));
|
|
250
|
-
expect(attachmentContext).toBeDefined();
|
|
251
|
-
expect(attachmentContext?.context).toHaveProperty("selectedComponent");
|
|
252
|
-
});
|
|
253
|
-
/**
|
|
254
|
-
* Should unregister context helpers when attachments are removed
|
|
255
|
-
*/
|
|
256
|
-
it("should unregister context helpers when attachments are removed", async () => {
|
|
257
|
-
const wrapper = ({ children }) => (react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, null,
|
|
258
|
-
react_2.default.createElement(tambo_context_attachment_provider_1.TamboContextAttachmentProvider, null, children)));
|
|
259
|
-
const { result } = (0, react_1.renderHook)(() => ({
|
|
260
|
-
attachment: (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(),
|
|
261
|
-
helpers: (0, tambo_context_helpers_provider_1.useTamboContextHelpers)(),
|
|
262
|
-
}), { wrapper });
|
|
263
|
-
// Add attachment
|
|
264
|
-
(0, react_1.act)(() => {
|
|
265
|
-
result.current.attachment.addContextAttachment({
|
|
266
|
-
name: "Button.tsx",
|
|
267
|
-
});
|
|
268
|
-
});
|
|
269
|
-
// Wait for context helper to be registered
|
|
270
|
-
await (0, react_1.waitFor)(async () => {
|
|
271
|
-
const contexts = await result.current.helpers.getAdditionalContext();
|
|
272
|
-
expect(contexts.length).toBeGreaterThan(0);
|
|
273
|
-
});
|
|
274
|
-
const initialContexts = await result.current.helpers.getAdditionalContext();
|
|
275
|
-
const initialCount = initialContexts.length;
|
|
276
|
-
const attachmentId = result.current.attachment.attachments[0].id;
|
|
277
|
-
// Remove attachment
|
|
278
|
-
(0, react_1.act)(() => {
|
|
279
|
-
result.current.attachment.removeContextAttachment(attachmentId);
|
|
280
|
-
});
|
|
281
|
-
// Wait for context helper to be unregistered
|
|
282
|
-
await (0, react_1.waitFor)(async () => {
|
|
283
|
-
const contexts = await result.current.helpers.getAdditionalContext();
|
|
284
|
-
expect(contexts.length).toBeLessThan(initialCount);
|
|
285
|
-
});
|
|
286
|
-
});
|
|
287
|
-
/**
|
|
288
|
-
* Should use default context data structure when no custom function provided
|
|
289
|
-
*/
|
|
290
|
-
it("should use default context data structure", async () => {
|
|
291
|
-
const wrapper = ({ children }) => (react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, null,
|
|
292
|
-
react_2.default.createElement(tambo_context_attachment_provider_1.TamboContextAttachmentProvider, null, children)));
|
|
293
|
-
const { result } = (0, react_1.renderHook)(() => ({
|
|
294
|
-
attachment: (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(),
|
|
295
|
-
helpers: (0, tambo_context_helpers_provider_1.useTamboContextHelpers)(),
|
|
296
|
-
}), { wrapper });
|
|
297
|
-
(0, react_1.act)(() => {
|
|
298
|
-
result.current.attachment.addContextAttachment({
|
|
299
|
-
name: "Button.tsx",
|
|
300
|
-
metadata: { filePath: "/src/Button.tsx", type: "component" },
|
|
301
|
-
});
|
|
302
|
-
});
|
|
303
|
-
await (0, react_1.waitFor)(async () => {
|
|
304
|
-
const contexts = await result.current.helpers.getAdditionalContext();
|
|
305
|
-
expect(contexts.length).toBeGreaterThan(0);
|
|
306
|
-
});
|
|
307
|
-
const contexts = await result.current.helpers.getAdditionalContext();
|
|
308
|
-
const attachmentContext = contexts.find((c) => c.name.includes(result.current.attachment.attachments[0].id));
|
|
309
|
-
expect(attachmentContext?.context).toMatchObject({
|
|
310
|
-
selectedComponent: {
|
|
311
|
-
name: "Button.tsx",
|
|
312
|
-
instruction: expect.stringContaining("Tambo interactable component"),
|
|
313
|
-
filePath: "/src/Button.tsx",
|
|
314
|
-
type: "component",
|
|
315
|
-
},
|
|
316
|
-
});
|
|
317
|
-
});
|
|
318
|
-
/**
|
|
319
|
-
* Should use custom getContextHelperData function when provided
|
|
320
|
-
*/
|
|
321
|
-
it("should use custom getContextHelperData function", async () => {
|
|
322
|
-
const customGetContextHelperData = jest.fn(async (context) => ({
|
|
323
|
-
selectedFile: {
|
|
324
|
-
name: context.name,
|
|
325
|
-
path: context.metadata?.filePath,
|
|
326
|
-
customField: "custom value",
|
|
327
|
-
},
|
|
328
|
-
}));
|
|
329
|
-
const wrapper = ({ children }) => (react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, null,
|
|
330
|
-
react_2.default.createElement(tambo_context_attachment_provider_1.TamboContextAttachmentProvider, { getContextHelperData: customGetContextHelperData }, children)));
|
|
331
|
-
const { result } = (0, react_1.renderHook)(() => ({
|
|
332
|
-
attachment: (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(),
|
|
333
|
-
helpers: (0, tambo_context_helpers_provider_1.useTamboContextHelpers)(),
|
|
334
|
-
}), { wrapper });
|
|
335
|
-
(0, react_1.act)(() => {
|
|
336
|
-
result.current.attachment.addContextAttachment({
|
|
337
|
-
name: "Button.tsx",
|
|
338
|
-
metadata: { filePath: "/src/Button.tsx" },
|
|
339
|
-
});
|
|
340
|
-
});
|
|
341
|
-
// Wait for context helper to be registered and called
|
|
342
|
-
await (0, react_1.waitFor)(async () => {
|
|
343
|
-
const contexts = await result.current.helpers.getAdditionalContext();
|
|
344
|
-
expect(contexts.length).toBeGreaterThan(0);
|
|
345
|
-
}, { timeout: 2000 });
|
|
346
|
-
expect(customGetContextHelperData).toHaveBeenCalled();
|
|
347
|
-
const contexts = await result.current.helpers.getAdditionalContext();
|
|
348
|
-
const attachmentContext = contexts.find((c) => c.name.includes(result.current.attachment.attachments[0].id));
|
|
349
|
-
expect(attachmentContext?.context).toEqual({
|
|
350
|
-
selectedFile: {
|
|
351
|
-
name: "Button.tsx",
|
|
352
|
-
path: "/src/Button.tsx",
|
|
353
|
-
customField: "custom value",
|
|
354
|
-
},
|
|
355
|
-
});
|
|
356
|
-
});
|
|
357
|
-
/**
|
|
358
|
-
* Should update context helpers when getContextHelperData function changes
|
|
359
|
-
* This tests the bug fix for stale closure issue
|
|
360
|
-
*/
|
|
361
|
-
it("should update existing context helpers when getContextHelperData changes", async () => {
|
|
362
|
-
// Create a wrapper component with state to manage the function
|
|
363
|
-
const TestWrapper = ({ children }) => {
|
|
364
|
-
const [version, setVersion] = react_2.default.useState("v1");
|
|
365
|
-
const getContextHelperData = react_2.default.useCallback(async (context) => ({
|
|
366
|
-
version,
|
|
367
|
-
name: context.name,
|
|
368
|
-
}), [version]);
|
|
369
|
-
// Expose setVersion for the test
|
|
370
|
-
TestWrapper.setVersion = setVersion;
|
|
371
|
-
return (react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, null,
|
|
372
|
-
react_2.default.createElement(tambo_context_attachment_provider_1.TamboContextAttachmentProvider, { getContextHelperData: getContextHelperData }, children)));
|
|
373
|
-
};
|
|
374
|
-
const { result } = (0, react_1.renderHook)(() => ({
|
|
375
|
-
attachment: (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(),
|
|
376
|
-
helpers: (0, tambo_context_helpers_provider_1.useTamboContextHelpers)(),
|
|
377
|
-
}), { wrapper: TestWrapper });
|
|
378
|
-
// Add attachment with first version
|
|
379
|
-
(0, react_1.act)(() => {
|
|
380
|
-
result.current.attachment.addContextAttachment({
|
|
381
|
-
name: "Button.tsx",
|
|
382
|
-
});
|
|
383
|
-
});
|
|
384
|
-
// Wait for context helper to be registered
|
|
385
|
-
await (0, react_1.waitFor)(async () => {
|
|
386
|
-
const contexts = await result.current.helpers.getAdditionalContext();
|
|
387
|
-
expect(contexts.length).toBeGreaterThan(0);
|
|
388
|
-
}, { timeout: 2000 });
|
|
389
|
-
// Verify v1 context
|
|
390
|
-
let contexts = await result.current.helpers.getAdditionalContext();
|
|
391
|
-
let attachmentContext = contexts.find((c) => c.name.includes(result.current.attachment.attachments[0].id));
|
|
392
|
-
expect(attachmentContext?.context).toMatchObject({ version: "v1" });
|
|
393
|
-
// Change the version which will trigger a new getContextHelperData function
|
|
394
|
-
(0, react_1.act)(() => {
|
|
395
|
-
TestWrapper.setVersion("v2");
|
|
396
|
-
});
|
|
397
|
-
// Wait for context to update to v2
|
|
398
|
-
await (0, react_1.waitFor)(async () => {
|
|
399
|
-
const contexts = await result.current.helpers.getAdditionalContext();
|
|
400
|
-
const context = contexts.find((c) => c.name.includes(result.current.attachment.attachments[0].id));
|
|
401
|
-
return context?.context.version === "v2";
|
|
402
|
-
}, { timeout: 2000 });
|
|
403
|
-
// Verify v2 context - should be updated, not stale
|
|
404
|
-
contexts = await result.current.helpers.getAdditionalContext();
|
|
405
|
-
attachmentContext = contexts.find((c) => c.name.includes(result.current.attachment.attachments[0].id));
|
|
406
|
-
expect(attachmentContext?.context).toMatchObject({ version: "v2" });
|
|
407
|
-
});
|
|
408
|
-
/**
|
|
409
|
-
* Should handle errors in getContextHelperData gracefully
|
|
410
|
-
*/
|
|
411
|
-
it("should handle errors in getContextHelperData gracefully", async () => {
|
|
412
|
-
const consoleErrorSpy = jest
|
|
413
|
-
.spyOn(console, "error")
|
|
414
|
-
.mockImplementation(() => { });
|
|
415
|
-
const errorGetData = jest.fn(async () => {
|
|
416
|
-
throw new Error("Custom data error");
|
|
417
|
-
});
|
|
418
|
-
const wrapper = ({ children }) => (react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, null,
|
|
419
|
-
react_2.default.createElement(tambo_context_attachment_provider_1.TamboContextAttachmentProvider, { getContextHelperData: errorGetData }, children)));
|
|
420
|
-
const { result } = (0, react_1.renderHook)(() => ({
|
|
421
|
-
attachment: (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(),
|
|
422
|
-
helpers: (0, tambo_context_helpers_provider_1.useTamboContextHelpers)(),
|
|
423
|
-
}), { wrapper });
|
|
424
|
-
(0, react_1.act)(() => {
|
|
425
|
-
result.current.attachment.addContextAttachment({
|
|
426
|
-
name: "Button.tsx",
|
|
427
|
-
});
|
|
428
|
-
});
|
|
429
|
-
// Wait for effect to run and try to call the function
|
|
389
|
+
// Wait for useEffect to run - helper should be registered and return null
|
|
430
390
|
await (0, react_1.waitFor)(() => {
|
|
431
|
-
expect(
|
|
432
|
-
}, { timeout: 2000 });
|
|
433
|
-
// Try to get contexts, which will trigger the error
|
|
434
|
-
await result.current.helpers.getAdditionalContext();
|
|
435
|
-
expect(errorGetData).toHaveBeenCalled();
|
|
436
|
-
expect(consoleErrorSpy).toHaveBeenCalled();
|
|
437
|
-
consoleErrorSpy.mockRestore();
|
|
438
|
-
});
|
|
439
|
-
});
|
|
440
|
-
describe("Custom Suggestions", () => {
|
|
441
|
-
/**
|
|
442
|
-
* Should start with null custom suggestions
|
|
443
|
-
*/
|
|
444
|
-
it("should initialize with null custom suggestions", () => {
|
|
445
|
-
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
446
|
-
wrapper: createWrapper(),
|
|
447
|
-
});
|
|
448
|
-
expect(result.current.customSuggestions).toBeNull();
|
|
449
|
-
});
|
|
450
|
-
/**
|
|
451
|
-
* Should set custom suggestions
|
|
452
|
-
*/
|
|
453
|
-
it("should set custom suggestions", () => {
|
|
454
|
-
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
455
|
-
wrapper: createWrapper(),
|
|
456
|
-
});
|
|
457
|
-
const suggestions = [
|
|
458
|
-
{
|
|
459
|
-
id: "1",
|
|
460
|
-
title: "Edit component",
|
|
461
|
-
detailedSuggestion: "Modify the Button component",
|
|
462
|
-
messageId: "",
|
|
463
|
-
},
|
|
464
|
-
{
|
|
465
|
-
id: "2",
|
|
466
|
-
title: "Add feature",
|
|
467
|
-
detailedSuggestion: "Add a new feature",
|
|
468
|
-
messageId: "",
|
|
469
|
-
},
|
|
470
|
-
];
|
|
471
|
-
(0, react_1.act)(() => {
|
|
472
|
-
result.current.setCustomSuggestions(suggestions);
|
|
473
|
-
});
|
|
474
|
-
expect(result.current.customSuggestions).toEqual(suggestions);
|
|
475
|
-
});
|
|
476
|
-
/**
|
|
477
|
-
* Should clear custom suggestions by setting to null
|
|
478
|
-
*/
|
|
479
|
-
it("should clear custom suggestions", () => {
|
|
480
|
-
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
481
|
-
wrapper: createWrapper(),
|
|
482
|
-
});
|
|
483
|
-
const suggestions = [
|
|
484
|
-
{
|
|
485
|
-
id: "1",
|
|
486
|
-
title: "Test",
|
|
487
|
-
detailedSuggestion: "Test suggestion",
|
|
488
|
-
messageId: "",
|
|
489
|
-
},
|
|
490
|
-
];
|
|
491
|
-
(0, react_1.act)(() => {
|
|
492
|
-
result.current.setCustomSuggestions(suggestions);
|
|
493
|
-
});
|
|
494
|
-
expect(result.current.customSuggestions).toEqual(suggestions);
|
|
495
|
-
(0, react_1.act)(() => {
|
|
496
|
-
result.current.setCustomSuggestions(null);
|
|
497
|
-
});
|
|
498
|
-
expect(result.current.customSuggestions).toBeNull();
|
|
499
|
-
});
|
|
500
|
-
/**
|
|
501
|
-
* Should update custom suggestions when changed
|
|
502
|
-
*/
|
|
503
|
-
it("should update custom suggestions", () => {
|
|
504
|
-
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
505
|
-
wrapper: createWrapper(),
|
|
506
|
-
});
|
|
507
|
-
const firstSuggestions = [
|
|
508
|
-
{
|
|
509
|
-
id: "1",
|
|
510
|
-
title: "First",
|
|
511
|
-
detailedSuggestion: "First suggestion",
|
|
512
|
-
messageId: "",
|
|
513
|
-
},
|
|
514
|
-
];
|
|
515
|
-
const secondSuggestions = [
|
|
516
|
-
{
|
|
517
|
-
id: "2",
|
|
518
|
-
title: "Second",
|
|
519
|
-
detailedSuggestion: "Second suggestion",
|
|
520
|
-
messageId: "",
|
|
521
|
-
},
|
|
522
|
-
];
|
|
523
|
-
(0, react_1.act)(() => {
|
|
524
|
-
result.current.setCustomSuggestions(firstSuggestions);
|
|
525
|
-
});
|
|
526
|
-
expect(result.current.customSuggestions).toEqual(firstSuggestions);
|
|
527
|
-
(0, react_1.act)(() => {
|
|
528
|
-
result.current.setCustomSuggestions(secondSuggestions);
|
|
529
|
-
});
|
|
530
|
-
expect(result.current.customSuggestions).toEqual(secondSuggestions);
|
|
531
|
-
});
|
|
532
|
-
});
|
|
533
|
-
describe("Combined Workflows", () => {
|
|
534
|
-
/**
|
|
535
|
-
* Should handle adding attachment and setting custom suggestions together
|
|
536
|
-
*/
|
|
537
|
-
it("should handle attachment and custom suggestions together", () => {
|
|
538
|
-
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
539
|
-
wrapper: createWrapper(),
|
|
540
|
-
});
|
|
541
|
-
const suggestions = [
|
|
542
|
-
{
|
|
543
|
-
id: "1",
|
|
544
|
-
title: "Edit file",
|
|
545
|
-
detailedSuggestion: "Edit this file",
|
|
546
|
-
messageId: "",
|
|
547
|
-
},
|
|
548
|
-
];
|
|
549
|
-
(0, react_1.act)(() => {
|
|
550
|
-
result.current.addContextAttachment({
|
|
551
|
-
name: "Button.tsx",
|
|
552
|
-
metadata: { filePath: "/src/Button.tsx" },
|
|
553
|
-
});
|
|
554
|
-
result.current.setCustomSuggestions(suggestions);
|
|
555
|
-
});
|
|
556
|
-
expect(result.current.attachments).toHaveLength(1);
|
|
557
|
-
expect(result.current.customSuggestions).toEqual(suggestions);
|
|
558
|
-
});
|
|
559
|
-
/**
|
|
560
|
-
* Should clear suggestions when clearing attachments
|
|
561
|
-
*/
|
|
562
|
-
it("should independently manage attachments and suggestions", () => {
|
|
563
|
-
const { result } = (0, react_1.renderHook)(() => (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(), {
|
|
564
|
-
wrapper: createWrapper(),
|
|
565
|
-
});
|
|
566
|
-
const suggestions = [
|
|
567
|
-
{
|
|
568
|
-
id: "1",
|
|
569
|
-
title: "Test",
|
|
570
|
-
detailedSuggestion: "Test suggestion",
|
|
571
|
-
messageId: "",
|
|
572
|
-
},
|
|
573
|
-
];
|
|
574
|
-
(0, react_1.act)(() => {
|
|
575
|
-
result.current.addContextAttachment({ name: "File.tsx" });
|
|
576
|
-
result.current.setCustomSuggestions(suggestions);
|
|
577
|
-
});
|
|
578
|
-
// Clear attachments
|
|
579
|
-
(0, react_1.act)(() => {
|
|
580
|
-
result.current.clearContextAttachments();
|
|
581
|
-
});
|
|
582
|
-
// Suggestions should remain
|
|
583
|
-
expect(result.current.attachments).toHaveLength(0);
|
|
584
|
-
expect(result.current.customSuggestions).toEqual(suggestions);
|
|
585
|
-
// Can clear suggestions separately
|
|
586
|
-
(0, react_1.act)(() => {
|
|
587
|
-
result.current.setCustomSuggestions(null);
|
|
588
|
-
});
|
|
589
|
-
expect(result.current.customSuggestions).toBeNull();
|
|
590
|
-
});
|
|
591
|
-
});
|
|
592
|
-
describe("Cleanup", () => {
|
|
593
|
-
/**
|
|
594
|
-
* Should cleanup context helpers on unmount
|
|
595
|
-
*/
|
|
596
|
-
it("should cleanup context helpers on unmount", async () => {
|
|
597
|
-
// Use a shared provider wrapper so context helpers persist
|
|
598
|
-
const SharedWrapper = ({ children }) => (react_2.default.createElement(tambo_context_helpers_provider_1.TamboContextHelpersProvider, null, children));
|
|
599
|
-
// First render with attachment provider
|
|
600
|
-
const { result: attachmentResult, unmount } = (0, react_1.renderHook)(() => ({
|
|
601
|
-
attachment: (0, tambo_context_attachment_provider_1.useTamboContextAttachment)(),
|
|
602
|
-
helpers: (0, tambo_context_helpers_provider_1.useTamboContextHelpers)(),
|
|
603
|
-
}), {
|
|
604
|
-
wrapper: ({ children }) => (react_2.default.createElement(SharedWrapper, null,
|
|
605
|
-
react_2.default.createElement(tambo_context_attachment_provider_1.TamboContextAttachmentProvider, null, children))),
|
|
606
|
-
});
|
|
607
|
-
// Add attachment
|
|
608
|
-
(0, react_1.act)(() => {
|
|
609
|
-
attachmentResult.current.attachment.addContextAttachment({
|
|
610
|
-
name: "Button.tsx",
|
|
611
|
-
});
|
|
391
|
+
expect(mockAddContextHelper).toHaveBeenCalledWith(CONTEXT_ATTACHMENTS_HELPER_KEY, expect.any(Function));
|
|
612
392
|
});
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
const contexts = await attachmentResult.current.helpers.getAdditionalContext();
|
|
617
|
-
const hasContext = contexts.some((c) => c.name.includes(attachmentId));
|
|
618
|
-
expect(hasContext).toBe(true);
|
|
619
|
-
});
|
|
620
|
-
// Unmount the attachment provider
|
|
621
|
-
unmount();
|
|
622
|
-
// Create new hook to check cleanup
|
|
623
|
-
const { result: helpersResult } = (0, react_1.renderHook)(() => (0, tambo_context_helpers_provider_1.useTamboContextHelpers)(), { wrapper: SharedWrapper });
|
|
624
|
-
// Wait a bit for cleanup effect to run
|
|
625
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
626
|
-
const contexts = await helpersResult.current.getAdditionalContext();
|
|
627
|
-
// Should not contain the attachment context after unmount
|
|
628
|
-
const hasAttachmentContext = contexts.some((c) => c.name.includes(attachmentId));
|
|
629
|
-
expect(hasAttachmentContext).toBe(false);
|
|
393
|
+
const helperFn = mockAddContextHelper.mock.calls.find((call) => call[0] === CONTEXT_ATTACHMENTS_HELPER_KEY)?.[1];
|
|
394
|
+
expect(helperFn).toBeDefined();
|
|
395
|
+
expect(helperFn()).toBeNull();
|
|
630
396
|
});
|
|
631
397
|
});
|
|
632
398
|
});
|