skybridge 0.0.0-dev.f0904af → 0.0.0-dev.f0c826f
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/LICENSE +21 -674
- package/README.md +123 -97
- package/bin/run.js +5 -0
- package/dist/cli/detect-port.d.ts +18 -0
- package/dist/cli/detect-port.js +61 -0
- package/dist/cli/detect-port.js.map +1 -0
- package/dist/cli/header.d.ts +4 -0
- package/dist/cli/header.js +6 -0
- package/dist/cli/header.js.map +1 -0
- package/dist/cli/run-command.d.ts +2 -0
- package/dist/cli/run-command.js +43 -0
- package/dist/cli/run-command.js.map +1 -0
- package/dist/cli/telemetry.d.ts +7 -0
- package/dist/cli/telemetry.js +123 -0
- package/dist/cli/telemetry.js.map +1 -0
- package/dist/cli/tunnel-control-server.d.ts +9 -0
- package/dist/cli/tunnel-control-server.js +31 -0
- package/dist/cli/tunnel-control-server.js.map +1 -0
- package/dist/cli/tunnel-control-server.test.js +39 -0
- package/dist/cli/tunnel-control-server.test.js.map +1 -0
- package/dist/cli/tunnel-handler.d.ts +3 -0
- package/dist/cli/tunnel-handler.js +48 -0
- package/dist/cli/tunnel-handler.js.map +1 -0
- package/dist/cli/tunnel-handler.test.js +105 -0
- package/dist/cli/tunnel-handler.test.js.map +1 -0
- package/dist/cli/tunnel.d.ts +57 -0
- package/dist/cli/tunnel.js +154 -0
- package/dist/cli/tunnel.js.map +1 -0
- package/dist/cli/tunnel.test.d.ts +1 -0
- package/dist/cli/tunnel.test.js +190 -0
- package/dist/cli/tunnel.test.js.map +1 -0
- package/dist/cli/types.d.ts +5 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/use-execute-steps.d.ts +11 -0
- package/dist/cli/use-execute-steps.js +36 -0
- package/dist/cli/use-execute-steps.js.map +1 -0
- package/dist/cli/use-messages.d.ts +3 -0
- package/dist/cli/use-messages.js +11 -0
- package/dist/cli/use-messages.js.map +1 -0
- package/dist/cli/use-nodemon.d.ts +2 -0
- package/dist/cli/use-nodemon.js +73 -0
- package/dist/cli/use-nodemon.js.map +1 -0
- package/dist/cli/use-open-browser.d.ts +1 -0
- package/dist/cli/use-open-browser.js +44 -0
- package/dist/cli/use-open-browser.js.map +1 -0
- package/dist/cli/use-tunnel.d.ts +14 -0
- package/dist/cli/use-tunnel.js +131 -0
- package/dist/cli/use-tunnel.js.map +1 -0
- package/dist/cli/use-typescript-check.d.ts +9 -0
- package/dist/cli/use-typescript-check.js +94 -0
- package/dist/cli/use-typescript-check.js.map +1 -0
- package/dist/commands/build.d.ts +9 -0
- package/dist/commands/build.js +102 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/create.d.ts +9 -0
- package/dist/commands/create.js +30 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/dev.d.ts +12 -0
- package/dist/commands/dev.js +80 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/start.d.ts +9 -0
- package/dist/commands/start.js +49 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/telemetry/disable.d.ts +5 -0
- package/dist/commands/telemetry/disable.js +14 -0
- package/dist/commands/telemetry/disable.js.map +1 -0
- package/dist/commands/telemetry/enable.d.ts +5 -0
- package/dist/commands/telemetry/enable.js +14 -0
- package/dist/commands/telemetry/enable.js.map +1 -0
- package/dist/commands/telemetry/status.d.ts +5 -0
- package/dist/commands/telemetry/status.js +14 -0
- package/dist/commands/telemetry/status.js.map +1 -0
- package/dist/server/asset-base-url-transform-plugin.d.ts +11 -0
- package/dist/server/asset-base-url-transform-plugin.js +48 -0
- package/dist/server/asset-base-url-transform-plugin.js.map +1 -0
- package/dist/server/asset-base-url-transform-plugin.test.d.ts +1 -0
- package/dist/server/asset-base-url-transform-plugin.test.js +134 -0
- package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -0
- package/dist/server/auth.d.ts +20 -0
- package/dist/server/auth.js +28 -0
- package/dist/server/auth.js.map +1 -0
- package/dist/server/content-helpers.d.ts +27 -0
- package/dist/server/content-helpers.js +46 -0
- package/dist/server/content-helpers.js.map +1 -0
- package/dist/server/content-helpers.test.d.ts +1 -0
- package/dist/server/content-helpers.test.js +70 -0
- package/dist/server/content-helpers.test.js.map +1 -0
- package/dist/server/express.d.ts +11 -0
- package/dist/server/express.js +101 -0
- package/dist/server/express.js.map +1 -0
- package/dist/server/express.test.d.ts +1 -0
- package/dist/server/express.test.js +430 -0
- package/dist/server/express.test.js.map +1 -0
- package/dist/server/file-ref.d.ts +8 -0
- package/dist/server/file-ref.js +8 -0
- package/dist/server/file-ref.js.map +1 -0
- package/dist/server/index.d.ts +8 -0
- package/dist/server/index.js +6 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/inferUtilityTypes.d.ts +64 -0
- package/dist/server/inferUtilityTypes.js +2 -0
- package/dist/server/inferUtilityTypes.js.map +1 -0
- package/dist/server/metric.d.ts +14 -0
- package/dist/server/metric.js +62 -0
- package/dist/server/metric.js.map +1 -0
- package/dist/server/middleware.d.ts +124 -0
- package/dist/server/middleware.js +93 -0
- package/dist/server/middleware.js.map +1 -0
- package/dist/server/middleware.test-d.d.ts +1 -0
- package/dist/server/middleware.test-d.js +75 -0
- package/dist/server/middleware.test-d.js.map +1 -0
- package/dist/server/middleware.test.d.ts +1 -0
- package/dist/server/middleware.test.js +493 -0
- package/dist/server/middleware.test.js.map +1 -0
- package/dist/server/server.d.ts +246 -0
- package/dist/server/server.js +476 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/templateHelper.d.ts +16 -0
- package/dist/server/templateHelper.js +11 -0
- package/dist/server/templateHelper.js.map +1 -0
- package/dist/server/templates.generated.d.ts +4 -0
- package/dist/server/templates.generated.js +47 -0
- package/dist/server/templates.generated.js.map +1 -0
- package/dist/server/tunnel-proxy-router.d.ts +7 -0
- package/dist/server/tunnel-proxy-router.js +110 -0
- package/dist/server/tunnel-proxy-router.js.map +1 -0
- package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
- package/dist/server/tunnel-proxy-router.test.js +229 -0
- package/dist/server/tunnel-proxy-router.test.js.map +1 -0
- package/dist/server/viewsDevServer.d.ts +14 -0
- package/dist/server/viewsDevServer.js +45 -0
- package/dist/server/viewsDevServer.js.map +1 -0
- package/dist/test/utils.d.ts +127 -0
- package/dist/test/utils.js +247 -0
- package/dist/test/utils.js.map +1 -0
- package/dist/test/view.test.d.ts +1 -0
- package/dist/test/view.test.js +523 -0
- package/dist/test/view.test.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/web/bridges/apps-sdk/adaptor.d.ts +26 -0
- package/dist/web/bridges/apps-sdk/adaptor.js +108 -0
- package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -0
- package/dist/web/bridges/apps-sdk/bridge.d.ts +10 -0
- package/dist/web/bridges/apps-sdk/bridge.js +46 -0
- package/dist/web/bridges/apps-sdk/bridge.js.map +1 -0
- package/dist/web/bridges/apps-sdk/index.d.ts +5 -0
- package/dist/web/bridges/apps-sdk/index.js +5 -0
- package/dist/web/bridges/apps-sdk/index.js.map +1 -0
- package/dist/web/bridges/apps-sdk/types.d.ts +133 -0
- package/dist/web/bridges/apps-sdk/types.js.map +1 -0
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +2 -0
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +7 -0
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -0
- package/dist/web/bridges/get-adaptor.d.ts +2 -0
- package/dist/web/bridges/get-adaptor.js +8 -0
- package/dist/web/bridges/get-adaptor.js.map +1 -0
- package/dist/web/bridges/index.d.ts +5 -0
- package/dist/web/bridges/index.js +6 -0
- package/dist/web/bridges/index.js.map +1 -0
- package/dist/web/bridges/mcp-app/adaptor.d.ts +50 -0
- package/dist/web/bridges/mcp-app/adaptor.js +271 -0
- package/dist/web/bridges/mcp-app/adaptor.js.map +1 -0
- package/dist/web/bridges/mcp-app/bridge.d.ts +26 -0
- package/dist/web/bridges/mcp-app/bridge.js +102 -0
- package/dist/web/bridges/mcp-app/bridge.js.map +1 -0
- package/dist/web/bridges/mcp-app/index.d.ts +4 -0
- package/dist/web/bridges/mcp-app/index.js +4 -0
- package/dist/web/bridges/mcp-app/index.js.map +1 -0
- package/dist/web/bridges/mcp-app/types.d.ts +8 -0
- package/dist/web/bridges/mcp-app/types.js +2 -0
- package/dist/web/bridges/mcp-app/types.js.map +1 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +7 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js +7 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.d.ts +1 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +26 -0
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -0
- package/dist/web/bridges/types.d.ts +117 -0
- package/dist/web/bridges/types.js +2 -0
- package/dist/web/bridges/types.js.map +1 -0
- package/dist/web/bridges/use-host-context.d.ts +2 -0
- package/dist/web/bridges/use-host-context.js +8 -0
- package/dist/web/bridges/use-host-context.js.map +1 -0
- package/dist/web/components/modal-provider.d.ts +4 -0
- package/dist/web/components/modal-provider.js +45 -0
- package/dist/web/components/modal-provider.js.map +1 -0
- package/dist/web/create-store.d.ts +3 -0
- package/dist/web/create-store.js +38 -0
- package/dist/web/create-store.js.map +1 -0
- package/dist/web/create-store.test.d.ts +1 -0
- package/dist/web/create-store.test.js +129 -0
- package/dist/web/create-store.test.js.map +1 -0
- package/dist/web/data-llm.d.ts +14 -0
- package/dist/web/data-llm.js +72 -0
- package/dist/web/data-llm.js.map +1 -0
- package/dist/web/data-llm.test.d.ts +1 -0
- package/dist/web/data-llm.test.js +142 -0
- package/dist/web/data-llm.test.js.map +1 -0
- package/dist/web/generate-helpers.d.ts +118 -0
- package/dist/web/generate-helpers.js +113 -0
- package/dist/web/generate-helpers.js.map +1 -0
- package/dist/web/generate-helpers.test-d.d.ts +1 -0
- package/dist/web/generate-helpers.test-d.js +209 -0
- package/dist/web/generate-helpers.test-d.js.map +1 -0
- package/dist/web/generate-helpers.test.d.ts +1 -0
- package/dist/web/generate-helpers.test.js +17 -0
- package/dist/web/generate-helpers.test.js.map +1 -0
- package/dist/web/helpers/state.d.ts +7 -0
- package/dist/web/helpers/state.js +45 -0
- package/dist/web/helpers/state.js.map +1 -0
- package/dist/web/helpers/state.test.d.ts +1 -0
- package/dist/web/helpers/state.test.js +53 -0
- package/dist/web/helpers/state.test.js.map +1 -0
- package/dist/web/hooks/index.d.ts +13 -0
- package/dist/web/hooks/index.js +14 -0
- package/dist/web/hooks/index.js.map +1 -0
- package/dist/web/hooks/test/utils.d.ts +16 -0
- package/dist/web/hooks/test/utils.js +64 -0
- package/dist/web/hooks/test/utils.js.map +1 -0
- package/dist/web/hooks/use-call-tool.d.ts +101 -0
- package/dist/web/hooks/use-call-tool.js +68 -0
- package/dist/web/hooks/use-call-tool.js.map +1 -0
- package/dist/web/hooks/use-call-tool.test-d.d.ts +1 -0
- package/dist/web/hooks/use-call-tool.test-d.js +104 -0
- package/dist/web/hooks/use-call-tool.test-d.js.map +1 -0
- package/dist/web/hooks/use-call-tool.test.d.ts +1 -0
- package/dist/web/hooks/use-call-tool.test.js +211 -0
- package/dist/web/hooks/use-call-tool.test.js.map +1 -0
- package/dist/web/hooks/use-display-mode.d.ts +4 -0
- package/dist/web/hooks/use-display-mode.js +9 -0
- package/dist/web/hooks/use-display-mode.js.map +1 -0
- package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
- package/dist/web/hooks/use-display-mode.test-d.js +8 -0
- package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
- package/dist/web/hooks/use-display-mode.test.d.ts +1 -0
- package/dist/web/hooks/use-display-mode.test.js +41 -0
- package/dist/web/hooks/use-display-mode.test.js.map +1 -0
- package/dist/web/hooks/use-files.d.ts +7 -0
- package/dist/web/hooks/use-files.js +10 -0
- package/dist/web/hooks/use-files.js.map +1 -0
- package/dist/web/hooks/use-files.test.d.ts +1 -0
- package/dist/web/hooks/use-files.test.js +54 -0
- package/dist/web/hooks/use-files.test.js.map +1 -0
- package/dist/web/hooks/use-layout.d.ts +22 -0
- package/dist/web/hooks/use-layout.js +23 -0
- package/dist/web/hooks/use-layout.js.map +1 -0
- package/dist/web/hooks/use-layout.test.d.ts +1 -0
- package/dist/web/hooks/use-layout.test.js +96 -0
- package/dist/web/hooks/use-layout.test.js.map +1 -0
- package/dist/web/hooks/use-open-external.d.ts +3 -0
- package/dist/web/hooks/use-open-external.js +8 -0
- package/dist/web/hooks/use-open-external.js.map +1 -0
- package/dist/web/hooks/use-open-external.test.d.ts +1 -0
- package/dist/web/hooks/use-open-external.test.js +65 -0
- package/dist/web/hooks/use-open-external.test.js.map +1 -0
- package/dist/web/hooks/use-request-close.d.ts +2 -0
- package/dist/web/hooks/use-request-close.js +8 -0
- package/dist/web/hooks/use-request-close.js.map +1 -0
- package/dist/web/hooks/use-request-close.test.d.ts +1 -0
- package/dist/web/hooks/use-request-close.test.js +52 -0
- package/dist/web/hooks/use-request-close.test.js.map +1 -0
- package/dist/web/hooks/use-request-modal.d.ts +9 -0
- package/dist/web/hooks/use-request-modal.js +16 -0
- package/dist/web/hooks/use-request-modal.js.map +1 -0
- package/dist/web/hooks/use-request-modal.test.d.ts +1 -0
- package/dist/web/hooks/use-request-modal.test.js +61 -0
- package/dist/web/hooks/use-request-modal.test.js.map +1 -0
- package/dist/web/hooks/use-request-size.d.ts +3 -0
- package/dist/web/hooks/use-request-size.js +8 -0
- package/dist/web/hooks/use-request-size.js.map +1 -0
- package/dist/web/hooks/use-request-size.test.d.ts +1 -0
- package/dist/web/hooks/use-request-size.test.js +65 -0
- package/dist/web/hooks/use-request-size.test.js.map +1 -0
- package/dist/web/hooks/use-send-follow-up-message.d.ts +2 -0
- package/dist/web/hooks/use-send-follow-up-message.js +8 -0
- package/dist/web/hooks/use-send-follow-up-message.js.map +1 -0
- package/dist/web/hooks/use-set-open-in-app-url.d.ts +1 -0
- package/dist/web/hooks/use-set-open-in-app-url.js +8 -0
- package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -0
- package/dist/web/hooks/use-set-open-in-app-url.test.d.ts +1 -0
- package/dist/web/hooks/use-set-open-in-app-url.test.js +43 -0
- package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -0
- package/dist/web/hooks/use-tool-info.d.ts +36 -0
- package/dist/web/hooks/use-tool-info.js +26 -0
- package/dist/web/hooks/use-tool-info.js.map +1 -0
- package/dist/web/hooks/use-tool-info.test-d.d.ts +1 -0
- package/dist/web/hooks/use-tool-info.test-d.js +109 -0
- package/dist/web/hooks/use-tool-info.test-d.js.map +1 -0
- package/dist/web/hooks/use-tool-info.test.d.ts +1 -0
- package/dist/web/hooks/use-tool-info.test.js +130 -0
- package/dist/web/hooks/use-tool-info.test.js.map +1 -0
- package/dist/web/hooks/use-user.d.ts +18 -0
- package/dist/web/hooks/use-user.js +35 -0
- package/dist/web/hooks/use-user.js.map +1 -0
- package/dist/web/hooks/use-user.test.d.ts +1 -0
- package/dist/web/hooks/use-user.test.js +122 -0
- package/dist/web/hooks/use-user.test.js.map +1 -0
- package/dist/web/hooks/use-view-state.d.ts +4 -0
- package/dist/web/hooks/use-view-state.js +32 -0
- package/dist/web/hooks/use-view-state.js.map +1 -0
- package/dist/web/hooks/use-view-state.test.d.ts +1 -0
- package/dist/web/hooks/use-view-state.test.js +177 -0
- package/dist/web/hooks/use-view-state.test.js.map +1 -0
- package/dist/web/index.d.ts +7 -0
- package/dist/web/index.js +8 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/mount-view.d.ts +1 -0
- package/dist/web/mount-view.js +27 -0
- package/dist/web/mount-view.js.map +1 -0
- package/dist/web/plugin/data-llm.test.d.ts +1 -0
- package/dist/web/plugin/data-llm.test.js +81 -0
- package/dist/web/plugin/data-llm.test.js.map +1 -0
- package/dist/web/plugin/plugin.d.ts +5 -0
- package/dist/web/plugin/plugin.js +163 -0
- package/dist/web/plugin/plugin.js.map +1 -0
- package/dist/web/plugin/scan-views.d.ts +16 -0
- package/dist/web/plugin/scan-views.js +88 -0
- package/dist/web/plugin/scan-views.js.map +1 -0
- package/dist/web/plugin/scan-views.test.d.ts +1 -0
- package/dist/web/plugin/scan-views.test.js +99 -0
- package/dist/web/plugin/scan-views.test.js.map +1 -0
- package/dist/web/plugin/transform-data-llm.d.ts +12 -0
- package/dist/web/plugin/transform-data-llm.js +96 -0
- package/dist/web/plugin/transform-data-llm.js.map +1 -0
- package/dist/web/plugin/transform-data-llm.test.d.ts +1 -0
- package/dist/web/plugin/transform-data-llm.test.js +81 -0
- package/dist/web/plugin/transform-data-llm.test.js.map +1 -0
- package/dist/web/plugin/validate-view.d.ts +1 -0
- package/dist/web/plugin/validate-view.js +9 -0
- package/dist/web/plugin/validate-view.js.map +1 -0
- package/dist/web/plugin/validate-view.test.d.ts +1 -0
- package/dist/web/plugin/validate-view.test.js +24 -0
- package/dist/web/plugin/validate-view.test.js.map +1 -0
- package/dist/web/proxy.d.ts +1 -0
- package/dist/web/proxy.js +52 -0
- package/dist/web/proxy.js.map +1 -0
- package/dist/web/types.d.ts +16 -0
- package/dist/web/types.js +2 -0
- package/dist/web/types.js.map +1 -0
- package/package.json +87 -31
- package/tsconfig.base.json +33 -0
- package/dist/src/server/index.d.ts +0 -2
- package/dist/src/server/index.js +0 -3
- package/dist/src/server/index.js.map +0 -1
- package/dist/src/server/server.d.ts +0 -12
- package/dist/src/server/server.js +0 -45
- package/dist/src/server/server.js.map +0 -1
- package/dist/src/server/templateHelper.d.ts +0 -14
- package/dist/src/server/templateHelper.js +0 -37
- package/dist/src/server/templateHelper.js.map +0 -1
- package/dist/src/server/templates/development.hbs +0 -12
- package/dist/src/server/templates/production.hbs +0 -6
- package/dist/src/server/widgetsDevServer.d.ts +0 -12
- package/dist/src/server/widgetsDevServer.js +0 -39
- package/dist/src/server/widgetsDevServer.js.map +0 -1
- package/dist/src/test/setup.js +0 -9
- package/dist/src/test/setup.js.map +0 -1
- package/dist/src/test/utils.d.ts +0 -28
- package/dist/src/test/utils.js +0 -43
- package/dist/src/test/utils.js.map +0 -1
- package/dist/src/test/widget.test.js +0 -69
- package/dist/src/test/widget.test.js.map +0 -1
- package/dist/src/web/index.d.ts +0 -5
- package/dist/src/web/index.js +0 -6
- package/dist/src/web/index.js.map +0 -1
- package/dist/src/web/mount-widget.d.ts +0 -1
- package/dist/src/web/mount-widget.js +0 -14
- package/dist/src/web/mount-widget.js.map +0 -1
- package/dist/src/web/plugin.d.ts +0 -2
- package/dist/src/web/plugin.js +0 -31
- package/dist/src/web/plugin.js.map +0 -1
- package/dist/src/web/types.d.ts +0 -95
- package/dist/src/web/types.js.map +0 -1
- package/dist/src/web/use-openai-global.d.ts +0 -2
- package/dist/src/web/use-openai-global.js +0 -21
- package/dist/src/web/use-openai-global.js.map +0 -1
- package/dist/src/web/use-tool-output.d.ts +0 -3
- package/dist/src/web/use-tool-output.js +0 -5
- package/dist/src/web/use-tool-output.js.map +0 -1
- package/dist/vitest.config.d.ts +0 -2
- package/dist/vitest.config.js +0 -9
- package/dist/vitest.config.js.map +0 -1
- /package/dist/{src/test/setup.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
- /package/dist/{src/test/widget.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
- /package/dist/{src/web → web/bridges/apps-sdk}/types.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-helpers.test-d.js","sourceRoot":"","sources":["../../src/web/generate-helpers.test-d.ts"],"names":[],"mappings":"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","sourcesContent":["import { expectTypeOf, test } from \"vitest\";\nimport type {\n InferTools,\n ToolInput,\n ToolNames,\n ToolOutput,\n ToolResponseMetadata,\n} from \"../server/index.js\";\nimport { createInterfaceTestServer, createTestServer } from \"../test/utils.js\";\nimport { generateHelpers } from \"./generate-helpers.js\";\n\nconst server = createTestServer();\ntype TestServer = typeof server;\n\nconst interfaceServer = createInterfaceTestServer();\ntype InterfaceTestServer = typeof interfaceServer;\n\ntest(\"InferTools extracts the tool registry type (views + registerTool)\", () => {\n type Tools = InferTools<TestServer>;\n\n expectTypeOf<Tools>().toHaveProperty(\"search-trip\");\n expectTypeOf<Tools>().toHaveProperty(\"get-trip-details\");\n expectTypeOf<Tools>().toHaveProperty(\"no-input-view\");\n expectTypeOf<Tools>().toHaveProperty(\"calculate-price\");\n expectTypeOf<Tools>().toHaveProperty(\"inferred-output-view\");\n expectTypeOf<Tools>().toHaveProperty(\"inferred-tool\");\n expectTypeOf<Tools>().toHaveProperty(\"view-with-metadata\");\n expectTypeOf<Tools>().toHaveProperty(\"tool-with-metadata\");\n expectTypeOf<Tools>().toHaveProperty(\"view-with-mixed-returns\");\n});\n\ntest(\"ToolNames returns a union of tool name literals (views + registerTool)\", () => {\n type Names = ToolNames<TestServer>;\n\n expectTypeOf<Names>().toEqualTypeOf<\n | \"search-trip\"\n | \"get-trip-details\"\n | \"no-input-view\"\n | \"calculate-price\"\n | \"inferred-output-view\"\n | \"inferred-tool\"\n | \"view-with-metadata\"\n | \"tool-with-metadata\"\n | \"view-with-mixed-returns\"\n >();\n});\n\ntest(\"ToolInput extracts the correct input type from Zod schema\", () => {\n type SearchInput = ToolInput<TestServer, \"search-trip\">;\n\n expectTypeOf<SearchInput>().toEqualTypeOf<{\n destination: string;\n departureDate?: string | undefined;\n maxPrice?: number | undefined;\n }>();\n\n type DetailsInput = ToolInput<TestServer, \"get-trip-details\">;\n\n expectTypeOf<DetailsInput>().toEqualTypeOf<{\n tripId: string;\n }>();\n\n type CalculateInput = ToolInput<TestServer, \"calculate-price\">;\n\n expectTypeOf<CalculateInput>().toEqualTypeOf<{\n tripId: string;\n passengers: number;\n }>();\n});\n\ntest(\"ToolOutput extracts the correct output type from callback's structuredContent\", () => {\n type SearchOutput = ToolOutput<TestServer, \"search-trip\">;\n\n expectTypeOf<SearchOutput>().toEqualTypeOf<{\n results: Array<{\n id: string;\n name: string;\n price: number;\n }>;\n totalCount: number;\n }>();\n\n type DetailsOutput = ToolOutput<TestServer, \"get-trip-details\">;\n\n expectTypeOf<DetailsOutput>().toEqualTypeOf<{\n name: string;\n description: string;\n images: string[];\n }>();\n\n // Note: outputSchema has totalPrice: z.string(), but callback returns number\n // Type is inferred from callback, so totalPrice is number\n type CalculateOutput = ToolOutput<TestServer, \"calculate-price\">;\n\n expectTypeOf<CalculateOutput>().toEqualTypeOf<{\n totalPrice: number;\n currency: string;\n }>();\n\n type NoInputOutput = ToolOutput<TestServer, \"no-input-view\">;\n expectTypeOf<NoInputOutput>().toEqualTypeOf<Record<never, unknown>>();\n});\n\ntest(\"ToolOutput extracts the correct output type from callback (inferred)\", () => {\n type InferredViewOutput = ToolOutput<TestServer, \"inferred-output-view\">;\n\n expectTypeOf<InferredViewOutput>().toEqualTypeOf<{\n inferredResults: { id: string; score: number }[];\n inferredCount: number;\n }>();\n\n type InferredToolOutput = ToolOutput<TestServer, \"inferred-tool\">;\n\n expectTypeOf<InferredToolOutput>().toEqualTypeOf<{\n itemDetails: { name: string; available: boolean };\n fetchedAt: string;\n }>();\n});\n\ntest(\"generateHelpers provides autocomplete for tool names (views + registerTool)\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n\n useCallTool(\"search-trip\");\n useCallTool(\"get-trip-details\");\n useCallTool(\"no-input-view\");\n useCallTool(\"calculate-price\");\n useCallTool(\"inferred-output-view\");\n useCallTool(\"inferred-tool\");\n useCallTool(\"view-with-metadata\");\n useCallTool(\"tool-with-metadata\");\n useCallTool(\"view-with-mixed-returns\");\n\n // @ts-expect-error - \"invalid-name\" is not a valid tool name\n useCallTool(\"invalid-name\");\n});\n\ntest(\"useCallTool returns correctly typed callTool function\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n const { callTool } = useCallTool(\"search-trip\");\n\n callTool({ destination: \"Spain\" });\n callTool({ destination: \"France\", departureDate: \"2024-06-01\" });\n callTool({ destination: \"Italy\", maxPrice: 1000 });\n\n const { callTool: calculateTool } = useCallTool(\"calculate-price\");\n calculateTool({ tripId: \"123\", passengers: 2 });\n});\n\ntest(\"callTool can be called without args for tools with no required inputs\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n const { callTool, callToolAsync } = useCallTool(\"no-input-view\");\n\n callTool();\n\n callTool({});\n\n callToolAsync();\n callToolAsync({});\n});\n\ntest(\"callTool requires args for tools with required inputs\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n const { callTool } = useCallTool(\"search-trip\");\n\n // @ts-expect-error - \"destination\" is required\n callTool();\n\n // @ts-expect-error - \"destination\" is required\n callTool({});\n\n // This should work\n callTool({ destination: \"Spain\" });\n});\n\ntest(\"callTool supports sideEffects for tools with required inputs\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n const { callTool } = useCallTool(\"search-trip\");\n\n callTool(\n { destination: \"Spain\" },\n {\n onSuccess: (response, args) => {\n expectTypeOf(response.structuredContent.results).toBeArray();\n expectTypeOf(args.destination).toBeString();\n },\n onError: (error, args) => {\n expectTypeOf(error).toBeUnknown();\n expectTypeOf(args.destination).toBeString();\n },\n onSettled: (response, error, args) => {\n if (response) {\n expectTypeOf(response.structuredContent.totalCount).toBeNumber();\n }\n expectTypeOf(error).toBeUnknown();\n expectTypeOf(args.destination).toBeString();\n },\n },\n );\n});\n\ntest(\"callTool supports sideEffects for tools with no required inputs\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n const { callTool } = useCallTool(\"no-input-view\");\n\n callTool({\n onSuccess: (response) => {\n expectTypeOf(response).toHaveProperty(\"structuredContent\");\n },\n });\n\n callTool(\n {},\n {\n onSuccess: (response) => {\n expectTypeOf(response).toHaveProperty(\"structuredContent\");\n },\n },\n );\n});\n\ntest(\"callToolAsync returns correctly typed promise\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n\n const { callToolAsync: searchAsync } = useCallTool(\"search-trip\");\n const searchPromise = searchAsync({ destination: \"Spain\" });\n expectTypeOf(searchPromise).resolves.toHaveProperty(\"structuredContent\");\n\n const { callToolAsync: noInputAsync } = useCallTool(\"no-input-view\");\n const noInputPromise = noInputAsync();\n expectTypeOf(noInputPromise).resolves.toHaveProperty(\"structuredContent\");\n});\n\ntest(\"useCallTool returns correctly typed data\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n const { data } = useCallTool(\"search-trip\");\n\n if (data) {\n expectTypeOf(data.structuredContent).toExtend<{\n results: Array<{\n id: string;\n name: string;\n price: number;\n }>;\n totalCount: number;\n }>();\n\n expectTypeOf(data.structuredContent.results).toBeArray();\n expectTypeOf(data.structuredContent.totalCount).toBeNumber();\n }\n});\n\ntest(\"useCallTool returns correctly typed data for callback-inferred outputs\", () => {\n const { useCallTool } = generateHelpers<TestServer>();\n\n const { data: viewData } = useCallTool(\"inferred-output-view\");\n if (viewData) {\n expectTypeOf(viewData.structuredContent).toExtend<{\n inferredResults: { id: string; score: number }[];\n inferredCount: number;\n }>();\n }\n\n const { data: toolData } = useCallTool(\"inferred-tool\");\n if (toolData) {\n expectTypeOf(toolData.structuredContent).toExtend<{\n itemDetails: { name: string; available: boolean };\n fetchedAt: string;\n }>();\n }\n});\n\ntest(\"generateHelpers provides autocomplete for tool names in useToolInfo (views + registerTool)\", () => {\n const { useToolInfo } = generateHelpers<TestServer>();\n\n useToolInfo<\"search-trip\">();\n useToolInfo<\"get-trip-details\">();\n useToolInfo<\"no-input-view\">();\n useToolInfo<\"calculate-price\">();\n useToolInfo<\"inferred-output-view\">();\n useToolInfo<\"inferred-tool\">();\n useToolInfo<\"view-with-metadata\">();\n useToolInfo<\"tool-with-metadata\">();\n useToolInfo<\"view-with-mixed-returns\">();\n\n // @ts-expect-error - \"invalid-name\" is not a valid tool name\n useToolInfo<\"invalid-name\">();\n});\n\ntest(\"useToolInfo infers input and output types\", () => {\n const { useToolInfo } = generateHelpers<TestServer>();\n const toolInfo = useToolInfo<\"search-trip\">();\n\n // Input is only available when not in idle state\n if (!(toolInfo.status === \"idle\")) {\n expectTypeOf(toolInfo.input).toExtend<\n ToolInput<TestServer, \"search-trip\">\n >();\n }\n\n if (toolInfo.status === \"success\") {\n expectTypeOf(toolInfo.output).toExtend<\n ToolOutput<TestServer, \"search-trip\">\n >();\n expectTypeOf(toolInfo.output.results).toBeArray();\n expectTypeOf(toolInfo.output.totalCount).toBeNumber();\n }\n});\n\ntest(\"ToolResponseMetadata extracts _meta type from callback\", () => {\n type ViewMeta = ToolResponseMetadata<TestServer, \"view-with-metadata\">;\n expectTypeOf<ViewMeta>().toEqualTypeOf<{\n requestId: string;\n timestamp: number;\n cached: boolean;\n }>();\n\n type ToolMeta = ToolResponseMetadata<TestServer, \"tool-with-metadata\">;\n expectTypeOf<ToolMeta>().toEqualTypeOf<{\n executionTime: number;\n source: string;\n }>();\n\n type SearchMeta = ToolResponseMetadata<TestServer, \"search-trip\">;\n expectTypeOf<SearchMeta>().toBeUnknown();\n});\n\ntest(\"useToolInfo infers responseMetadata type from generateHelpers\", () => {\n const { useToolInfo } = generateHelpers<TestServer>();\n const toolInfo = useToolInfo<\"view-with-metadata\">();\n\n if (toolInfo.isSuccess) {\n expectTypeOf(toolInfo.responseMetadata.requestId).toBeString();\n expectTypeOf(toolInfo.responseMetadata.timestamp).toBeNumber();\n expectTypeOf(toolInfo.responseMetadata.cached).toBeBoolean();\n }\n});\n\ntest(\"ToolResponseMetadata extracts _meta from mixed return paths\", () => {\n // View has multiple return paths: some with _meta, some without\n // ExtractMeta should still infer the _meta type from branches that have it\n type MixedMeta = ToolResponseMetadata<TestServer, \"view-with-mixed-returns\">;\n expectTypeOf<MixedMeta>().toEqualTypeOf<{\n processedAt: number;\n region: string;\n }>();\n});\n\ntest(\"ToolOutput extracts correct type when using interface declaration\", () => {\n type InterfaceViewOutput = ToolOutput<InterfaceTestServer, \"interface-view\">;\n\n expectTypeOf<InterfaceViewOutput>().toHaveProperty(\"itemName\");\n expectTypeOf<InterfaceViewOutput[\"itemName\"]>().toBeString();\n expectTypeOf<InterfaceViewOutput[\"quantity\"]>().toBeNumber();\n});\n\ntest(\"ToolResponseMetadata extracts correct type when using interface declaration\", () => {\n type InterfaceViewMeta = ToolResponseMetadata<\n InterfaceTestServer,\n \"interface-view\"\n >;\n\n expectTypeOf<InterfaceViewMeta>().toHaveProperty(\"processedBy\");\n expectTypeOf<InterfaceViewMeta[\"processedBy\"]>().toBeString();\n expectTypeOf<InterfaceViewMeta[\"version\"]>().toBeNumber();\n});\n\ntest(\"generateHelpers works with interface-typed server\", () => {\n const { useCallTool, useToolInfo } = generateHelpers<InterfaceTestServer>();\n\n const { data } = useCallTool(\"interface-view\");\n if (data) {\n expectTypeOf(data.structuredContent.itemName).toBeString();\n expectTypeOf(data.structuredContent.quantity).toBeNumber();\n }\n\n const toolInfo = useToolInfo<\"interface-view\">();\n if (toolInfo.isSuccess) {\n expectTypeOf(toolInfo.output.itemName).toBeString();\n expectTypeOf(toolInfo.output.quantity).toBeNumber();\n expectTypeOf(toolInfo.responseMetadata.processedBy).toBeString();\n expectTypeOf(toolInfo.responseMetadata.version).toBeNumber();\n }\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { createMinimalTestServer } from "../test/utils.js";
|
|
3
|
+
import { generateHelpers } from "./generate-helpers.js";
|
|
4
|
+
const server = createMinimalTestServer();
|
|
5
|
+
describe("generateHelpers", () => {
|
|
6
|
+
it("should return an object with useCallTool hook", () => {
|
|
7
|
+
const hooks = generateHelpers();
|
|
8
|
+
expect(hooks).toHaveProperty("useCallTool");
|
|
9
|
+
expect(typeof hooks.useCallTool).toBe("function");
|
|
10
|
+
});
|
|
11
|
+
it("should return an object with useToolInfo hook", () => {
|
|
12
|
+
const hooks = generateHelpers();
|
|
13
|
+
expect(hooks).toHaveProperty("useToolInfo");
|
|
14
|
+
expect(typeof hooks.useToolInfo).toBe("function");
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=generate-helpers.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-helpers.test.js","sourceRoot":"","sources":["../../src/web/generate-helpers.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,MAAM,GAAG,uBAAuB,EAAE,CAAC;AAGzC,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,KAAK,GAAG,eAAe,EAAc,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,KAAK,GAAG,eAAe,EAAc,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { createMinimalTestServer } from \"../test/utils.js\";\nimport { generateHelpers } from \"./generate-helpers.js\";\n\nconst server = createMinimalTestServer();\ntype TestServer = typeof server;\n\ndescribe(\"generateHelpers\", () => {\n it(\"should return an object with useCallTool hook\", () => {\n const hooks = generateHelpers<TestServer>();\n expect(hooks).toHaveProperty(\"useCallTool\");\n expect(typeof hooks.useCallTool).toBe(\"function\");\n });\n\n it(\"should return an object with useToolInfo hook\", () => {\n const hooks = generateHelpers<TestServer>();\n expect(hooks).toHaveProperty(\"useToolInfo\");\n expect(typeof hooks.useToolInfo).toBe(\"function\");\n });\n});\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type SuperJSONResult } from "superjson";
|
|
2
|
+
import type { UnknownObject } from "../types.js";
|
|
3
|
+
export declare function filterViewContext<T extends UnknownObject>(state?: T | null): T | null;
|
|
4
|
+
export declare function injectViewContext<T extends UnknownObject>(newState: T | null): T | null;
|
|
5
|
+
export declare function serializeState(value: UnknownObject): unknown;
|
|
6
|
+
export declare function deserializeState(value: SuperJSONResult): unknown;
|
|
7
|
+
export declare function getInitialState<State extends UnknownObject>(defaultState?: State | (() => State)): State | null;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import superjson, {} from "superjson";
|
|
2
|
+
import { getAdaptor } from "../bridges/index.js";
|
|
3
|
+
import { VIEW_CONTEXT_KEY } from "../data-llm.js";
|
|
4
|
+
export function filterViewContext(state) {
|
|
5
|
+
if (state === null || state === undefined) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
const { [VIEW_CONTEXT_KEY]: _, ...filteredState } = state;
|
|
9
|
+
return filteredState;
|
|
10
|
+
}
|
|
11
|
+
export function injectViewContext(newState) {
|
|
12
|
+
if (newState === null) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const currentState = getAdaptor()
|
|
16
|
+
.getHostContextStore("viewState")
|
|
17
|
+
.getSnapshot();
|
|
18
|
+
if (currentState !== null &&
|
|
19
|
+
currentState !== undefined &&
|
|
20
|
+
VIEW_CONTEXT_KEY in currentState) {
|
|
21
|
+
return {
|
|
22
|
+
...newState,
|
|
23
|
+
[VIEW_CONTEXT_KEY]: currentState[VIEW_CONTEXT_KEY],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return newState;
|
|
27
|
+
}
|
|
28
|
+
export function serializeState(value) {
|
|
29
|
+
return superjson.parse(superjson.stringify(value)); // Strips functions
|
|
30
|
+
}
|
|
31
|
+
export function deserializeState(value) {
|
|
32
|
+
return superjson.deserialize(value);
|
|
33
|
+
}
|
|
34
|
+
export function getInitialState(defaultState) {
|
|
35
|
+
const viewState = getAdaptor()
|
|
36
|
+
.getHostContextStore("viewState")
|
|
37
|
+
.getSnapshot();
|
|
38
|
+
if (viewState !== null && viewState !== undefined) {
|
|
39
|
+
return filterViewContext(viewState);
|
|
40
|
+
}
|
|
41
|
+
return typeof defaultState === "function"
|
|
42
|
+
? defaultState()
|
|
43
|
+
: (defaultState ?? null);
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/web/helpers/state.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,EAAE,EAAwB,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGlD,MAAM,UAAU,iBAAiB,CAC/B,KAAgB;IAEhB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,GAAG,aAAa,EAAE,GAAG,KAEnD,CAAC;IAEF,OAAO,aAAkB,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,QAAkB;IAElB,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,YAAY,GAAG,UAAU,EAAE;SAC9B,mBAAmB,CAAC,WAAW,CAAC;SAChC,WAAW,EAAmD,CAAC;IAElE,IACE,YAAY,KAAK,IAAI;QACrB,YAAY,KAAK,SAAS;QAC1B,gBAAgB,IAAI,YAAY,EAChC,CAAC;QACD,OAAO;YACL,GAAG,QAAQ;YACX,CAAC,gBAAgB,CAAC,EAAE,YAAY,CAAC,gBAAgB,CAAC;SAC9C,CAAC;IACT,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAoB;IACjD,OAAO,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB;AACzE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAsB;IACrD,OAAO,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,YAAoC;IAEpC,MAAM,SAAS,GAAG,UAAU,EAAE;SAC3B,mBAAmB,CAAC,WAAW,CAAC;SAChC,WAAW,EAAkB,CAAC;IAEjC,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAClD,OAAO,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,OAAO,YAAY,KAAK,UAAU;QACvC,CAAC,CAAC,YAAY,EAAE;QAChB,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import superjson, { type SuperJSONResult } from \"superjson\";\nimport { getAdaptor } from \"../bridges/index.js\";\nimport { VIEW_CONTEXT_KEY } from \"../data-llm.js\";\nimport type { UnknownObject } from \"../types.js\";\n\nexport function filterViewContext<T extends UnknownObject>(\n state?: T | null,\n): T | null {\n if (state === null || state === undefined) {\n return null;\n }\n\n const { [VIEW_CONTEXT_KEY]: _, ...filteredState } = state as T & {\n [VIEW_CONTEXT_KEY]?: unknown;\n };\n\n return filteredState as T;\n}\n\nexport function injectViewContext<T extends UnknownObject>(\n newState: T | null,\n): T | null {\n if (newState === null) {\n return null;\n }\n\n const currentState = getAdaptor()\n .getHostContextStore(\"viewState\")\n .getSnapshot() as (T & { [VIEW_CONTEXT_KEY]?: unknown }) | null;\n\n if (\n currentState !== null &&\n currentState !== undefined &&\n VIEW_CONTEXT_KEY in currentState\n ) {\n return {\n ...newState,\n [VIEW_CONTEXT_KEY]: currentState[VIEW_CONTEXT_KEY],\n } as T;\n }\n\n return newState;\n}\n\nexport function serializeState(value: UnknownObject) {\n return superjson.parse(superjson.stringify(value)); // Strips functions\n}\n\nexport function deserializeState(value: SuperJSONResult): unknown {\n return superjson.deserialize(value);\n}\n\nexport function getInitialState<State extends UnknownObject>(\n defaultState?: State | (() => State),\n): State | null {\n const viewState = getAdaptor()\n .getHostContextStore(\"viewState\")\n .getSnapshot() as State | null;\n\n if (viewState !== null && viewState !== undefined) {\n return filterViewContext(viewState);\n }\n\n return typeof defaultState === \"function\"\n ? defaultState()\n : (defaultState ?? null);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { VIEW_CONTEXT_KEY } from "../data-llm.js";
|
|
3
|
+
import { filterViewContext, serializeState } from "./state.js";
|
|
4
|
+
describe("state helpers", () => {
|
|
5
|
+
describe("filterViewContext", () => {
|
|
6
|
+
it("should return null when state is null", () => {
|
|
7
|
+
expect(filterViewContext(null)).toBe(null);
|
|
8
|
+
});
|
|
9
|
+
it("should return null when state is undefined", () => {
|
|
10
|
+
expect(filterViewContext(undefined)).toBe(null);
|
|
11
|
+
});
|
|
12
|
+
it("should correctly filter VIEW_CONTEXT_KEY and preserve other properties", () => {
|
|
13
|
+
const stateWithContextAndOthers = {
|
|
14
|
+
a: 1,
|
|
15
|
+
b: "two",
|
|
16
|
+
c: { nested: true },
|
|
17
|
+
[VIEW_CONTEXT_KEY]: "context",
|
|
18
|
+
};
|
|
19
|
+
const filteredWithContextAndOthers = filterViewContext(stateWithContextAndOthers);
|
|
20
|
+
expect(filteredWithContextAndOthers).toEqual({
|
|
21
|
+
a: 1,
|
|
22
|
+
b: "two",
|
|
23
|
+
c: { nested: true },
|
|
24
|
+
});
|
|
25
|
+
const stateNoContext = { count: 5, name: "test" };
|
|
26
|
+
const filteredNoContext = filterViewContext(stateNoContext);
|
|
27
|
+
expect(filteredNoContext).toEqual(stateNoContext);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe("serializeState", () => {
|
|
31
|
+
it("should serialize plain objects", () => {
|
|
32
|
+
const array = [1, "two", { three: 3 }];
|
|
33
|
+
const date = new Date("2023-01-01T00:00:00Z");
|
|
34
|
+
const object = {
|
|
35
|
+
a: 1,
|
|
36
|
+
b: "test",
|
|
37
|
+
c: true,
|
|
38
|
+
array,
|
|
39
|
+
date,
|
|
40
|
+
function: () => "test",
|
|
41
|
+
};
|
|
42
|
+
const result = serializeState(object);
|
|
43
|
+
expect(result).toEqual({
|
|
44
|
+
a: 1,
|
|
45
|
+
b: "test",
|
|
46
|
+
c: true,
|
|
47
|
+
array: [1, "two", { three: 3 }],
|
|
48
|
+
date: new Date("2023-01-01T00:00:00.000Z"),
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=state.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.test.js","sourceRoot":"","sources":["../../../src/web/helpers/state.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE/D,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;YAChF,MAAM,yBAAyB,GAAG;gBAChC,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,KAAK;gBACR,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;gBACnB,CAAC,gBAAgB,CAAC,EAAE,SAAS;aAC9B,CAAC;YACF,MAAM,4BAA4B,GAAG,iBAAiB,CACpD,yBAAyB,CAC1B,CAAC;YACF,MAAM,CAAC,4BAA4B,CAAC,CAAC,OAAO,CAAC;gBAC3C,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,KAAK;gBACR,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;aACpB,CAAC,CAAC;YAEH,MAAM,cAAc,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAClD,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;YAC5D,MAAM,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,KAAK,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YACvC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC;YAC9C,MAAM,MAAM,GAAG;gBACb,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,MAAM;gBACT,CAAC,EAAE,IAAI;gBACP,KAAK;gBACL,IAAI;gBACJ,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM;aACvB,CAAC;YACF,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;YAEtC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,CAAC,EAAE,CAAC;gBACJ,CAAC,EAAE,MAAM;gBACT,CAAC,EAAE,IAAI;gBACP,KAAK,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;gBAC/B,IAAI,EAAE,IAAI,IAAI,CAAC,0BAA0B,CAAC;aAC3C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { VIEW_CONTEXT_KEY } from \"../data-llm.js\";\nimport { filterViewContext, serializeState } from \"./state.js\";\n\ndescribe(\"state helpers\", () => {\n describe(\"filterViewContext\", () => {\n it(\"should return null when state is null\", () => {\n expect(filterViewContext(null)).toBe(null);\n });\n\n it(\"should return null when state is undefined\", () => {\n expect(filterViewContext(undefined)).toBe(null);\n });\n\n it(\"should correctly filter VIEW_CONTEXT_KEY and preserve other properties\", () => {\n const stateWithContextAndOthers = {\n a: 1,\n b: \"two\",\n c: { nested: true },\n [VIEW_CONTEXT_KEY]: \"context\",\n };\n const filteredWithContextAndOthers = filterViewContext(\n stateWithContextAndOthers,\n );\n expect(filteredWithContextAndOthers).toEqual({\n a: 1,\n b: \"two\",\n c: { nested: true },\n });\n\n const stateNoContext = { count: 5, name: \"test\" };\n const filteredNoContext = filterViewContext(stateNoContext);\n expect(filteredNoContext).toEqual(stateNoContext);\n });\n });\n\n describe(\"serializeState\", () => {\n it(\"should serialize plain objects\", () => {\n const array = [1, \"two\", { three: 3 }];\n const date = new Date(\"2023-01-01T00:00:00Z\");\n const object = {\n a: 1,\n b: \"test\",\n c: true,\n array,\n date,\n function: () => \"test\",\n };\n const result = serializeState(object);\n\n expect(result).toEqual({\n a: 1,\n b: \"test\",\n c: true,\n array: [1, \"two\", { three: 3 }],\n date: new Date(\"2023-01-01T00:00:00.000Z\"),\n });\n });\n });\n});\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { type CallToolAsyncFn, type CallToolFn, type CallToolState, type SideEffects, useCallTool, } from "./use-call-tool.js";
|
|
2
|
+
export { useDisplayMode } from "./use-display-mode.js";
|
|
3
|
+
export { useFiles } from "./use-files.js";
|
|
4
|
+
export { type LayoutState, useLayout } from "./use-layout.js";
|
|
5
|
+
export { type OpenExternalFn, useOpenExternal } from "./use-open-external.js";
|
|
6
|
+
export { type RequestCloseFn, useRequestClose } from "./use-request-close.js";
|
|
7
|
+
export { useRequestModal } from "./use-request-modal.js";
|
|
8
|
+
export { type RequestSizeFn, useRequestSize } from "./use-request-size.js";
|
|
9
|
+
export { useSendFollowUpMessage } from "./use-send-follow-up-message.js";
|
|
10
|
+
export { useSetOpenInAppUrl } from "./use-set-open-in-app-url.js";
|
|
11
|
+
export { useToolInfo } from "./use-tool-info.js";
|
|
12
|
+
export { type UserState, useUser } from "./use-user.js";
|
|
13
|
+
export { useViewState } from "./use-view-state.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { useCallTool, } from "./use-call-tool.js";
|
|
2
|
+
export { useDisplayMode } from "./use-display-mode.js";
|
|
3
|
+
export { useFiles } from "./use-files.js";
|
|
4
|
+
export { useLayout } from "./use-layout.js";
|
|
5
|
+
export { useOpenExternal } from "./use-open-external.js";
|
|
6
|
+
export { useRequestClose } from "./use-request-close.js";
|
|
7
|
+
export { useRequestModal } from "./use-request-modal.js";
|
|
8
|
+
export { useRequestSize } from "./use-request-size.js";
|
|
9
|
+
export { useSendFollowUpMessage } from "./use-send-follow-up-message.js";
|
|
10
|
+
export { useSetOpenInAppUrl } from "./use-set-open-in-app-url.js";
|
|
11
|
+
export { useToolInfo } from "./use-tool-info.js";
|
|
12
|
+
export { useUser } from "./use-user.js";
|
|
13
|
+
export { useViewState } from "./use-view-state.js";
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/web/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAoB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAuB,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAuB,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAsB,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAkB,OAAO,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["export {\n type CallToolAsyncFn,\n type CallToolFn,\n type CallToolState,\n type SideEffects,\n useCallTool,\n} from \"./use-call-tool.js\";\nexport { useDisplayMode } from \"./use-display-mode.js\";\nexport { useFiles } from \"./use-files.js\";\nexport { type LayoutState, useLayout } from \"./use-layout.js\";\nexport { type OpenExternalFn, useOpenExternal } from \"./use-open-external.js\";\nexport { type RequestCloseFn, useRequestClose } from \"./use-request-close.js\";\nexport { useRequestModal } from \"./use-request-modal.js\";\nexport { type RequestSizeFn, useRequestSize } from \"./use-request-size.js\";\nexport { useSendFollowUpMessage } from \"./use-send-follow-up-message.js\";\nexport { useSetOpenInAppUrl } from \"./use-set-open-in-app-url.js\";\nexport { useToolInfo } from \"./use-tool-info.js\";\nexport { type UserState, useUser } from \"./use-user.js\";\nexport { useViewState } from \"./use-view-state.js\";\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { McpUiHostContext, McpUiToolResultNotification } from "@modelcontextprotocol/ext-apps";
|
|
2
|
+
export declare class MockResizeObserver {
|
|
3
|
+
observe(): void;
|
|
4
|
+
unobserve(): void;
|
|
5
|
+
disconnect(): void;
|
|
6
|
+
}
|
|
7
|
+
export declare const getMcpAppHostPostMessageMock: (initialContext?: McpUiHostContext) => import("vitest").Mock<(message: {
|
|
8
|
+
method: string;
|
|
9
|
+
id: number;
|
|
10
|
+
}) => void>;
|
|
11
|
+
export declare const fireToolInputNotification: (args: Record<string, unknown>) => void;
|
|
12
|
+
export declare const fireToolResultNotification: (params: {
|
|
13
|
+
content: McpUiToolResultNotification["params"]["content"];
|
|
14
|
+
structuredContent: Record<string, unknown>;
|
|
15
|
+
_meta?: Record<string, unknown>;
|
|
16
|
+
}) => void;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { fireEvent } from "@testing-library/react";
|
|
2
|
+
import { act } from "react";
|
|
3
|
+
import { vi } from "vitest";
|
|
4
|
+
export class MockResizeObserver {
|
|
5
|
+
observe() { }
|
|
6
|
+
unobserve() { }
|
|
7
|
+
disconnect() { }
|
|
8
|
+
}
|
|
9
|
+
const DEFAULT_CONTEXT = {};
|
|
10
|
+
export const getMcpAppHostPostMessageMock = (initialContext = DEFAULT_CONTEXT) => vi.fn((message) => {
|
|
11
|
+
switch (message.method) {
|
|
12
|
+
case "ui/initialize": {
|
|
13
|
+
const result = {
|
|
14
|
+
protocolVersion: "2025-06-18",
|
|
15
|
+
hostInfo: { name: "test-host", version: "1.0.0" },
|
|
16
|
+
hostCapabilities: {},
|
|
17
|
+
hostContext: initialContext,
|
|
18
|
+
};
|
|
19
|
+
act(() => fireEvent(window, new MessageEvent("message", {
|
|
20
|
+
source: window.parent,
|
|
21
|
+
data: {
|
|
22
|
+
jsonrpc: "2.0",
|
|
23
|
+
id: message.id,
|
|
24
|
+
result,
|
|
25
|
+
},
|
|
26
|
+
})));
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
case "ui/update-model-context": {
|
|
30
|
+
act(() => fireEvent(window, new MessageEvent("message", {
|
|
31
|
+
source: window.parent,
|
|
32
|
+
data: {
|
|
33
|
+
jsonrpc: "2.0",
|
|
34
|
+
id: message.id,
|
|
35
|
+
result: {},
|
|
36
|
+
},
|
|
37
|
+
})));
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
export const fireToolInputNotification = (args) => {
|
|
43
|
+
fireEvent(window, new MessageEvent("message", {
|
|
44
|
+
source: window.parent,
|
|
45
|
+
data: {
|
|
46
|
+
jsonrpc: "2.0",
|
|
47
|
+
method: "ui/notifications/tool-input",
|
|
48
|
+
params: {
|
|
49
|
+
arguments: args,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
}));
|
|
53
|
+
};
|
|
54
|
+
export const fireToolResultNotification = (params) => {
|
|
55
|
+
fireEvent(window, new MessageEvent("message", {
|
|
56
|
+
source: window.parent,
|
|
57
|
+
data: {
|
|
58
|
+
jsonrpc: "2.0",
|
|
59
|
+
method: "ui/notifications/tool-result",
|
|
60
|
+
params,
|
|
61
|
+
},
|
|
62
|
+
}));
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/web/hooks/test/utils.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE5B,MAAM,OAAO,kBAAkB;IAC7B,OAAO,KAAU,CAAC;IAClB,SAAS,KAAU,CAAC;IACpB,UAAU,KAAU,CAAC;CACtB;AAED,MAAM,eAAe,GAAqB,EAAE,CAAC;AAE7C,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAC1C,iBAAmC,eAAe,EAClD,EAAE,CACF,EAAE,CAAC,EAAE,CAAC,CAAC,OAAuC,EAAE,EAAE;IAChD,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;QACvB,KAAK,eAAe,CAAC,CAAC,CAAC;YACrB,MAAM,MAAM,GAA0B;gBACpC,eAAe,EAAE,YAAY;gBAC7B,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE;gBACjD,gBAAgB,EAAE,EAAE;gBACpB,WAAW,EAAE,cAAc;aAC5B,CAAC;YACF,GAAG,CAAC,GAAG,EAAE,CACP,SAAS,CACP,MAAM,EACN,IAAI,YAAY,CAIb,SAAS,EAAE;gBACZ,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,IAAI,EAAE;oBACJ,OAAO,EAAE,KAAK;oBACd,EAAE,EAAE,OAAO,CAAC,EAAE;oBACd,MAAM;iBACP;aACF,CAAC,CACH,CACF,CAAC;YACF,MAAM;QACR,CAAC;QACD,KAAK,yBAAyB,CAAC,CAAC,CAAC;YAC/B,GAAG,CAAC,GAAG,EAAE,CACP,SAAS,CACP,MAAM,EACN,IAAI,YAAY,CACd,SAAS,EACT;gBACE,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,IAAI,EAAE;oBACJ,OAAO,EAAE,KAAK;oBACd,EAAE,EAAE,OAAO,CAAC,EAAE;oBACd,MAAM,EAAE,EAAE;iBACX;aACF,CACF,CACF,CACF,CAAC;YACF,MAAM;QACR,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,IAA6B,EAAE,EAAE;IACzE,SAAS,CACP,MAAM,EACN,IAAI,YAAY,CACd,SAAS,EACT;QACE,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,IAAI,EAAE;YACJ,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,6BAA6B;YACrC,MAAM,EAAE;gBACN,SAAS,EAAE,IAAI;aAChB;SACF;KACF,CACF,CACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,MAI1C,EAAE,EAAE;IACH,SAAS,CACP,MAAM,EACN,IAAI,YAAY,CACd,SAAS,EACT;QACE,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,IAAI,EAAE;YACJ,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,8BAA8B;YACtC,MAAM;SACP;KACF,CACF,CACF,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import type {\n McpUiHostContext,\n McpUiInitializeResult,\n McpUiToolInputNotification,\n McpUiToolResultNotification,\n} from \"@modelcontextprotocol/ext-apps\";\nimport { fireEvent } from \"@testing-library/react\";\nimport { act } from \"react\";\nimport { vi } from \"vitest\";\n\nexport class MockResizeObserver {\n observe(): void {}\n unobserve(): void {}\n disconnect(): void {}\n}\n\nconst DEFAULT_CONTEXT: McpUiHostContext = {};\n\nexport const getMcpAppHostPostMessageMock = (\n initialContext: McpUiHostContext = DEFAULT_CONTEXT,\n) =>\n vi.fn((message: { method: string; id: number }) => {\n switch (message.method) {\n case \"ui/initialize\": {\n const result: McpUiInitializeResult = {\n protocolVersion: \"2025-06-18\",\n hostInfo: { name: \"test-host\", version: \"1.0.0\" },\n hostCapabilities: {},\n hostContext: initialContext,\n };\n act(() =>\n fireEvent(\n window,\n new MessageEvent<{\n jsonrpc: \"2.0\";\n id: number;\n result: McpUiInitializeResult;\n }>(\"message\", {\n source: window.parent,\n data: {\n jsonrpc: \"2.0\",\n id: message.id,\n result,\n },\n }),\n ),\n );\n break;\n }\n case \"ui/update-model-context\": {\n act(() =>\n fireEvent(\n window,\n new MessageEvent<{ jsonrpc: \"2.0\"; id: number; result: unknown }>(\n \"message\",\n {\n source: window.parent,\n data: {\n jsonrpc: \"2.0\",\n id: message.id,\n result: {},\n },\n },\n ),\n ),\n );\n break;\n }\n }\n });\n\nexport const fireToolInputNotification = (args: Record<string, unknown>) => {\n fireEvent(\n window,\n new MessageEvent<McpUiToolInputNotification & { jsonrpc: \"2.0\" }>(\n \"message\",\n {\n source: window.parent,\n data: {\n jsonrpc: \"2.0\",\n method: \"ui/notifications/tool-input\",\n params: {\n arguments: args,\n },\n },\n },\n ),\n );\n};\n\nexport const fireToolResultNotification = (params: {\n content: McpUiToolResultNotification[\"params\"][\"content\"];\n structuredContent: Record<string, unknown>;\n _meta?: Record<string, unknown>;\n}) => {\n fireEvent(\n window,\n new MessageEvent<McpUiToolResultNotification & { jsonrpc: \"2.0\" }>(\n \"message\",\n {\n source: window.parent,\n data: {\n jsonrpc: \"2.0\",\n method: \"ui/notifications/tool-result\",\n params,\n },\n },\n ),\n );\n};\n"]}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { type CallToolArgs, type CallToolResponse } from "../bridges/index.js";
|
|
2
|
+
import type { HasRequiredKeys } from "../types.js";
|
|
3
|
+
type CallToolIdleState = {
|
|
4
|
+
status: "idle";
|
|
5
|
+
isIdle: true;
|
|
6
|
+
isPending: false;
|
|
7
|
+
isSuccess: false;
|
|
8
|
+
isError: false;
|
|
9
|
+
data: undefined;
|
|
10
|
+
error: undefined;
|
|
11
|
+
};
|
|
12
|
+
type CallToolPendingState = {
|
|
13
|
+
status: "pending";
|
|
14
|
+
isIdle: false;
|
|
15
|
+
isPending: true;
|
|
16
|
+
isSuccess: false;
|
|
17
|
+
isError: false;
|
|
18
|
+
data: undefined;
|
|
19
|
+
error: undefined;
|
|
20
|
+
};
|
|
21
|
+
type CallToolSuccessState<TData extends CallToolResponse = CallToolResponse> = {
|
|
22
|
+
status: "success";
|
|
23
|
+
isIdle: false;
|
|
24
|
+
isPending: false;
|
|
25
|
+
isSuccess: true;
|
|
26
|
+
isError: false;
|
|
27
|
+
data: TData;
|
|
28
|
+
error: undefined;
|
|
29
|
+
};
|
|
30
|
+
type CallToolErrorState = {
|
|
31
|
+
status: "error";
|
|
32
|
+
isIdle: false;
|
|
33
|
+
isPending: false;
|
|
34
|
+
isSuccess: false;
|
|
35
|
+
isError: true;
|
|
36
|
+
data: undefined;
|
|
37
|
+
error: unknown;
|
|
38
|
+
};
|
|
39
|
+
export type CallToolState<TData extends CallToolResponse = CallToolResponse> = CallToolIdleState | CallToolPendingState | CallToolSuccessState<TData> | CallToolErrorState;
|
|
40
|
+
export type SideEffects<ToolArgs, ToolResponse> = {
|
|
41
|
+
onSuccess?: (data: ToolResponse, toolArgs: ToolArgs) => void;
|
|
42
|
+
onError?: (error: unknown, toolArgs: ToolArgs) => void;
|
|
43
|
+
onSettled?: (data: ToolResponse | undefined, error: unknown | undefined, toolArgs: ToolArgs) => void;
|
|
44
|
+
};
|
|
45
|
+
type IsArgsOptional<T> = [T] extends [null] ? true : HasRequiredKeys<T> extends false ? true : false;
|
|
46
|
+
export type CallToolFn<TArgs, TResponse> = IsArgsOptional<TArgs> extends true ? {
|
|
47
|
+
(): void;
|
|
48
|
+
(sideEffects: SideEffects<TArgs, TResponse>): void;
|
|
49
|
+
(args: TArgs): void;
|
|
50
|
+
(args: TArgs, sideEffects: SideEffects<TArgs, TResponse>): void;
|
|
51
|
+
} : {
|
|
52
|
+
(args: TArgs): void;
|
|
53
|
+
(args: TArgs, sideEffects: SideEffects<TArgs, TResponse>): void;
|
|
54
|
+
};
|
|
55
|
+
export type CallToolAsyncFn<TArgs, TResponse> = IsArgsOptional<TArgs> extends true ? {
|
|
56
|
+
(): Promise<TResponse>;
|
|
57
|
+
(args: TArgs): Promise<TResponse>;
|
|
58
|
+
} : (args: TArgs) => Promise<TResponse>;
|
|
59
|
+
type ToolResponseSignature = Pick<CallToolResponse, "structuredContent" | "meta">;
|
|
60
|
+
export declare const useCallTool: <ToolArgs extends CallToolArgs = null, ToolResponse extends Partial<ToolResponseSignature> = Record<string, never>>(name: string) => {
|
|
61
|
+
callTool: CallToolFn<ToolArgs, CallToolResponse & ToolResponse>;
|
|
62
|
+
callToolAsync: CallToolAsyncFn<ToolArgs, CallToolResponse & ToolResponse>;
|
|
63
|
+
status: "idle";
|
|
64
|
+
isIdle: true;
|
|
65
|
+
isPending: false;
|
|
66
|
+
isSuccess: false;
|
|
67
|
+
isError: false;
|
|
68
|
+
data: undefined;
|
|
69
|
+
error: undefined;
|
|
70
|
+
} | {
|
|
71
|
+
callTool: CallToolFn<ToolArgs, CallToolResponse & ToolResponse>;
|
|
72
|
+
callToolAsync: CallToolAsyncFn<ToolArgs, CallToolResponse & ToolResponse>;
|
|
73
|
+
status: "pending";
|
|
74
|
+
isIdle: false;
|
|
75
|
+
isPending: true;
|
|
76
|
+
isSuccess: false;
|
|
77
|
+
isError: false;
|
|
78
|
+
data: undefined;
|
|
79
|
+
error: undefined;
|
|
80
|
+
} | {
|
|
81
|
+
callTool: CallToolFn<ToolArgs, CallToolResponse & ToolResponse>;
|
|
82
|
+
callToolAsync: CallToolAsyncFn<ToolArgs, CallToolResponse & ToolResponse>;
|
|
83
|
+
status: "error";
|
|
84
|
+
isIdle: false;
|
|
85
|
+
isPending: false;
|
|
86
|
+
isSuccess: false;
|
|
87
|
+
isError: true;
|
|
88
|
+
data: undefined;
|
|
89
|
+
error: unknown;
|
|
90
|
+
} | {
|
|
91
|
+
callTool: CallToolFn<ToolArgs, CallToolResponse & ToolResponse>;
|
|
92
|
+
callToolAsync: CallToolAsyncFn<ToolArgs, CallToolResponse & ToolResponse>;
|
|
93
|
+
status: "success";
|
|
94
|
+
isIdle: false;
|
|
95
|
+
isPending: false;
|
|
96
|
+
isSuccess: true;
|
|
97
|
+
isError: false;
|
|
98
|
+
data: CallToolResponse & ToolResponse;
|
|
99
|
+
error: undefined;
|
|
100
|
+
};
|
|
101
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { useRef, useState } from "react";
|
|
2
|
+
import { getAdaptor, } from "../bridges/index.js";
|
|
3
|
+
export const useCallTool = (name) => {
|
|
4
|
+
const [{ status, data, error }, setCallToolState] = useState({ status: "idle", data: undefined, error: undefined });
|
|
5
|
+
const callIdRef = useRef(0);
|
|
6
|
+
const adaptor = getAdaptor();
|
|
7
|
+
const execute = async (toolArgs) => {
|
|
8
|
+
const callId = ++callIdRef.current;
|
|
9
|
+
setCallToolState({ status: "pending", data: undefined, error: undefined });
|
|
10
|
+
try {
|
|
11
|
+
const data = await adaptor.callTool(name, toolArgs);
|
|
12
|
+
if (callId === callIdRef.current) {
|
|
13
|
+
setCallToolState({ status: "success", data, error: undefined });
|
|
14
|
+
}
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (callId === callIdRef.current) {
|
|
19
|
+
setCallToolState({ status: "error", data: undefined, error });
|
|
20
|
+
}
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const callToolAsync = ((toolArgs) => {
|
|
25
|
+
if (toolArgs === undefined) {
|
|
26
|
+
return execute(null);
|
|
27
|
+
}
|
|
28
|
+
return execute(toolArgs);
|
|
29
|
+
});
|
|
30
|
+
const callTool = ((firstArg, sideEffects) => {
|
|
31
|
+
let toolArgs;
|
|
32
|
+
if (firstArg &&
|
|
33
|
+
typeof firstArg === "object" &&
|
|
34
|
+
("onSuccess" in firstArg ||
|
|
35
|
+
"onError" in firstArg ||
|
|
36
|
+
"onSettled" in firstArg)) {
|
|
37
|
+
toolArgs = null; // no toolArgs provided
|
|
38
|
+
sideEffects = firstArg;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
toolArgs = (firstArg === undefined ? null : firstArg);
|
|
42
|
+
}
|
|
43
|
+
execute(toolArgs)
|
|
44
|
+
.then((data) => {
|
|
45
|
+
sideEffects?.onSuccess?.(data, toolArgs);
|
|
46
|
+
sideEffects?.onSettled?.(data, undefined, toolArgs);
|
|
47
|
+
})
|
|
48
|
+
.catch((error) => {
|
|
49
|
+
sideEffects?.onError?.(error, toolArgs);
|
|
50
|
+
sideEffects?.onSettled?.(undefined, error, toolArgs);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
const callToolState = {
|
|
54
|
+
status,
|
|
55
|
+
data,
|
|
56
|
+
error,
|
|
57
|
+
isIdle: status === "idle",
|
|
58
|
+
isPending: status === "pending",
|
|
59
|
+
isSuccess: status === "success",
|
|
60
|
+
isError: status === "error",
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
...callToolState,
|
|
64
|
+
callTool,
|
|
65
|
+
callToolAsync,
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=use-call-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-call-tool.js","sourceRoot":"","sources":["../../../src/web/hooks/use-call-tool.ts"],"names":[],"mappings":"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","sourcesContent":["import { useRef, useState } from \"react\";\n\nimport {\n type CallToolArgs,\n type CallToolResponse,\n getAdaptor,\n} from \"../bridges/index.js\";\nimport type { HasRequiredKeys } from \"../types.js\";\n\ntype CallToolIdleState = {\n status: \"idle\";\n isIdle: true;\n isPending: false;\n isSuccess: false;\n isError: false;\n data: undefined;\n error: undefined;\n};\n\ntype CallToolPendingState = {\n status: \"pending\";\n isIdle: false;\n isPending: true;\n isSuccess: false;\n isError: false;\n data: undefined;\n error: undefined;\n};\n\ntype CallToolSuccessState<TData extends CallToolResponse = CallToolResponse> = {\n status: \"success\";\n isIdle: false;\n isPending: false;\n isSuccess: true;\n isError: false;\n data: TData;\n error: undefined;\n};\n\ntype CallToolErrorState = {\n status: \"error\";\n isIdle: false;\n isPending: false;\n isSuccess: false;\n isError: true;\n data: undefined;\n error: unknown;\n};\n\nexport type CallToolState<TData extends CallToolResponse = CallToolResponse> =\n | CallToolIdleState\n | CallToolPendingState\n | CallToolSuccessState<TData>\n | CallToolErrorState;\n\nexport type SideEffects<ToolArgs, ToolResponse> = {\n onSuccess?: (data: ToolResponse, toolArgs: ToolArgs) => void;\n onError?: (error: unknown, toolArgs: ToolArgs) => void;\n onSettled?: (\n data: ToolResponse | undefined,\n error: unknown | undefined,\n toolArgs: ToolArgs,\n ) => void;\n};\n\ntype IsArgsOptional<T> = [T] extends [null]\n ? true\n : HasRequiredKeys<T> extends false\n ? true\n : false;\n\nexport type CallToolFn<TArgs, TResponse> =\n IsArgsOptional<TArgs> extends true\n ? {\n (): void;\n (sideEffects: SideEffects<TArgs, TResponse>): void;\n (args: TArgs): void;\n (args: TArgs, sideEffects: SideEffects<TArgs, TResponse>): void;\n }\n : {\n (args: TArgs): void;\n (args: TArgs, sideEffects: SideEffects<TArgs, TResponse>): void;\n };\n\nexport type CallToolAsyncFn<TArgs, TResponse> =\n IsArgsOptional<TArgs> extends true\n ? {\n (): Promise<TResponse>;\n (args: TArgs): Promise<TResponse>;\n }\n : (args: TArgs) => Promise<TResponse>;\n\ntype ToolResponseSignature = Pick<\n CallToolResponse,\n \"structuredContent\" | \"meta\"\n>;\n\nexport const useCallTool = <\n ToolArgs extends CallToolArgs = null,\n ToolResponse extends Partial<ToolResponseSignature> = Record<string, never>,\n>(\n name: string,\n) => {\n type CombinedCallToolResponse = CallToolResponse & ToolResponse;\n\n const [{ status, data, error }, setCallToolState] = useState<\n Omit<\n CallToolState<CombinedCallToolResponse>,\n \"isIdle\" | \"isPending\" | \"isSuccess\" | \"isError\"\n >\n >({ status: \"idle\", data: undefined, error: undefined });\n\n const callIdRef = useRef(0);\n const adaptor = getAdaptor();\n\n const execute = async (\n toolArgs: ToolArgs,\n ): Promise<CombinedCallToolResponse> => {\n const callId = ++callIdRef.current;\n setCallToolState({ status: \"pending\", data: undefined, error: undefined });\n\n try {\n const data = await adaptor.callTool<ToolArgs, CombinedCallToolResponse>(\n name,\n toolArgs,\n );\n if (callId === callIdRef.current) {\n setCallToolState({ status: \"success\", data, error: undefined });\n }\n\n return data;\n } catch (error) {\n if (callId === callIdRef.current) {\n setCallToolState({ status: \"error\", data: undefined, error });\n }\n throw error;\n }\n };\n\n const callToolAsync = ((toolArgs?: ToolArgs) => {\n if (toolArgs === undefined) {\n return execute(null as ToolArgs);\n }\n return execute(toolArgs);\n }) as CallToolAsyncFn<ToolArgs, CombinedCallToolResponse>;\n\n const callTool = ((\n firstArg?: ToolArgs | SideEffects<ToolArgs, CombinedCallToolResponse>,\n sideEffects?: SideEffects<ToolArgs, CombinedCallToolResponse>,\n ) => {\n let toolArgs: ToolArgs;\n if (\n firstArg &&\n typeof firstArg === \"object\" &&\n (\"onSuccess\" in firstArg ||\n \"onError\" in firstArg ||\n \"onSettled\" in firstArg)\n ) {\n toolArgs = null as ToolArgs; // no toolArgs provided\n sideEffects = firstArg;\n } else {\n toolArgs = (firstArg === undefined ? null : firstArg) as ToolArgs;\n }\n\n execute(toolArgs)\n .then((data) => {\n sideEffects?.onSuccess?.(data, toolArgs);\n sideEffects?.onSettled?.(data, undefined, toolArgs);\n })\n .catch((error) => {\n sideEffects?.onError?.(error, toolArgs);\n sideEffects?.onSettled?.(undefined, error, toolArgs);\n });\n }) as CallToolFn<ToolArgs, CombinedCallToolResponse>;\n\n const callToolState = {\n status,\n data,\n error,\n isIdle: status === \"idle\",\n isPending: status === \"pending\",\n isSuccess: status === \"success\",\n isError: status === \"error\",\n } as CallToolState<CombinedCallToolResponse>;\n\n return {\n ...callToolState,\n callTool,\n callToolAsync,\n };\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { expectTypeOf, test } from "vitest";
|
|
2
|
+
import { useCallTool, } from "./use-call-tool.js";
|
|
3
|
+
test("callTool can be called without args when ToolArgs is null", () => {
|
|
4
|
+
const { callTool, callToolAsync } = useCallTool("test-tool");
|
|
5
|
+
callTool();
|
|
6
|
+
callTool({ onSuccess: () => { } });
|
|
7
|
+
callToolAsync();
|
|
8
|
+
});
|
|
9
|
+
test("callTool requires args when ToolArgs has required properties", () => {
|
|
10
|
+
const { callTool, callToolAsync } = useCallTool("test-tool");
|
|
11
|
+
// @ts-expect-error - query is required
|
|
12
|
+
callTool();
|
|
13
|
+
callTool({ query: "test" });
|
|
14
|
+
callTool({ query: "test" }, { onSuccess: () => { } });
|
|
15
|
+
// @ts-expect-error - query is required
|
|
16
|
+
callToolAsync();
|
|
17
|
+
callToolAsync({ query: "test" });
|
|
18
|
+
});
|
|
19
|
+
test("callTool supports sideEffects with correct types", () => {
|
|
20
|
+
const { callTool } = useCallTool("test-tool");
|
|
21
|
+
callTool({ id: 1 }, {
|
|
22
|
+
onSuccess: (data, args) => {
|
|
23
|
+
expectTypeOf(data.structuredContent.result).toBeString();
|
|
24
|
+
expectTypeOf(args.id).toBeNumber();
|
|
25
|
+
},
|
|
26
|
+
onError: (error, args) => {
|
|
27
|
+
expectTypeOf(error).toBeUnknown();
|
|
28
|
+
expectTypeOf(args.id).toBeNumber();
|
|
29
|
+
},
|
|
30
|
+
onSettled: (data, error, args) => {
|
|
31
|
+
if (data) {
|
|
32
|
+
expectTypeOf(data.structuredContent.result).toBeString();
|
|
33
|
+
}
|
|
34
|
+
expectTypeOf(error).toEqualTypeOf();
|
|
35
|
+
expectTypeOf(args.id).toBeNumber();
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
test("callTool allows sideEffects as first arg when ToolArgs is null", () => {
|
|
40
|
+
const { callTool } = useCallTool("test-tool");
|
|
41
|
+
callTool({
|
|
42
|
+
onSuccess: (data) => {
|
|
43
|
+
expectTypeOf(data.structuredContent.value).toBeNumber();
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
test("callToolAsync returns correctly typed promise", () => {
|
|
48
|
+
const { callToolAsync } = useCallTool("test-tool");
|
|
49
|
+
const promise = callToolAsync({ name: "test" });
|
|
50
|
+
expectTypeOf(promise).resolves.toHaveProperty("structuredContent");
|
|
51
|
+
expectTypeOf(promise).resolves.toHaveProperty("meta");
|
|
52
|
+
});
|
|
53
|
+
test("state narrowing works correctly with status", () => {
|
|
54
|
+
const result = useCallTool("test-tool");
|
|
55
|
+
if (result.status === "idle") {
|
|
56
|
+
expectTypeOf(result.isIdle).toEqualTypeOf();
|
|
57
|
+
expectTypeOf(result.data).toEqualTypeOf();
|
|
58
|
+
}
|
|
59
|
+
if (result.status === "pending") {
|
|
60
|
+
expectTypeOf(result.isPending).toEqualTypeOf();
|
|
61
|
+
expectTypeOf(result.data).toEqualTypeOf();
|
|
62
|
+
}
|
|
63
|
+
if (result.status === "success") {
|
|
64
|
+
expectTypeOf(result.isSuccess).toEqualTypeOf();
|
|
65
|
+
expectTypeOf(result.data).not.toEqualTypeOf();
|
|
66
|
+
expectTypeOf(result.data.structuredContent.data).toBeString();
|
|
67
|
+
}
|
|
68
|
+
if (result.status === "error") {
|
|
69
|
+
expectTypeOf(result.isError).toEqualTypeOf();
|
|
70
|
+
expectTypeOf(result.error).toBeUnknown();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
test("state narrowing works correctly with boolean flags", () => {
|
|
74
|
+
const result = useCallTool("test-tool");
|
|
75
|
+
if (result.isIdle) {
|
|
76
|
+
expectTypeOf(result.status).toEqualTypeOf();
|
|
77
|
+
}
|
|
78
|
+
if (result.isPending) {
|
|
79
|
+
expectTypeOf(result.status).toEqualTypeOf();
|
|
80
|
+
}
|
|
81
|
+
if (result.isSuccess) {
|
|
82
|
+
expectTypeOf(result.status).toEqualTypeOf();
|
|
83
|
+
expectTypeOf(result.data.structuredContent.items).toBeArray();
|
|
84
|
+
}
|
|
85
|
+
if (result.isError) {
|
|
86
|
+
expectTypeOf(result.status).toEqualTypeOf();
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
test("CallToolState type is correctly exported and usable", () => {
|
|
90
|
+
const state = {};
|
|
91
|
+
if (state.status === "success") {
|
|
92
|
+
expectTypeOf(state.data.structuredContent.foo).toBeString();
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
test("SideEffects type is correctly exported and usable", () => {
|
|
96
|
+
const sideEffects = {
|
|
97
|
+
onSuccess: (data, args) => {
|
|
98
|
+
expectTypeOf(data.structuredContent.y).toBeString();
|
|
99
|
+
expectTypeOf(args.x).toBeNumber();
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
expectTypeOf(sideEffects).toHaveProperty("onSuccess");
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=use-call-tool.test-d.js.map
|