@frontmcp/sdk 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -18
- package/package.json +20 -5
- package/src/app/app.registry.d.ts +3 -2
- package/src/app/app.registry.js +3 -1
- package/src/app/app.registry.js.map +1 -1
- package/src/app/instances/app.local.instance.js +2 -2
- package/src/app/instances/app.local.instance.js.map +1 -1
- package/src/auth/auth.registry.d.ts +34 -2
- package/src/auth/auth.registry.js +162 -24
- package/src/auth/auth.registry.js.map +1 -1
- package/src/auth/auth.utils.js +8 -9
- package/src/auth/auth.utils.js.map +1 -1
- package/src/auth/authorization/authorization.class.d.ts +125 -0
- package/src/auth/authorization/authorization.class.js +224 -0
- package/src/auth/authorization/authorization.class.js.map +1 -0
- package/src/auth/authorization/authorization.types.d.ts +300 -0
- package/src/auth/authorization/authorization.types.js +79 -0
- package/src/auth/authorization/authorization.types.js.map +1 -0
- package/src/auth/authorization/index.d.ts +5 -0
- package/src/auth/authorization/index.js +19 -0
- package/src/auth/authorization/index.js.map +1 -0
- package/src/auth/authorization/orchestrated.authorization.d.ts +242 -0
- package/src/auth/authorization/orchestrated.authorization.js +306 -0
- package/src/auth/authorization/orchestrated.authorization.js.map +1 -0
- package/src/auth/authorization/public.authorization.d.ts +91 -0
- package/src/auth/authorization/public.authorization.js +132 -0
- package/src/auth/authorization/public.authorization.js.map +1 -0
- package/src/auth/authorization/transparent.authorization.d.ts +130 -0
- package/src/auth/authorization/transparent.authorization.js +147 -0
- package/src/auth/authorization/transparent.authorization.js.map +1 -0
- package/src/auth/consent/consent.types.d.ts +111 -0
- package/src/auth/consent/consent.types.js +119 -0
- package/src/auth/consent/consent.types.js.map +1 -0
- package/src/auth/consent/index.d.ts +1 -0
- package/src/auth/consent/index.js +13 -0
- package/src/auth/consent/index.js.map +1 -0
- package/src/auth/detection/auth-provider-detection.d.ts +84 -0
- package/src/auth/detection/auth-provider-detection.js +230 -0
- package/src/auth/detection/auth-provider-detection.js.map +1 -0
- package/src/auth/detection/index.d.ts +1 -0
- package/src/auth/detection/index.js +15 -0
- package/src/auth/detection/index.js.map +1 -0
- package/src/auth/flows/auth.verify.flow.d.ts +110 -0
- package/src/auth/flows/auth.verify.flow.js +379 -0
- package/src/auth/flows/auth.verify.flow.js.map +1 -0
- package/src/auth/flows/oauth.authorize.flow.d.ts +118 -164
- package/src/auth/flows/oauth.authorize.flow.js +701 -33
- package/src/auth/flows/oauth.authorize.flow.js.map +1 -1
- package/src/auth/flows/oauth.callback.flow.d.ts +117 -0
- package/src/auth/flows/oauth.callback.flow.js +357 -0
- package/src/auth/flows/oauth.callback.flow.js.map +1 -0
- package/src/auth/flows/oauth.register.flow.d.ts +32 -125
- package/src/auth/flows/oauth.token.flow.d.ts +52 -154
- package/src/auth/flows/oauth.token.flow.js +193 -55
- package/src/auth/flows/oauth.token.flow.js.map +1 -1
- package/src/auth/flows/session.verify.flow.d.ts +66 -321
- package/src/auth/flows/session.verify.flow.js +107 -18
- package/src/auth/flows/session.verify.flow.js.map +1 -1
- package/src/auth/flows/well-known.jwks.flow.d.ts +34 -205
- package/src/auth/flows/well-known.jwks.flow.js +15 -8
- package/src/auth/flows/well-known.jwks.flow.js.map +1 -1
- package/src/auth/flows/well-known.oauth-authorization-server.flow.d.ts +48 -223
- package/src/auth/flows/well-known.oauth-authorization-server.flow.js +2 -3
- package/src/auth/flows/well-known.oauth-authorization-server.flow.js.map +1 -1
- package/src/auth/flows/well-known.prm.flow.d.ts +19 -120
- package/src/auth/flows/well-known.prm.flow.js +3 -4
- package/src/auth/flows/well-known.prm.flow.js.map +1 -1
- package/src/auth/instances/instance.local-primary-auth.d.ts +91 -4
- package/src/auth/instances/instance.local-primary-auth.js +236 -6
- package/src/auth/instances/instance.local-primary-auth.js.map +1 -1
- package/src/auth/instances/instance.remote-primary-auth.d.ts +4 -3
- package/src/auth/instances/instance.remote-primary-auth.js +2 -2
- package/src/auth/instances/instance.remote-primary-auth.js.map +1 -1
- package/src/auth/session/authorization-vault.d.ts +611 -0
- package/src/auth/session/authorization-vault.js +817 -0
- package/src/auth/session/authorization-vault.js.map +1 -0
- package/src/auth/session/authorization.store.d.ts +301 -0
- package/src/auth/session/authorization.store.js +323 -0
- package/src/auth/session/authorization.store.js.map +1 -0
- package/src/auth/session/encrypted-authorization-vault.d.ts +181 -0
- package/src/auth/session/encrypted-authorization-vault.js +493 -0
- package/src/auth/session/encrypted-authorization-vault.js.map +1 -0
- package/src/auth/session/index.d.ts +4 -4
- package/src/auth/session/index.js +11 -7
- package/src/auth/session/index.js.map +1 -1
- package/src/auth/session/session.schema.d.ts +1 -1
- package/src/auth/session/session.service.d.ts +1 -1
- package/src/auth/session/transport-session.manager.d.ts +101 -0
- package/src/auth/session/transport-session.manager.js +300 -0
- package/src/auth/session/transport-session.manager.js.map +1 -0
- package/src/auth/session/transport-session.types.d.ts +457 -0
- package/src/auth/session/transport-session.types.js +110 -0
- package/src/auth/session/transport-session.types.js.map +1 -0
- package/src/auth/session/utils/session-id.utils.d.ts +14 -2
- package/src/auth/session/utils/session-id.utils.js +68 -19
- package/src/auth/session/utils/session-id.utils.js.map +1 -1
- package/src/auth/session/vault-encryption.d.ts +189 -0
- package/src/auth/session/vault-encryption.js +263 -0
- package/src/auth/session/vault-encryption.js.map +1 -0
- package/src/auth/ui/base-layout.d.ts +188 -0
- package/src/auth/ui/base-layout.js +292 -0
- package/src/auth/ui/base-layout.js.map +1 -0
- package/src/auth/ui/htmx-templates.d.ts +135 -0
- package/src/auth/ui/htmx-templates.js +433 -0
- package/src/auth/ui/htmx-templates.js.map +1 -0
- package/src/auth/ui/index.d.ts +11 -0
- package/src/auth/ui/index.js +35 -0
- package/src/auth/ui/index.js.map +1 -0
- package/src/auth/utils/audience.validator.d.ts +129 -0
- package/src/auth/utils/audience.validator.js +196 -0
- package/src/auth/utils/audience.validator.js.map +1 -0
- package/src/auth/utils/index.d.ts +2 -0
- package/src/auth/utils/index.js +7 -0
- package/src/auth/utils/index.js.map +1 -0
- package/src/auth/utils/www-authenticate.utils.d.ts +97 -0
- package/src/auth/utils/www-authenticate.utils.js +183 -0
- package/src/auth/utils/www-authenticate.utils.js.map +1 -0
- package/src/common/common.schema.d.ts +2 -16
- package/src/common/constants.d.ts +3 -0
- package/src/common/constants.js +6 -1
- package/src/common/constants.js.map +1 -1
- package/src/common/decorators/decorator-utils.d.ts +131 -0
- package/src/common/decorators/decorator-utils.js +195 -0
- package/src/common/decorators/decorator-utils.js.map +1 -0
- package/src/common/decorators/front-mcp.decorator.js +3 -2
- package/src/common/decorators/front-mcp.decorator.js.map +1 -1
- package/src/common/decorators/hook.decorator.d.ts +58 -2
- package/src/common/decorators/hook.decorator.js +127 -17
- package/src/common/decorators/hook.decorator.js.map +1 -1
- package/src/common/decorators/plugin.decorator.d.ts +1 -1
- package/src/common/decorators/plugin.decorator.js +11 -10
- package/src/common/decorators/plugin.decorator.js.map +1 -1
- package/src/common/decorators/resource.decorator.d.ts +32 -3
- package/src/common/decorators/resource.decorator.js +46 -4
- package/src/common/decorators/resource.decorator.js.map +1 -1
- package/src/common/decorators/tool.decorator.d.ts +54 -5
- package/src/common/decorators/tool.decorator.js.map +1 -1
- package/src/common/dynamic/dynamic.plugin.d.ts +22 -11
- package/src/common/dynamic/dynamic.plugin.js +7 -1
- package/src/common/dynamic/dynamic.plugin.js.map +1 -1
- package/src/common/entries/prompt.entry.d.ts +46 -2
- package/src/common/entries/prompt.entry.js +10 -0
- package/src/common/entries/prompt.entry.js.map +1 -1
- package/src/common/entries/resource.entry.d.ts +69 -6
- package/src/common/entries/resource.entry.js +27 -3
- package/src/common/entries/resource.entry.js.map +1 -1
- package/src/common/entries/scope.entry.d.ts +5 -1
- package/src/common/entries/scope.entry.js +3 -3
- package/src/common/entries/scope.entry.js.map +1 -1
- package/src/common/flow/flow.utils.d.ts +56 -0
- package/src/common/flow/flow.utils.js +96 -0
- package/src/common/flow/flow.utils.js.map +1 -0
- package/src/common/index.d.ts +2 -2
- package/src/common/index.js +2 -2
- package/src/common/index.js.map +1 -1
- package/src/common/interfaces/execution-context.interface.d.ts +59 -0
- package/src/common/interfaces/execution-context.interface.js +81 -0
- package/src/common/interfaces/execution-context.interface.js.map +1 -0
- package/src/common/interfaces/flow.interface.d.ts +1 -1
- package/src/common/interfaces/flow.interface.js.map +1 -1
- package/src/common/interfaces/index.d.ts +1 -0
- package/src/common/interfaces/index.js +1 -0
- package/src/common/interfaces/index.js.map +1 -1
- package/src/common/interfaces/internal/primary-auth-provider.interface.d.ts +17 -2
- package/src/common/interfaces/internal/primary-auth-provider.interface.js +52 -4
- package/src/common/interfaces/internal/primary-auth-provider.interface.js.map +1 -1
- package/src/common/interfaces/internal/registry.interface.d.ts +16 -2
- package/src/common/interfaces/internal/registry.interface.js.map +1 -1
- package/src/common/interfaces/plugin.interface.js.map +1 -1
- package/src/common/interfaces/prompt.interface.d.ts +53 -4
- package/src/common/interfaces/prompt.interface.js +78 -0
- package/src/common/interfaces/prompt.interface.js.map +1 -1
- package/src/common/interfaces/resource.interface.d.ts +47 -17
- package/src/common/interfaces/resource.interface.js +53 -0
- package/src/common/interfaces/resource.interface.js.map +1 -1
- package/src/common/interfaces/tool.interface.d.ts +39 -22
- package/src/common/interfaces/tool.interface.js +61 -34
- package/src/common/interfaces/tool.interface.js.map +1 -1
- package/src/common/metadata/adapter.metadata.d.ts +1 -9
- package/src/common/metadata/app.metadata.d.ts +425 -730
- package/src/common/metadata/auth-provider.metadata.d.ts +2 -12
- package/src/common/metadata/flow.metadata.d.ts +10 -25
- package/src/common/metadata/front-mcp.metadata.d.ts +602 -1023
- package/src/common/metadata/front-mcp.metadata.js +6 -4
- package/src/common/metadata/front-mcp.metadata.js.map +1 -1
- package/src/common/metadata/hook.metadata.d.ts +1 -1
- package/src/common/metadata/hook.metadata.js.map +1 -1
- package/src/common/metadata/index.d.ts +1 -0
- package/src/common/metadata/index.js +1 -0
- package/src/common/metadata/index.js.map +1 -1
- package/src/common/metadata/logger.metadata.d.ts +1 -9
- package/src/common/metadata/plugin.metadata.d.ts +8 -30
- package/src/common/metadata/prompt.metadata.d.ts +4 -161
- package/src/common/metadata/provider.metadata.d.ts +2 -12
- package/src/common/metadata/resource.metadata.d.ts +6 -98
- package/src/common/metadata/resource.metadata.js +15 -6
- package/src/common/metadata/resource.metadata.js.map +1 -1
- package/src/common/metadata/tool-ui.metadata.d.ts +10 -0
- package/src/common/metadata/tool-ui.metadata.js +12 -0
- package/src/common/metadata/tool-ui.metadata.js.map +1 -0
- package/src/common/metadata/tool.metadata.d.ts +78 -199
- package/src/common/metadata/tool.metadata.js +11 -14
- package/src/common/metadata/tool.metadata.js.map +1 -1
- package/src/common/providers/base-config.provider.d.ts +84 -0
- package/src/common/providers/base-config.provider.js +128 -0
- package/src/common/providers/base-config.provider.js.map +1 -0
- package/src/common/records/plugin.record.d.ts +5 -6
- package/src/common/records/plugin.record.js.map +1 -1
- package/src/common/records/prompt.record.js.map +1 -1
- package/src/common/records/resource.record.d.ts +17 -1
- package/src/common/records/resource.record.js +12 -6
- package/src/common/records/resource.record.js.map +1 -1
- package/src/common/records/tool.record.js.map +1 -1
- package/src/common/schemas/annotated-class.schema.d.ts +9 -9
- package/src/common/schemas/annotated-class.schema.js +92 -27
- package/src/common/schemas/annotated-class.schema.js.map +1 -1
- package/src/common/schemas/http-input.schema.d.ts +6 -30
- package/src/common/schemas/http-output.schema.d.ts +326 -1630
- package/src/common/schemas/http-output.schema.js +39 -1
- package/src/common/schemas/http-output.schema.js.map +1 -1
- package/src/common/tokens/front-mcp.tokens.js +4 -1
- package/src/common/tokens/front-mcp.tokens.js.map +1 -1
- package/src/common/tokens/resource.tokens.d.ts +2 -0
- package/src/common/tokens/resource.tokens.js +4 -1
- package/src/common/tokens/resource.tokens.js.map +1 -1
- package/src/common/tokens/tool.tokens.d.ts +2 -0
- package/src/common/tokens/tool.tokens.js +2 -0
- package/src/common/tokens/tool.tokens.js.map +1 -1
- package/src/common/types/auth/jwt.types.d.ts +5 -31
- package/src/common/types/auth/session.types.d.ts +97 -192
- package/src/common/types/auth/session.types.js +24 -11
- package/src/common/types/auth/session.types.js.map +1 -1
- package/src/common/types/options/auth.options.d.ts +1013 -490
- package/src/common/types/options/auth.options.js +554 -36
- package/src/common/types/options/auth.options.js.map +1 -1
- package/src/common/types/options/http.options.d.ts +1 -9
- package/src/common/types/options/logging.options.d.ts +7 -13
- package/src/common/types/options/logging.options.js +4 -0
- package/src/common/types/options/logging.options.js.map +1 -1
- package/src/common/types/options/server-info.options.d.ts +3 -31
- package/src/common/types/options/session.options.d.ts +90 -10
- package/src/common/types/options/session.options.js +26 -3
- package/src/common/types/options/session.options.js.map +1 -1
- package/src/common/utils/decide-request-intent.utils.d.ts +8 -46
- package/src/common/utils/decide-request-intent.utils.js +88 -23
- package/src/common/utils/decide-request-intent.utils.js.map +1 -1
- package/src/completion/flows/complete.flow.d.ts +74 -0
- package/src/completion/flows/complete.flow.js +199 -0
- package/src/completion/flows/complete.flow.js.map +1 -0
- package/src/errors/authorization-required.error.d.ts +189 -0
- package/src/errors/authorization-required.error.js +274 -0
- package/src/errors/authorization-required.error.js.map +1 -0
- package/src/errors/index.d.ts +2 -1
- package/src/errors/index.js +17 -1
- package/src/errors/index.js.map +1 -1
- package/src/errors/mcp.error.d.ts +101 -1
- package/src/errors/mcp.error.js +147 -2
- package/src/errors/mcp.error.js.map +1 -1
- package/src/flows/flow.instance.js +4 -3
- package/src/flows/flow.instance.js.map +1 -1
- package/src/flows/flow.registry.js.map +1 -1
- package/src/flows/flow.stages.js +14 -11
- package/src/flows/flow.stages.js.map +1 -1
- package/src/front-mcp/front-mcp.providers.d.ts +464 -102
- package/src/front-mcp/front-mcp.providers.js +3 -5
- package/src/front-mcp/front-mcp.providers.js.map +1 -1
- package/src/hooks/hook.instance.d.ts +1 -1
- package/src/hooks/hook.instance.js +5 -2
- package/src/hooks/hook.instance.js.map +1 -1
- package/src/hooks/hook.registry.js +7 -5
- package/src/hooks/hook.registry.js.map +1 -1
- package/src/index.d.ts +28 -9
- package/src/index.js +5 -1
- package/src/index.js.map +1 -1
- package/src/logger/instances/instance.logger.js +3 -2
- package/src/logger/instances/instance.logger.js.map +1 -1
- package/src/logger/logger.registry.js +7 -2
- package/src/logger/logger.registry.js.map +1 -1
- package/src/logging/flows/set-level.flow.d.ts +62 -0
- package/src/logging/flows/set-level.flow.js +108 -0
- package/src/logging/flows/set-level.flow.js.map +1 -0
- package/src/mcp-apps/csp.d.ts +111 -0
- package/src/mcp-apps/csp.js +267 -0
- package/src/mcp-apps/csp.js.map +1 -0
- package/src/mcp-apps/index.d.ts +23 -0
- package/src/mcp-apps/index.js +91 -0
- package/src/mcp-apps/index.js.map +1 -0
- package/src/mcp-apps/schemas.d.ts +403 -0
- package/src/mcp-apps/schemas.js +345 -0
- package/src/mcp-apps/schemas.js.map +1 -0
- package/src/mcp-apps/template.d.ts +94 -0
- package/src/mcp-apps/template.js +419 -0
- package/src/mcp-apps/template.js.map +1 -0
- package/src/mcp-apps/types.d.ts +323 -0
- package/src/mcp-apps/types.js +59 -0
- package/src/mcp-apps/types.js.map +1 -0
- package/src/notification/index.d.ts +1 -0
- package/src/notification/index.js +13 -0
- package/src/notification/index.js.map +1 -0
- package/src/notification/notification.service.d.ts +378 -0
- package/src/notification/notification.service.js +727 -0
- package/src/notification/notification.service.js.map +1 -0
- package/src/plugin/plugin.registry.js +12 -9
- package/src/plugin/plugin.registry.js.map +1 -1
- package/src/prompt/flows/get-prompt.flow.d.ts +153 -0
- package/src/prompt/flows/get-prompt.flow.js +214 -0
- package/src/prompt/flows/get-prompt.flow.js.map +1 -0
- package/src/prompt/flows/prompts-list.flow.d.ts +67 -0
- package/src/prompt/flows/prompts-list.flow.js +176 -0
- package/src/prompt/flows/prompts-list.flow.js.map +1 -0
- package/src/prompt/index.d.ts +7 -0
- package/src/prompt/index.js +17 -0
- package/src/prompt/index.js.map +1 -0
- package/src/prompt/prompt.events.d.ts +17 -0
- package/src/prompt/prompt.events.js +25 -0
- package/src/prompt/prompt.events.js.map +1 -0
- package/src/prompt/prompt.instance.d.ts +30 -0
- package/src/prompt/prompt.instance.js +120 -0
- package/src/prompt/prompt.instance.js.map +1 -0
- package/src/prompt/prompt.registry.d.ts +79 -12
- package/src/prompt/prompt.registry.js +360 -15
- package/src/prompt/prompt.registry.js.map +1 -1
- package/src/prompt/prompt.types.d.ts +26 -0
- package/src/prompt/prompt.types.js +11 -0
- package/src/prompt/prompt.types.js.map +1 -0
- package/src/prompt/prompt.utils.d.ts +26 -0
- package/src/prompt/prompt.utils.js +136 -0
- package/src/prompt/prompt.utils.js.map +1 -0
- package/src/provider/provider.registry.d.ts +12 -5
- package/src/provider/provider.registry.js +30 -138
- package/src/provider/provider.registry.js.map +1 -1
- package/src/regsitry/registry.base.d.ts +1 -1
- package/src/regsitry/registry.base.js.map +1 -1
- package/src/resource/flows/read-resource.flow.d.ts +91 -0
- package/src/resource/flows/read-resource.flow.js +270 -0
- package/src/resource/flows/read-resource.flow.js.map +1 -0
- package/src/resource/flows/resource-templates-list.flow.d.ts +64 -0
- package/src/resource/flows/resource-templates-list.flow.js +191 -0
- package/src/resource/flows/resource-templates-list.flow.js.map +1 -0
- package/src/resource/flows/resources-list.flow.d.ts +64 -0
- package/src/resource/flows/resources-list.flow.js +196 -0
- package/src/resource/flows/resources-list.flow.js.map +1 -0
- package/src/resource/flows/subscribe-resource.flow.d.ts +45 -0
- package/src/resource/flows/subscribe-resource.flow.js +123 -0
- package/src/resource/flows/subscribe-resource.flow.js.map +1 -0
- package/src/resource/flows/unsubscribe-resource.flow.d.ts +44 -0
- package/src/resource/flows/unsubscribe-resource.flow.js +107 -0
- package/src/resource/flows/unsubscribe-resource.flow.js.map +1 -0
- package/src/resource/index.d.ts +8 -0
- package/src/resource/index.js +20 -0
- package/src/resource/index.js.map +1 -0
- package/src/resource/resource.events.d.ts +24 -0
- package/src/resource/resource.events.js +17 -0
- package/src/resource/resource.events.js.map +1 -0
- package/src/resource/resource.instance.d.ts +35 -0
- package/src/resource/resource.instance.js +163 -0
- package/src/resource/resource.instance.js.map +1 -0
- package/src/resource/resource.registry.d.ts +106 -12
- package/src/resource/resource.registry.js +449 -13
- package/src/resource/resource.registry.js.map +1 -1
- package/src/resource/resource.types.d.ts +35 -0
- package/src/resource/resource.types.js +11 -0
- package/src/resource/resource.types.js.map +1 -0
- package/src/resource/resource.utils.d.ts +30 -0
- package/src/resource/resource.utils.js +151 -0
- package/src/resource/resource.utils.js.map +1 -0
- package/src/scope/flows/http.request.flow.d.ts +48 -330
- package/src/scope/flows/http.request.flow.js +306 -78
- package/src/scope/flows/http.request.flow.js.map +1 -1
- package/src/scope/scope.instance.d.ts +12 -0
- package/src/scope/scope.instance.js +145 -15
- package/src/scope/scope.instance.js.map +1 -1
- package/src/tool/flows/call-tool.flow.d.ts +64 -1110
- package/src/tool/flows/call-tool.flow.js +303 -15
- package/src/tool/flows/call-tool.flow.js.map +1 -1
- package/src/tool/flows/tools-list.flow.d.ts +32 -473
- package/src/tool/flows/tools-list.flow.js +111 -10
- package/src/tool/flows/tools-list.flow.js.map +1 -1
- package/src/tool/tool.events.d.ts +8 -1
- package/src/tool/tool.events.js.map +1 -1
- package/src/tool/tool.instance.d.ts +3 -1
- package/src/tool/tool.instance.js +17 -3
- package/src/tool/tool.instance.js.map +1 -1
- package/src/tool/tool.registry.d.ts +7 -1
- package/src/tool/tool.registry.js +26 -10
- package/src/tool/tool.registry.js.map +1 -1
- package/src/tool/tool.types.d.ts +4 -4
- package/src/tool/tool.types.js.map +1 -1
- package/src/tool/tool.utils.d.ts +3 -12
- package/src/tool/tool.utils.js +39 -193
- package/src/tool/tool.utils.js.map +1 -1
- package/src/tool/ui/index.d.ts +22 -0
- package/src/tool/ui/index.js +63 -0
- package/src/tool/ui/index.js.map +1 -0
- package/src/tool/ui/platform-adapters.d.ts +10 -0
- package/src/tool/ui/platform-adapters.js +18 -0
- package/src/tool/ui/platform-adapters.js.map +1 -0
- package/src/tool/ui/template-helpers.d.ts +46 -0
- package/src/tool/ui/template-helpers.js +112 -0
- package/src/tool/ui/template-helpers.js.map +1 -0
- package/src/tool/ui/ui-resource-template.d.ts +34 -0
- package/src/tool/ui/ui-resource-template.js +64 -0
- package/src/tool/ui/ui-resource-template.js.map +1 -0
- package/src/tool/ui/ui-resource.handler.d.ts +74 -0
- package/src/tool/ui/ui-resource.handler.js +129 -0
- package/src/tool/ui/ui-resource.handler.js.map +1 -0
- package/src/transport/adapters/transport.local.adapter.d.ts +2 -2
- package/src/transport/adapters/transport.local.adapter.js +28 -7
- package/src/transport/adapters/transport.local.adapter.js.map +1 -1
- package/src/transport/adapters/transport.sse.adapter.d.ts +2 -2
- package/src/transport/adapters/transport.sse.adapter.js +4 -3
- package/src/transport/adapters/transport.sse.adapter.js.map +1 -1
- package/src/transport/adapters/transport.streamable-http.adapter.d.ts +10 -3
- package/src/transport/adapters/transport.streamable-http.adapter.js +54 -8
- package/src/transport/adapters/transport.streamable-http.adapter.js.map +1 -1
- package/src/transport/flows/handle.sse.flow.d.ts +29 -63
- package/src/transport/flows/handle.sse.flow.js +78 -10
- package/src/transport/flows/handle.sse.flow.js.map +1 -1
- package/src/transport/flows/handle.stateless-http.flow.d.ts +29 -0
- package/src/transport/flows/handle.stateless-http.flow.js +102 -0
- package/src/transport/flows/handle.stateless-http.flow.js.map +1 -0
- package/src/transport/flows/handle.streamable-http.flow.d.ts +32 -64
- package/src/transport/flows/handle.streamable-http.flow.js +158 -26
- package/src/transport/flows/handle.streamable-http.flow.js.map +1 -1
- package/src/transport/legacy/legacy.sse.tranporter.d.ts +9 -0
- package/src/transport/legacy/legacy.sse.tranporter.js +17 -2
- package/src/transport/legacy/legacy.sse.tranporter.js.map +1 -1
- package/src/transport/mcp-handlers/call-tool-request.handler.js +27 -1
- package/src/transport/mcp-handlers/call-tool-request.handler.js.map +1 -1
- package/src/transport/mcp-handlers/complete-request.handler.d.ts +69 -0
- package/src/transport/mcp-handlers/complete-request.handler.js +11 -0
- package/src/transport/mcp-handlers/complete-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/get-prompt-request.handler.d.ts +87 -0
- package/src/transport/mcp-handlers/get-prompt-request.handler.js +11 -0
- package/src/transport/mcp-handlers/get-prompt-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/index.d.ts +517 -208
- package/src/transport/mcp-handlers/index.js +39 -2
- package/src/transport/mcp-handlers/index.js.map +1 -1
- package/src/transport/mcp-handlers/initialize-request.handler.d.ts +1 -1
- package/src/transport/mcp-handlers/initialize-request.handler.js +73 -7
- package/src/transport/mcp-handlers/initialize-request.handler.js.map +1 -1
- package/src/transport/mcp-handlers/list-prompts-request.handler.d.ts +54 -0
- package/src/transport/mcp-handlers/list-prompts-request.handler.js +11 -0
- package/src/transport/mcp-handlers/list-prompts-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/list-resource-templates-request.handler.d.ts +51 -0
- package/src/transport/mcp-handlers/list-resource-templates-request.handler.js +12 -0
- package/src/transport/mcp-handlers/list-resource-templates-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/list-resources-request.handler.d.ts +51 -0
- package/src/transport/mcp-handlers/list-resources-request.handler.js +12 -0
- package/src/transport/mcp-handlers/list-resources-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/list-tools-request.handler.d.ts +19 -146
- package/src/transport/mcp-handlers/logging-set-level-request.handler.d.ts +46 -0
- package/src/transport/mcp-handlers/logging-set-level-request.handler.js +34 -0
- package/src/transport/mcp-handlers/logging-set-level-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/mcp-handlers.types.d.ts +3 -7
- package/src/transport/mcp-handlers/mcp-handlers.types.js.map +1 -1
- package/src/transport/mcp-handlers/read-resource-request.handler.d.ts +46 -0
- package/src/transport/mcp-handlers/read-resource-request.handler.js +12 -0
- package/src/transport/mcp-handlers/read-resource-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/roots-list-changed-notification.handler.d.ts +11 -0
- package/src/transport/mcp-handlers/roots-list-changed-notification.handler.js +26 -0
- package/src/transport/mcp-handlers/roots-list-changed-notification.handler.js.map +1 -0
- package/src/transport/mcp-handlers/subscribe-request.handler.d.ts +37 -0
- package/src/transport/mcp-handlers/subscribe-request.handler.js +34 -0
- package/src/transport/mcp-handlers/subscribe-request.handler.js.map +1 -0
- package/src/transport/mcp-handlers/unsubscribe-request.handler.d.ts +37 -0
- package/src/transport/mcp-handlers/unsubscribe-request.handler.js +34 -0
- package/src/transport/mcp-handlers/unsubscribe-request.handler.js.map +1 -0
- package/src/transport/transport.local.js +7 -2
- package/src/transport/transport.local.js.map +1 -1
- package/src/transport/transport.registry.d.ts +30 -0
- package/src/transport/transport.registry.js +84 -1
- package/src/transport/transport.registry.js.map +1 -1
- package/src/transport/transport.types.d.ts +3 -3
- package/src/transport/transport.types.js.map +1 -1
- package/src/utils/content.utils.d.ts +48 -0
- package/src/utils/content.utils.js +194 -0
- package/src/utils/content.utils.js.map +1 -0
- package/src/utils/index.d.ts +8 -0
- package/src/utils/index.js +55 -0
- package/src/utils/index.js.map +1 -0
- package/src/utils/lineage.utils.d.ts +40 -0
- package/src/utils/lineage.utils.js +82 -0
- package/src/utils/lineage.utils.js.map +1 -0
- package/src/utils/naming.utils.d.ts +46 -0
- package/src/utils/naming.utils.js +136 -0
- package/src/utils/naming.utils.js.map +1 -0
- package/src/utils/types.utils.d.ts +2 -2
- package/src/utils/types.utils.js.map +1 -1
- package/src/utils/uri-template.utils.d.ts +57 -0
- package/src/utils/uri-template.utils.js +113 -0
- package/src/utils/uri-template.utils.js.map +1 -0
- package/src/utils/uri-validation.utils.d.ts +40 -0
- package/src/utils/uri-validation.utils.js +76 -0
- package/src/utils/uri-validation.utils.js.map +1 -0
- package/src/__test-utils__/fixtures/hook.fixtures.d.ts +0 -46
- package/src/__test-utils__/fixtures/hook.fixtures.js +0 -114
- package/src/__test-utils__/fixtures/hook.fixtures.js.map +0 -1
- package/src/__test-utils__/fixtures/index.d.ts +0 -7
- package/src/__test-utils__/fixtures/index.js +0 -11
- package/src/__test-utils__/fixtures/index.js.map +0 -1
- package/src/__test-utils__/fixtures/plugin.fixtures.d.ts +0 -46
- package/src/__test-utils__/fixtures/plugin.fixtures.js +0 -127
- package/src/__test-utils__/fixtures/plugin.fixtures.js.map +0 -1
- package/src/__test-utils__/fixtures/provider.fixtures.d.ts +0 -69
- package/src/__test-utils__/fixtures/provider.fixtures.js +0 -131
- package/src/__test-utils__/fixtures/provider.fixtures.js.map +0 -1
- package/src/__test-utils__/fixtures/scope.fixtures.d.ts +0 -14
- package/src/__test-utils__/fixtures/scope.fixtures.js +0 -59
- package/src/__test-utils__/fixtures/scope.fixtures.js.map +0 -1
- package/src/__test-utils__/fixtures/tool.fixtures.d.ts +0 -36
- package/src/__test-utils__/fixtures/tool.fixtures.js +0 -91
- package/src/__test-utils__/fixtures/tool.fixtures.js.map +0 -1
- package/src/__test-utils__/helpers/assertion.helpers.d.ts +0 -45
- package/src/__test-utils__/helpers/assertion.helpers.js +0 -153
- package/src/__test-utils__/helpers/assertion.helpers.js.map +0 -1
- package/src/__test-utils__/helpers/async.helpers.d.ts +0 -48
- package/src/__test-utils__/helpers/async.helpers.js +0 -112
- package/src/__test-utils__/helpers/async.helpers.js.map +0 -1
- package/src/__test-utils__/helpers/index.d.ts +0 -6
- package/src/__test-utils__/helpers/index.js +0 -10
- package/src/__test-utils__/helpers/index.js.map +0 -1
- package/src/__test-utils__/helpers/setup.helpers.d.ts +0 -54
- package/src/__test-utils__/helpers/setup.helpers.js +0 -106
- package/src/__test-utils__/helpers/setup.helpers.js.map +0 -1
- package/src/__test-utils__/index.d.ts +0 -9
- package/src/__test-utils__/index.js +0 -14
- package/src/__test-utils__/index.js.map +0 -1
- package/src/__test-utils__/mocks/flow-instance.mock.d.ts +0 -50
- package/src/__test-utils__/mocks/flow-instance.mock.js +0 -72
- package/src/__test-utils__/mocks/flow-instance.mock.js.map +0 -1
- package/src/__test-utils__/mocks/hook-registry.mock.d.ts +0 -25
- package/src/__test-utils__/mocks/hook-registry.mock.js +0 -65
- package/src/__test-utils__/mocks/hook-registry.mock.js.map +0 -1
- package/src/__test-utils__/mocks/index.d.ts +0 -8
- package/src/__test-utils__/mocks/index.js +0 -12
- package/src/__test-utils__/mocks/index.js.map +0 -1
- package/src/__test-utils__/mocks/plugin-registry.mock.d.ts +0 -43
- package/src/__test-utils__/mocks/plugin-registry.mock.js +0 -70
- package/src/__test-utils__/mocks/plugin-registry.mock.js.map +0 -1
- package/src/__test-utils__/mocks/provider-registry.mock.d.ts +0 -39
- package/src/__test-utils__/mocks/provider-registry.mock.js +0 -72
- package/src/__test-utils__/mocks/provider-registry.mock.js.map +0 -1
- package/src/__test-utils__/mocks/tool-registry.mock.d.ts +0 -43
- package/src/__test-utils__/mocks/tool-registry.mock.js +0 -79
- package/src/__test-utils__/mocks/tool-registry.mock.js.map +0 -1
- package/src/auth/path.utils.d.ts +0 -20
- package/src/auth/path.utils.js +0 -71
- package/src/auth/path.utils.js.map +0 -1
- package/src/common/decorators-old/async-with.decorator.d.ts +0 -10
- package/src/common/decorators-old/async-with.decorator.js +0 -24
- package/src/common/decorators-old/async-with.decorator.js.map +0 -1
- package/src/common/decorators-old/auth-hook.decorator.d.ts +0 -14
- package/src/common/decorators-old/auth-hook.decorator.js +0 -27
- package/src/common/decorators-old/auth-hook.decorator.js.map +0 -1
- package/src/common/decorators-old/session-hook.decorator.d.ts +0 -14
- package/src/common/decorators-old/session-hook.decorator.js +0 -27
- package/src/common/decorators-old/session-hook.decorator.js.map +0 -1
|
@@ -2,41 +2,73 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
// tools/flows/call-tool.flow.ts
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
5
6
|
const common_1 = require("../../common");
|
|
6
7
|
const zod_1 = require("zod");
|
|
7
8
|
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
8
9
|
const errors_1 = require("../../errors");
|
|
10
|
+
const ui_1 = require("../ui");
|
|
9
11
|
const inputSchema = zod_1.z.object({
|
|
10
12
|
request: types_js_1.CallToolRequestSchema,
|
|
13
|
+
// z.any() used because ctx is the MCP SDK's ToolCallExtra type which varies by SDK version
|
|
11
14
|
ctx: zod_1.z.any(),
|
|
12
15
|
});
|
|
13
16
|
const outputSchema = types_js_1.CallToolResultSchema;
|
|
14
17
|
const stateSchema = zod_1.z.object({
|
|
15
|
-
input: zod_1.z
|
|
16
|
-
.object({
|
|
18
|
+
input: zod_1.z.looseObject({
|
|
17
19
|
name: zod_1.z.string().min(1).max(64),
|
|
18
|
-
arguments: zod_1.z.
|
|
19
|
-
})
|
|
20
|
-
.passthrough(),
|
|
20
|
+
arguments: zod_1.z.looseObject({}).optional(),
|
|
21
|
+
}),
|
|
21
22
|
authInfo: zod_1.z.any().optional(),
|
|
22
23
|
tool: zod_1.z.instanceof(common_1.ToolEntry),
|
|
23
24
|
toolContext: zod_1.z.instanceof(common_1.ToolContext),
|
|
24
25
|
// Store the raw executed output for plugins to see
|
|
25
26
|
rawOutput: zod_1.z.any().optional(),
|
|
26
27
|
output: outputSchema,
|
|
28
|
+
// Tool owner ID for hook filtering (set during parseInput)
|
|
29
|
+
_toolOwnerId: zod_1.z.string().optional(),
|
|
27
30
|
});
|
|
28
31
|
const plan = {
|
|
29
|
-
pre: [
|
|
32
|
+
pre: [
|
|
33
|
+
'parseInput',
|
|
34
|
+
'findTool',
|
|
35
|
+
'checkToolAuthorization',
|
|
36
|
+
'createToolCallContext',
|
|
37
|
+
'acquireQuota',
|
|
38
|
+
'acquireSemaphore',
|
|
39
|
+
],
|
|
30
40
|
execute: ['validateInput', 'execute', 'validateOutput'],
|
|
31
41
|
finalize: ['releaseSemaphore', 'releaseQuota', 'finalize'],
|
|
32
42
|
};
|
|
33
43
|
const name = 'tools:call-tool';
|
|
34
44
|
const { Stage } = (0, common_1.FlowHooksOf)(name);
|
|
45
|
+
/**
|
|
46
|
+
* Safely stringify a value, handling circular references and other edge cases.
|
|
47
|
+
* This prevents tool calls from failing due to serialization errors.
|
|
48
|
+
*/
|
|
49
|
+
const safeStringify = (value, space) => {
|
|
50
|
+
const seen = new WeakSet();
|
|
51
|
+
try {
|
|
52
|
+
return JSON.stringify(value, (_key, val) => {
|
|
53
|
+
if (typeof val === 'object' && val !== null) {
|
|
54
|
+
if (seen.has(val))
|
|
55
|
+
return '[Circular]';
|
|
56
|
+
seen.add(val);
|
|
57
|
+
}
|
|
58
|
+
return val;
|
|
59
|
+
}, space);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return JSON.stringify({ error: 'Output could not be serialized' });
|
|
63
|
+
}
|
|
64
|
+
};
|
|
35
65
|
let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
36
66
|
logger = this.scopeLogger.child('CallToolFlow');
|
|
37
67
|
async parseInput() {
|
|
38
68
|
this.logger.verbose('parseInput:start');
|
|
39
69
|
let method;
|
|
70
|
+
// NOTE: `any` is intentional - Zod parsing validates these values
|
|
71
|
+
// Using unknown would require redundant type guards after schema validation
|
|
40
72
|
let params;
|
|
41
73
|
let ctx;
|
|
42
74
|
try {
|
|
@@ -46,7 +78,7 @@ let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
|
46
78
|
ctx = inputData.ctx;
|
|
47
79
|
}
|
|
48
80
|
catch (e) {
|
|
49
|
-
throw new errors_1.InvalidInputError('Invalid Input', e instanceof zod_1.z.ZodError ? e.
|
|
81
|
+
throw new errors_1.InvalidInputError('Invalid Input', e instanceof zod_1.z.ZodError ? e.issues : undefined);
|
|
50
82
|
}
|
|
51
83
|
if (method !== 'tools/call') {
|
|
52
84
|
this.logger.warn(`parseInput: invalid method "${method}"`);
|
|
@@ -58,11 +90,9 @@ let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
|
58
90
|
const tool = activeTools.find((entry) => {
|
|
59
91
|
return entry.fullName === name || entry.name === name;
|
|
60
92
|
});
|
|
61
|
-
// Store tool owner ID in
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
this.state.set({ input: params, authInfo: ctx.authInfo });
|
|
93
|
+
// Store tool owner ID in state for hook filtering
|
|
94
|
+
const toolOwnerId = tool?.owner?.id;
|
|
95
|
+
this.state.set({ input: params, authInfo: ctx.authInfo, _toolOwnerId: toolOwnerId });
|
|
66
96
|
this.logger.verbose('parseInput:done');
|
|
67
97
|
}
|
|
68
98
|
async findTool() {
|
|
@@ -83,6 +113,78 @@ let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
|
83
113
|
this.logger.info(`findTool: tool "${name}" found`);
|
|
84
114
|
this.logger.verbose('findTool:done');
|
|
85
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Check if the tool's parent app is authorized.
|
|
118
|
+
* For progressive authorization, tools from unauthorized apps
|
|
119
|
+
* return an AuthorizationRequiredError with an auth_url.
|
|
120
|
+
*/
|
|
121
|
+
async checkToolAuthorization() {
|
|
122
|
+
this.logger.verbose('checkToolAuthorization:start');
|
|
123
|
+
const { tool, authInfo } = this.state;
|
|
124
|
+
// Get authorization from authInfo.extra if available
|
|
125
|
+
const authorization = authInfo?.extra?.['authorization'];
|
|
126
|
+
// No auth context = public mode, skip authorization check
|
|
127
|
+
if (!authorization) {
|
|
128
|
+
this.logger.verbose('checkToolAuthorization:skip (no auth context)');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// Get app ID from tool owner (uses existing lineage system)
|
|
132
|
+
const appId = tool?.owner?.id;
|
|
133
|
+
if (!appId) {
|
|
134
|
+
// Tool has no owner = global tool, skip app-level authorization check
|
|
135
|
+
this.logger.verbose('checkToolAuthorization:skip (no owner)');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
// Check if app is authorized using existing session structure
|
|
139
|
+
const isAppAuthorized = authorization.authorizedAppIds?.includes(appId) || appId in (authorization.authorizedApps || {});
|
|
140
|
+
if (!isAppAuthorized) {
|
|
141
|
+
// Get incremental auth configuration from scope's auth options
|
|
142
|
+
const apps = this.scope.apps.getApps();
|
|
143
|
+
const app = apps.find((a) => a.metadata.id === appId);
|
|
144
|
+
const authOptions = this.scope.auth?.options;
|
|
145
|
+
// Determine skippedAppBehavior:
|
|
146
|
+
// 1. Only applies in orchestrated mode with incrementalAuth configured
|
|
147
|
+
// 2. Default to 'anonymous' if not configured (allow anonymous fallback)
|
|
148
|
+
let skippedBehavior = 'anonymous';
|
|
149
|
+
if (authOptions && (0, common_1.isOrchestratedMode)(authOptions)) {
|
|
150
|
+
// Orchestrated mode - check incrementalAuth config
|
|
151
|
+
const incrementalConfig = authOptions.incrementalAuth;
|
|
152
|
+
if (incrementalConfig) {
|
|
153
|
+
// If incremental auth is disabled, always require auth
|
|
154
|
+
if (incrementalConfig.enabled === false) {
|
|
155
|
+
skippedBehavior = 'require-auth';
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
skippedBehavior = incrementalConfig.skippedAppBehavior || 'anonymous';
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// If incrementalAuth not configured, default is enabled with 'anonymous' behavior
|
|
162
|
+
}
|
|
163
|
+
// For public/transparent modes, default 'anonymous' behavior applies
|
|
164
|
+
if (skippedBehavior === 'anonymous' && app?.metadata?.auth?.mode === 'public') {
|
|
165
|
+
// App supports anonymous - continue with anonymous access
|
|
166
|
+
this.logger.verbose(`checkToolAuthorization: using anonymous for ${appId}`);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
// Require explicit authorization - build auth URL
|
|
170
|
+
const authUrl = this.buildProgressiveAuthUrl(appId, tool?.fullName || '');
|
|
171
|
+
this.logger.info(`checkToolAuthorization: authorization required for app "${appId}"`);
|
|
172
|
+
throw new errors_1.AuthorizationRequiredError({
|
|
173
|
+
appId,
|
|
174
|
+
toolId: tool?.fullName || tool?.name || 'unknown',
|
|
175
|
+
authUrl,
|
|
176
|
+
message: `Authorization required for ${appId}. Please authorize to use ${tool?.fullName || tool?.name}.`,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
this.logger.verbose('checkToolAuthorization:done');
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Build the URL for progressive/incremental authorization
|
|
183
|
+
*/
|
|
184
|
+
buildProgressiveAuthUrl(appId, toolId) {
|
|
185
|
+
const baseUrl = this.scope.fullPath || '';
|
|
186
|
+
return `${baseUrl}/oauth/authorize?app=${encodeURIComponent(appId)}&tool=${encodeURIComponent(toolId)}`;
|
|
187
|
+
}
|
|
86
188
|
async createToolCallContext() {
|
|
87
189
|
this.logger.verbose('createToolCallContext:start');
|
|
88
190
|
const { ctx } = this.input;
|
|
@@ -131,7 +233,7 @@ let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
|
131
233
|
}
|
|
132
234
|
catch (err) {
|
|
133
235
|
if (err instanceof zod_1.z.ZodError) {
|
|
134
|
-
throw new errors_1.InvalidInputError('Invalid tool input', err.
|
|
236
|
+
throw new errors_1.InvalidInputError('Invalid tool input', err.issues);
|
|
135
237
|
}
|
|
136
238
|
this.logger.error('validateInput: failed to parse input', err);
|
|
137
239
|
throw new errors_1.InvalidInputError('Unknown error occurred when trying to parse input');
|
|
@@ -178,7 +280,7 @@ let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
|
178
280
|
}
|
|
179
281
|
async finalize() {
|
|
180
282
|
this.logger.verbose('finalize:start');
|
|
181
|
-
const { tool, rawOutput } = this.state;
|
|
283
|
+
const { tool, rawOutput, input } = this.state;
|
|
182
284
|
if (!tool) {
|
|
183
285
|
this.logger.error('finalize: tool not found in state');
|
|
184
286
|
throw new errors_1.ToolExecutionError('unknown', new Error('Tool not found in state'));
|
|
@@ -198,8 +300,188 @@ let CallToolFlow = class CallToolFlow extends common_1.FlowBase {
|
|
|
198
300
|
// Use InvalidOutputError, which hides internal details in production
|
|
199
301
|
throw new errors_1.InvalidOutputError();
|
|
200
302
|
}
|
|
303
|
+
const result = parseResult.data;
|
|
304
|
+
// If tool has UI config, render and add to _meta
|
|
305
|
+
if ((0, ui_1.hasUIConfig)(tool.metadata)) {
|
|
306
|
+
try {
|
|
307
|
+
// Cast scope to Scope to access toolUI and notifications
|
|
308
|
+
const scope = this.scope;
|
|
309
|
+
// Get session info for platform detection from authInfo (already in state from parseInput)
|
|
310
|
+
const { authInfo } = this.state;
|
|
311
|
+
const sessionId = authInfo?.sessionId;
|
|
312
|
+
const requestId = (0, crypto_1.randomUUID)();
|
|
313
|
+
// Get platform type: first check sessionIdPayload (detected from user-agent),
|
|
314
|
+
// then fall back to notification service (detected from MCP clientInfo),
|
|
315
|
+
// finally default to 'openai'
|
|
316
|
+
const platformType = authInfo?.sessionIdPayload?.platformType ??
|
|
317
|
+
(sessionId ? scope.notifications.getPlatformType(sessionId) : undefined) ??
|
|
318
|
+
'openai';
|
|
319
|
+
// Get the serving mode (default to 'inline' for backward compatibility)
|
|
320
|
+
const servingMode = tool.metadata.ui.servingMode ?? 'inline';
|
|
321
|
+
if (servingMode === 'static') {
|
|
322
|
+
// For static mode: return ONLY structured data
|
|
323
|
+
// The static widget was already registered at server startup and advertised in tools/list
|
|
324
|
+
// Widget reads tool output from platform context (e.g., window.openai.toolOutput)
|
|
325
|
+
// NO UI _meta fields needed - the client uses the outputTemplate URI from tools/list
|
|
326
|
+
// Return structured data as JSON text content
|
|
327
|
+
result.content = [
|
|
328
|
+
{
|
|
329
|
+
type: 'text',
|
|
330
|
+
text: safeStringify(rawOutput),
|
|
331
|
+
},
|
|
332
|
+
];
|
|
333
|
+
// Do NOT add any UI _meta fields - widget reads from platform context
|
|
334
|
+
// The outputTemplate URI (ui://widget/{toolName}.html) was already provided in tools/list
|
|
335
|
+
this.logger.verbose('finalize: UI using static mode (structured data only)', {
|
|
336
|
+
tool: tool.metadata.name,
|
|
337
|
+
platform: platformType,
|
|
338
|
+
outputKeys: rawOutput && typeof rawOutput === 'object' && !Array.isArray(rawOutput) ? Object.keys(rawOutput) : [],
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
else if (servingMode === 'hybrid') {
|
|
342
|
+
// For hybrid mode: return structured data + transpiled component code
|
|
343
|
+
// The hybrid shell (React runtime + renderer) was pre-compiled at server startup
|
|
344
|
+
// and advertised via outputTemplate URI in tools/list.
|
|
345
|
+
// The shell dynamically imports the component code from _meta['ui/component']
|
|
346
|
+
// and renders it with toolOutput data from the platform context.
|
|
347
|
+
// Build the component payload with transpiled code
|
|
348
|
+
const componentPayload = scope.toolUI.buildHybridComponentPayload({
|
|
349
|
+
toolName: tool.metadata.name,
|
|
350
|
+
template: tool.metadata.ui.template,
|
|
351
|
+
uiConfig: tool.metadata.ui,
|
|
352
|
+
});
|
|
353
|
+
// Return structured data as JSON text content
|
|
354
|
+
result.content = [
|
|
355
|
+
{
|
|
356
|
+
type: 'text',
|
|
357
|
+
text: safeStringify(rawOutput),
|
|
358
|
+
},
|
|
359
|
+
];
|
|
360
|
+
// Add component payload to _meta for the hybrid shell's dynamic renderer
|
|
361
|
+
if (componentPayload) {
|
|
362
|
+
result._meta = {
|
|
363
|
+
...result._meta,
|
|
364
|
+
'ui/component': componentPayload,
|
|
365
|
+
'ui/type': componentPayload.type,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
this.logger.verbose('finalize: UI using hybrid mode (structured data + component)', {
|
|
369
|
+
tool: tool.metadata.name,
|
|
370
|
+
platform: platformType,
|
|
371
|
+
hasComponent: !!componentPayload,
|
|
372
|
+
componentType: componentPayload?.type,
|
|
373
|
+
componentHash: componentPayload?.hash,
|
|
374
|
+
outputKeys: rawOutput && typeof rawOutput === 'object' && !Array.isArray(rawOutput) ? Object.keys(rawOutput) : [],
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
// For inline mode (default): render HTML with data embedded in each response
|
|
379
|
+
// Use async version to support React component templates via SSR
|
|
380
|
+
const uiResult = await scope.toolUI.renderAndRegisterAsync({
|
|
381
|
+
toolName: tool.metadata.name,
|
|
382
|
+
requestId,
|
|
383
|
+
input: input?.arguments && typeof input.arguments === 'object' && !Array.isArray(input.arguments)
|
|
384
|
+
? input.arguments
|
|
385
|
+
: {},
|
|
386
|
+
output: rawOutput,
|
|
387
|
+
structuredContent: result.structuredContent,
|
|
388
|
+
uiConfig: tool.metadata.ui,
|
|
389
|
+
platformType,
|
|
390
|
+
});
|
|
391
|
+
// Merge UI metadata into result._meta
|
|
392
|
+
result._meta = {
|
|
393
|
+
...result._meta,
|
|
394
|
+
...uiResult.meta,
|
|
395
|
+
};
|
|
396
|
+
// For platforms that support widgets (OpenAI, ext-apps), clear content since widget displays data
|
|
397
|
+
// For Claude and other platforms, keep the text content as they don't support _meta UI fields
|
|
398
|
+
const supportsWidgets = platformType === 'openai' || platformType === 'ext-apps';
|
|
399
|
+
if (supportsWidgets) {
|
|
400
|
+
// Clear content - widget will display from _meta['ui/html']
|
|
401
|
+
result.content = [];
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
// For Claude and other platforms without widget support:
|
|
405
|
+
// Return JSON data + HTML template as artifact hint
|
|
406
|
+
const htmlContent = uiResult?.meta?.['ui/html'];
|
|
407
|
+
if (htmlContent) {
|
|
408
|
+
// Include HTML template as artifact hint for Claude
|
|
409
|
+
// Claude can use this to create an HTML artifact for visual display
|
|
410
|
+
result.content = [
|
|
411
|
+
{
|
|
412
|
+
type: 'text',
|
|
413
|
+
text: `## Data\n\`\`\`json\n${safeStringify(rawOutput, 2)}\n\`\`\`\n\n## Visual Template (for artifact rendering)\n\`\`\`html\n${htmlContent}\n\`\`\``,
|
|
414
|
+
},
|
|
415
|
+
];
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
// Fallback: JSON only
|
|
419
|
+
result.content = [
|
|
420
|
+
{
|
|
421
|
+
type: 'text',
|
|
422
|
+
text: safeStringify(rawOutput, 2),
|
|
423
|
+
},
|
|
424
|
+
];
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
this.logger.verbose('finalize: UI metadata added (inline mode)', {
|
|
428
|
+
tool: tool.metadata.name,
|
|
429
|
+
platform: platformType,
|
|
430
|
+
supportsWidgets,
|
|
431
|
+
contentCleared: supportsWidgets,
|
|
432
|
+
htmlHintIncluded: !supportsWidgets && !!uiResult?.meta?.['ui/html'],
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
catch (error) {
|
|
437
|
+
// UI rendering failure should not fail the tool call
|
|
438
|
+
// Log with full context to help debugging
|
|
439
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
440
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
441
|
+
const uiConfig = tool.metadata.ui;
|
|
442
|
+
this.logger.error('finalize: UI rendering failed', {
|
|
443
|
+
tool: tool.metadata.name,
|
|
444
|
+
error: errorMessage,
|
|
445
|
+
stack: errorStack,
|
|
446
|
+
templateType: uiConfig?.template
|
|
447
|
+
? typeof uiConfig.template === 'function'
|
|
448
|
+
? 'react-component'
|
|
449
|
+
: typeof uiConfig.template === 'string'
|
|
450
|
+
? uiConfig.template.endsWith('.tsx') || uiConfig.template.endsWith('.jsx')
|
|
451
|
+
? 'react-file'
|
|
452
|
+
: 'html-file'
|
|
453
|
+
: 'unknown'
|
|
454
|
+
: 'none',
|
|
455
|
+
hasStructuredContent: result.structuredContent !== undefined,
|
|
456
|
+
structuredContentKeys: result.structuredContent &&
|
|
457
|
+
typeof result.structuredContent === 'object' &&
|
|
458
|
+
result.structuredContent !== null &&
|
|
459
|
+
!Array.isArray(result.structuredContent)
|
|
460
|
+
? Object.keys(result.structuredContent)
|
|
461
|
+
: [],
|
|
462
|
+
});
|
|
463
|
+
// In debug mode, also log to console for immediate visibility
|
|
464
|
+
if (process.env['DEBUG'] || process.env['NODE_ENV'] === 'development') {
|
|
465
|
+
console.error('[FrontMCP] UI Rendering Error:', {
|
|
466
|
+
tool: tool.metadata.name,
|
|
467
|
+
error: errorMessage,
|
|
468
|
+
stack: errorStack,
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
// Log the final result being sent
|
|
474
|
+
this.logger.info('finalize: sending response', {
|
|
475
|
+
tool: tool.metadata.name,
|
|
476
|
+
hasContent: Array.isArray(result.content) && result.content.length > 0,
|
|
477
|
+
contentLength: Array.isArray(result.content) ? result.content.length : 0,
|
|
478
|
+
hasStructuredContent: result.structuredContent !== undefined,
|
|
479
|
+
hasMeta: result._meta !== undefined,
|
|
480
|
+
metaKeys: result._meta ? Object.keys(result._meta) : [],
|
|
481
|
+
isError: result.isError,
|
|
482
|
+
});
|
|
201
483
|
// Respond with the properly formatted MCP result
|
|
202
|
-
this.respond(
|
|
484
|
+
this.respond(result);
|
|
203
485
|
this.logger.verbose('finalize:done');
|
|
204
486
|
}
|
|
205
487
|
};
|
|
@@ -215,6 +497,12 @@ tslib_1.__decorate([
|
|
|
215
497
|
tslib_1.__metadata("design:paramtypes", []),
|
|
216
498
|
tslib_1.__metadata("design:returntype", Promise)
|
|
217
499
|
], CallToolFlow.prototype, "findTool", null);
|
|
500
|
+
tslib_1.__decorate([
|
|
501
|
+
Stage('checkToolAuthorization'),
|
|
502
|
+
tslib_1.__metadata("design:type", Function),
|
|
503
|
+
tslib_1.__metadata("design:paramtypes", []),
|
|
504
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
505
|
+
], CallToolFlow.prototype, "checkToolAuthorization", null);
|
|
218
506
|
tslib_1.__decorate([
|
|
219
507
|
Stage('createToolCallContext'),
|
|
220
508
|
tslib_1.__metadata("design:type", Function),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call-tool.flow.js","sourceRoot":"","sources":["../../../../src/tool/flows/call-tool.flow.ts"],"names":[],"mappings":"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","sourcesContent":["// tools/flows/call-tool.flow.ts\nimport { Flow, FlowBase, FlowHooksOf, FlowPlan, FlowRunOptions, ToolContext, ToolEntry } from '../../common';\nimport { z } from 'zod';\nimport { CallToolRequestSchema, CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';\nimport {\n InvalidMethodError,\n ToolNotFoundError,\n InvalidInputError,\n InvalidOutputError,\n ToolExecutionError,\n} from '../../errors';\n\nconst inputSchema = z.object({\n request: CallToolRequestSchema,\n ctx: z.any(),\n});\n\nconst outputSchema = CallToolResultSchema;\n\nconst stateSchema = z.object({\n input: z\n .object({\n name: z.string().min(1).max(64),\n arguments: z.object({}).passthrough().optional(),\n })\n .passthrough(),\n authInfo: z.any().optional() as z.ZodType<AuthInfo>,\n tool: z.instanceof(ToolEntry),\n toolContext: z.instanceof(ToolContext),\n // Store the raw executed output for plugins to see\n rawOutput: z.any().optional(),\n output: outputSchema,\n});\n\nconst plan = {\n pre: ['parseInput', 'findTool', 'createToolCallContext', 'acquireQuota', 'acquireSemaphore'],\n execute: ['validateInput', 'execute', 'validateOutput'],\n finalize: ['releaseSemaphore', 'releaseQuota', 'finalize'],\n} as const satisfies FlowPlan<string>;\n\ndeclare global {\n interface ExtendFlows {\n 'tools:call-tool': FlowRunOptions<\n CallToolFlow,\n typeof plan,\n typeof inputSchema,\n typeof outputSchema,\n typeof stateSchema\n >;\n }\n}\n\nconst name = 'tools:call-tool' as const;\nconst { Stage } = FlowHooksOf<'tools:call-tool'>(name);\n\n@Flow({\n name,\n plan,\n inputSchema,\n outputSchema,\n access: 'authorized',\n})\nexport default class CallToolFlow extends FlowBase<typeof name> {\n logger = this.scopeLogger.child('CallToolFlow');\n\n @Stage('parseInput')\n async parseInput() {\n this.logger.verbose('parseInput:start');\n\n let method!: string;\n let params: any;\n let ctx: any;\n try {\n const inputData = inputSchema.parse(this.rawInput);\n method = inputData.request.method;\n params = inputData.request.params;\n ctx = inputData.ctx;\n } catch (e) {\n throw new InvalidInputError('Invalid Input', e instanceof z.ZodError ? e.errors : undefined);\n }\n\n if (method !== 'tools/call') {\n this.logger.warn(`parseInput: invalid method \"${method}\"`);\n throw new InvalidMethodError(method, 'tools/call');\n }\n\n // Find the tool early to get its owner ID for hook filtering\n const { name } = params;\n const activeTools = this.scope.tools.getTools(true);\n const tool = activeTools.find((entry) => {\n return entry.fullName === name || entry.name === name;\n });\n\n // Store tool owner ID in the flow input for hook filtering\n if (tool?.owner) {\n (this.rawInput as any)._toolOwnerId = tool.owner.id;\n }\n\n this.state.set({ input: params, authInfo: ctx.authInfo });\n this.logger.verbose('parseInput:done');\n }\n\n @Stage('findTool')\n async findTool() {\n this.logger.verbose('findTool:start');\n // TODO: add support for session based tools\n const activeTools = this.scope.tools.getTools(true);\n this.logger.info(`findTool: discovered ${activeTools.length} active tool(s) (including hidden)`);\n\n const { name } = this.state.required.input;\n const tool = activeTools.find((entry) => {\n return entry.fullName === name || entry.name === name;\n });\n\n if (!tool) {\n this.logger.warn(`findTool: tool \"${name}\" not found`);\n throw new ToolNotFoundError(name);\n }\n\n this.logger = this.logger.child(`CallToolFlow(${name})`);\n this.state.set('tool', tool);\n this.logger.info(`findTool: tool \"${name}\" found`);\n this.logger.verbose('findTool:done');\n }\n\n @Stage('createToolCallContext')\n async createToolCallContext() {\n this.logger.verbose('createToolCallContext:start');\n const { ctx } = this.input;\n const { tool, input } = this.state.required;\n\n try {\n const context = tool.create(input.arguments, ctx);\n const toolHooks = this.scope.hooks.getClsHooks(tool.record.provide).map((hook) => {\n hook.run = async () => {\n return context[hook.metadata.method]();\n };\n return hook;\n });\n\n this.appendContextHooks(toolHooks);\n context.mark('createToolCallContext');\n this.state.set('toolContext', context);\n this.logger.verbose('createToolCallContext:done');\n } catch (error) {\n this.logger.error('createToolCallContext: failed to create context', error);\n throw new ToolExecutionError(tool.metadata.name, error instanceof Error ? error : undefined);\n }\n }\n\n @Stage('acquireQuota')\n async acquireQuota() {\n this.logger.verbose('acquireQuota:start');\n // used for rate limiting\n this.state.toolContext?.mark('acquireQuota');\n this.logger.verbose('acquireQuota:done');\n }\n\n @Stage('acquireSemaphore')\n async acquireSemaphore() {\n this.logger.verbose('acquireSemaphore:start');\n // used for concurrency control\n this.state.toolContext?.mark('acquireSemaphore');\n this.logger.verbose('acquireSemaphore:done');\n }\n\n @Stage('validateInput')\n async validateInput() {\n this.logger.verbose('validateInput:start');\n const { tool, input } = this.state.required;\n const { toolContext } = this.state;\n if (!toolContext) {\n return;\n }\n toolContext.mark('validateInput');\n\n try {\n toolContext.input = tool.parseInput(input);\n this.logger.verbose('validateInput:done');\n } catch (err) {\n if (err instanceof z.ZodError) {\n throw new InvalidInputError('Invalid tool input', err.errors);\n }\n\n this.logger.error('validateInput: failed to parse input', err);\n throw new InvalidInputError('Unknown error occurred when trying to parse input');\n }\n }\n\n @Stage('execute')\n async execute() {\n this.logger.verbose('execute:start');\n const toolContext = this.state.toolContext;\n if (!toolContext) {\n return;\n }\n toolContext.mark('execute');\n\n try {\n toolContext.output = await toolContext.execute(toolContext.input);\n this.logger.verbose('execute:done');\n } catch (error) {\n this.logger.error('execute: tool execution failed', error);\n throw new ToolExecutionError(\n this.state.tool?.metadata.name || 'unknown',\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n @Stage('validateOutput')\n async validateOutput() {\n this.logger.verbose('validateOutput:start');\n const { toolContext } = this.state;\n if (!toolContext) {\n return;\n }\n toolContext.mark('validateOutput');\n\n // Store the RAW output for plugins (cache, PII, etc.) to inspect\n this.state.set('rawOutput', toolContext.output);\n\n this.logger.verbose('validateOutput:done');\n }\n\n @Stage('releaseSemaphore')\n async releaseSemaphore() {\n this.logger.verbose('releaseSemaphore:start');\n // release concurrency control\n this.state.toolContext?.mark('releaseSemaphore');\n this.logger.verbose('releaseSemaphore:done');\n }\n\n @Stage('releaseQuota')\n async releaseQuota() {\n this.logger.verbose('releaseQuota:start');\n // release rate limiting\n this.state.toolContext?.mark('releaseQuota');\n this.logger.verbose('releaseQuota:done');\n }\n\n @Stage('finalize')\n async finalize() {\n this.logger.verbose('finalize:start');\n const { tool, rawOutput } = this.state;\n\n if (!tool) {\n this.logger.error('finalize: tool not found in state');\n throw new ToolExecutionError('unknown', new Error('Tool not found in state'));\n }\n\n if (rawOutput === undefined) {\n this.logger.error('finalize: tool output not found in state');\n throw new ToolExecutionError(tool.metadata.name, new Error('Tool output not found'));\n }\n\n // Parse and construct the MCP-compliant output using safeParseOutput\n const parseResult = tool.safeParseOutput(rawOutput);\n\n if (!parseResult.success) {\n // add support for request id in error messages\n this.logger.error('finalize: output validation failed', {\n tool: tool.metadata.name,\n errors: parseResult.error,\n });\n\n // Use InvalidOutputError, which hides internal details in production\n throw new InvalidOutputError();\n }\n\n // Respond with the properly formatted MCP result\n this.respond(parseResult.data);\n this.logger.verbose('finalize:done');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"call-tool.flow.js","sourceRoot":"","sources":["../../../../src/tool/flows/call-tool.flow.ts"],"names":[],"mappings":";;;AAAA,gCAAgC;AAChC,mCAAoC;AACpC,yCASsB;AACtB,6BAAwB;AACxB,iEAAiG;AAEjG,yCAOsB;AACtB,8BAAoC;AAGpC,MAAM,WAAW,GAAG,OAAC,CAAC,MAAM,CAAC;IAC3B,OAAO,EAAE,gCAAqB;IAC9B,2FAA2F;IAC3F,GAAG,EAAE,OAAC,CAAC,GAAG,EAAE;CACb,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,+BAAoB,CAAC;AAE1C,MAAM,WAAW,GAAG,OAAC,CAAC,MAAM,CAAC;IAC3B,KAAK,EAAE,OAAC,CAAC,WAAW,CAAC;QACnB,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,SAAS,EAAE,OAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;KACxC,CAAC;IACF,QAAQ,EAAE,OAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAyB;IACnD,IAAI,EAAE,OAAC,CAAC,UAAU,CAAC,kBAAS,CAAC;IAC7B,WAAW,EAAE,OAAC,CAAC,UAAU,CAAC,oBAAW,CAAC;IACtC,mDAAmD;IACnD,SAAS,EAAE,OAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC7B,MAAM,EAAE,YAAY;IACpB,2DAA2D;IAC3D,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAEH,MAAM,IAAI,GAAG;IACX,GAAG,EAAE;QACH,YAAY;QACZ,UAAU;QACV,wBAAwB;QACxB,uBAAuB;QACvB,cAAc;QACd,kBAAkB;KACnB;IACD,OAAO,EAAE,CAAC,eAAe,EAAE,SAAS,EAAE,gBAAgB,CAAC;IACvD,QAAQ,EAAE,CAAC,kBAAkB,EAAE,cAAc,EAAE,UAAU,CAAC;CACvB,CAAC;AActC,MAAM,IAAI,GAAG,iBAA0B,CAAC;AACxC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAA,oBAAW,EAAoB,IAAI,CAAC,CAAC;AAEvD;;;GAGG;AACH,MAAM,aAAa,GAAG,CAAC,KAAc,EAAE,KAAc,EAAU,EAAE;IAC/D,MAAM,IAAI,GAAG,IAAI,OAAO,EAAU,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CACnB,KAAK,EACL,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACZ,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;gBAC5C,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,OAAO,YAAY,CAAC;gBACvC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC,EACD,KAAK,CACN,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC,CAAC;IACrE,CAAC;AACH,CAAC,CAAC;AASa,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,iBAAqB;IAC7D,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAG1C,AAAN,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAExC,IAAI,MAAe,CAAC;QACpB,kEAAkE;QAClE,4EAA4E;QAC5E,IAAI,MAAW,CAAC;QAChB,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC;YAClC,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC;YAClC,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC;QACtB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,0BAAiB,CAAC,eAAe,EAAE,CAAC,YAAY,OAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC/F,CAAC;QAED,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,MAAM,GAAG,CAAC,CAAC;YAC3D,MAAM,IAAI,2BAAkB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACrD,CAAC;QAED,6DAA6D;QAC7D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;QACxB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;YACtC,OAAO,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,kDAAkD;QAClD,MAAM,WAAW,GAAG,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAEpC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;QACrF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACzC,CAAC;IAGK,AAAN,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACtC,4CAA4C;QAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,WAAW,CAAC,MAAM,oCAAoC,CAAC,CAAC;QAEjG,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC3C,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;YACtC,OAAO,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,IAAI,aAAa,CAAC,CAAC;YACvD,MAAM,IAAI,0BAAiB,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,IAAI,GAAG,CAAC,CAAC;QACzD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,IAAI,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACvC,CAAC;IAED;;;;OAIG;IAEG,AAAN,KAAK,CAAC,sBAAsB;QAC1B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;QACpD,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAEtC,qDAAqD;QACrD,MAAM,aAAa,GAAG,QAAQ,EAAE,KAAK,EAAE,CAAC,eAAe,CAK1C,CAAC;QAEd,0DAA0D;QAC1D,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,+CAA+C,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QAED,4DAA4D;QAC5D,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,sEAAsE;YACtE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,8DAA8D;QAC9D,MAAM,eAAe,GACnB,aAAa,CAAC,gBAAgB,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,aAAa,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;QAEnG,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,+DAA+D;YAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;YACtD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC;YAE7C,gCAAgC;YAChC,uEAAuE;YACvE,yEAAyE;YACzE,IAAI,eAAe,GAAiC,WAAW,CAAC;YAEhE,IAAI,WAAW,IAAI,IAAA,2BAAkB,EAAC,WAAW,CAAC,EAAE,CAAC;gBACnD,mDAAmD;gBACnD,MAAM,iBAAiB,GAAG,WAAW,CAAC,eAAe,CAAC;gBACtD,IAAI,iBAAiB,EAAE,CAAC;oBACtB,uDAAuD;oBACvD,IAAI,iBAAiB,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;wBACxC,eAAe,GAAG,cAAc,CAAC;oBACnC,CAAC;yBAAM,CAAC;wBACN,eAAe,GAAG,iBAAiB,CAAC,kBAAkB,IAAI,WAAW,CAAC;oBACxE,CAAC;gBACH,CAAC;gBACD,kFAAkF;YACpF,CAAC;YACD,qEAAqE;YAErE,IAAI,eAAe,KAAK,WAAW,IAAI,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC9E,0DAA0D;gBAC1D,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,+CAA+C,KAAK,EAAE,CAAC,CAAC;gBAC5E,OAAO;YACT,CAAC;YAED,kDAAkD;YAClD,MAAM,OAAO,GAAG,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC;YAE1E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2DAA2D,KAAK,GAAG,CAAC,CAAC;YACtF,MAAM,IAAI,mCAA0B,CAAC;gBACnC,KAAK;gBACL,MAAM,EAAE,IAAI,EAAE,QAAQ,IAAI,IAAI,EAAE,IAAI,IAAI,SAAS;gBACjD,OAAO;gBACP,OAAO,EAAE,8BAA8B,KAAK,6BAA6B,IAAI,EAAE,QAAQ,IAAI,IAAI,EAAE,IAAI,GAAG;aACzG,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACK,uBAAuB,CAAC,KAAa,EAAE,MAAc;QAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC1C,OAAO,GAAG,OAAO,wBAAwB,kBAAkB,CAAC,KAAK,CAAC,SAAS,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;IAC1G,CAAC;IAGK,AAAN,KAAK,CAAC,qBAAqB;QACzB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;QACnD,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAC3B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;QAE5C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAClD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC/E,IAAI,CAAC,GAAG,GAAG,KAAK,IAAI,EAAE;oBACpB,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzC,CAAC,CAAC;gBACF,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YACtC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iDAAiD,EAAE,KAAK,CAAC,CAAC;YAC5E,MAAM,IAAI,2BAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;IAGK,AAAN,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC1C,yBAAyB;QACzB,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC3C,CAAC;IAGK,AAAN,KAAK,CAAC,gBAAgB;QACpB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;QAC9C,+BAA+B;QAC/B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC/C,CAAC;IAGK,AAAN,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAC3C,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;QAC5C,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACnC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAElC,IAAI,CAAC;YACH,WAAW,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,OAAC,CAAC,QAAQ,EAAE,CAAC;gBAC9B,MAAM,IAAI,0BAAiB,CAAC,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YAChE,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,GAAG,CAAC,CAAC;YAC/D,MAAM,IAAI,0BAAiB,CAAC,mDAAmD,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAGK,AAAN,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACrC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;QAC3C,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE5B,IAAI,CAAC;YACH,WAAW,CAAC,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAClE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;YAC3D,MAAM,IAAI,2BAAkB,CAC1B,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,SAAS,EAC3C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;QACJ,CAAC;IACH,CAAC;IAGK,AAAN,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC5C,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACnC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAEnC,iEAAiE;QACjE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAEhD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC7C,CAAC;IAGK,AAAN,KAAK,CAAC,gBAAgB;QACpB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;QAC9C,8BAA8B;QAC9B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC/C,CAAC;IAGK,AAAN,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC1C,wBAAwB;QACxB,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC3C,CAAC;IAGK,AAAN,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACtC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAE9C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACvD,MAAM,IAAI,2BAAkB,CAAC,SAAS,EAAE,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAChF,CAAC;QAED,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC9D,MAAM,IAAI,2BAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;QACvF,CAAC;QAED,qEAAqE;QACrE,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAEpD,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YACzB,+CAA+C;YAC/C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,EAAE;gBACtD,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;gBACxB,MAAM,EAAE,WAAW,CAAC,KAAK;aAC1B,CAAC,CAAC;YAEH,qEAAqE;YACrE,MAAM,IAAI,2BAAkB,EAAE,CAAC;QACjC,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC;QAEhC,iDAAiD;QACjD,IAAI,IAAA,gBAAW,EAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,yDAAyD;gBACzD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAc,CAAC;gBAElC,2FAA2F;gBAC3F,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;gBAChC,MAAM,SAAS,GAAG,QAAQ,EAAE,SAAS,CAAC;gBACtC,MAAM,SAAS,GAAW,IAAA,mBAAU,GAAE,CAAC;gBAEvC,8EAA8E;gBAC9E,yEAAyE;gBACzE,8BAA8B;gBAC9B,MAAM,YAAY,GAChB,QAAQ,EAAE,gBAAgB,EAAE,YAAY;oBACxC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBACxE,QAAQ,CAAC;gBAEX,wEAAwE;gBACxE,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,IAAI,QAAQ,CAAC;gBAE7D,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;oBAC7B,+CAA+C;oBAC/C,0FAA0F;oBAC1F,kFAAkF;oBAClF,qFAAqF;oBAErF,8CAA8C;oBAC9C,MAAM,CAAC,OAAO,GAAG;wBACf;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC;yBAC/B;qBACF,CAAC;oBAEF,sEAAsE;oBACtE,0FAA0F;oBAE1F,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,uDAAuD,EAAE;wBAC3E,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;wBACxB,QAAQ,EAAE,YAAY;wBACtB,UAAU,EACR,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;qBACxG,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;oBACpC,sEAAsE;oBACtE,iFAAiF;oBACjF,uDAAuD;oBACvD,8EAA8E;oBAC9E,iEAAiE;oBAEjE,mDAAmD;oBACnD,MAAM,gBAAgB,GAAG,KAAK,CAAC,MAAM,CAAC,2BAA2B,CAAC;wBAChE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;wBAC5B,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ;wBACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;qBAC3B,CAAC,CAAC;oBAEH,8CAA8C;oBAC9C,MAAM,CAAC,OAAO,GAAG;wBACf;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC;yBAC/B;qBACF,CAAC;oBAEF,yEAAyE;oBACzE,IAAI,gBAAgB,EAAE,CAAC;wBACrB,MAAM,CAAC,KAAK,GAAG;4BACb,GAAG,MAAM,CAAC,KAAK;4BACf,cAAc,EAAE,gBAAgB;4BAChC,SAAS,EAAE,gBAAgB,CAAC,IAAI;yBACjC,CAAC;oBACJ,CAAC;oBAED,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,8DAA8D,EAAE;wBAClF,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;wBACxB,QAAQ,EAAE,YAAY;wBACtB,YAAY,EAAE,CAAC,CAAC,gBAAgB;wBAChC,aAAa,EAAE,gBAAgB,EAAE,IAAI;wBACrC,aAAa,EAAE,gBAAgB,EAAE,IAAI;wBACrC,UAAU,EACR,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;qBACxG,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,6EAA6E;oBAC7E,iEAAiE;oBACjE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC;wBACzD,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;wBAC5B,SAAS;wBACT,KAAK,EACH,KAAK,EAAE,SAAS,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC;4BACxF,CAAC,CAAE,KAAK,CAAC,SAAqC;4BAC9C,CAAC,CAAC,EAAE;wBACR,MAAM,EAAE,SAAS;wBACjB,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;wBAC3C,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;wBAC1B,YAAY;qBACb,CAAC,CAAC;oBAEH,sCAAsC;oBACtC,MAAM,CAAC,KAAK,GAAG;wBACb,GAAG,MAAM,CAAC,KAAK;wBACf,GAAG,QAAQ,CAAC,IAAI;qBACjB,CAAC;oBAEF,kGAAkG;oBAClG,8FAA8F;oBAC9F,MAAM,eAAe,GAAG,YAAY,KAAK,QAAQ,IAAI,YAAY,KAAK,UAAU,CAAC;oBAEjF,IAAI,eAAe,EAAE,CAAC;wBACpB,4DAA4D;wBAC5D,MAAM,CAAC,OAAO,GAAG,EAAE,CAAC;oBACtB,CAAC;yBAAM,CAAC;wBACN,yDAAyD;wBACzD,oDAAoD;wBACpD,MAAM,WAAW,GAAG,QAAQ,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC;wBAEhD,IAAI,WAAW,EAAE,CAAC;4BAChB,oDAAoD;4BACpD,oEAAoE;4BACpE,MAAM,CAAC,OAAO,GAAG;gCACf;oCACE,IAAI,EAAE,MAAM;oCACZ,IAAI,EAAE,wBAAwB,aAAa,CACzC,SAAS,EACT,CAAC,CACF,wEAAwE,WAAW,UAAU;iCAC/F;6BACF,CAAC;wBACJ,CAAC;6BAAM,CAAC;4BACN,sBAAsB;4BACtB,MAAM,CAAC,OAAO,GAAG;gCACf;oCACE,IAAI,EAAE,MAAM;oCACZ,IAAI,EAAE,aAAa,CAAC,SAAS,EAAE,CAAC,CAAC;iCAClC;6BACF,CAAC;wBACJ,CAAC;oBACH,CAAC;oBAED,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,2CAA2C,EAAE;wBAC/D,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;wBACxB,QAAQ,EAAE,YAAY;wBACtB,eAAe;wBACf,cAAc,EAAE,eAAe;wBAC/B,gBAAgB,EAAE,CAAC,eAAe,IAAI,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC;qBACpE,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,qDAAqD;gBACrD,0CAA0C;gBAC1C,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC5E,MAAM,UAAU,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;gBACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAElC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE;oBACjD,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;oBACxB,KAAK,EAAE,YAAY;oBACnB,KAAK,EAAE,UAAU;oBACjB,YAAY,EAAE,QAAQ,EAAE,QAAQ;wBAC9B,CAAC,CAAC,OAAO,QAAQ,CAAC,QAAQ,KAAK,UAAU;4BACvC,CAAC,CAAC,iBAAiB;4BACnB,CAAC,CAAC,OAAO,QAAQ,CAAC,QAAQ,KAAK,QAAQ;gCACvC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;oCACxE,CAAC,CAAC,YAAY;oCACd,CAAC,CAAC,WAAW;gCACf,CAAC,CAAC,SAAS;wBACb,CAAC,CAAC,MAAM;oBACV,oBAAoB,EAAE,MAAM,CAAC,iBAAiB,KAAK,SAAS;oBAC5D,qBAAqB,EACnB,MAAM,CAAC,iBAAiB;wBACxB,OAAO,MAAM,CAAC,iBAAiB,KAAK,QAAQ;wBAC5C,MAAM,CAAC,iBAAiB,KAAK,IAAI;wBACjC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC;wBACtC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;wBACvC,CAAC,CAAC,EAAE;iBACT,CAAC,CAAC;gBAEH,8DAA8D;gBAC9D,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,aAAa,EAAE,CAAC;oBACtE,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE;wBAC9C,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;wBACxB,KAAK,EAAE,YAAY;wBACnB,KAAK,EAAE,UAAU;qBAClB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,kCAAkC;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE;YAC7C,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;YACxB,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;YACtE,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACxE,oBAAoB,EAAE,MAAM,CAAC,iBAAiB,KAAK,SAAS;YAC5D,OAAO,EAAE,MAAM,CAAC,KAAK,KAAK,SAAS;YACnC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;YACvD,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAC;QAEH,iDAAiD;QACjD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACvC,CAAC;CACF,CAAA;AAvfO;IADL,KAAK,CAAC,YAAY,CAAC;;;;8CAmCnB;AAGK;IADL,KAAK,CAAC,UAAU,CAAC;;;;4CAqBjB;AAQK;IADL,KAAK,CAAC,wBAAwB,CAAC;;;;0DA4E/B;AAWK;IADL,KAAK,CAAC,uBAAuB,CAAC;;;;yDAuB9B;AAGK;IADL,KAAK,CAAC,cAAc,CAAC;;;;gDAMrB;AAGK;IADL,KAAK,CAAC,kBAAkB,CAAC;;;;oDAMzB;AAGK;IADL,KAAK,CAAC,eAAe,CAAC;;;;iDAqBtB;AAGK;IADL,KAAK,CAAC,SAAS,CAAC;;;;2CAmBhB;AAGK;IADL,KAAK,CAAC,gBAAgB,CAAC;;;;kDAavB;AAGK;IADL,KAAK,CAAC,kBAAkB,CAAC;;;;oDAMzB;AAGK;IADL,KAAK,CAAC,cAAc,CAAC;;;;gDAMrB;AAGK;IADL,KAAK,CAAC,UAAU,CAAC;;;;4CA4OjB;AA1fkB,YAAY;IAPhC,IAAA,aAAI,EAAC;QACJ,IAAI;QACJ,IAAI;QACJ,WAAW;QACX,YAAY;QACZ,MAAM,EAAE,YAAY;KACrB,CAAC;GACmB,YAAY,CA2fhC;kBA3foB,YAAY","sourcesContent":["// tools/flows/call-tool.flow.ts\nimport { randomUUID } from 'crypto';\nimport {\n Flow,\n FlowBase,\n FlowHooksOf,\n FlowPlan,\n FlowRunOptions,\n ToolContext,\n ToolEntry,\n isOrchestratedMode,\n} from '../../common';\nimport { z } from 'zod';\nimport { CallToolRequestSchema, CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';\nimport {\n InvalidMethodError,\n ToolNotFoundError,\n InvalidInputError,\n InvalidOutputError,\n ToolExecutionError,\n AuthorizationRequiredError,\n} from '../../errors';\nimport { hasUIConfig } from '../ui';\nimport { Scope } from '../../scope';\n\nconst inputSchema = z.object({\n request: CallToolRequestSchema,\n // z.any() used because ctx is the MCP SDK's ToolCallExtra type which varies by SDK version\n ctx: z.any(),\n});\n\nconst outputSchema = CallToolResultSchema;\n\nconst stateSchema = z.object({\n input: z.looseObject({\n name: z.string().min(1).max(64),\n arguments: z.looseObject({}).optional(),\n }),\n authInfo: z.any().optional() as z.ZodType<AuthInfo>,\n tool: z.instanceof(ToolEntry),\n toolContext: z.instanceof(ToolContext),\n // Store the raw executed output for plugins to see\n rawOutput: z.any().optional(),\n output: outputSchema,\n // Tool owner ID for hook filtering (set during parseInput)\n _toolOwnerId: z.string().optional(),\n});\n\nconst plan = {\n pre: [\n 'parseInput',\n 'findTool',\n 'checkToolAuthorization',\n 'createToolCallContext',\n 'acquireQuota',\n 'acquireSemaphore',\n ],\n execute: ['validateInput', 'execute', 'validateOutput'],\n finalize: ['releaseSemaphore', 'releaseQuota', 'finalize'],\n} as const satisfies FlowPlan<string>;\n\ndeclare global {\n interface ExtendFlows {\n 'tools:call-tool': FlowRunOptions<\n CallToolFlow,\n typeof plan,\n typeof inputSchema,\n typeof outputSchema,\n typeof stateSchema\n >;\n }\n}\n\nconst name = 'tools:call-tool' as const;\nconst { Stage } = FlowHooksOf<'tools:call-tool'>(name);\n\n/**\n * Safely stringify a value, handling circular references and other edge cases.\n * This prevents tool calls from failing due to serialization errors.\n */\nconst safeStringify = (value: unknown, space?: number): string => {\n const seen = new WeakSet<object>();\n try {\n return JSON.stringify(\n value,\n (_key, val) => {\n if (typeof val === 'object' && val !== null) {\n if (seen.has(val)) return '[Circular]';\n seen.add(val);\n }\n return val;\n },\n space,\n );\n } catch {\n return JSON.stringify({ error: 'Output could not be serialized' });\n }\n};\n\n@Flow({\n name,\n plan,\n inputSchema,\n outputSchema,\n access: 'authorized',\n})\nexport default class CallToolFlow extends FlowBase<typeof name> {\n logger = this.scopeLogger.child('CallToolFlow');\n\n @Stage('parseInput')\n async parseInput() {\n this.logger.verbose('parseInput:start');\n\n let method!: string;\n // NOTE: `any` is intentional - Zod parsing validates these values\n // Using unknown would require redundant type guards after schema validation\n let params: any;\n let ctx: any;\n try {\n const inputData = inputSchema.parse(this.rawInput);\n method = inputData.request.method;\n params = inputData.request.params;\n ctx = inputData.ctx;\n } catch (e) {\n throw new InvalidInputError('Invalid Input', e instanceof z.ZodError ? e.issues : undefined);\n }\n\n if (method !== 'tools/call') {\n this.logger.warn(`parseInput: invalid method \"${method}\"`);\n throw new InvalidMethodError(method, 'tools/call');\n }\n\n // Find the tool early to get its owner ID for hook filtering\n const { name } = params;\n const activeTools = this.scope.tools.getTools(true);\n const tool = activeTools.find((entry) => {\n return entry.fullName === name || entry.name === name;\n });\n\n // Store tool owner ID in state for hook filtering\n const toolOwnerId = tool?.owner?.id;\n\n this.state.set({ input: params, authInfo: ctx.authInfo, _toolOwnerId: toolOwnerId });\n this.logger.verbose('parseInput:done');\n }\n\n @Stage('findTool')\n async findTool() {\n this.logger.verbose('findTool:start');\n // TODO: add support for session based tools\n const activeTools = this.scope.tools.getTools(true);\n this.logger.info(`findTool: discovered ${activeTools.length} active tool(s) (including hidden)`);\n\n const { name } = this.state.required.input;\n const tool = activeTools.find((entry) => {\n return entry.fullName === name || entry.name === name;\n });\n\n if (!tool) {\n this.logger.warn(`findTool: tool \"${name}\" not found`);\n throw new ToolNotFoundError(name);\n }\n\n this.logger = this.logger.child(`CallToolFlow(${name})`);\n this.state.set('tool', tool);\n this.logger.info(`findTool: tool \"${name}\" found`);\n this.logger.verbose('findTool:done');\n }\n\n /**\n * Check if the tool's parent app is authorized.\n * For progressive authorization, tools from unauthorized apps\n * return an AuthorizationRequiredError with an auth_url.\n */\n @Stage('checkToolAuthorization')\n async checkToolAuthorization() {\n this.logger.verbose('checkToolAuthorization:start');\n const { tool, authInfo } = this.state;\n\n // Get authorization from authInfo.extra if available\n const authorization = authInfo?.extra?.['authorization'] as\n | {\n authorizedAppIds?: string[];\n authorizedApps?: Record<string, unknown>;\n }\n | undefined;\n\n // No auth context = public mode, skip authorization check\n if (!authorization) {\n this.logger.verbose('checkToolAuthorization:skip (no auth context)');\n return;\n }\n\n // Get app ID from tool owner (uses existing lineage system)\n const appId = tool?.owner?.id;\n if (!appId) {\n // Tool has no owner = global tool, skip app-level authorization check\n this.logger.verbose('checkToolAuthorization:skip (no owner)');\n return;\n }\n\n // Check if app is authorized using existing session structure\n const isAppAuthorized =\n authorization.authorizedAppIds?.includes(appId) || appId in (authorization.authorizedApps || {});\n\n if (!isAppAuthorized) {\n // Get incremental auth configuration from scope's auth options\n const apps = this.scope.apps.getApps();\n const app = apps.find((a) => a.metadata.id === appId);\n const authOptions = this.scope.auth?.options;\n\n // Determine skippedAppBehavior:\n // 1. Only applies in orchestrated mode with incrementalAuth configured\n // 2. Default to 'anonymous' if not configured (allow anonymous fallback)\n let skippedBehavior: 'anonymous' | 'require-auth' = 'anonymous';\n\n if (authOptions && isOrchestratedMode(authOptions)) {\n // Orchestrated mode - check incrementalAuth config\n const incrementalConfig = authOptions.incrementalAuth;\n if (incrementalConfig) {\n // If incremental auth is disabled, always require auth\n if (incrementalConfig.enabled === false) {\n skippedBehavior = 'require-auth';\n } else {\n skippedBehavior = incrementalConfig.skippedAppBehavior || 'anonymous';\n }\n }\n // If incrementalAuth not configured, default is enabled with 'anonymous' behavior\n }\n // For public/transparent modes, default 'anonymous' behavior applies\n\n if (skippedBehavior === 'anonymous' && app?.metadata?.auth?.mode === 'public') {\n // App supports anonymous - continue with anonymous access\n this.logger.verbose(`checkToolAuthorization: using anonymous for ${appId}`);\n return;\n }\n\n // Require explicit authorization - build auth URL\n const authUrl = this.buildProgressiveAuthUrl(appId, tool?.fullName || '');\n\n this.logger.info(`checkToolAuthorization: authorization required for app \"${appId}\"`);\n throw new AuthorizationRequiredError({\n appId,\n toolId: tool?.fullName || tool?.name || 'unknown',\n authUrl,\n message: `Authorization required for ${appId}. Please authorize to use ${tool?.fullName || tool?.name}.`,\n });\n }\n\n this.logger.verbose('checkToolAuthorization:done');\n }\n\n /**\n * Build the URL for progressive/incremental authorization\n */\n private buildProgressiveAuthUrl(appId: string, toolId: string): string {\n const baseUrl = this.scope.fullPath || '';\n return `${baseUrl}/oauth/authorize?app=${encodeURIComponent(appId)}&tool=${encodeURIComponent(toolId)}`;\n }\n\n @Stage('createToolCallContext')\n async createToolCallContext() {\n this.logger.verbose('createToolCallContext:start');\n const { ctx } = this.input;\n const { tool, input } = this.state.required;\n\n try {\n const context = tool.create(input.arguments, ctx);\n const toolHooks = this.scope.hooks.getClsHooks(tool.record.provide).map((hook) => {\n hook.run = async () => {\n return context[hook.metadata.method]();\n };\n return hook;\n });\n\n this.appendContextHooks(toolHooks);\n context.mark('createToolCallContext');\n this.state.set('toolContext', context);\n this.logger.verbose('createToolCallContext:done');\n } catch (error) {\n this.logger.error('createToolCallContext: failed to create context', error);\n throw new ToolExecutionError(tool.metadata.name, error instanceof Error ? error : undefined);\n }\n }\n\n @Stage('acquireQuota')\n async acquireQuota() {\n this.logger.verbose('acquireQuota:start');\n // used for rate limiting\n this.state.toolContext?.mark('acquireQuota');\n this.logger.verbose('acquireQuota:done');\n }\n\n @Stage('acquireSemaphore')\n async acquireSemaphore() {\n this.logger.verbose('acquireSemaphore:start');\n // used for concurrency control\n this.state.toolContext?.mark('acquireSemaphore');\n this.logger.verbose('acquireSemaphore:done');\n }\n\n @Stage('validateInput')\n async validateInput() {\n this.logger.verbose('validateInput:start');\n const { tool, input } = this.state.required;\n const { toolContext } = this.state;\n if (!toolContext) {\n return;\n }\n toolContext.mark('validateInput');\n\n try {\n toolContext.input = tool.parseInput(input);\n this.logger.verbose('validateInput:done');\n } catch (err) {\n if (err instanceof z.ZodError) {\n throw new InvalidInputError('Invalid tool input', err.issues);\n }\n\n this.logger.error('validateInput: failed to parse input', err);\n throw new InvalidInputError('Unknown error occurred when trying to parse input');\n }\n }\n\n @Stage('execute')\n async execute() {\n this.logger.verbose('execute:start');\n const toolContext = this.state.toolContext;\n if (!toolContext) {\n return;\n }\n toolContext.mark('execute');\n\n try {\n toolContext.output = await toolContext.execute(toolContext.input);\n this.logger.verbose('execute:done');\n } catch (error) {\n this.logger.error('execute: tool execution failed', error);\n throw new ToolExecutionError(\n this.state.tool?.metadata.name || 'unknown',\n error instanceof Error ? error : undefined,\n );\n }\n }\n\n @Stage('validateOutput')\n async validateOutput() {\n this.logger.verbose('validateOutput:start');\n const { toolContext } = this.state;\n if (!toolContext) {\n return;\n }\n toolContext.mark('validateOutput');\n\n // Store the RAW output for plugins (cache, PII, etc.) to inspect\n this.state.set('rawOutput', toolContext.output);\n\n this.logger.verbose('validateOutput:done');\n }\n\n @Stage('releaseSemaphore')\n async releaseSemaphore() {\n this.logger.verbose('releaseSemaphore:start');\n // release concurrency control\n this.state.toolContext?.mark('releaseSemaphore');\n this.logger.verbose('releaseSemaphore:done');\n }\n\n @Stage('releaseQuota')\n async releaseQuota() {\n this.logger.verbose('releaseQuota:start');\n // release rate limiting\n this.state.toolContext?.mark('releaseQuota');\n this.logger.verbose('releaseQuota:done');\n }\n\n @Stage('finalize')\n async finalize() {\n this.logger.verbose('finalize:start');\n const { tool, rawOutput, input } = this.state;\n\n if (!tool) {\n this.logger.error('finalize: tool not found in state');\n throw new ToolExecutionError('unknown', new Error('Tool not found in state'));\n }\n\n if (rawOutput === undefined) {\n this.logger.error('finalize: tool output not found in state');\n throw new ToolExecutionError(tool.metadata.name, new Error('Tool output not found'));\n }\n\n // Parse and construct the MCP-compliant output using safeParseOutput\n const parseResult = tool.safeParseOutput(rawOutput);\n\n if (!parseResult.success) {\n // add support for request id in error messages\n this.logger.error('finalize: output validation failed', {\n tool: tool.metadata.name,\n errors: parseResult.error,\n });\n\n // Use InvalidOutputError, which hides internal details in production\n throw new InvalidOutputError();\n }\n\n const result = parseResult.data;\n\n // If tool has UI config, render and add to _meta\n if (hasUIConfig(tool.metadata)) {\n try {\n // Cast scope to Scope to access toolUI and notifications\n const scope = this.scope as Scope;\n\n // Get session info for platform detection from authInfo (already in state from parseInput)\n const { authInfo } = this.state;\n const sessionId = authInfo?.sessionId;\n const requestId: string = randomUUID();\n\n // Get platform type: first check sessionIdPayload (detected from user-agent),\n // then fall back to notification service (detected from MCP clientInfo),\n // finally default to 'openai'\n const platformType =\n authInfo?.sessionIdPayload?.platformType ??\n (sessionId ? scope.notifications.getPlatformType(sessionId) : undefined) ??\n 'openai';\n\n // Get the serving mode (default to 'inline' for backward compatibility)\n const servingMode = tool.metadata.ui.servingMode ?? 'inline';\n\n if (servingMode === 'static') {\n // For static mode: return ONLY structured data\n // The static widget was already registered at server startup and advertised in tools/list\n // Widget reads tool output from platform context (e.g., window.openai.toolOutput)\n // NO UI _meta fields needed - the client uses the outputTemplate URI from tools/list\n\n // Return structured data as JSON text content\n result.content = [\n {\n type: 'text',\n text: safeStringify(rawOutput),\n },\n ];\n\n // Do NOT add any UI _meta fields - widget reads from platform context\n // The outputTemplate URI (ui://widget/{toolName}.html) was already provided in tools/list\n\n this.logger.verbose('finalize: UI using static mode (structured data only)', {\n tool: tool.metadata.name,\n platform: platformType,\n outputKeys:\n rawOutput && typeof rawOutput === 'object' && !Array.isArray(rawOutput) ? Object.keys(rawOutput) : [],\n });\n } else if (servingMode === 'hybrid') {\n // For hybrid mode: return structured data + transpiled component code\n // The hybrid shell (React runtime + renderer) was pre-compiled at server startup\n // and advertised via outputTemplate URI in tools/list.\n // The shell dynamically imports the component code from _meta['ui/component']\n // and renders it with toolOutput data from the platform context.\n\n // Build the component payload with transpiled code\n const componentPayload = scope.toolUI.buildHybridComponentPayload({\n toolName: tool.metadata.name,\n template: tool.metadata.ui.template,\n uiConfig: tool.metadata.ui,\n });\n\n // Return structured data as JSON text content\n result.content = [\n {\n type: 'text',\n text: safeStringify(rawOutput),\n },\n ];\n\n // Add component payload to _meta for the hybrid shell's dynamic renderer\n if (componentPayload) {\n result._meta = {\n ...result._meta,\n 'ui/component': componentPayload,\n 'ui/type': componentPayload.type,\n };\n }\n\n this.logger.verbose('finalize: UI using hybrid mode (structured data + component)', {\n tool: tool.metadata.name,\n platform: platformType,\n hasComponent: !!componentPayload,\n componentType: componentPayload?.type,\n componentHash: componentPayload?.hash,\n outputKeys:\n rawOutput && typeof rawOutput === 'object' && !Array.isArray(rawOutput) ? Object.keys(rawOutput) : [],\n });\n } else {\n // For inline mode (default): render HTML with data embedded in each response\n // Use async version to support React component templates via SSR\n const uiResult = await scope.toolUI.renderAndRegisterAsync({\n toolName: tool.metadata.name,\n requestId,\n input:\n input?.arguments && typeof input.arguments === 'object' && !Array.isArray(input.arguments)\n ? (input.arguments as Record<string, unknown>)\n : {},\n output: rawOutput,\n structuredContent: result.structuredContent,\n uiConfig: tool.metadata.ui,\n platformType,\n });\n\n // Merge UI metadata into result._meta\n result._meta = {\n ...result._meta,\n ...uiResult.meta,\n };\n\n // For platforms that support widgets (OpenAI, ext-apps), clear content since widget displays data\n // For Claude and other platforms, keep the text content as they don't support _meta UI fields\n const supportsWidgets = platformType === 'openai' || platformType === 'ext-apps';\n\n if (supportsWidgets) {\n // Clear content - widget will display from _meta['ui/html']\n result.content = [];\n } else {\n // For Claude and other platforms without widget support:\n // Return JSON data + HTML template as artifact hint\n const htmlContent = uiResult?.meta?.['ui/html'];\n\n if (htmlContent) {\n // Include HTML template as artifact hint for Claude\n // Claude can use this to create an HTML artifact for visual display\n result.content = [\n {\n type: 'text',\n text: `## Data\\n\\`\\`\\`json\\n${safeStringify(\n rawOutput,\n 2,\n )}\\n\\`\\`\\`\\n\\n## Visual Template (for artifact rendering)\\n\\`\\`\\`html\\n${htmlContent}\\n\\`\\`\\``,\n },\n ];\n } else {\n // Fallback: JSON only\n result.content = [\n {\n type: 'text',\n text: safeStringify(rawOutput, 2),\n },\n ];\n }\n }\n\n this.logger.verbose('finalize: UI metadata added (inline mode)', {\n tool: tool.metadata.name,\n platform: platformType,\n supportsWidgets,\n contentCleared: supportsWidgets,\n htmlHintIncluded: !supportsWidgets && !!uiResult?.meta?.['ui/html'],\n });\n }\n } catch (error) {\n // UI rendering failure should not fail the tool call\n // Log with full context to help debugging\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorStack = error instanceof Error ? error.stack : undefined;\n const uiConfig = tool.metadata.ui;\n\n this.logger.error('finalize: UI rendering failed', {\n tool: tool.metadata.name,\n error: errorMessage,\n stack: errorStack,\n templateType: uiConfig?.template\n ? typeof uiConfig.template === 'function'\n ? 'react-component'\n : typeof uiConfig.template === 'string'\n ? uiConfig.template.endsWith('.tsx') || uiConfig.template.endsWith('.jsx')\n ? 'react-file'\n : 'html-file'\n : 'unknown'\n : 'none',\n hasStructuredContent: result.structuredContent !== undefined,\n structuredContentKeys:\n result.structuredContent &&\n typeof result.structuredContent === 'object' &&\n result.structuredContent !== null &&\n !Array.isArray(result.structuredContent)\n ? Object.keys(result.structuredContent)\n : [],\n });\n\n // In debug mode, also log to console for immediate visibility\n if (process.env['DEBUG'] || process.env['NODE_ENV'] === 'development') {\n console.error('[FrontMCP] UI Rendering Error:', {\n tool: tool.metadata.name,\n error: errorMessage,\n stack: errorStack,\n });\n }\n }\n }\n\n // Log the final result being sent\n this.logger.info('finalize: sending response', {\n tool: tool.metadata.name,\n hasContent: Array.isArray(result.content) && result.content.length > 0,\n contentLength: Array.isArray(result.content) ? result.content.length : 0,\n hasStructuredContent: result.structuredContent !== undefined,\n hasMeta: result._meta !== undefined,\n metaKeys: result._meta ? Object.keys(result._meta) : [],\n isError: result.isError,\n });\n\n // Respond with the properly formatted MCP result\n this.respond(result);\n this.logger.verbose('finalize:done');\n }\n}\n"]}
|