@tambo-ai/react 0.65.3 → 0.66.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/README.md +120 -20
- package/dist/{providers/hoc → 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-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/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/index.d.ts +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +2 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/mcp-hooks.d.ts +77 -6
- 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.js +83 -18
- package/dist/mcp/mcp-hooks.test.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/dist/mcp/tambo-mcp-provider.js +2 -1
- package/dist/mcp/tambo-mcp-provider.js.map +1 -1
- 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/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/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-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-interactable-provider-partial-updates.test.js +87 -87
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- 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.js +9 -9
- package/dist/providers/tambo-interactables-additional-context-edge-cases.test.js.map +1 -1
- package/dist/providers/tambo-interactables-additional-context.test.js +11 -11
- package/dist/providers/tambo-interactables-additional-context.test.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.js +152 -30
- package/dist/providers/tambo-registry-provider.test.js.map +1 -1
- 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 +5 -0
- package/dist/providers/tambo-stubs.js.map +1 -1
- package/dist/providers/tambo-thread-input-provider.d.ts +1 -0
- 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.d.ts.map +1 -1
- package/dist/providers/tambo-thread-provider.js.map +1 -1
- package/dist/providers/tambo-thread-provider.test.js +32 -36
- package/dist/providers/tambo-thread-provider.test.js.map +1 -1
- 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 +189 -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 +147 -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/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 +2 -1
- package/dist/util/message-builder.d.ts.map +1 -1
- package/dist/util/message-builder.js +54 -36
- package/dist/util/message-builder.js.map +1 -1
- package/dist/util/message-builder.test.js +500 -13
- package/dist/util/message-builder.test.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/{providers/hoc → 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-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/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/index.d.ts +1 -1
- 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-hooks.d.ts +77 -6
- 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.js +84 -19
- package/esm/mcp/mcp-hooks.test.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/esm/mcp/tambo-mcp-provider.js +2 -1
- package/esm/mcp/tambo-mcp-provider.js.map +1 -1
- 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/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/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-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-interactable-provider-partial-updates.test.js +1 -1
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- 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.js +3 -3
- package/esm/providers/tambo-interactables-additional-context-edge-cases.test.js.map +1 -1
- package/esm/providers/tambo-interactables-additional-context.test.js +3 -3
- package/esm/providers/tambo-interactables-additional-context.test.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.js +148 -26
- package/esm/providers/tambo-registry-provider.test.js.map +1 -1
- 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 +5 -0
- package/esm/providers/tambo-stubs.js.map +1 -1
- package/esm/providers/tambo-thread-input-provider.d.ts +1 -0
- 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.d.ts.map +1 -1
- package/esm/providers/tambo-thread-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider.test.js +24 -28
- package/esm/providers/tambo-thread-provider.test.js.map +1 -1
- 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 +182 -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 +136 -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/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 +2 -1
- package/esm/util/message-builder.d.ts.map +1 -1
- package/esm/util/message-builder.js +54 -36
- package/esm/util/message-builder.js.map +1 -1
- package/esm/util/message-builder.test.js +500 -13
- package/esm/util/message-builder.test.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 +13 -8
- 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/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/dist/util/validate-zod-schema.test.d.ts +0 -2
- package/dist/util/validate-zod-schema.test.d.ts.map +0 -1
- package/dist/util/validate-zod-schema.test.js +0 -96
- package/dist/util/validate-zod-schema.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/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/esm/util/validate-zod-schema.test.d.ts +0 -2
- package/esm/util/validate-zod-schema.test.d.ts.map +0 -1
- package/esm/util/validate-zod-schema.test.js +0 -94
- package/esm/util/validate-zod-schema.test.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-hooks.test.js","sourceRoot":"","sources":["../../src/mcp/mcp-hooks.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,GAGpB,MAAM,aAAa,CAAC;AAErB,gDAAgD;AAChD,IAAI,UAAU,GAAc,IAAI,CAAC,EAAE,EAAE,CAAC;AACtC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/B,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,EAAE;IAC9D,YAAY,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE;CAC3C,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,mDAAmD,EAAE,GAAG,EAAE;IACjE,IAAI,WAAwB,CAAC;IAE7B,UAAU,CAAC,GAAG,EAAE;QACd,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QACvB,WAAW,GAAG,IAAI,WAAW,CAAC;YAC5B,cAAc,EAAE;gBACd,OAAO,EAAE;oBACP,KAAK,EAAE,KAAK,EAAE,4BAA4B;iBAC3C;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,0CAA0C;QAC1C,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;gBAC/C,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;aAChD;SACF,CAAC;QACF,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;gBAC/C,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;aAChD;SACF,CAAC;QAEF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;YACxD,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;YACxD,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,uEAAuE;QACvE,UAAU,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;YAClD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,IAAI,eAAe,GAAsB,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAa,GAAG,EAAE;YAC7B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAC;YAClD,SAAS,CAAC,GAAG,EAAE;gBACb,IAAI,OAAO,EAAE,CAAC;oBACZ,eAAe,GAAG,OAAO,CAAC;gBAC5B,CAAC;YACH,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;YACd,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,CACJ,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;oBACD;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,oCAAoC;QACpC,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,yEAAyE;QACzE,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9D,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAEpD,iDAAiD;QACjD,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CACnC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,oBAAoB,CAC9C,CAAC;QACF,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAE9D,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CACnC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,oBAAoB,CAC9C,CAAC;QACF,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,0CAA0C;QAC1C,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;gBAC/C,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;aAChD;SACF,CAAC;QACF,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;gBAC/C,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;aAChD;SACF,CAAC;QAEF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;YACxD,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;YACxD,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,UAAU,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;YAClD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,IAAI,eAAe,GAAsB,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAa,GAAG,EAAE;YAC7B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAC;YAClD,SAAS,CAAC,GAAG,EAAE;gBACb,IAAI,OAAO,EAAE,CAAC;oBACZ,eAAe,GAAG,OAAO,CAAC;gBAC5B,CAAC;YACH,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;YACd,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CACzB,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;oBACD;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,wCAAwC;QACxC,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,MAAM,kBAAkB,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACrE,MAAM,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC3D,MAAM,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC3D,MAAM,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC3D,MAAM,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAE3D,kBAAkB;QAClB,QAAQ,CACN,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,qEAAqE;QACrE,6DAA6D;QAC7D,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,MAAM,kBAAkB,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACrE,MAAM,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACtD,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACtD,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,+BAA+B;QAE/F,sCAAsC;QACtC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;SACzD,CAAC;QACF,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;SACzD,CAAC;QAEF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;YACxD,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;YACxD,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,UAAU,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;YAClD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,IAAI,eAAe,GAAsB,EAAE,CAAC;QAC5C,IAAI,kBAAkB,GAAa,EAAE,CAAC;QACtC,MAAM,OAAO,GAAa,GAAG,EAAE;YAC7B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;YACrC,SAAS,CAAC,GAAG,EAAE;gBACb,IAAI,OAAO,EAAE,CAAC;oBACZ,eAAe,GAAG,OAAO,CAAC;gBAC5B,CAAC;gBACD,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACjD,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,CACJ,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;oBACD;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,gCAAgC;QAChC,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,qDAAqD;QACrD,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAEzD,8DAA8D;QAC9D,MAAM,SAAS,GAAG,WAAW;aAC1B,aAAa,EAAE;aACf,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAElC,+DAA+D;QAC/D,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,CACtC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,aAAa,CACxD,CAAC;QACF,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvC,sDAAsD;QACtD,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/D,6EAA6E;QAC7E,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvE,uFAAuF;QACvF,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QACH,oBAAoB;QACpB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;SACzD,CAAC;QAEF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;YACxD,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,gCAAgC;QAChC,UAAU,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;YAClD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,IAAI,GAAG,KAAK,0BAA0B,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,IAAI,eAAe,GAAsB,EAAE,CAAC;QAC5C,IAAI,eAAe,GAAG,CAAC,CAAC;QACxB,MAAM,OAAO,GAAa,GAAG,EAAE;YAC7B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;YACrC,SAAS,CAAC,GAAG,EAAE;gBACb,IAAI,OAAO,EAAE,CAAC;oBACZ,eAAe,GAAG,OAAO,CAAC;gBAC5B,CAAC;gBACD,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;YACnC,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,CACJ,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;oBACD;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,yCAAyC;QACzC,8CAA8C;QAC9C,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,qCAAqC;QACxE,CAAC,CAAC,CAAC;QAEH,sFAAsF;QACtF,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9D,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACnD,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;SACzD,CAAC;QACF,MAAM,cAAc,GAAG;YACrB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;SACzD,CAAC;QAEF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;YACxD,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;YACxD,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,UAAU,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;YAClD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,IAAI,eAAe,GAAsB,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAa,GAAG,EAAE;YAC7B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAC;YAClD,SAAS,CAAC,GAAG,EAAE;gBACb,IAAI,OAAO,EAAE,CAAC;oBACZ,eAAe,GAAG,OAAO,CAAC;gBAC5B,CAAC;YACH,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;YACd,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CACzB,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,yCAAyC;QACzC,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAExE,eAAe;QACf,QAAQ,CACN,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;oBACD;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,wCAAwC;QACxC,iDAAiD;QACjD,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9D,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACnD,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,+CAA+C,EAAE,GAAG,EAAE;IAC7D,IAAI,WAAwB,CAAC;IAE7B,UAAU,CAAC,GAAG,EAAE;QACd,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QACvB,WAAW,GAAG,IAAI,WAAW,CAAC;YAC5B,cAAc,EAAE;gBACd,OAAO,EAAE;oBACP,KAAK,EAAE,KAAK;iBACb;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,4CAA4C;QAC5C,MAAM,gBAAgB,GAAG;YACvB,SAAS,EAAE;gBACT;oBACE,GAAG,EAAE,4BAA4B;oBACjC,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,YAAY;iBACvB;gBACD;oBACE,GAAG,EAAE,4BAA4B;oBACjC,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,YAAY;iBACvB;aACF;SACF,CAAC;QACF,MAAM,gBAAgB,GAAG;YACvB,SAAS,EAAE;gBACT;oBACE,GAAG,EAAE,2BAA2B;oBAChC,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,iBAAiB;iBAC5B;gBACD;oBACE,GAAG,EAAE,6BAA6B;oBAClC,IAAI,EAAE,QAAQ;oBACd,QAAQ,EAAE,eAAe;iBAC1B;aACF;SACF,CAAC;QAEF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACzD,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;YAC5D,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACzD,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;YAC5D,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,UAAU,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;YAClD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,IAAI,iBAAiB,GAAwB,EAAE,CAAC;QAChD,MAAM,OAAO,GAAa,GAAG,EAAE;YAC7B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,uBAAuB,EAAE,CAAC;YACtD,SAAS,CAAC,GAAG,EAAE;gBACb,IAAI,SAAS,EAAE,CAAC;oBACd,iBAAiB,GAAG,SAAS,CAAC;gBAChC,CAAC;YACH,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,CACJ,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;oBACD;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,sCAAsC;QACtC,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,2EAA2E;QAC3E,MAAM,YAAY,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAClE,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,qCAAqC,CAAC,CAAC;QACtE,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,qCAAqC,CAAC,CAAC;QACtE,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,oCAAoC,CAAC,CAAC;QACrE,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,sCAAsC,CAAC,CAAC;QAEvE,mDAAmD;QACnD,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CACtC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,KAAK,qCAAqC,CAChE,CAAC;QACF,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAE/D,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CACtC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,KAAK,oCAAoC,CAC/D,CAAC;QACF,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,gBAAgB,GAAG;YACvB,SAAS,EAAE;gBACT;oBACE,GAAG,EAAE,2BAA2B;oBAChC,IAAI,EAAE,UAAU;oBAChB,QAAQ,EAAE,YAAY;iBACvB;aACF;SACF,CAAC;QAEF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACzD,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;YAC5D,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,UAAU,CAAC,kBAAkB,CAAC,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,iBAAiB,GAAwB,EAAE,CAAC;QAChD,MAAM,OAAO,GAAa,GAAG,EAAE;YAC7B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,uBAAuB,EAAE,CAAC;YACtD,SAAS,CAAC,GAAG,EAAE;gBACb,IAAI,SAAS,EAAE,CAAC;oBACd,iBAAiB,GAAG,SAAS,CAAC;gBAChC,CAAC;YACH,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,CACJ,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,+BAA+B;QAC/B,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,gBAAgB,GAAG;YACvB,SAAS,EAAE;gBACT;oBACE,GAAG,EAAE,4BAA4B;oBACjC,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,YAAY;iBACvB;gBACD;oBACE,GAAG,EAAE,4BAA4B;oBACjC,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,YAAY;iBACvB;aACF;SACF,CAAC;QACF,MAAM,gBAAgB,GAAG;YACvB,SAAS,EAAE;gBACT;oBACE,GAAG,EAAE,2BAA2B;oBAChC,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,iBAAiB;iBAC5B;aACF;SACF,CAAC;QAEF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACzD,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;YAC5D,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACzD,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;YAC5D,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,UAAU,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;YAClD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,IAAI,iBAAiB,GAAwB,EAAE,CAAC;QAChD,MAAM,OAAO,GAAa,GAAG,EAAE;YAC7B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,uBAAuB,EAAE,CAAC;YACtD,SAAS,CAAC,GAAG,EAAE;gBACb,IAAI,SAAS,EAAE,CAAC;oBACd,iBAAiB,GAAG,SAAS,CAAC;gBAChC,CAAC;YACH,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;YAChB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CACzB,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;oBACD;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,iDAAiD;QACjD,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,qCAAqC,CAAC,CAAC;QACrE,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,oCAAoC,CAAC,CAAC;QAEpE,sBAAsB;QACtB,QAAQ,CACN,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,kEAAkE;QAClE,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC,CAAC,YAAY;QACzE,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC;QAC5D,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,qCAAqC,CAAC,CAAC,CAAC,+BAA+B;QACzG,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,oCAAoC,CAAC,CAAC,CAAC,mBAAmB;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC9D,IAAI,WAAwB,CAAC;IAE7B,UAAU,CAAC,GAAG,EAAE;QACd,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QACvB,WAAW,GAAG,IAAI,WAAW,CAAC;YAC5B,cAAc,EAAE;gBACd,OAAO,EAAE;oBACP,KAAK,EAAE,KAAK;iBACb;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,gBAAgB,GAAG;YACvB,SAAS,EAAE;gBACT;oBACE,GAAG,EAAE,2BAA2B;oBAChC,IAAI,EAAE,UAAU;oBAChB,QAAQ,EAAE,YAAY;iBACvB;aACF;SACF,CAAC;QAEF,MAAM,gBAAgB,GAAG;YACvB,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,2BAA2B;oBAChC,QAAQ,EAAE,YAAY;oBACtB,IAAI,EAAE,eAAe;iBACtB;aACF;SACF,CAAC;QAEF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACzD,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;YAC5D,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;YAC3D,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,UAAU,CAAC,kBAAkB,CAAC,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC;QAEnD,IAAI,oBAAoB,GAAQ,IAAI,CAAC;QACrC,MAAM,OAAO,GAAa,GAAG,EAAE;YAC7B,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,mBAAmB,CAChD,2BAA2B,CAC5B,CAAC;YACF,SAAS,CAAC,GAAG,EAAE;gBACb,IAAI,YAAY,EAAE,CAAC;oBACjB,oBAAoB,GAAG,YAAY,CAAC;gBACtC,CAAC;YACH,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,CACJ,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACpE,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC;YACpD,GAAG,EAAE,2BAA2B;SACjC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,gBAAgB,GAAG;YACvB,SAAS,EAAE;gBACT;oBACE,GAAG,EAAE,2BAA2B;oBAChC,IAAI,EAAE,UAAU;oBAChB,QAAQ,EAAE,YAAY;iBACvB;aACF;SACF,CAAC;QACF,MAAM,gBAAgB,GAAG;YACvB,SAAS,EAAE;gBACT;oBACE,GAAG,EAAE,2BAA2B;oBAChC,IAAI,EAAE,MAAM;oBACZ,QAAQ,EAAE,iBAAiB;iBAC5B;aACF;SACF,CAAC;QAEF,MAAM,iBAAiB,GAAG;YACxB,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,2BAA2B;oBAChC,QAAQ,EAAE,YAAY;oBACtB,IAAI,EAAE,eAAe;iBACtB;aACF;SACF,CAAC;QAEF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACzD,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;YAC5D,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,iBAAiB,CAAC;YAC5D,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,MAAM,WAAW,GAAG;YAClB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACzD,aAAa,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC;YAC5D,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QACF,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;SACjB,CAAC;QAEF,UAAU,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;YAClD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,IAAI,GAAG,KAAK,0BAA0B;gBAAE,OAAO,OAAO,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,IAAI,oBAAoB,GAAQ,IAAI,CAAC;QACrC,MAAM,OAAO,GAAa,GAAG,EAAE;YAC7B,sBAAsB;YACtB,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,mBAAmB,CAChD,oCAAoC,CACrC,CAAC;YACF,SAAS,CAAC,GAAG,EAAE;gBACb,IAAI,YAAY,EAAE,CAAC;oBACjB,oBAAoB,GAAG,YAAY,CAAC;gBACtC,CAAC;YACH,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,MAAM,CACJ,oBAAC,kBAAkB,CAAC,QAAQ,IAC1B,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAS;gBAClD,WAAW;gBACX,eAAe,EAAE,KAAK;aACvB;YAED,oBAAC,qBAAqB,IACpB,UAAU,EAAE;oBACV;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;oBACD;wBACE,GAAG,EAAE,0BAA0B;wBAC/B,SAAS,EAAE,YAAY,CAAC,GAAG;qBAC5B;iBACF;gBAED,oBAAC,qBAAqB;oBACpB,oBAAC,gBAAgB;wBACf,oBAAC,OAAO,OAAG,CACM,CACG,CACF,CACI,CAC/B,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACpE,2DAA2D;QAC3D,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC;YACpD,GAAG,EAAE,2BAA2B;SACjC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { render, waitFor } from \"@testing-library/react\";\nimport { QueryClient } from \"@tanstack/react-query\";\nimport React, { useEffect } from \"react\";\nimport { TamboClientContext } from \"../providers/tambo-client-provider\";\nimport { TamboMcpTokenProvider } from \"../providers/tambo-mcp-token-provider\";\nimport { TamboRegistryProvider } from \"../providers/tambo-registry-provider\";\nimport { MCPTransport } from \"./mcp-client\";\nimport { TamboMcpProvider, useTamboMcpServers } from \"./tambo-mcp-provider\";\nimport {\n useTamboMcpPromptList,\n useTamboMcpResourceList,\n useTamboMcpResource,\n type ListPromptEntry,\n type ListResourceEntry,\n} from \"./mcp-hooks\";\n\n// Mock the MCP client to avoid ES module issues\nlet createImpl: jest.Mock = jest.fn();\njest.mock(\"./mcp-client\", () => ({\n MCPClient: { create: (...args: any[]) => createImpl(...args) },\n MCPTransport: { SSE: \"sse\", HTTP: \"http\" },\n}));\n\ndescribe(\"useTamboMcpPromptList - individual server caching\", () => {\n let queryClient: QueryClient;\n\n beforeEach(() => {\n createImpl = jest.fn();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: false, // Disable retries for tests\n },\n },\n });\n });\n\n afterEach(() => {\n queryClient.clear();\n });\n\n it(\"should fetch and combine prompts from multiple servers\", async () => {\n // Mock two servers with different prompts\n const serverAPrompts = {\n prompts: [\n { name: \"prompt-a1\", description: \"Prompt A1\" },\n { name: \"prompt-a2\", description: \"Prompt A2\" },\n ],\n };\n const serverBPrompts = {\n prompts: [\n { name: \"prompt-b1\", description: \"Prompt B1\" },\n { name: \"prompt-b2\", description: \"Prompt B2\" },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverAPrompts),\n close: jest.fn(),\n };\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverBPrompts),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n // Mock MCPClient.create to return different clients for different URLs\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedPrompts: ListPromptEntry[] = [];\n const Capture: React.FC = () => {\n const { data: prompts } = useTamboMcpPromptList();\n useEffect(() => {\n if (prompts) {\n capturedPrompts = prompts;\n }\n }, [prompts]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for all prompts to be loaded\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(4);\n });\n\n // Verify all prompts are present (with prefixes since we have 2 servers)\n const promptNames = capturedPrompts.map((p) => p.prompt.name);\n expect(promptNames).toContain(\"server-a:prompt-a1\");\n expect(promptNames).toContain(\"server-a:prompt-a2\");\n expect(promptNames).toContain(\"server-b:prompt-b1\");\n expect(promptNames).toContain(\"server-b:prompt-b2\");\n\n // Verify each prompt has the correct server info\n const promptA1 = capturedPrompts.find(\n (p) => p.prompt.name === \"server-a:prompt-a1\",\n );\n expect(promptA1?.server.url).toBe(\"https://server-a.example\");\n\n const promptB1 = capturedPrompts.find(\n (p) => p.prompt.name === \"server-b:prompt-b1\",\n );\n expect(promptB1?.server.url).toBe(\"https://server-b.example\");\n });\n\n it(\"should remove prompts when a server is removed\", async () => {\n // Mock two servers with different prompts\n const serverAPrompts = {\n prompts: [\n { name: \"prompt-a1\", description: \"Prompt A1\" },\n { name: \"prompt-a2\", description: \"Prompt A2\" },\n ],\n };\n const serverBPrompts = {\n prompts: [\n { name: \"prompt-b1\", description: \"Prompt B1\" },\n { name: \"prompt-b2\", description: \"Prompt B2\" },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverAPrompts),\n close: jest.fn(),\n };\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverBPrompts),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedPrompts: ListPromptEntry[] = [];\n const Capture: React.FC = () => {\n const { data: prompts } = useTamboMcpPromptList();\n useEffect(() => {\n if (prompts) {\n capturedPrompts = prompts;\n }\n }, [prompts]);\n return null;\n };\n\n const { rerender } = render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for initial prompts to be loaded\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(4);\n });\n\n const initialPromptNames = capturedPrompts.map((p) => p.prompt.name);\n expect(initialPromptNames).toContain(\"server-a:prompt-a1\");\n expect(initialPromptNames).toContain(\"server-a:prompt-a2\");\n expect(initialPromptNames).toContain(\"server-b:prompt-b1\");\n expect(initialPromptNames).toContain(\"server-b:prompt-b2\");\n\n // Remove server B\n rerender(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for prompts to be updated (server B prompts should disappear)\n // When only 1 server remains, prompts should NOT be prefixed\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(2);\n });\n\n const updatedPromptNames = capturedPrompts.map((p) => p.prompt.name);\n expect(updatedPromptNames).toContain(\"prompt-a1\");\n expect(updatedPromptNames).toContain(\"prompt-a2\");\n expect(updatedPromptNames).not.toContain(\"prompt-b1\");\n expect(updatedPromptNames).not.toContain(\"prompt-b2\");\n expect(updatedPromptNames).not.toContain(\"server-a:prompt-a1\"); // No prefix when only 1 server\n\n // Verify server B's client was closed\n expect(clientB.close).toHaveBeenCalled();\n });\n\n it(\"should cache prompts individually per server using server key\", async () => {\n const serverAPrompts = {\n prompts: [{ name: \"prompt-a\", description: \"Prompt A\" }],\n };\n const serverBPrompts = {\n prompts: [{ name: \"prompt-b\", description: \"Prompt B\" }],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverAPrompts),\n close: jest.fn(),\n };\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverBPrompts),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedPrompts: ListPromptEntry[] = [];\n let capturedServerKeys: string[] = [];\n const Capture: React.FC = () => {\n const { data: prompts } = useTamboMcpPromptList();\n const servers = useTamboMcpServers();\n useEffect(() => {\n if (prompts) {\n capturedPrompts = prompts;\n }\n capturedServerKeys = servers.map((s) => s.key);\n }, [prompts, servers]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for prompts to be loaded\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(2);\n });\n\n // Verify that listPrompts was called once per server\n expect(mockClientA.listPrompts).toHaveBeenCalledTimes(1);\n expect(mockClientB.listPrompts).toHaveBeenCalledTimes(1);\n\n // Verify the query cache has separate entries for each server\n const cacheKeys = queryClient\n .getQueryCache()\n .getAll()\n .map((query) => query.queryKey);\n\n // Should have separate cache entries for each server's prompts\n const promptCacheKeys = cacheKeys.filter(\n (key) => Array.isArray(key) && key[0] === \"mcp-prompts\",\n );\n expect(promptCacheKeys.length).toBe(2);\n // Ensure provider keys are populated before asserting\n await waitFor(() => expect(capturedServerKeys.length).toBe(2));\n\n // Verify each connected server key is present exactly once in the cache keys\n const promptKeySet = new Set(promptCacheKeys.map((k) => String(k[1])));\n // The server keys are captured from the provider to avoid relying on string substrings\n capturedServerKeys.forEach((key) => {\n expect(promptKeySet.has(key)).toBe(true);\n });\n // And no duplicates\n expect(promptKeySet.size).toBe(capturedServerKeys.length);\n });\n\n it(\"should handle server errors gracefully without affecting other servers\", async () => {\n const serverAPrompts = {\n prompts: [{ name: \"prompt-a\", description: \"Prompt A\" }],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverAPrompts),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n // Server B will fail to connect\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") {\n throw new Error(\"Connection failed\");\n }\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedPrompts: ListPromptEntry[] = [];\n let mcpServersCount = 0;\n const Capture: React.FC = () => {\n const { data: prompts } = useTamboMcpPromptList();\n const servers = useTamboMcpServers();\n useEffect(() => {\n if (prompts) {\n capturedPrompts = prompts;\n }\n mcpServersCount = servers.length;\n }, [prompts, servers]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for server A prompts to be loaded\n // Server B should fail but not block server A\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(1);\n expect(mcpServersCount).toBe(2); // Both servers should be in the list\n });\n\n // Verify only server A's prompts are present (with prefix since 2 servers configured)\n const promptNames = capturedPrompts.map((p) => p.prompt.name);\n expect(promptNames).toContain(\"server-a:prompt-a\");\n expect(promptNames).not.toContain(\"server-b:prompt-b\");\n });\n\n it(\"should add prompts when a new server is added\", async () => {\n const serverAPrompts = {\n prompts: [{ name: \"prompt-a\", description: \"Prompt A\" }],\n };\n const serverBPrompts = {\n prompts: [{ name: \"prompt-b\", description: \"Prompt B\" }],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverAPrompts),\n close: jest.fn(),\n };\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverBPrompts),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedPrompts: ListPromptEntry[] = [];\n const Capture: React.FC = () => {\n const { data: prompts } = useTamboMcpPromptList();\n useEffect(() => {\n if (prompts) {\n capturedPrompts = prompts;\n }\n }, [prompts]);\n return null;\n };\n\n const { rerender } = render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for initial prompts from server A\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(1);\n });\n\n expect(capturedPrompts.map((p) => p.prompt.name)).toContain(\"prompt-a\");\n\n // Add server B\n rerender(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for server B prompts to be added\n // Now with 2 servers, prompts should be prefixed\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(2);\n });\n\n const promptNames = capturedPrompts.map((p) => p.prompt.name);\n expect(promptNames).toContain(\"server-a:prompt-a\");\n expect(promptNames).toContain(\"server-b:prompt-b\");\n });\n});\n\ndescribe(\"useTamboMcpResourceList - resource management\", () => {\n let queryClient: QueryClient;\n\n beforeEach(() => {\n createImpl = jest.fn();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: false,\n },\n },\n });\n });\n\n afterEach(() => {\n queryClient.clear();\n });\n\n it(\"should fetch and combine resources from multiple servers\", async () => {\n // Mock two servers with different resources\n const serverAResources = {\n resources: [\n {\n uri: \"file:///home/user/doc1.txt\",\n name: \"Document 1\",\n mimeType: \"text/plain\",\n },\n {\n uri: \"file:///home/user/doc2.txt\",\n name: \"Document 2\",\n mimeType: \"text/plain\",\n },\n ],\n };\n const serverBResources = {\n resources: [\n {\n uri: \"file:///workspace/code.js\",\n name: \"Code File\",\n mimeType: \"text/javascript\",\n },\n {\n uri: \"file:///workspace/README.md\",\n name: \"Readme\",\n mimeType: \"text/markdown\",\n },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverAResources),\n close: jest.fn(),\n };\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverBResources),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedResources: ListResourceEntry[] = [];\n const Capture: React.FC = () => {\n const { data: resources } = useTamboMcpResourceList();\n useEffect(() => {\n if (resources) {\n capturedResources = resources;\n }\n }, [resources]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for all resources to be loaded\n await waitFor(() => {\n expect(capturedResources.length).toBe(4);\n });\n\n // Verify all resources are present (with prefixes since we have 2 servers)\n const resourceUris = capturedResources.map((r) => r.resource.uri);\n expect(resourceUris).toContain(\"server-a:file:///home/user/doc1.txt\");\n expect(resourceUris).toContain(\"server-a:file:///home/user/doc2.txt\");\n expect(resourceUris).toContain(\"server-b:file:///workspace/code.js\");\n expect(resourceUris).toContain(\"server-b:file:///workspace/README.md\");\n\n // Verify each resource has the correct server info\n const resource1 = capturedResources.find(\n (r) => r.resource.uri === \"server-a:file:///home/user/doc1.txt\",\n );\n expect(resource1?.server.url).toBe(\"https://server-a.example\");\n\n const resource2 = capturedResources.find(\n (r) => r.resource.uri === \"server-b:file:///workspace/code.js\",\n );\n expect(resource2?.server.url).toBe(\"https://server-b.example\");\n });\n\n it(\"should not prefix resources when only one server exists\", async () => {\n const serverAResources = {\n resources: [\n {\n uri: \"file:///home/user/doc.txt\",\n name: \"Document\",\n mimeType: \"text/plain\",\n },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverAResources),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async () => clientA);\n\n let capturedResources: ListResourceEntry[] = [];\n const Capture: React.FC = () => {\n const { data: resources } = useTamboMcpResourceList();\n useEffect(() => {\n if (resources) {\n capturedResources = resources;\n }\n }, [resources]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n await waitFor(() => {\n expect(capturedResources.length).toBe(1);\n });\n\n // No prefix when only 1 server\n expect(capturedResources[0].resource.uri).toBe(\"file:///home/user/doc.txt\");\n });\n\n it(\"should remove resource prefixes when a server is removed\", async () => {\n const serverAResources = {\n resources: [\n {\n uri: \"file:///home/user/doc1.txt\",\n name: \"Document 1\",\n mimeType: \"text/plain\",\n },\n {\n uri: \"file:///home/user/doc2.txt\",\n name: \"Document 2\",\n mimeType: \"text/plain\",\n },\n ],\n };\n const serverBResources = {\n resources: [\n {\n uri: \"file:///workspace/code.js\",\n name: \"Code File\",\n mimeType: \"text/javascript\",\n },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverAResources),\n close: jest.fn(),\n };\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverBResources),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedResources: ListResourceEntry[] = [];\n const Capture: React.FC = () => {\n const { data: resources } = useTamboMcpResourceList();\n useEffect(() => {\n if (resources) {\n capturedResources = resources;\n }\n }, [resources]);\n return null;\n };\n\n const { rerender } = render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for all resources to be loaded (prefixed)\n await waitFor(() => {\n expect(capturedResources.length).toBe(3);\n });\n\n const initialUris = capturedResources.map((r) => r.resource.uri);\n expect(initialUris).toContain(\"server-a:file:///home/user/doc1.txt\");\n expect(initialUris).toContain(\"server-b:file:///workspace/code.js\");\n\n // Now remove server B\n rerender(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for server B resources to be removed and prefixes stripped\n await waitFor(() => {\n expect(capturedResources.length).toBe(2);\n });\n\n const updatedUris = capturedResources.map((r) => r.resource.uri);\n expect(updatedUris).toContain(\"file:///home/user/doc1.txt\"); // No prefix\n expect(updatedUris).toContain(\"file:///home/user/doc2.txt\");\n expect(updatedUris).not.toContain(\"server-a:file:///home/user/doc1.txt\"); // No prefix when only 1 server\n expect(updatedUris).not.toContain(\"server-b:file:///workspace/code.js\"); // Server B removed\n });\n});\n\ndescribe(\"useTamboMcpResource - read individual resource\", () => {\n let queryClient: QueryClient;\n\n beforeEach(() => {\n createImpl = jest.fn();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: false,\n },\n },\n });\n });\n\n afterEach(() => {\n queryClient.clear();\n });\n\n it(\"should read a resource from a single server (unprefixed)\", async () => {\n const serverAResources = {\n resources: [\n {\n uri: \"file:///home/user/doc.txt\",\n name: \"Document\",\n mimeType: \"text/plain\",\n },\n ],\n };\n\n const resourceContents = {\n contents: [\n {\n uri: \"file:///home/user/doc.txt\",\n mimeType: \"text/plain\",\n text: \"Hello, world!\",\n },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverAResources),\n readResource: jest.fn().mockResolvedValue(resourceContents),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async () => clientA);\n\n let capturedResourceData: any = null;\n const Capture: React.FC = () => {\n const { data: resourceData } = useTamboMcpResource(\n \"file:///home/user/doc.txt\",\n );\n useEffect(() => {\n if (resourceData) {\n capturedResourceData = resourceData;\n }\n }, [resourceData]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n await waitFor(() => {\n expect(capturedResourceData).not.toBeNull();\n });\n\n expect(capturedResourceData.contents[0].text).toBe(\"Hello, world!\");\n expect(mockClientA.readResource).toHaveBeenCalledWith({\n uri: \"file:///home/user/doc.txt\",\n });\n });\n\n it(\"should read a resource from multiple servers (prefixed)\", async () => {\n const serverAResources = {\n resources: [\n {\n uri: \"file:///home/user/doc.txt\",\n name: \"Document\",\n mimeType: \"text/plain\",\n },\n ],\n };\n const serverBResources = {\n resources: [\n {\n uri: \"file:///workspace/code.js\",\n name: \"Code\",\n mimeType: \"text/javascript\",\n },\n ],\n };\n\n const resourceContentsA = {\n contents: [\n {\n uri: \"file:///home/user/doc.txt\",\n mimeType: \"text/plain\",\n text: \"From server A\",\n },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverAResources),\n readResource: jest.fn().mockResolvedValue(resourceContentsA),\n close: jest.fn(),\n };\n\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverBResources),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedResourceData: any = null;\n const Capture: React.FC = () => {\n // Request with prefix\n const { data: resourceData } = useTamboMcpResource(\n \"server-a:file:///home/user/doc.txt\",\n );\n useEffect(() => {\n if (resourceData) {\n capturedResourceData = resourceData;\n }\n }, [resourceData]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n await waitFor(() => {\n expect(capturedResourceData).not.toBeNull();\n });\n\n expect(capturedResourceData.contents[0].text).toBe(\"From server A\");\n // Verify the prefix was stripped before calling the server\n expect(mockClientA.readResource).toHaveBeenCalledWith({\n uri: \"file:///home/user/doc.txt\",\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"mcp-hooks.test.js","sourceRoot":"","sources":["../../src/mcp/mcp-hooks.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { render, waitFor } from \"@testing-library/react\";\nimport { QueryClient } from \"@tanstack/react-query\";\nimport React, { useEffect } from \"react\";\nimport { TamboClientContext } from \"../providers/tambo-client-provider\";\nimport { TamboMcpTokenProvider } from \"../providers/tambo-mcp-token-provider\";\nimport { TamboRegistryProvider } from \"../providers/tambo-registry-provider\";\nimport { MCPTransport } from \"./mcp-client\";\nimport { TamboMcpProvider, useTamboMcpServers } from \"./tambo-mcp-provider\";\nimport {\n useTamboMcpPromptList,\n useTamboMcpResourceList,\n useTamboMcpResource,\n isMcpResourceEntry,\n type ListPromptEntry,\n type ListResourceEntry,\n} from \"./mcp-hooks\";\n\n// Mock the MCP client to avoid ES module issues\nlet createImpl: jest.Mock = jest.fn();\njest.mock(\"./mcp-client\", () => ({\n MCPClient: { create: (...args: any[]) => createImpl(...args) },\n MCPTransport: { SSE: \"sse\", HTTP: \"http\" },\n}));\n\ndescribe(\"useTamboMcpPromptList - individual server caching\", () => {\n let queryClient: QueryClient;\n\n beforeEach(() => {\n createImpl = jest.fn();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: false, // Disable retries for tests\n },\n },\n });\n });\n\n afterEach(() => {\n queryClient.clear();\n });\n\n it(\"should fetch and combine prompts from multiple servers\", async () => {\n // Mock two servers with different prompts\n const serverAPrompts = {\n prompts: [\n { name: \"prompt-a1\", description: \"Prompt A1\" },\n { name: \"prompt-a2\", description: \"Prompt A2\" },\n ],\n };\n const serverBPrompts = {\n prompts: [\n { name: \"prompt-b1\", description: \"Prompt B1\" },\n { name: \"prompt-b2\", description: \"Prompt B2\" },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverAPrompts),\n close: jest.fn(),\n };\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverBPrompts),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n // Mock MCPClient.create to return different clients for different URLs\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedPrompts: ListPromptEntry[] = [];\n const Capture: React.FC = () => {\n const { data: prompts } = useTamboMcpPromptList();\n useEffect(() => {\n if (prompts) {\n capturedPrompts = prompts;\n }\n }, [prompts]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for all prompts to be loaded\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(4);\n });\n\n // Verify all prompts are present (with prefixes since we have 2 servers)\n const promptNames = capturedPrompts.map((p) => p.prompt.name);\n expect(promptNames).toContain(\"server-a:prompt-a1\");\n expect(promptNames).toContain(\"server-a:prompt-a2\");\n expect(promptNames).toContain(\"server-b:prompt-b1\");\n expect(promptNames).toContain(\"server-b:prompt-b2\");\n\n // Verify each prompt has the correct server info\n const promptA1 = capturedPrompts.find(\n (p) => p.prompt.name === \"server-a:prompt-a1\",\n );\n expect(promptA1?.server.url).toBe(\"https://server-a.example\");\n\n const promptB1 = capturedPrompts.find(\n (p) => p.prompt.name === \"server-b:prompt-b1\",\n );\n expect(promptB1?.server.url).toBe(\"https://server-b.example\");\n });\n\n it(\"should remove prompts when a server is removed\", async () => {\n // Mock two servers with different prompts\n const serverAPrompts = {\n prompts: [\n { name: \"prompt-a1\", description: \"Prompt A1\" },\n { name: \"prompt-a2\", description: \"Prompt A2\" },\n ],\n };\n const serverBPrompts = {\n prompts: [\n { name: \"prompt-b1\", description: \"Prompt B1\" },\n { name: \"prompt-b2\", description: \"Prompt B2\" },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverAPrompts),\n close: jest.fn(),\n };\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverBPrompts),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedPrompts: ListPromptEntry[] = [];\n const Capture: React.FC = () => {\n const { data: prompts } = useTamboMcpPromptList();\n useEffect(() => {\n if (prompts) {\n capturedPrompts = prompts;\n }\n }, [prompts]);\n return null;\n };\n\n const { rerender } = render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for initial prompts to be loaded\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(4);\n });\n\n const initialPromptNames = capturedPrompts.map((p) => p.prompt.name);\n expect(initialPromptNames).toContain(\"server-a:prompt-a1\");\n expect(initialPromptNames).toContain(\"server-a:prompt-a2\");\n expect(initialPromptNames).toContain(\"server-b:prompt-b1\");\n expect(initialPromptNames).toContain(\"server-b:prompt-b2\");\n\n // Remove server B\n rerender(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for prompts to be updated (server B prompts should disappear)\n // Prompts are now always prefixed (breaking change)\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(2);\n });\n\n const updatedPromptNames = capturedPrompts.map((p) => p.prompt.name);\n expect(updatedPromptNames).toContain(\"server-a:prompt-a1\");\n expect(updatedPromptNames).toContain(\"server-a:prompt-a2\");\n expect(updatedPromptNames).not.toContain(\"prompt-b1\");\n expect(updatedPromptNames).not.toContain(\"prompt-b2\");\n expect(updatedPromptNames).not.toContain(\"prompt-a1\"); // Always prefixed now\n\n // Verify server B's client was closed\n expect(clientB.close).toHaveBeenCalled();\n });\n\n it(\"should cache prompts individually per server using server key\", async () => {\n const serverAPrompts = {\n prompts: [{ name: \"prompt-a\", description: \"Prompt A\" }],\n };\n const serverBPrompts = {\n prompts: [{ name: \"prompt-b\", description: \"Prompt B\" }],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverAPrompts),\n close: jest.fn(),\n };\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverBPrompts),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedPrompts: ListPromptEntry[] = [];\n let capturedServerKeys: string[] = [];\n const Capture: React.FC = () => {\n const { data: prompts } = useTamboMcpPromptList();\n const servers = useTamboMcpServers();\n useEffect(() => {\n if (prompts) {\n capturedPrompts = prompts;\n }\n capturedServerKeys = servers.map((s) => s.key);\n }, [prompts, servers]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for prompts to be loaded\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(2);\n });\n\n // Verify that listPrompts was called once per server\n expect(mockClientA.listPrompts).toHaveBeenCalledTimes(1);\n expect(mockClientB.listPrompts).toHaveBeenCalledTimes(1);\n\n // Verify the query cache has separate entries for each server\n const cacheKeys = queryClient\n .getQueryCache()\n .getAll()\n .map((query) => query.queryKey);\n\n // Should have separate cache entries for each server's prompts\n const promptCacheKeys = cacheKeys.filter(\n (key) => Array.isArray(key) && key[0] === \"mcp-prompts\",\n );\n expect(promptCacheKeys.length).toBe(2);\n // Ensure provider keys are populated before asserting\n await waitFor(() => expect(capturedServerKeys.length).toBe(2));\n\n // Verify each connected server key is present exactly once in the cache keys\n const promptKeySet = new Set(promptCacheKeys.map((k) => String(k[1])));\n // The server keys are captured from the provider to avoid relying on string substrings\n capturedServerKeys.forEach((key) => {\n expect(promptKeySet.has(key)).toBe(true);\n });\n // And no duplicates\n expect(promptKeySet.size).toBe(capturedServerKeys.length);\n });\n\n it(\"should handle server errors gracefully without affecting other servers\", async () => {\n const serverAPrompts = {\n prompts: [{ name: \"prompt-a\", description: \"Prompt A\" }],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverAPrompts),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n // Server B will fail to connect\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") {\n throw new Error(\"Connection failed\");\n }\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedPrompts: ListPromptEntry[] = [];\n let mcpServersCount = 0;\n const Capture: React.FC = () => {\n const { data: prompts } = useTamboMcpPromptList();\n const servers = useTamboMcpServers();\n useEffect(() => {\n if (prompts) {\n capturedPrompts = prompts;\n }\n mcpServersCount = servers.length;\n }, [prompts, servers]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for server A prompts to be loaded\n // Server B should fail but not block server A\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(1);\n expect(mcpServersCount).toBe(2); // Both servers should be in the list\n });\n\n // Verify only server A's prompts are present (with prefix since 2 servers configured)\n const promptNames = capturedPrompts.map((p) => p.prompt.name);\n expect(promptNames).toContain(\"server-a:prompt-a\");\n expect(promptNames).not.toContain(\"server-b:prompt-b\");\n });\n\n it(\"should add prompts when a new server is added\", async () => {\n const serverAPrompts = {\n prompts: [{ name: \"prompt-a\", description: \"Prompt A\" }],\n };\n const serverBPrompts = {\n prompts: [{ name: \"prompt-b\", description: \"Prompt B\" }],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverAPrompts),\n close: jest.fn(),\n };\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue(serverBPrompts),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedPrompts: ListPromptEntry[] = [];\n const Capture: React.FC = () => {\n const { data: prompts } = useTamboMcpPromptList();\n useEffect(() => {\n if (prompts) {\n capturedPrompts = prompts;\n }\n }, [prompts]);\n return null;\n };\n\n const { rerender } = render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for initial prompts from server A (always prefixed)\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(1);\n });\n\n expect(capturedPrompts.map((p) => p.prompt.name)).toContain(\n \"server-a:prompt-a\",\n );\n\n // Add server B\n rerender(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for server B prompts to be added\n // Now with 2 servers, prompts should be prefixed\n await waitFor(() => {\n expect(capturedPrompts.length).toBe(2);\n });\n\n const promptNames = capturedPrompts.map((p) => p.prompt.name);\n expect(promptNames).toContain(\"server-a:prompt-a\");\n expect(promptNames).toContain(\"server-b:prompt-b\");\n });\n});\n\ndescribe(\"useTamboMcpResourceList - resource management\", () => {\n let queryClient: QueryClient;\n\n beforeEach(() => {\n createImpl = jest.fn();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: false,\n },\n },\n });\n });\n\n afterEach(() => {\n queryClient.clear();\n });\n\n it(\"should identify MCP-backed entries with isMcpResourceEntry\", () => {\n const registryEntry: ListResourceEntry = {\n server: null,\n // Resource shape is not important for this helper, so cast to keep the\n // test focused on the discriminant field.\n resource: {\n uri: \"file:///registry/doc.txt\",\n name: \"Registry Doc\",\n mimeType: \"text/plain\",\n } as any,\n };\n\n const mcpEntry: ListResourceEntry = {\n server: { key: \"server-a\", client: {} } as any,\n resource: {\n uri: \"server-a:file:///home/user/doc.txt\",\n name: \"Document\",\n mimeType: \"text/plain\",\n } as any,\n };\n\n expect(isMcpResourceEntry(mcpEntry)).toBe(true);\n expect(isMcpResourceEntry(registryEntry)).toBe(false);\n });\n\n it(\"should fetch and combine resources from multiple servers\", async () => {\n // Mock two servers with different resources\n const serverAResources = {\n resources: [\n {\n uri: \"file:///home/user/doc1.txt\",\n name: \"Document 1\",\n mimeType: \"text/plain\",\n },\n {\n uri: \"file:///home/user/doc2.txt\",\n name: \"Document 2\",\n mimeType: \"text/plain\",\n },\n ],\n };\n const serverBResources = {\n resources: [\n {\n uri: \"file:///workspace/code.js\",\n name: \"Code File\",\n mimeType: \"text/javascript\",\n },\n {\n uri: \"file:///workspace/README.md\",\n name: \"Readme\",\n mimeType: \"text/markdown\",\n },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverAResources),\n close: jest.fn(),\n };\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverBResources),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedResources: ListResourceEntry[] = [];\n const Capture: React.FC = () => {\n const { data: resources } = useTamboMcpResourceList();\n useEffect(() => {\n if (resources) {\n capturedResources = resources;\n }\n }, [resources]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for all resources to be loaded\n await waitFor(() => {\n expect(capturedResources.length).toBe(4);\n });\n\n // Verify all resources are present (with prefixes since we have 2 servers)\n const resourceUris = capturedResources.map((r) => r.resource.uri);\n expect(resourceUris).toContain(\"server-a:file:///home/user/doc1.txt\");\n expect(resourceUris).toContain(\"server-a:file:///home/user/doc2.txt\");\n expect(resourceUris).toContain(\"server-b:file:///workspace/code.js\");\n expect(resourceUris).toContain(\"server-b:file:///workspace/README.md\");\n\n // Verify each resource has the correct server info\n const resource1 = capturedResources.find(\n (r) => r.resource.uri === \"server-a:file:///home/user/doc1.txt\",\n );\n expect(resource1).toBeDefined();\n expect(resource1!.server).not.toBeNull();\n expect(resource1!.server!.url).toBe(\"https://server-a.example\");\n\n const resource2 = capturedResources.find(\n (r) => r.resource.uri === \"server-b:file:///workspace/code.js\",\n );\n expect(resource2).toBeDefined();\n expect(resource2!.server).not.toBeNull();\n expect(resource2!.server!.url).toBe(\"https://server-b.example\");\n });\n\n it(\"should always prefix MCP resources even with single server\", async () => {\n const serverAResources = {\n resources: [\n {\n uri: \"file:///home/user/doc.txt\",\n name: \"Document\",\n mimeType: \"text/plain\",\n },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverAResources),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async () => clientA);\n\n let capturedResources: ListResourceEntry[] = [];\n const Capture: React.FC = () => {\n const { data: resources } = useTamboMcpResourceList();\n useEffect(() => {\n if (resources) {\n capturedResources = resources;\n }\n }, [resources]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n await waitFor(() => {\n expect(capturedResources.length).toBe(1);\n });\n\n // Always prefix MCP resources, even with 1 server (breaking change)\n expect(capturedResources[0].resource.uri).toBe(\n \"server-a:file:///home/user/doc.txt\",\n );\n });\n\n it(\"should maintain prefixes even when servers are removed\", async () => {\n const serverAResources = {\n resources: [\n {\n uri: \"file:///home/user/doc1.txt\",\n name: \"Document 1\",\n mimeType: \"text/plain\",\n },\n {\n uri: \"file:///home/user/doc2.txt\",\n name: \"Document 2\",\n mimeType: \"text/plain\",\n },\n ],\n };\n const serverBResources = {\n resources: [\n {\n uri: \"file:///workspace/code.js\",\n name: \"Code File\",\n mimeType: \"text/javascript\",\n },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverAResources),\n close: jest.fn(),\n };\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverBResources),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedResources: ListResourceEntry[] = [];\n const Capture: React.FC = () => {\n const { data: resources } = useTamboMcpResourceList();\n useEffect(() => {\n if (resources) {\n capturedResources = resources;\n }\n }, [resources]);\n return null;\n };\n\n const { rerender } = render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for all resources to be loaded (prefixed)\n await waitFor(() => {\n expect(capturedResources.length).toBe(3);\n });\n\n const initialUris = capturedResources.map((r) => r.resource.uri);\n expect(initialUris).toContain(\"server-a:file:///home/user/doc1.txt\");\n expect(initialUris).toContain(\"server-b:file:///workspace/code.js\");\n\n // Now remove server B\n rerender(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n // Wait for server B resources to be removed (prefixes maintained)\n await waitFor(() => {\n expect(capturedResources.length).toBe(2);\n });\n\n const updatedUris = capturedResources.map((r) => r.resource.uri);\n // Prefixes are maintained even with only 1 server (breaking change)\n expect(updatedUris).toContain(\"server-a:file:///home/user/doc1.txt\");\n expect(updatedUris).toContain(\"server-a:file:///home/user/doc2.txt\");\n expect(updatedUris).not.toContain(\"file:///home/user/doc1.txt\"); // Always prefixed now\n expect(updatedUris).not.toContain(\"server-b:file:///workspace/code.js\"); // Server B removed\n });\n});\n\ndescribe(\"useTamboMcpResource - read individual resource\", () => {\n let queryClient: QueryClient;\n\n beforeEach(() => {\n createImpl = jest.fn();\n queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: false,\n },\n },\n });\n });\n\n afterEach(() => {\n queryClient.clear();\n });\n\n it(\"should read a resource from a single server (prefixed)\", async () => {\n const serverAResources = {\n resources: [\n {\n uri: \"file:///home/user/doc.txt\",\n name: \"Document\",\n mimeType: \"text/plain\",\n },\n ],\n };\n\n const resourceContents = {\n contents: [\n {\n uri: \"file:///home/user/doc.txt\",\n mimeType: \"text/plain\",\n text: \"Hello, world!\",\n },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverAResources),\n readResource: jest.fn().mockResolvedValue(resourceContents),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async () => clientA);\n\n let capturedResourceData: any = null;\n const Capture: React.FC = () => {\n // MCP resources are always prefixed, even with single server\n const { data: resourceData } = useTamboMcpResource(\n \"server-a:file:///home/user/doc.txt\",\n );\n useEffect(() => {\n if (resourceData) {\n capturedResourceData = resourceData;\n }\n }, [resourceData]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n await waitFor(() => {\n expect(capturedResourceData).not.toBeNull();\n });\n\n expect(capturedResourceData.contents[0].text).toBe(\"Hello, world!\");\n expect(mockClientA.readResource).toHaveBeenCalledWith({\n uri: \"file:///home/user/doc.txt\",\n });\n });\n\n it(\"should read a resource from multiple servers (prefixed)\", async () => {\n const serverAResources = {\n resources: [\n {\n uri: \"file:///home/user/doc.txt\",\n name: \"Document\",\n mimeType: \"text/plain\",\n },\n ],\n };\n const serverBResources = {\n resources: [\n {\n uri: \"file:///workspace/code.js\",\n name: \"Code\",\n mimeType: \"text/javascript\",\n },\n ],\n };\n\n const resourceContentsA = {\n contents: [\n {\n uri: \"file:///home/user/doc.txt\",\n mimeType: \"text/plain\",\n text: \"From server A\",\n },\n ],\n };\n\n const mockClientA = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverAResources),\n readResource: jest.fn().mockResolvedValue(resourceContentsA),\n close: jest.fn(),\n };\n\n const mockClientB = {\n listTools: jest.fn().mockResolvedValue([]),\n listPrompts: jest.fn().mockResolvedValue({ prompts: [] }),\n listResources: jest.fn().mockResolvedValue(serverBResources),\n close: jest.fn(),\n };\n\n const clientA = {\n client: mockClientA,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n const clientB = {\n client: mockClientB,\n listTools: jest.fn().mockResolvedValue([]),\n close: jest.fn(),\n };\n\n createImpl.mockImplementation(async (url: string) => {\n if (url === \"https://server-a.example\") return clientA;\n if (url === \"https://server-b.example\") return clientB;\n throw new Error(`Unexpected URL: ${url}`);\n });\n\n let capturedResourceData: any = null;\n const Capture: React.FC = () => {\n // Request with prefix\n const { data: resourceData } = useTamboMcpResource(\n \"server-a:file:///home/user/doc.txt\",\n );\n useEffect(() => {\n if (resourceData) {\n capturedResourceData = resourceData;\n }\n }, [resourceData]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n mcpServers={[\n {\n url: \"https://server-a.example\",\n transport: MCPTransport.SSE,\n },\n {\n url: \"https://server-b.example\",\n transport: MCPTransport.SSE,\n },\n ]}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n await waitFor(() => {\n expect(capturedResourceData).not.toBeNull();\n });\n\n expect(capturedResourceData.contents[0].text).toBe(\"From server A\");\n // Verify the prefix was stripped before calling the server\n expect(mockClientA.readResource).toHaveBeenCalledWith({\n uri: \"file:///home/user/doc.txt\",\n });\n });\n\n it(\"should read registry resources via resourceSource even when not listed\", async () => {\n const registryUri = \"file:///local/registry-doc.txt\";\n\n const listResources = jest.fn().mockResolvedValue([]);\n const getResource = jest.fn().mockResolvedValue({\n contents: [\n {\n uri: registryUri,\n mimeType: \"text/plain\",\n text: \"Registry content\",\n },\n ],\n });\n\n let capturedResourceData: any = null;\n const Capture: React.FC = () => {\n const { data: resourceData } = useTamboMcpResource(registryUri);\n useEffect(() => {\n if (resourceData) {\n capturedResourceData = resourceData;\n }\n }, [resourceData]);\n return null;\n };\n\n render(\n <TamboClientContext.Provider\n value={{\n client: { baseURL: \"https://api.tambo.co\" } as any,\n queryClient,\n isUpdatingToken: false,\n }}\n >\n <TamboRegistryProvider\n listResources={listResources}\n getResource={getResource}\n >\n <TamboMcpTokenProvider>\n <TamboMcpProvider>\n <Capture />\n </TamboMcpProvider>\n </TamboMcpTokenProvider>\n </TamboRegistryProvider>\n </TamboClientContext.Provider>,\n );\n\n await waitFor(() => {\n expect(capturedResourceData).not.toBeNull();\n });\n\n expect(getResource).toHaveBeenCalledWith(registryUri);\n expect(capturedResourceData.contents[0].text).toBe(\"Registry content\");\n });\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-mcp-provider.d.ts","sourceRoot":"","sources":["../../src/mcp/tambo-mcp-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEZ,EAAE,EAMH,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"tambo-mcp-provider.d.ts","sourceRoot":"","sources":["../../src/mcp/tambo-mcp-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAEZ,EAAE,EAMH,MAAM,OAAO,CAAC;AACf,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EAAE,KAAK,uBAAuB,EAAkB,MAAM,eAAe,CAAC;AAC7E,OAAO,EACL,SAAS,EACT,qBAAqB,EACrB,WAAW,EACX,kBAAkB,EAEnB,MAAM,cAAc,CAAC;AAEtB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAoB5D;AAED;;;;;;;;;;GAUG;AACH,UAAU,eAAgB,SAAQ,uBAAuB;IACvD;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAChC;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,MAAM,EAAE,SAAS,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,eAAe,EAAE,KAAK,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,kBAAkB,GAAG,eAAe,CAAC;AAE7D;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,EAC7C,KAAK,EAAE,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,EAC3C,UAAU,EAAE,eAAe,KACxB,UAAU,CAAC,qBAAqB,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,CACT,OAAO,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAC1C,KAAK,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EACxC,UAAU,EAAE,eAAe,KACxB,UAAU,CAAC,kBAAkB,CAAC,CAAC;CACrC;AAqCD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAyUA,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,kBAAkB,mBAE9B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,sBAAsB,QAAO,uBAMzC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAZG,uBAYsB,CAAC"}
|
|
@@ -211,7 +211,8 @@ export const TamboMcpProvider = ({ handlers, contextKey, children }) => {
|
|
|
211
211
|
}
|
|
212
212
|
return result.content;
|
|
213
213
|
},
|
|
214
|
-
|
|
214
|
+
inputSchema: tool.inputSchema ?? {},
|
|
215
|
+
outputSchema: {},
|
|
215
216
|
transformToContent: (content) => {
|
|
216
217
|
if (isContentPartArray(content)) {
|
|
217
218
|
return content;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-mcp-provider.js","sourceRoot":"","sources":["../../src/mcp/tambo-mcp-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {\n createContext,\n FC,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { TamboTool } from \"../model/component-metadata\";\nimport {\n getMcpServerUniqueKey,\n type NormalizedMcpServerInfo,\n} from \"../model/mcp-server-info\";\nimport { useTamboMcpToken } from \"../providers/tambo-mcp-token-provider\";\nimport {\n useTamboMcpServerInfos,\n useTamboRegistry,\n} from \"../providers/tambo-registry-provider\";\nimport { isContentPartArray, toText } from \"../util/content-parts\";\nimport { type ElicitationContextState, useElicitation } from \"./elicitation\";\nimport {\n MCPClient,\n MCPElicitationHandler,\n MCPHandlers,\n MCPSamplingHandler,\n MCPTransport,\n} from \"./mcp-client\";\n\n/**\n * Extracts error message from MCP tool result content.\n * Handles both array and string content formats.\n * Always returns a string, even for invalid/null inputs.\n * @returns The extracted error message as a string\n */\nexport function extractErrorMessage(content: unknown): string {\n if (content === undefined || content === null) {\n return \"Unknown error occurred\";\n }\n\n if (Array.isArray(content)) {\n const textItems = content\n .filter((item) => item?.type === \"text\" && typeof item.text === \"string\")\n .map((item) => item.text);\n\n return textItems.length > 0\n ? textItems.join(\" \")\n : \"Error occurred but no details provided\";\n }\n\n if (typeof content === \"object\") {\n return JSON.stringify(content);\n }\n\n return `${content}`;\n}\n\n/**\n * Normalized MCP server information as consumed by the provider.\n *\n * Extends `NormalizedMcpServerInfo` from the core model by:\n * - narrowing `handlers` to `Partial<MCPHandlers>`\n * - adding a stable `key` derived from URL/transport/headers\n *\n * The registry is responsible for producing `NormalizedMcpServerInfo`\n * instances; this type adds the MCP-specific wiring needed to connect and\n * track clients.\n */\ninterface McpServerConfig extends NormalizedMcpServerInfo {\n /**\n * Optional handlers for elicitation and sampling requests from the server.\n * Interpreted as a partial set of MCP handlers.\n */\n handlers?: Partial<MCPHandlers>;\n /**\n * Stable identity for this server derived from its URL/transport/headers.\n * Present for all server states (connected or failed).\n */\n key: string;\n}\n\n/**\n * Connected MCP server with an active client.\n */\nexport interface ConnectedMcpServer extends McpServerConfig {\n client: MCPClient;\n}\n\n/**\n * Failed MCP server with a connection error.\n */\nexport interface FailedMcpServer extends McpServerConfig {\n client?: never;\n connectionError: Error;\n}\n\n/**\n * An active or failed MCP server, with access to the MCP client.\n */\nexport type McpServer = ConnectedMcpServer | FailedMcpServer;\n\n/**\n * Provider-level MCP handlers that receive the McpServerInfo as context in addition to the request.\n * These handlers are applied to all MCP servers unless overridden by per-server handlers.\n *\n * Handlers receive three parameters:\n * 1. request - The MCP request\n * 2. extra - RequestHandlerExtra containing AbortSignal and other metadata\n * 3. serverInfo - Configuration of the MCP server that triggered this request\n */\nexport interface ProviderMCPHandlers {\n elicitation?: (\n request: Parameters<MCPElicitationHandler>[0],\n extra: Parameters<MCPElicitationHandler>[1],\n serverInfo: McpServerConfig,\n ) => ReturnType<MCPElicitationHandler>;\n sampling?: (\n request: Parameters<MCPSamplingHandler>[0],\n extra: Parameters<MCPSamplingHandler>[1],\n serverInfo: McpServerConfig,\n ) => ReturnType<MCPSamplingHandler>;\n}\n\n/**\n * Context value for MCP provider including server list and elicitation state\n */\ninterface McpProviderContextValue extends ElicitationContextState {\n servers: McpServer[];\n}\n\nconst McpProviderContext = createContext<McpProviderContextValue>({\n servers: [],\n elicitation: null,\n resolveElicitation: null,\n});\n\n// Constant for the internal Tambo MCP server name\nconst TAMBO_INTERNAL_MCP_SERVER_NAME = \"__tambo_internal_mcp_server__\";\n\n/**\n * Creates a stable hash of a string for use as a cache key.\n * Uses Java-style string hashing (DJB2-like) for deterministic results.\n *\n * Note: We use a synchronous hash instead of crypto.subtle.digest because:\n * - crypto.subtle.digest is async, which adds complexity in React hooks (useMemo, useEffect)\n * - This is not for security, just for creating a stable identifier to detect token changes\n * - Synchronous hashing avoids race conditions and simplifies component lifecycle\n * @param input - The string to hash\n * @returns A compact base36 hash string\n */\nfunction hashString(input: string): string {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n hash = (Math.imul(31, hash) + input.charCodeAt(i)) | 0;\n }\n return (hash >>> 0).toString(36);\n}\n\n/**\n * This provider is used to register tools from MCP servers.\n * It automatically includes an internal Tambo MCP server when an MCP access token is available.\n *\n * **BREAKING CHANGE**: This provider no longer accepts `mcpServers` as a prop.\n * Instead, pass `mcpServers` to `TamboProvider` or `TamboRegistryProvider`.\n * This provider must be wrapped inside `TamboProvider` to access the MCP server registry.\n * @param props - The provider props\n * @param props.handlers - Optional handlers applied to all MCP servers unless overridden per-server\n * @param props.contextKey - Optional context key for fetching threadless MCP tokens when not in a thread\n * @param props.children - The children to wrap\n * @returns The TamboMcpProvider component\n */\nexport const TamboMcpProvider: FC<{\n handlers?: ProviderMCPHandlers;\n contextKey?: string;\n children: React.ReactNode;\n}> = ({ handlers, contextKey, children }) => {\n const { registerTool } = useTamboRegistry();\n const { mcpAccessToken, tamboBaseUrl } = useTamboMcpToken(contextKey);\n const mcpServers = useTamboMcpServerInfos();\n const providerSamplingHandler = handlers?.sampling;\n\n // Elicitation state and default handler\n const { elicitation, resolveElicitation, defaultElicitationHandler } =\n useElicitation();\n\n // Use provided handler or fall back to default\n const providerElicitationHandler =\n handlers?.elicitation ?? defaultElicitationHandler;\n\n // Stable reference to track active clients by server key\n const clientMapRef = useRef<Map<string, McpServer>>(new Map());\n // Track tool ownership to prevent duplicate registrations across servers\n // toolOwnerRef: tool name -> server key; keyToToolsRef: server key -> set of tool names\n const toolOwnerRef = useRef<Map<string, string>>(new Map());\n const keyToToolsRef = useRef<Map<string, Set<string>>>(new Map());\n\n // State for exposing connected servers to consumers\n const [connectedMcpServers, setConnectedMcpServers] = useState<McpServer[]>(\n [],\n );\n\n // Stable map of current server configurations keyed by server key\n const currentServersMap = useMemo(() => {\n const servers = [...mcpServers];\n\n // Add internal Tambo MCP server if we have an access token and a base URL\n if (mcpAccessToken && tamboBaseUrl) {\n const base = new URL(tamboBaseUrl);\n base.pathname = `${base.pathname.replace(/\\/+$/, \"\")}/mcp`;\n const tamboMcpUrl = base.toString();\n // Include token hash in serverKey so changing tokens trigger reconnection\n const tokenHash = hashString(mcpAccessToken);\n servers.push({\n name: TAMBO_INTERNAL_MCP_SERVER_NAME,\n url: tamboMcpUrl,\n transport: MCPTransport.HTTP,\n serverKey: `tambo-${tokenHash}`, // Include token hash in key to force reconnection on token change\n customHeaders: {\n Authorization: `Bearer ${mcpAccessToken}`,\n },\n });\n }\n\n // Create a map of server key -> server info for efficient lookups\n const serverMap = new Map<string, McpServerConfig>();\n servers.forEach((server) => {\n const serverInfo = normalizeServerInfo(server);\n // Store without cloning to avoid unnecessary allocation\n serverMap.set(serverInfo.key, serverInfo);\n });\n\n return serverMap;\n }, [mcpServers, mcpAccessToken, tamboBaseUrl]);\n\n // Main effect: manage client lifecycle (create/remove)\n useEffect(() => {\n const clientMap = clientMapRef.current;\n const currentKeys = new Set(currentServersMap.keys());\n const existingKeys = new Set(clientMap.keys());\n\n // 1. Remove clients that are no longer in the current server list\n const keysToRemove = Array.from(existingKeys).filter(\n (key) => !currentKeys.has(key),\n );\n keysToRemove.forEach((key) => {\n const server = clientMap.get(key);\n if (server?.client?.close) {\n try {\n // Call close() sync - it may or may not return a promise\n const closeResult = server.client.close();\n // If it returns a promise, handle errors but don't wait\n if (closeResult && typeof closeResult.catch === \"function\") {\n void closeResult.catch((error) => {\n const url = (server as McpServer).url ?? \"(unknown url)\";\n console.error(`Error closing MCP client for ${url}:`, error);\n });\n }\n } catch (error) {\n const url = (server as McpServer).url ?? \"(unknown url)\";\n console.error(`Error closing MCP client for ${url}:`, error);\n }\n }\n // Release tool ownership for this server\n const owned = keyToToolsRef.current.get(key);\n if (owned) {\n for (const name of owned) toolOwnerRef.current.delete(name);\n keyToToolsRef.current.delete(key);\n }\n clientMap.delete(key);\n });\n\n // 2. Add new clients for servers that don't exist yet\n const keysToAdd = Array.from(currentKeys).filter(\n (key) => !existingKeys.has(key),\n );\n\n async function addClients(keys: string[]) {\n await Promise.allSettled(\n keys.map(async (key) => {\n const serverInfo = currentServersMap.get(key)!;\n\n try {\n // Build effective handlers (per-server overrides provider)\n const effectiveHandlers: Partial<MCPHandlers> = {};\n\n if (serverInfo.handlers?.elicitation) {\n effectiveHandlers.elicitation = serverInfo.handlers.elicitation;\n } else if (providerElicitationHandler) {\n effectiveHandlers.elicitation = async (\n request: Parameters<MCPElicitationHandler>[0],\n extra: Parameters<MCPElicitationHandler>[1],\n ) => await providerElicitationHandler(request, extra, serverInfo);\n }\n\n if (serverInfo.handlers?.sampling) {\n effectiveHandlers.sampling = serverInfo.handlers.sampling;\n } else if (providerSamplingHandler) {\n effectiveHandlers.sampling = async (\n request: Parameters<MCPSamplingHandler>[0],\n extra: Parameters<MCPSamplingHandler>[1],\n ) => await providerSamplingHandler(request, extra, serverInfo);\n }\n\n const client = await MCPClient.create(\n serverInfo.url,\n serverInfo.transport,\n serverInfo.customHeaders,\n undefined,\n undefined,\n effectiveHandlers,\n );\n\n const connectedServer: ConnectedMcpServer = {\n ...serverInfo,\n client,\n };\n\n clientMap.set(key, connectedServer);\n setConnectedMcpServers(Array.from(clientMap.values()));\n\n // Register tools from this server (deduplicated by ownership)\n try {\n const tools = await client.listTools();\n const shouldPrefix = currentServersMap.size > 1;\n\n tools.forEach((tool) => {\n // Prefix tool name with serverKey if multiple servers are present\n const toolName = shouldPrefix\n ? `${serverInfo.serverKey}__${tool.name}`\n : tool.name;\n\n // Skip if another server already owns this tool (using final name for ownership)\n const currentOwner = toolOwnerRef.current.get(toolName);\n if (currentOwner && currentOwner !== key) {\n return;\n }\n\n // Record ownership for this server key (using final name)\n if (!currentOwner) {\n toolOwnerRef.current.set(toolName, key);\n if (!keyToToolsRef.current.has(key)) {\n keyToToolsRef.current.set(key, new Set());\n }\n keyToToolsRef.current.get(key)!.add(toolName);\n }\n\n registerTool({\n description: tool.description ?? \"\",\n name: toolName,\n tool: async (args: Record<string, unknown> = {}) => {\n const server = clientMap.get(key);\n if (!server?.client) {\n throw new Error(\n `MCP server for tool ${tool.name} is not connected`,\n );\n }\n const result = await server.client.callTool(\n tool.name,\n args,\n );\n if (result.isError) {\n const errorMessage = extractErrorMessage(result.content);\n throw new Error(errorMessage);\n }\n return result.content;\n },\n toolSchema: tool.inputSchema as TamboTool[\"toolSchema\"],\n transformToContent: (content: unknown) => {\n if (isContentPartArray(content)) {\n return content;\n }\n return [{ type: \"text\", text: toText(content) }];\n },\n });\n });\n } catch (error) {\n console.error(\n `Failed to register tools from MCP server ${serverInfo.url}:`,\n error,\n );\n }\n } catch (error) {\n const failedServer: FailedMcpServer = {\n ...serverInfo,\n connectionError: error as Error,\n };\n clientMap.set(key, failedServer);\n setConnectedMcpServers(Array.from(clientMap.values()));\n console.error(\n `Failed to connect to MCP server ${serverInfo.url}:`,\n error,\n );\n }\n }),\n );\n }\n\n if (keysToAdd.length > 0) {\n addClients(keysToAdd).catch((err) => {\n console.error(\"Unexpected error in addClients:\", err);\n });\n }\n\n // Update state after removals (additions update state asynchronously above)\n if (keysToRemove.length > 0) {\n setConnectedMcpServers(Array.from(clientMap.values()));\n }\n }, [\n currentServersMap,\n providerElicitationHandler,\n providerSamplingHandler,\n registerTool,\n ]);\n\n // Update handlers when they change (without recreating clients)\n useEffect(() => {\n const clientMap = clientMapRef.current;\n\n clientMap.forEach((server, key) => {\n if (!server.client) {\n return; // Skip failed servers\n }\n\n const serverInfo = currentServersMap.get(key);\n if (!serverInfo) {\n return; // Server was removed, handled by main effect\n }\n\n // Determine effective handlers\n const effectiveElicitationHandler =\n serverInfo.handlers?.elicitation ??\n (providerElicitationHandler\n ? async (\n request: Parameters<MCPElicitationHandler>[0],\n extra: Parameters<MCPElicitationHandler>[1],\n ) => await providerElicitationHandler(request, extra, serverInfo)\n : undefined);\n\n const effectiveSamplingHandler =\n serverInfo.handlers?.sampling ??\n (providerSamplingHandler\n ? async (\n request: Parameters<MCPSamplingHandler>[0],\n extra: Parameters<MCPSamplingHandler>[1],\n ) => await providerSamplingHandler(request, extra, serverInfo)\n : undefined);\n\n // Update handlers unconditionally (allows removal by passing undefined)\n server.client.updateElicitationHandler?.(effectiveElicitationHandler);\n server.client.updateSamplingHandler?.(effectiveSamplingHandler);\n });\n }, [currentServersMap, providerElicitationHandler, providerSamplingHandler]);\n\n // Cleanup on unmount: close all clients\n useEffect(() => {\n const clientMap = clientMapRef.current;\n const ownerMapAtMount = toolOwnerRef.current;\n const keyToToolsAtMount = keyToToolsRef.current;\n return () => {\n clientMap.forEach((server) => {\n if (server?.client?.close) {\n try {\n // Call close() sync - it may or may not return a promise\n const closeResult = server.client.close();\n // If it returns a promise, handle errors but don't wait\n if (closeResult && typeof closeResult.catch === \"function\") {\n void closeResult.catch((error) => {\n const url = (server as McpServer).url ?? \"(unknown url)\";\n console.error(\n `Error closing MCP client on unmount for ${url}:`,\n error,\n );\n });\n }\n } catch (error) {\n const url = (server as McpServer).url ?? \"(unknown url)\";\n console.error(\n `Error closing MCP client on unmount for ${url}:`,\n error,\n );\n }\n }\n });\n clientMap.clear();\n ownerMapAtMount.clear();\n keyToToolsAtMount.clear();\n };\n }, []);\n\n const contextValue = useMemo(\n () => ({\n servers: connectedMcpServers,\n elicitation,\n resolveElicitation,\n }),\n [connectedMcpServers, elicitation, resolveElicitation],\n );\n\n return (\n <McpProviderContext.Provider value={contextValue}>\n {children}\n </McpProviderContext.Provider>\n );\n};\n\n/**\n * Hook to access the actual MCP servers, as they are connected (or fail to\n * connect).\n *\n * You can call methods on the MCP client that is included in the MCP server\n * object.\n *\n * If the server fails to connect, the `client` property will be `undefined` and\n * the `connectionError` property will be set.\n *\n * For example, to forcibly disconnect and reconnect all MCP servers:\n *\n * ```tsx\n * const mcpServers = useTamboMcpServers();\n * mcpServers.forEach((mcpServer) => {\n * mcpServer.client?.reconnect();\n * });\n * ```\n *\n * Note that the MCP servers are not guaranteed to be in the same order as the\n * input array, because they are added as they are connected.\n * @returns The MCP servers\n */\nexport const useTamboMcpServers = () => {\n return useContext(McpProviderContext).servers;\n};\n\n/**\n * Hook to access MCP elicitation state from TamboMcpProvider.\n * This provides access to the current elicitation request and methods to respond to it.\n *\n * The elicitation state is automatically managed by TamboMcpProvider when MCP servers\n * request user input through the elicitation protocol.\n * @returns The elicitation state with current request and response handler\n * @example\n * ```tsx\n * function ElicitationUI() {\n * const { elicitation, resolveElicitation } = useTamboMcpElicitation();\n *\n * if (!elicitation) return null;\n *\n * return (\n * <div>\n * <p>{elicitation.message}</p>\n * <button onClick={() => resolveElicitation?.({ action: \"accept\", content: {} })}>\n * Accept\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport const useTamboMcpElicitation = (): ElicitationContextState => {\n const context = useContext(McpProviderContext);\n return {\n elicitation: context.elicitation,\n resolveElicitation: context.resolveElicitation,\n };\n};\n\n/**\n * @deprecated Use `useTamboMcpElicitation` instead.\n * This hook will be removed in a future version.\n */\nexport const useTamboElicitationContext = useTamboMcpElicitation;\n\n/**\n * Normalizes registry server metadata into a `McpServerConfig`.\n *\n * Accepts a `NormalizedMcpServerInfo`, which already guarantees a concrete\n * `transport` and a `serverKey` derived by the registry, and narrows the\n * opaque `handlers` field to `Partial<MCPHandlers>`.\n * @param server - The normalized MCP server info from the registry\n * @returns The server config with typed handlers and unique key\n */\nfunction normalizeServerInfo(server: NormalizedMcpServerInfo): McpServerConfig {\n // Always use getMcpServerUniqueKey for connection identity to ensure\n // that changes to URL, transport, or customHeaders trigger client recreation.\n // The serverKey is kept for namespacing purposes (readable short name),\n // but the connection identity key must include all connection properties.\n const key = getMcpServerUniqueKey(server);\n // Cast handlers to proper type if present\n const handlers = server.handlers as Partial<MCPHandlers> | undefined;\n return {\n ...server,\n handlers,\n key,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tambo-mcp-provider.js","sourceRoot":"","sources":["../../src/mcp/tambo-mcp-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {\n createContext,\n FC,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n getMcpServerUniqueKey,\n type NormalizedMcpServerInfo,\n} from \"../model/mcp-server-info\";\nimport { useTamboMcpToken } from \"../providers/tambo-mcp-token-provider\";\nimport {\n useTamboMcpServerInfos,\n useTamboRegistry,\n} from \"../providers/tambo-registry-provider\";\nimport { isContentPartArray, toText } from \"../util/content-parts\";\nimport { type ElicitationContextState, useElicitation } from \"./elicitation\";\nimport {\n MCPClient,\n MCPElicitationHandler,\n MCPHandlers,\n MCPSamplingHandler,\n MCPTransport,\n} from \"./mcp-client\";\n\n/**\n * Extracts error message from MCP tool result content.\n * Handles both array and string content formats.\n * Always returns a string, even for invalid/null inputs.\n * @returns The extracted error message as a string\n */\nexport function extractErrorMessage(content: unknown): string {\n if (content === undefined || content === null) {\n return \"Unknown error occurred\";\n }\n\n if (Array.isArray(content)) {\n const textItems = content\n .filter((item) => item?.type === \"text\" && typeof item.text === \"string\")\n .map((item) => item.text);\n\n return textItems.length > 0\n ? textItems.join(\" \")\n : \"Error occurred but no details provided\";\n }\n\n if (typeof content === \"object\") {\n return JSON.stringify(content);\n }\n\n return `${content}`;\n}\n\n/**\n * Normalized MCP server information as consumed by the provider.\n *\n * Extends `NormalizedMcpServerInfo` from the core model by:\n * - narrowing `handlers` to `Partial<MCPHandlers>`\n * - adding a stable `key` derived from URL/transport/headers\n *\n * The registry is responsible for producing `NormalizedMcpServerInfo`\n * instances; this type adds the MCP-specific wiring needed to connect and\n * track clients.\n */\ninterface McpServerConfig extends NormalizedMcpServerInfo {\n /**\n * Optional handlers for elicitation and sampling requests from the server.\n * Interpreted as a partial set of MCP handlers.\n */\n handlers?: Partial<MCPHandlers>;\n /**\n * Stable identity for this server derived from its URL/transport/headers.\n * Present for all server states (connected or failed).\n */\n key: string;\n}\n\n/**\n * Connected MCP server with an active client.\n */\nexport interface ConnectedMcpServer extends McpServerConfig {\n client: MCPClient;\n}\n\n/**\n * Failed MCP server with a connection error.\n */\nexport interface FailedMcpServer extends McpServerConfig {\n client?: never;\n connectionError: Error;\n}\n\n/**\n * An active or failed MCP server, with access to the MCP client.\n */\nexport type McpServer = ConnectedMcpServer | FailedMcpServer;\n\n/**\n * Provider-level MCP handlers that receive the McpServerInfo as context in addition to the request.\n * These handlers are applied to all MCP servers unless overridden by per-server handlers.\n *\n * Handlers receive three parameters:\n * 1. request - The MCP request\n * 2. extra - RequestHandlerExtra containing AbortSignal and other metadata\n * 3. serverInfo - Configuration of the MCP server that triggered this request\n */\nexport interface ProviderMCPHandlers {\n elicitation?: (\n request: Parameters<MCPElicitationHandler>[0],\n extra: Parameters<MCPElicitationHandler>[1],\n serverInfo: McpServerConfig,\n ) => ReturnType<MCPElicitationHandler>;\n sampling?: (\n request: Parameters<MCPSamplingHandler>[0],\n extra: Parameters<MCPSamplingHandler>[1],\n serverInfo: McpServerConfig,\n ) => ReturnType<MCPSamplingHandler>;\n}\n\n/**\n * Context value for MCP provider including server list and elicitation state\n */\ninterface McpProviderContextValue extends ElicitationContextState {\n servers: McpServer[];\n}\n\nconst McpProviderContext = createContext<McpProviderContextValue>({\n servers: [],\n elicitation: null,\n resolveElicitation: null,\n});\n\n// Constant for the internal Tambo MCP server name\nconst TAMBO_INTERNAL_MCP_SERVER_NAME = \"__tambo_internal_mcp_server__\";\n\n/**\n * Creates a stable hash of a string for use as a cache key.\n * Uses Java-style string hashing (DJB2-like) for deterministic results.\n *\n * Note: We use a synchronous hash instead of crypto.subtle.digest because:\n * - crypto.subtle.digest is async, which adds complexity in React hooks (useMemo, useEffect)\n * - This is not for security, just for creating a stable identifier to detect token changes\n * - Synchronous hashing avoids race conditions and simplifies component lifecycle\n * @param input - The string to hash\n * @returns A compact base36 hash string\n */\nfunction hashString(input: string): string {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n hash = (Math.imul(31, hash) + input.charCodeAt(i)) | 0;\n }\n return (hash >>> 0).toString(36);\n}\n\n/**\n * This provider is used to register tools from MCP servers.\n * It automatically includes an internal Tambo MCP server when an MCP access token is available.\n *\n * **BREAKING CHANGE**: This provider no longer accepts `mcpServers` as a prop.\n * Instead, pass `mcpServers` to `TamboProvider` or `TamboRegistryProvider`.\n * This provider must be wrapped inside `TamboProvider` to access the MCP server registry.\n * @param props - The provider props\n * @param props.handlers - Optional handlers applied to all MCP servers unless overridden per-server\n * @param props.contextKey - Optional context key for fetching threadless MCP tokens when not in a thread\n * @param props.children - The children to wrap\n * @returns The TamboMcpProvider component\n */\nexport const TamboMcpProvider: FC<{\n handlers?: ProviderMCPHandlers;\n contextKey?: string;\n children: React.ReactNode;\n}> = ({ handlers, contextKey, children }) => {\n const { registerTool } = useTamboRegistry();\n const { mcpAccessToken, tamboBaseUrl } = useTamboMcpToken(contextKey);\n const mcpServers = useTamboMcpServerInfos();\n const providerSamplingHandler = handlers?.sampling;\n\n // Elicitation state and default handler\n const { elicitation, resolveElicitation, defaultElicitationHandler } =\n useElicitation();\n\n // Use provided handler or fall back to default\n const providerElicitationHandler =\n handlers?.elicitation ?? defaultElicitationHandler;\n\n // Stable reference to track active clients by server key\n const clientMapRef = useRef<Map<string, McpServer>>(new Map());\n // Track tool ownership to prevent duplicate registrations across servers\n // toolOwnerRef: tool name -> server key; keyToToolsRef: server key -> set of tool names\n const toolOwnerRef = useRef<Map<string, string>>(new Map());\n const keyToToolsRef = useRef<Map<string, Set<string>>>(new Map());\n\n // State for exposing connected servers to consumers\n const [connectedMcpServers, setConnectedMcpServers] = useState<McpServer[]>(\n [],\n );\n\n // Stable map of current server configurations keyed by server key\n const currentServersMap = useMemo(() => {\n const servers = [...mcpServers];\n\n // Add internal Tambo MCP server if we have an access token and a base URL\n if (mcpAccessToken && tamboBaseUrl) {\n const base = new URL(tamboBaseUrl);\n base.pathname = `${base.pathname.replace(/\\/+$/, \"\")}/mcp`;\n const tamboMcpUrl = base.toString();\n // Include token hash in serverKey so changing tokens trigger reconnection\n const tokenHash = hashString(mcpAccessToken);\n servers.push({\n name: TAMBO_INTERNAL_MCP_SERVER_NAME,\n url: tamboMcpUrl,\n transport: MCPTransport.HTTP,\n serverKey: `tambo-${tokenHash}`, // Include token hash in key to force reconnection on token change\n customHeaders: {\n Authorization: `Bearer ${mcpAccessToken}`,\n },\n });\n }\n\n // Create a map of server key -> server info for efficient lookups\n const serverMap = new Map<string, McpServerConfig>();\n servers.forEach((server) => {\n const serverInfo = normalizeServerInfo(server);\n // Store without cloning to avoid unnecessary allocation\n serverMap.set(serverInfo.key, serverInfo);\n });\n\n return serverMap;\n }, [mcpServers, mcpAccessToken, tamboBaseUrl]);\n\n // Main effect: manage client lifecycle (create/remove)\n useEffect(() => {\n const clientMap = clientMapRef.current;\n const currentKeys = new Set(currentServersMap.keys());\n const existingKeys = new Set(clientMap.keys());\n\n // 1. Remove clients that are no longer in the current server list\n const keysToRemove = Array.from(existingKeys).filter(\n (key) => !currentKeys.has(key),\n );\n keysToRemove.forEach((key) => {\n const server = clientMap.get(key);\n if (server?.client?.close) {\n try {\n // Call close() sync - it may or may not return a promise\n const closeResult = server.client.close();\n // If it returns a promise, handle errors but don't wait\n if (closeResult && typeof closeResult.catch === \"function\") {\n void closeResult.catch((error) => {\n const url = (server as McpServer).url ?? \"(unknown url)\";\n console.error(`Error closing MCP client for ${url}:`, error);\n });\n }\n } catch (error) {\n const url = (server as McpServer).url ?? \"(unknown url)\";\n console.error(`Error closing MCP client for ${url}:`, error);\n }\n }\n // Release tool ownership for this server\n const owned = keyToToolsRef.current.get(key);\n if (owned) {\n for (const name of owned) toolOwnerRef.current.delete(name);\n keyToToolsRef.current.delete(key);\n }\n clientMap.delete(key);\n });\n\n // 2. Add new clients for servers that don't exist yet\n const keysToAdd = Array.from(currentKeys).filter(\n (key) => !existingKeys.has(key),\n );\n\n async function addClients(keys: string[]) {\n await Promise.allSettled(\n keys.map(async (key) => {\n const serverInfo = currentServersMap.get(key)!;\n\n try {\n // Build effective handlers (per-server overrides provider)\n const effectiveHandlers: Partial<MCPHandlers> = {};\n\n if (serverInfo.handlers?.elicitation) {\n effectiveHandlers.elicitation = serverInfo.handlers.elicitation;\n } else if (providerElicitationHandler) {\n effectiveHandlers.elicitation = async (\n request: Parameters<MCPElicitationHandler>[0],\n extra: Parameters<MCPElicitationHandler>[1],\n ) => await providerElicitationHandler(request, extra, serverInfo);\n }\n\n if (serverInfo.handlers?.sampling) {\n effectiveHandlers.sampling = serverInfo.handlers.sampling;\n } else if (providerSamplingHandler) {\n effectiveHandlers.sampling = async (\n request: Parameters<MCPSamplingHandler>[0],\n extra: Parameters<MCPSamplingHandler>[1],\n ) => await providerSamplingHandler(request, extra, serverInfo);\n }\n\n const client = await MCPClient.create(\n serverInfo.url,\n serverInfo.transport,\n serverInfo.customHeaders,\n undefined,\n undefined,\n effectiveHandlers,\n );\n\n const connectedServer: ConnectedMcpServer = {\n ...serverInfo,\n client,\n };\n\n clientMap.set(key, connectedServer);\n setConnectedMcpServers(Array.from(clientMap.values()));\n\n // Register tools from this server (deduplicated by ownership)\n try {\n const tools = await client.listTools();\n const shouldPrefix = currentServersMap.size > 1;\n\n tools.forEach((tool) => {\n // Prefix tool name with serverKey if multiple servers are present\n const toolName = shouldPrefix\n ? `${serverInfo.serverKey}__${tool.name}`\n : tool.name;\n\n // Skip if another server already owns this tool (using final name for ownership)\n const currentOwner = toolOwnerRef.current.get(toolName);\n if (currentOwner && currentOwner !== key) {\n return;\n }\n\n // Record ownership for this server key (using final name)\n if (!currentOwner) {\n toolOwnerRef.current.set(toolName, key);\n if (!keyToToolsRef.current.has(key)) {\n keyToToolsRef.current.set(key, new Set());\n }\n keyToToolsRef.current.get(key)!.add(toolName);\n }\n\n registerTool({\n description: tool.description ?? \"\",\n name: toolName,\n tool: async (args: Record<string, unknown> = {}) => {\n const server = clientMap.get(key);\n if (!server?.client) {\n throw new Error(\n `MCP server for tool ${tool.name} is not connected`,\n );\n }\n const result = await server.client.callTool(\n tool.name,\n args,\n );\n if (result.isError) {\n const errorMessage = extractErrorMessage(result.content);\n throw new Error(errorMessage);\n }\n return result.content;\n },\n inputSchema: tool.inputSchema ?? {},\n outputSchema: {},\n transformToContent: (content: unknown) => {\n if (isContentPartArray(content)) {\n return content;\n }\n return [{ type: \"text\", text: toText(content) }];\n },\n });\n });\n } catch (error) {\n console.error(\n `Failed to register tools from MCP server ${serverInfo.url}:`,\n error,\n );\n }\n } catch (error) {\n const failedServer: FailedMcpServer = {\n ...serverInfo,\n connectionError: error as Error,\n };\n clientMap.set(key, failedServer);\n setConnectedMcpServers(Array.from(clientMap.values()));\n console.error(\n `Failed to connect to MCP server ${serverInfo.url}:`,\n error,\n );\n }\n }),\n );\n }\n\n if (keysToAdd.length > 0) {\n addClients(keysToAdd).catch((err) => {\n console.error(\"Unexpected error in addClients:\", err);\n });\n }\n\n // Update state after removals (additions update state asynchronously above)\n if (keysToRemove.length > 0) {\n setConnectedMcpServers(Array.from(clientMap.values()));\n }\n }, [\n currentServersMap,\n providerElicitationHandler,\n providerSamplingHandler,\n registerTool,\n ]);\n\n // Update handlers when they change (without recreating clients)\n useEffect(() => {\n const clientMap = clientMapRef.current;\n\n clientMap.forEach((server, key) => {\n if (!server.client) {\n return; // Skip failed servers\n }\n\n const serverInfo = currentServersMap.get(key);\n if (!serverInfo) {\n return; // Server was removed, handled by main effect\n }\n\n // Determine effective handlers\n const effectiveElicitationHandler =\n serverInfo.handlers?.elicitation ??\n (providerElicitationHandler\n ? async (\n request: Parameters<MCPElicitationHandler>[0],\n extra: Parameters<MCPElicitationHandler>[1],\n ) => await providerElicitationHandler(request, extra, serverInfo)\n : undefined);\n\n const effectiveSamplingHandler =\n serverInfo.handlers?.sampling ??\n (providerSamplingHandler\n ? async (\n request: Parameters<MCPSamplingHandler>[0],\n extra: Parameters<MCPSamplingHandler>[1],\n ) => await providerSamplingHandler(request, extra, serverInfo)\n : undefined);\n\n // Update handlers unconditionally (allows removal by passing undefined)\n server.client.updateElicitationHandler?.(effectiveElicitationHandler);\n server.client.updateSamplingHandler?.(effectiveSamplingHandler);\n });\n }, [currentServersMap, providerElicitationHandler, providerSamplingHandler]);\n\n // Cleanup on unmount: close all clients\n useEffect(() => {\n const clientMap = clientMapRef.current;\n const ownerMapAtMount = toolOwnerRef.current;\n const keyToToolsAtMount = keyToToolsRef.current;\n return () => {\n clientMap.forEach((server) => {\n if (server?.client?.close) {\n try {\n // Call close() sync - it may or may not return a promise\n const closeResult = server.client.close();\n // If it returns a promise, handle errors but don't wait\n if (closeResult && typeof closeResult.catch === \"function\") {\n void closeResult.catch((error) => {\n const url = (server as McpServer).url ?? \"(unknown url)\";\n console.error(\n `Error closing MCP client on unmount for ${url}:`,\n error,\n );\n });\n }\n } catch (error) {\n const url = (server as McpServer).url ?? \"(unknown url)\";\n console.error(\n `Error closing MCP client on unmount for ${url}:`,\n error,\n );\n }\n }\n });\n clientMap.clear();\n ownerMapAtMount.clear();\n keyToToolsAtMount.clear();\n };\n }, []);\n\n const contextValue = useMemo(\n () => ({\n servers: connectedMcpServers,\n elicitation,\n resolveElicitation,\n }),\n [connectedMcpServers, elicitation, resolveElicitation],\n );\n\n return (\n <McpProviderContext.Provider value={contextValue}>\n {children}\n </McpProviderContext.Provider>\n );\n};\n\n/**\n * Hook to access the actual MCP servers, as they are connected (or fail to\n * connect).\n *\n * You can call methods on the MCP client that is included in the MCP server\n * object.\n *\n * If the server fails to connect, the `client` property will be `undefined` and\n * the `connectionError` property will be set.\n *\n * For example, to forcibly disconnect and reconnect all MCP servers:\n *\n * ```tsx\n * const mcpServers = useTamboMcpServers();\n * mcpServers.forEach((mcpServer) => {\n * mcpServer.client?.reconnect();\n * });\n * ```\n *\n * Note that the MCP servers are not guaranteed to be in the same order as the\n * input array, because they are added as they are connected.\n * @returns The MCP servers\n */\nexport const useTamboMcpServers = () => {\n return useContext(McpProviderContext).servers;\n};\n\n/**\n * Hook to access MCP elicitation state from TamboMcpProvider.\n * This provides access to the current elicitation request and methods to respond to it.\n *\n * The elicitation state is automatically managed by TamboMcpProvider when MCP servers\n * request user input through the elicitation protocol.\n * @returns The elicitation state with current request and response handler\n * @example\n * ```tsx\n * function ElicitationUI() {\n * const { elicitation, resolveElicitation } = useTamboMcpElicitation();\n *\n * if (!elicitation) return null;\n *\n * return (\n * <div>\n * <p>{elicitation.message}</p>\n * <button onClick={() => resolveElicitation?.({ action: \"accept\", content: {} })}>\n * Accept\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport const useTamboMcpElicitation = (): ElicitationContextState => {\n const context = useContext(McpProviderContext);\n return {\n elicitation: context.elicitation,\n resolveElicitation: context.resolveElicitation,\n };\n};\n\n/**\n * @deprecated Use `useTamboMcpElicitation` instead.\n * This hook will be removed in a future version.\n */\nexport const useTamboElicitationContext = useTamboMcpElicitation;\n\n/**\n * Normalizes registry server metadata into a `McpServerConfig`.\n *\n * Accepts a `NormalizedMcpServerInfo`, which already guarantees a concrete\n * `transport` and a `serverKey` derived by the registry, and narrows the\n * opaque `handlers` field to `Partial<MCPHandlers>`.\n * @param server - The normalized MCP server info from the registry\n * @returns The server config with typed handlers and unique key\n */\nfunction normalizeServerInfo(server: NormalizedMcpServerInfo): McpServerConfig {\n // Always use getMcpServerUniqueKey for connection identity to ensure\n // that changes to URL, transport, or customHeaders trigger client recreation.\n // The serverKey is kept for namespacing purposes (readable short name),\n // but the connection identity key must include all connection properties.\n const key = getMcpServerUniqueKey(server);\n // Cast handlers to proper type if present\n const handlers = server.handlers as Partial<MCPHandlers> | undefined;\n return {\n ...server,\n handlers,\n key,\n };\n}\n"]}
|