skybridge 0.0.0-dev.d675894 → 0.0.0-dev.d6a0dd5
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/dist/src/server/templates/development.hbs +1 -1
- package/dist/src/server/templates/production.hbs +1 -1
- package/dist/src/web/bridges/apps-sdk-adapter.d.ts +3 -1
- package/dist/src/web/bridges/apps-sdk-adapter.js +7 -1
- package/dist/src/web/bridges/apps-sdk-adapter.js.map +1 -1
- package/dist/src/web/bridges/get-bridge-methods.d.ts +1 -1
- package/dist/src/web/bridges/get-bridge-methods.js +2 -2
- package/dist/src/web/bridges/get-bridge-methods.js.map +1 -1
- package/dist/src/web/bridges/hooks/types.d.ts +6 -0
- package/dist/src/web/bridges/hooks/types.js +2 -0
- package/dist/src/web/bridges/hooks/types.js.map +1 -0
- package/dist/src/web/bridges/hooks/use-bridge.d.ts +2 -2
- package/dist/src/web/bridges/hooks/use-bridge.js +6 -44
- package/dist/src/web/bridges/hooks/use-bridge.js.map +1 -1
- package/dist/src/web/bridges/hooks/use-mcp-app-bridge.d.ts +3 -2
- package/dist/src/web/bridges/hooks/use-mcp-app-bridge.js +1 -1
- package/dist/src/web/bridges/hooks/use-mcp-app-bridge.js.map +1 -1
- package/dist/src/web/bridges/hooks/use-mcp-app-bridge.test.js +19 -27
- package/dist/src/web/bridges/hooks/use-mcp-app-bridge.test.js.map +1 -1
- package/dist/src/web/bridges/index.d.ts +1 -0
- package/dist/src/web/bridges/index.js +1 -0
- package/dist/src/web/bridges/index.js.map +1 -1
- package/dist/src/web/bridges/mcp-app-adapter.d.ts +5 -1
- package/dist/src/web/bridges/mcp-app-adapter.js +70 -2
- package/dist/src/web/bridges/mcp-app-adapter.js.map +1 -1
- package/dist/src/web/bridges/mcp-app-bridge.d.ts +13 -5
- package/dist/src/web/bridges/mcp-app-bridge.js +55 -25
- package/dist/src/web/bridges/mcp-app-bridge.js.map +1 -1
- package/dist/src/web/bridges/types.d.ts +24 -0
- package/dist/src/web/generate-helpers.test-d.js +4 -1
- package/dist/src/web/generate-helpers.test-d.js.map +1 -1
- package/dist/src/web/hooks/test/utils.d.ts +10 -0
- package/dist/src/web/hooks/test/utils.js +39 -0
- package/dist/src/web/hooks/test/utils.js.map +1 -0
- package/dist/src/web/hooks/use-call-tool.js +12 -4
- package/dist/src/web/hooks/use-call-tool.js.map +1 -1
- package/dist/src/web/hooks/use-call-tool.test.js +26 -0
- package/dist/src/web/hooks/use-call-tool.test.js.map +1 -1
- package/dist/src/web/hooks/use-send-follow-up-message.js +2 -7
- package/dist/src/web/hooks/use-send-follow-up-message.js.map +1 -1
- package/dist/src/web/hooks/use-tool-info.d.ts +12 -1
- package/dist/src/web/hooks/use-tool-info.js +15 -9
- package/dist/src/web/hooks/use-tool-info.js.map +1 -1
- package/dist/src/web/hooks/use-tool-info.test-d.js +40 -4
- package/dist/src/web/hooks/use-tool-info.test-d.js.map +1 -1
- package/dist/src/web/hooks/use-tool-info.test.js +116 -47
- package/dist/src/web/hooks/use-tool-info.test.js.map +1 -1
- package/dist/src/web/hooks/use-user.js +2 -2
- package/dist/src/web/hooks/use-user.js.map +1 -1
- package/dist/src/web/types.d.ts +2 -4
- package/dist/src/web/types.js.map +1 -1
- package/package.json +5 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<base href="{{serverUrl}}" />
|
|
2
|
-
<script>
|
|
2
|
+
<script type="module">window.skybridge = { hostType: "{{hostType}}" };</script>
|
|
3
3
|
<script type="module">
|
|
4
4
|
import { injectIntoGlobalHook } from "{{serverUrl}}/@react-refresh";
|
|
5
5
|
injectIntoGlobalHook(window); window.$RefreshReg$ = () => {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<base href="{{serverUrl}}" />
|
|
2
|
-
<script>
|
|
2
|
+
<script type="module">window.skybridge = { hostType: "{{hostType}}" };</script>
|
|
3
3
|
<div id="root"></div>
|
|
4
4
|
<script type="module">
|
|
5
5
|
import('{{serverUrl}}/assets/{{widgetFile}}');
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
import type { Methods } from "./types";
|
|
1
|
+
import type { CallToolResponse, Methods } from "./types.js";
|
|
2
|
+
export declare const callTool: <ToolArgs extends Record<string, unknown> | null = null, ToolResponse extends CallToolResponse = CallToolResponse>(name: string, args: ToolArgs) => Promise<ToolResponse>;
|
|
2
3
|
export declare const requestDisplayMode: Methods["requestDisplayMode"];
|
|
4
|
+
export declare const sendFollowUpMessage: Methods["sendFollowUpMessage"];
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const callTool = async (name, args) => {
|
|
2
|
+
return window.openai.callTool(name, args);
|
|
3
|
+
};
|
|
4
|
+
export const requestDisplayMode = ({ mode }) => {
|
|
2
5
|
return window.openai.requestDisplayMode({ mode });
|
|
3
6
|
};
|
|
7
|
+
export const sendFollowUpMessage = (prompt) => {
|
|
8
|
+
return window.openai.sendFollowUpMessage({ prompt });
|
|
9
|
+
};
|
|
4
10
|
//# sourceMappingURL=apps-sdk-adapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps-sdk-adapter.js","sourceRoot":"","sources":["../../../../src/web/bridges/apps-sdk-adapter.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAkC,CAAC,
|
|
1
|
+
{"version":3,"file":"apps-sdk-adapter.js","sourceRoot":"","sources":["../../../../src/web/bridges/apps-sdk-adapter.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAI3B,IAAY,EACZ,IAAc,EACS,EAAE;IACzB,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAyB,IAAI,EAAE,IAAI,CAAC,CAAC;AACpE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAkC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;IAC5E,OAAO,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAmC,CAAC,MAAM,EAAE,EAAE;IAC5E,OAAO,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;AACvD,CAAC,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Methods } from "./types";
|
|
1
|
+
import type { Methods } from "./types.js";
|
|
2
2
|
export declare const getBridgeMethods: () => Methods;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as AppsSdkAdapter from "./apps-sdk-adapter";
|
|
2
|
-
import * as McpAppAdapter from "./mcp-app-adapter";
|
|
1
|
+
import * as AppsSdkAdapter from "./apps-sdk-adapter.js";
|
|
2
|
+
import * as McpAppAdapter from "./mcp-app-adapter.js";
|
|
3
3
|
export const getBridgeMethods = () => {
|
|
4
4
|
return window.skybridge.hostType === "apps-sdk"
|
|
5
5
|
? AppsSdkAdapter
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-bridge-methods.js","sourceRoot":"","sources":["../../../../src/web/bridges/get-bridge-methods.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,cAAc,MAAM,
|
|
1
|
+
{"version":3,"file":"get-bridge-methods.js","sourceRoot":"","sources":["../../../../src/web/bridges/get-bridge-methods.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AAGtD,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAY,EAAE;IAC5C,OAAO,MAAM,CAAC,SAAS,CAAC,QAAQ,KAAK,UAAU;QAC7C,CAAC,CAAC,cAAc;QAChB,CAAC,CAAC,aAAa,CAAC;AACpB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/types.ts"],"names":[],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { BridgeInterface } from "../types";
|
|
2
|
-
export declare const useBridge: <K extends keyof BridgeInterface>(key: K
|
|
1
|
+
import type { BridgeInterface } from "../types.js";
|
|
2
|
+
export declare const useBridge: <K extends keyof BridgeInterface>(key: K) => BridgeInterface[K];
|
|
@@ -1,21 +1,7 @@
|
|
|
1
1
|
import { useSyncExternalStore } from "react";
|
|
2
|
-
import { AppsSdkBridge } from "../apps-sdk-bridge";
|
|
3
|
-
import {
|
|
4
|
-
const
|
|
5
|
-
theme: "light",
|
|
6
|
-
locale: "en-US",
|
|
7
|
-
displayMode: "inline",
|
|
8
|
-
safeArea: {
|
|
9
|
-
insets: {
|
|
10
|
-
top: 0,
|
|
11
|
-
right: 0,
|
|
12
|
-
bottom: 0,
|
|
13
|
-
left: 0,
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
maxHeight: window.innerHeight,
|
|
17
|
-
};
|
|
18
|
-
const getExternalStore = (key, defaultValue = DEFAULT_VALUE_FOR_MCP_APP_BRIDGE[key]) => {
|
|
2
|
+
import { AppsSdkBridge } from "../apps-sdk-bridge.js";
|
|
3
|
+
import { getMcpAppAdapter } from "../mcp-app-adapter.js";
|
|
4
|
+
const getExternalStore = (key) => {
|
|
19
5
|
const hostType = window.skybridge.hostType;
|
|
20
6
|
if (hostType === "apps-sdk") {
|
|
21
7
|
const bridge = AppsSdkBridge.getInstance();
|
|
@@ -24,34 +10,10 @@ const getExternalStore = (key, defaultValue = DEFAULT_VALUE_FOR_MCP_APP_BRIDGE[k
|
|
|
24
10
|
getSnapshot: () => bridge.getSnapshot(key),
|
|
25
11
|
};
|
|
26
12
|
}
|
|
27
|
-
|
|
28
|
-
if (key === "safeArea") {
|
|
29
|
-
return {
|
|
30
|
-
subscribe: bridge.subscribe("safeAreaInsets"),
|
|
31
|
-
getSnapshot: () => {
|
|
32
|
-
const safeArea = bridge.getSnapshot("safeAreaInsets");
|
|
33
|
-
return safeArea
|
|
34
|
-
? { insets: safeArea }
|
|
35
|
-
: defaultValue;
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
if (key === "maxHeight") {
|
|
40
|
-
return {
|
|
41
|
-
subscribe: bridge.subscribe("viewport"),
|
|
42
|
-
getSnapshot: () => {
|
|
43
|
-
const viewport = bridge.getSnapshot("viewport");
|
|
44
|
-
return (viewport?.maxHeight ?? defaultValue);
|
|
45
|
-
},
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
subscribe: bridge.subscribe(key),
|
|
50
|
-
getSnapshot: () => (bridge.getSnapshot(key) ?? defaultValue),
|
|
51
|
-
};
|
|
13
|
+
return getMcpAppAdapter()[key];
|
|
52
14
|
};
|
|
53
|
-
export const useBridge = (key
|
|
54
|
-
const externalStore = getExternalStore(key
|
|
15
|
+
export const useBridge = (key) => {
|
|
16
|
+
const externalStore = getExternalStore(key);
|
|
55
17
|
return useSyncExternalStore(externalStore.subscribe, externalStore.getSnapshot);
|
|
56
18
|
};
|
|
57
19
|
//# sourceMappingURL=use-bridge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-bridge.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/use-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"use-bridge.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/use-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAIzD,MAAM,gBAAgB,GAAG,CACvB,GAAM,EACkB,EAAE;IAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC;IAC3C,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;QAC3C,OAAO;YACL,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;YAChC,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC;SAC3C,CAAC;IACJ,CAAC;IAED,OAAO,gBAAgB,EAAE,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,GAAM,EACc,EAAE;IACtB,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE5C,OAAO,oBAAoB,CACzB,aAAa,CAAC,SAAS,EACvB,aAAa,CAAC,WAAW,CAC1B,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { McpUiInitializeRequest } from "@modelcontextprotocol/ext-apps";
|
|
2
|
+
import { type McpAppBridgeContext } from "../mcp-app-bridge.js";
|
|
2
3
|
type McpAppInitializationOptions = Pick<McpUiInitializeRequest["params"], "appInfo">;
|
|
3
|
-
export declare function useMcpAppBridge<K extends keyof
|
|
4
|
+
export declare function useMcpAppBridge<K extends keyof McpAppBridgeContext>(key: K, options?: Partial<McpAppInitializationOptions>, requestTimeout?: number): McpAppBridgeContext[K];
|
|
4
5
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useSyncExternalStore } from "react";
|
|
2
|
-
import { McpAppBridge } from "../mcp-app-bridge";
|
|
2
|
+
import { McpAppBridge } from "../mcp-app-bridge.js";
|
|
3
3
|
export function useMcpAppBridge(key, options, requestTimeout) {
|
|
4
4
|
const bridge = McpAppBridge.getInstance(options, requestTimeout);
|
|
5
5
|
return useSyncExternalStore(bridge.subscribe(key), () => bridge.getSnapshot(key));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-mcp-app-bridge.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/use-mcp-app-bridge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-mcp-app-bridge.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/use-mcp-app-bridge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,YAAY,EAA4B,MAAM,sBAAsB,CAAC;AAO9E,MAAM,UAAU,eAAe,CAC7B,GAAM,EACN,OAA8C,EAC9C,cAAuB;IAEvB,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACjE,OAAO,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CACtD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CACxB,CAAC;AACJ,CAAC"}
|
|
@@ -1,52 +1,44 @@
|
|
|
1
|
-
import { act, renderHook, waitFor } from "@testing-library/react";
|
|
1
|
+
import { act, fireEvent, renderHook, waitFor } from "@testing-library/react";
|
|
2
2
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
+
import { MCPAppHostPostMessageMock } from "../../hooks/test/utils.js";
|
|
3
4
|
import { McpAppBridge } from "../mcp-app-bridge.js";
|
|
4
5
|
import { useMcpAppBridge } from "./use-mcp-app-bridge.js";
|
|
5
6
|
describe("useMcpAppBridge", () => {
|
|
6
|
-
let mockPostMessage;
|
|
7
7
|
beforeEach(async () => {
|
|
8
|
-
|
|
9
|
-
Object.defineProperty(window, "parent", {
|
|
10
|
-
value: { postMessage: mockPostMessage },
|
|
11
|
-
writable: true,
|
|
12
|
-
configurable: true,
|
|
13
|
-
});
|
|
8
|
+
vi.stubGlobal("parent", { postMessage: MCPAppHostPostMessageMock });
|
|
14
9
|
vi.stubGlobal("skybridge", { hostType: "mcp-app" });
|
|
15
10
|
McpAppBridge.resetInstance();
|
|
16
11
|
});
|
|
17
12
|
afterEach(() => {
|
|
18
13
|
vi.clearAllMocks();
|
|
19
14
|
});
|
|
20
|
-
it("should return the theme value from host context", async () => {
|
|
15
|
+
it("should return the theme value from host context and update on notification", async () => {
|
|
21
16
|
const { result } = renderHook(() => useMcpAppBridge("theme"));
|
|
22
|
-
const initCall = mockPostMessage.mock.calls.find((call) => call[0].method === "ui/initialize");
|
|
23
|
-
if (initCall) {
|
|
24
|
-
act(() => {
|
|
25
|
-
window.dispatchEvent(new MessageEvent("message", {
|
|
26
|
-
data: {
|
|
27
|
-
jsonrpc: "2.0",
|
|
28
|
-
id: initCall[0].id,
|
|
29
|
-
result: {
|
|
30
|
-
protocolVersion: "2025-06-18",
|
|
31
|
-
hostInfo: { name: "test-host", version: "1.0.0" },
|
|
32
|
-
hostCapabilities: {},
|
|
33
|
-
hostContext: { theme: "light" },
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
}));
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
17
|
await waitFor(() => {
|
|
40
18
|
expect(result.current).toBe("light");
|
|
41
19
|
});
|
|
20
|
+
fireEvent(window, new MessageEvent("message", {
|
|
21
|
+
data: {
|
|
22
|
+
jsonrpc: "2.0",
|
|
23
|
+
method: "ui/notifications/host-context-changed",
|
|
24
|
+
params: {
|
|
25
|
+
theme: "dark",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
}));
|
|
29
|
+
await waitFor(() => {
|
|
30
|
+
expect(result.current).toBe("dark");
|
|
31
|
+
});
|
|
42
32
|
});
|
|
43
33
|
it("should reject the request after timeout", async () => {
|
|
44
34
|
vi.useFakeTimers();
|
|
45
35
|
const consoleErrorSpy = vi
|
|
46
36
|
.spyOn(console, "error")
|
|
47
37
|
.mockImplementation(() => { });
|
|
38
|
+
const nonRespondingMock = vi.fn();
|
|
39
|
+
vi.stubGlobal("parent", { postMessage: nonRespondingMock });
|
|
48
40
|
renderHook(() => useMcpAppBridge("theme", undefined, 100));
|
|
49
|
-
expect(
|
|
41
|
+
expect(nonRespondingMock).toHaveBeenCalledWith(expect.objectContaining({ method: "ui/initialize" }), "*");
|
|
50
42
|
await act(async () => {
|
|
51
43
|
await vi.advanceTimersByTimeAsync(100);
|
|
52
44
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-mcp-app-bridge.test.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/use-mcp-app-bridge.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"use-mcp-app-bridge.test.js","sourceRoot":"","sources":["../../../../../src/web/bridges/hooks/use-mcp-app-bridge.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACpE,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;QACpD,YAAY,CAAC,aAAa,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;QAC1F,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QAE9D,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,SAAS,CACP,MAAM,EACN,IAAI,YAAY,CAAC,SAAS,EAAE;YAC1B,IAAI,EAAE;gBACJ,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,uCAAuC;gBAC/C,MAAM,EAAE;oBACN,KAAK,EAAE,MAAM;iBACd;aACF;SACF,CAAC,CACH,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,eAAe,GAAG,EAAE;aACvB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC;aACvB,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAEhC,MAAM,iBAAiB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAE5D,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;QAE3D,MAAM,CAAC,iBAAiB,CAAC,CAAC,oBAAoB,CAC5C,MAAM,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,EACpD,GAAG,CACJ,CAAC;QAEF,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE;YACnB,MAAM,EAAE,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAC/B,CAAC;QAEF,eAAe,CAAC,WAAW,EAAE,CAAC;QAC9B,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/web/bridges/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/web/bridges/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC"}
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BridgeExternalStore } from "./hooks/types.js";
|
|
2
|
+
import type { BridgeInterface, CallToolResponse, Methods } from "./types.js";
|
|
3
|
+
export declare const callTool: <ToolArgs extends Record<string, unknown> | null = null, ToolResponse extends CallToolResponse = CallToolResponse>(name: string, args: ToolArgs) => Promise<ToolResponse>;
|
|
2
4
|
export declare const requestDisplayMode: Methods["requestDisplayMode"];
|
|
5
|
+
export declare const sendFollowUpMessage: Methods["sendFollowUpMessage"];
|
|
6
|
+
export declare const getMcpAppAdapter: () => { [K in keyof BridgeInterface]: BridgeExternalStore<K>; };
|
|
@@ -1,5 +1,26 @@
|
|
|
1
|
-
import { McpAppBridge } from "./mcp-app-bridge";
|
|
2
|
-
export const
|
|
1
|
+
import { McpAppBridge, } from "./mcp-app-bridge.js";
|
|
2
|
+
export const callTool = async (name, args) => {
|
|
3
|
+
const bridge = McpAppBridge.getInstance();
|
|
4
|
+
const response = await bridge.request({
|
|
5
|
+
method: "tools/call",
|
|
6
|
+
params: {
|
|
7
|
+
name,
|
|
8
|
+
arguments: args ?? undefined,
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
const result = response.content
|
|
12
|
+
.filter((content) => content.type === "text")
|
|
13
|
+
.map(({ text }) => text)
|
|
14
|
+
.join("\n");
|
|
15
|
+
return {
|
|
16
|
+
content: response.content,
|
|
17
|
+
structuredContent: response.structuredContent ?? {},
|
|
18
|
+
isError: response.isError ?? false,
|
|
19
|
+
result,
|
|
20
|
+
meta: response._meta ?? {},
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export const requestDisplayMode = ({ mode }) => {
|
|
3
24
|
const bridge = McpAppBridge.getInstance();
|
|
4
25
|
if (mode !== "modal") {
|
|
5
26
|
return bridge.request({
|
|
@@ -9,4 +30,51 @@ export const requestDisplayMode = ({ mode, }) => {
|
|
|
9
30
|
}
|
|
10
31
|
throw new Error("Modal display mode is not accessible in MCP App.");
|
|
11
32
|
};
|
|
33
|
+
export const sendFollowUpMessage = async (prompt) => {
|
|
34
|
+
const bridge = McpAppBridge.getInstance();
|
|
35
|
+
await bridge.request({
|
|
36
|
+
method: "ui/message",
|
|
37
|
+
params: {
|
|
38
|
+
role: "user",
|
|
39
|
+
content: [
|
|
40
|
+
{
|
|
41
|
+
type: "text",
|
|
42
|
+
text: prompt,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
const createExternalStore = (keys, getSnapshot) => {
|
|
49
|
+
const bridge = McpAppBridge.getInstance();
|
|
50
|
+
return {
|
|
51
|
+
subscribe: bridge.subscribe(keys),
|
|
52
|
+
getSnapshot: () => {
|
|
53
|
+
const context = Object.fromEntries(keys.map((k) => [k, bridge.getSnapshot(k)]));
|
|
54
|
+
return getSnapshot(context);
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
export const getMcpAppAdapter = () => ({
|
|
59
|
+
theme: createExternalStore(["theme"], ({ theme }) => theme ?? "light"),
|
|
60
|
+
locale: createExternalStore(["locale"], ({ locale }) => locale ?? "en-US"),
|
|
61
|
+
safeArea: createExternalStore(["safeAreaInsets"], ({ safeAreaInsets }) => ({
|
|
62
|
+
insets: safeAreaInsets ?? { top: 0, right: 0, bottom: 0, left: 0 },
|
|
63
|
+
})),
|
|
64
|
+
displayMode: createExternalStore(["displayMode"], ({ displayMode }) => displayMode ?? "inline"),
|
|
65
|
+
maxHeight: createExternalStore(["viewport"], ({ viewport }) => viewport?.maxHeight ?? window.innerHeight),
|
|
66
|
+
userAgent: createExternalStore(["platform", "deviceCapabilities"], ({ platform, deviceCapabilities }) => ({
|
|
67
|
+
device: {
|
|
68
|
+
type: platform === "web" ? "desktop" : (platform ?? "unknown"),
|
|
69
|
+
},
|
|
70
|
+
capabilities: {
|
|
71
|
+
hover: true,
|
|
72
|
+
touch: true,
|
|
73
|
+
...deviceCapabilities,
|
|
74
|
+
},
|
|
75
|
+
})),
|
|
76
|
+
toolInput: createExternalStore(["toolInput"], ({ toolInput }) => toolInput ?? null),
|
|
77
|
+
toolOutput: createExternalStore(["toolResult"], ({ toolResult }) => toolResult?.structuredContent ?? null),
|
|
78
|
+
toolResponseMetadata: createExternalStore(["toolResult"], ({ toolResult }) => toolResult?._meta ?? null),
|
|
79
|
+
});
|
|
12
80
|
//# sourceMappingURL=mcp-app-adapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-app-adapter.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app-adapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mcp-app-adapter.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import type { McpUiHostContext, McpUiInitializeRequest } from "@modelcontextprotocol/ext-apps";
|
|
1
|
+
import type { McpUiHostContext, McpUiInitializeRequest, McpUiToolCancelledNotification, McpUiToolInputNotification, McpUiToolResultNotification } from "@modelcontextprotocol/ext-apps";
|
|
2
2
|
type McpAppInitializationOptions = Pick<McpUiInitializeRequest["params"], "appInfo">;
|
|
3
|
+
export type McpToolState = {
|
|
4
|
+
toolInput: NonNullable<McpUiToolInputNotification["params"]["arguments"]> | null;
|
|
5
|
+
toolResult: McpUiToolResultNotification["params"] | null;
|
|
6
|
+
toolCancelled: McpUiToolCancelledNotification["params"] | null;
|
|
7
|
+
};
|
|
8
|
+
export type McpAppBridgeContext = McpUiHostContext & McpToolState;
|
|
9
|
+
export type McpAppBridgeKey = keyof McpAppBridgeContext;
|
|
3
10
|
export declare class McpAppBridge {
|
|
4
11
|
private static instance;
|
|
5
|
-
context:
|
|
12
|
+
context: McpAppBridgeContext;
|
|
6
13
|
private listeners;
|
|
7
14
|
private pendingRequests;
|
|
8
15
|
private nextId;
|
|
@@ -11,8 +18,9 @@ export declare class McpAppBridge {
|
|
|
11
18
|
private requestTimeout;
|
|
12
19
|
constructor(options: McpAppInitializationOptions, requestTimeout?: number);
|
|
13
20
|
static getInstance(options?: Partial<McpAppInitializationOptions>, requestTimeout?: number): McpAppBridge;
|
|
14
|
-
subscribe
|
|
15
|
-
|
|
21
|
+
subscribe(key: McpAppBridgeKey): (onChange: () => void) => () => void;
|
|
22
|
+
subscribe(keys: readonly McpAppBridgeKey[]): (onChange: () => void) => () => void;
|
|
23
|
+
getSnapshot<K extends keyof McpAppBridgeContext>(key: K): McpAppBridgeContext[K];
|
|
16
24
|
cleanup: () => void;
|
|
17
25
|
static resetInstance(): void;
|
|
18
26
|
request<R extends {
|
|
@@ -20,7 +28,7 @@ export declare class McpAppBridge {
|
|
|
20
28
|
params?: unknown;
|
|
21
29
|
}, T>({ method, params, }: R): Promise<T>;
|
|
22
30
|
private emit;
|
|
23
|
-
private
|
|
31
|
+
private updateContext;
|
|
24
32
|
private init;
|
|
25
33
|
private handleMessage;
|
|
26
34
|
private connect;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
const LATEST_PROTOCOL_VERSION = "2025-11-21";
|
|
2
2
|
export class McpAppBridge {
|
|
3
3
|
static instance = null;
|
|
4
|
-
context =
|
|
4
|
+
context = {
|
|
5
|
+
toolInput: null,
|
|
6
|
+
toolCancelled: null,
|
|
7
|
+
toolResult: null,
|
|
8
|
+
};
|
|
5
9
|
listeners = new Map();
|
|
6
10
|
pendingRequests = new Map();
|
|
7
11
|
nextId = 1;
|
|
@@ -32,14 +36,23 @@ export class McpAppBridge {
|
|
|
32
36
|
}
|
|
33
37
|
return McpAppBridge.instance;
|
|
34
38
|
}
|
|
35
|
-
subscribe
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
subscribe(keyOrKeys) {
|
|
40
|
+
const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];
|
|
41
|
+
return (onChange) => {
|
|
42
|
+
for (const key of keys) {
|
|
43
|
+
this.listeners.set(key, new Set([...(this.listeners.get(key) || []), onChange]));
|
|
44
|
+
}
|
|
45
|
+
this.init();
|
|
46
|
+
return () => {
|
|
47
|
+
for (const key of keys) {
|
|
48
|
+
this.listeners.get(key)?.delete(onChange);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
getSnapshot(key) {
|
|
54
|
+
return this.context[key];
|
|
55
|
+
}
|
|
43
56
|
cleanup = () => {
|
|
44
57
|
window.removeEventListener("message", this.handleMessage);
|
|
45
58
|
this.pendingRequests.forEach((request) => {
|
|
@@ -73,10 +86,8 @@ export class McpAppBridge {
|
|
|
73
86
|
listener();
|
|
74
87
|
});
|
|
75
88
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return;
|
|
79
|
-
this.context = context;
|
|
89
|
+
updateContext(context) {
|
|
90
|
+
this.context = { ...this.context, ...context };
|
|
80
91
|
for (const key of Object.keys(context)) {
|
|
81
92
|
this.emit(key);
|
|
82
93
|
}
|
|
@@ -93,21 +104,40 @@ export class McpAppBridge {
|
|
|
93
104
|
}
|
|
94
105
|
handleMessage = (event) => {
|
|
95
106
|
const data = event.data;
|
|
96
|
-
if (data
|
|
107
|
+
if (data.jsonrpc !== "2.0")
|
|
97
108
|
return;
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
109
|
+
if ("id" in data) {
|
|
110
|
+
const request = this.pendingRequests.get(data.id);
|
|
111
|
+
if (request) {
|
|
112
|
+
clearTimeout(request.timeout);
|
|
113
|
+
this.pendingRequests.delete(data.id);
|
|
114
|
+
if ("error" in data) {
|
|
115
|
+
request.reject(new Error(data.error.message));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
request.resolve(data.result);
|
|
105
119
|
}
|
|
106
|
-
request.resolve(data.result);
|
|
107
120
|
return;
|
|
108
121
|
}
|
|
109
|
-
|
|
110
|
-
|
|
122
|
+
switch (data.method) {
|
|
123
|
+
case "ui/notifications/host-context-changed":
|
|
124
|
+
this.updateContext(data.params);
|
|
125
|
+
return;
|
|
126
|
+
case "ui/notifications/tool-input":
|
|
127
|
+
this.updateContext({
|
|
128
|
+
toolInput: data.params.arguments ?? {},
|
|
129
|
+
});
|
|
130
|
+
return;
|
|
131
|
+
case "ui/notifications/tool-result":
|
|
132
|
+
this.updateContext({
|
|
133
|
+
toolResult: data.params,
|
|
134
|
+
});
|
|
135
|
+
return;
|
|
136
|
+
case "ui/notifications/tool-cancelled":
|
|
137
|
+
this.updateContext({
|
|
138
|
+
toolCancelled: data.params,
|
|
139
|
+
});
|
|
140
|
+
return;
|
|
111
141
|
}
|
|
112
142
|
};
|
|
113
143
|
async connect() {
|
|
@@ -116,7 +146,7 @@ export class McpAppBridge {
|
|
|
116
146
|
method: "ui/initialize",
|
|
117
147
|
params: this.appInitializationOptions,
|
|
118
148
|
});
|
|
119
|
-
this.
|
|
149
|
+
this.updateContext(result.hostContext);
|
|
120
150
|
this.notify({ method: "ui/notifications/initialized" });
|
|
121
151
|
}
|
|
122
152
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-app-bridge.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app-bridge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mcp-app-bridge.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app-bridge.ts"],"names":[],"mappings":"AAkCA,MAAM,uBAAuB,GAAG,YAAY,CAAC;AAqB7C,MAAM,OAAO,YAAY;IACf,MAAM,CAAC,QAAQ,GAAwB,IAAI,CAAC;IAC7C,OAAO,GAAwB;QACpC,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,UAAU,EAAE,IAAI;KACjB,CAAC;IACM,SAAS,GAAG,IAAI,GAAG,EAAoC,CAAC;IACxD,eAAe,GAAG,IAAI,GAAG,EAA4C,CAAC;IACtE,MAAM,GAAG,CAAC,CAAC;IACX,WAAW,CAAU;IACrB,wBAAwB,CAAmC;IAC3D,cAAc,CAAS;IAE/B,YACE,OAAoC,EACpC,iBAAyB,MAAM;QAE/B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,wBAAwB,GAAG;YAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,eAAe,EAAE,EAAE;YACnB,eAAe,EAAE,uBAAuB;SACzC,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,WAAW,CACvB,OAA8C,EAC9C,cAAuB;QAEvB,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,YAAY,CAAC,QAAQ,IAAI,CAAC,OAAO,IAAI,cAAc,CAAC,EAAE,CAAC;YACzD,OAAO,CAAC,IAAI,CACV,uFAAuF,CACxF,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC3B,MAAM,cAAc,GAAgC;gBAClD,OAAO,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE;aACrD,CAAC;YACF,YAAY,CAAC,QAAQ,GAAG,IAAI,YAAY,CACtC,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,EACjC,cAAc,CACf,CAAC;QACJ,CAAC;QACD,OAAO,YAAY,CAAC,QAAQ,CAAC;IAC/B,CAAC;IAMM,SAAS,CACd,SAAuD;QAEvD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAChE,OAAO,CAAC,QAAoB,EAAE,EAAE;YAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,SAAS,CAAC,GAAG,CAChB,GAAG,EACH,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CACxD,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,OAAO,GAAG,EAAE;gBACV,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC;IAEM,WAAW,CAChB,GAAM;QAEN,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAEM,OAAO,GAAG,GAAG,EAAE;QACpB,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1D,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACvC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC,CAAC;IAEK,MAAM,CAAC,aAAa;QACzB,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC1B,YAAY,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAChC,YAAY,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC/B,CAAC;IACH,CAAC;IAEM,OAAO,CAAoD,EAChE,MAAM,EACN,MAAM,GACJ;QACF,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,EAAK,CAAC;QAChE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE;YAC3B,OAAO,EAAE,OAAmC;YAC5C,MAAM;YACN,OAAO,EAAE,UAAU,CAAC,GAAG,EAAE;gBACvB,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;gBACvC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAClC,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC;SACxB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;QAEvE,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,IAAI,CAAC,GAAoB;QAC/B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC5C,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,OAAqC;QACzD,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;QAC/C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAEO,IAAI;QACV,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAExB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAEO,aAAa,GAAG,CACtB,KAAwD,EACxD,EAAE;QACF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACxB,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK;YAAE,OAAO;QAEnC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClD,IAAI,OAAO,EAAE,CAAC;gBACZ,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBAC9B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACrC,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;oBACpB,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC9C,OAAO;gBACT,CAAC;gBAED,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;YAED,OAAO;QACT,CAAC;QAED,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;YACpB,KAAK,uCAAuC;gBAC1C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAChC,OAAO;YACT,KAAK,6BAA6B;gBAChC,IAAI,CAAC,aAAa,CAAC;oBACjB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE;iBACvC,CAAC,CAAC;gBACH,OAAO;YACT,KAAK,8BAA8B;gBACjC,IAAI,CAAC,aAAa,CAAC;oBACjB,UAAU,EAAE,IAAI,CAAC,MAAM;iBACxB,CAAC,CAAC;gBACH,OAAO;YACT,KAAK,iCAAiC;gBACpC,IAAI,CAAC,aAAa,CAAC;oBACjB,aAAa,EAAE,IAAI,CAAC,MAAM;iBAC3B,CAAC,CAAC;gBACH,OAAO;QACX,CAAC;IACH,CAAC,CAAC;IAEM,KAAK,CAAC,OAAO;QACnB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAG/B;gBACA,MAAM,EAAE,eAAe;gBACvB,MAAM,EAAE,IAAI,CAAC,wBAAwB;aACtC,CAAC,CAAC;YAEH,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,YAA0C;QACvD,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,YAAY,EAAE,EAAE,GAAG,CAAC,CAAC;IACtE,CAAC"}
|
|
@@ -1,11 +1,23 @@
|
|
|
1
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export type CallToolArgs = Record<string, unknown> | null;
|
|
3
|
+
export type CallToolResponse = {
|
|
4
|
+
content: CallToolResult["content"];
|
|
5
|
+
structuredContent: NonNullable<CallToolResult["structuredContent"]>;
|
|
6
|
+
isError: NonNullable<CallToolResult["isError"]>;
|
|
7
|
+
result: string;
|
|
8
|
+
meta: NonNullable<CallToolResult["_meta"]>;
|
|
9
|
+
};
|
|
1
10
|
export type Methods = {
|
|
11
|
+
callTool<ToolArgs extends CallToolArgs = null, ToolResponse extends CallToolResponse = CallToolResponse>(name: string, args: ToolArgs): Promise<ToolResponse>;
|
|
2
12
|
requestDisplayMode({ mode }: {
|
|
3
13
|
mode: DisplayMode;
|
|
4
14
|
}): Promise<{
|
|
5
15
|
mode: DisplayMode;
|
|
6
16
|
}>;
|
|
17
|
+
sendFollowUpMessage(prompt: string): Promise<void>;
|
|
7
18
|
};
|
|
8
19
|
export type DisplayMode = "pip" | "inline" | "fullscreen" | "modal";
|
|
20
|
+
export type DeviceType = "mobile" | "tablet" | "desktop" | "unknown";
|
|
9
21
|
export interface BridgeInterface {
|
|
10
22
|
theme: "light" | "dark";
|
|
11
23
|
locale: string;
|
|
@@ -19,4 +31,16 @@ export interface BridgeInterface {
|
|
|
19
31
|
};
|
|
20
32
|
};
|
|
21
33
|
maxHeight: number;
|
|
34
|
+
userAgent: {
|
|
35
|
+
device: {
|
|
36
|
+
type: DeviceType;
|
|
37
|
+
};
|
|
38
|
+
capabilities: {
|
|
39
|
+
hover: boolean;
|
|
40
|
+
touch: boolean;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
toolInput: Record<string, unknown> | null;
|
|
44
|
+
toolOutput: Record<string, unknown> | null;
|
|
45
|
+
toolResponseMetadata: Record<string, unknown> | null;
|
|
22
46
|
}
|
|
@@ -154,7 +154,10 @@ test("generateHelpers provides autocomplete for tool names in useToolInfo (widge
|
|
|
154
154
|
test("useToolInfo infers input and output types", () => {
|
|
155
155
|
const { useToolInfo } = generateHelpers();
|
|
156
156
|
const toolInfo = useToolInfo();
|
|
157
|
-
|
|
157
|
+
// Input is only available when not in idle state
|
|
158
|
+
if (!(toolInfo.status === "idle")) {
|
|
159
|
+
expectTypeOf(toolInfo.input).toExtend();
|
|
160
|
+
}
|
|
158
161
|
if (toolInfo.status === "success") {
|
|
159
162
|
expectTypeOf(toolInfo.output).toExtend();
|
|
160
163
|
expectTypeOf(toolInfo.output.results).toBeArray();
|