@frontmcp/ui 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/LICENSE +201 -0
- package/README.md +438 -0
- package/package.json +147 -0
- package/src/adapters/index.d.ts +10 -0
- package/src/adapters/index.js +18 -0
- package/src/adapters/index.js.map +1 -0
- package/src/adapters/platform-meta.d.ts +165 -0
- package/src/adapters/platform-meta.js +310 -0
- package/src/adapters/platform-meta.js.map +1 -0
- package/src/base-template/bridge.d.ts +89 -0
- package/src/base-template/bridge.js +452 -0
- package/src/base-template/bridge.js.map +1 -0
- package/src/base-template/default-base-template.d.ts +91 -0
- package/src/base-template/default-base-template.js +435 -0
- package/src/base-template/default-base-template.js.map +1 -0
- package/src/base-template/index.d.ts +14 -0
- package/src/base-template/index.js +30 -0
- package/src/base-template/index.js.map +1 -0
- package/src/base-template/polyfills.d.ts +30 -0
- package/src/base-template/polyfills.js +190 -0
- package/src/base-template/polyfills.js.map +1 -0
- package/src/base-template/theme-styles.d.ts +73 -0
- package/src/base-template/theme-styles.js +95 -0
- package/src/base-template/theme-styles.js.map +1 -0
- package/src/bridge/adapters/base-adapter.d.ts +103 -0
- package/src/bridge/adapters/base-adapter.js +314 -0
- package/src/bridge/adapters/base-adapter.js.map +1 -0
- package/src/bridge/adapters/claude.adapter.d.ts +66 -0
- package/src/bridge/adapters/claude.adapter.js +145 -0
- package/src/bridge/adapters/claude.adapter.js.map +1 -0
- package/src/bridge/adapters/ext-apps.adapter.d.ts +142 -0
- package/src/bridge/adapters/ext-apps.adapter.js +416 -0
- package/src/bridge/adapters/ext-apps.adapter.js.map +1 -0
- package/src/bridge/adapters/gemini.adapter.d.ts +63 -0
- package/src/bridge/adapters/gemini.adapter.js +160 -0
- package/src/bridge/adapters/gemini.adapter.js.map +1 -0
- package/src/bridge/adapters/generic.adapter.d.ts +55 -0
- package/src/bridge/adapters/generic.adapter.js +108 -0
- package/src/bridge/adapters/generic.adapter.js.map +1 -0
- package/src/bridge/adapters/index.d.ts +25 -0
- package/src/bridge/adapters/index.js +65 -0
- package/src/bridge/adapters/index.js.map +1 -0
- package/src/bridge/adapters/openai.adapter.d.ts +64 -0
- package/src/bridge/adapters/openai.adapter.js +194 -0
- package/src/bridge/adapters/openai.adapter.js.map +1 -0
- package/src/bridge/core/adapter-registry.d.ts +121 -0
- package/src/bridge/core/adapter-registry.js +271 -0
- package/src/bridge/core/adapter-registry.js.map +1 -0
- package/src/bridge/core/bridge-factory.d.ts +198 -0
- package/src/bridge/core/bridge-factory.js +428 -0
- package/src/bridge/core/bridge-factory.js.map +1 -0
- package/src/bridge/core/index.d.ts +9 -0
- package/src/bridge/core/index.js +22 -0
- package/src/bridge/core/index.js.map +1 -0
- package/src/bridge/index.d.ts +61 -0
- package/src/bridge/index.js +94 -0
- package/src/bridge/index.js.map +1 -0
- package/src/bridge/runtime/iife-generator.d.ts +61 -0
- package/src/bridge/runtime/iife-generator.js +940 -0
- package/src/bridge/runtime/iife-generator.js.map +1 -0
- package/src/bridge/runtime/index.d.ts +8 -0
- package/src/bridge/runtime/index.js +16 -0
- package/src/bridge/runtime/index.js.map +1 -0
- package/src/bridge/types.d.ts +385 -0
- package/src/bridge/types.js +11 -0
- package/src/bridge/types.js.map +1 -0
- package/src/build/cdn-resources.d.ts +140 -0
- package/src/build/cdn-resources.js +314 -0
- package/src/build/cdn-resources.js.map +1 -0
- package/src/build/index.d.ts +294 -0
- package/src/build/index.js +325 -0
- package/src/build/index.js.map +1 -0
- package/src/build/widget-manifest.d.ts +212 -0
- package/src/build/widget-manifest.js +652 -0
- package/src/build/widget-manifest.js.map +1 -0
- package/src/bundler/bundler.d.ts +110 -0
- package/src/bundler/bundler.js +432 -0
- package/src/bundler/bundler.js.map +1 -0
- package/src/bundler/cache.d.ts +172 -0
- package/src/bundler/cache.js +250 -0
- package/src/bundler/cache.js.map +1 -0
- package/src/bundler/index.d.ts +41 -0
- package/src/bundler/index.js +73 -0
- package/src/bundler/index.js.map +1 -0
- package/src/bundler/sandbox/enclave-adapter.d.ts +120 -0
- package/src/bundler/sandbox/enclave-adapter.js +339 -0
- package/src/bundler/sandbox/enclave-adapter.js.map +1 -0
- package/src/bundler/sandbox/executor.d.ts +13 -0
- package/src/bundler/sandbox/executor.js +22 -0
- package/src/bundler/sandbox/executor.js.map +1 -0
- package/src/bundler/sandbox/policy.d.ts +61 -0
- package/src/bundler/sandbox/policy.js +238 -0
- package/src/bundler/sandbox/policy.js.map +1 -0
- package/src/bundler/types.d.ts +347 -0
- package/src/bundler/types.js +132 -0
- package/src/bundler/types.js.map +1 -0
- package/src/components/alert.d.ts +71 -0
- package/src/components/alert.js +189 -0
- package/src/components/alert.js.map +1 -0
- package/src/components/alert.schema.d.ts +114 -0
- package/src/components/alert.schema.js +105 -0
- package/src/components/alert.schema.js.map +1 -0
- package/src/components/avatar.d.ts +76 -0
- package/src/components/avatar.js +176 -0
- package/src/components/avatar.js.map +1 -0
- package/src/components/avatar.schema.d.ts +169 -0
- package/src/components/avatar.schema.js +103 -0
- package/src/components/avatar.schema.js.map +1 -0
- package/src/components/badge.d.ts +70 -0
- package/src/components/badge.js +149 -0
- package/src/components/badge.js.map +1 -0
- package/src/components/badge.schema.d.ts +109 -0
- package/src/components/badge.schema.js +96 -0
- package/src/components/badge.schema.js.map +1 -0
- package/src/components/button.d.ts +111 -0
- package/src/components/button.js +336 -0
- package/src/components/button.js.map +1 -0
- package/src/components/button.schema.d.ts +148 -0
- package/src/components/button.schema.js +121 -0
- package/src/components/button.schema.js.map +1 -0
- package/src/components/card.d.ts +60 -0
- package/src/components/card.js +117 -0
- package/src/components/card.js.map +1 -0
- package/src/components/card.schema.d.ts +113 -0
- package/src/components/card.schema.js +98 -0
- package/src/components/card.schema.js.map +1 -0
- package/src/components/form.d.ts +239 -0
- package/src/components/form.js +420 -0
- package/src/components/form.js.map +1 -0
- package/src/components/form.schema.d.ts +441 -0
- package/src/components/form.schema.js +406 -0
- package/src/components/form.schema.js.map +1 -0
- package/src/components/index.d.ts +29 -0
- package/src/components/index.js +98 -0
- package/src/components/index.js.map +1 -0
- package/src/components/list.d.ts +127 -0
- package/src/components/list.js +279 -0
- package/src/components/list.js.map +1 -0
- package/src/components/list.schema.d.ts +134 -0
- package/src/components/list.schema.js +168 -0
- package/src/components/list.schema.js.map +1 -0
- package/src/components/modal.d.ts +111 -0
- package/src/components/modal.js +260 -0
- package/src/components/modal.js.map +1 -0
- package/src/components/modal.schema.d.ts +186 -0
- package/src/components/modal.schema.js +167 -0
- package/src/components/modal.schema.js.map +1 -0
- package/src/components/table.d.ts +105 -0
- package/src/components/table.js +283 -0
- package/src/components/table.js.map +1 -0
- package/src/components/table.schema.d.ts +159 -0
- package/src/components/table.schema.js +173 -0
- package/src/components/table.schema.js.map +1 -0
- package/src/handlebars/helpers.d.ts +348 -0
- package/src/handlebars/helpers.js +605 -0
- package/src/handlebars/helpers.js.map +1 -0
- package/src/handlebars/index.d.ts +193 -0
- package/src/handlebars/index.js +350 -0
- package/src/handlebars/index.js.map +1 -0
- package/src/index.d.ts +50 -0
- package/src/index.js +192 -0
- package/src/index.js.map +1 -0
- package/src/layouts/base.d.ts +88 -0
- package/src/layouts/base.js +227 -0
- package/src/layouts/base.js.map +1 -0
- package/src/layouts/index.d.ts +7 -0
- package/src/layouts/index.js +25 -0
- package/src/layouts/index.js.map +1 -0
- package/src/layouts/presets.d.ts +133 -0
- package/src/layouts/presets.js +277 -0
- package/src/layouts/presets.js.map +1 -0
- package/src/pages/consent.d.ts +116 -0
- package/src/pages/consent.js +218 -0
- package/src/pages/consent.js.map +1 -0
- package/src/pages/error.d.ts +100 -0
- package/src/pages/error.js +263 -0
- package/src/pages/error.js.map +1 -0
- package/src/pages/index.d.ts +8 -0
- package/src/pages/index.js +27 -0
- package/src/pages/index.js.map +1 -0
- package/src/react/Alert.d.ts +101 -0
- package/src/react/Alert.js +51 -0
- package/src/react/Alert.js.map +1 -0
- package/src/react/Badge.d.ts +100 -0
- package/src/react/Badge.js +55 -0
- package/src/react/Badge.js.map +1 -0
- package/src/react/Button.d.ts +108 -0
- package/src/react/Button.js +52 -0
- package/src/react/Button.js.map +1 -0
- package/src/react/Card.d.ts +103 -0
- package/src/react/Card.js +55 -0
- package/src/react/Card.js.map +1 -0
- package/src/react/hooks/context.d.ts +178 -0
- package/src/react/hooks/context.js +287 -0
- package/src/react/hooks/context.js.map +1 -0
- package/src/react/hooks/index.d.ts +41 -0
- package/src/react/hooks/index.js +61 -0
- package/src/react/hooks/index.js.map +1 -0
- package/src/react/hooks/tools.d.ts +283 -0
- package/src/react/hooks/tools.js +465 -0
- package/src/react/hooks/tools.js.map +1 -0
- package/src/react/index.d.ts +80 -0
- package/src/react/index.js +113 -0
- package/src/react/index.js.map +1 -0
- package/src/react/types.d.ts +105 -0
- package/src/react/types.js +12 -0
- package/src/react/types.js.map +1 -0
- package/src/react/utils.d.ts +42 -0
- package/src/react/utils.js +99 -0
- package/src/react/utils.js.map +1 -0
- package/src/registry/index.d.ts +45 -0
- package/src/registry/index.js +67 -0
- package/src/registry/index.js.map +1 -0
- package/src/registry/render-template.d.ts +86 -0
- package/src/registry/render-template.js +239 -0
- package/src/registry/render-template.js.map +1 -0
- package/src/registry/tool-ui.registry.d.ts +260 -0
- package/src/registry/tool-ui.registry.js +438 -0
- package/src/registry/tool-ui.registry.js.map +1 -0
- package/src/registry/uri-utils.d.ts +55 -0
- package/src/registry/uri-utils.js +97 -0
- package/src/registry/uri-utils.js.map +1 -0
- package/src/render/index.d.ts +7 -0
- package/src/render/index.js +14 -0
- package/src/render/index.js.map +1 -0
- package/src/render/prerender.d.ts +56 -0
- package/src/render/prerender.js +98 -0
- package/src/render/prerender.js.map +1 -0
- package/src/renderers/cache.d.ts +144 -0
- package/src/renderers/cache.js +240 -0
- package/src/renderers/cache.js.map +1 -0
- package/src/renderers/html.renderer.d.ts +122 -0
- package/src/renderers/html.renderer.js +204 -0
- package/src/renderers/html.renderer.js.map +1 -0
- package/src/renderers/index.d.ts +35 -0
- package/src/renderers/index.js +70 -0
- package/src/renderers/index.js.map +1 -0
- package/src/renderers/mdx.renderer.d.ts +119 -0
- package/src/renderers/mdx.renderer.js +305 -0
- package/src/renderers/mdx.renderer.js.map +1 -0
- package/src/renderers/react.renderer.d.ts +95 -0
- package/src/renderers/react.renderer.js +260 -0
- package/src/renderers/react.renderer.js.map +1 -0
- package/src/renderers/registry.d.ts +133 -0
- package/src/renderers/registry.js +232 -0
- package/src/renderers/registry.js.map +1 -0
- package/src/renderers/types.d.ts +341 -0
- package/src/renderers/types.js +9 -0
- package/src/renderers/types.js.map +1 -0
- package/src/renderers/utils/detect.d.ts +106 -0
- package/src/renderers/utils/detect.js +267 -0
- package/src/renderers/utils/detect.js.map +1 -0
- package/src/renderers/utils/hash.d.ts +39 -0
- package/src/renderers/utils/hash.js +75 -0
- package/src/renderers/utils/hash.js.map +1 -0
- package/src/renderers/utils/index.d.ts +8 -0
- package/src/renderers/utils/index.js +28 -0
- package/src/renderers/utils/index.js.map +1 -0
- package/src/renderers/utils/transpiler.d.ts +88 -0
- package/src/renderers/utils/transpiler.js +215 -0
- package/src/renderers/utils/transpiler.js.map +1 -0
- package/src/runtime/adapters/html.adapter.d.ts +58 -0
- package/src/runtime/adapters/html.adapter.js +131 -0
- package/src/runtime/adapters/html.adapter.js.map +1 -0
- package/src/runtime/adapters/index.d.ts +25 -0
- package/src/runtime/adapters/index.js +54 -0
- package/src/runtime/adapters/index.js.map +1 -0
- package/src/runtime/adapters/mdx.adapter.d.ts +72 -0
- package/src/runtime/adapters/mdx.adapter.js +241 -0
- package/src/runtime/adapters/mdx.adapter.js.map +1 -0
- package/src/runtime/adapters/react.adapter.d.ts +69 -0
- package/src/runtime/adapters/react.adapter.js +245 -0
- package/src/runtime/adapters/react.adapter.js.map +1 -0
- package/src/runtime/adapters/types.d.ts +94 -0
- package/src/runtime/adapters/types.js +11 -0
- package/src/runtime/adapters/types.js.map +1 -0
- package/src/runtime/csp.d.ts +37 -0
- package/src/runtime/csp.js +140 -0
- package/src/runtime/csp.js.map +1 -0
- package/src/runtime/index.d.ts +16 -0
- package/src/runtime/index.js +72 -0
- package/src/runtime/index.js.map +1 -0
- package/src/runtime/mcp-bridge.d.ts +100 -0
- package/src/runtime/mcp-bridge.js +581 -0
- package/src/runtime/mcp-bridge.js.map +1 -0
- package/src/runtime/renderer-runtime.d.ts +132 -0
- package/src/runtime/renderer-runtime.js +389 -0
- package/src/runtime/renderer-runtime.js.map +1 -0
- package/src/runtime/sanitizer.d.ts +171 -0
- package/src/runtime/sanitizer.js +318 -0
- package/src/runtime/sanitizer.js.map +1 -0
- package/src/runtime/types.d.ts +414 -0
- package/src/runtime/types.js +12 -0
- package/src/runtime/types.js.map +1 -0
- package/src/runtime/wrapper.d.ts +375 -0
- package/src/runtime/wrapper.js +1793 -0
- package/src/runtime/wrapper.js.map +1 -0
- package/src/styles/index.d.ts +7 -0
- package/src/styles/index.js +11 -0
- package/src/styles/index.js.map +1 -0
- package/src/styles/variants.d.ts +50 -0
- package/src/styles/variants.js +175 -0
- package/src/styles/variants.js.map +1 -0
- package/src/theme/cdn.d.ts +194 -0
- package/src/theme/cdn.js +375 -0
- package/src/theme/cdn.js.map +1 -0
- package/src/theme/index.d.ts +17 -0
- package/src/theme/index.js +57 -0
- package/src/theme/index.js.map +1 -0
- package/src/theme/platforms.d.ts +106 -0
- package/src/theme/platforms.js +161 -0
- package/src/theme/platforms.js.map +1 -0
- package/src/theme/presets/github-openai.d.ts +49 -0
- package/src/theme/presets/github-openai.js +189 -0
- package/src/theme/presets/github-openai.js.map +1 -0
- package/src/theme/presets/index.d.ts +10 -0
- package/src/theme/presets/index.js +17 -0
- package/src/theme/presets/index.js.map +1 -0
- package/src/theme/theme.d.ts +395 -0
- package/src/theme/theme.js +332 -0
- package/src/theme/theme.js.map +1 -0
- package/src/tool-template/builder.d.ts +212 -0
- package/src/tool-template/builder.js +397 -0
- package/src/tool-template/builder.js.map +1 -0
- package/src/tool-template/index.d.ts +15 -0
- package/src/tool-template/index.js +38 -0
- package/src/tool-template/index.js.map +1 -0
- package/src/types/index.d.ts +13 -0
- package/src/types/index.js +26 -0
- package/src/types/index.js.map +1 -0
- package/src/types/ui-config.d.ts +357 -0
- package/src/types/ui-config.js +12 -0
- package/src/types/ui-config.js.map +1 -0
- package/src/types/ui-runtime.d.ts +965 -0
- package/src/types/ui-runtime.js +117 -0
- package/src/types/ui-runtime.js.map +1 -0
- package/src/validation/error-box.d.ts +55 -0
- package/src/validation/error-box.js +75 -0
- package/src/validation/error-box.js.map +1 -0
- package/src/validation/index.d.ts +12 -0
- package/src/validation/index.js +21 -0
- package/src/validation/index.js.map +1 -0
- package/src/validation/wrapper.d.ts +96 -0
- package/src/validation/wrapper.js +117 -0
- package/src/validation/wrapper.js.map +1 -0
- package/src/web-components/core/attribute-parser.d.ts +85 -0
- package/src/web-components/core/attribute-parser.js +189 -0
- package/src/web-components/core/attribute-parser.js.map +1 -0
- package/src/web-components/core/base-element.d.ts +197 -0
- package/src/web-components/core/base-element.js +289 -0
- package/src/web-components/core/base-element.js.map +1 -0
- package/src/web-components/core/index.d.ts +8 -0
- package/src/web-components/core/index.js +18 -0
- package/src/web-components/core/index.js.map +1 -0
- package/src/web-components/elements/fmcp-alert.d.ts +45 -0
- package/src/web-components/elements/fmcp-alert.js +93 -0
- package/src/web-components/elements/fmcp-alert.js.map +1 -0
- package/src/web-components/elements/fmcp-badge.d.ts +46 -0
- package/src/web-components/elements/fmcp-badge.js +99 -0
- package/src/web-components/elements/fmcp-badge.js.map +1 -0
- package/src/web-components/elements/fmcp-button.d.ts +124 -0
- package/src/web-components/elements/fmcp-button.js +233 -0
- package/src/web-components/elements/fmcp-button.js.map +1 -0
- package/src/web-components/elements/fmcp-card.d.ts +52 -0
- package/src/web-components/elements/fmcp-card.js +115 -0
- package/src/web-components/elements/fmcp-card.js.map +1 -0
- package/src/web-components/elements/fmcp-input.d.ts +95 -0
- package/src/web-components/elements/fmcp-input.js +248 -0
- package/src/web-components/elements/fmcp-input.js.map +1 -0
- package/src/web-components/elements/fmcp-select.d.ts +99 -0
- package/src/web-components/elements/fmcp-select.js +243 -0
- package/src/web-components/elements/fmcp-select.js.map +1 -0
- package/src/web-components/elements/index.d.ts +12 -0
- package/src/web-components/elements/index.js +34 -0
- package/src/web-components/elements/index.js.map +1 -0
- package/src/web-components/index.d.ts +49 -0
- package/src/web-components/index.js +75 -0
- package/src/web-components/index.js.map +1 -0
- package/src/web-components/register.d.ts +56 -0
- package/src/web-components/register.js +80 -0
- package/src/web-components/register.js.map +1 -0
- package/src/web-components/types.d.ts +121 -0
- package/src/web-components/types.js +25 -0
- package/src/web-components/types.js.map +1 -0
- package/src/widgets/index.d.ts +7 -0
- package/src/widgets/index.js +24 -0
- package/src/widgets/index.js.map +1 -0
- package/src/widgets/progress.d.ts +132 -0
- package/src/widgets/progress.js +303 -0
- package/src/widgets/progress.js.map +1 -0
- package/src/widgets/resource.d.ts +162 -0
- package/src/widgets/resource.js +340 -0
- package/src/widgets/resource.js.map +1 -0
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file tools.tsx
|
|
4
|
+
* @description React hooks for MCP tool interactions.
|
|
5
|
+
*
|
|
6
|
+
* Provides hooks for calling tools, accessing tool input/output,
|
|
7
|
+
* and managing tool execution state.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { useCallTool, useToolInput, useToolOutput } from '@frontmcp/ui/react';
|
|
12
|
+
*
|
|
13
|
+
* function WeatherWidget() {
|
|
14
|
+
* const input = useToolInput<{ location: string }>();
|
|
15
|
+
* const output = useToolOutput<WeatherData>();
|
|
16
|
+
* const [callWeather, { data, loading, error }] = useCallTool<WeatherData>('get_weather');
|
|
17
|
+
*
|
|
18
|
+
* return (
|
|
19
|
+
* <div>
|
|
20
|
+
* <p>Location: {input?.location}</p>
|
|
21
|
+
* <button onClick={() => callWeather({ location: 'NYC' })}>
|
|
22
|
+
* Get Weather
|
|
23
|
+
* </button>
|
|
24
|
+
* {loading && <p>Loading...</p>}
|
|
25
|
+
* {data && <p>Temperature: {data.temperature}</p>}
|
|
26
|
+
* </div>
|
|
27
|
+
* );
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @module @frontmcp/ui/react/hooks
|
|
32
|
+
*/
|
|
33
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
+
exports.useToolInput = useToolInput;
|
|
35
|
+
exports.useToolOutput = useToolOutput;
|
|
36
|
+
exports.useStructuredContent = useStructuredContent;
|
|
37
|
+
exports.useCallTool = useCallTool;
|
|
38
|
+
exports.useToolCalls = useToolCalls;
|
|
39
|
+
exports.useSendMessage = useSendMessage;
|
|
40
|
+
exports.useOpenLink = useOpenLink;
|
|
41
|
+
const react_1 = require("react");
|
|
42
|
+
const context_1 = require("./context");
|
|
43
|
+
// ============================================
|
|
44
|
+
// Tool Input/Output Hooks
|
|
45
|
+
// ============================================
|
|
46
|
+
/**
|
|
47
|
+
* Hook to get the current tool input arguments.
|
|
48
|
+
* Returns the arguments passed to the tool when it was invoked.
|
|
49
|
+
*
|
|
50
|
+
* @typeParam T - Expected shape of the tool input
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```tsx
|
|
54
|
+
* interface WeatherInput {
|
|
55
|
+
* location: string;
|
|
56
|
+
* units?: 'celsius' | 'fahrenheit';
|
|
57
|
+
* }
|
|
58
|
+
*
|
|
59
|
+
* function WeatherWidget() {
|
|
60
|
+
* const input = useToolInput<WeatherInput>();
|
|
61
|
+
*
|
|
62
|
+
* return (
|
|
63
|
+
* <div>
|
|
64
|
+
* <h1>Weather for {input?.location}</h1>
|
|
65
|
+
* <p>Units: {input?.units ?? 'celsius'}</p>
|
|
66
|
+
* </div>
|
|
67
|
+
* );
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
function useToolInput() {
|
|
72
|
+
const { bridge, ready } = (0, context_1.useMcpBridgeContext)();
|
|
73
|
+
if (!ready || !bridge) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
return bridge.getToolInput();
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Hook to get the current tool output/result.
|
|
85
|
+
* Returns the result data from the tool execution.
|
|
86
|
+
*
|
|
87
|
+
* @typeParam T - Expected shape of the tool output
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```tsx
|
|
91
|
+
* interface WeatherOutput {
|
|
92
|
+
* temperature: number;
|
|
93
|
+
* condition: string;
|
|
94
|
+
* humidity: number;
|
|
95
|
+
* }
|
|
96
|
+
*
|
|
97
|
+
* function WeatherDisplay() {
|
|
98
|
+
* const output = useToolOutput<WeatherOutput>();
|
|
99
|
+
*
|
|
100
|
+
* if (!output) return <div>No data</div>;
|
|
101
|
+
*
|
|
102
|
+
* return (
|
|
103
|
+
* <div>
|
|
104
|
+
* <p>Temperature: {output.temperature}°</p>
|
|
105
|
+
* <p>Condition: {output.condition}</p>
|
|
106
|
+
* </div>
|
|
107
|
+
* );
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
function useToolOutput() {
|
|
112
|
+
const { bridge, ready } = (0, context_1.useMcpBridgeContext)();
|
|
113
|
+
const [output, setOutput] = (0, react_1.useState)(null);
|
|
114
|
+
(0, react_1.useEffect)(() => {
|
|
115
|
+
if (!ready || !bridge)
|
|
116
|
+
return;
|
|
117
|
+
// Get initial output
|
|
118
|
+
try {
|
|
119
|
+
const initialOutput = bridge.getToolOutput();
|
|
120
|
+
if (initialOutput !== undefined) {
|
|
121
|
+
setOutput(initialOutput);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// Ignore
|
|
126
|
+
}
|
|
127
|
+
// Subscribe to tool result updates
|
|
128
|
+
const unsubscribe = bridge.onToolResult((result) => {
|
|
129
|
+
setOutput(result);
|
|
130
|
+
});
|
|
131
|
+
return unsubscribe;
|
|
132
|
+
}, [bridge, ready]);
|
|
133
|
+
return output;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Hook to get the structured content from the tool output.
|
|
137
|
+
* This is the parsed/structured version of the tool result.
|
|
138
|
+
*
|
|
139
|
+
* @typeParam T - Expected shape of the structured content
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```tsx
|
|
143
|
+
* interface WeatherData {
|
|
144
|
+
* forecast: Array<{ day: string; temp: number }>;
|
|
145
|
+
* }
|
|
146
|
+
*
|
|
147
|
+
* function ForecastDisplay() {
|
|
148
|
+
* const content = useStructuredContent<WeatherData>();
|
|
149
|
+
*
|
|
150
|
+
* return (
|
|
151
|
+
* <ul>
|
|
152
|
+
* {content?.forecast.map(day => (
|
|
153
|
+
* <li key={day.day}>{day.day}: {day.temp}°</li>
|
|
154
|
+
* ))}
|
|
155
|
+
* </ul>
|
|
156
|
+
* );
|
|
157
|
+
* }
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
function useStructuredContent() {
|
|
161
|
+
const { bridge, ready } = (0, context_1.useMcpBridgeContext)();
|
|
162
|
+
if (!ready || !bridge) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
const adapter = bridge.getAdapter?.();
|
|
167
|
+
if (adapter) {
|
|
168
|
+
return adapter.getStructuredContent();
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// ============================================
|
|
177
|
+
// Tool Execution Hooks
|
|
178
|
+
// ============================================
|
|
179
|
+
/**
|
|
180
|
+
* Hook to call an MCP tool with loading and error state management.
|
|
181
|
+
*
|
|
182
|
+
* Returns a tuple with:
|
|
183
|
+
* 1. The call function
|
|
184
|
+
* 2. State object (data, loading, error, called)
|
|
185
|
+
* 3. Reset function
|
|
186
|
+
*
|
|
187
|
+
* @typeParam TInput - Shape of the tool input arguments
|
|
188
|
+
* @typeParam TOutput - Expected shape of the tool output
|
|
189
|
+
*
|
|
190
|
+
* @example Basic usage
|
|
191
|
+
* ```tsx
|
|
192
|
+
* function WeatherButton() {
|
|
193
|
+
* const [getWeather, { data, loading, error }] = useCallTool<
|
|
194
|
+
* { location: string },
|
|
195
|
+
* { temperature: number; condition: string }
|
|
196
|
+
* >('get_weather');
|
|
197
|
+
*
|
|
198
|
+
* return (
|
|
199
|
+
* <div>
|
|
200
|
+
* <button
|
|
201
|
+
* onClick={() => getWeather({ location: 'San Francisco' })}
|
|
202
|
+
* disabled={loading}
|
|
203
|
+
* >
|
|
204
|
+
* {loading ? 'Loading...' : 'Get Weather'}
|
|
205
|
+
* </button>
|
|
206
|
+
* {error && <p className="error">{error.message}</p>}
|
|
207
|
+
* {data && <p>{data.temperature}° - {data.condition}</p>}
|
|
208
|
+
* </div>
|
|
209
|
+
* );
|
|
210
|
+
* }
|
|
211
|
+
* ```
|
|
212
|
+
*
|
|
213
|
+
* @example With callbacks
|
|
214
|
+
* ```tsx
|
|
215
|
+
* function WeatherWidget() {
|
|
216
|
+
* const [getWeather, state, reset] = useCallTool('get_weather', {
|
|
217
|
+
* onSuccess: (data) => console.log('Got weather:', data),
|
|
218
|
+
* onError: (err) => console.error('Failed:', err),
|
|
219
|
+
* });
|
|
220
|
+
*
|
|
221
|
+
* return (
|
|
222
|
+
* <div>
|
|
223
|
+
* <button onClick={() => getWeather({ location: 'NYC' })}>
|
|
224
|
+
* Get Weather
|
|
225
|
+
* </button>
|
|
226
|
+
* <button onClick={reset}>Reset</button>
|
|
227
|
+
* </div>
|
|
228
|
+
* );
|
|
229
|
+
* }
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
function useCallTool(toolName, options = {}) {
|
|
233
|
+
const { bridge, ready } = (0, context_1.useMcpBridgeContext)();
|
|
234
|
+
const { onSuccess, onError, resetOnToolChange = true } = options;
|
|
235
|
+
console.log('useCallTool', toolName, bridge);
|
|
236
|
+
const [state, setState] = (0, react_1.useState)({
|
|
237
|
+
data: null,
|
|
238
|
+
loading: false,
|
|
239
|
+
error: null,
|
|
240
|
+
called: false,
|
|
241
|
+
});
|
|
242
|
+
// Reset state when tool name changes
|
|
243
|
+
(0, react_1.useEffect)(() => {
|
|
244
|
+
if (resetOnToolChange) {
|
|
245
|
+
setState({
|
|
246
|
+
data: null,
|
|
247
|
+
loading: false,
|
|
248
|
+
error: null,
|
|
249
|
+
called: false,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}, [toolName, resetOnToolChange]);
|
|
253
|
+
const reset = (0, react_1.useCallback)(() => {
|
|
254
|
+
setState({
|
|
255
|
+
data: null,
|
|
256
|
+
loading: false,
|
|
257
|
+
error: null,
|
|
258
|
+
called: false,
|
|
259
|
+
});
|
|
260
|
+
}, []);
|
|
261
|
+
const callTool = (0, react_1.useCallback)(async (args) => {
|
|
262
|
+
if (!ready || !bridge) {
|
|
263
|
+
const error = new Error('Bridge not initialized');
|
|
264
|
+
setState((prev) => ({ ...prev, error, called: true }));
|
|
265
|
+
onError?.(error);
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
setState((prev) => ({
|
|
269
|
+
...prev,
|
|
270
|
+
loading: true,
|
|
271
|
+
error: null,
|
|
272
|
+
called: true,
|
|
273
|
+
}));
|
|
274
|
+
try {
|
|
275
|
+
const result = await bridge.callTool(toolName, args);
|
|
276
|
+
const data = result;
|
|
277
|
+
setState({
|
|
278
|
+
data,
|
|
279
|
+
loading: false,
|
|
280
|
+
error: null,
|
|
281
|
+
called: true,
|
|
282
|
+
});
|
|
283
|
+
onSuccess?.(data);
|
|
284
|
+
return data;
|
|
285
|
+
}
|
|
286
|
+
catch (err) {
|
|
287
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
288
|
+
setState({
|
|
289
|
+
data: null,
|
|
290
|
+
loading: false,
|
|
291
|
+
error,
|
|
292
|
+
called: true,
|
|
293
|
+
});
|
|
294
|
+
onError?.(error);
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
}, [bridge, ready, toolName, onSuccess, onError]);
|
|
298
|
+
return [callTool, state, reset];
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Hook to manage multiple tool calls.
|
|
302
|
+
* Useful when you need to track state for multiple tools.
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```tsx
|
|
306
|
+
* function MultiToolWidget() {
|
|
307
|
+
* const tools = useToolCalls({
|
|
308
|
+
* weather: 'get_weather',
|
|
309
|
+
* news: 'get_news',
|
|
310
|
+
* stocks: 'get_stocks',
|
|
311
|
+
* });
|
|
312
|
+
*
|
|
313
|
+
* return (
|
|
314
|
+
* <div>
|
|
315
|
+
* <button onClick={() => tools.weather.call({ location: 'NYC' })}>
|
|
316
|
+
* Get Weather
|
|
317
|
+
* </button>
|
|
318
|
+
* <button onClick={() => tools.news.call({ topic: 'tech' })}>
|
|
319
|
+
* Get News
|
|
320
|
+
* </button>
|
|
321
|
+
* {tools.weather.loading && <p>Loading weather...</p>}
|
|
322
|
+
* {tools.news.data && <p>News: {tools.news.data.headline}</p>}
|
|
323
|
+
* </div>
|
|
324
|
+
* );
|
|
325
|
+
* }
|
|
326
|
+
* ```
|
|
327
|
+
*/
|
|
328
|
+
function useToolCalls(toolMap) {
|
|
329
|
+
const bridge = (0, context_1.useMcpBridge)();
|
|
330
|
+
const [states, setStates] = (0, react_1.useState)(() => {
|
|
331
|
+
const initial = {};
|
|
332
|
+
for (const key of Object.keys(toolMap)) {
|
|
333
|
+
initial[key] = { data: null, loading: false, error: null, called: false };
|
|
334
|
+
}
|
|
335
|
+
return initial;
|
|
336
|
+
});
|
|
337
|
+
const createCallFn = (0, react_1.useCallback)((key, toolName) => async (args) => {
|
|
338
|
+
if (!bridge) {
|
|
339
|
+
setStates((prev) => ({
|
|
340
|
+
...prev,
|
|
341
|
+
[key]: {
|
|
342
|
+
...prev[key],
|
|
343
|
+
error: new Error('Bridge not initialized'),
|
|
344
|
+
called: true,
|
|
345
|
+
},
|
|
346
|
+
}));
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
setStates((prev) => ({
|
|
350
|
+
...prev,
|
|
351
|
+
[key]: { ...prev[key], loading: true, error: null, called: true },
|
|
352
|
+
}));
|
|
353
|
+
try {
|
|
354
|
+
const result = await bridge.callTool(toolName, args);
|
|
355
|
+
setStates((prev) => ({
|
|
356
|
+
...prev,
|
|
357
|
+
[key]: { data: result, loading: false, error: null, called: true },
|
|
358
|
+
}));
|
|
359
|
+
return result;
|
|
360
|
+
}
|
|
361
|
+
catch (err) {
|
|
362
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
363
|
+
setStates((prev) => ({
|
|
364
|
+
...prev,
|
|
365
|
+
[key]: { data: null, loading: false, error, called: true },
|
|
366
|
+
}));
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
}, [bridge]);
|
|
370
|
+
const createResetFn = (0, react_1.useCallback)((key) => () => {
|
|
371
|
+
setStates((prev) => ({
|
|
372
|
+
...prev,
|
|
373
|
+
[key]: { data: null, loading: false, error: null, called: false },
|
|
374
|
+
}));
|
|
375
|
+
}, []);
|
|
376
|
+
// Build result object
|
|
377
|
+
const result = {};
|
|
378
|
+
for (const [key, toolName] of Object.entries(toolMap)) {
|
|
379
|
+
const state = states[key] || {
|
|
380
|
+
data: null,
|
|
381
|
+
loading: false,
|
|
382
|
+
error: null,
|
|
383
|
+
called: false,
|
|
384
|
+
};
|
|
385
|
+
result[key] = {
|
|
386
|
+
call: createCallFn(key, toolName),
|
|
387
|
+
data: state.data,
|
|
388
|
+
loading: state.loading,
|
|
389
|
+
error: state.error,
|
|
390
|
+
reset: createResetFn(key),
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
return result;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Hook to send a message to the conversation.
|
|
397
|
+
* Returns a function and state for sending messages.
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* ```tsx
|
|
401
|
+
* function ChatWidget() {
|
|
402
|
+
* const [sendMessage, { loading, error, sent }] = useSendMessage();
|
|
403
|
+
*
|
|
404
|
+
* return (
|
|
405
|
+
* <button
|
|
406
|
+
* onClick={() => sendMessage('Here is the weather update!')}
|
|
407
|
+
* disabled={loading}
|
|
408
|
+
* >
|
|
409
|
+
* {loading ? 'Sending...' : 'Send Update'}
|
|
410
|
+
* </button>
|
|
411
|
+
* );
|
|
412
|
+
* }
|
|
413
|
+
* ```
|
|
414
|
+
*/
|
|
415
|
+
function useSendMessage() {
|
|
416
|
+
const bridge = (0, context_1.useMcpBridge)();
|
|
417
|
+
const [state, setState] = (0, react_1.useState)({
|
|
418
|
+
loading: false,
|
|
419
|
+
error: null,
|
|
420
|
+
sent: false,
|
|
421
|
+
});
|
|
422
|
+
const sendMessage = (0, react_1.useCallback)(async (content) => {
|
|
423
|
+
if (!bridge) {
|
|
424
|
+
setState({ loading: false, error: new Error('Bridge not initialized'), sent: false });
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
setState({ loading: true, error: null, sent: false });
|
|
428
|
+
try {
|
|
429
|
+
await bridge.sendMessage(content);
|
|
430
|
+
setState({ loading: false, error: null, sent: true });
|
|
431
|
+
}
|
|
432
|
+
catch (err) {
|
|
433
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
434
|
+
setState({ loading: false, error, sent: false });
|
|
435
|
+
}
|
|
436
|
+
}, [bridge]);
|
|
437
|
+
return [sendMessage, state];
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Hook to open external links via the bridge.
|
|
441
|
+
*
|
|
442
|
+
* @example
|
|
443
|
+
* ```tsx
|
|
444
|
+
* function LinkButton() {
|
|
445
|
+
* const openLink = useOpenLink();
|
|
446
|
+
*
|
|
447
|
+
* return (
|
|
448
|
+
* <button onClick={() => openLink('https://example.com')}>
|
|
449
|
+
* Open Website
|
|
450
|
+
* </button>
|
|
451
|
+
* );
|
|
452
|
+
* }
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
455
|
+
function useOpenLink() {
|
|
456
|
+
const bridge = (0, context_1.useMcpBridge)();
|
|
457
|
+
return (0, react_1.useCallback)(async (url) => {
|
|
458
|
+
if (!bridge) {
|
|
459
|
+
console.warn('Bridge not initialized, cannot open link');
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
await bridge.openLink(url);
|
|
463
|
+
}, [bridge]);
|
|
464
|
+
}
|
|
465
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../../src/react/hooks/tools.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file tools.tsx\n * @description React hooks for MCP tool interactions.\n *\n * Provides hooks for calling tools, accessing tool input/output,\n * and managing tool execution state.\n *\n * @example\n * ```tsx\n * import { useCallTool, useToolInput, useToolOutput } from '@frontmcp/ui/react';\n *\n * function WeatherWidget() {\n * const input = useToolInput<{ location: string }>();\n * const output = useToolOutput<WeatherData>();\n * const [callWeather, { data, loading, error }] = useCallTool<WeatherData>('get_weather');\n *\n * return (\n * <div>\n * <p>Location: {input?.location}</p>\n * <button onClick={() => callWeather({ location: 'NYC' })}>\n * Get Weather\n * </button>\n * {loading && <p>Loading...</p>}\n * {data && <p>Temperature: {data.temperature}</p>}\n * </div>\n * );\n * }\n * ```\n *\n * @module @frontmcp/ui/react/hooks\n */\n\nimport { useState, useCallback, useEffect } from 'react';\nimport { useMcpBridgeContext, useMcpBridge } from './context';\n\n// ============================================\n// Types\n// ============================================\n\n/**\n * State for tool execution.\n */\nexport interface ToolState<T = unknown> {\n /** Tool result data */\n data: T | null;\n /** Whether the tool is currently executing */\n loading: boolean;\n /** Execution error, if any */\n error: Error | null;\n /** Whether the tool has been called at least once */\n called: boolean;\n}\n\n/**\n * Options for useCallTool hook.\n */\nexport interface UseCallToolOptions {\n /** Automatically reset state when tool name changes */\n resetOnToolChange?: boolean;\n /** Callback when tool execution succeeds */\n onSuccess?: (data: unknown) => void;\n /** Callback when tool execution fails */\n onError?: (error: Error) => void;\n}\n\n/**\n * Return type for useCallTool hook.\n */\nexport type UseCallToolReturn<TInput extends object, TOutput> = [\n /** Function to call the tool */\n (args: TInput) => Promise<TOutput | null>,\n /** Current tool state */\n ToolState<TOutput>,\n /** Reset state to initial values */\n () => void,\n];\n\n// ============================================\n// Tool Input/Output Hooks\n// ============================================\n\n/**\n * Hook to get the current tool input arguments.\n * Returns the arguments passed to the tool when it was invoked.\n *\n * @typeParam T - Expected shape of the tool input\n *\n * @example\n * ```tsx\n * interface WeatherInput {\n * location: string;\n * units?: 'celsius' | 'fahrenheit';\n * }\n *\n * function WeatherWidget() {\n * const input = useToolInput<WeatherInput>();\n *\n * return (\n * <div>\n * <h1>Weather for {input?.location}</h1>\n * <p>Units: {input?.units ?? 'celsius'}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useToolInput<T extends object = Record<string, unknown>>(): T | null {\n const { bridge, ready } = useMcpBridgeContext();\n\n if (!ready || !bridge) {\n return null;\n }\n\n try {\n return bridge.getToolInput() as T;\n } catch {\n return null;\n }\n}\n\n/**\n * Hook to get the current tool output/result.\n * Returns the result data from the tool execution.\n *\n * @typeParam T - Expected shape of the tool output\n *\n * @example\n * ```tsx\n * interface WeatherOutput {\n * temperature: number;\n * condition: string;\n * humidity: number;\n * }\n *\n * function WeatherDisplay() {\n * const output = useToolOutput<WeatherOutput>();\n *\n * if (!output) return <div>No data</div>;\n *\n * return (\n * <div>\n * <p>Temperature: {output.temperature}°</p>\n * <p>Condition: {output.condition}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useToolOutput<T = unknown>(): T | null {\n const { bridge, ready } = useMcpBridgeContext();\n const [output, setOutput] = useState<T | null>(null);\n\n useEffect(() => {\n if (!ready || !bridge) return;\n\n // Get initial output\n try {\n const initialOutput = bridge.getToolOutput();\n if (initialOutput !== undefined) {\n setOutput(initialOutput as T);\n }\n } catch {\n // Ignore\n }\n\n // Subscribe to tool result updates\n const unsubscribe = bridge.onToolResult((result) => {\n setOutput(result as T);\n });\n\n return unsubscribe;\n }, [bridge, ready]);\n\n return output;\n}\n\n/**\n * Hook to get the structured content from the tool output.\n * This is the parsed/structured version of the tool result.\n *\n * @typeParam T - Expected shape of the structured content\n *\n * @example\n * ```tsx\n * interface WeatherData {\n * forecast: Array<{ day: string; temp: number }>;\n * }\n *\n * function ForecastDisplay() {\n * const content = useStructuredContent<WeatherData>();\n *\n * return (\n * <ul>\n * {content?.forecast.map(day => (\n * <li key={day.day}>{day.day}: {day.temp}°</li>\n * ))}\n * </ul>\n * );\n * }\n * ```\n */\nexport function useStructuredContent<T = unknown>(): T | null {\n const { bridge, ready } = useMcpBridgeContext();\n\n if (!ready || !bridge) {\n return null;\n }\n\n try {\n const adapter = bridge.getAdapter?.();\n if (adapter) {\n return adapter.getStructuredContent() as T;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n// ============================================\n// Tool Execution Hooks\n// ============================================\n\n/**\n * Hook to call an MCP tool with loading and error state management.\n *\n * Returns a tuple with:\n * 1. The call function\n * 2. State object (data, loading, error, called)\n * 3. Reset function\n *\n * @typeParam TInput - Shape of the tool input arguments\n * @typeParam TOutput - Expected shape of the tool output\n *\n * @example Basic usage\n * ```tsx\n * function WeatherButton() {\n * const [getWeather, { data, loading, error }] = useCallTool<\n * { location: string },\n * { temperature: number; condition: string }\n * >('get_weather');\n *\n * return (\n * <div>\n * <button\n * onClick={() => getWeather({ location: 'San Francisco' })}\n * disabled={loading}\n * >\n * {loading ? 'Loading...' : 'Get Weather'}\n * </button>\n * {error && <p className=\"error\">{error.message}</p>}\n * {data && <p>{data.temperature}° - {data.condition}</p>}\n * </div>\n * );\n * }\n * ```\n *\n * @example With callbacks\n * ```tsx\n * function WeatherWidget() {\n * const [getWeather, state, reset] = useCallTool('get_weather', {\n * onSuccess: (data) => console.log('Got weather:', data),\n * onError: (err) => console.error('Failed:', err),\n * });\n *\n * return (\n * <div>\n * <button onClick={() => getWeather({ location: 'NYC' })}>\n * Get Weather\n * </button>\n * <button onClick={reset}>Reset</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useCallTool<TInput extends object = Record<string, unknown>, TOutput = unknown>(\n toolName: string,\n options: UseCallToolOptions = {},\n): UseCallToolReturn<TInput, TOutput> {\n const { bridge, ready } = useMcpBridgeContext();\n const { onSuccess, onError, resetOnToolChange = true } = options;\n\n console.log('useCallTool', toolName, bridge);\n const [state, setState] = useState<ToolState<TOutput>>({\n data: null,\n loading: false,\n error: null,\n called: false,\n });\n\n // Reset state when tool name changes\n useEffect(() => {\n if (resetOnToolChange) {\n setState({\n data: null,\n loading: false,\n error: null,\n called: false,\n });\n }\n }, [toolName, resetOnToolChange]);\n\n const reset = useCallback(() => {\n setState({\n data: null,\n loading: false,\n error: null,\n called: false,\n });\n }, []);\n\n const callTool = useCallback(\n async (args: TInput): Promise<TOutput | null> => {\n if (!ready || !bridge) {\n const error = new Error('Bridge not initialized');\n setState((prev) => ({ ...prev, error, called: true }));\n onError?.(error);\n return null;\n }\n\n setState((prev) => ({\n ...prev,\n loading: true,\n error: null,\n called: true,\n }));\n\n try {\n const result = await bridge.callTool(toolName, args as Record<string, unknown>);\n const data = result as TOutput;\n\n setState({\n data,\n loading: false,\n error: null,\n called: true,\n });\n\n onSuccess?.(data);\n return data;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n\n setState({\n data: null,\n loading: false,\n error,\n called: true,\n });\n\n onError?.(error);\n return null;\n }\n },\n [bridge, ready, toolName, onSuccess, onError],\n );\n\n return [callTool, state, reset];\n}\n\n/**\n * Hook to manage multiple tool calls.\n * Useful when you need to track state for multiple tools.\n *\n * @example\n * ```tsx\n * function MultiToolWidget() {\n * const tools = useToolCalls({\n * weather: 'get_weather',\n * news: 'get_news',\n * stocks: 'get_stocks',\n * });\n *\n * return (\n * <div>\n * <button onClick={() => tools.weather.call({ location: 'NYC' })}>\n * Get Weather\n * </button>\n * <button onClick={() => tools.news.call({ topic: 'tech' })}>\n * Get News\n * </button>\n * {tools.weather.loading && <p>Loading weather...</p>}\n * {tools.news.data && <p>News: {tools.news.data.headline}</p>}\n * </div>\n * );\n * }\n * ```\n */\nexport function useToolCalls<T extends Record<string, string>>(\n toolMap: T,\n): {\n [K in keyof T]: {\n call: (args: Record<string, unknown>) => Promise<unknown>;\n data: unknown;\n loading: boolean;\n error: Error | null;\n reset: () => void;\n };\n} {\n const bridge = useMcpBridge();\n const [states, setStates] = useState<Record<string, ToolState<unknown>>>(() => {\n const initial: Record<string, ToolState<unknown>> = {};\n for (const key of Object.keys(toolMap)) {\n initial[key] = { data: null, loading: false, error: null, called: false };\n }\n return initial;\n });\n\n const createCallFn = useCallback(\n (key: string, toolName: string) =>\n async (args: Record<string, unknown>): Promise<unknown> => {\n if (!bridge) {\n setStates((prev) => ({\n ...prev,\n [key]: {\n ...prev[key],\n error: new Error('Bridge not initialized'),\n called: true,\n },\n }));\n return null;\n }\n\n setStates((prev) => ({\n ...prev,\n [key]: { ...prev[key], loading: true, error: null, called: true },\n }));\n\n try {\n const result = await bridge.callTool(toolName, args);\n setStates((prev) => ({\n ...prev,\n [key]: { data: result, loading: false, error: null, called: true },\n }));\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setStates((prev) => ({\n ...prev,\n [key]: { data: null, loading: false, error, called: true },\n }));\n return null;\n }\n },\n [bridge],\n );\n\n const createResetFn = useCallback(\n (key: string) => () => {\n setStates((prev) => ({\n ...prev,\n [key]: { data: null, loading: false, error: null, called: false },\n }));\n },\n [],\n );\n\n // Build result object\n const result = {} as {\n [K in keyof T]: {\n call: (args: Record<string, unknown>) => Promise<unknown>;\n data: unknown;\n loading: boolean;\n error: Error | null;\n reset: () => void;\n };\n };\n\n for (const [key, toolName] of Object.entries(toolMap)) {\n const state = states[key] || {\n data: null,\n loading: false,\n error: null,\n called: false,\n };\n result[key as keyof T] = {\n call: createCallFn(key, toolName),\n data: state.data,\n loading: state.loading,\n error: state.error,\n reset: createResetFn(key),\n };\n }\n\n return result;\n}\n\n/**\n * Hook to send a message to the conversation.\n * Returns a function and state for sending messages.\n *\n * @example\n * ```tsx\n * function ChatWidget() {\n * const [sendMessage, { loading, error, sent }] = useSendMessage();\n *\n * return (\n * <button\n * onClick={() => sendMessage('Here is the weather update!')}\n * disabled={loading}\n * >\n * {loading ? 'Sending...' : 'Send Update'}\n * </button>\n * );\n * }\n * ```\n */\nexport function useSendMessage(): [\n (content: string) => Promise<void>,\n { loading: boolean; error: Error | null; sent: boolean },\n] {\n const bridge = useMcpBridge();\n const [state, setState] = useState({\n loading: false,\n error: null as Error | null,\n sent: false,\n });\n\n const sendMessage = useCallback(\n async (content: string): Promise<void> => {\n if (!bridge) {\n setState({ loading: false, error: new Error('Bridge not initialized'), sent: false });\n return;\n }\n\n setState({ loading: true, error: null, sent: false });\n\n try {\n await bridge.sendMessage(content);\n setState({ loading: false, error: null, sent: true });\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setState({ loading: false, error, sent: false });\n }\n },\n [bridge],\n );\n\n return [sendMessage, state];\n}\n\n/**\n * Hook to open external links via the bridge.\n *\n * @example\n * ```tsx\n * function LinkButton() {\n * const openLink = useOpenLink();\n *\n * return (\n * <button onClick={() => openLink('https://example.com')}>\n * Open Website\n * </button>\n * );\n * }\n * ```\n */\nexport function useOpenLink(): (url: string) => Promise<void> {\n const bridge = useMcpBridge();\n\n return useCallback(\n async (url: string): Promise<void> => {\n if (!bridge) {\n console.warn('Bridge not initialized, cannot open link');\n return;\n }\n\n await bridge.openLink(url);\n },\n [bridge],\n );\n}\n"]}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file index.ts
|
|
3
|
+
* @description React components and hooks for FrontMCP UI.
|
|
4
|
+
*
|
|
5
|
+
* These are pure React components that can be used:
|
|
6
|
+
* 1. As regular React components in your app
|
|
7
|
+
* 2. To generate static HTML via render functions
|
|
8
|
+
* 3. With hooks to access the MCP bridge
|
|
9
|
+
*
|
|
10
|
+
* @example React usage
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import { Card, Badge, Button, Alert } from '@frontmcp/ui/react';
|
|
13
|
+
*
|
|
14
|
+
* function App() {
|
|
15
|
+
* return (
|
|
16
|
+
* <Card title="Welcome" variant="elevated">
|
|
17
|
+
* <Badge variant="success">New</Badge>
|
|
18
|
+
* <p>Card content here</p>
|
|
19
|
+
* <Button variant="primary">Click Me</Button>
|
|
20
|
+
* </Card>
|
|
21
|
+
* );
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @example Static HTML generation
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { renderCard, renderBadge } from '@frontmcp/ui/react';
|
|
28
|
+
*
|
|
29
|
+
* const cardHtml = await renderCard({
|
|
30
|
+
* title: 'Welcome',
|
|
31
|
+
* variant: 'elevated',
|
|
32
|
+
* children: '<p>Content</p>',
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @example Using hooks with the MCP bridge
|
|
37
|
+
* ```tsx
|
|
38
|
+
* import {
|
|
39
|
+
* McpBridgeProvider,
|
|
40
|
+
* useMcpBridge,
|
|
41
|
+
* useToolInput,
|
|
42
|
+
* useCallTool,
|
|
43
|
+
* useTheme,
|
|
44
|
+
* } from '@frontmcp/ui/react';
|
|
45
|
+
*
|
|
46
|
+
* function App() {
|
|
47
|
+
* return (
|
|
48
|
+
* <McpBridgeProvider>
|
|
49
|
+
* <WeatherWidget />
|
|
50
|
+
* </McpBridgeProvider>
|
|
51
|
+
* );
|
|
52
|
+
* }
|
|
53
|
+
*
|
|
54
|
+
* function WeatherWidget() {
|
|
55
|
+
* const input = useToolInput<{ location: string }>();
|
|
56
|
+
* const theme = useTheme();
|
|
57
|
+
* const [getWeather, { data, loading }] = useCallTool('get_weather');
|
|
58
|
+
*
|
|
59
|
+
* return (
|
|
60
|
+
* <Card title={`Weather for ${input?.location}`} variant={theme === 'dark' ? 'elevated' : 'default'}>
|
|
61
|
+
* {loading ? 'Loading...' : data?.temperature}
|
|
62
|
+
* </Card>
|
|
63
|
+
* );
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* @module @frontmcp/ui/react
|
|
68
|
+
*/
|
|
69
|
+
export { Card, renderCard, renderCardSync } from './Card';
|
|
70
|
+
export { Badge, renderBadge, renderBadgeSync } from './Badge';
|
|
71
|
+
export { Button, renderButton, renderButtonSync } from './Button';
|
|
72
|
+
export { Alert, renderAlert, renderAlertSync } from './Alert';
|
|
73
|
+
export { McpBridgeProvider, useMcpBridgeContext, useMcpBridge, useTheme, useDisplayMode, useHostContext, useCapability, useToolInput, useToolOutput, useStructuredContent, useCallTool, useToolCalls, useSendMessage, useOpenLink, type McpBridgeContextValue, type McpBridgeProviderProps, type ToolState, type UseCallToolOptions, type UseCallToolReturn, } from './hooks';
|
|
74
|
+
export type { CardProps, CardRenderProps, CardVariant, CardSize } from './Card';
|
|
75
|
+
export type { BadgeProps, BadgeRenderProps, BadgeVariant, BadgeSize } from './Badge';
|
|
76
|
+
export type { ButtonProps, ButtonRenderProps, ButtonVariant, ButtonSize } from './Button';
|
|
77
|
+
export type { AlertProps, AlertRenderProps, AlertVariant } from './Alert';
|
|
78
|
+
export type { FmcpCard, FmcpBadge, FmcpButton, FmcpAlert } from './types';
|
|
79
|
+
export type { CardOptions, BadgeOptions, ButtonOptions, AlertOptions } from './types';
|
|
80
|
+
export { renderChildrenToString, isBrowser, isServer } from './utils';
|