@tambo-ai/react 1.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/context-helpers/current-interactables-context-helper.d.ts +16 -2
- package/dist/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
- package/dist/context-helpers/current-interactables-context-helper.js.map +1 -1
- package/dist/context-helpers/current-interactables-context-helper.test.d.ts +2 -0
- package/dist/context-helpers/current-interactables-context-helper.test.d.ts.map +1 -0
- package/dist/context-helpers/current-interactables-context-helper.test.js +70 -0
- package/dist/context-helpers/current-interactables-context-helper.test.js.map +1 -0
- package/dist/hoc/with-tambo-interactable.d.ts.map +1 -1
- package/dist/hoc/with-tambo-interactable.js +11 -2
- package/dist/hoc/with-tambo-interactable.js.map +1 -1
- package/dist/hoc/with-tambo-interactable.test.js +14 -0
- package/dist/hoc/with-tambo-interactable.test.js.map +1 -1
- package/dist/mcp/elicitation.d.ts +3 -37
- package/dist/mcp/elicitation.d.ts.map +1 -1
- package/dist/mcp/elicitation.js +7 -24
- package/dist/mcp/elicitation.js.map +1 -1
- package/dist/mcp/index.d.ts +4 -4
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +2 -2
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/mcp-client.test.js +17 -17
- package/dist/mcp/mcp-client.test.js.map +1 -1
- package/dist/mcp/mcp-hooks.d.ts.map +1 -1
- package/dist/mcp/mcp-hooks.js +8 -5
- package/dist/mcp/mcp-hooks.js.map +1 -1
- package/dist/mcp/mcp-hooks.test.js +30 -29
- package/dist/mcp/mcp-hooks.test.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.d.ts +6 -9
- package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/dist/mcp/tambo-mcp-provider.js +9 -13
- package/dist/mcp/tambo-mcp-provider.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.test.js +26 -25
- package/dist/mcp/tambo-mcp-provider.test.js.map +1 -1
- package/dist/mcp/use-mcp-servers.test.js +2 -1
- package/dist/mcp/use-mcp-servers.test.js.map +1 -1
- package/dist/model/component-metadata.d.ts +7 -372
- package/dist/model/component-metadata.d.ts.map +1 -1
- package/dist/model/component-metadata.js.map +1 -1
- package/dist/model/validate-input.test.d.ts +2 -0
- package/dist/model/validate-input.test.d.ts.map +1 -0
- package/dist/model/validate-input.test.js +38 -0
- package/dist/model/validate-input.test.js.map +1 -0
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js +2 -0
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.d.ts +7 -7
- package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/dist/providers/tambo-interactable-provider.js +26 -4
- package/dist/providers/tambo-interactable-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.test.js +78 -0
- package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
- package/dist/providers/tambo-registry-provider.d.ts +2 -1
- package/dist/providers/tambo-registry-provider.d.ts.map +1 -1
- package/dist/providers/tambo-registry-provider.js +19 -0
- package/dist/providers/tambo-registry-provider.js.map +1 -1
- package/dist/providers/tambo-registry-provider.test.js +36 -0
- package/dist/providers/tambo-registry-provider.test.js.map +1 -1
- package/dist/providers/tambo-registry-schema-compat.test.js +4 -4
- package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -1
- package/dist/schema/index.d.ts +2 -4
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +9 -11
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/json-schema.d.ts +1 -17
- package/dist/schema/json-schema.d.ts.map +1 -1
- package/dist/schema/json-schema.js +5 -69
- package/dist/schema/json-schema.js.map +1 -1
- package/dist/schema/schema.test.js +24 -25
- package/dist/schema/schema.test.js.map +1 -1
- package/dist/schema/standard-schema.test.js +25 -25
- package/dist/schema/standard-schema.test.js.map +1 -1
- package/dist/schema/validate.test.js +33 -33
- package/dist/schema/validate.test.js.map +1 -1
- package/dist/testing/tools.d.ts +4 -4
- package/dist/testing/tools.test.d.ts +2 -0
- package/dist/testing/tools.test.d.ts.map +1 -0
- package/dist/testing/tools.test.js +60 -0
- package/dist/testing/tools.test.js.map +1 -0
- package/dist/util/mcp-server-utils.d.ts +1 -1
- package/dist/util/mcp-server-utils.d.ts.map +1 -1
- package/dist/util/mcp-server-utils.js +4 -4
- package/dist/util/mcp-server-utils.js.map +1 -1
- package/dist/util/mcp-server-utils.test.js +27 -27
- package/dist/util/mcp-server-utils.test.js.map +1 -1
- package/dist/util/registry.js +1 -1
- package/dist/util/registry.js.map +1 -1
- package/dist/util/resource-content-resolver.js +5 -5
- package/dist/util/resource-content-resolver.js.map +1 -1
- package/dist/util/resource-content-resolver.test.js +6 -6
- package/dist/util/resource-content-resolver.test.js.map +1 -1
- package/dist/util/tool-caller.test.d.ts +2 -0
- package/dist/util/tool-caller.test.d.ts.map +1 -0
- package/dist/util/tool-caller.test.js +71 -0
- package/dist/util/tool-caller.test.js.map +1 -0
- package/dist/v1/__tests__/v1-interactables.test.js +6 -0
- package/dist/v1/__tests__/v1-interactables.test.js.map +1 -1
- package/dist/v1/components/v1-component-renderer.test.js +1 -0
- package/dist/v1/components/v1-component-renderer.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts +1 -1
- package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-auth-state.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.js +2 -2
- package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.js +17 -17
- package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.js +2 -2
- package/dist/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js +9 -5
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.js +2 -2
- package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +1 -0
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.d.ts +7 -6
- package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.js +2 -2
- package/dist/v1/hooks/use-tambo-v1.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.test.js +24 -23
- package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/dist/v1/index.d.ts +6 -6
- package/dist/v1/index.d.ts.map +1 -1
- package/dist/v1/index.js +2 -2
- package/dist/v1/index.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts +2 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.js +2 -0
- package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.d.ts +2 -2
- package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.js +9 -9
- package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.test.js +35 -0
- package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.js +2 -1
- package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.js +2 -2
- package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/dist/v1/types/event.test.js +13 -13
- package/dist/v1/types/event.test.js.map +1 -1
- package/dist/v1/types/message.d.ts +12 -109
- package/dist/v1/types/message.d.ts.map +1 -1
- package/dist/v1/types/message.js +0 -7
- package/dist/v1/types/message.js.map +1 -1
- package/dist/v1/utils/event-accumulator.test.js +183 -184
- package/dist/v1/utils/event-accumulator.test.js.map +1 -1
- package/dist/v1/utils/json-patch.test.js +4 -4
- package/dist/v1/utils/json-patch.test.js.map +1 -1
- package/dist/v1/utils/keyed-throttle.test.js +12 -12
- package/dist/v1/utils/keyed-throttle.test.js.map +1 -1
- package/dist/v1/utils/registry-conversion.test.js +13 -13
- package/dist/v1/utils/registry-conversion.test.js.map +1 -1
- package/dist/v1/utils/stream-handler.test.js +5 -5
- package/dist/v1/utils/stream-handler.test.js.map +1 -1
- package/dist/v1/utils/tool-call-tracker.test.js +15 -9
- package/dist/v1/utils/tool-call-tracker.test.js.map +1 -1
- package/dist/v1/utils/tool-executor.test.js +25 -26
- package/dist/v1/utils/tool-executor.test.js.map +1 -1
- package/dist/v1/utils/unstrictify.test.js +16 -16
- package/dist/v1/utils/unstrictify.test.js.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.d.ts +16 -2
- package/esm/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.js.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.test.d.ts +2 -0
- package/esm/context-helpers/current-interactables-context-helper.test.d.ts.map +1 -0
- package/esm/context-helpers/current-interactables-context-helper.test.js +68 -0
- package/esm/context-helpers/current-interactables-context-helper.test.js.map +1 -0
- package/esm/hoc/with-tambo-interactable.d.ts.map +1 -1
- package/esm/hoc/with-tambo-interactable.js +11 -2
- package/esm/hoc/with-tambo-interactable.js.map +1 -1
- package/esm/hoc/with-tambo-interactable.test.js +14 -0
- package/esm/hoc/with-tambo-interactable.test.js.map +1 -1
- package/esm/mcp/elicitation.d.ts +3 -37
- package/esm/mcp/elicitation.d.ts.map +1 -1
- package/esm/mcp/elicitation.js +4 -24
- package/esm/mcp/elicitation.js.map +1 -1
- package/esm/mcp/index.d.ts +4 -4
- package/esm/mcp/index.d.ts.map +1 -1
- package/esm/mcp/index.js +1 -1
- package/esm/mcp/index.js.map +1 -1
- package/esm/mcp/mcp-client.test.js +1 -1
- package/esm/mcp/mcp-client.test.js.map +1 -1
- package/esm/mcp/mcp-hooks.d.ts.map +1 -1
- package/esm/mcp/mcp-hooks.js +4 -1
- package/esm/mcp/mcp-hooks.js.map +1 -1
- package/esm/mcp/mcp-hooks.test.js +3 -2
- package/esm/mcp/mcp-hooks.test.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.d.ts +6 -9
- package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/esm/mcp/tambo-mcp-provider.js +4 -8
- package/esm/mcp/tambo-mcp-provider.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.test.js +3 -2
- package/esm/mcp/tambo-mcp-provider.test.js.map +1 -1
- package/esm/mcp/use-mcp-servers.test.js +2 -1
- package/esm/mcp/use-mcp-servers.test.js.map +1 -1
- package/esm/model/component-metadata.d.ts +7 -372
- package/esm/model/component-metadata.d.ts.map +1 -1
- package/esm/model/component-metadata.js.map +1 -1
- package/esm/model/validate-input.test.d.ts +2 -0
- package/esm/model/validate-input.test.d.ts.map +1 -0
- package/esm/model/validate-input.test.js +36 -0
- package/esm/model/validate-input.test.js.map +1 -0
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js +2 -0
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +7 -7
- package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/esm/providers/tambo-interactable-provider.js +26 -4
- package/esm/providers/tambo-interactable-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.test.js +78 -0
- package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
- package/esm/providers/tambo-registry-provider.d.ts +2 -1
- package/esm/providers/tambo-registry-provider.d.ts.map +1 -1
- package/esm/providers/tambo-registry-provider.js +19 -0
- package/esm/providers/tambo-registry-provider.js.map +1 -1
- package/esm/providers/tambo-registry-provider.test.js +36 -0
- package/esm/providers/tambo-registry-provider.test.js.map +1 -1
- package/esm/providers/tambo-registry-schema-compat.test.js +4 -4
- package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -1
- package/esm/schema/index.d.ts +2 -4
- package/esm/schema/index.d.ts.map +1 -1
- package/esm/schema/index.js +2 -4
- package/esm/schema/index.js.map +1 -1
- package/esm/schema/json-schema.d.ts +1 -17
- package/esm/schema/json-schema.d.ts.map +1 -1
- package/esm/schema/json-schema.js +2 -67
- package/esm/schema/json-schema.js.map +1 -1
- package/esm/schema/schema.test.js +1 -2
- package/esm/schema/schema.test.js.map +1 -1
- package/esm/schema/standard-schema.test.js +1 -1
- package/esm/schema/standard-schema.test.js.map +1 -1
- package/esm/schema/validate.test.js +1 -1
- package/esm/schema/validate.test.js.map +1 -1
- package/esm/testing/tools.d.ts +4 -4
- package/esm/testing/tools.test.d.ts +2 -0
- package/esm/testing/tools.test.d.ts.map +1 -0
- package/esm/testing/tools.test.js +58 -0
- package/esm/testing/tools.test.js.map +1 -0
- package/esm/util/mcp-server-utils.d.ts +1 -1
- package/esm/util/mcp-server-utils.d.ts.map +1 -1
- package/esm/util/mcp-server-utils.js +1 -1
- package/esm/util/mcp-server-utils.js.map +1 -1
- package/esm/util/mcp-server-utils.test.js +1 -1
- package/esm/util/mcp-server-utils.test.js.map +1 -1
- package/esm/util/registry.js +1 -1
- package/esm/util/registry.js.map +1 -1
- package/esm/util/resource-content-resolver.js +1 -1
- package/esm/util/resource-content-resolver.js.map +1 -1
- package/esm/util/resource-content-resolver.test.js +2 -2
- package/esm/util/resource-content-resolver.test.js.map +1 -1
- package/esm/util/tool-caller.test.d.ts +2 -0
- package/esm/util/tool-caller.test.d.ts.map +1 -0
- package/esm/util/tool-caller.test.js +69 -0
- package/esm/util/tool-caller.test.js.map +1 -0
- package/esm/v1/__tests__/v1-interactables.test.js +6 -0
- package/esm/v1/__tests__/v1-interactables.test.js.map +1 -1
- package/esm/v1/components/v1-component-renderer.test.js +1 -0
- package/esm/v1/components/v1-component-renderer.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-auth-state.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.js +6 -6
- package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js +9 -5
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +1 -0
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.d.ts +7 -6
- package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.js +1 -1
- package/esm/v1/hooks/use-tambo-v1.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.test.js +23 -22
- package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/esm/v1/index.d.ts +6 -6
- package/esm/v1/index.d.ts.map +1 -1
- package/esm/v1/index.js +1 -1
- package/esm/v1/index.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts +2 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.js +2 -0
- package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.d.ts +2 -2
- package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.js +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.test.js +35 -0
- package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.js +2 -1
- package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.js +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/esm/v1/types/event.test.js +1 -1
- package/esm/v1/types/event.test.js.map +1 -1
- package/esm/v1/types/message.d.ts +12 -109
- package/esm/v1/types/message.d.ts.map +1 -1
- package/esm/v1/types/message.js +0 -7
- package/esm/v1/types/message.js.map +1 -1
- package/esm/v1/utils/event-accumulator.test.js +2 -3
- package/esm/v1/utils/event-accumulator.test.js.map +1 -1
- package/esm/v1/utils/json-patch.test.js +1 -1
- package/esm/v1/utils/json-patch.test.js.map +1 -1
- package/esm/v1/utils/keyed-throttle.test.js +1 -1
- package/esm/v1/utils/keyed-throttle.test.js.map +1 -1
- package/esm/v1/utils/registry-conversion.test.js +1 -1
- package/esm/v1/utils/registry-conversion.test.js.map +1 -1
- package/esm/v1/utils/stream-handler.test.js +1 -1
- package/esm/v1/utils/stream-handler.test.js.map +1 -1
- package/esm/v1/utils/tool-call-tracker.test.js +9 -3
- package/esm/v1/utils/tool-call-tracker.test.js.map +1 -1
- package/esm/v1/utils/tool-executor.test.js +1 -2
- package/esm/v1/utils/tool-executor.test.js.map +1 -1
- package/esm/v1/utils/unstrictify.test.js +1 -1
- package/esm/v1/utils/unstrictify.test.js.map +1 -1
- package/package.json +10 -11
- package/dist/mcp/mcp-client.d.ts +0 -185
- package/dist/mcp/mcp-client.d.ts.map +0 -1
- package/dist/mcp/mcp-client.js +0 -219
- package/dist/mcp/mcp-client.js.map +0 -1
- package/dist/mcp/mcp-constants.d.ts +0 -19
- package/dist/mcp/mcp-constants.d.ts.map +0 -1
- package/dist/mcp/mcp-constants.js +0 -21
- package/dist/mcp/mcp-constants.js.map +0 -1
- package/dist/model/mcp-server-info.d.ts +0 -76
- package/dist/model/mcp-server-info.d.ts.map +0 -1
- package/dist/model/mcp-server-info.js +0 -29
- package/dist/model/mcp-server-info.js.map +0 -1
- package/dist/schema/schema.d.ts +0 -49
- package/dist/schema/schema.d.ts.map +0 -1
- package/dist/schema/schema.js +0 -129
- package/dist/schema/schema.js.map +0 -1
- package/dist/schema/standard-schema.d.ts +0 -22
- package/dist/schema/standard-schema.d.ts.map +0 -1
- package/dist/schema/standard-schema.js +0 -42
- package/dist/schema/standard-schema.js.map +0 -1
- package/dist/schema/validate.d.ts +0 -14
- package/dist/schema/validate.d.ts.map +0 -1
- package/dist/schema/validate.js +0 -148
- package/dist/schema/validate.js.map +0 -1
- package/dist/v1/types/auth.d.ts +0 -24
- package/dist/v1/types/auth.d.ts.map +0 -1
- package/dist/v1/types/auth.js +0 -3
- package/dist/v1/types/auth.js.map +0 -1
- package/dist/v1/types/event.d.ts +0 -89
- package/dist/v1/types/event.d.ts.map +0 -1
- package/dist/v1/types/event.js +0 -57
- package/dist/v1/types/event.js.map +0 -1
- package/dist/v1/types/thread.d.ts +0 -58
- package/dist/v1/types/thread.d.ts.map +0 -1
- package/dist/v1/types/thread.js +0 -9
- package/dist/v1/types/thread.js.map +0 -1
- package/dist/v1/types/tool-choice.d.ts +0 -8
- package/dist/v1/types/tool-choice.d.ts.map +0 -1
- package/dist/v1/types/tool-choice.js +0 -3
- package/dist/v1/types/tool-choice.js.map +0 -1
- package/dist/v1/utils/event-accumulator.d.ts +0 -165
- package/dist/v1/utils/event-accumulator.d.ts.map +0 -1
- package/dist/v1/utils/event-accumulator.js +0 -1277
- package/dist/v1/utils/event-accumulator.js.map +0 -1
- package/dist/v1/utils/json-patch.d.ts +0 -18
- package/dist/v1/utils/json-patch.d.ts.map +0 -1
- package/dist/v1/utils/json-patch.js +0 -35
- package/dist/v1/utils/json-patch.js.map +0 -1
- package/dist/v1/utils/keyed-throttle.d.ts +0 -42
- package/dist/v1/utils/keyed-throttle.d.ts.map +0 -1
- package/dist/v1/utils/keyed-throttle.js +0 -86
- package/dist/v1/utils/keyed-throttle.js.map +0 -1
- package/dist/v1/utils/registry-conversion.d.ts +0 -53
- package/dist/v1/utils/registry-conversion.d.ts.map +0 -1
- package/dist/v1/utils/registry-conversion.js +0 -115
- package/dist/v1/utils/registry-conversion.js.map +0 -1
- package/dist/v1/utils/stream-handler.d.ts +0 -45
- package/dist/v1/utils/stream-handler.d.ts.map +0 -1
- package/dist/v1/utils/stream-handler.js +0 -47
- package/dist/v1/utils/stream-handler.js.map +0 -1
- package/dist/v1/utils/thread-utils.d.ts +0 -16
- package/dist/v1/utils/thread-utils.d.ts.map +0 -1
- package/dist/v1/utils/thread-utils.js +0 -34
- package/dist/v1/utils/thread-utils.js.map +0 -1
- package/dist/v1/utils/tool-call-tracker.d.ts +0 -73
- package/dist/v1/utils/tool-call-tracker.d.ts.map +0 -1
- package/dist/v1/utils/tool-call-tracker.js +0 -180
- package/dist/v1/utils/tool-call-tracker.js.map +0 -1
- package/dist/v1/utils/tool-executor.d.ts +0 -67
- package/dist/v1/utils/tool-executor.d.ts.map +0 -1
- package/dist/v1/utils/tool-executor.js +0 -160
- package/dist/v1/utils/tool-executor.js.map +0 -1
- package/dist/v1/utils/unstrictify.d.ts +0 -32
- package/dist/v1/utils/unstrictify.d.ts.map +0 -1
- package/dist/v1/utils/unstrictify.js +0 -159
- package/dist/v1/utils/unstrictify.js.map +0 -1
- package/esm/mcp/mcp-client.d.ts +0 -185
- package/esm/mcp/mcp-client.d.ts.map +0 -1
- package/esm/mcp/mcp-client.js +0 -216
- package/esm/mcp/mcp-client.js.map +0 -1
- package/esm/mcp/mcp-constants.d.ts +0 -19
- package/esm/mcp/mcp-constants.d.ts.map +0 -1
- package/esm/mcp/mcp-constants.js +0 -18
- package/esm/mcp/mcp-constants.js.map +0 -1
- package/esm/model/mcp-server-info.d.ts +0 -76
- package/esm/model/mcp-server-info.d.ts.map +0 -1
- package/esm/model/mcp-server-info.js +0 -25
- package/esm/model/mcp-server-info.js.map +0 -1
- package/esm/schema/schema.d.ts +0 -49
- package/esm/schema/schema.d.ts.map +0 -1
- package/esm/schema/schema.js +0 -124
- package/esm/schema/schema.js.map +0 -1
- package/esm/schema/standard-schema.d.ts +0 -22
- package/esm/schema/standard-schema.d.ts.map +0 -1
- package/esm/schema/standard-schema.js +0 -39
- package/esm/schema/standard-schema.js.map +0 -1
- package/esm/schema/validate.d.ts +0 -14
- package/esm/schema/validate.d.ts.map +0 -1
- package/esm/schema/validate.js +0 -145
- package/esm/schema/validate.js.map +0 -1
- package/esm/v1/types/auth.d.ts +0 -24
- package/esm/v1/types/auth.d.ts.map +0 -1
- package/esm/v1/types/auth.js +0 -2
- package/esm/v1/types/auth.js.map +0 -1
- package/esm/v1/types/event.d.ts +0 -89
- package/esm/v1/types/event.d.ts.map +0 -1
- package/esm/v1/types/event.js +0 -53
- package/esm/v1/types/event.js.map +0 -1
- package/esm/v1/types/thread.d.ts +0 -58
- package/esm/v1/types/thread.d.ts.map +0 -1
- package/esm/v1/types/thread.js +0 -8
- package/esm/v1/types/thread.js.map +0 -1
- package/esm/v1/types/tool-choice.d.ts +0 -8
- package/esm/v1/types/tool-choice.d.ts.map +0 -1
- package/esm/v1/types/tool-choice.js +0 -2
- package/esm/v1/types/tool-choice.js.map +0 -1
- package/esm/v1/utils/event-accumulator.d.ts +0 -165
- package/esm/v1/utils/event-accumulator.d.ts.map +0 -1
- package/esm/v1/utils/event-accumulator.js +0 -1268
- package/esm/v1/utils/event-accumulator.js.map +0 -1
- package/esm/v1/utils/json-patch.d.ts +0 -18
- package/esm/v1/utils/json-patch.d.ts.map +0 -1
- package/esm/v1/utils/json-patch.js +0 -32
- package/esm/v1/utils/json-patch.js.map +0 -1
- package/esm/v1/utils/keyed-throttle.d.ts +0 -42
- package/esm/v1/utils/keyed-throttle.d.ts.map +0 -1
- package/esm/v1/utils/keyed-throttle.js +0 -83
- package/esm/v1/utils/keyed-throttle.js.map +0 -1
- package/esm/v1/utils/registry-conversion.d.ts +0 -53
- package/esm/v1/utils/registry-conversion.d.ts.map +0 -1
- package/esm/v1/utils/registry-conversion.js +0 -109
- package/esm/v1/utils/registry-conversion.js.map +0 -1
- package/esm/v1/utils/stream-handler.d.ts +0 -45
- package/esm/v1/utils/stream-handler.d.ts.map +0 -1
- package/esm/v1/utils/stream-handler.js +0 -44
- package/esm/v1/utils/stream-handler.js.map +0 -1
- package/esm/v1/utils/thread-utils.d.ts +0 -16
- package/esm/v1/utils/thread-utils.d.ts.map +0 -1
- package/esm/v1/utils/thread-utils.js +0 -31
- package/esm/v1/utils/thread-utils.js.map +0 -1
- package/esm/v1/utils/tool-call-tracker.d.ts +0 -73
- package/esm/v1/utils/tool-call-tracker.d.ts.map +0 -1
- package/esm/v1/utils/tool-call-tracker.js +0 -176
- package/esm/v1/utils/tool-call-tracker.js.map +0 -1
- package/esm/v1/utils/tool-executor.d.ts +0 -67
- package/esm/v1/utils/tool-executor.d.ts.map +0 -1
- package/esm/v1/utils/tool-executor.js +0 -154
- package/esm/v1/utils/tool-executor.js.map +0 -1
- package/esm/v1/utils/unstrictify.d.ts +0 -32
- package/esm/v1/utils/unstrictify.d.ts.map +0 -1
- package/esm/v1/utils/unstrictify.js +0 -155
- package/esm/v1/utils/unstrictify.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unstrictify.test.js","sourceRoot":"","sources":["../../../src/v1/utils/unstrictify.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport { canBeNull, unstrictifyToolCallParamsFromSchema } from \"./unstrictify\";\n\ndescribe(\"canBeNull\", () => {\n it(\"should return true for schema with type null\", () => {\n const schema: JSONSchema7 = { type: \"null\" };\n expect(canBeNull(schema)).toBe(true);\n });\n\n it(\"should return true for schema with anyOf containing type null\", () => {\n const schema: JSONSchema7 = {\n anyOf: [{ type: \"string\" }, { type: \"null\" }],\n };\n expect(canBeNull(schema)).toBe(true);\n });\n\n it(\"should return true for deeply nested anyOf containing type null\", () => {\n const schema: JSONSchema7 = {\n anyOf: [\n { type: \"string\" },\n {\n anyOf: [{ type: \"number\" }, { type: \"null\" }],\n },\n ],\n };\n expect(canBeNull(schema)).toBe(true);\n });\n\n it(\"should return false for non-object schema\", () => {\n expect(canBeNull(true)).toBe(false);\n expect(canBeNull(\"string\" as JSONSchema7Definition)).toBe(false);\n });\n\n it(\"should return false for schema without null type\", () => {\n const schema: JSONSchema7 = { type: \"string\" };\n expect(canBeNull(schema)).toBe(false);\n });\n\n it(\"should return false for schema with anyOf not containing null type\", () => {\n const schema: JSONSchema7 = {\n anyOf: [{ type: \"string\" }, { type: \"number\" }],\n };\n expect(canBeNull(schema)).toBe(false);\n });\n});\n\ndescribe(\"unstrictifyToolCallParamsFromSchema\", () => {\n it(\"should strip null values for optional non-nullable params\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n age: { type: \"number\" },\n },\n required: [\"name\"],\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {\n name: \"John\",\n age: null,\n });\n\n expect(result).toEqual({ name: \"John\" });\n });\n\n it(\"should preserve pass-through params not in original schema\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n },\n required: [\"name\"],\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {\n name: \"John\",\n _tambo_statusMessage: \"Processing...\",\n _tambo_displayMessage: \"Hello\",\n });\n\n expect(result).toEqual({\n name: \"John\",\n _tambo_statusMessage: \"Processing...\",\n _tambo_displayMessage: \"Hello\",\n });\n });\n\n it(\"should handle nested object unstrictification with pass-through params\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n user: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n email: { type: \"string\" },\n },\n required: [\"name\"],\n },\n },\n required: [\"user\"],\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {\n user: { name: \"John\", email: null },\n _tambo_statusMessage: \"Updating user\",\n });\n\n expect(result).toEqual({\n user: { name: \"John\" },\n _tambo_statusMessage: \"Updating user\",\n });\n });\n\n it(\"should return params as-is for non-object schemas\", () => {\n const schema: JSONSchema7 = { type: \"string\" };\n const params = { name: \"John\", _tambo_foo: \"bar\" };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, params);\n\n expect(result).toEqual(params);\n });\n\n it(\"should handle empty params\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n },\n required: [],\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {});\n\n expect(result).toEqual({});\n });\n\n it(\"should handle schema with no properties defined\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {\n anything: \"value\",\n _tambo_status: \"ok\",\n });\n\n // Only _tambo_* keys pass through; unknown keys are dropped\n expect(result).toEqual({\n _tambo_status: \"ok\",\n });\n });\n\n it(\"should drop hallucinated keys not in schema or _tambo_* prefix\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n city: { type: \"string\" },\n },\n required: [\"city\"],\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {\n city: \"NYC\",\n temperatur: \"celsius\",\n _tambo_statusMessage: \"Fetching\",\n });\n\n expect(result).toEqual({\n city: \"NYC\",\n _tambo_statusMessage: \"Fetching\",\n });\n });\n\n it(\"should handle arrays with nested objects\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n targets: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n range: { type: \"string\" },\n style: {\n type: \"object\",\n properties: {\n bold: { type: \"boolean\" },\n fontFamily: { type: \"string\" },\n },\n required: [],\n },\n },\n required: [\"style\"],\n },\n },\n },\n required: [\"targets\"],\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {\n targets: [\n { range: \"A1:B1\", style: { bold: true, fontFamily: null } },\n { range: \"A2:A6\", style: { bold: false, fontFamily: null } },\n ],\n });\n\n expect(result).toEqual({\n targets: [\n { range: \"A1:B1\", style: { bold: true } },\n { range: \"A2:A6\", style: { bold: false } },\n ],\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"unstrictify.test.js","sourceRoot":"","sources":["../../../src/v1/utils/unstrictify.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport {\n canBeNull,\n unstrictifyToolCallParamsFromSchema,\n} from \"@tambo-ai/client\";\n\ndescribe(\"canBeNull\", () => {\n it(\"should return true for schema with type null\", () => {\n const schema: JSONSchema7 = { type: \"null\" };\n expect(canBeNull(schema)).toBe(true);\n });\n\n it(\"should return true for schema with anyOf containing type null\", () => {\n const schema: JSONSchema7 = {\n anyOf: [{ type: \"string\" }, { type: \"null\" }],\n };\n expect(canBeNull(schema)).toBe(true);\n });\n\n it(\"should return true for deeply nested anyOf containing type null\", () => {\n const schema: JSONSchema7 = {\n anyOf: [\n { type: \"string\" },\n {\n anyOf: [{ type: \"number\" }, { type: \"null\" }],\n },\n ],\n };\n expect(canBeNull(schema)).toBe(true);\n });\n\n it(\"should return false for non-object schema\", () => {\n expect(canBeNull(true)).toBe(false);\n expect(canBeNull(\"string\" as JSONSchema7Definition)).toBe(false);\n });\n\n it(\"should return false for schema without null type\", () => {\n const schema: JSONSchema7 = { type: \"string\" };\n expect(canBeNull(schema)).toBe(false);\n });\n\n it(\"should return false for schema with anyOf not containing null type\", () => {\n const schema: JSONSchema7 = {\n anyOf: [{ type: \"string\" }, { type: \"number\" }],\n };\n expect(canBeNull(schema)).toBe(false);\n });\n});\n\ndescribe(\"unstrictifyToolCallParamsFromSchema\", () => {\n it(\"should strip null values for optional non-nullable params\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n age: { type: \"number\" },\n },\n required: [\"name\"],\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {\n name: \"John\",\n age: null,\n });\n\n expect(result).toEqual({ name: \"John\" });\n });\n\n it(\"should preserve pass-through params not in original schema\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n },\n required: [\"name\"],\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {\n name: \"John\",\n _tambo_statusMessage: \"Processing...\",\n _tambo_displayMessage: \"Hello\",\n });\n\n expect(result).toEqual({\n name: \"John\",\n _tambo_statusMessage: \"Processing...\",\n _tambo_displayMessage: \"Hello\",\n });\n });\n\n it(\"should handle nested object unstrictification with pass-through params\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n user: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n email: { type: \"string\" },\n },\n required: [\"name\"],\n },\n },\n required: [\"user\"],\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {\n user: { name: \"John\", email: null },\n _tambo_statusMessage: \"Updating user\",\n });\n\n expect(result).toEqual({\n user: { name: \"John\" },\n _tambo_statusMessage: \"Updating user\",\n });\n });\n\n it(\"should return params as-is for non-object schemas\", () => {\n const schema: JSONSchema7 = { type: \"string\" };\n const params = { name: \"John\", _tambo_foo: \"bar\" };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, params);\n\n expect(result).toEqual(params);\n });\n\n it(\"should handle empty params\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n },\n required: [],\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {});\n\n expect(result).toEqual({});\n });\n\n it(\"should handle schema with no properties defined\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {\n anything: \"value\",\n _tambo_status: \"ok\",\n });\n\n // Only _tambo_* keys pass through; unknown keys are dropped\n expect(result).toEqual({\n _tambo_status: \"ok\",\n });\n });\n\n it(\"should drop hallucinated keys not in schema or _tambo_* prefix\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n city: { type: \"string\" },\n },\n required: [\"city\"],\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {\n city: \"NYC\",\n temperatur: \"celsius\",\n _tambo_statusMessage: \"Fetching\",\n });\n\n expect(result).toEqual({\n city: \"NYC\",\n _tambo_statusMessage: \"Fetching\",\n });\n });\n\n it(\"should handle arrays with nested objects\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n targets: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n range: { type: \"string\" },\n style: {\n type: \"object\",\n properties: {\n bold: { type: \"boolean\" },\n fontFamily: { type: \"string\" },\n },\n required: [],\n },\n },\n required: [\"style\"],\n },\n },\n },\n required: [\"targets\"],\n };\n\n const result = unstrictifyToolCallParamsFromSchema(schema, {\n targets: [\n { range: \"A1:B1\", style: { bold: true, fontFamily: null } },\n { range: \"A2:A6\", style: { bold: false, fontFamily: null } },\n ],\n });\n\n expect(result).toEqual({\n targets: [\n { range: \"A1:B1\", style: { bold: true } },\n { range: \"A2:A6\", style: { bold: false } },\n ],\n });\n });\n});\n"]}
|
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
import { ContextHelperFn } from "./types.js";
|
|
1
|
+
import type { ContextHelperFn } from "./types.js";
|
|
2
|
+
interface InteractableComponentMetadata {
|
|
3
|
+
id: string;
|
|
4
|
+
componentName: string;
|
|
5
|
+
description: string;
|
|
6
|
+
props: unknown;
|
|
7
|
+
propsSchema: string;
|
|
8
|
+
state: unknown;
|
|
9
|
+
isSelectedForInteraction: boolean;
|
|
10
|
+
stateSchema: string;
|
|
11
|
+
}
|
|
12
|
+
export interface InteractablesContext {
|
|
13
|
+
components: InteractableComponentMetadata[];
|
|
14
|
+
}
|
|
2
15
|
/**
|
|
3
16
|
* Prebuilt context helper that provides information about all interactable components currently on the page.
|
|
4
17
|
* This gives the AI awareness of what components it can interact with and their current state.
|
|
@@ -24,5 +37,6 @@ export declare const currentInteractablesContextHelper: ContextHelperFn;
|
|
|
24
37
|
* @param components Array of interactable components
|
|
25
38
|
* @returns A context helper function that returns component metadata or null if no components exist
|
|
26
39
|
*/
|
|
27
|
-
export declare const createInteractablesContextHelper: (components: unknown[]) =>
|
|
40
|
+
export declare const createInteractablesContextHelper: (components: unknown[]) => (() => InteractablesContext | null);
|
|
41
|
+
export {};
|
|
28
42
|
//# sourceMappingURL=current-interactables-context-helper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"current-interactables-context-helper.d.ts","sourceRoot":"","sources":["../../src/context-helpers/current-interactables-context-helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"current-interactables-context-helper.d.ts","sourceRoot":"","sources":["../../src/context-helpers/current-interactables-context-helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,UAAU,6BAA6B;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,wBAAwB,EAAE,OAAO,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,6BAA6B,EAAE,CAAC;CAC7C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,iCAAiC,EAAE,eAI/C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,GAC3C,YAAY,OAAO,EAAE,KACpB,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAyCpC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"current-interactables-context-helper.js","sourceRoot":"","sources":["../../src/context-helpers/current-interactables-context-helper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"current-interactables-context-helper.js","sourceRoot":"","sources":["../../src/context-helpers/current-interactables-context-helper.ts"],"names":[],"mappings":"AAiBA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAoB,GAAG,EAAE;IACrE,mFAAmF;IACnF,wEAAwE;IACxE,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAC9C,UAAqB,EACgB,EAAE;IACvC,OAAO,GAAG,EAAE;QACV,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1D,OAAO,IAAI,CAAC,CAAC,yCAAyC;QACxD,CAAC;QAED,OAAO;YACL,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;gBACvC,yEAAyE;gBACzE,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;oBACxD,OAAO;wBACL,EAAE,EAAE,SAAS;wBACb,aAAa,EAAE,SAAS;wBACxB,WAAW,EAAE,mBAAmB;wBAChC,KAAK,EAAE,SAAS;wBAChB,WAAW,EAAE,eAAe;wBAC5B,KAAK,EAAE,SAAS;wBAChB,wBAAwB,EAAE,KAAK;wBAC/B,WAAW,EAAE,eAAe;qBAC7B,CAAC;gBACJ,CAAC;gBAED,MAAM,IAAI,GAAG,SAAoC,CAAC;gBAClD,OAAO;oBACL,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,SAAS,CAAC;oBAChC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC;oBAC7C,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;oBAC3C,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,WAAW,EAAE,IAAI,CAAC,WAAW;wBAC3B,CAAC,CAAC,iDAAiD;wBACnD,CAAC,CAAC,eAAe;oBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,wBAAwB,EACrB,IAAI,CAAC,wBAAgD,IAAI,KAAK;oBACjE,WAAW,EAAE,IAAI,CAAC,WAAW;wBAC3B,CAAC,CAAC,iDAAiD;wBACnD,CAAC,CAAC,eAAe;iBACpB,CAAC;YACJ,CAAC,CAAC;SACH,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import type { ContextHelperFn } from \"./types\";\n\ninterface InteractableComponentMetadata {\n id: string;\n componentName: string;\n description: string;\n props: unknown;\n propsSchema: string;\n state: unknown;\n isSelectedForInteraction: boolean;\n stateSchema: string;\n}\n\nexport interface InteractablesContext {\n components: InteractableComponentMetadata[];\n}\n\n/**\n * Prebuilt context helper that provides information about all interactable components currently on the page.\n * This gives the AI awareness of what components it can interact with and their current state.\n * @returns an object with description and components, or null to skip including this context.\n * To disable this helper, override it with a function that returns null:\n * @example\n * ```tsx\n * // To disable the default interactables context\n * const { addContextHelper } = useTamboContextHelpers();\n * addContextHelper(\"interactables\", () => null);\n *\n * // To customize the context\n * addContextHelper(\"interactables\", () => ({\n * description: \"Custom description\",\n * components: getCustomComponentsSubset()\n * }));\n * ```\n */\nexport const currentInteractablesContextHelper: ContextHelperFn = () => {\n // This will be provided by the interactable provider when it registers this helper\n // Since we're provider-only now, this function gets replaced at runtime\n return null;\n};\n\n/**\n * Creates an interactables context helper with access to the current components.\n * This is used internally by TamboInteractableProvider.\n * @param components Array of interactable components\n * @returns A context helper function that returns component metadata or null if no components exist\n */\nexport const createInteractablesContextHelper = (\n components: unknown[],\n): (() => InteractablesContext | null) => {\n return () => {\n if (!Array.isArray(components) || components.length === 0) {\n return null; // No interactable components on the page\n }\n\n return {\n components: components.map((component) => {\n // Type guard: ensure component is an object with the expected properties\n if (typeof component !== \"object\" || component === null) {\n return {\n id: \"unknown\",\n componentName: \"unknown\",\n description: \"invalid component\",\n props: undefined,\n propsSchema: \"Not specified\",\n state: undefined,\n isSelectedForInteraction: false,\n stateSchema: \"Not specified\",\n };\n }\n\n const comp = component as Record<string, unknown>;\n return {\n id: String(comp.id ?? \"unknown\"),\n componentName: String(comp.name ?? \"unknown\"),\n description: String(comp.description ?? \"\"),\n props: comp.props,\n propsSchema: comp.propsSchema\n ? \"Available - use component-specific update tools\"\n : \"Not specified\",\n state: comp.state,\n isSelectedForInteraction:\n (comp.isSelectedForInteraction as boolean | undefined) ?? false,\n stateSchema: comp.stateSchema\n ? \"Available - use component-specific update tools\"\n : \"Not specified\",\n };\n }),\n };\n };\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"current-interactables-context-helper.test.d.ts","sourceRoot":"","sources":["../../src/context-helpers/current-interactables-context-helper.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { currentInteractablesContextHelper, createInteractablesContextHelper, } from "./current-interactables-context-helper.js";
|
|
2
|
+
describe("currentInteractablesContextHelper", () => {
|
|
3
|
+
it("returns null by default (placeholder before provider replaces it)", () => {
|
|
4
|
+
expect(currentInteractablesContextHelper()).toBeNull();
|
|
5
|
+
});
|
|
6
|
+
});
|
|
7
|
+
describe("createInteractablesContextHelper", () => {
|
|
8
|
+
it("returns null when components array is empty", () => {
|
|
9
|
+
const helper = createInteractablesContextHelper([]);
|
|
10
|
+
expect(helper()).toBeNull();
|
|
11
|
+
});
|
|
12
|
+
it("maps valid component objects to metadata", () => {
|
|
13
|
+
const components = [
|
|
14
|
+
{
|
|
15
|
+
id: "comp-1",
|
|
16
|
+
name: "WeatherCard",
|
|
17
|
+
description: "Shows weather",
|
|
18
|
+
props: { city: "NYC" },
|
|
19
|
+
propsSchema: { type: "object" },
|
|
20
|
+
state: { temp: 72 },
|
|
21
|
+
isSelectedForInteraction: true,
|
|
22
|
+
stateSchema: { type: "object" },
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
const helper = createInteractablesContextHelper(components);
|
|
26
|
+
const result = helper();
|
|
27
|
+
expect(result).toEqual({
|
|
28
|
+
components: [
|
|
29
|
+
{
|
|
30
|
+
id: "comp-1",
|
|
31
|
+
componentName: "WeatherCard",
|
|
32
|
+
description: "Shows weather",
|
|
33
|
+
props: { city: "NYC" },
|
|
34
|
+
propsSchema: "Available - use component-specific update tools",
|
|
35
|
+
state: { temp: 72 },
|
|
36
|
+
isSelectedForInteraction: true,
|
|
37
|
+
stateSchema: "Available - use component-specific update tools",
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
it("handles invalid (non-object) components gracefully", () => {
|
|
43
|
+
const components = [null, "not-an-object", 42];
|
|
44
|
+
const helper = createInteractablesContextHelper(components);
|
|
45
|
+
const result = helper();
|
|
46
|
+
expect(result?.components).toHaveLength(3);
|
|
47
|
+
for (const comp of result?.components ?? []) {
|
|
48
|
+
expect(comp.id).toBe("unknown");
|
|
49
|
+
expect(comp.componentName).toBe("unknown");
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
it("uses defaults for missing properties", () => {
|
|
53
|
+
const components = [{}];
|
|
54
|
+
const helper = createInteractablesContextHelper(components);
|
|
55
|
+
const result = helper();
|
|
56
|
+
expect(result?.components[0]).toEqual({
|
|
57
|
+
id: "unknown",
|
|
58
|
+
componentName: "unknown",
|
|
59
|
+
description: "",
|
|
60
|
+
props: undefined,
|
|
61
|
+
propsSchema: "Not specified",
|
|
62
|
+
state: undefined,
|
|
63
|
+
isSelectedForInteraction: false,
|
|
64
|
+
stateSchema: "Not specified",
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
//# sourceMappingURL=current-interactables-context-helper.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"current-interactables-context-helper.test.js","sourceRoot":"","sources":["../../src/context-helpers/current-interactables-context-helper.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n currentInteractablesContextHelper,\n createInteractablesContextHelper,\n} from \"./current-interactables-context-helper\";\n\ndescribe(\"currentInteractablesContextHelper\", () => {\n it(\"returns null by default (placeholder before provider replaces it)\", () => {\n expect(currentInteractablesContextHelper()).toBeNull();\n });\n});\n\ndescribe(\"createInteractablesContextHelper\", () => {\n it(\"returns null when components array is empty\", () => {\n const helper = createInteractablesContextHelper([]);\n expect(helper()).toBeNull();\n });\n\n it(\"maps valid component objects to metadata\", () => {\n const components = [\n {\n id: \"comp-1\",\n name: \"WeatherCard\",\n description: \"Shows weather\",\n props: { city: \"NYC\" },\n propsSchema: { type: \"object\" },\n state: { temp: 72 },\n isSelectedForInteraction: true,\n stateSchema: { type: \"object\" },\n },\n ];\n\n const helper = createInteractablesContextHelper(components);\n const result = helper();\n expect(result).toEqual({\n components: [\n {\n id: \"comp-1\",\n componentName: \"WeatherCard\",\n description: \"Shows weather\",\n props: { city: \"NYC\" },\n propsSchema: \"Available - use component-specific update tools\",\n state: { temp: 72 },\n isSelectedForInteraction: true,\n stateSchema: \"Available - use component-specific update tools\",\n },\n ],\n });\n });\n\n it(\"handles invalid (non-object) components gracefully\", () => {\n const components = [null, \"not-an-object\", 42];\n\n const helper = createInteractablesContextHelper(components);\n const result = helper();\n expect(result?.components).toHaveLength(3);\n for (const comp of result?.components ?? []) {\n expect(comp.id).toBe(\"unknown\");\n expect(comp.componentName).toBe(\"unknown\");\n }\n });\n\n it(\"uses defaults for missing properties\", () => {\n const components = [{}];\n\n const helper = createInteractablesContextHelper(components);\n const result = helper();\n expect(result?.components[0]).toEqual({\n id: \"unknown\",\n componentName: \"unknown\",\n description: \"\",\n props: undefined,\n propsSchema: \"Not specified\",\n state: undefined,\n isSelectedForInteraction: false,\n stateSchema: \"Not specified\",\n });\n });\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-tambo-interactable.d.ts","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.tsx"],"names":[],"mappings":"AACA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAK5C,MAAM,WAAW,kBAAkB,CACjC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC;;;OAGG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CAC7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,SAAS,MAAM,EACjE,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,EACrD,MAAM,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"with-tambo-interactable.d.ts","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.tsx"],"names":[],"mappings":"AACA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAK5C,MAAM,WAAW,kBAAkB,CACjC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC;;;OAGG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CAC7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,SAAS,MAAM,EACjE,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,EACrD,MAAM,EAAE,kBAAkB,yDAyI3B"}
|
|
@@ -39,7 +39,7 @@ import { ComponentContentProvider } from "../v1/utils/component-renderer.js";
|
|
|
39
39
|
export function withTamboInteractable(WrappedComponent, config) {
|
|
40
40
|
const displayName = WrappedComponent.displayName ?? WrappedComponent.name ?? "Component";
|
|
41
41
|
const TamboInteractableWrapper = (props) => {
|
|
42
|
-
const { addInteractableComponent, updateInteractableComponentProps, getInteractableComponent, } = useTamboInteractable();
|
|
42
|
+
const { addInteractableComponent, removeInteractableComponent, updateInteractableComponentProps, getInteractableComponent, } = useTamboInteractable();
|
|
43
43
|
const [interactableId, setInteractableId] = useState(null);
|
|
44
44
|
const isInitialized = useRef(false);
|
|
45
45
|
const lastSerializedProps = useRef({});
|
|
@@ -70,10 +70,19 @@ export function withTamboInteractable(WrappedComponent, config) {
|
|
|
70
70
|
isInitialized.current = true;
|
|
71
71
|
}
|
|
72
72
|
}, [addInteractableComponent, componentProps, onInteractableReady]);
|
|
73
|
-
// Register the component as interactable on mount
|
|
73
|
+
// Register the component as interactable on mount
|
|
74
74
|
useEffect(() => {
|
|
75
75
|
registerComponent();
|
|
76
76
|
}, [registerComponent]);
|
|
77
|
+
// Clean up on unmount only, keyed on stable values
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
return () => {
|
|
80
|
+
if (isInitialized.current && interactableId) {
|
|
81
|
+
removeInteractableComponent(interactableId);
|
|
82
|
+
isInitialized.current = false;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}, [interactableId, removeInteractableComponent]);
|
|
77
86
|
// Update the interactable component when props change from parent
|
|
78
87
|
useEffect(() => {
|
|
79
88
|
if (interactableId && isInitialized.current) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-tambo-interactable.js","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { ToolAnnotations } from \"../model/component-metadata\";\nimport { useTamboInteractable } from \"../providers/tambo-interactable-provider\";\nimport { SupportedSchema } from \"../schema\";\nimport { TamboMessageProvider } from \"../v1/hooks/use-tambo-current-message\";\nimport type { TamboThreadMessage } from \"../v1/types/message\";\nimport { ComponentContentProvider } from \"../v1/utils/component-renderer\";\n\nexport interface InteractableConfig<\n Props = Record<string, unknown>,\n State = Record<string, unknown>,\n> {\n /**\n * The name of the component, used for identification in Tambo.\n */\n componentName: string;\n /**\n * A brief description of the component's purpose and functionality. LLM will\n * use this to understand how to interact with it.\n */\n description: string;\n /**\n * Optional schema for component props. If provided, prop updates will be\n * validated against this schema.\n */\n propsSchema?: SupportedSchema<Props>;\n /**\n * Optional schema for component state. If provided, state updates will be\n * validated against this schema.\n */\n stateSchema?: SupportedSchema<State>;\n /**\n * Optional annotations for the interactable component's auto-registered tools\n * (props update and state update). By default, `tamboStreamableHint` is `true`\n * so props/state updates stream in real-time. Set `{ tamboStreamableHint: false }`\n * to disable streaming for this component's tools.\n */\n annotations?: ToolAnnotations;\n}\n\n/**\n * Props injected by withTamboInteractable HOC. These can be passed to the wrapped\n * component to customize interactable behavior.\n */\nexport interface WithTamboInteractableProps {\n /**\n * Optional ID to use for this interactable component instance.\n * If not provided, a unique ID will be generated automatically.\n */\n interactableId?: string;\n /**\n * Callback fired when the component has been registered as interactable.\n * @param id - The assigned interactable component ID\n */\n onInteractableReady?: (id: string) => void;\n /**\n * Callback fired when the component's serializable props are updated by Tambo\n * through a tool call. Note: Only serializable props are tracked.\n * @param newProps - The updated serializable props\n */\n onPropsUpdate?: (newProps: Record<string, unknown>) => void;\n}\n\n/**\n * Higher-Order Component that makes any component interactable by tambo.\n * @param WrappedComponent - The component to make interactable\n * @param config - Configuration for the interactable component\n * @returns A new component that is automatically registered as interactable\n * @example\n * ```tsx\n * const MyNote: React.FC<{ title: string; content: string }> = ({ title, content }) => {\n * const [isPinned, setIsPinned] = useTamboComponentState(\"isPinned\", false);\n * return (\n * <div style={{ border: isPinned ? \"2px solid gold\" : \"1px solid gray\", order: isPinned ? -1 : 0 }}>\n * <h2>{title}</h2>\n * <p>{content}</p>\n * </div>\n * );\n * };\n *\n * const MyInteractableNote = withTamboInteractable(MyNote, {\n * componentName: \"MyNote\",\n * description: \"A note component\",\n * propsSchema: z.object({\n * title: z.string(),\n * content: z.string(),\n * }),\n * stateSchema: z.object({\n * isPinned: z.boolean(),\n * }),\n * });\n *\n * // Usage\n * <MyInteractableNote title=\"My Note\" content=\"This is my note\" />\n * ```\n */\nexport function withTamboInteractable<ComponentProps extends object>(\n WrappedComponent: React.ComponentType<ComponentProps>,\n config: InteractableConfig,\n) {\n const displayName =\n WrappedComponent.displayName ?? WrappedComponent.name ?? \"Component\";\n\n const TamboInteractableWrapper: React.FC<\n ComponentProps & WithTamboInteractableProps\n > = (props) => {\n const {\n addInteractableComponent,\n updateInteractableComponentProps,\n getInteractableComponent,\n } = useTamboInteractable();\n\n const [interactableId, setInteractableId] = useState<string | null>(null);\n const isInitialized = useRef(false);\n const lastSerializedProps = useRef<Record<string, unknown>>({});\n\n // Extract interactable-specific props from component props\n const {\n interactableId: _providedId, // Reserved for future use\n onInteractableReady,\n onPropsUpdate,\n ...componentProps\n } = props;\n\n // Get the current interactable component to track prop updates\n const currentInteractable = interactableId\n ? getInteractableComponent(interactableId)\n : null;\n\n // Use the props from the interactable component if available, otherwise use the passed props\n // We need to be careful not to create a loop, so we only use stored props if they're different from passed props\n const effectiveProps = currentInteractable?.props ?? componentProps;\n\n // Memoize the registration function\n const registerComponent = useCallback(() => {\n if (!isInitialized.current) {\n const id = addInteractableComponent({\n name: config.componentName,\n description: config.description,\n component: WrappedComponent,\n props: componentProps,\n propsSchema: config.propsSchema,\n stateSchema: config.stateSchema,\n annotations: config.annotations,\n });\n\n setInteractableId(id);\n onInteractableReady?.(id);\n isInitialized.current = true;\n }\n }, [addInteractableComponent, componentProps, onInteractableReady]);\n\n // Register the component as interactable on mount (only once)\n useEffect(() => {\n registerComponent();\n }, [registerComponent]);\n\n // Update the interactable component when props change from parent\n useEffect(() => {\n if (interactableId && isInitialized.current) {\n // Only update if the props are different from what we last sent\n const lastPropsString = JSON.stringify(lastSerializedProps.current);\n const currentPropsString = JSON.stringify(componentProps);\n\n if (lastPropsString !== currentPropsString) {\n updateInteractableComponentProps(interactableId, componentProps);\n onPropsUpdate?.(componentProps);\n lastSerializedProps.current = componentProps;\n }\n }\n }, [\n interactableId,\n componentProps,\n updateInteractableComponentProps,\n onPropsUpdate,\n ]);\n\n // If the interactable ID is not yet set, render the component without provider\n if (!interactableId) {\n return <WrappedComponent {...(effectiveProps as ComponentProps)} />;\n }\n\n // Create a minimal message with interactable metadata\n // This allows useTamboCurrentComponent to work with standalone interactable components\n const minimalMessage: TamboThreadMessage = {\n id: interactableId,\n role: \"assistant\" as const,\n content: [\n {\n type: \"component\" as const,\n id: interactableId,\n name: config.componentName,\n props: effectiveProps,\n state: {},\n },\n ],\n createdAt: new Date().toISOString(),\n };\n\n // Wrap with TamboMessageProvider and ComponentContentProvider including interactable metadata\n return (\n <TamboMessageProvider\n message={minimalMessage}\n interactableMetadata={{\n id: interactableId,\n componentName: config.componentName,\n description: config.description,\n }}\n >\n <ComponentContentProvider\n componentId={interactableId}\n threadId=\"\"\n messageId=\"\"\n componentName={config.componentName}\n >\n <WrappedComponent {...(effectiveProps as ComponentProps)} />\n </ComponentContentProvider>\n </TamboMessageProvider>\n );\n };\n\n TamboInteractableWrapper.displayName = `withTamboInteractable(${displayName})`;\n\n return TamboInteractableWrapper;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"with-tambo-interactable.js","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { ToolAnnotations } from \"../model/component-metadata\";\nimport { useTamboInteractable } from \"../providers/tambo-interactable-provider\";\nimport { SupportedSchema } from \"../schema\";\nimport { TamboMessageProvider } from \"../v1/hooks/use-tambo-current-message\";\nimport type { TamboThreadMessage } from \"../v1/types/message\";\nimport { ComponentContentProvider } from \"../v1/utils/component-renderer\";\n\nexport interface InteractableConfig<\n Props = Record<string, unknown>,\n State = Record<string, unknown>,\n> {\n /**\n * The name of the component, used for identification in Tambo.\n */\n componentName: string;\n /**\n * A brief description of the component's purpose and functionality. LLM will\n * use this to understand how to interact with it.\n */\n description: string;\n /**\n * Optional schema for component props. If provided, prop updates will be\n * validated against this schema.\n */\n propsSchema?: SupportedSchema<Props>;\n /**\n * Optional schema for component state. If provided, state updates will be\n * validated against this schema.\n */\n stateSchema?: SupportedSchema<State>;\n /**\n * Optional annotations for the interactable component's auto-registered tools\n * (props update and state update). By default, `tamboStreamableHint` is `true`\n * so props/state updates stream in real-time. Set `{ tamboStreamableHint: false }`\n * to disable streaming for this component's tools.\n */\n annotations?: ToolAnnotations;\n}\n\n/**\n * Props injected by withTamboInteractable HOC. These can be passed to the wrapped\n * component to customize interactable behavior.\n */\nexport interface WithTamboInteractableProps {\n /**\n * Optional ID to use for this interactable component instance.\n * If not provided, a unique ID will be generated automatically.\n */\n interactableId?: string;\n /**\n * Callback fired when the component has been registered as interactable.\n * @param id - The assigned interactable component ID\n */\n onInteractableReady?: (id: string) => void;\n /**\n * Callback fired when the component's serializable props are updated by Tambo\n * through a tool call. Note: Only serializable props are tracked.\n * @param newProps - The updated serializable props\n */\n onPropsUpdate?: (newProps: Record<string, unknown>) => void;\n}\n\n/**\n * Higher-Order Component that makes any component interactable by tambo.\n * @param WrappedComponent - The component to make interactable\n * @param config - Configuration for the interactable component\n * @returns A new component that is automatically registered as interactable\n * @example\n * ```tsx\n * const MyNote: React.FC<{ title: string; content: string }> = ({ title, content }) => {\n * const [isPinned, setIsPinned] = useTamboComponentState(\"isPinned\", false);\n * return (\n * <div style={{ border: isPinned ? \"2px solid gold\" : \"1px solid gray\", order: isPinned ? -1 : 0 }}>\n * <h2>{title}</h2>\n * <p>{content}</p>\n * </div>\n * );\n * };\n *\n * const MyInteractableNote = withTamboInteractable(MyNote, {\n * componentName: \"MyNote\",\n * description: \"A note component\",\n * propsSchema: z.object({\n * title: z.string(),\n * content: z.string(),\n * }),\n * stateSchema: z.object({\n * isPinned: z.boolean(),\n * }),\n * });\n *\n * // Usage\n * <MyInteractableNote title=\"My Note\" content=\"This is my note\" />\n * ```\n */\nexport function withTamboInteractable<ComponentProps extends object>(\n WrappedComponent: React.ComponentType<ComponentProps>,\n config: InteractableConfig,\n) {\n const displayName =\n WrappedComponent.displayName ?? WrappedComponent.name ?? \"Component\";\n\n const TamboInteractableWrapper: React.FC<\n ComponentProps & WithTamboInteractableProps\n > = (props) => {\n const {\n addInteractableComponent,\n removeInteractableComponent,\n updateInteractableComponentProps,\n getInteractableComponent,\n } = useTamboInteractable();\n\n const [interactableId, setInteractableId] = useState<string | null>(null);\n const isInitialized = useRef(false);\n const lastSerializedProps = useRef<Record<string, unknown>>({});\n\n // Extract interactable-specific props from component props\n const {\n interactableId: _providedId, // Reserved for future use\n onInteractableReady,\n onPropsUpdate,\n ...componentProps\n } = props;\n\n // Get the current interactable component to track prop updates\n const currentInteractable = interactableId\n ? getInteractableComponent(interactableId)\n : null;\n\n // Use the props from the interactable component if available, otherwise use the passed props\n // We need to be careful not to create a loop, so we only use stored props if they're different from passed props\n const effectiveProps = currentInteractable?.props ?? componentProps;\n\n // Memoize the registration function\n const registerComponent = useCallback(() => {\n if (!isInitialized.current) {\n const id = addInteractableComponent({\n name: config.componentName,\n description: config.description,\n component: WrappedComponent,\n props: componentProps,\n propsSchema: config.propsSchema,\n stateSchema: config.stateSchema,\n annotations: config.annotations,\n });\n\n setInteractableId(id);\n onInteractableReady?.(id);\n isInitialized.current = true;\n }\n }, [addInteractableComponent, componentProps, onInteractableReady]);\n\n // Register the component as interactable on mount\n useEffect(() => {\n registerComponent();\n }, [registerComponent]);\n\n // Clean up on unmount only, keyed on stable values\n useEffect(() => {\n return () => {\n if (isInitialized.current && interactableId) {\n removeInteractableComponent(interactableId);\n isInitialized.current = false;\n }\n };\n }, [interactableId, removeInteractableComponent]);\n\n // Update the interactable component when props change from parent\n useEffect(() => {\n if (interactableId && isInitialized.current) {\n // Only update if the props are different from what we last sent\n const lastPropsString = JSON.stringify(lastSerializedProps.current);\n const currentPropsString = JSON.stringify(componentProps);\n\n if (lastPropsString !== currentPropsString) {\n updateInteractableComponentProps(interactableId, componentProps);\n onPropsUpdate?.(componentProps);\n lastSerializedProps.current = componentProps;\n }\n }\n }, [\n interactableId,\n componentProps,\n updateInteractableComponentProps,\n onPropsUpdate,\n ]);\n\n // If the interactable ID is not yet set, render the component without provider\n if (!interactableId) {\n return <WrappedComponent {...(effectiveProps as ComponentProps)} />;\n }\n\n // Create a minimal message with interactable metadata\n // This allows useTamboCurrentComponent to work with standalone interactable components\n const minimalMessage: TamboThreadMessage = {\n id: interactableId,\n role: \"assistant\" as const,\n content: [\n {\n type: \"component\" as const,\n id: interactableId,\n name: config.componentName,\n props: effectiveProps,\n state: {},\n },\n ],\n createdAt: new Date().toISOString(),\n };\n\n // Wrap with TamboMessageProvider and ComponentContentProvider including interactable metadata\n return (\n <TamboMessageProvider\n message={minimalMessage}\n interactableMetadata={{\n id: interactableId,\n componentName: config.componentName,\n description: config.description,\n }}\n >\n <ComponentContentProvider\n componentId={interactableId}\n threadId=\"\"\n messageId=\"\"\n componentName={config.componentName}\n >\n <WrappedComponent {...(effectiveProps as ComponentProps)} />\n </ComponentContentProvider>\n </TamboMessageProvider>\n );\n };\n\n TamboInteractableWrapper.displayName = `withTamboInteractable(${displayName})`;\n\n return TamboInteractableWrapper;\n}\n"]}
|
|
@@ -195,5 +195,19 @@ describe("withTamboInteractable", () => {
|
|
|
195
195
|
expect(screen.getByTestId("optional")).toHaveTextContent("undefined");
|
|
196
196
|
expect(screen.getByTestId("nullable")).toHaveTextContent("null");
|
|
197
197
|
});
|
|
198
|
+
it("should call removeInteractableComponent on unmount", async () => {
|
|
199
|
+
const InteractableComponent = withTamboInteractable(TestComponent, {
|
|
200
|
+
componentName: "TestComponent",
|
|
201
|
+
description: "A test component",
|
|
202
|
+
propsSchema: testSchema,
|
|
203
|
+
});
|
|
204
|
+
const { unmount } = render(React.createElement(TamboInteractableProvider, null,
|
|
205
|
+
React.createElement(InteractableComponent, { title: "Unmount Test" })));
|
|
206
|
+
await waitFor(() => {
|
|
207
|
+
expect(mockAddInteractableComponent).toHaveBeenCalled();
|
|
208
|
+
});
|
|
209
|
+
unmount();
|
|
210
|
+
expect(mockRemoveInteractableComponent).toHaveBeenCalledWith("mock-id-123");
|
|
211
|
+
});
|
|
198
212
|
});
|
|
199
213
|
//# sourceMappingURL=with-tambo-interactable.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-tambo-interactable.test.js","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { render, screen, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod/v3\";\nimport { useTamboCurrentComponent } from \"../v1/hooks/use-tambo-current-message\";\nimport { TamboInteractableProvider } from \"../providers/tambo-interactable-provider\";\nimport { withTamboInteractable } from \"./with-tambo-interactable\";\n\n// Create a consistent mock implementation\nconst mockAddInteractableComponent = jest.fn(() => \"mock-id-123\");\nconst mockUpdateInteractableComponentProps = jest.fn();\nconst mockGetInteractableComponent = jest.fn(() => null);\nconst mockRemoveInteractableComponent = jest.fn();\nconst mockGetInteractableComponentsByName = jest.fn(() => []);\nconst mockClearAllInteractableComponents = jest.fn();\n\n// Mock the interactable provider\njest.mock(\"../providers/tambo-interactable-provider\", () => ({\n TamboInteractableProvider: ({ children }: { children: React.ReactNode }) => (\n <div data-testid=\"interactable-provider\">{children}</div>\n ),\n useTamboInteractable: () => ({\n addInteractableComponent: mockAddInteractableComponent,\n updateInteractableComponentProps: mockUpdateInteractableComponentProps,\n getInteractableComponent: mockGetInteractableComponent,\n removeInteractableComponent: mockRemoveInteractableComponent,\n getInteractableComponentsByName: mockGetInteractableComponentsByName,\n clearAllInteractableComponents: mockClearAllInteractableComponents,\n interactableComponents: [],\n }),\n}));\n\ndescribe(\"withTamboInteractable\", () => {\n // Simple test component\n interface TestComponentProps {\n title: string;\n count?: number;\n }\n\n const TestComponent: React.FC<TestComponentProps> = ({ title, count }) => (\n <div>\n <h1 data-testid=\"title\">{title}</h1>\n {count !== undefined && <span data-testid=\"count\">{count}</span>}\n </div>\n );\n\n const testSchema = z.object({\n title: z.string(),\n count: z.number().optional(),\n });\n\n beforeEach(() => {\n jest.clearAllMocks();\n // Reset mock implementations\n mockAddInteractableComponent.mockReturnValue(\"mock-id-123\");\n mockGetInteractableComponent.mockReturnValue(null);\n mockGetInteractableComponentsByName.mockReturnValue([]);\n });\n\n it(\"should render the wrapped component with provided props\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Hello\" count={42} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Hello\");\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"42\");\n });\n\n it(\"should set displayName correctly\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n expect(InteractableComponent.displayName).toBe(\n \"withTamboInteractable(TestComponent)\",\n );\n });\n\n it(\"should handle components without displayName\", () => {\n const AnonymousComponent = () => <div>Anonymous</div>;\n\n const InteractableComponent = withTamboInteractable(AnonymousComponent, {\n componentName: \"AnonymousComponent\",\n description: \"An anonymous component\",\n });\n\n // Anonymous components get their name from the function name\n expect(InteractableComponent.displayName).toBe(\n \"withTamboInteractable(AnonymousComponent)\",\n );\n });\n\n it(\"should provide TamboMessageProvider with interactable metadata\", async () => {\n // Child component that uses the context\n const ContextConsumer = () => {\n const component = useTamboCurrentComponent();\n return (\n <div>\n <span data-testid=\"interactable-id\">{component?.interactableId}</span>\n <span data-testid=\"component-name\">{component?.componentName}</span>\n <span data-testid=\"description\">{component?.description}</span>\n </div>\n );\n };\n\n // Wrap TestComponent to include ContextConsumer\n const TestComponentWithConsumer: React.FC<TestComponentProps> = (props) => (\n <div>\n <TestComponent {...props} />\n <ContextConsumer />\n </div>\n );\n\n const InteractableWithConsumer = withTamboInteractable(\n TestComponentWithConsumer,\n {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n },\n );\n\n render(\n <TamboInteractableProvider>\n <InteractableWithConsumer title=\"Hello\" />\n </TamboInteractableProvider>,\n );\n\n // Wait for the component to register and render\n await waitFor(() => {\n expect(screen.getByTestId(\"interactable-id\")).toHaveTextContent(\n \"mock-id-123\",\n );\n });\n\n expect(screen.getByTestId(\"component-name\")).toHaveTextContent(\n \"TestComponent\",\n );\n expect(screen.getByTestId(\"description\")).toHaveTextContent(\n \"A test component\",\n );\n });\n\n it(\"should create minimal message with correct structure\", async () => {\n // Child component that checks the message structure\n const MessageChecker = () => {\n const component = useTamboCurrentComponent();\n return (\n <div>\n <span data-testid=\"has-component-name\">\n {component?.componentName ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-props\">{component?.props ? \"yes\" : \"no\"}</span>\n <span data-testid=\"has-interactable-id\">\n {component?.interactableId ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-description\">\n {component?.description ? \"yes\" : \"no\"}\n </span>\n </div>\n );\n };\n\n const TestComponentWithChecker: React.FC<TestComponentProps> = (props) => (\n <div>\n <TestComponent {...props} />\n <MessageChecker />\n </div>\n );\n\n const InteractableWithChecker = withTamboInteractable(\n TestComponentWithChecker,\n {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n },\n );\n\n render(\n <TamboInteractableProvider>\n <InteractableWithChecker title=\"Hello\" count={42} />\n </TamboInteractableProvider>,\n );\n\n await waitFor(() => {\n expect(screen.getByTestId(\"has-component-name\")).toHaveTextContent(\"yes\");\n });\n\n expect(screen.getByTestId(\"has-props\")).toHaveTextContent(\"yes\");\n expect(screen.getByTestId(\"has-interactable-id\")).toHaveTextContent(\"yes\");\n expect(screen.getByTestId(\"has-description\")).toHaveTextContent(\"yes\");\n });\n\n it(\"should pass through all component props correctly\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test Title\" count={100} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test Title\");\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"100\");\n });\n\n it(\"should filter out interactable-specific props from component props\", () => {\n interface ExtendedProps extends TestComponentProps {\n onInteractableReady?: (id: string) => void;\n onPropsUpdate?: (props: Record<string, any>) => void;\n }\n\n const ExtendedComponent: React.FC<ExtendedProps> = ({\n title,\n onInteractableReady,\n onPropsUpdate,\n }) => (\n <div>\n <span data-testid=\"title\">{title}</span>\n <span data-testid=\"has-ready\">\n {onInteractableReady ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-update\">{onPropsUpdate ? \"yes\" : \"no\"}</span>\n </div>\n );\n\n const InteractableComponent = withTamboInteractable(ExtendedComponent, {\n componentName: \"ExtendedComponent\",\n description: \"An extended component\",\n });\n\n const mockReady = jest.fn();\n const mockUpdate = jest.fn();\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent\n title=\"Test\"\n onInteractableReady={mockReady}\n onPropsUpdate={mockUpdate}\n />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test\");\n // These props should be filtered out\n expect(screen.getByTestId(\"has-ready\")).toHaveTextContent(\"no\");\n expect(screen.getByTestId(\"has-update\")).toHaveTextContent(\"no\");\n });\n\n it(\"should pass annotations config to addInteractableComponent\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n annotations: { tamboStreamableHint: false },\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test\" />\n </TamboInteractableProvider>,\n );\n\n expect(mockAddInteractableComponent).toHaveBeenCalledWith(\n expect.objectContaining({\n annotations: { tamboStreamableHint: false },\n }),\n );\n });\n\n it(\"should work without propsSchema\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"No Schema\" />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"No Schema\");\n });\n\n it(\"should render before interactable ID is set\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n const { container } = render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Early Render\" />\n </TamboInteractableProvider>,\n );\n\n // Component should render even before ID is available\n expect(\n container.querySelector('[data-testid=\"title\"]'),\n ).toBeInTheDocument();\n });\n\n it(\"should handle null/undefined values in props\", () => {\n interface NullableProps {\n title: string;\n optional?: string;\n nullable: string | null;\n }\n\n const NullableComponent: React.FC<NullableProps> = ({\n title,\n optional,\n nullable,\n }) => (\n <div>\n <span data-testid=\"title\">{title}</span>\n <span data-testid=\"optional\">{optional ?? \"undefined\"}</span>\n <span data-testid=\"nullable\">{nullable ?? \"null\"}</span>\n </div>\n );\n\n const InteractableComponent = withTamboInteractable(NullableComponent, {\n componentName: \"NullableComponent\",\n description: \"A component with nullable props\",\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test\" nullable={null} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test\");\n expect(screen.getByTestId(\"optional\")).toHaveTextContent(\"undefined\");\n expect(screen.getByTestId(\"nullable\")).toHaveTextContent(\"null\");\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"with-tambo-interactable.test.js","sourceRoot":"","sources":["../../src/hoc/with-tambo-interactable.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { render, screen, waitFor } from \"@testing-library/react\";\nimport React from \"react\";\nimport { z } from \"zod/v3\";\nimport { useTamboCurrentComponent } from \"../v1/hooks/use-tambo-current-message\";\nimport { TamboInteractableProvider } from \"../providers/tambo-interactable-provider\";\nimport { withTamboInteractable } from \"./with-tambo-interactable\";\n\n// Create a consistent mock implementation\nconst mockAddInteractableComponent = jest.fn(() => \"mock-id-123\");\nconst mockUpdateInteractableComponentProps = jest.fn();\nconst mockGetInteractableComponent = jest.fn(() => null);\nconst mockRemoveInteractableComponent = jest.fn();\nconst mockGetInteractableComponentsByName = jest.fn(() => []);\nconst mockClearAllInteractableComponents = jest.fn();\n\n// Mock the interactable provider\njest.mock(\"../providers/tambo-interactable-provider\", () => ({\n TamboInteractableProvider: ({ children }: { children: React.ReactNode }) => (\n <div data-testid=\"interactable-provider\">{children}</div>\n ),\n useTamboInteractable: () => ({\n addInteractableComponent: mockAddInteractableComponent,\n updateInteractableComponentProps: mockUpdateInteractableComponentProps,\n getInteractableComponent: mockGetInteractableComponent,\n removeInteractableComponent: mockRemoveInteractableComponent,\n getInteractableComponentsByName: mockGetInteractableComponentsByName,\n clearAllInteractableComponents: mockClearAllInteractableComponents,\n interactableComponents: [],\n }),\n}));\n\ndescribe(\"withTamboInteractable\", () => {\n // Simple test component\n interface TestComponentProps {\n title: string;\n count?: number;\n }\n\n const TestComponent: React.FC<TestComponentProps> = ({ title, count }) => (\n <div>\n <h1 data-testid=\"title\">{title}</h1>\n {count !== undefined && <span data-testid=\"count\">{count}</span>}\n </div>\n );\n\n const testSchema = z.object({\n title: z.string(),\n count: z.number().optional(),\n });\n\n beforeEach(() => {\n jest.clearAllMocks();\n // Reset mock implementations\n mockAddInteractableComponent.mockReturnValue(\"mock-id-123\");\n mockGetInteractableComponent.mockReturnValue(null);\n mockGetInteractableComponentsByName.mockReturnValue([]);\n });\n\n it(\"should render the wrapped component with provided props\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Hello\" count={42} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Hello\");\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"42\");\n });\n\n it(\"should set displayName correctly\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n expect(InteractableComponent.displayName).toBe(\n \"withTamboInteractable(TestComponent)\",\n );\n });\n\n it(\"should handle components without displayName\", () => {\n const AnonymousComponent = () => <div>Anonymous</div>;\n\n const InteractableComponent = withTamboInteractable(AnonymousComponent, {\n componentName: \"AnonymousComponent\",\n description: \"An anonymous component\",\n });\n\n // Anonymous components get their name from the function name\n expect(InteractableComponent.displayName).toBe(\n \"withTamboInteractable(AnonymousComponent)\",\n );\n });\n\n it(\"should provide TamboMessageProvider with interactable metadata\", async () => {\n // Child component that uses the context\n const ContextConsumer = () => {\n const component = useTamboCurrentComponent();\n return (\n <div>\n <span data-testid=\"interactable-id\">{component?.interactableId}</span>\n <span data-testid=\"component-name\">{component?.componentName}</span>\n <span data-testid=\"description\">{component?.description}</span>\n </div>\n );\n };\n\n // Wrap TestComponent to include ContextConsumer\n const TestComponentWithConsumer: React.FC<TestComponentProps> = (props) => (\n <div>\n <TestComponent {...props} />\n <ContextConsumer />\n </div>\n );\n\n const InteractableWithConsumer = withTamboInteractable(\n TestComponentWithConsumer,\n {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n },\n );\n\n render(\n <TamboInteractableProvider>\n <InteractableWithConsumer title=\"Hello\" />\n </TamboInteractableProvider>,\n );\n\n // Wait for the component to register and render\n await waitFor(() => {\n expect(screen.getByTestId(\"interactable-id\")).toHaveTextContent(\n \"mock-id-123\",\n );\n });\n\n expect(screen.getByTestId(\"component-name\")).toHaveTextContent(\n \"TestComponent\",\n );\n expect(screen.getByTestId(\"description\")).toHaveTextContent(\n \"A test component\",\n );\n });\n\n it(\"should create minimal message with correct structure\", async () => {\n // Child component that checks the message structure\n const MessageChecker = () => {\n const component = useTamboCurrentComponent();\n return (\n <div>\n <span data-testid=\"has-component-name\">\n {component?.componentName ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-props\">{component?.props ? \"yes\" : \"no\"}</span>\n <span data-testid=\"has-interactable-id\">\n {component?.interactableId ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-description\">\n {component?.description ? \"yes\" : \"no\"}\n </span>\n </div>\n );\n };\n\n const TestComponentWithChecker: React.FC<TestComponentProps> = (props) => (\n <div>\n <TestComponent {...props} />\n <MessageChecker />\n </div>\n );\n\n const InteractableWithChecker = withTamboInteractable(\n TestComponentWithChecker,\n {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n },\n );\n\n render(\n <TamboInteractableProvider>\n <InteractableWithChecker title=\"Hello\" count={42} />\n </TamboInteractableProvider>,\n );\n\n await waitFor(() => {\n expect(screen.getByTestId(\"has-component-name\")).toHaveTextContent(\"yes\");\n });\n\n expect(screen.getByTestId(\"has-props\")).toHaveTextContent(\"yes\");\n expect(screen.getByTestId(\"has-interactable-id\")).toHaveTextContent(\"yes\");\n expect(screen.getByTestId(\"has-description\")).toHaveTextContent(\"yes\");\n });\n\n it(\"should pass through all component props correctly\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test Title\" count={100} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test Title\");\n expect(screen.getByTestId(\"count\")).toHaveTextContent(\"100\");\n });\n\n it(\"should filter out interactable-specific props from component props\", () => {\n interface ExtendedProps extends TestComponentProps {\n onInteractableReady?: (id: string) => void;\n onPropsUpdate?: (props: Record<string, any>) => void;\n }\n\n const ExtendedComponent: React.FC<ExtendedProps> = ({\n title,\n onInteractableReady,\n onPropsUpdate,\n }) => (\n <div>\n <span data-testid=\"title\">{title}</span>\n <span data-testid=\"has-ready\">\n {onInteractableReady ? \"yes\" : \"no\"}\n </span>\n <span data-testid=\"has-update\">{onPropsUpdate ? \"yes\" : \"no\"}</span>\n </div>\n );\n\n const InteractableComponent = withTamboInteractable(ExtendedComponent, {\n componentName: \"ExtendedComponent\",\n description: \"An extended component\",\n });\n\n const mockReady = jest.fn();\n const mockUpdate = jest.fn();\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent\n title=\"Test\"\n onInteractableReady={mockReady}\n onPropsUpdate={mockUpdate}\n />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test\");\n // These props should be filtered out\n expect(screen.getByTestId(\"has-ready\")).toHaveTextContent(\"no\");\n expect(screen.getByTestId(\"has-update\")).toHaveTextContent(\"no\");\n });\n\n it(\"should pass annotations config to addInteractableComponent\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n annotations: { tamboStreamableHint: false },\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test\" />\n </TamboInteractableProvider>,\n );\n\n expect(mockAddInteractableComponent).toHaveBeenCalledWith(\n expect.objectContaining({\n annotations: { tamboStreamableHint: false },\n }),\n );\n });\n\n it(\"should work without propsSchema\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"No Schema\" />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"No Schema\");\n });\n\n it(\"should render before interactable ID is set\", () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n });\n\n const { container } = render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Early Render\" />\n </TamboInteractableProvider>,\n );\n\n // Component should render even before ID is available\n expect(\n container.querySelector('[data-testid=\"title\"]'),\n ).toBeInTheDocument();\n });\n\n it(\"should handle null/undefined values in props\", () => {\n interface NullableProps {\n title: string;\n optional?: string;\n nullable: string | null;\n }\n\n const NullableComponent: React.FC<NullableProps> = ({\n title,\n optional,\n nullable,\n }) => (\n <div>\n <span data-testid=\"title\">{title}</span>\n <span data-testid=\"optional\">{optional ?? \"undefined\"}</span>\n <span data-testid=\"nullable\">{nullable ?? \"null\"}</span>\n </div>\n );\n\n const InteractableComponent = withTamboInteractable(NullableComponent, {\n componentName: \"NullableComponent\",\n description: \"A component with nullable props\",\n });\n\n render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Test\" nullable={null} />\n </TamboInteractableProvider>,\n );\n\n expect(screen.getByTestId(\"title\")).toHaveTextContent(\"Test\");\n expect(screen.getByTestId(\"optional\")).toHaveTextContent(\"undefined\");\n expect(screen.getByTestId(\"nullable\")).toHaveTextContent(\"null\");\n });\n\n it(\"should call removeInteractableComponent on unmount\", async () => {\n const InteractableComponent = withTamboInteractable(TestComponent, {\n componentName: \"TestComponent\",\n description: \"A test component\",\n propsSchema: testSchema,\n });\n\n const { unmount } = render(\n <TamboInteractableProvider>\n <InteractableComponent title=\"Unmount Test\" />\n </TamboInteractableProvider>,\n );\n\n await waitFor(() => {\n expect(mockAddInteractableComponent).toHaveBeenCalled();\n });\n\n unmount();\n\n expect(mockRemoveInteractableComponent).toHaveBeenCalledWith(\"mock-id-123\");\n });\n});\n"]}
|
package/esm/mcp/elicitation.d.ts
CHANGED
|
@@ -1,40 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* Schema type for elicitation request fields
|
|
5
|
-
*/
|
|
6
|
-
export type ElicitationRequestedSchema = ElicitRequestFormParams["requestedSchema"];
|
|
7
|
-
/**
|
|
8
|
-
* Elicitation request from MCP server
|
|
9
|
-
*/
|
|
10
|
-
export interface TamboElicitationRequest {
|
|
11
|
-
message: string;
|
|
12
|
-
requestedSchema: ElicitationRequestedSchema;
|
|
13
|
-
/** AbortSignal that fires when the server cancels the request (e.g., timeout) */
|
|
14
|
-
signal?: AbortSignal;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Re-export PrimitiveSchemaDefinition for consumers that need to work with schema fields
|
|
18
|
-
*/
|
|
19
|
-
export type { PrimitiveSchemaDefinition };
|
|
20
|
-
/**
|
|
21
|
-
* Elicitation response to be sent back
|
|
22
|
-
*/
|
|
23
|
-
export interface TamboElicitationResponse {
|
|
24
|
-
action: "accept" | "decline" | "cancel";
|
|
25
|
-
content?: Record<string, unknown>;
|
|
26
|
-
[x: string]: unknown;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Elicitation context state - read-only interface for consumers.
|
|
30
|
-
* State management is handled internally by useElicitation hook.
|
|
31
|
-
*/
|
|
32
|
-
export interface ElicitationContextState {
|
|
33
|
-
/** Current elicitation request, or null if none active */
|
|
34
|
-
elicitation: TamboElicitationRequest | null;
|
|
35
|
-
/** Function to call when user responds to elicitation (clears state automatically) */
|
|
36
|
-
resolveElicitation: ((response: TamboElicitationResponse) => void) | null;
|
|
37
|
-
}
|
|
1
|
+
import type { MCPElicitationHandler, TamboElicitationRequest, TamboElicitationResponse } from "@tambo-ai/client";
|
|
2
|
+
export type { ElicitationRequestedSchema, TamboElicitationRequest, TamboElicitationResponse, ElicitationContextState, PrimitiveSchemaDefinition, } from "@tambo-ai/client";
|
|
3
|
+
export { toElicitationRequestedSchema, hasRequestedSchema, } from "@tambo-ai/client";
|
|
38
4
|
/**
|
|
39
5
|
* Internal hook that manages elicitation state and creates a default handler.
|
|
40
6
|
* This bundles all the state management and handler creation for elicitation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elicitation.d.ts","sourceRoot":"","sources":["../../src/mcp/elicitation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"elicitation.d.ts","sourceRoot":"","sources":["../../src/mcp/elicitation.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,kBAAkB,CAAC;AAO1B,YAAY,EACV,0BAA0B,EAC1B,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,4BAA4B,EAC5B,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B;;;;;;GAMG;AACH,wBAAgB,cAAc;;;oCAId,wBAAwB,KAAK,IAAI;+FAAjC,wBAAwB,KAAK,IAAI;;EAoEhD"}
|
package/esm/mcp/elicitation.js
CHANGED
|
@@ -1,26 +1,6 @@
|
|
|
1
1
|
import { useCallback, useState } from "react";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* ElicitationRequestedSchema type.
|
|
5
|
-
*
|
|
6
|
-
* The MCP SDK guarantees that the runtime
|
|
7
|
-
* `ElicitRequest["params"]["requestedSchema"]` shape stays aligned with the
|
|
8
|
-
* spec-defined `ElicitRequestFormParams["requestedSchema"]`. This helper
|
|
9
|
-
* centralizes the cast based on that contract so that if a future SDK version
|
|
10
|
-
* ever diverges, we have a single place to tighten the implementation (for
|
|
11
|
-
* example with structural validation or normalization).
|
|
12
|
-
* @returns requestedSchema as ElicitationRequestedSchema
|
|
13
|
-
*/
|
|
14
|
-
function toElicitationRequestedSchema(value) {
|
|
15
|
-
return value;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Type guard for the elicitation form params shape.
|
|
19
|
-
* @returns true when params include requestedSchema
|
|
20
|
-
*/
|
|
21
|
-
function hasRequestedSchema(params) {
|
|
22
|
-
return "requestedSchema" in params;
|
|
23
|
-
}
|
|
2
|
+
import { toElicitationRequestedSchema as toSchema, hasRequestedSchema as hasSchema, } from "@tambo-ai/client";
|
|
3
|
+
export { toElicitationRequestedSchema, hasRequestedSchema, } from "@tambo-ai/client";
|
|
24
4
|
/**
|
|
25
5
|
* Internal hook that manages elicitation state and creates a default handler.
|
|
26
6
|
* This bundles all the state management and handler creation for elicitation.
|
|
@@ -33,7 +13,7 @@ export function useElicitation() {
|
|
|
33
13
|
const [resolveElicitation, setResolveElicitation] = useState(null);
|
|
34
14
|
const defaultElicitationHandler = useCallback(async (request, extra) => {
|
|
35
15
|
return await new Promise((resolve, reject) => {
|
|
36
|
-
if (!
|
|
16
|
+
if (!hasSchema(request.params)) {
|
|
37
17
|
const mode = "mode" in request.params ? String(request.params.mode) : "unknown";
|
|
38
18
|
reject(new Error(`Unsupported MCP elicitation params: expected requestedSchema (form mode), got mode=${mode}`));
|
|
39
19
|
return;
|
|
@@ -44,7 +24,7 @@ export function useElicitation() {
|
|
|
44
24
|
// for cross-version compatibility
|
|
45
25
|
setElicitation({
|
|
46
26
|
message: request.params.message,
|
|
47
|
-
requestedSchema:
|
|
27
|
+
requestedSchema: toSchema(request.params.requestedSchema),
|
|
48
28
|
signal: extra.signal,
|
|
49
29
|
});
|
|
50
30
|
// If the signal is already aborted, reject immediately
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elicitation.js","sourceRoot":"","sources":["../../src/mcp/elicitation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"elicitation.js","sourceRoot":"","sources":["../../src/mcp/elicitation.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAM9C,OAAO,EACL,4BAA4B,IAAI,QAAQ,EACxC,kBAAkB,IAAI,SAAS,GAChC,MAAM,kBAAkB,CAAC;AAU1B,OAAO,EACL,4BAA4B,EAC5B,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B;;;;;;GAMG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GACjC,QAAQ,CAAiC,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,QAAQ,CAE1D,IAAI,CAAC,CAAC;IAER,MAAM,yBAAyB,GAA0B,WAAW,CAClE,KAAK,EACH,OAAsB,EACtB,KAA6D,EACtC,EAAE;QACzB,OAAO,MAAM,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACzD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,GACR,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAErE,MAAM,CACJ,IAAI,KAAK,CACP,sFAAsF,IAAI,EAAE,CAC7F,CACF,CAAC;gBACF,OAAO;YACT,CAAC;YAED,6CAA6C;YAC7C,yEAAyE;YACzE,yEAAyE;YACzE,kCAAkC;YAClC,cAAc,CAAC;gBACb,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO;gBAC/B,eAAe,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC;gBACzD,MAAM,EAAE,KAAK,CAAC,MAAM;aACrB,CAAC,CAAC;YAEH,uDAAuD;YACvD,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACzB,cAAc,CAAC,IAAI,CAAC,CAAC;gBACrB,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBACrC,OAAO;YACT,CAAC;YAED,sCAAsC;YACtC,MAAM,WAAW,GAAG,GAAG,EAAE;gBACvB,cAAc,CAAC,IAAI,CAAC,CAAC;gBACrB,qBAAqB,CAAC,IAAI,CAAC,CAAC;gBAC5B,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;YACvC,CAAC,CAAC;YAEF,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAEpE,sEAAsE;YACtE,qBAAqB,CAAC,GAAG,EAAE,CAAC,CAAC,QAAsB,EAAE,EAAE;gBACrD,uDAAuD;gBACvD,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;gBACvD,0CAA0C;gBAC1C,cAAc,CAAC,IAAI,CAAC,CAAC;gBACrB,qBAAqB,CAAC,IAAI,CAAC,CAAC;gBAC5B,OAAO,CAAC,QAAQ,CAAC,CAAC;YACpB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,EACD,EAAE,CACH,CAAC;IAEF,OAAO;QACL,WAAW;QACX,cAAc;QACd,kBAAkB;QAClB,qBAAqB;QACrB,yBAAyB;KAC1B,CAAC;AACJ,CAAC","sourcesContent":["// React-specific hook (not in client package)\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n ClientNotification,\n ClientRequest,\n ElicitRequest,\n ElicitResult,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { useCallback, useState } from \"react\";\nimport type {\n MCPElicitationHandler,\n TamboElicitationRequest,\n TamboElicitationResponse,\n} from \"@tambo-ai/client\";\nimport {\n toElicitationRequestedSchema as toSchema,\n hasRequestedSchema as hasSchema,\n} from \"@tambo-ai/client\";\n\n// Re-export types and functions from @tambo-ai/client for barrel consumers\nexport type {\n ElicitationRequestedSchema,\n TamboElicitationRequest,\n TamboElicitationResponse,\n ElicitationContextState,\n PrimitiveSchemaDefinition,\n} from \"@tambo-ai/client\";\nexport {\n toElicitationRequestedSchema,\n hasRequestedSchema,\n} from \"@tambo-ai/client\";\n\n/**\n * Internal hook that manages elicitation state and creates a default handler.\n * This bundles all the state management and handler creation for elicitation.\n *\n * Do not export this hook from this package. It is only intended to be used internally by the TamboMcpProvider.\n * @returns Elicitation state and default handler\n */\nexport function useElicitation() {\n const [elicitation, setElicitation] =\n useState<TamboElicitationRequest | null>(null);\n const [resolveElicitation, setResolveElicitation] = useState<\n ((response: TamboElicitationResponse) => void) | null\n >(null);\n\n const defaultElicitationHandler: MCPElicitationHandler = useCallback(\n async (\n request: ElicitRequest,\n extra: RequestHandlerExtra<ClientRequest, ClientNotification>,\n ): Promise<ElicitResult> => {\n return await new Promise<ElicitResult>((resolve, reject) => {\n if (!hasSchema(request.params)) {\n const mode =\n \"mode\" in request.params ? String(request.params.mode) : \"unknown\";\n\n reject(\n new Error(\n `Unsupported MCP elicitation params: expected requestedSchema (form mode), got mode=${mode}`,\n ),\n );\n return;\n }\n\n // Set the elicitation request to show the UI\n // Cast is needed because ElicitRequest uses Zod-inferred types (from the\n // user's installed zod version), while we use pure TypeScript spec types\n // for cross-version compatibility\n setElicitation({\n message: request.params.message,\n requestedSchema: toSchema(request.params.requestedSchema),\n signal: extra.signal,\n });\n\n // If the signal is already aborted, reject immediately\n if (extra.signal.aborted) {\n setElicitation(null);\n reject(new Error(\"Request aborted\"));\n return;\n }\n\n // Listen for abort signal to clean up\n const handleAbort = () => {\n setElicitation(null);\n setResolveElicitation(null);\n reject(new Error(\"Request aborted\"));\n };\n\n extra.signal.addEventListener(\"abort\", handleAbort, { once: true });\n\n // Store the resolve function so we can call it when the user responds\n setResolveElicitation(() => (response: ElicitResult) => {\n // Remove abort listener since we're resolving normally\n extra.signal.removeEventListener(\"abort\", handleAbort);\n // Clear state now that user has responded\n setElicitation(null);\n setResolveElicitation(null);\n resolve(response);\n });\n });\n },\n [],\n );\n\n return {\n elicitation,\n setElicitation,\n resolveElicitation,\n setResolveElicitation,\n defaultElicitationHandler,\n };\n}\n"]}
|
package/esm/mcp/index.d.ts
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
* you'll need to install `zod` and `zod-to-json-schema` as optional peer dependencies.
|
|
7
7
|
* See the React SDK README for the recommended version ranges.
|
|
8
8
|
*/
|
|
9
|
-
export { MCPTransport } from "
|
|
10
|
-
export type { MCPElicitationHandler, MCPHandlers, MCPSamplingHandler, } from "
|
|
11
|
-
export type { ElicitationRequestedSchema, PrimitiveSchemaDefinition, TamboElicitationRequest, TamboElicitationResponse, } from "
|
|
9
|
+
export { MCPTransport } from "@tambo-ai/client";
|
|
10
|
+
export type { MCPElicitationHandler, MCPHandlers, MCPSamplingHandler, } from "@tambo-ai/client";
|
|
11
|
+
export type { ElicitationRequestedSchema, PrimitiveSchemaDefinition, TamboElicitationRequest, TamboElicitationResponse, } from "@tambo-ai/client";
|
|
12
12
|
export { useTamboMcpPrompt, useTamboMcpPromptList, useTamboMcpResource, useTamboMcpResourceList, isMcpResourceEntry, } from "./mcp-hooks.js";
|
|
13
13
|
export type { ListPromptEntry, ListPromptItem, ListResourceEntry, ListResourceItem, } from "./mcp-hooks.js";
|
|
14
14
|
export { TamboMcpProvider, useTamboMcpElicitation, useTamboMcpServers, useTamboElicitationContext, type ConnectedMcpServer, type FailedMcpServer, type McpServer, type ProviderMCPHandlers, } from "./tambo-mcp-provider.js";
|
|
15
|
-
export type { McpServerInfo, NormalizedMcpServerInfo
|
|
15
|
+
export type { McpServerInfo, NormalizedMcpServerInfo } from "@tambo-ai/client";
|
|
16
16
|
//# sourceMappingURL=index.d.ts.map
|
package/esm/mcp/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EACV,qBAAqB,EACrB,WAAW,EACX,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,0BAA0B,EAC1B,yBAAyB,EACzB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,0BAA0B,EAC1B,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,mBAAmB,GACzB,MAAM,sBAAsB,CAAC;AAG9B,YAAY,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC"}
|