@tambo-ai/react 0.65.2 → 0.66.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +174 -81
- package/dist/context-helpers/context-helpers-provider.test.d.ts.map +1 -0
- package/dist/context-helpers/{__tests__/context-helpers-provider.test.js → context-helpers-provider.test.js} +2 -2
- package/dist/context-helpers/context-helpers-provider.test.js.map +1 -0
- package/dist/context-helpers/context-helpers.test.d.ts.map +1 -0
- package/dist/context-helpers/{__tests__/context-helpers.test.js → context-helpers.test.js} +1 -1
- package/dist/context-helpers/context-helpers.test.js.map +1 -0
- package/{esm/providers → dist}/hoc/with-tambo-interactable.d.ts +2 -2
- package/dist/hoc/with-tambo-interactable.d.ts.map +1 -0
- package/dist/{providers/hoc → hoc}/with-tambo-interactable.js +29 -2
- package/dist/hoc/with-tambo-interactable.js.map +1 -0
- package/dist/hoc/with-tambo-interactable.test.d.ts +2 -0
- package/dist/hoc/with-tambo-interactable.test.d.ts.map +1 -0
- package/dist/hoc/with-tambo-interactable.test.js +192 -0
- package/dist/hoc/with-tambo-interactable.test.js.map +1 -0
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +2 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/use-component-state.d.ts +11 -24
- package/dist/hooks/use-component-state.d.ts.map +1 -1
- package/dist/hooks/use-component-state.js +14 -5
- package/dist/hooks/use-component-state.js.map +1 -1
- package/dist/hooks/use-component-state.test.d.ts.map +1 -0
- package/dist/hooks/{__tests__/use-component-state.test.js → use-component-state.test.js} +7 -7
- package/dist/hooks/use-component-state.test.js.map +1 -0
- package/dist/hooks/use-current-message.d.ts +51 -7
- package/dist/hooks/use-current-message.d.ts.map +1 -1
- package/dist/hooks/use-current-message.js +50 -6
- package/dist/hooks/use-current-message.js.map +1 -1
- package/dist/hooks/use-current-message.test.d.ts +2 -0
- package/dist/hooks/use-current-message.test.d.ts.map +1 -0
- package/dist/hooks/use-current-message.test.js +264 -0
- package/dist/hooks/use-current-message.test.js.map +1 -0
- package/dist/hooks/use-message-images.test.d.ts.map +1 -0
- package/dist/hooks/{__tests__/use-message-images.test.js → use-message-images.test.js} +1 -1
- package/dist/hooks/use-message-images.test.js.map +1 -0
- package/dist/hooks/use-streaming-props.d.ts +7 -19
- package/dist/hooks/use-streaming-props.d.ts.map +1 -1
- package/dist/hooks/use-streaming-props.js +7 -19
- package/dist/hooks/use-streaming-props.js.map +1 -1
- package/dist/hooks/use-suggestions.d.ts +1 -1
- package/dist/hooks/use-suggestions.d.ts.map +1 -1
- package/dist/hooks/use-suggestions.js.map +1 -1
- package/dist/hooks/use-suggestions.test.d.ts.map +1 -0
- package/dist/hooks/{__tests__/use-suggestions.test.js → use-suggestions.test.js} +36 -29
- package/dist/hooks/use-suggestions.test.js.map +1 -0
- package/dist/hooks/use-tambo-stream-status.d.ts +9 -8
- package/dist/hooks/use-tambo-stream-status.d.ts.map +1 -1
- package/dist/hooks/use-tambo-stream-status.js +9 -8
- package/dist/hooks/use-tambo-stream-status.js.map +1 -1
- package/dist/hooks/use-tambo-stream-status.test.d.ts.map +1 -0
- package/dist/hooks/{__tests__/use-tambo-stream-status.test.js → use-tambo-stream-status.test.js} +6 -6
- package/dist/hooks/use-tambo-stream-status.test.js.map +1 -0
- package/dist/hooks/use-tambo-threads.test.d.ts.map +1 -0
- package/dist/hooks/{__tests__/use-tambo-threads.test.js → use-tambo-threads.test.js} +3 -3
- package/dist/hooks/use-tambo-threads.test.js.map +1 -0
- package/dist/index.d.ts +10 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/elicitation.d.ts +10 -2
- package/dist/mcp/elicitation.d.ts.map +1 -1
- package/dist/mcp/elicitation.js +19 -1
- package/dist/mcp/elicitation.js.map +1 -1
- package/dist/mcp/elicitation.test.d.ts.map +1 -0
- package/dist/mcp/{__tests__/elicitation.test.js → elicitation.test.js} +1 -1
- package/dist/mcp/elicitation.test.js.map +1 -0
- package/dist/mcp/index.d.ts +11 -2
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +11 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/mcp-client.d.ts +29 -10
- package/dist/mcp/mcp-client.d.ts.map +1 -1
- package/dist/mcp/mcp-client.test.d.ts.map +1 -0
- package/dist/mcp/{__tests__/mcp-client.test.js → mcp-client.test.js} +1 -1
- package/dist/mcp/mcp-client.test.js.map +1 -0
- package/dist/mcp/mcp-hooks.d.ts +129 -25
- package/dist/mcp/mcp-hooks.d.ts.map +1 -1
- package/dist/mcp/mcp-hooks.js +104 -40
- package/dist/mcp/mcp-hooks.js.map +1 -1
- package/dist/mcp/mcp-hooks.test.d.ts.map +1 -0
- package/dist/mcp/{__tests__/mcp-hooks.test.js → mcp-hooks.test.js} +90 -51
- package/dist/mcp/mcp-hooks.test.js.map +1 -0
- package/dist/mcp/tambo-mcp-provider.d.ts +2 -0
- package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/dist/mcp/tambo-mcp-provider.js +60 -13
- package/dist/mcp/tambo-mcp-provider.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.test.d.ts.map +1 -0
- package/dist/mcp/{__tests__/tambo-mcp-provider.test.js → tambo-mcp-provider.test.js} +9 -25
- package/dist/mcp/tambo-mcp-provider.test.js.map +1 -0
- package/dist/mcp/use-mcp-servers.test.d.ts.map +1 -0
- package/dist/mcp/{__tests__/use-mcp-servers.test.js → use-mcp-servers.test.js} +5 -11
- package/dist/mcp/use-mcp-servers.test.js.map +1 -0
- package/dist/model/component-metadata.d.ts +444 -14
- package/dist/model/component-metadata.d.ts.map +1 -1
- package/dist/model/component-metadata.js.map +1 -1
- package/dist/model/generate-component-response.d.ts +12 -1
- package/dist/model/generate-component-response.d.ts.map +1 -1
- package/dist/model/generate-component-response.js.map +1 -1
- package/dist/model/mcp-server-info.d.ts +3 -1
- package/dist/model/mcp-server-info.d.ts.map +1 -1
- package/dist/model/mcp-server-info.js.map +1 -1
- package/dist/model/resource-info.d.ts +55 -0
- package/dist/model/resource-info.d.ts.map +1 -0
- package/dist/model/resource-info.js +3 -0
- package/dist/model/resource-info.js.map +1 -0
- package/dist/model/tambo-thread.d.ts +6 -1
- package/dist/model/tambo-thread.d.ts.map +1 -1
- package/dist/model/tambo-thread.js.map +1 -1
- package/dist/providers/hooks/use-tambo-session-token.test.d.ts.map +1 -0
- package/dist/providers/hooks/{__tests__/use-tambo-session-token.test.js → use-tambo-session-token.test.js} +1 -1
- package/dist/providers/hooks/use-tambo-session-token.test.js.map +1 -0
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/tambo-client-provider.d.ts +0 -4
- package/dist/providers/tambo-client-provider.d.ts.map +1 -1
- package/dist/providers/tambo-client-provider.js +0 -3
- package/dist/providers/tambo-client-provider.js.map +1 -1
- package/dist/providers/tambo-component-provider.d.ts +4 -4
- package/dist/providers/tambo-component-provider.d.ts.map +1 -1
- package/dist/providers/tambo-component-provider.js.map +1 -1
- package/dist/providers/tambo-context-attachment-provider.test.d.ts.map +1 -0
- package/dist/providers/{__tests__/tambo-context-attachment-provider.test.js → tambo-context-attachment-provider.test.js} +2 -2
- package/dist/providers/tambo-context-attachment-provider.test.js.map +1 -0
- package/dist/providers/tambo-context-helpers-provider.test.d.ts.map +1 -0
- package/dist/providers/{__tests__/tambo-context-helpers-provider.test.js → tambo-context-helpers-provider.test.js} +2 -2
- package/dist/providers/tambo-context-helpers-provider.test.js.map +1 -0
- package/dist/providers/tambo-interactable-provider-partial-updates.test.d.ts.map +1 -0
- package/dist/providers/{__tests__/tambo-interactable-provider-partial-updates.test.js → tambo-interactable-provider-partial-updates.test.js} +91 -91
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -0
- package/dist/providers/tambo-interactable-provider.d.ts +2 -3
- package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/dist/providers/tambo-interactable-provider.js +47 -41
- package/dist/providers/tambo-interactable-provider.js.map +1 -1
- package/dist/providers/tambo-interactables-additional-context-edge-cases.test.d.ts.map +1 -0
- package/dist/providers/{__tests__/tambo-interactables-additional-context-edge-cases.test.js → tambo-interactables-additional-context-edge-cases.test.js} +17 -17
- package/dist/providers/tambo-interactables-additional-context-edge-cases.test.js.map +1 -0
- package/dist/providers/tambo-interactables-additional-context.test.d.ts.map +1 -0
- package/dist/providers/{__tests__/tambo-interactables-additional-context.test.js → tambo-interactables-additional-context.test.js} +19 -19
- package/dist/providers/tambo-interactables-additional-context.test.js.map +1 -0
- package/dist/providers/tambo-mcp-token-provider.d.ts +20 -13
- package/dist/providers/tambo-mcp-token-provider.d.ts.map +1 -1
- package/dist/providers/tambo-mcp-token-provider.js +122 -10
- package/dist/providers/tambo-mcp-token-provider.js.map +1 -1
- package/dist/providers/tambo-prop-stream-provider.test.d.ts.map +1 -0
- package/dist/providers/{__tests__/tambo-prop-stream-provider.test.js → tambo-prop-stream-provider.test.js} +32 -25
- package/dist/providers/tambo-prop-stream-provider.test.js.map +1 -0
- package/dist/providers/tambo-provider.d.ts +2 -2
- package/dist/providers/tambo-provider.d.ts.map +1 -1
- package/dist/providers/tambo-provider.js +5 -7
- package/dist/providers/tambo-provider.js.map +1 -1
- package/dist/providers/tambo-registry-provider.d.ts +28 -7
- package/dist/providers/tambo-registry-provider.d.ts.map +1 -1
- package/dist/providers/tambo-registry-provider.js +70 -181
- package/dist/providers/tambo-registry-provider.js.map +1 -1
- package/dist/providers/tambo-registry-provider.test.d.ts.map +1 -0
- package/dist/providers/{__tests__/tambo-registry-provider.test.js → tambo-registry-provider.test.js} +153 -31
- package/dist/providers/tambo-registry-provider.test.js.map +1 -0
- package/dist/providers/tambo-registry-schema-compat.test.d.ts +2 -0
- package/dist/providers/tambo-registry-schema-compat.test.d.ts.map +1 -0
- package/dist/providers/tambo-registry-schema-compat.test.js +616 -0
- package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -0
- package/dist/providers/tambo-stubs.d.ts +2 -2
- package/dist/providers/tambo-stubs.d.ts.map +1 -1
- package/dist/providers/tambo-stubs.js +9 -2
- package/dist/providers/tambo-stubs.js.map +1 -1
- package/dist/providers/tambo-stubs.test.d.ts.map +1 -0
- package/dist/providers/{__tests__/tambo-stubs.test.js → tambo-stubs.test.js} +2 -2
- package/dist/providers/tambo-stubs.test.js.map +1 -0
- package/dist/providers/tambo-thread-input-provider.d.ts +2 -1
- package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-input-provider.js +3 -3
- package/dist/providers/tambo-thread-input-provider.js.map +1 -1
- package/dist/providers/tambo-thread-provider-initial-messages.test.d.ts.map +1 -0
- package/dist/providers/{__tests__/tambo-thread-provider-initial-messages.test.js → tambo-thread-provider-initial-messages.test.js} +7 -9
- package/dist/providers/tambo-thread-provider-initial-messages.test.js.map +1 -0
- package/dist/providers/tambo-thread-provider.d.ts +8 -0
- package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-provider.js +82 -19
- package/dist/providers/tambo-thread-provider.js.map +1 -1
- package/dist/providers/tambo-thread-provider.test.d.ts.map +1 -0
- package/dist/providers/{__tests__/tambo-thread-provider.test.js → tambo-thread-provider.test.js} +42 -78
- package/dist/providers/tambo-thread-provider.test.js.map +1 -0
- package/dist/schema/index.d.ts +6 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +18 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/json-schema.d.ts +35 -0
- package/dist/schema/json-schema.d.ts.map +1 -0
- package/dist/schema/json-schema.js +103 -0
- package/dist/schema/json-schema.js.map +1 -0
- package/dist/schema/schema.d.ts +66 -0
- package/dist/schema/schema.d.ts.map +1 -0
- package/dist/schema/schema.js +192 -0
- package/dist/schema/schema.js.map +1 -0
- package/dist/schema/schema.test.d.ts +2 -0
- package/dist/schema/schema.test.d.ts.map +1 -0
- package/dist/schema/schema.test.js +41 -0
- package/dist/schema/schema.test.js.map +1 -0
- package/dist/schema/standard-schema.d.ts +21 -0
- package/dist/schema/standard-schema.d.ts.map +1 -0
- package/dist/schema/standard-schema.js +37 -0
- package/dist/schema/standard-schema.js.map +1 -0
- package/dist/schema/validate.d.ts +14 -0
- package/dist/schema/validate.d.ts.map +1 -0
- package/dist/schema/validate.js +148 -0
- package/dist/schema/validate.js.map +1 -0
- package/dist/schema/validate.test.d.ts +2 -0
- package/dist/schema/validate.test.d.ts.map +1 -0
- package/dist/schema/validate.test.js +128 -0
- package/dist/schema/validate.test.js.map +1 -0
- package/dist/schema/zod.d.ts +54 -0
- package/dist/schema/zod.d.ts.map +1 -0
- package/dist/schema/zod.js +135 -0
- package/dist/schema/zod.js.map +1 -0
- package/dist/testing/tools.d.ts +29 -15
- package/dist/testing/tools.d.ts.map +1 -1
- package/dist/testing/tools.js +64 -19
- package/dist/testing/tools.js.map +1 -1
- package/dist/util/content-parts.test.d.ts.map +1 -0
- package/dist/util/{__tests__/content-parts.test.js → content-parts.test.js} +1 -1
- package/dist/util/content-parts.test.js.map +1 -0
- package/dist/util/generate-component.d.ts.map +1 -1
- package/dist/util/generate-component.js +3 -3
- package/dist/util/generate-component.js.map +1 -1
- package/dist/util/mcp-server-utils.d.ts +23 -0
- package/dist/util/mcp-server-utils.d.ts.map +1 -0
- package/dist/util/mcp-server-utils.js +107 -0
- package/dist/util/mcp-server-utils.js.map +1 -0
- package/dist/util/mcp-server-utils.test.d.ts +2 -0
- package/dist/util/mcp-server-utils.test.d.ts.map +1 -0
- package/dist/util/mcp-server-utils.test.js +287 -0
- package/dist/util/mcp-server-utils.test.js.map +1 -0
- package/dist/util/message-builder.d.ts +4 -3
- package/dist/util/message-builder.d.ts.map +1 -1
- package/dist/util/message-builder.js +83 -8
- package/dist/util/message-builder.js.map +1 -1
- package/dist/util/message-builder.test.d.ts.map +1 -0
- package/dist/util/message-builder.test.js +678 -0
- package/dist/util/message-builder.test.js.map +1 -0
- package/dist/util/query-utils.d.ts.map +1 -1
- package/dist/util/query-utils.js +49 -31
- package/dist/util/query-utils.js.map +1 -1
- package/dist/util/registry-validators.d.ts +26 -0
- package/dist/util/registry-validators.d.ts.map +1 -0
- package/dist/util/registry-validators.js +105 -0
- package/dist/util/registry-validators.js.map +1 -0
- package/dist/util/registry-validators.test.d.ts +2 -0
- package/dist/util/registry-validators.test.d.ts.map +1 -0
- package/dist/util/registry-validators.test.js +235 -0
- package/dist/util/registry-validators.test.js.map +1 -0
- package/dist/util/registry.d.ts +35 -7
- package/dist/util/registry.d.ts.map +1 -1
- package/dist/util/registry.js +60 -77
- package/dist/util/registry.js.map +1 -1
- package/dist/util/registry.test.d.ts +2 -0
- package/dist/util/registry.test.d.ts.map +1 -0
- package/dist/util/registry.test.js +204 -0
- package/dist/util/registry.test.js.map +1 -0
- package/dist/util/resource-validators.d.ts +16 -0
- package/dist/util/resource-validators.d.ts.map +1 -0
- package/dist/util/resource-validators.js +34 -0
- package/dist/util/resource-validators.js.map +1 -0
- package/dist/util/tool-caller.d.ts +2 -2
- package/dist/util/tool-caller.d.ts.map +1 -1
- package/dist/util/tool-caller.js +12 -4
- package/dist/util/tool-caller.js.map +1 -1
- package/esm/context-helpers/context-helpers-provider.test.d.ts.map +1 -0
- package/esm/context-helpers/{__tests__/context-helpers-provider.test.js → context-helpers-provider.test.js} +2 -2
- package/esm/context-helpers/context-helpers-provider.test.js.map +1 -0
- package/esm/context-helpers/context-helpers.test.d.ts.map +1 -0
- package/esm/context-helpers/{__tests__/context-helpers.test.js → context-helpers.test.js} +1 -1
- package/esm/context-helpers/context-helpers.test.js.map +1 -0
- package/{dist/providers → esm}/hoc/with-tambo-interactable.d.ts +2 -2
- package/esm/hoc/with-tambo-interactable.d.ts.map +1 -0
- package/esm/{providers/hoc → hoc}/with-tambo-interactable.js +29 -2
- package/esm/hoc/with-tambo-interactable.js.map +1 -0
- package/esm/hoc/with-tambo-interactable.test.d.ts +2 -0
- package/esm/hoc/with-tambo-interactable.test.d.ts.map +1 -0
- package/esm/hoc/with-tambo-interactable.test.js +187 -0
- package/esm/hoc/with-tambo-interactable.test.js.map +1 -0
- package/esm/hooks/index.d.ts +1 -1
- package/esm/hooks/index.d.ts.map +1 -1
- package/esm/hooks/index.js +1 -1
- package/esm/hooks/index.js.map +1 -1
- package/esm/hooks/use-component-state.d.ts +11 -24
- package/esm/hooks/use-component-state.d.ts.map +1 -1
- package/esm/hooks/use-component-state.js +14 -5
- package/esm/hooks/use-component-state.js.map +1 -1
- package/esm/hooks/use-component-state.test.d.ts.map +1 -0
- package/esm/hooks/{__tests__/use-component-state.test.js → use-component-state.test.js} +7 -7
- package/esm/hooks/use-component-state.test.js.map +1 -0
- package/esm/hooks/use-current-message.d.ts +51 -7
- package/esm/hooks/use-current-message.d.ts.map +1 -1
- package/esm/hooks/use-current-message.js +48 -5
- package/esm/hooks/use-current-message.js.map +1 -1
- package/esm/hooks/use-current-message.test.d.ts +2 -0
- package/esm/hooks/use-current-message.test.d.ts.map +1 -0
- package/esm/hooks/use-current-message.test.js +259 -0
- package/esm/hooks/use-current-message.test.js.map +1 -0
- package/esm/hooks/use-message-images.test.d.ts.map +1 -0
- package/esm/hooks/{__tests__/use-message-images.test.js → use-message-images.test.js} +1 -1
- package/esm/hooks/use-message-images.test.js.map +1 -0
- package/esm/hooks/use-streaming-props.d.ts +7 -19
- package/esm/hooks/use-streaming-props.d.ts.map +1 -1
- package/esm/hooks/use-streaming-props.js +7 -19
- package/esm/hooks/use-streaming-props.js.map +1 -1
- package/esm/hooks/use-suggestions.d.ts +1 -1
- package/esm/hooks/use-suggestions.d.ts.map +1 -1
- package/esm/hooks/use-suggestions.js.map +1 -1
- package/esm/hooks/use-suggestions.test.d.ts.map +1 -0
- package/esm/hooks/{__tests__/use-suggestions.test.js → use-suggestions.test.js} +36 -29
- package/esm/hooks/use-suggestions.test.js.map +1 -0
- package/esm/hooks/use-tambo-stream-status.d.ts +9 -8
- package/esm/hooks/use-tambo-stream-status.d.ts.map +1 -1
- package/esm/hooks/use-tambo-stream-status.js +9 -8
- package/esm/hooks/use-tambo-stream-status.js.map +1 -1
- package/esm/hooks/use-tambo-stream-status.test.d.ts.map +1 -0
- package/esm/hooks/{__tests__/use-tambo-stream-status.test.js → use-tambo-stream-status.test.js} +6 -6
- package/esm/hooks/use-tambo-stream-status.test.js.map +1 -0
- package/esm/hooks/use-tambo-threads.test.d.ts.map +1 -0
- package/esm/hooks/{__tests__/use-tambo-threads.test.js → use-tambo-threads.test.js} +3 -3
- package/esm/hooks/use-tambo-threads.test.js.map +1 -0
- package/esm/index.d.ts +10 -8
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +4 -2
- package/esm/index.js.map +1 -1
- package/esm/mcp/elicitation.d.ts +10 -2
- package/esm/mcp/elicitation.d.ts.map +1 -1
- package/esm/mcp/elicitation.js +19 -1
- package/esm/mcp/elicitation.js.map +1 -1
- package/esm/mcp/elicitation.test.d.ts.map +1 -0
- package/esm/mcp/{__tests__/elicitation.test.js → elicitation.test.js} +1 -1
- package/esm/mcp/elicitation.test.js.map +1 -0
- package/esm/mcp/index.d.ts +11 -2
- package/esm/mcp/index.d.ts.map +1 -1
- package/esm/mcp/index.js +10 -1
- package/esm/mcp/index.js.map +1 -1
- package/esm/mcp/mcp-client.d.ts +29 -10
- package/esm/mcp/mcp-client.d.ts.map +1 -1
- package/esm/mcp/mcp-client.test.d.ts.map +1 -0
- package/esm/mcp/{__tests__/mcp-client.test.js → mcp-client.test.js} +1 -1
- package/esm/mcp/mcp-client.test.js.map +1 -0
- package/esm/mcp/mcp-hooks.d.ts +129 -25
- package/esm/mcp/mcp-hooks.d.ts.map +1 -1
- package/esm/mcp/mcp-hooks.js +103 -40
- package/esm/mcp/mcp-hooks.js.map +1 -1
- package/esm/mcp/mcp-hooks.test.d.ts.map +1 -0
- package/esm/mcp/{__tests__/mcp-hooks.test.js → mcp-hooks.test.js} +90 -51
- package/esm/mcp/mcp-hooks.test.js.map +1 -0
- package/esm/mcp/tambo-mcp-provider.d.ts +2 -0
- package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/esm/mcp/tambo-mcp-provider.js +60 -13
- package/esm/mcp/tambo-mcp-provider.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.test.d.ts.map +1 -0
- package/esm/mcp/{__tests__/tambo-mcp-provider.test.js → tambo-mcp-provider.test.js} +9 -25
- package/esm/mcp/tambo-mcp-provider.test.js.map +1 -0
- package/esm/mcp/use-mcp-servers.test.d.ts.map +1 -0
- package/esm/mcp/{__tests__/use-mcp-servers.test.js → use-mcp-servers.test.js} +5 -11
- package/esm/mcp/use-mcp-servers.test.js.map +1 -0
- package/esm/model/component-metadata.d.ts +444 -14
- package/esm/model/component-metadata.d.ts.map +1 -1
- package/esm/model/component-metadata.js.map +1 -1
- package/esm/model/generate-component-response.d.ts +12 -1
- package/esm/model/generate-component-response.d.ts.map +1 -1
- package/esm/model/generate-component-response.js.map +1 -1
- package/esm/model/mcp-server-info.d.ts +3 -1
- package/esm/model/mcp-server-info.d.ts.map +1 -1
- package/esm/model/mcp-server-info.js.map +1 -1
- package/esm/model/resource-info.d.ts +55 -0
- package/esm/model/resource-info.d.ts.map +1 -0
- package/esm/model/resource-info.js +2 -0
- package/esm/model/resource-info.js.map +1 -0
- package/esm/model/tambo-thread.d.ts +6 -1
- package/esm/model/tambo-thread.d.ts.map +1 -1
- package/esm/model/tambo-thread.js.map +1 -1
- package/esm/providers/hooks/use-tambo-session-token.test.d.ts.map +1 -0
- package/esm/providers/hooks/{__tests__/use-tambo-session-token.test.js → use-tambo-session-token.test.js} +1 -1
- package/esm/providers/hooks/use-tambo-session-token.test.js.map +1 -0
- package/esm/providers/index.d.ts +1 -1
- package/esm/providers/index.d.ts.map +1 -1
- package/esm/providers/index.js.map +1 -1
- package/esm/providers/tambo-client-provider.d.ts +0 -4
- package/esm/providers/tambo-client-provider.d.ts.map +1 -1
- package/esm/providers/tambo-client-provider.js +0 -3
- package/esm/providers/tambo-client-provider.js.map +1 -1
- package/esm/providers/tambo-component-provider.d.ts +4 -4
- package/esm/providers/tambo-component-provider.d.ts.map +1 -1
- package/esm/providers/tambo-component-provider.js.map +1 -1
- package/esm/providers/tambo-context-attachment-provider.test.d.ts.map +1 -0
- package/esm/providers/{__tests__/tambo-context-attachment-provider.test.js → tambo-context-attachment-provider.test.js} +2 -2
- package/esm/providers/tambo-context-attachment-provider.test.js.map +1 -0
- package/esm/providers/tambo-context-helpers-provider.test.d.ts.map +1 -0
- package/esm/providers/{__tests__/tambo-context-helpers-provider.test.js → tambo-context-helpers-provider.test.js} +2 -2
- package/esm/providers/tambo-context-helpers-provider.test.js.map +1 -0
- package/esm/providers/tambo-interactable-provider-partial-updates.test.d.ts.map +1 -0
- package/esm/providers/{__tests__/tambo-interactable-provider-partial-updates.test.js → tambo-interactable-provider-partial-updates.test.js} +5 -5
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -0
- package/esm/providers/tambo-interactable-provider.d.ts +2 -3
- package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/esm/providers/tambo-interactable-provider.js +44 -38
- package/esm/providers/tambo-interactable-provider.js.map +1 -1
- package/esm/providers/tambo-interactables-additional-context-edge-cases.test.d.ts.map +1 -0
- package/esm/providers/{__tests__/tambo-interactables-additional-context-edge-cases.test.js → tambo-interactables-additional-context-edge-cases.test.js} +10 -10
- package/esm/providers/tambo-interactables-additional-context-edge-cases.test.js.map +1 -0
- package/esm/providers/tambo-interactables-additional-context.test.d.ts.map +1 -0
- package/esm/providers/{__tests__/tambo-interactables-additional-context.test.js → tambo-interactables-additional-context.test.js} +10 -10
- package/esm/providers/tambo-interactables-additional-context.test.js.map +1 -0
- package/esm/providers/tambo-mcp-token-provider.d.ts +20 -13
- package/esm/providers/tambo-mcp-token-provider.d.ts.map +1 -1
- package/esm/providers/tambo-mcp-token-provider.js +123 -11
- package/esm/providers/tambo-mcp-token-provider.js.map +1 -1
- package/esm/providers/tambo-prop-stream-provider.test.d.ts.map +1 -0
- package/esm/providers/{__tests__/tambo-prop-stream-provider.test.js → tambo-prop-stream-provider.test.js} +32 -25
- package/esm/providers/tambo-prop-stream-provider.test.js.map +1 -0
- package/esm/providers/tambo-provider.d.ts +2 -2
- package/esm/providers/tambo-provider.d.ts.map +1 -1
- package/esm/providers/tambo-provider.js +5 -7
- package/esm/providers/tambo-provider.js.map +1 -1
- package/esm/providers/tambo-registry-provider.d.ts +28 -7
- package/esm/providers/tambo-registry-provider.d.ts.map +1 -1
- package/esm/providers/tambo-registry-provider.js +67 -175
- package/esm/providers/tambo-registry-provider.js.map +1 -1
- package/esm/providers/tambo-registry-provider.test.d.ts.map +1 -0
- package/esm/providers/{__tests__/tambo-registry-provider.test.js → tambo-registry-provider.test.js} +149 -27
- package/esm/providers/tambo-registry-provider.test.js.map +1 -0
- package/esm/providers/tambo-registry-schema-compat.test.d.ts +2 -0
- package/esm/providers/tambo-registry-schema-compat.test.d.ts.map +1 -0
- package/esm/providers/tambo-registry-schema-compat.test.js +578 -0
- package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -0
- package/esm/providers/tambo-stubs.d.ts +2 -2
- package/esm/providers/tambo-stubs.d.ts.map +1 -1
- package/esm/providers/tambo-stubs.js +9 -2
- package/esm/providers/tambo-stubs.js.map +1 -1
- package/esm/providers/tambo-stubs.test.d.ts.map +1 -0
- package/esm/providers/{__tests__/tambo-stubs.test.js → tambo-stubs.test.js} +2 -2
- package/esm/providers/tambo-stubs.test.js.map +1 -0
- package/esm/providers/tambo-thread-input-provider.d.ts +2 -1
- package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-input-provider.js +3 -3
- package/esm/providers/tambo-thread-input-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider-initial-messages.test.d.ts.map +1 -0
- package/esm/providers/{__tests__/tambo-thread-provider-initial-messages.test.js → tambo-thread-provider-initial-messages.test.js} +7 -9
- package/esm/providers/tambo-thread-provider-initial-messages.test.js.map +1 -0
- package/esm/providers/tambo-thread-provider.d.ts +8 -0
- package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-provider.js +82 -19
- package/esm/providers/tambo-thread-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider.test.d.ts.map +1 -0
- package/esm/providers/{__tests__/tambo-thread-provider.test.js → tambo-thread-provider.test.js} +34 -70
- package/esm/providers/tambo-thread-provider.test.js.map +1 -0
- package/esm/schema/index.d.ts +6 -0
- package/esm/schema/index.d.ts.map +1 -0
- package/esm/schema/index.js +6 -0
- package/esm/schema/index.js.map +1 -0
- package/esm/schema/json-schema.d.ts +35 -0
- package/esm/schema/json-schema.d.ts.map +1 -0
- package/esm/schema/json-schema.js +98 -0
- package/esm/schema/json-schema.js.map +1 -0
- package/esm/schema/schema.d.ts +66 -0
- package/esm/schema/schema.d.ts.map +1 -0
- package/esm/schema/schema.js +185 -0
- package/esm/schema/schema.js.map +1 -0
- package/esm/schema/schema.test.d.ts +2 -0
- package/esm/schema/schema.test.d.ts.map +1 -0
- package/esm/schema/schema.test.js +39 -0
- package/esm/schema/schema.test.js.map +1 -0
- package/esm/schema/standard-schema.d.ts +21 -0
- package/esm/schema/standard-schema.d.ts.map +1 -0
- package/esm/schema/standard-schema.js +34 -0
- package/esm/schema/standard-schema.js.map +1 -0
- package/esm/schema/validate.d.ts +14 -0
- package/esm/schema/validate.d.ts.map +1 -0
- package/esm/schema/validate.js +145 -0
- package/esm/schema/validate.js.map +1 -0
- package/esm/schema/validate.test.d.ts +2 -0
- package/esm/schema/validate.test.d.ts.map +1 -0
- package/esm/schema/validate.test.js +126 -0
- package/esm/schema/validate.test.js.map +1 -0
- package/esm/schema/zod.d.ts +54 -0
- package/esm/schema/zod.d.ts.map +1 -0
- package/esm/schema/zod.js +124 -0
- package/esm/schema/zod.js.map +1 -0
- package/esm/testing/tools.d.ts +29 -15
- package/esm/testing/tools.d.ts.map +1 -1
- package/esm/testing/tools.js +62 -16
- package/esm/testing/tools.js.map +1 -1
- package/esm/util/content-parts.test.d.ts.map +1 -0
- package/esm/util/{__tests__/content-parts.test.js → content-parts.test.js} +1 -1
- package/esm/util/content-parts.test.js.map +1 -0
- package/esm/util/generate-component.d.ts.map +1 -1
- package/esm/util/generate-component.js +3 -3
- package/esm/util/generate-component.js.map +1 -1
- package/esm/util/mcp-server-utils.d.ts +23 -0
- package/esm/util/mcp-server-utils.d.ts.map +1 -0
- package/esm/util/mcp-server-utils.js +102 -0
- package/esm/util/mcp-server-utils.js.map +1 -0
- package/esm/util/mcp-server-utils.test.d.ts +2 -0
- package/esm/util/mcp-server-utils.test.d.ts.map +1 -0
- package/esm/util/mcp-server-utils.test.js +285 -0
- package/esm/util/mcp-server-utils.test.js.map +1 -0
- package/esm/util/message-builder.d.ts +4 -3
- package/esm/util/message-builder.d.ts.map +1 -1
- package/esm/util/message-builder.js +83 -8
- package/esm/util/message-builder.js.map +1 -1
- package/esm/util/message-builder.test.d.ts.map +1 -0
- package/esm/util/message-builder.test.js +676 -0
- package/esm/util/message-builder.test.js.map +1 -0
- package/esm/util/query-utils.d.ts.map +1 -1
- package/esm/util/query-utils.js +49 -31
- package/esm/util/query-utils.js.map +1 -1
- package/esm/util/registry-validators.d.ts +26 -0
- package/esm/util/registry-validators.d.ts.map +1 -0
- package/esm/util/registry-validators.js +100 -0
- package/esm/util/registry-validators.js.map +1 -0
- package/esm/util/registry-validators.test.d.ts +2 -0
- package/esm/util/registry-validators.test.d.ts.map +1 -0
- package/esm/util/registry-validators.test.js +233 -0
- package/esm/util/registry-validators.test.js.map +1 -0
- package/esm/util/registry.d.ts +35 -7
- package/esm/util/registry.d.ts.map +1 -1
- package/esm/util/registry.js +57 -73
- package/esm/util/registry.js.map +1 -1
- package/esm/util/registry.test.d.ts +2 -0
- package/esm/util/registry.test.d.ts.map +1 -0
- package/esm/util/registry.test.js +169 -0
- package/esm/util/registry.test.js.map +1 -0
- package/esm/util/resource-validators.d.ts +16 -0
- package/esm/util/resource-validators.d.ts.map +1 -0
- package/esm/util/resource-validators.js +30 -0
- package/esm/util/resource-validators.js.map +1 -0
- package/esm/util/tool-caller.d.ts +2 -2
- package/esm/util/tool-caller.d.ts.map +1 -1
- package/esm/util/tool-caller.js +12 -4
- package/esm/util/tool-caller.js.map +1 -1
- package/package.json +30 -11
- package/dist/__tests__/util/validate-zod-schema.test.d.ts +0 -2
- package/dist/__tests__/util/validate-zod-schema.test.d.ts.map +0 -1
- package/dist/__tests__/util/validate-zod-schema.test.js +0 -96
- package/dist/__tests__/util/validate-zod-schema.test.js.map +0 -1
- package/dist/context-helpers/__tests__/context-helpers-provider.test.d.ts.map +0 -1
- package/dist/context-helpers/__tests__/context-helpers-provider.test.js.map +0 -1
- package/dist/context-helpers/__tests__/context-helpers.test.d.ts.map +0 -1
- package/dist/context-helpers/__tests__/context-helpers.test.js.map +0 -1
- package/dist/hooks/__tests__/use-component-state.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/use-component-state.test.js.map +0 -1
- package/dist/hooks/__tests__/use-message-images.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/use-message-images.test.js.map +0 -1
- package/dist/hooks/__tests__/use-suggestions.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/use-suggestions.test.js.map +0 -1
- package/dist/hooks/__tests__/use-tambo-stream-status.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/use-tambo-stream-status.test.js.map +0 -1
- package/dist/hooks/__tests__/use-tambo-threads.test.d.ts.map +0 -1
- package/dist/hooks/__tests__/use-tambo-threads.test.js.map +0 -1
- package/dist/mcp/__tests__/elicitation.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/elicitation.test.js.map +0 -1
- package/dist/mcp/__tests__/mcp-client.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/mcp-client.test.js.map +0 -1
- package/dist/mcp/__tests__/mcp-hooks.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/mcp-hooks.test.js.map +0 -1
- package/dist/mcp/__tests__/tambo-mcp-provider.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/tambo-mcp-provider.test.js.map +0 -1
- package/dist/mcp/__tests__/use-mcp-servers.test.d.ts.map +0 -1
- package/dist/mcp/__tests__/use-mcp-servers.test.js.map +0 -1
- package/dist/providers/__tests__/tambo-context-attachment-provider.test.d.ts.map +0 -1
- package/dist/providers/__tests__/tambo-context-attachment-provider.test.js.map +0 -1
- package/dist/providers/__tests__/tambo-context-helpers-provider.test.d.ts.map +0 -1
- package/dist/providers/__tests__/tambo-context-helpers-provider.test.js.map +0 -1
- package/dist/providers/__tests__/tambo-interactable-provider-partial-updates.test.d.ts.map +0 -1
- package/dist/providers/__tests__/tambo-interactable-provider-partial-updates.test.js.map +0 -1
- package/dist/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.d.ts.map +0 -1
- package/dist/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.js.map +0 -1
- package/dist/providers/__tests__/tambo-interactables-additional-context.test.d.ts.map +0 -1
- package/dist/providers/__tests__/tambo-interactables-additional-context.test.js.map +0 -1
- package/dist/providers/__tests__/tambo-prop-stream-provider.test.d.ts.map +0 -1
- package/dist/providers/__tests__/tambo-prop-stream-provider.test.js.map +0 -1
- package/dist/providers/__tests__/tambo-registry-provider.test.d.ts.map +0 -1
- package/dist/providers/__tests__/tambo-registry-provider.test.js.map +0 -1
- package/dist/providers/__tests__/tambo-stubs.test.d.ts.map +0 -1
- package/dist/providers/__tests__/tambo-stubs.test.js.map +0 -1
- package/dist/providers/__tests__/tambo-thread-provider-initial-messages.test.d.ts.map +0 -1
- package/dist/providers/__tests__/tambo-thread-provider-initial-messages.test.js.map +0 -1
- package/dist/providers/__tests__/tambo-thread-provider.test.d.ts.map +0 -1
- package/dist/providers/__tests__/tambo-thread-provider.test.js.map +0 -1
- package/dist/providers/hoc/with-tambo-interactable.d.ts.map +0 -1
- package/dist/providers/hoc/with-tambo-interactable.js.map +0 -1
- package/dist/providers/hooks/__tests__/use-tambo-session-token.test.d.ts.map +0 -1
- package/dist/providers/hooks/__tests__/use-tambo-session-token.test.js.map +0 -1
- package/dist/util/__tests__/content-parts.test.d.ts.map +0 -1
- package/dist/util/__tests__/content-parts.test.js.map +0 -1
- package/dist/util/__tests__/message-builder.test.d.ts.map +0 -1
- package/dist/util/__tests__/message-builder.test.js +0 -191
- package/dist/util/__tests__/message-builder.test.js.map +0 -1
- package/dist/util/validate-zod-schema.d.ts +0 -10
- package/dist/util/validate-zod-schema.d.ts.map +0 -1
- package/dist/util/validate-zod-schema.js +0 -100
- package/dist/util/validate-zod-schema.js.map +0 -1
- package/esm/__tests__/util/validate-zod-schema.test.d.ts +0 -2
- package/esm/__tests__/util/validate-zod-schema.test.d.ts.map +0 -1
- package/esm/__tests__/util/validate-zod-schema.test.js +0 -94
- package/esm/__tests__/util/validate-zod-schema.test.js.map +0 -1
- package/esm/context-helpers/__tests__/context-helpers-provider.test.d.ts.map +0 -1
- package/esm/context-helpers/__tests__/context-helpers-provider.test.js.map +0 -1
- package/esm/context-helpers/__tests__/context-helpers.test.d.ts.map +0 -1
- package/esm/context-helpers/__tests__/context-helpers.test.js.map +0 -1
- package/esm/hooks/__tests__/use-component-state.test.d.ts.map +0 -1
- package/esm/hooks/__tests__/use-component-state.test.js.map +0 -1
- package/esm/hooks/__tests__/use-message-images.test.d.ts.map +0 -1
- package/esm/hooks/__tests__/use-message-images.test.js.map +0 -1
- package/esm/hooks/__tests__/use-suggestions.test.d.ts.map +0 -1
- package/esm/hooks/__tests__/use-suggestions.test.js.map +0 -1
- package/esm/hooks/__tests__/use-tambo-stream-status.test.d.ts.map +0 -1
- package/esm/hooks/__tests__/use-tambo-stream-status.test.js.map +0 -1
- package/esm/hooks/__tests__/use-tambo-threads.test.d.ts.map +0 -1
- package/esm/hooks/__tests__/use-tambo-threads.test.js.map +0 -1
- package/esm/mcp/__tests__/elicitation.test.d.ts.map +0 -1
- package/esm/mcp/__tests__/elicitation.test.js.map +0 -1
- package/esm/mcp/__tests__/mcp-client.test.d.ts.map +0 -1
- package/esm/mcp/__tests__/mcp-client.test.js.map +0 -1
- package/esm/mcp/__tests__/mcp-hooks.test.d.ts.map +0 -1
- package/esm/mcp/__tests__/mcp-hooks.test.js.map +0 -1
- package/esm/mcp/__tests__/tambo-mcp-provider.test.d.ts.map +0 -1
- package/esm/mcp/__tests__/tambo-mcp-provider.test.js.map +0 -1
- package/esm/mcp/__tests__/use-mcp-servers.test.d.ts.map +0 -1
- package/esm/mcp/__tests__/use-mcp-servers.test.js.map +0 -1
- package/esm/providers/__tests__/tambo-context-attachment-provider.test.d.ts.map +0 -1
- package/esm/providers/__tests__/tambo-context-attachment-provider.test.js.map +0 -1
- package/esm/providers/__tests__/tambo-context-helpers-provider.test.d.ts.map +0 -1
- package/esm/providers/__tests__/tambo-context-helpers-provider.test.js.map +0 -1
- package/esm/providers/__tests__/tambo-interactable-provider-partial-updates.test.d.ts.map +0 -1
- package/esm/providers/__tests__/tambo-interactable-provider-partial-updates.test.js.map +0 -1
- package/esm/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.d.ts.map +0 -1
- package/esm/providers/__tests__/tambo-interactables-additional-context-edge-cases.test.js.map +0 -1
- package/esm/providers/__tests__/tambo-interactables-additional-context.test.d.ts.map +0 -1
- package/esm/providers/__tests__/tambo-interactables-additional-context.test.js.map +0 -1
- package/esm/providers/__tests__/tambo-prop-stream-provider.test.d.ts.map +0 -1
- package/esm/providers/__tests__/tambo-prop-stream-provider.test.js.map +0 -1
- package/esm/providers/__tests__/tambo-registry-provider.test.d.ts.map +0 -1
- package/esm/providers/__tests__/tambo-registry-provider.test.js.map +0 -1
- package/esm/providers/__tests__/tambo-stubs.test.d.ts.map +0 -1
- package/esm/providers/__tests__/tambo-stubs.test.js.map +0 -1
- package/esm/providers/__tests__/tambo-thread-provider-initial-messages.test.d.ts.map +0 -1
- package/esm/providers/__tests__/tambo-thread-provider-initial-messages.test.js.map +0 -1
- package/esm/providers/__tests__/tambo-thread-provider.test.d.ts.map +0 -1
- package/esm/providers/__tests__/tambo-thread-provider.test.js.map +0 -1
- package/esm/providers/hoc/with-tambo-interactable.d.ts.map +0 -1
- package/esm/providers/hoc/with-tambo-interactable.js.map +0 -1
- package/esm/providers/hooks/__tests__/use-tambo-session-token.test.d.ts.map +0 -1
- package/esm/providers/hooks/__tests__/use-tambo-session-token.test.js.map +0 -1
- package/esm/util/__tests__/content-parts.test.d.ts.map +0 -1
- package/esm/util/__tests__/content-parts.test.js.map +0 -1
- package/esm/util/__tests__/message-builder.test.d.ts.map +0 -1
- package/esm/util/__tests__/message-builder.test.js +0 -189
- package/esm/util/__tests__/message-builder.test.js.map +0 -1
- package/esm/util/validate-zod-schema.d.ts +0 -10
- package/esm/util/validate-zod-schema.d.ts.map +0 -1
- package/esm/util/validate-zod-schema.js +0 -97
- package/esm/util/validate-zod-schema.js.map +0 -1
- /package/dist/context-helpers/{__tests__/context-helpers-provider.test.d.ts → context-helpers-provider.test.d.ts} +0 -0
- /package/dist/context-helpers/{__tests__/context-helpers.test.d.ts → context-helpers.test.d.ts} +0 -0
- /package/dist/hooks/{__tests__/use-component-state.test.d.ts → use-component-state.test.d.ts} +0 -0
- /package/dist/hooks/{__tests__/use-message-images.test.d.ts → use-message-images.test.d.ts} +0 -0
- /package/dist/hooks/{__tests__/use-suggestions.test.d.ts → use-suggestions.test.d.ts} +0 -0
- /package/dist/hooks/{__tests__/use-tambo-stream-status.test.d.ts → use-tambo-stream-status.test.d.ts} +0 -0
- /package/dist/hooks/{__tests__/use-tambo-threads.test.d.ts → use-tambo-threads.test.d.ts} +0 -0
- /package/dist/mcp/{__tests__/elicitation.test.d.ts → elicitation.test.d.ts} +0 -0
- /package/dist/mcp/{__tests__/mcp-client.test.d.ts → mcp-client.test.d.ts} +0 -0
- /package/dist/mcp/{__tests__/mcp-hooks.test.d.ts → mcp-hooks.test.d.ts} +0 -0
- /package/dist/mcp/{__tests__/tambo-mcp-provider.test.d.ts → tambo-mcp-provider.test.d.ts} +0 -0
- /package/dist/mcp/{__tests__/use-mcp-servers.test.d.ts → use-mcp-servers.test.d.ts} +0 -0
- /package/dist/providers/hooks/{__tests__/use-tambo-session-token.test.d.ts → use-tambo-session-token.test.d.ts} +0 -0
- /package/dist/providers/{__tests__/tambo-context-attachment-provider.test.d.ts → tambo-context-attachment-provider.test.d.ts} +0 -0
- /package/dist/providers/{__tests__/tambo-context-helpers-provider.test.d.ts → tambo-context-helpers-provider.test.d.ts} +0 -0
- /package/dist/providers/{__tests__/tambo-interactable-provider-partial-updates.test.d.ts → tambo-interactable-provider-partial-updates.test.d.ts} +0 -0
- /package/dist/providers/{__tests__/tambo-interactables-additional-context-edge-cases.test.d.ts → tambo-interactables-additional-context-edge-cases.test.d.ts} +0 -0
- /package/dist/providers/{__tests__/tambo-interactables-additional-context.test.d.ts → tambo-interactables-additional-context.test.d.ts} +0 -0
- /package/dist/providers/{__tests__/tambo-prop-stream-provider.test.d.ts → tambo-prop-stream-provider.test.d.ts} +0 -0
- /package/dist/providers/{__tests__/tambo-registry-provider.test.d.ts → tambo-registry-provider.test.d.ts} +0 -0
- /package/dist/providers/{__tests__/tambo-stubs.test.d.ts → tambo-stubs.test.d.ts} +0 -0
- /package/dist/providers/{__tests__/tambo-thread-provider-initial-messages.test.d.ts → tambo-thread-provider-initial-messages.test.d.ts} +0 -0
- /package/dist/providers/{__tests__/tambo-thread-provider.test.d.ts → tambo-thread-provider.test.d.ts} +0 -0
- /package/dist/util/{__tests__/content-parts.test.d.ts → content-parts.test.d.ts} +0 -0
- /package/dist/util/{__tests__/message-builder.test.d.ts → message-builder.test.d.ts} +0 -0
- /package/esm/context-helpers/{__tests__/context-helpers-provider.test.d.ts → context-helpers-provider.test.d.ts} +0 -0
- /package/esm/context-helpers/{__tests__/context-helpers.test.d.ts → context-helpers.test.d.ts} +0 -0
- /package/esm/hooks/{__tests__/use-component-state.test.d.ts → use-component-state.test.d.ts} +0 -0
- /package/esm/hooks/{__tests__/use-message-images.test.d.ts → use-message-images.test.d.ts} +0 -0
- /package/esm/hooks/{__tests__/use-suggestions.test.d.ts → use-suggestions.test.d.ts} +0 -0
- /package/esm/hooks/{__tests__/use-tambo-stream-status.test.d.ts → use-tambo-stream-status.test.d.ts} +0 -0
- /package/esm/hooks/{__tests__/use-tambo-threads.test.d.ts → use-tambo-threads.test.d.ts} +0 -0
- /package/esm/mcp/{__tests__/elicitation.test.d.ts → elicitation.test.d.ts} +0 -0
- /package/esm/mcp/{__tests__/mcp-client.test.d.ts → mcp-client.test.d.ts} +0 -0
- /package/esm/mcp/{__tests__/mcp-hooks.test.d.ts → mcp-hooks.test.d.ts} +0 -0
- /package/esm/mcp/{__tests__/tambo-mcp-provider.test.d.ts → tambo-mcp-provider.test.d.ts} +0 -0
- /package/esm/mcp/{__tests__/use-mcp-servers.test.d.ts → use-mcp-servers.test.d.ts} +0 -0
- /package/esm/providers/hooks/{__tests__/use-tambo-session-token.test.d.ts → use-tambo-session-token.test.d.ts} +0 -0
- /package/esm/providers/{__tests__/tambo-context-attachment-provider.test.d.ts → tambo-context-attachment-provider.test.d.ts} +0 -0
- /package/esm/providers/{__tests__/tambo-context-helpers-provider.test.d.ts → tambo-context-helpers-provider.test.d.ts} +0 -0
- /package/esm/providers/{__tests__/tambo-interactable-provider-partial-updates.test.d.ts → tambo-interactable-provider-partial-updates.test.d.ts} +0 -0
- /package/esm/providers/{__tests__/tambo-interactables-additional-context-edge-cases.test.d.ts → tambo-interactables-additional-context-edge-cases.test.d.ts} +0 -0
- /package/esm/providers/{__tests__/tambo-interactables-additional-context.test.d.ts → tambo-interactables-additional-context.test.d.ts} +0 -0
- /package/esm/providers/{__tests__/tambo-prop-stream-provider.test.d.ts → tambo-prop-stream-provider.test.d.ts} +0 -0
- /package/esm/providers/{__tests__/tambo-registry-provider.test.d.ts → tambo-registry-provider.test.d.ts} +0 -0
- /package/esm/providers/{__tests__/tambo-stubs.test.d.ts → tambo-stubs.test.d.ts} +0 -0
- /package/esm/providers/{__tests__/tambo-thread-provider-initial-messages.test.d.ts → tambo-thread-provider-initial-messages.test.d.ts} +0 -0
- /package/esm/providers/{__tests__/tambo-thread-provider.test.d.ts → tambo-thread-provider.test.d.ts} +0 -0
- /package/esm/util/{__tests__/content-parts.test.d.ts → content-parts.test.d.ts} +0 -0
- /package/esm/util/{__tests__/message-builder.test.d.ts → message-builder.test.d.ts} +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { McpServerInfo, NormalizedMcpServerInfo } from "../model/mcp-server-info";
|
|
2
|
+
/**
|
|
3
|
+
* Derives a short, meaningful key from a server URL.
|
|
4
|
+
* Strips TLDs and common prefixes to get a human-readable identifier.
|
|
5
|
+
* For example, "https://mcp.linear.app/mcp" becomes "linear".
|
|
6
|
+
* @returns A lowercased, human-readable key derived from the URL
|
|
7
|
+
*/
|
|
8
|
+
export declare function deriveServerKey(url: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Normalizes an MCP server info object, ensuring it has a serverKey.
|
|
11
|
+
* If serverKey is not provided, derives it from the URL.
|
|
12
|
+
* @returns The normalized MCP server info object
|
|
13
|
+
*/
|
|
14
|
+
export declare function normalizeServerInfo(server: McpServerInfo | string): NormalizedMcpServerInfo;
|
|
15
|
+
/**
|
|
16
|
+
* Deduplicates MCP servers by connection identity and ensures serverKey uniqueness.
|
|
17
|
+
* First deduplicates by connection (url + transport), then ensures serverKey uniqueness
|
|
18
|
+
* by appending -2, -3, etc. to duplicate serverKeys.
|
|
19
|
+
* @param servers - Array of normalized MCP server info objects
|
|
20
|
+
* @returns Array of deduplicated servers with unique serverKeys
|
|
21
|
+
*/
|
|
22
|
+
export declare function deduplicateMcpServers(servers: NormalizedMcpServerInfo[]): NormalizedMcpServerInfo[];
|
|
23
|
+
//# sourceMappingURL=mcp-server-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server-utils.d.ts","sourceRoot":"","sources":["../../src/util/mcp-server-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,uBAAuB,EACxB,MAAM,0BAA0B,CAAC;AAGlC;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAmDnD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,GAAG,MAAM,GAC7B,uBAAuB,CAazB;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,uBAAuB,EAAE,GACjC,uBAAuB,EAAE,CA8B3B"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deriveServerKey = deriveServerKey;
|
|
4
|
+
exports.normalizeServerInfo = normalizeServerInfo;
|
|
5
|
+
exports.deduplicateMcpServers = deduplicateMcpServers;
|
|
6
|
+
const mcp_server_info_1 = require("../model/mcp-server-info");
|
|
7
|
+
/**
|
|
8
|
+
* Derives a short, meaningful key from a server URL.
|
|
9
|
+
* Strips TLDs and common prefixes to get a human-readable identifier.
|
|
10
|
+
* For example, "https://mcp.linear.app/mcp" becomes "linear".
|
|
11
|
+
* @returns A lowercased, human-readable key derived from the URL
|
|
12
|
+
*/
|
|
13
|
+
function deriveServerKey(url) {
|
|
14
|
+
try {
|
|
15
|
+
const parsed = new URL(url);
|
|
16
|
+
const hostname = parsed.hostname;
|
|
17
|
+
// Split hostname into parts
|
|
18
|
+
const parts = hostname.split(".");
|
|
19
|
+
// Remove common TLD patterns
|
|
20
|
+
// Handle cases like: .com, .org, .co.uk, .com.au, etc.
|
|
21
|
+
let relevantParts = [...parts];
|
|
22
|
+
// If we have 3+ parts and the last two are short (likely TLD like .co.uk)
|
|
23
|
+
if (relevantParts.length >= 3 &&
|
|
24
|
+
relevantParts[relevantParts.length - 1].length <= 3 &&
|
|
25
|
+
relevantParts[relevantParts.length - 2].length <= 3) {
|
|
26
|
+
relevantParts = relevantParts.slice(0, -2);
|
|
27
|
+
}
|
|
28
|
+
// Otherwise just remove the last part (TLD like .com)
|
|
29
|
+
else if (relevantParts.length >= 2) {
|
|
30
|
+
relevantParts = relevantParts.slice(0, -1);
|
|
31
|
+
}
|
|
32
|
+
// From what's left, prefer the rightmost part that's not a common prefix
|
|
33
|
+
// Common prefixes: www, api, mcp, app, etc.
|
|
34
|
+
const commonPrefixes = new Set([
|
|
35
|
+
"www",
|
|
36
|
+
"api",
|
|
37
|
+
"mcp",
|
|
38
|
+
"app",
|
|
39
|
+
"staging",
|
|
40
|
+
"dev",
|
|
41
|
+
"prod",
|
|
42
|
+
]);
|
|
43
|
+
// Work backwards through the parts to find a meaningful name
|
|
44
|
+
for (let i = relevantParts.length - 1; i >= 0; i--) {
|
|
45
|
+
const part = relevantParts[i];
|
|
46
|
+
if (part && !commonPrefixes.has(part.toLowerCase())) {
|
|
47
|
+
return part.toLowerCase();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Fallback: use the last relevant part even if it's a common prefix
|
|
51
|
+
return relevantParts[relevantParts.length - 1]?.toLowerCase() || hostname;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// If URL parsing fails, just return a sanitized version of the input
|
|
55
|
+
return url.replace(/[^a-zA-Z0-9]/g, "_").toLowerCase();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Normalizes an MCP server info object, ensuring it has a serverKey.
|
|
60
|
+
* If serverKey is not provided, derives it from the URL.
|
|
61
|
+
* @returns The normalized MCP server info object
|
|
62
|
+
*/
|
|
63
|
+
function normalizeServerInfo(server) {
|
|
64
|
+
const base = typeof server === "string"
|
|
65
|
+
? {
|
|
66
|
+
url: server,
|
|
67
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
68
|
+
}
|
|
69
|
+
: server;
|
|
70
|
+
const serverKey = base.serverKey ?? deriveServerKey(base.url);
|
|
71
|
+
const transport = base.transport ?? mcp_server_info_1.MCPTransport.HTTP;
|
|
72
|
+
return { ...base, transport, serverKey };
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Deduplicates MCP servers by connection identity and ensures serverKey uniqueness.
|
|
76
|
+
* First deduplicates by connection (url + transport), then ensures serverKey uniqueness
|
|
77
|
+
* by appending -2, -3, etc. to duplicate serverKeys.
|
|
78
|
+
* @param servers - Array of normalized MCP server info objects
|
|
79
|
+
* @returns Array of deduplicated servers with unique serverKeys
|
|
80
|
+
*/
|
|
81
|
+
function deduplicateMcpServers(servers) {
|
|
82
|
+
if (servers.length === 0) {
|
|
83
|
+
return servers;
|
|
84
|
+
}
|
|
85
|
+
// 1. Deduplicate by connection identity using a stable key
|
|
86
|
+
const byKey = new Map();
|
|
87
|
+
for (const server of servers) {
|
|
88
|
+
const key = (0, mcp_server_info_1.getMcpServerUniqueKey)(server);
|
|
89
|
+
byKey.set(key, server);
|
|
90
|
+
}
|
|
91
|
+
const deduped = Array.from(byKey.values());
|
|
92
|
+
// 2. Ensure serverKey uniqueness for readable, unambiguous prefixes
|
|
93
|
+
const seen = new Map();
|
|
94
|
+
return deduped.map((server) => {
|
|
95
|
+
const baseKey = server.serverKey;
|
|
96
|
+
const count = (seen.get(baseKey) ?? 0) + 1;
|
|
97
|
+
seen.set(baseKey, count);
|
|
98
|
+
if (count === 1) {
|
|
99
|
+
return server;
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
...server,
|
|
103
|
+
serverKey: `${baseKey}-${count}`,
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=mcp-server-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server-utils.js","sourceRoot":"","sources":["../../src/util/mcp-server-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n McpServerInfo,\n NormalizedMcpServerInfo,\n} from \"../model/mcp-server-info\";\nimport { getMcpServerUniqueKey, MCPTransport } from \"../model/mcp-server-info\";\n\n/**\n * Derives a short, meaningful key from a server URL.\n * Strips TLDs and common prefixes to get a human-readable identifier.\n * For example, \"https://mcp.linear.app/mcp\" becomes \"linear\".\n * @returns A lowercased, human-readable key derived from the URL\n */\nexport function deriveServerKey(url: string): string {\n try {\n const parsed = new URL(url);\n const hostname = parsed.hostname;\n\n // Split hostname into parts\n const parts = hostname.split(\".\");\n\n // Remove common TLD patterns\n // Handle cases like: .com, .org, .co.uk, .com.au, etc.\n let relevantParts = [...parts];\n\n // If we have 3+ parts and the last two are short (likely TLD like .co.uk)\n if (\n relevantParts.length >= 3 &&\n relevantParts[relevantParts.length - 1].length <= 3 &&\n relevantParts[relevantParts.length - 2].length <= 3\n ) {\n relevantParts = relevantParts.slice(0, -2);\n }\n // Otherwise just remove the last part (TLD like .com)\n else if (relevantParts.length >= 2) {\n relevantParts = relevantParts.slice(0, -1);\n }\n\n // From what's left, prefer the rightmost part that's not a common prefix\n // Common prefixes: www, api, mcp, app, etc.\n const commonPrefixes = new Set([\n \"www\",\n \"api\",\n \"mcp\",\n \"app\",\n \"staging\",\n \"dev\",\n \"prod\",\n ]);\n\n // Work backwards through the parts to find a meaningful name\n for (let i = relevantParts.length - 1; i >= 0; i--) {\n const part = relevantParts[i];\n if (part && !commonPrefixes.has(part.toLowerCase())) {\n return part.toLowerCase();\n }\n }\n\n // Fallback: use the last relevant part even if it's a common prefix\n return relevantParts[relevantParts.length - 1]?.toLowerCase() || hostname;\n } catch {\n // If URL parsing fails, just return a sanitized version of the input\n return url.replace(/[^a-zA-Z0-9]/g, \"_\").toLowerCase();\n }\n}\n\n/**\n * Normalizes an MCP server info object, ensuring it has a serverKey.\n * If serverKey is not provided, derives it from the URL.\n * @returns The normalized MCP server info object\n */\nexport function normalizeServerInfo(\n server: McpServerInfo | string,\n): NormalizedMcpServerInfo {\n const base: McpServerInfo =\n typeof server === \"string\"\n ? {\n url: server,\n transport: MCPTransport.HTTP,\n }\n : server;\n\n const serverKey = base.serverKey ?? deriveServerKey(base.url);\n const transport = base.transport ?? MCPTransport.HTTP;\n\n return { ...base, transport, serverKey };\n}\n\n/**\n * Deduplicates MCP servers by connection identity and ensures serverKey uniqueness.\n * First deduplicates by connection (url + transport), then ensures serverKey uniqueness\n * by appending -2, -3, etc. to duplicate serverKeys.\n * @param servers - Array of normalized MCP server info objects\n * @returns Array of deduplicated servers with unique serverKeys\n */\nexport function deduplicateMcpServers(\n servers: NormalizedMcpServerInfo[],\n): NormalizedMcpServerInfo[] {\n if (servers.length === 0) {\n return servers;\n }\n\n // 1. Deduplicate by connection identity using a stable key\n const byKey = new Map<string, NormalizedMcpServerInfo>();\n for (const server of servers) {\n const key = getMcpServerUniqueKey(server);\n byKey.set(key, server);\n }\n\n const deduped = Array.from(byKey.values());\n\n // 2. Ensure serverKey uniqueness for readable, unambiguous prefixes\n const seen = new Map<string, number>();\n return deduped.map((server) => {\n const baseKey = server.serverKey;\n const count = (seen.get(baseKey) ?? 0) + 1;\n seen.set(baseKey, count);\n\n if (count === 1) {\n return server;\n }\n\n return {\n ...server,\n serverKey: `${baseKey}-${count}`,\n };\n });\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server-utils.test.d.ts","sourceRoot":"","sources":["../../src/util/mcp-server-utils.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const mcp_server_info_1 = require("../model/mcp-server-info");
|
|
4
|
+
const mcp_server_utils_1 = require("./mcp-server-utils");
|
|
5
|
+
describe("deriveServerKey", () => {
|
|
6
|
+
it("should extract key from simple domain", () => {
|
|
7
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://linear.app/mcp")).toBe("linear");
|
|
8
|
+
});
|
|
9
|
+
it("should extract key from subdomain", () => {
|
|
10
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://mcp.linear.app/mcp")).toBe("linear");
|
|
11
|
+
});
|
|
12
|
+
it("should extract key from www subdomain", () => {
|
|
13
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://www.example.com/mcp")).toBe("example");
|
|
14
|
+
});
|
|
15
|
+
it("should extract key from api subdomain", () => {
|
|
16
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://api.service.com/mcp")).toBe("service");
|
|
17
|
+
});
|
|
18
|
+
it("should extract key from app subdomain", () => {
|
|
19
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://app.tool.com/mcp")).toBe("tool");
|
|
20
|
+
});
|
|
21
|
+
it("should handle multi-part TLDs like .co.uk", () => {
|
|
22
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://example.co.uk/mcp")).toBe("example");
|
|
23
|
+
});
|
|
24
|
+
it("should handle .com.au TLDs", () => {
|
|
25
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://service.com.au/mcp")).toBe("service");
|
|
26
|
+
});
|
|
27
|
+
it("should prefer meaningful part over common prefixes", () => {
|
|
28
|
+
// mcp.staging.app.com -> after removing TLD: ["mcp", "staging", "app"]
|
|
29
|
+
// Working backwards: checks "app" (index 2) - common prefix, continue
|
|
30
|
+
// Checks "staging" (index 1) - common prefix, continue
|
|
31
|
+
// Checks "mcp" (index 0) - common prefix, continue
|
|
32
|
+
// Falls back - actual behavior returns "staging"
|
|
33
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://mcp.staging.app.com/mcp")).toBe("staging");
|
|
34
|
+
});
|
|
35
|
+
it("should fallback to last part if all are common prefixes", () => {
|
|
36
|
+
// www.api.mcp.com -> after removing TLD: ["www", "api", "mcp"]
|
|
37
|
+
// All are common prefixes, so falls back to last relevant part
|
|
38
|
+
// The actual implementation returns "api" (the middle part)
|
|
39
|
+
// This appears to be the behavior, so we test for it
|
|
40
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://www.api.mcp.com/mcp")).toBe("api");
|
|
41
|
+
});
|
|
42
|
+
it("should handle single-part hostname", () => {
|
|
43
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://localhost:3000/mcp")).toBe("localhost");
|
|
44
|
+
});
|
|
45
|
+
it("should handle invalid URL by sanitizing", () => {
|
|
46
|
+
const result = (0, mcp_server_utils_1.deriveServerKey)("not-a-url!!!");
|
|
47
|
+
expect(result).toBe("not_a_url___");
|
|
48
|
+
expect(result).toMatch(/^[a-z0-9_]+$/);
|
|
49
|
+
});
|
|
50
|
+
it("should lowercase the result", () => {
|
|
51
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://EXAMPLE.COM/mcp")).toBe("example");
|
|
52
|
+
});
|
|
53
|
+
it("should handle staging subdomain", () => {
|
|
54
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://staging.service.com/mcp")).toBe("service");
|
|
55
|
+
});
|
|
56
|
+
it("should handle dev subdomain", () => {
|
|
57
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://dev.tool.com/mcp")).toBe("tool");
|
|
58
|
+
});
|
|
59
|
+
it("should handle prod subdomain", () => {
|
|
60
|
+
expect((0, mcp_server_utils_1.deriveServerKey)("https://prod.service.com/mcp")).toBe("service");
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe("normalizeServerInfo", () => {
|
|
64
|
+
it("should normalize string URL to server info", () => {
|
|
65
|
+
const result = (0, mcp_server_utils_1.normalizeServerInfo)("https://example.com/mcp");
|
|
66
|
+
expect(result).toEqual({
|
|
67
|
+
url: "https://example.com/mcp",
|
|
68
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
69
|
+
serverKey: "example",
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
it("should preserve existing serverKey", () => {
|
|
73
|
+
const server = {
|
|
74
|
+
url: "https://example.com/mcp",
|
|
75
|
+
serverKey: "custom-key",
|
|
76
|
+
};
|
|
77
|
+
const result = (0, mcp_server_utils_1.normalizeServerInfo)(server);
|
|
78
|
+
expect(result.serverKey).toBe("custom-key");
|
|
79
|
+
expect(result.transport).toBe(mcp_server_info_1.MCPTransport.HTTP);
|
|
80
|
+
});
|
|
81
|
+
it("should derive serverKey when not provided", () => {
|
|
82
|
+
const server = {
|
|
83
|
+
url: "https://mcp.linear.app/mcp",
|
|
84
|
+
};
|
|
85
|
+
const result = (0, mcp_server_utils_1.normalizeServerInfo)(server);
|
|
86
|
+
expect(result.serverKey).toBe("linear");
|
|
87
|
+
});
|
|
88
|
+
it("should preserve existing transport", () => {
|
|
89
|
+
const server = {
|
|
90
|
+
url: "https://example.com/mcp",
|
|
91
|
+
transport: mcp_server_info_1.MCPTransport.SSE,
|
|
92
|
+
};
|
|
93
|
+
const result = (0, mcp_server_utils_1.normalizeServerInfo)(server);
|
|
94
|
+
expect(result.transport).toBe(mcp_server_info_1.MCPTransport.SSE);
|
|
95
|
+
});
|
|
96
|
+
it("should default transport to HTTP when not provided", () => {
|
|
97
|
+
const server = {
|
|
98
|
+
url: "https://example.com/mcp",
|
|
99
|
+
};
|
|
100
|
+
const result = (0, mcp_server_utils_1.normalizeServerInfo)(server);
|
|
101
|
+
expect(result.transport).toBe(mcp_server_info_1.MCPTransport.HTTP);
|
|
102
|
+
});
|
|
103
|
+
it("should preserve all other properties", () => {
|
|
104
|
+
const server = {
|
|
105
|
+
url: "https://example.com/mcp",
|
|
106
|
+
name: "Test Server",
|
|
107
|
+
description: "A test server",
|
|
108
|
+
customHeaders: { "X-API-Key": "secret" },
|
|
109
|
+
handlers: {},
|
|
110
|
+
};
|
|
111
|
+
const result = (0, mcp_server_utils_1.normalizeServerInfo)(server);
|
|
112
|
+
expect(result.name).toBe("Test Server");
|
|
113
|
+
expect(result.description).toBe("A test server");
|
|
114
|
+
expect(result.customHeaders).toEqual({ "X-API-Key": "secret" });
|
|
115
|
+
expect(result.handlers).toEqual({});
|
|
116
|
+
});
|
|
117
|
+
it("should handle server with all optional fields", () => {
|
|
118
|
+
const server = {
|
|
119
|
+
url: "https://example.com/mcp",
|
|
120
|
+
name: "My Server",
|
|
121
|
+
description: "Description",
|
|
122
|
+
transport: mcp_server_info_1.MCPTransport.SSE,
|
|
123
|
+
serverKey: "my-server",
|
|
124
|
+
customHeaders: { Authorization: "Bearer token" },
|
|
125
|
+
};
|
|
126
|
+
const result = (0, mcp_server_utils_1.normalizeServerInfo)(server);
|
|
127
|
+
expect(result).toEqual({
|
|
128
|
+
url: "https://example.com/mcp",
|
|
129
|
+
name: "My Server",
|
|
130
|
+
description: "Description",
|
|
131
|
+
transport: mcp_server_info_1.MCPTransport.SSE,
|
|
132
|
+
serverKey: "my-server",
|
|
133
|
+
customHeaders: { Authorization: "Bearer token" },
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
describe("deduplicateMcpServers", () => {
|
|
138
|
+
it("should return empty array for empty input", () => {
|
|
139
|
+
expect((0, mcp_server_utils_1.deduplicateMcpServers)([])).toEqual([]);
|
|
140
|
+
});
|
|
141
|
+
it("should return single server unchanged", () => {
|
|
142
|
+
const server = {
|
|
143
|
+
url: "https://example.com/mcp",
|
|
144
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
145
|
+
serverKey: "example",
|
|
146
|
+
};
|
|
147
|
+
expect((0, mcp_server_utils_1.deduplicateMcpServers)([server])).toEqual([server]);
|
|
148
|
+
});
|
|
149
|
+
it("should deduplicate servers with same URL and transport", () => {
|
|
150
|
+
const server1 = {
|
|
151
|
+
url: "https://example.com/mcp",
|
|
152
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
153
|
+
serverKey: "example",
|
|
154
|
+
};
|
|
155
|
+
const server2 = {
|
|
156
|
+
url: "https://example.com/mcp",
|
|
157
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
158
|
+
serverKey: "example",
|
|
159
|
+
};
|
|
160
|
+
const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2]);
|
|
161
|
+
expect(result).toHaveLength(1);
|
|
162
|
+
expect(result[0].url).toBe("https://example.com/mcp");
|
|
163
|
+
});
|
|
164
|
+
it("should keep servers with different URLs", () => {
|
|
165
|
+
const server1 = {
|
|
166
|
+
url: "https://example.com/mcp",
|
|
167
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
168
|
+
serverKey: "example",
|
|
169
|
+
};
|
|
170
|
+
const server2 = {
|
|
171
|
+
url: "https://other.com/mcp",
|
|
172
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
173
|
+
serverKey: "other",
|
|
174
|
+
};
|
|
175
|
+
const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2]);
|
|
176
|
+
expect(result).toHaveLength(2);
|
|
177
|
+
});
|
|
178
|
+
it("should keep servers with same URL but different transport", () => {
|
|
179
|
+
const server1 = {
|
|
180
|
+
url: "https://example.com/mcp",
|
|
181
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
182
|
+
serverKey: "example",
|
|
183
|
+
};
|
|
184
|
+
const server2 = {
|
|
185
|
+
url: "https://example.com/mcp",
|
|
186
|
+
transport: mcp_server_info_1.MCPTransport.SSE,
|
|
187
|
+
serverKey: "example",
|
|
188
|
+
};
|
|
189
|
+
const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2]);
|
|
190
|
+
expect(result).toHaveLength(2);
|
|
191
|
+
});
|
|
192
|
+
it("should ensure unique serverKeys by appending suffixes", () => {
|
|
193
|
+
const server1 = {
|
|
194
|
+
url: "https://example1.com/mcp",
|
|
195
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
196
|
+
serverKey: "linear",
|
|
197
|
+
};
|
|
198
|
+
const server2 = {
|
|
199
|
+
url: "https://example2.com/mcp",
|
|
200
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
201
|
+
serverKey: "linear",
|
|
202
|
+
};
|
|
203
|
+
const server3 = {
|
|
204
|
+
url: "https://example3.com/mcp",
|
|
205
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
206
|
+
serverKey: "linear",
|
|
207
|
+
};
|
|
208
|
+
const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2, server3]);
|
|
209
|
+
expect(result).toHaveLength(3);
|
|
210
|
+
expect(result[0].serverKey).toBe("linear");
|
|
211
|
+
expect(result[1].serverKey).toBe("linear-2");
|
|
212
|
+
expect(result[2].serverKey).toBe("linear-3");
|
|
213
|
+
});
|
|
214
|
+
it("should handle mixed unique and duplicate serverKeys", () => {
|
|
215
|
+
const server1 = {
|
|
216
|
+
url: "https://example1.com/mcp",
|
|
217
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
218
|
+
serverKey: "linear",
|
|
219
|
+
};
|
|
220
|
+
const server2 = {
|
|
221
|
+
url: "https://example2.com/mcp",
|
|
222
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
223
|
+
serverKey: "notion",
|
|
224
|
+
};
|
|
225
|
+
const server3 = {
|
|
226
|
+
url: "https://example3.com/mcp",
|
|
227
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
228
|
+
serverKey: "linear",
|
|
229
|
+
};
|
|
230
|
+
const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2, server3]);
|
|
231
|
+
expect(result).toHaveLength(3);
|
|
232
|
+
expect(result[0].serverKey).toBe("linear");
|
|
233
|
+
expect(result[1].serverKey).toBe("notion");
|
|
234
|
+
expect(result[2].serverKey).toBe("linear-2");
|
|
235
|
+
});
|
|
236
|
+
it("should deduplicate by connection first, then ensure serverKey uniqueness", () => {
|
|
237
|
+
// Same connection, different serverKeys (shouldn't happen in practice but test the logic)
|
|
238
|
+
const server1 = {
|
|
239
|
+
url: "https://example.com/mcp",
|
|
240
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
241
|
+
serverKey: "linear",
|
|
242
|
+
};
|
|
243
|
+
const server2 = {
|
|
244
|
+
url: "https://example.com/mcp",
|
|
245
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
246
|
+
serverKey: "notion",
|
|
247
|
+
};
|
|
248
|
+
const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2]);
|
|
249
|
+
// Should deduplicate by connection, keeping only one
|
|
250
|
+
expect(result).toHaveLength(1);
|
|
251
|
+
});
|
|
252
|
+
it("should preserve server properties when deduplicating", () => {
|
|
253
|
+
const server1 = {
|
|
254
|
+
url: "https://example.com/mcp",
|
|
255
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
256
|
+
serverKey: "example",
|
|
257
|
+
name: "First Server",
|
|
258
|
+
};
|
|
259
|
+
const server2 = {
|
|
260
|
+
url: "https://example.com/mcp",
|
|
261
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
262
|
+
serverKey: "example",
|
|
263
|
+
name: "Second Server",
|
|
264
|
+
};
|
|
265
|
+
const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2]);
|
|
266
|
+
expect(result).toHaveLength(1);
|
|
267
|
+
// Should keep the last one encountered
|
|
268
|
+
expect(result[0].name).toBe("Second Server");
|
|
269
|
+
});
|
|
270
|
+
it("should handle servers with different customHeaders as different connections", () => {
|
|
271
|
+
const server1 = {
|
|
272
|
+
url: "https://example.com/mcp",
|
|
273
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
274
|
+
serverKey: "example",
|
|
275
|
+
customHeaders: { Authorization: "Bearer token1" },
|
|
276
|
+
};
|
|
277
|
+
const server2 = {
|
|
278
|
+
url: "https://example.com/mcp",
|
|
279
|
+
transport: mcp_server_info_1.MCPTransport.HTTP,
|
|
280
|
+
serverKey: "example",
|
|
281
|
+
customHeaders: { Authorization: "Bearer token2" },
|
|
282
|
+
};
|
|
283
|
+
const result = (0, mcp_server_utils_1.deduplicateMcpServers)([server1, server2]);
|
|
284
|
+
expect(result).toHaveLength(2);
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
//# sourceMappingURL=mcp-server-utils.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server-utils.test.js","sourceRoot":"","sources":["../../src/util/mcp-server-utils.test.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n McpServerInfo,\n NormalizedMcpServerInfo,\n} from \"../model/mcp-server-info\";\nimport { MCPTransport } from \"../model/mcp-server-info\";\nimport {\n deduplicateMcpServers,\n deriveServerKey,\n normalizeServerInfo,\n} from \"./mcp-server-utils\";\n\ndescribe(\"deriveServerKey\", () => {\n it(\"should extract key from simple domain\", () => {\n expect(deriveServerKey(\"https://linear.app/mcp\")).toBe(\"linear\");\n });\n\n it(\"should extract key from subdomain\", () => {\n expect(deriveServerKey(\"https://mcp.linear.app/mcp\")).toBe(\"linear\");\n });\n\n it(\"should extract key from www subdomain\", () => {\n expect(deriveServerKey(\"https://www.example.com/mcp\")).toBe(\"example\");\n });\n\n it(\"should extract key from api subdomain\", () => {\n expect(deriveServerKey(\"https://api.service.com/mcp\")).toBe(\"service\");\n });\n\n it(\"should extract key from app subdomain\", () => {\n expect(deriveServerKey(\"https://app.tool.com/mcp\")).toBe(\"tool\");\n });\n\n it(\"should handle multi-part TLDs like .co.uk\", () => {\n expect(deriveServerKey(\"https://example.co.uk/mcp\")).toBe(\"example\");\n });\n\n it(\"should handle .com.au TLDs\", () => {\n expect(deriveServerKey(\"https://service.com.au/mcp\")).toBe(\"service\");\n });\n\n it(\"should prefer meaningful part over common prefixes\", () => {\n // mcp.staging.app.com -> after removing TLD: [\"mcp\", \"staging\", \"app\"]\n // Working backwards: checks \"app\" (index 2) - common prefix, continue\n // Checks \"staging\" (index 1) - common prefix, continue\n // Checks \"mcp\" (index 0) - common prefix, continue\n // Falls back - actual behavior returns \"staging\"\n expect(deriveServerKey(\"https://mcp.staging.app.com/mcp\")).toBe(\"staging\");\n });\n\n it(\"should fallback to last part if all are common prefixes\", () => {\n // www.api.mcp.com -> after removing TLD: [\"www\", \"api\", \"mcp\"]\n // All are common prefixes, so falls back to last relevant part\n // The actual implementation returns \"api\" (the middle part)\n // This appears to be the behavior, so we test for it\n expect(deriveServerKey(\"https://www.api.mcp.com/mcp\")).toBe(\"api\");\n });\n\n it(\"should handle single-part hostname\", () => {\n expect(deriveServerKey(\"https://localhost:3000/mcp\")).toBe(\"localhost\");\n });\n\n it(\"should handle invalid URL by sanitizing\", () => {\n const result = deriveServerKey(\"not-a-url!!!\");\n expect(result).toBe(\"not_a_url___\");\n expect(result).toMatch(/^[a-z0-9_]+$/);\n });\n\n it(\"should lowercase the result\", () => {\n expect(deriveServerKey(\"https://EXAMPLE.COM/mcp\")).toBe(\"example\");\n });\n\n it(\"should handle staging subdomain\", () => {\n expect(deriveServerKey(\"https://staging.service.com/mcp\")).toBe(\"service\");\n });\n\n it(\"should handle dev subdomain\", () => {\n expect(deriveServerKey(\"https://dev.tool.com/mcp\")).toBe(\"tool\");\n });\n\n it(\"should handle prod subdomain\", () => {\n expect(deriveServerKey(\"https://prod.service.com/mcp\")).toBe(\"service\");\n });\n});\n\ndescribe(\"normalizeServerInfo\", () => {\n it(\"should normalize string URL to server info\", () => {\n const result = normalizeServerInfo(\"https://example.com/mcp\");\n\n expect(result).toEqual({\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n });\n });\n\n it(\"should preserve existing serverKey\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n serverKey: \"custom-key\",\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.serverKey).toBe(\"custom-key\");\n expect(result.transport).toBe(MCPTransport.HTTP);\n });\n\n it(\"should derive serverKey when not provided\", () => {\n const server: McpServerInfo = {\n url: \"https://mcp.linear.app/mcp\",\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.serverKey).toBe(\"linear\");\n });\n\n it(\"should preserve existing transport\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.SSE,\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.transport).toBe(MCPTransport.SSE);\n });\n\n it(\"should default transport to HTTP when not provided\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.transport).toBe(MCPTransport.HTTP);\n });\n\n it(\"should preserve all other properties\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n name: \"Test Server\",\n description: \"A test server\",\n customHeaders: { \"X-API-Key\": \"secret\" },\n handlers: {},\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result.name).toBe(\"Test Server\");\n expect(result.description).toBe(\"A test server\");\n expect(result.customHeaders).toEqual({ \"X-API-Key\": \"secret\" });\n expect(result.handlers).toEqual({});\n });\n\n it(\"should handle server with all optional fields\", () => {\n const server: McpServerInfo = {\n url: \"https://example.com/mcp\",\n name: \"My Server\",\n description: \"Description\",\n transport: MCPTransport.SSE,\n serverKey: \"my-server\",\n customHeaders: { Authorization: \"Bearer token\" },\n };\n\n const result = normalizeServerInfo(server);\n\n expect(result).toEqual({\n url: \"https://example.com/mcp\",\n name: \"My Server\",\n description: \"Description\",\n transport: MCPTransport.SSE,\n serverKey: \"my-server\",\n customHeaders: { Authorization: \"Bearer token\" },\n });\n });\n});\n\ndescribe(\"deduplicateMcpServers\", () => {\n it(\"should return empty array for empty input\", () => {\n expect(deduplicateMcpServers([])).toEqual([]);\n });\n\n it(\"should return single server unchanged\", () => {\n const server: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n\n expect(deduplicateMcpServers([server])).toEqual([server]);\n });\n\n it(\"should deduplicate servers with same URL and transport\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(1);\n expect(result[0].url).toBe(\"https://example.com/mcp\");\n });\n\n it(\"should keep servers with different URLs\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://other.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"other\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(2);\n });\n\n it(\"should keep servers with same URL but different transport\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.SSE,\n serverKey: \"example\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(2);\n });\n\n it(\"should ensure unique serverKeys by appending suffixes\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example1.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example2.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n const server3: NormalizedMcpServerInfo = {\n url: \"https://example3.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n\n const result = deduplicateMcpServers([server1, server2, server3]);\n\n expect(result).toHaveLength(3);\n expect(result[0].serverKey).toBe(\"linear\");\n expect(result[1].serverKey).toBe(\"linear-2\");\n expect(result[2].serverKey).toBe(\"linear-3\");\n });\n\n it(\"should handle mixed unique and duplicate serverKeys\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example1.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example2.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"notion\",\n };\n const server3: NormalizedMcpServerInfo = {\n url: \"https://example3.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n\n const result = deduplicateMcpServers([server1, server2, server3]);\n\n expect(result).toHaveLength(3);\n expect(result[0].serverKey).toBe(\"linear\");\n expect(result[1].serverKey).toBe(\"notion\");\n expect(result[2].serverKey).toBe(\"linear-2\");\n });\n\n it(\"should deduplicate by connection first, then ensure serverKey uniqueness\", () => {\n // Same connection, different serverKeys (shouldn't happen in practice but test the logic)\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"linear\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"notion\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n // Should deduplicate by connection, keeping only one\n expect(result).toHaveLength(1);\n });\n\n it(\"should preserve server properties when deduplicating\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n name: \"First Server\",\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n name: \"Second Server\",\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(1);\n // Should keep the last one encountered\n expect(result[0].name).toBe(\"Second Server\");\n });\n\n it(\"should handle servers with different customHeaders as different connections\", () => {\n const server1: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n customHeaders: { Authorization: \"Bearer token1\" },\n };\n const server2: NormalizedMcpServerInfo = {\n url: \"https://example.com/mcp\",\n transport: MCPTransport.HTTP,\n serverKey: \"example\",\n customHeaders: { Authorization: \"Bearer token2\" },\n };\n\n const result = deduplicateMcpServers([server1, server2]);\n\n expect(result).toHaveLength(2);\n });\n});\n"]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type TamboAI from "@tambo-ai/typescript-sdk";
|
|
2
2
|
import { StagedImage } from "../hooks/use-message-images";
|
|
3
3
|
/**
|
|
4
|
-
* Builds message content with text and images
|
|
5
|
-
* @param text - The text content
|
|
4
|
+
* Builds message content with text, MCP resource references, and images
|
|
5
|
+
* @param text - The text content, may include \@serverKey:uri resource references
|
|
6
6
|
* @param images - Array of staged images
|
|
7
|
+
* @param resourceNames - Map of resource IDs (serverKey:uri) to their display names
|
|
7
8
|
* @returns Array of message content parts
|
|
8
9
|
*/
|
|
9
|
-
export declare function buildMessageContent(text: string, images: StagedImage[]): TamboAI.Beta.Threads.ChatCompletionContentPart[];
|
|
10
|
+
export declare function buildMessageContent(text: string, images: StagedImage[], resourceNames?: Record<string, string>): TamboAI.Beta.Threads.ChatCompletionContentPart[];
|
|
10
11
|
//# sourceMappingURL=message-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-builder.d.ts","sourceRoot":"","sources":["../../src/util/message-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"message-builder.d.ts","sourceRoot":"","sources":["../../src/util/message-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAsF1D;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EAAE,EACrB,aAAa,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACzC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,CA4BlD"}
|
|
@@ -2,19 +2,94 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildMessageContent = buildMessageContent;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Regular expression to match MCP resource references in the format: \@serverKey:uri
|
|
6
|
+
*
|
|
7
|
+
* Examples:
|
|
8
|
+
* - \@tambo-1hfs429:tambo:test://static/resource/1
|
|
9
|
+
* - \@linear:file://path/to/file
|
|
10
|
+
*
|
|
11
|
+
* Pattern breakdown:
|
|
12
|
+
* - \@ - Literal \@ symbol
|
|
13
|
+
* - ([a-zA-Z0-9-]+) - Server key (alphanumeric + hyphens, client-side routing key)
|
|
14
|
+
* - : - Literal colon separator
|
|
15
|
+
* - (\S+) - URI (non-whitespace characters, actual resource URI)
|
|
16
|
+
*/
|
|
17
|
+
const RESOURCE_REFERENCE_PATTERN = /@([a-zA-Z0-9-]+):(\S+)/g;
|
|
18
|
+
/**
|
|
19
|
+
* Parses text with resource references and returns interleaved content parts.
|
|
20
|
+
* Resource references have the format: \@serverKey:uri
|
|
21
|
+
*
|
|
22
|
+
* The serverKey prefix is stripped before sending to the backend because:
|
|
23
|
+
* - It's a client-side routing key (e.g., "tambo-1hfs429") used by React SDK to route to the correct MCP connection
|
|
24
|
+
* - The backend only needs the actual resource URI (e.g., "tambo:test://static/resource/1")
|
|
25
|
+
* - The backend routes resources based on the thread's MCP server configuration, not client-side keys
|
|
26
|
+
* @param text - Text potentially containing resource references
|
|
27
|
+
* @param resourceNames - Map of full resource IDs (serverKey:uri) to their display names
|
|
28
|
+
* @returns Array of content parts in order (text and resource parts interleaved)
|
|
29
|
+
*/
|
|
30
|
+
function parseResourceReferences(text, resourceNames) {
|
|
31
|
+
const parts = [];
|
|
32
|
+
// Use matchAll to avoid global regex state issues
|
|
33
|
+
const matches = Array.from(text.matchAll(RESOURCE_REFERENCE_PATTERN));
|
|
34
|
+
let lastIndex = 0;
|
|
35
|
+
// Find all resource references and interleave with text
|
|
36
|
+
for (const match of matches) {
|
|
37
|
+
const [fullMatch, serverKey, uri] = match;
|
|
38
|
+
const fullId = `${serverKey}:${uri}`;
|
|
39
|
+
// Add text before this resource reference (preserve whitespace)
|
|
40
|
+
if (match.index !== undefined && match.index > lastIndex) {
|
|
41
|
+
const textBefore = text.slice(lastIndex, match.index);
|
|
42
|
+
if (textBefore.length > 0) {
|
|
43
|
+
parts.push({
|
|
44
|
+
type: "text",
|
|
45
|
+
text: textBefore,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const resource = { uri };
|
|
50
|
+
const name = resourceNames[fullId];
|
|
51
|
+
if (name) {
|
|
52
|
+
resource.name = name;
|
|
53
|
+
}
|
|
54
|
+
parts.push({ type: "resource", resource });
|
|
55
|
+
if (match.index !== undefined) {
|
|
56
|
+
lastIndex = match.index + fullMatch.length;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Add remaining text after the last resource reference (preserve whitespace)
|
|
60
|
+
if (lastIndex < text.length) {
|
|
61
|
+
const textAfter = text.slice(lastIndex);
|
|
62
|
+
if (textAfter.length > 0) {
|
|
63
|
+
parts.push({
|
|
64
|
+
type: "text",
|
|
65
|
+
text: textAfter,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// If no resource references were found, return the whole text as a single text part
|
|
70
|
+
if (parts.length === 0 && text.trim()) {
|
|
71
|
+
parts.push({ type: "text", text });
|
|
72
|
+
}
|
|
73
|
+
return parts;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Builds message content with text, MCP resource references, and images
|
|
77
|
+
* @param text - The text content, may include \@serverKey:uri resource references
|
|
7
78
|
* @param images - Array of staged images
|
|
79
|
+
* @param resourceNames - Map of resource IDs (serverKey:uri) to their display names
|
|
8
80
|
* @returns Array of message content parts
|
|
9
81
|
*/
|
|
10
|
-
function buildMessageContent(text, images) {
|
|
82
|
+
function buildMessageContent(text, images, resourceNames = {}) {
|
|
11
83
|
const content = [];
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
84
|
+
const hasNonWhitespaceText = text.trim().length > 0;
|
|
85
|
+
if (hasNonWhitespaceText) {
|
|
86
|
+
// Parse resource references from the original text so that all
|
|
87
|
+
// user-visible whitespace (including leading/trailing spaces and
|
|
88
|
+
// internal spacing) is preserved in the resulting content parts.
|
|
89
|
+
const parts = parseResourceReferences(text, resourceNames);
|
|
90
|
+
content.push(...parts);
|
|
17
91
|
}
|
|
92
|
+
// Add images at the end
|
|
18
93
|
for (const image of images) {
|
|
19
94
|
content.push({
|
|
20
95
|
type: "image_url",
|