skybridge 2.0.3 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/dist/cli/run-plain.js +2 -1
- package/dist/cli/run-plain.js.map +1 -1
- package/dist/cli/use-nodemon.d.ts +11 -1
- package/dist/cli/use-nodemon.js +19 -5
- package/dist/cli/use-nodemon.js.map +1 -1
- package/dist/commands/dev.js +3 -3
- package/dist/commands/dev.js.map +1 -1
- package/dist/server/app.d.ts +22 -5
- package/dist/server/app.js +24 -13
- package/dist/server/app.js.map +1 -1
- package/dist/server/app.test.js +81 -0
- package/dist/server/app.test.js.map +1 -1
- package/dist/server/auth/providers/custom.d.ts +4 -2
- package/dist/server/auth/providers/custom.js.map +1 -1
- package/dist/server/auth/providers/workos.d.ts +3 -2
- package/dist/server/auth/providers/workos.js +2 -1
- package/dist/server/auth/providers/workos.js.map +1 -1
- package/dist/server/auth/verify.d.ts +5 -3
- package/dist/server/auth/verify.js.map +1 -1
- package/dist/server/auth/verify.test.js +16 -0
- package/dist/server/auth/verify.test.js.map +1 -1
- package/dist/server/events.d.ts +113 -0
- package/dist/server/events.js +318 -0
- package/dist/server/events.js.map +1 -0
- package/dist/server/events.test.d.ts +1 -0
- package/dist/server/events.test.js +172 -0
- package/dist/server/events.test.js.map +1 -0
- package/dist/server/express.d.ts +3 -2
- package/dist/server/express.js +17 -11
- package/dist/server/express.js.map +1 -1
- package/dist/server/express.test.js +45 -0
- package/dist/server/express.test.js.map +1 -1
- package/dist/server/form-input.d.ts +120 -0
- package/dist/server/form-input.js +89 -0
- package/dist/server/form-input.js.map +1 -0
- package/dist/server/index.d.ts +4 -2
- package/dist/server/index.js +3 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp-errors.test.js +188 -0
- package/dist/server/mcp-errors.test.js.map +1 -1
- package/dist/server/metric.d.ts +5 -3
- package/dist/server/metric.js +5 -5
- package/dist/server/metric.js.map +1 -1
- package/dist/server/register-tool.test.js +203 -0
- package/dist/server/register-tool.test.js.map +1 -1
- package/dist/server/server.d.ts +254 -10
- package/dist/server/server.js +262 -9
- package/dist/server/server.js.map +1 -1
- package/dist/server/tool-extra.test.js +79 -0
- package/dist/server/tool-extra.test.js.map +1 -1
- package/dist/web/bridges/adaptor.d.ts +14 -3
- package/dist/web/bridges/adaptor.js +164 -14
- package/dist/web/bridges/adaptor.js.map +1 -1
- package/dist/web/bridges/adaptor.test.js +62 -6
- package/dist/web/bridges/adaptor.test.js.map +1 -1
- package/dist/web/bridges/apps-sdk/bridge.js +1 -1
- package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
- package/dist/web/bridges/apps-sdk/types.d.ts +2 -3
- package/dist/web/bridges/apps-sdk/types.js.map +1 -1
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +3 -3
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +3 -3
- package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
- package/dist/web/bridges/mcp-app/bridge.d.ts +1 -1
- package/dist/web/bridges/mcp-app/bridge.js +9 -2
- package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
- package/dist/web/bridges/mcp-app/types.d.ts +18 -3
- package/dist/web/bridges/mcp-app/types.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +2 -2
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
- package/dist/web/bridges/types.d.ts +57 -4
- package/dist/web/bridges/types.js +1 -1
- package/dist/web/bridges/types.js.map +1 -1
- package/dist/web/data-llm.js +3 -2
- package/dist/web/data-llm.js.map +1 -1
- package/dist/web/data-llm.test.js +6 -0
- package/dist/web/data-llm.test.js.map +1 -1
- package/dist/web/generate-helpers.d.ts +2 -2
- package/dist/web/generate-helpers.js +2 -2
- package/dist/web/generate-helpers.js.map +1 -1
- package/dist/web/hooks/index.d.ts +5 -1
- package/dist/web/hooks/index.js +5 -1
- package/dist/web/hooks/index.js.map +1 -1
- package/dist/web/hooks/openai-extensions.test.d.ts +1 -0
- package/dist/web/hooks/openai-extensions.test.js +107 -0
- package/dist/web/hooks/openai-extensions.test.js.map +1 -0
- package/dist/web/hooks/use-call-tool.d.ts +2 -2
- package/dist/web/hooks/use-call-tool.js +15 -10
- package/dist/web/hooks/use-call-tool.js.map +1 -1
- package/dist/web/hooks/use-call-tool.test.js +13 -2
- package/dist/web/hooks/use-call-tool.test.js.map +1 -1
- package/dist/web/hooks/use-deep-link.d.ts +22 -0
- package/dist/web/hooks/use-deep-link.js +34 -0
- package/dist/web/hooks/use-deep-link.js.map +1 -0
- package/dist/web/hooks/use-file-resource.d.ts +37 -0
- package/dist/web/hooks/use-file-resource.js +98 -0
- package/dist/web/hooks/use-file-resource.js.map +1 -0
- package/dist/web/hooks/use-file-resource.test.d.ts +1 -0
- package/dist/web/hooks/use-file-resource.test.js +65 -0
- package/dist/web/hooks/use-file-resource.test.js.map +1 -0
- package/dist/web/hooks/use-host.d.ts +27 -5
- package/dist/web/hooks/use-host.js +20 -5
- package/dist/web/hooks/use-host.js.map +1 -1
- package/dist/web/hooks/use-model-context.d.ts +44 -0
- package/dist/web/hooks/use-model-context.js +63 -0
- package/dist/web/hooks/use-model-context.js.map +1 -0
- package/dist/web/hooks/use-open-file.d.ts +20 -0
- package/dist/web/hooks/use-open-file.js +25 -0
- package/dist/web/hooks/use-open-file.js.map +1 -0
- package/dist/web/hooks/use-register-view-tool.d.ts +1 -1
- package/dist/web/hooks/use-register-view-tool.js +1 -1
- package/dist/web/hooks/use-register-view-tool.js.map +1 -1
- package/dist/web/hooks/use-send-follow-up-message.d.ts +8 -2
- package/dist/web/hooks/use-send-follow-up-message.js +6 -0
- package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adaptor.test.js","sourceRoot":"","sources":["../../../src/web/bridges/adaptor.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { VIEW_STATE_WARNING_TOKENS } from \"../../context-warnings.js\";\nimport { HostAdaptor } from \"./adaptor.js\";\nimport { AppsSdkBridge } from \"./apps-sdk/bridge.js\";\nimport { McpAppBridge } from \"./mcp-app/bridge.js\";\nimport { NotSupportedError } from \"./types.js\";\n\ndescribe(\"HostAdaptor\", () => {\n beforeEach(() => {\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"skybridge\", {});\n vi.stubGlobal(\"parent\", { postMessage: vi.fn() });\n localStorage.clear();\n });\n afterEach(() => {\n vi.unstubAllGlobals();\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n localStorage.clear();\n });\n\n it(\"callTool always routes to mcp.callServerTool\", async () => {\n vi.stubGlobal(\"openai\", { callTool: vi.fn() });\n const adaptor = new HostAdaptor();\n const fakeApp = {\n callServerTool: vi.fn().mockResolvedValue({\n content: [],\n structuredContent: { ok: true },\n isError: false,\n _meta: { x: 1 },\n }),\n };\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n (adaptor as any).mcp.getApp = vi.fn().mockResolvedValue(fakeApp);\n\n const result = await adaptor.callTool(\"greet\", { name: \"alice\" });\n expect(fakeApp.callServerTool).toHaveBeenCalledWith({\n name: \"greet\",\n arguments: { name: \"alice\" },\n });\n expect(result.structuredContent).toEqual({ ok: true });\n expect(result.meta).toEqual({ x: 1 });\n });\n\n it(\"download returns isError when host lacks downloadFile capability\", async () => {\n vi.stubGlobal(\"openai\", undefined);\n const adaptor = new HostAdaptor();\n const fakeApp = {\n getHostCapabilities: () => ({}),\n downloadFile: vi.fn(),\n };\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n (adaptor as any).mcp.getApp = vi.fn().mockResolvedValue(fakeApp);\n const r = await adaptor.download({ contents: [] });\n expect(r.isError).toBe(true);\n expect(fakeApp.downloadFile).not.toHaveBeenCalled();\n });\n\n it(\"sendFollowUpMessage routes to window.openai only when scrollToBottom is set\", async () => {\n const sendFollowUpMessage = vi.fn().mockResolvedValue(undefined);\n vi.stubGlobal(\"openai\", { sendFollowUpMessage });\n let adaptor = new HostAdaptor();\n await adaptor.sendFollowUpMessage(\"hi\", { scrollToBottom: false });\n expect(sendFollowUpMessage).toHaveBeenCalledWith({\n prompt: \"hi\",\n scrollToBottom: false,\n });\n\n // Default case falls through to MCP\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"openai\", undefined);\n adaptor = new HostAdaptor();\n const sendMessage = vi.fn().mockResolvedValue(undefined);\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n (adaptor as any).mcp.getApp = vi.fn().mockResolvedValue({ sendMessage });\n await adaptor.sendFollowUpMessage(\"hi\");\n expect(sendMessage).toHaveBeenCalledWith({\n role: \"user\",\n content: [{ type: \"text\", text: \"hi\" }],\n });\n });\n\n it(\"openExternal routes to window.openai only when redirectUrl: false\", async () => {\n const openExternal = vi.fn();\n vi.stubGlobal(\"openai\", { openExternal });\n let adaptor = new HostAdaptor();\n adaptor.openExternal(\"https://x\", { redirectUrl: false });\n expect(openExternal).toHaveBeenCalledWith({\n href: \"https://x\",\n redirectUrl: false,\n });\n\n // Default case falls through to MCP openLink\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"openai\", undefined);\n adaptor = new HostAdaptor();\n const openLink = vi.fn();\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n (adaptor as any).mcp.getApp = vi.fn().mockResolvedValue({ openLink });\n adaptor.openExternal(\"https://x\");\n await new Promise((r) => setTimeout(r, 0));\n expect(openLink).toHaveBeenCalledWith({ url: \"https://x\" });\n });\n\n it(\"Apps-SDK-exclusive methods throw NotSupportedError when window.openai is null\", async () => {\n vi.stubGlobal(\"openai\", undefined);\n const adaptor = new HostAdaptor();\n await expect(adaptor.uploadFile(new File([], \"x\"))).rejects.toThrow(\n NotSupportedError,\n );\n await expect(adaptor.selectFiles()).rejects.toThrow(NotSupportedError);\n await expect(adaptor.getFileDownloadUrl({ fileId: \"x\" })).rejects.toThrow(\n NotSupportedError,\n );\n await expect(adaptor.setOpenInAppUrl(\"https://x\")).rejects.toThrow(\n NotSupportedError,\n );\n });\n\n it(\"uploadFile delegates to window.openai.uploadFile and tracks fileId in widgetState\", async () => {\n const setWidgetState = vi.fn().mockResolvedValue(undefined);\n const uploadFile = vi.fn().mockResolvedValue({\n fileId: \"abc\",\n fileName: \"x\",\n mimeType: \"image/png\",\n });\n vi.stubGlobal(\"openai\", { uploadFile, setWidgetState, widgetState: null });\n const adaptor = new HostAdaptor();\n const file = new File([], \"x\", { type: \"image/png\" });\n const r = await adaptor.uploadFile(file, { library: true });\n expect(uploadFile).toHaveBeenCalledWith(file, { library: true });\n expect(r.fileId).toBe(\"abc\");\n expect(setWidgetState).toHaveBeenCalledWith(\n expect.objectContaining({ imageIds: [\"abc\"] }),\n );\n });\n\n it(\"uploadFile does not track a non-image fileId in widgetState.imageIds\", async () => {\n const setWidgetState = vi.fn().mockResolvedValue(undefined);\n const uploadFile = vi.fn().mockResolvedValue({\n fileId: \"sediment://file_txt\",\n fileName: \"notes.txt\",\n mimeType: \"text/plain\",\n });\n vi.stubGlobal(\"openai\", { uploadFile, setWidgetState, widgetState: null });\n const adaptor = new HostAdaptor();\n\n await adaptor.uploadFile(new File([], \"notes.txt\", { type: \"text/plain\" }));\n\n for (const call of setWidgetState.mock.calls) {\n expect(call[0].imageIds ?? []).not.toContain(\"sediment://file_txt\");\n }\n });\n\n it(\"setViewState uses window.openai.setWidgetState when present\", async () => {\n const setWidgetState = vi.fn().mockResolvedValue(undefined);\n vi.stubGlobal(\"openai\", { setWidgetState, widgetState: null });\n const adaptor = new HostAdaptor();\n await adaptor.setViewState({ count: 1 });\n expect(setWidgetState).toHaveBeenCalledWith(\n expect.objectContaining({ modelContent: { count: 1 } }),\n );\n });\n\n it(\"warns when setViewState reaches 20K tokens\", async () => {\n const setWidgetState = vi.fn().mockResolvedValue(undefined);\n vi.stubGlobal(\"openai\", { setWidgetState, widgetState: null });\n const adaptor = new HostAdaptor();\n const warnSpy = vi.spyOn(console, \"warn\").mockImplementation(() => {});\n\n await adaptor.setViewState({\n longText: \"x\".repeat(VIEW_STATE_WARNING_TOKENS * 4),\n });\n\n expect(warnSpy).toHaveBeenCalledWith(\n expect.stringContaining(\"setWidgetState is persisting\"),\n );\n\n warnSpy.mockRestore();\n });\n\n it(\"setViewState falls back to MCP updateModelContext + localStorage when window.openai is absent\", async () => {\n vi.stubGlobal(\"openai\", undefined);\n const adaptor = new HostAdaptor();\n const updateModelContext = vi.fn().mockResolvedValue(undefined);\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n (adaptor as any).mcp.getApp = vi\n .fn()\n .mockResolvedValue({ updateModelContext });\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n (adaptor as any)._viewUUID = \"view-1\";\n await adaptor.setViewState({ count: 2 });\n expect(updateModelContext).toHaveBeenCalledWith({\n structuredContent: { count: 2 },\n content: [{ type: \"text\", text: JSON.stringify({ count: 2 }) }],\n });\n const keys: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key !== null) {\n keys.push(key);\n }\n }\n expect(keys.some((k) => k.endsWith(\":view-1\"))).toBe(true);\n });\n\n it(\"openModal/closeModal: delegates to window.openai.requestModal when present, polyfill state otherwise\", () => {\n const requestModal = vi.fn();\n vi.stubGlobal(\"openai\", { requestModal });\n let adaptor = new HostAdaptor();\n adaptor.openModal({ title: \"Hi\" });\n expect(requestModal).toHaveBeenCalledWith({ title: \"Hi\" });\n expect(() => adaptor.closeModal()).not.toThrow();\n\n // Polyfill path\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"openai\", undefined);\n adaptor = new HostAdaptor();\n adaptor.openModal({ params: { x: 1 } });\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n expect((adaptor as any)._polyfillDisplay).toEqual({\n mode: \"modal\",\n params: { x: 1 },\n });\n adaptor.closeModal();\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n expect((adaptor as any)._polyfillDisplay).toEqual({ mode: \"inline\" });\n });\n\n it(\"getHostContextStore: display/viewState route to Apps SDK overlay when present, MCP otherwise\", () => {\n vi.stubGlobal(\"openai\", {\n view: { mode: \"fullscreen\" },\n widgetState: { modelContent: { count: 5 }, privateContent: {} },\n });\n let adaptor = new HostAdaptor();\n expect(adaptor.getHostContextStore(\"display\").getSnapshot()).toEqual({\n mode: \"fullscreen\",\n });\n expect(adaptor.getHostContextStore(\"viewState\").getSnapshot()).toEqual({\n count: 5,\n });\n // Other keys (theme) always flow through MCP; default fallback when no notification\n expect(adaptor.getHostContextStore(\"theme\").getSnapshot()).toBe(\"light\");\n\n // Polyfill / local-state path\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"openai\", undefined);\n adaptor = new HostAdaptor();\n expect(adaptor.getHostContextStore(\"display\").getSnapshot()).toEqual({\n mode: \"inline\",\n });\n expect(adaptor.getHostContextStore(\"viewState\").getSnapshot()).toBe(null);\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"adaptor.test.js","sourceRoot":"","sources":["../../../src/web/bridges/adaptor.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { VIEW_STATE_WARNING_TOKENS } from \"../../context-warnings.js\";\nimport { HostAdaptor } from \"./adaptor.js\";\nimport { AppsSdkBridge } from \"./apps-sdk/bridge.js\";\nimport { McpAppBridge } from \"./mcp-app/bridge.js\";\nimport { NotSupportedError } from \"./types.js\";\n\nfunction stubApp(adaptor: HostAdaptor, app: object) {\n (\n adaptor as unknown as { mcp: { getApp: () => Promise<object> } }\n ).mcp.getApp = () => Promise.resolve(app);\n}\n\ndescribe(\"HostAdaptor\", () => {\n beforeEach(() => {\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"skybridge\", {});\n vi.stubGlobal(\"parent\", { postMessage: vi.fn() });\n localStorage.clear();\n });\n afterEach(() => {\n vi.unstubAllGlobals();\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n localStorage.clear();\n });\n\n it(\"callTool always routes to mcp.callServerTool\", async () => {\n vi.stubGlobal(\"openai\", { callTool: vi.fn() });\n const adaptor = new HostAdaptor();\n const fakeApp = {\n callServerTool: vi.fn().mockResolvedValue({\n content: [],\n structuredContent: { ok: true },\n isError: false,\n _meta: { x: 1 },\n }),\n };\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n (adaptor as any).mcp.getApp = vi.fn().mockResolvedValue(fakeApp);\n\n const result = await adaptor.callTool(\"greet\", { name: \"alice\" });\n expect(fakeApp.callServerTool).toHaveBeenCalledWith(\n {\n name: \"greet\",\n arguments: { name: \"alice\" },\n },\n { timeout: undefined },\n );\n expect(result.structuredContent).toEqual({ ok: true });\n expect(result.meta).toEqual({ x: 1 });\n });\n\n it(\"download returns isError when host lacks downloadFile capability\", async () => {\n vi.stubGlobal(\"openai\", undefined);\n const adaptor = new HostAdaptor();\n const fakeApp = {\n getHostCapabilities: () => ({}),\n downloadFile: vi.fn(),\n };\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n (adaptor as any).mcp.getApp = vi.fn().mockResolvedValue(fakeApp);\n const r = await adaptor.download({ contents: [] });\n expect(r.isError).toBe(true);\n expect(fakeApp.downloadFile).not.toHaveBeenCalled();\n });\n\n it(\"sendFollowUpMessage uses window.openai for plain text and ui/message for content blocks or a target\", async () => {\n const sendFollowUpMessage = vi.fn().mockResolvedValue(undefined);\n vi.stubGlobal(\"openai\", { sendFollowUpMessage });\n let adaptor = new HostAdaptor();\n await adaptor.sendFollowUpMessage(\"hi\", { scrollToBottom: false });\n expect(sendFollowUpMessage).toHaveBeenCalledWith({\n prompt: \"hi\",\n scrollToBottom: false,\n });\n\n // Default case falls through to MCP\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"openai\", undefined);\n adaptor = new HostAdaptor();\n const sendMessage = vi.fn().mockResolvedValue(undefined);\n const getHostCapabilities = () => ({\n experimental: { \"openai/message\": {} },\n });\n stubApp(adaptor, { sendMessage });\n await adaptor.sendFollowUpMessage(\"hi\");\n expect(sendMessage).toHaveBeenCalledWith({\n role: \"user\",\n content: [{ type: \"text\", text: \"hi\" }],\n });\n\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"openai\", { sendFollowUpMessage });\n adaptor = new HostAdaptor();\n stubApp(adaptor, { sendMessage, getHostCapabilities });\n const item = {\n type: \"text\" as const,\n text: \"M6 hex bolt\",\n _meta: { \"openai/title\": \"Hex bolt\" },\n };\n await adaptor.sendFollowUpMessage([item], { target: \"new\" });\n expect(sendMessage).toHaveBeenLastCalledWith({\n role: \"user\",\n content: [item],\n _meta: { \"openai/message\": { target: \"new\" } },\n });\n expect(sendFollowUpMessage).toHaveBeenCalledTimes(1);\n });\n\n it(\"openFile sends openai/files/open only on hosts advertising openai/files\", async () => {\n const adaptor = new HostAdaptor();\n const request = vi.fn().mockResolvedValue({});\n let capabilities: Record<string, unknown> = {};\n stubApp(adaptor, { request, getHostCapabilities: () => capabilities });\n\n await expect(adaptor.openFile(\"/tmp/part.stl\")).rejects.toThrow(\n \"openai/files\",\n );\n expect(request).not.toHaveBeenCalled();\n\n capabilities = { experimental: { \"openai/files\": {} } };\n await adaptor.openFile(\"/tmp/part.stl\");\n expect(request).toHaveBeenCalledWith(\n { method: \"openai/files/open\", params: { path: \"/tmp/part.stl\" } },\n expect.anything(),\n );\n });\n\n it(\"openExternal routes to window.openai only when redirectUrl: false\", async () => {\n const openExternal = vi.fn();\n vi.stubGlobal(\"openai\", { openExternal });\n let adaptor = new HostAdaptor();\n adaptor.openExternal(\"https://x\", { redirectUrl: false });\n expect(openExternal).toHaveBeenCalledWith({\n href: \"https://x\",\n redirectUrl: false,\n });\n\n // Default case falls through to MCP openLink\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"openai\", undefined);\n adaptor = new HostAdaptor();\n const openLink = vi.fn();\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n (adaptor as any).mcp.getApp = vi.fn().mockResolvedValue({ openLink });\n adaptor.openExternal(\"https://x\");\n await new Promise((r) => setTimeout(r, 0));\n expect(openLink).toHaveBeenCalledWith({ url: \"https://x\" });\n });\n\n it(\"Apps-SDK-exclusive methods throw NotSupportedError when window.openai is null\", async () => {\n vi.stubGlobal(\"openai\", undefined);\n const adaptor = new HostAdaptor();\n await expect(adaptor.uploadFile(new File([], \"x\"))).rejects.toThrow(\n NotSupportedError,\n );\n await expect(adaptor.selectFiles()).rejects.toThrow(NotSupportedError);\n await expect(adaptor.getFileDownloadUrl({ fileId: \"x\" })).rejects.toThrow(\n NotSupportedError,\n );\n await expect(adaptor.setOpenInAppUrl(\"https://x\")).rejects.toThrow(\n NotSupportedError,\n );\n });\n\n it(\"file methods throw NotSupportedError when window.openai lacks them\", async () => {\n vi.stubGlobal(\"openai\", {});\n const adaptor = new HostAdaptor();\n\n const uploadError = await adaptor\n .uploadFile(new File([], \"x\"))\n .catch((e: unknown) => e);\n expect(uploadError).toBeInstanceOf(NotSupportedError);\n expect((uploadError as NotSupportedError).method).toBe(\"uploadFile\");\n\n const downloadError = await adaptor\n .getFileDownloadUrl({ fileId: \"x\" })\n .catch((e: unknown) => e);\n expect(downloadError).toBeInstanceOf(NotSupportedError);\n expect((downloadError as NotSupportedError).method).toBe(\n \"getFileDownloadUrl\",\n );\n\n const selectError = await adaptor.selectFiles().catch((e: unknown) => e);\n expect(selectError).toBeInstanceOf(NotSupportedError);\n expect((selectError as NotSupportedError).method).toBe(\"selectFiles\");\n });\n\n it(\"uploadFile delegates to window.openai.uploadFile and tracks fileId in widgetState\", async () => {\n const setWidgetState = vi.fn().mockResolvedValue(undefined);\n const uploadFile = vi.fn().mockResolvedValue({\n fileId: \"abc\",\n fileName: \"x\",\n mimeType: \"image/png\",\n });\n vi.stubGlobal(\"openai\", { uploadFile, setWidgetState, widgetState: null });\n const adaptor = new HostAdaptor();\n const file = new File([], \"x\", { type: \"image/png\" });\n const r = await adaptor.uploadFile(file, { library: true });\n expect(uploadFile).toHaveBeenCalledWith(file, { library: true });\n expect(r.fileId).toBe(\"abc\");\n expect(setWidgetState).toHaveBeenCalledWith(\n expect.objectContaining({ imageIds: [\"abc\"] }),\n );\n });\n\n it(\"uploadFile does not track a non-image fileId in widgetState.imageIds\", async () => {\n const setWidgetState = vi.fn().mockResolvedValue(undefined);\n const uploadFile = vi.fn().mockResolvedValue({\n fileId: \"sediment://file_txt\",\n fileName: \"notes.txt\",\n mimeType: \"text/plain\",\n });\n vi.stubGlobal(\"openai\", { uploadFile, setWidgetState, widgetState: null });\n const adaptor = new HostAdaptor();\n\n await adaptor.uploadFile(new File([], \"notes.txt\", { type: \"text/plain\" }));\n\n for (const call of setWidgetState.mock.calls) {\n expect(call[0].imageIds ?? []).not.toContain(\"sediment://file_txt\");\n }\n });\n\n it(\"setViewState uses window.openai.setWidgetState when present\", async () => {\n const setWidgetState = vi.fn().mockResolvedValue(undefined);\n vi.stubGlobal(\"openai\", { setWidgetState, widgetState: null });\n const adaptor = new HostAdaptor();\n await adaptor.setViewState({ count: 1 });\n expect(setWidgetState).toHaveBeenCalledWith(\n expect.objectContaining({ modelContent: { count: 1 } }),\n );\n });\n\n it(\"warns when setViewState reaches 20K tokens\", async () => {\n const setWidgetState = vi.fn().mockResolvedValue(undefined);\n vi.stubGlobal(\"openai\", { setWidgetState, widgetState: null });\n const adaptor = new HostAdaptor();\n const warnSpy = vi.spyOn(console, \"warn\").mockImplementation(() => {});\n\n await adaptor.setViewState({\n longText: \"x\".repeat(VIEW_STATE_WARNING_TOKENS * 4),\n });\n\n expect(warnSpy).toHaveBeenCalledWith(\n expect.stringContaining(\"setWidgetState is persisting\"),\n );\n\n warnSpy.mockRestore();\n });\n\n it(\"setViewState falls back to MCP updateModelContext + localStorage when window.openai is absent\", async () => {\n vi.stubGlobal(\"openai\", undefined);\n const adaptor = new HostAdaptor();\n const updateModelContext = vi.fn().mockResolvedValue(undefined);\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n (adaptor as any).mcp.getApp = vi\n .fn()\n .mockResolvedValue({ updateModelContext });\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n (adaptor as any)._viewUUID = \"view-1\";\n await adaptor.setViewState({ count: 2 });\n expect(updateModelContext).toHaveBeenCalledWith({\n structuredContent: { count: 2 },\n content: [\n {\n type: \"text\",\n text: JSON.stringify({ count: 2 }),\n annotations: { audience: [\"assistant\"] },\n },\n ],\n });\n const keys: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key !== null) {\n keys.push(key);\n }\n }\n expect(keys.some((k) => k.endsWith(\":view-1\"))).toBe(true);\n });\n\n it(\"openModal/closeModal: delegates to window.openai.requestModal when present, polyfill state otherwise\", () => {\n const requestModal = vi.fn();\n vi.stubGlobal(\"openai\", { requestModal });\n let adaptor = new HostAdaptor();\n adaptor.openModal({ title: \"Hi\" });\n expect(requestModal).toHaveBeenCalledWith({ title: \"Hi\" });\n expect(() => adaptor.closeModal()).not.toThrow();\n\n // Polyfill path\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"openai\", undefined);\n adaptor = new HostAdaptor();\n adaptor.openModal({ params: { x: 1 } });\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n expect((adaptor as any)._polyfillDisplay).toEqual({\n mode: \"modal\",\n params: { x: 1 },\n });\n adaptor.closeModal();\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n expect((adaptor as any)._polyfillDisplay).toEqual({ mode: \"inline\" });\n });\n\n it(\"getHostContextStore: display/viewState route to ChatGPT overlay when present, MCP otherwise\", () => {\n vi.stubGlobal(\"openai\", {\n view: { mode: \"fullscreen\" },\n widgetState: { modelContent: { count: 5 }, privateContent: {} },\n });\n let adaptor = new HostAdaptor();\n expect(adaptor.getHostContextStore(\"display\").getSnapshot()).toEqual({\n mode: \"fullscreen\",\n });\n expect(adaptor.getHostContextStore(\"viewState\").getSnapshot()).toEqual({\n count: 5,\n });\n // Other keys (theme) always flow through MCP; default fallback when no notification\n expect(adaptor.getHostContextStore(\"theme\").getSnapshot()).toBe(\"light\");\n\n // Polyfill / local-state path\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"openai\", undefined);\n adaptor = new HostAdaptor();\n expect(adaptor.getHostContextStore(\"display\").getSnapshot()).toEqual({\n mode: \"inline\",\n });\n expect(adaptor.getHostContextStore(\"viewState\").getSnapshot()).toBe(null);\n });\n});\n"]}
|
|
@@ -4,7 +4,7 @@ export class AppsSdkBridge {
|
|
|
4
4
|
static instance = null;
|
|
5
5
|
static getInstance() {
|
|
6
6
|
if (window.openai === undefined) {
|
|
7
|
-
throw new Error("Apps SDK Bridge requires window.openai (
|
|
7
|
+
throw new Error("Apps SDK Bridge requires window.openai (ChatGPT runtime).");
|
|
8
8
|
}
|
|
9
9
|
if (AppsSdkBridge.instance === null) {
|
|
10
10
|
AppsSdkBridge.instance = new AppsSdkBridge();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../../../src/web/bridges/apps-sdk/bridge.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,sBAAsB,GAEvB,MAAM,YAAY,CAAC;AAEpB,qFAAqF;AACrF,MAAM,OAAO,aAAa;IAChB,MAAM,CAAC,QAAQ,GAAyB,IAAI,CAAC;IAE9C,MAAM,CAAC,WAAW;QACvB,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../../../src/web/bridges/apps-sdk/bridge.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,sBAAsB,GAEvB,MAAM,YAAY,CAAC;AAEpB,qFAAqF;AACrF,MAAM,OAAO,aAAa;IAChB,MAAM,CAAC,QAAQ,GAAyB,IAAI,CAAC;IAE9C,MAAM,CAAC,WAAW;QACvB,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;QACJ,CAAC;QACD,IAAI,aAAa,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpC,aAAa,CAAC,QAAQ,GAAG,IAAI,aAAa,EAAE,CAAC;QAC/C,CAAC;QACD,OAAO,aAAa,CAAC,QAAQ,CAAC;IAChC,CAAC;IAEM,MAAM,CAAC,aAAa;QACzB,IAAI,aAAa,CAAC,QAAQ,EAAE,CAAC;YAC3B,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC;QAChC,CAAC;IACH,CAAC;IAIM,SAAS,CACd,SAAmE;QAEnE,MAAM,IAAI,GAAsC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;YACtE,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAChB,OAAO,CAAC,QAAoB,EAAE,EAAE;YAC9B,MAAM,eAAe,GAAG,CAAC,KAAsB,EAAE,EAAE;gBACjD,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CACjC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,CACjD,CAAC;gBACF,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBACvB,OAAO;gBACT,CAAC;gBACD,QAAQ,EAAE,CAAC;YACb,CAAC,CAAC;YAEF,MAAM,CAAC,gBAAgB,CAAC,sBAAsB,EAAE,eAAe,EAAE;gBAC/D,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;YAEH,OAAO,GAAG,EAAE;gBACV,MAAM,CAAC,mBAAmB,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC;YACtE,CAAC,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC;IAEM,WAAW,GAAG,CAAiC,GAAM,EAAE,EAAE;QAC9D,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,+EAA+E,GAAG,8CAA8C,CACjI,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC,CAAC;IAEK,mBAAmB;QAIxB,OAAO;YACL,OAAO,EAAE;gBACP,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;gBACjC,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;aAC5C;YACD,SAAS,EAAE;gBACT,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;gBACxC,WAAW,EAAE,GAAG,EAAE,CAChB,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,YAAY,IAAI,IAAI;aACxD;SACF,CAAC;IACJ,CAAC","sourcesContent":["import type { Bridge, HostContextStore, Subscribe } from \"../types.js\";\nimport {\n type AppsSdkContext,\n SET_GLOBALS_EVENT_TYPE,\n type SetGlobalsEvent,\n} from \"./types.js\";\n\n/** @internal Singleton bridge over `window.openai` events. Used by `HostAdaptor`. */\nexport class AppsSdkBridge implements Bridge<AppsSdkContext> {\n private static instance: AppsSdkBridge | null = null;\n\n public static getInstance(): AppsSdkBridge {\n if (window.openai === undefined) {\n throw new Error(\n \"Apps SDK Bridge requires window.openai (ChatGPT runtime).\",\n );\n }\n if (AppsSdkBridge.instance === null) {\n AppsSdkBridge.instance = new AppsSdkBridge();\n }\n return AppsSdkBridge.instance;\n }\n\n public static resetInstance(): void {\n if (AppsSdkBridge.instance) {\n AppsSdkBridge.instance = null;\n }\n }\n\n public subscribe(key: keyof AppsSdkContext): Subscribe;\n public subscribe(keys: readonly (keyof AppsSdkContext)[]): Subscribe;\n public subscribe(\n keyOrKeys: keyof AppsSdkContext | readonly (keyof AppsSdkContext)[],\n ): Subscribe {\n const keys: readonly (keyof AppsSdkContext)[] = Array.isArray(keyOrKeys)\n ? keyOrKeys\n : [keyOrKeys];\n return (onChange: () => void) => {\n const handleSetGlobal = (event: SetGlobalsEvent) => {\n const hasRelevantChange = keys.some(\n (key) => event.detail.globals[key] !== undefined,\n );\n if (!hasRelevantChange) {\n return;\n }\n onChange();\n };\n\n window.addEventListener(SET_GLOBALS_EVENT_TYPE, handleSetGlobal, {\n passive: true,\n });\n\n return () => {\n window.removeEventListener(SET_GLOBALS_EVENT_TYPE, handleSetGlobal);\n };\n };\n }\n\n public getSnapshot = <K extends keyof AppsSdkContext>(key: K) => {\n if (window.openai === undefined) {\n throw new Error(\n `window.openai is not available. Make sure you're calling the hook requiring ${key} within the OpenAI iFrame skybridge runtime.`,\n );\n }\n\n return window.openai[key];\n };\n\n public createOverlayStores(): {\n display: HostContextStore<\"display\">;\n viewState: HostContextStore<\"viewState\">;\n } {\n return {\n display: {\n subscribe: this.subscribe(\"view\"),\n getSnapshot: () => this.getSnapshot(\"view\"),\n },\n viewState: {\n subscribe: this.subscribe(\"widgetState\"),\n getSnapshot: () =>\n this.getSnapshot(\"widgetState\")?.modelContent ?? null,\n },\n };\n }\n}\n"]}
|
|
@@ -79,17 +79,16 @@ export type AppsSdkMethods<WS extends AppsSdkWidgetState = AppsSdkWidgetState> =
|
|
|
79
79
|
*/
|
|
80
80
|
requestModal: (args: RequestModalOptions) => Promise<void>;
|
|
81
81
|
/** Uploads a new file to the host. Pass `{ library: true }` to also save to the user's ChatGPT file library. */
|
|
82
|
-
uploadFile
|
|
82
|
+
uploadFile?: (file: File, options?: UploadFileOptions) => Promise<FileMetadata>;
|
|
83
83
|
/**
|
|
84
84
|
* Opens ChatGPT's file library picker and returns app-authorized files.
|
|
85
|
-
* Feature-detect before using: this method may not be available on all host versions.
|
|
86
85
|
*/
|
|
87
86
|
selectFiles?: () => Promise<FileMetadata[]>;
|
|
88
87
|
/**
|
|
89
88
|
* Downloads a file from the host. Works for files uploaded by the widget,
|
|
90
89
|
* files selected via selectFiles(), or files provided via tool/file params.
|
|
91
90
|
*/
|
|
92
|
-
getFileDownloadUrl
|
|
91
|
+
getFileDownloadUrl?: (file: FileMetadata) => Promise<{
|
|
93
92
|
downloadUrl: string;
|
|
94
93
|
}>;
|
|
95
94
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/web/bridges/apps-sdk/types.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,wBAAwB,GAAG,sBAAsB,CAAC;AAC/D,MAAM,OAAO,iBAAkB,SAAQ,WAErC;IACkB,IAAI,GAAG,wBAAwB,CAAC;CACnD;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/web/bridges/apps-sdk/types.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,wBAAwB,GAAG,sBAAsB,CAAC;AAC/D,MAAM,OAAO,iBAAkB,SAAQ,WAErC;IACkB,IAAI,GAAG,wBAAwB,CAAC;CACnD;AA6GD,sDAAsD;AACtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAC3D,MAAM,OAAO,eAAgB,SAAQ,WAEnC;IACkB,IAAI,GAAG,sBAAsB,CAAC;CACjD","sourcesContent":["import type { UnknownObject } from \"../../types.js\";\nimport type {\n CallToolArgs,\n CallToolResponse,\n FileMetadata,\n RequestModalOptions,\n UploadFileOptions,\n} from \"../types.js\";\n\ntype DisplayMode = \"pip\" | \"inline\" | \"fullscreen\" | \"modal\";\ntype RequestDisplayMode = Exclude<DisplayMode, \"modal\">;\n\nexport type AppsSdkWidgetState = {\n modelContent: Record<string, unknown>;\n privateContent: Record<string, unknown>;\n imageIds?: string[];\n};\n\nexport const TOOL_RESPONSE_EVENT_TYPE = \"openai:tool_response\";\nexport class ToolResponseEvent extends CustomEvent<{\n tool: { name: string; args: UnknownObject };\n}> {\n override readonly type = TOOL_RESPONSE_EVENT_TYPE;\n}\n\ndeclare global {\n interface Window {\n openai: AppsSdkMethods & AppsSdkContext;\n }\n\n interface WindowEventMap {\n [SET_GLOBALS_EVENT_TYPE]: SetGlobalsEvent;\n }\n}\n\nexport type AppsSdkContext<\n ToolInput extends UnknownObject = Record<never, unknown>,\n ToolOutput extends UnknownObject = UnknownObject,\n ToolResponseMetadata extends UnknownObject = UnknownObject,\n WS extends AppsSdkWidgetState = AppsSdkWidgetState,\n> = {\n theme: Theme;\n userAgent: UserAgent;\n locale: string;\n\n // layout\n maxHeight: number | undefined;\n displayMode: DisplayMode;\n safeArea: SafeArea;\n view: View;\n\n // state\n toolInput: ToolInput;\n toolOutput: ToolOutput | { text: string } | null;\n toolResponseMetadata: ToolResponseMetadata | null;\n widgetState: WS | null;\n};\n\nexport type AppsSdkMethods<WS extends AppsSdkWidgetState = AppsSdkWidgetState> =\n {\n /** Calls a tool on your MCP. Returns the full response. */\n callTool: <\n ToolArgs extends CallToolArgs = null,\n ToolResponse extends CallToolResponse = CallToolResponse,\n >(\n name: string,\n args: ToolArgs,\n ) => Promise<ToolResponse>;\n\n /**\n * Triggers a followup turn in the ChatGPT conversation\n * scrollToBottom is optional, defaults to true, and can be\n * set to false to prevent auto-scroll.\n */\n sendFollowUpMessage: (args: {\n prompt: string;\n scrollToBottom?: boolean;\n }) => Promise<void>;\n\n /** Opens an external link, redirects web page or mobile app */\n openExternal(args: { href: string; redirectUrl?: false }): void;\n\n /** For transitioning an app from inline to fullscreen or pip */\n requestDisplayMode: (args: { mode: RequestDisplayMode }) => Promise<{\n /**\n * The granted display mode. The host may reject the request.\n * For mobile, PiP is always coerced to fullscreen.\n */\n mode: RequestDisplayMode;\n }>;\n\n /** Requests the host to close (dismiss) the widget. */\n requestClose: () => Promise<void>;\n\n /**\n * Sets the widget state.\n * This state is persisted across widget renders.\n */\n setWidgetState: (state: WS) => Promise<void>;\n\n /**\n * Opens a modal portaled outside of the widget iFrame.\n * This ensures the modal is correctly displayed and not limited to the widget's area.\n */\n requestModal: (args: RequestModalOptions) => Promise<void>;\n\n /** Uploads a new file to the host. Pass `{ library: true }` to also save to the user's ChatGPT file library. */\n uploadFile?: (\n file: File,\n options?: UploadFileOptions,\n ) => Promise<FileMetadata>;\n\n /**\n * Opens ChatGPT's file library picker and returns app-authorized files.\n */\n selectFiles?: () => Promise<FileMetadata[]>;\n\n /**\n * Downloads a file from the host. Works for files uploaded by the widget,\n * files selected via selectFiles(), or files provided via tool/file params.\n */\n getFileDownloadUrl?: (\n file: FileMetadata,\n ) => Promise<{ downloadUrl: string }>;\n\n /**\n * Sets the open in app URL.\n * This URL will be opened in the app when the user clicks on the top right button in fullscreen mode.\n */\n setOpenInAppUrl: (args: { href: string }) => Promise<void>;\n };\n\n// Dispatched when any global changes in the host page\nexport const SET_GLOBALS_EVENT_TYPE = \"openai:set_globals\";\nexport class SetGlobalsEvent extends CustomEvent<{\n globals: Partial<AppsSdkContext>;\n}> {\n override readonly type = SET_GLOBALS_EVENT_TYPE;\n}\n\ntype View = {\n mode: DisplayMode;\n params?: Record<string, unknown>;\n};\n\ntype Theme = \"light\" | \"dark\";\n\ntype SafeAreaInsets = {\n top: number;\n bottom: number;\n left: number;\n right: number;\n};\n\ntype SafeArea = {\n insets: SafeAreaInsets;\n};\n\ntype DeviceType = \"mobile\" | \"tablet\" | \"desktop\" | \"unknown\";\n\ntype UserAgent = {\n device: { type: DeviceType };\n capabilities: {\n hover: boolean;\n touch: boolean;\n };\n};\n"]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { AppsSdkContext } from "./types.js";
|
|
2
2
|
/**
|
|
3
|
-
* Read a single key from the raw
|
|
3
|
+
* Read a single key from the raw ChatGPT (`window.openai`) context.
|
|
4
4
|
*
|
|
5
5
|
* Advanced escape hatch — prefer the cross-host hooks (`useViewport`, `useUser`,
|
|
6
|
-
* `useToolInfo`, etc.) which work in both
|
|
6
|
+
* `useToolInfo`, etc.) which work in both ChatGPT and MCP Apps. Reach for
|
|
7
7
|
* this when you need ChatGPT-only fields not surfaced by the public hooks.
|
|
8
8
|
*
|
|
9
|
-
* Throws if called outside the
|
|
9
|
+
* Throws if called outside the ChatGPT (`window.openai`) runtime.
|
|
10
10
|
*
|
|
11
11
|
* @see https://docs.skybridge.tech/api-reference/use-apps-sdk-context
|
|
12
12
|
*/
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { useSyncExternalStore } from "react";
|
|
2
2
|
import { AppsSdkBridge } from "./bridge.js";
|
|
3
3
|
/**
|
|
4
|
-
* Read a single key from the raw
|
|
4
|
+
* Read a single key from the raw ChatGPT (`window.openai`) context.
|
|
5
5
|
*
|
|
6
6
|
* Advanced escape hatch — prefer the cross-host hooks (`useViewport`, `useUser`,
|
|
7
|
-
* `useToolInfo`, etc.) which work in both
|
|
7
|
+
* `useToolInfo`, etc.) which work in both ChatGPT and MCP Apps. Reach for
|
|
8
8
|
* this when you need ChatGPT-only fields not surfaced by the public hooks.
|
|
9
9
|
*
|
|
10
|
-
* Throws if called outside the
|
|
10
|
+
* Throws if called outside the ChatGPT (`window.openai`) runtime.
|
|
11
11
|
*
|
|
12
12
|
* @see https://docs.skybridge.tech/api-reference/use-apps-sdk-context
|
|
13
13
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-apps-sdk-context.js","sourceRoot":"","sources":["../../../../src/web/bridges/apps-sdk/use-apps-sdk-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAM;IAEN,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;IAC3C,OAAO,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CACtD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CACxB,CAAC;AACJ,CAAC","sourcesContent":["import { useSyncExternalStore } from \"react\";\nimport { AppsSdkBridge } from \"./bridge.js\";\nimport type { AppsSdkContext } from \"./types.js\";\n\n/**\n * Read a single key from the raw
|
|
1
|
+
{"version":3,"file":"use-apps-sdk-context.js","sourceRoot":"","sources":["../../../../src/web/bridges/apps-sdk/use-apps-sdk-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAM;IAEN,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;IAC3C,OAAO,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CACtD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CACxB,CAAC;AACJ,CAAC","sourcesContent":["import { useSyncExternalStore } from \"react\";\nimport { AppsSdkBridge } from \"./bridge.js\";\nimport type { AppsSdkContext } from \"./types.js\";\n\n/**\n * Read a single key from the raw ChatGPT (`window.openai`) context.\n *\n * Advanced escape hatch — prefer the cross-host hooks (`useViewport`, `useUser`,\n * `useToolInfo`, etc.) which work in both ChatGPT and MCP Apps. Reach for\n * this when you need ChatGPT-only fields not surfaced by the public hooks.\n *\n * Throws if called outside the ChatGPT (`window.openai`) runtime.\n *\n * @see https://docs.skybridge.tech/api-reference/use-apps-sdk-context\n */\nexport function useAppsSdkContext<K extends keyof AppsSdkContext>(\n key: K,\n): AppsSdkContext[K] {\n const bridge = AppsSdkBridge.getInstance();\n return useSyncExternalStore(bridge.subscribe(key), () =>\n bridge.getSnapshot(key),\n );\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { Implementation } from "@modelcontextprotocol/client";
|
|
1
2
|
import { App } from "@modelcontextprotocol/ext-apps";
|
|
2
|
-
import { type Implementation } from "@modelcontextprotocol/sdk/types.js";
|
|
3
3
|
import type { AnyViewToolHandler, Bridge, HostContextStore, Subscribe, ViewToolConfig } from "../types.js";
|
|
4
4
|
import type { McpAppContext, McpAppContextKey } from "./types.js";
|
|
5
5
|
/** @internal Singleton bridge over the `ext-apps` JSON-RPC App connection. Used by `HostAdaptor`. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { ListToolsRequestSchema } from "@modelcontextprotocol/core";
|
|
1
2
|
import { App } from "@modelcontextprotocol/ext-apps";
|
|
2
|
-
import { ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
3
3
|
import { dequal } from "dequal/lite";
|
|
4
4
|
import * as z from "zod/v4";
|
|
5
5
|
function createMcpStore(bridge, keys, computeSnapshot) {
|
|
@@ -25,6 +25,7 @@ export class McpAppBridge {
|
|
|
25
25
|
toolCancelled: null,
|
|
26
26
|
toolResult: null,
|
|
27
27
|
hostInfo: null,
|
|
28
|
+
hostCapabilities: null,
|
|
28
29
|
};
|
|
29
30
|
listeners = new Map();
|
|
30
31
|
app;
|
|
@@ -58,6 +59,7 @@ export class McpAppBridge {
|
|
|
58
59
|
this.updateContext({
|
|
59
60
|
...hostContext,
|
|
60
61
|
hostInfo: this.app.getHostVersion() ?? null,
|
|
62
|
+
hostCapabilities: this.app.getHostCapabilities() ?? null,
|
|
61
63
|
});
|
|
62
64
|
}
|
|
63
65
|
catch (err) {
|
|
@@ -140,7 +142,12 @@ export class McpAppBridge {
|
|
|
140
142
|
},
|
|
141
143
|
})),
|
|
142
144
|
toolInput: createMcpStore(this, ["toolInput"], ({ toolInput }) => toolInput ?? null),
|
|
143
|
-
toolOutput: createMcpStore(this, ["toolResult"], ({ toolResult }) =>
|
|
145
|
+
toolOutput: createMcpStore(this, ["toolResult"], ({ toolResult }) => {
|
|
146
|
+
const structuredContent = toolResult?.structuredContent;
|
|
147
|
+
return typeof structuredContent === "object"
|
|
148
|
+
? structuredContent
|
|
149
|
+
: null;
|
|
150
|
+
}),
|
|
144
151
|
toolResponseMetadata: createMcpStore(this, ["toolResult"], ({ toolResult }) => toolResult?._meta ?? null),
|
|
145
152
|
};
|
|
146
153
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/bridge.ts"],"names":[],"mappings":"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","sourcesContent":["import { App } from \"@modelcontextprotocol/ext-apps\";\nimport {\n type Implementation,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { dequal } from \"dequal/lite\";\nimport * as z from \"zod/v4\";\nimport type {\n AnyViewToolHandler,\n Bridge,\n HostContextStore,\n Subscribe,\n ViewToolConfig,\n} from \"../types.js\";\nimport type { McpAppContext, McpAppContextKey } from \"./types.js\";\n\ntype PickContext<K extends readonly McpAppContextKey[]> = {\n [P in K[number]]: McpAppContext[P];\n};\n\nfunction createMcpStore<const Keys extends readonly McpAppContextKey[], R>(\n bridge: McpAppBridge,\n keys: Keys,\n computeSnapshot: (context: PickContext<Keys>) => R,\n) {\n let cachedValue: R | undefined;\n return {\n subscribe: bridge.subscribe(keys),\n getSnapshot: () => {\n const context = Object.fromEntries(\n keys.map((k) => [k, bridge.getSnapshot(k)]),\n ) as PickContext<Keys>;\n const newValue = computeSnapshot(context);\n if (cachedValue !== undefined && dequal(cachedValue, newValue)) {\n return cachedValue;\n }\n cachedValue = newValue;\n return newValue;\n },\n };\n}\n\n/** @internal Singleton bridge over the `ext-apps` JSON-RPC App connection. Used by `HostAdaptor`. */\nexport class McpAppBridge implements Bridge<McpAppContext> {\n private static instance: McpAppBridge | null = null;\n public context: McpAppContext = {\n toolInput: null,\n toolCancelled: null,\n toolResult: null,\n hostInfo: null,\n };\n private listeners = new Map<McpAppContextKey, Set<() => void>>();\n private app: App;\n private connectPromise: Promise<void>;\n\n constructor(options: { appInfo: Implementation }) {\n this.app = new App(options.appInfo, { tools: { listChanged: true } });\n\n this.app.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [],\n }));\n\n this.app.ontoolinput = (params) => {\n this.updateContext({ toolInput: params.arguments ?? {} });\n };\n\n this.app.ontoolinputpartial = (params) => {\n this.updateContext({ toolInput: params.arguments ?? {} });\n };\n\n this.app.ontoolresult = (params) => {\n this.updateContext({ toolResult: params });\n };\n\n this.app.ontoolcancelled = (params) => {\n this.updateContext({ toolCancelled: params });\n };\n\n this.app.onhostcontextchanged = (params) => {\n this.updateContext(params);\n };\n\n this.connectPromise = this.connect();\n }\n\n private async connect() {\n try {\n await this.app.connect();\n const hostContext = this.app.getHostContext();\n this.updateContext({\n ...hostContext,\n hostInfo: this.app.getHostVersion() ?? null,\n });\n } catch (err) {\n console.error(err);\n }\n }\n\n public async getApp(): Promise<App> {\n await this.connectPromise;\n return this.app;\n }\n\n public registerViewTool(\n config: ViewToolConfig,\n handler: AnyViewToolHandler,\n ): () => void {\n const inputSchema = config.inputSchema\n ? z.object(config.inputSchema)\n : z.object({});\n\n const registered = this.app.registerTool(\n config.name,\n {\n ...(config.title !== undefined ? { title: config.title } : {}),\n ...(config.description !== undefined\n ? { description: config.description }\n : {}),\n inputSchema,\n ...(config.annotations ? { annotations: config.annotations } : {}),\n },\n handler,\n );\n\n return () => {\n registered.remove();\n };\n }\n\n public static getInstance(\n options?: Partial<{ appInfo: Implementation }>,\n ): McpAppBridge {\n if (McpAppBridge.instance && options) {\n console.warn(\n \"McpAppBridge.getInstance: options ignored, instance already exists\",\n );\n }\n if (!McpAppBridge.instance) {\n const defaultOptions = {\n appInfo: { name: \"skybridge-app\", version: \"0.0.1\" },\n };\n McpAppBridge.instance = new McpAppBridge({\n ...defaultOptions,\n ...options,\n });\n }\n return McpAppBridge.instance;\n }\n\n public subscribe(key: McpAppContextKey): Subscribe;\n public subscribe(keys: readonly McpAppContextKey[]): Subscribe;\n public subscribe(\n keyOrKeys: McpAppContextKey | readonly McpAppContextKey[],\n ): Subscribe {\n const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];\n return (onChange: () => void) => {\n for (const key of keys) {\n this.listeners.set(\n key,\n new Set([...(this.listeners.get(key) || []), onChange]),\n );\n }\n return () => {\n for (const key of keys) {\n this.listeners.get(key)?.delete(onChange);\n }\n };\n };\n }\n\n public getSnapshot<K extends keyof McpAppContext>(key: K): McpAppContext[K] {\n return this.context[key];\n }\n\n public createContextStores(): {\n theme: HostContextStore<\"theme\">;\n locale: HostContextStore<\"locale\">;\n safeArea: HostContextStore<\"safeArea\">;\n displayMode: HostContextStore<\"displayMode\">;\n maxHeight: HostContextStore<\"maxHeight\">;\n userAgent: HostContextStore<\"userAgent\">;\n toolInput: HostContextStore<\"toolInput\">;\n toolOutput: HostContextStore<\"toolOutput\">;\n toolResponseMetadata: HostContextStore<\"toolResponseMetadata\">;\n } {\n return {\n theme: createMcpStore(this, [\"theme\"], ({ theme }) => theme ?? \"light\"),\n locale: createMcpStore(\n this,\n [\"locale\"],\n ({ locale }) => locale ?? \"en-US\",\n ),\n safeArea: createMcpStore(\n this,\n [\"safeAreaInsets\"],\n ({ safeAreaInsets }) => ({\n insets: safeAreaInsets ?? { top: 0, right: 0, bottom: 0, left: 0 },\n }),\n ),\n displayMode: createMcpStore(\n this,\n [\"displayMode\"],\n ({ displayMode }) => displayMode ?? \"inline\",\n ),\n maxHeight: createMcpStore(\n this,\n [\"containerDimensions\"],\n ({ containerDimensions }) => {\n if (containerDimensions && \"maxHeight\" in containerDimensions) {\n return containerDimensions.maxHeight;\n }\n return undefined;\n },\n ),\n userAgent: createMcpStore(\n this,\n [\"platform\", \"deviceCapabilities\"],\n ({ platform, deviceCapabilities }) => ({\n device: {\n type: platform === \"web\" ? \"desktop\" : (platform ?? \"unknown\"),\n },\n capabilities: {\n hover: true,\n touch: true,\n ...deviceCapabilities,\n },\n }),\n ),\n toolInput: createMcpStore(\n this,\n [\"toolInput\"],\n ({ toolInput }) => toolInput ?? null,\n ),\n toolOutput: createMcpStore(\n this,\n [\"toolResult\"],\n ({ toolResult }) => toolResult?.structuredContent ?? null,\n ),\n toolResponseMetadata: createMcpStore(\n this,\n [\"toolResult\"],\n ({ toolResult }) => toolResult?._meta ?? null,\n ),\n };\n }\n\n public cleanup = () => {\n this.listeners.clear();\n };\n\n public static resetInstance(): void {\n if (McpAppBridge.instance) {\n McpAppBridge.instance.cleanup();\n McpAppBridge.instance = null;\n }\n }\n\n private emit(key: McpAppContextKey) {\n this.listeners.get(key)?.forEach((listener) => {\n listener();\n });\n }\n\n private updateContext(context: Partial<McpAppContext>) {\n this.context = { ...this.context, ...context };\n for (const key of Object.keys(context)) {\n this.emit(key);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/bridge.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Implementation } from \"@modelcontextprotocol/client\";\nimport { ListToolsRequestSchema } from \"@modelcontextprotocol/core\";\nimport { App } from \"@modelcontextprotocol/ext-apps\";\nimport { dequal } from \"dequal/lite\";\nimport * as z from \"zod/v4\";\nimport type {\n AnyViewToolHandler,\n Bridge,\n HostContextStore,\n Subscribe,\n ViewToolConfig,\n} from \"../types.js\";\nimport type { McpAppContext, McpAppContextKey } from \"./types.js\";\n\ntype PickContext<K extends readonly McpAppContextKey[]> = {\n [P in K[number]]: McpAppContext[P];\n};\n\nfunction createMcpStore<const Keys extends readonly McpAppContextKey[], R>(\n bridge: McpAppBridge,\n keys: Keys,\n computeSnapshot: (context: PickContext<Keys>) => R,\n) {\n let cachedValue: R | undefined;\n return {\n subscribe: bridge.subscribe(keys),\n getSnapshot: () => {\n const context = Object.fromEntries(\n keys.map((k) => [k, bridge.getSnapshot(k)]),\n ) as PickContext<Keys>;\n const newValue = computeSnapshot(context);\n if (cachedValue !== undefined && dequal(cachedValue, newValue)) {\n return cachedValue;\n }\n cachedValue = newValue;\n return newValue;\n },\n };\n}\n\n/** @internal Singleton bridge over the `ext-apps` JSON-RPC App connection. Used by `HostAdaptor`. */\nexport class McpAppBridge implements Bridge<McpAppContext> {\n private static instance: McpAppBridge | null = null;\n public context: McpAppContext = {\n toolInput: null,\n toolCancelled: null,\n toolResult: null,\n hostInfo: null,\n hostCapabilities: null,\n };\n private listeners = new Map<McpAppContextKey, Set<() => void>>();\n private app: App;\n private connectPromise: Promise<void>;\n\n constructor(options: { appInfo: Implementation }) {\n this.app = new App(options.appInfo, { tools: { listChanged: true } });\n\n this.app.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [],\n }));\n\n this.app.ontoolinput = (params) => {\n this.updateContext({ toolInput: params.arguments ?? {} });\n };\n\n this.app.ontoolinputpartial = (params) => {\n this.updateContext({ toolInput: params.arguments ?? {} });\n };\n\n this.app.ontoolresult = (params) => {\n this.updateContext({ toolResult: params });\n };\n\n this.app.ontoolcancelled = (params) => {\n this.updateContext({ toolCancelled: params });\n };\n\n this.app.onhostcontextchanged = (params) => {\n this.updateContext(params);\n };\n\n this.connectPromise = this.connect();\n }\n\n private async connect() {\n try {\n await this.app.connect();\n const hostContext = this.app.getHostContext();\n this.updateContext({\n ...hostContext,\n hostInfo: this.app.getHostVersion() ?? null,\n hostCapabilities: this.app.getHostCapabilities() ?? null,\n });\n } catch (err) {\n console.error(err);\n }\n }\n\n public async getApp(): Promise<App> {\n await this.connectPromise;\n return this.app;\n }\n\n public registerViewTool(\n config: ViewToolConfig,\n handler: AnyViewToolHandler,\n ): () => void {\n const inputSchema = config.inputSchema\n ? z.object(config.inputSchema)\n : z.object({});\n\n const registered = this.app.registerTool(\n config.name,\n {\n ...(config.title !== undefined ? { title: config.title } : {}),\n ...(config.description !== undefined\n ? { description: config.description }\n : {}),\n inputSchema,\n ...(config.annotations ? { annotations: config.annotations } : {}),\n },\n handler,\n );\n\n return () => {\n registered.remove();\n };\n }\n\n public static getInstance(\n options?: Partial<{ appInfo: Implementation }>,\n ): McpAppBridge {\n if (McpAppBridge.instance && options) {\n console.warn(\n \"McpAppBridge.getInstance: options ignored, instance already exists\",\n );\n }\n if (!McpAppBridge.instance) {\n const defaultOptions = {\n appInfo: { name: \"skybridge-app\", version: \"0.0.1\" },\n };\n McpAppBridge.instance = new McpAppBridge({\n ...defaultOptions,\n ...options,\n });\n }\n return McpAppBridge.instance;\n }\n\n public subscribe(key: McpAppContextKey): Subscribe;\n public subscribe(keys: readonly McpAppContextKey[]): Subscribe;\n public subscribe(\n keyOrKeys: McpAppContextKey | readonly McpAppContextKey[],\n ): Subscribe {\n const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];\n return (onChange: () => void) => {\n for (const key of keys) {\n this.listeners.set(\n key,\n new Set([...(this.listeners.get(key) || []), onChange]),\n );\n }\n return () => {\n for (const key of keys) {\n this.listeners.get(key)?.delete(onChange);\n }\n };\n };\n }\n\n public getSnapshot<K extends keyof McpAppContext>(key: K): McpAppContext[K] {\n return this.context[key];\n }\n\n public createContextStores(): {\n theme: HostContextStore<\"theme\">;\n locale: HostContextStore<\"locale\">;\n safeArea: HostContextStore<\"safeArea\">;\n displayMode: HostContextStore<\"displayMode\">;\n maxHeight: HostContextStore<\"maxHeight\">;\n userAgent: HostContextStore<\"userAgent\">;\n toolInput: HostContextStore<\"toolInput\">;\n toolOutput: HostContextStore<\"toolOutput\">;\n toolResponseMetadata: HostContextStore<\"toolResponseMetadata\">;\n } {\n return {\n theme: createMcpStore(this, [\"theme\"], ({ theme }) => theme ?? \"light\"),\n locale: createMcpStore(\n this,\n [\"locale\"],\n ({ locale }) => locale ?? \"en-US\",\n ),\n safeArea: createMcpStore(\n this,\n [\"safeAreaInsets\"],\n ({ safeAreaInsets }) => ({\n insets: safeAreaInsets ?? { top: 0, right: 0, bottom: 0, left: 0 },\n }),\n ),\n displayMode: createMcpStore(\n this,\n [\"displayMode\"],\n ({ displayMode }) => displayMode ?? \"inline\",\n ),\n maxHeight: createMcpStore(\n this,\n [\"containerDimensions\"],\n ({ containerDimensions }) => {\n if (containerDimensions && \"maxHeight\" in containerDimensions) {\n return containerDimensions.maxHeight;\n }\n return undefined;\n },\n ),\n userAgent: createMcpStore(\n this,\n [\"platform\", \"deviceCapabilities\"],\n ({ platform, deviceCapabilities }) => ({\n device: {\n type: platform === \"web\" ? \"desktop\" : (platform ?? \"unknown\"),\n },\n capabilities: {\n hover: true,\n touch: true,\n ...deviceCapabilities,\n },\n }),\n ),\n toolInput: createMcpStore(\n this,\n [\"toolInput\"],\n ({ toolInput }) => toolInput ?? null,\n ),\n toolOutput: createMcpStore(this, [\"toolResult\"], ({ toolResult }) => {\n const structuredContent = toolResult?.structuredContent;\n return typeof structuredContent === \"object\"\n ? (structuredContent as Record<string, unknown> | null)\n : null;\n }),\n toolResponseMetadata: createMcpStore(\n this,\n [\"toolResult\"],\n ({ toolResult }) => toolResult?._meta ?? null,\n ),\n };\n }\n\n public cleanup = () => {\n this.listeners.clear();\n };\n\n public static resetInstance(): void {\n if (McpAppBridge.instance) {\n McpAppBridge.instance.cleanup();\n McpAppBridge.instance = null;\n }\n }\n\n private emit(key: McpAppContextKey) {\n this.listeners.get(key)?.forEach((listener) => {\n listener();\n });\n }\n\n private updateContext(context: Partial<McpAppContext>) {\n this.context = { ...this.context, ...context };\n for (const key of Object.keys(context)) {\n this.emit(key);\n }\n }\n}\n"]}
|
|
@@ -1,10 +1,25 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { Implementation } from "@modelcontextprotocol/client";
|
|
2
|
+
import type { McpUiHostCapabilities, McpUiHostContext, McpUiToolCancelledNotification, McpUiToolInputNotification, McpUiToolResultNotification, McpUiUpdateModelContextRequest } from "@modelcontextprotocol/ext-apps";
|
|
3
3
|
export type McpToolState = {
|
|
4
4
|
toolInput: NonNullable<McpUiToolInputNotification["params"]["arguments"]> | null;
|
|
5
5
|
toolResult: McpUiToolResultNotification["params"] | null;
|
|
6
6
|
toolCancelled: McpUiToolCancelledNotification["params"] | null;
|
|
7
7
|
hostInfo: Implementation | null;
|
|
8
|
+
hostCapabilities: McpUiHostCapabilities | null;
|
|
8
9
|
};
|
|
9
|
-
|
|
10
|
+
/** ChatGPT-only host context keys from the OpenAI MCP extensions. */
|
|
11
|
+
export type OpenAIHostContext = {
|
|
12
|
+
/** App-relative URL the view was opened on through a deep link. */
|
|
13
|
+
"openai/deepLink"?: {
|
|
14
|
+
url: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Context this view attached to the conversation. `null` once the user
|
|
18
|
+
* removed it, for example by deleting its composer attachment.
|
|
19
|
+
*/
|
|
20
|
+
"openai/modelContext"?: (McpUiUpdateModelContextRequest["params"] & {
|
|
21
|
+
updateId: string;
|
|
22
|
+
}) | null;
|
|
23
|
+
};
|
|
24
|
+
export type McpAppContext = McpUiHostContext & OpenAIHostContext & McpToolState;
|
|
10
25
|
export type McpAppContextKey = keyof McpAppContext;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n McpUiHostContext,\n McpUiToolCancelledNotification,\n McpUiToolInputNotification,\n McpUiToolResultNotification,\n} from \"@modelcontextprotocol/ext-apps\";\
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Implementation } from \"@modelcontextprotocol/client\";\nimport type {\n McpUiHostCapabilities,\n McpUiHostContext,\n McpUiToolCancelledNotification,\n McpUiToolInputNotification,\n McpUiToolResultNotification,\n McpUiUpdateModelContextRequest,\n} from \"@modelcontextprotocol/ext-apps\";\n\nexport type McpToolState = {\n toolInput: NonNullable<\n McpUiToolInputNotification[\"params\"][\"arguments\"]\n > | null;\n toolResult: McpUiToolResultNotification[\"params\"] | null;\n toolCancelled: McpUiToolCancelledNotification[\"params\"] | null;\n hostInfo: Implementation | null;\n hostCapabilities: McpUiHostCapabilities | null;\n};\n\n/** ChatGPT-only host context keys from the OpenAI MCP extensions. */\nexport type OpenAIHostContext = {\n /** App-relative URL the view was opened on through a deep link. */\n \"openai/deepLink\"?: { url: string };\n /**\n * Context this view attached to the conversation. `null` once the user\n * removed it, for example by deleting its composer attachment.\n */\n \"openai/modelContext\"?:\n | (McpUiUpdateModelContextRequest[\"params\"] & { updateId: string })\n | null;\n};\n\nexport type McpAppContext = McpUiHostContext & OpenAIHostContext & McpToolState;\n\nexport type McpAppContextKey = keyof McpAppContext;\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Implementation } from "@modelcontextprotocol/
|
|
1
|
+
import type { Implementation } from "@modelcontextprotocol/client";
|
|
2
2
|
import type { McpAppContext } from "./types.js";
|
|
3
3
|
type McpAppInitializationOptions = {
|
|
4
4
|
appInfo: Implementation;
|
|
@@ -7,7 +7,7 @@ type McpAppInitializationOptions = {
|
|
|
7
7
|
* Read a single key from the raw MCP Apps (`ext-apps`) bridge context.
|
|
8
8
|
*
|
|
9
9
|
* Advanced escape hatch — prefer the cross-host hooks (`useToolInfo`,
|
|
10
|
-
* `useViewport`, etc.) which work in both MCP Apps and
|
|
10
|
+
* `useViewport`, etc.) which work in both MCP Apps and ChatGPT. Reach for this
|
|
11
11
|
* when you need protocol-level fields not surfaced by the public hooks.
|
|
12
12
|
*
|
|
13
13
|
* `options.appInfo` is honored only on the first call that creates the
|
|
@@ -4,7 +4,7 @@ import { McpAppBridge } from "./bridge.js";
|
|
|
4
4
|
* Read a single key from the raw MCP Apps (`ext-apps`) bridge context.
|
|
5
5
|
*
|
|
6
6
|
* Advanced escape hatch — prefer the cross-host hooks (`useToolInfo`,
|
|
7
|
-
* `useViewport`, etc.) which work in both MCP Apps and
|
|
7
|
+
* `useViewport`, etc.) which work in both MCP Apps and ChatGPT. Reach for this
|
|
8
8
|
* when you need protocol-level fields not surfaced by the public hooks.
|
|
9
9
|
*
|
|
10
10
|
* `options.appInfo` is honored only on the first call that creates the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-mcp-app-context.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/use-mcp-app-context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO3C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAM,EACN,OAA8C;IAE9C,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CACtD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CACxB,CAAC;AACJ,CAAC","sourcesContent":["import type { Implementation } from \"@modelcontextprotocol/
|
|
1
|
+
{"version":3,"file":"use-mcp-app-context.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/use-mcp-app-context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO3C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAM,EACN,OAA8C;IAE9C,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CACtD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CACxB,CAAC;AACJ,CAAC","sourcesContent":["import type { Implementation } from \"@modelcontextprotocol/client\";\n\nimport { useSyncExternalStore } from \"react\";\nimport { McpAppBridge } from \"./bridge.js\";\nimport type { McpAppContext } from \"./types.js\";\n\ntype McpAppInitializationOptions = {\n appInfo: Implementation;\n};\n\n/**\n * Read a single key from the raw MCP Apps (`ext-apps`) bridge context.\n *\n * Advanced escape hatch — prefer the cross-host hooks (`useToolInfo`,\n * `useViewport`, etc.) which work in both MCP Apps and ChatGPT. Reach for this\n * when you need protocol-level fields not surfaced by the public hooks.\n *\n * `options.appInfo` is honored only on the first call that creates the\n * underlying bridge; subsequent calls reuse the singleton.\n *\n * @see https://docs.skybridge.tech/api-reference/use-mcp-app-context\n */\nexport function useMcpAppContext<K extends keyof McpAppContext>(\n key: K,\n options?: Partial<McpAppInitializationOptions>,\n): McpAppContext[K] {\n const bridge = McpAppBridge.getInstance(options);\n return useSyncExternalStore(bridge.subscribe(key), () =>\n bridge.getSnapshot(key),\n );\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { CallToolResult, EmbeddedResource, ResourceLink, ToolAnnotations } from "@modelcontextprotocol/
|
|
1
|
+
import type { CallToolResult, ContentBlock, EmbeddedResource, ResourceLink, ToolAnnotations } from "@modelcontextprotocol/client";
|
|
2
|
+
import type { McpUiUpdateModelContextRequest } from "@modelcontextprotocol/ext-apps";
|
|
2
3
|
import type { useSyncExternalStore } from "react";
|
|
3
4
|
import type { output as ZodOutput, ZodType } from "zod/v4";
|
|
4
5
|
/**
|
|
@@ -15,6 +16,16 @@ declare global {
|
|
|
15
16
|
}
|
|
16
17
|
/** Arguments passed to a tool call. `null` for tools that take no input. */
|
|
17
18
|
export type CallToolArgs = Record<string, unknown> | null;
|
|
19
|
+
/** Options for a tool call made from the view. */
|
|
20
|
+
export type CallToolOptions = {
|
|
21
|
+
/**
|
|
22
|
+
* Request timeout in milliseconds. Omit it to keep the SDK default (60s).
|
|
23
|
+
* Raise it for tools that wait on the user, such as ChatGPT forms.
|
|
24
|
+
*/
|
|
25
|
+
timeout?: number;
|
|
26
|
+
};
|
|
27
|
+
/** Payload of `ui/update-model-context`. Content blocks may carry `_meta`. */
|
|
28
|
+
export type ModelContextParams = McpUiUpdateModelContextRequest["params"];
|
|
18
29
|
/**
|
|
19
30
|
* Result of a tool call as surfaced to the view: MCP `content` blocks plus
|
|
20
31
|
* the typed `structuredContent` and optional `meta`. `isError` is set when
|
|
@@ -129,8 +140,45 @@ export type OpenExternalOptions = {
|
|
|
129
140
|
};
|
|
130
141
|
/** Options for {@link useSendFollowUpMessage}. */
|
|
131
142
|
export type SendFollowUpMessageOptions = {
|
|
143
|
+
/** Apps SDK only: set to `false` to keep the chat scroll position. */
|
|
132
144
|
scrollToBottom?: boolean;
|
|
145
|
+
/**
|
|
146
|
+
* ChatGPT only, from the OpenAI MCP extensions: `"new"` starts a new
|
|
147
|
+
* conversation with the message. Defaults to the active conversation.
|
|
148
|
+
* Rejects on hosts that don't advertise `openai/message`.
|
|
149
|
+
*/
|
|
150
|
+
target?: "active" | "new";
|
|
151
|
+
};
|
|
152
|
+
/** How the host should return a file resource's contents. */
|
|
153
|
+
export type ResourceRepresentation = "text" | "blob";
|
|
154
|
+
/** Contents of a file resource: text, or a base64 `blob`. */
|
|
155
|
+
export type FileResourceContent = {
|
|
156
|
+
text: string;
|
|
157
|
+
} | {
|
|
158
|
+
blob: string;
|
|
159
|
+
};
|
|
160
|
+
/** A file resource as read from the host. */
|
|
161
|
+
export type FileResource = FileResourceContent & {
|
|
162
|
+
mimeType?: string;
|
|
163
|
+
/** Whether the host accepts writes to this resource. */
|
|
164
|
+
writable: boolean;
|
|
165
|
+
/** Version token of these contents, sent back as `ifMatch` on write. */
|
|
166
|
+
etag?: string;
|
|
133
167
|
};
|
|
168
|
+
/** Result of `openai/resources/write`. */
|
|
169
|
+
export type FileResourceWriteResult = {
|
|
170
|
+
outcome: "saved" | "conflict";
|
|
171
|
+
etag: string;
|
|
172
|
+
} | {
|
|
173
|
+
outcome: "too-large";
|
|
174
|
+
maxBytes: number;
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* A follow-up message: plain text, or content blocks. On ChatGPT, a text or
|
|
178
|
+
* image block with `_meta["openai/title"]` becomes a labeled item the user can
|
|
179
|
+
* remove.
|
|
180
|
+
*/
|
|
181
|
+
export type FollowUpMessage = string | ContentBlock[];
|
|
134
182
|
/** Options for {@link useRequestSize}. Omit a dimension to leave it unchanged. */
|
|
135
183
|
export type RequestSizeOptions = {
|
|
136
184
|
width?: number;
|
|
@@ -188,16 +236,21 @@ export type AnyViewToolHandler = (args: Record<string, unknown>) => ViewToolResu
|
|
|
188
236
|
*/
|
|
189
237
|
export interface Adaptor {
|
|
190
238
|
getHostContextStore<K extends keyof HostContext>(key: K): HostContextStore<K>;
|
|
191
|
-
callTool<ToolArgs extends CallToolArgs = null, ToolResponse extends CallToolResponse = CallToolResponse>(name: string, args: ToolArgs): Promise<ToolResponse>;
|
|
239
|
+
callTool<ToolArgs extends CallToolArgs = null, ToolResponse extends CallToolResponse = CallToolResponse>(name: string, args: ToolArgs, options?: CallToolOptions): Promise<ToolResponse>;
|
|
192
240
|
requestDisplayMode(mode: RequestDisplayMode): Promise<{
|
|
193
241
|
mode: RequestDisplayMode;
|
|
194
242
|
}>;
|
|
195
243
|
requestClose(): Promise<void>;
|
|
196
244
|
requestSize(size: RequestSizeOptions): Promise<void>;
|
|
197
|
-
sendFollowUpMessage(prompt:
|
|
245
|
+
sendFollowUpMessage(prompt: FollowUpMessage, options?: SendFollowUpMessageOptions): Promise<void>;
|
|
198
246
|
openExternal(href: string, options?: OpenExternalOptions): void;
|
|
199
247
|
download(params: DownloadParams): Promise<DownloadResult>;
|
|
200
248
|
setViewState(stateOrUpdater: SetViewStateAction): Promise<void>;
|
|
249
|
+
updateModelContext(params: ModelContextParams): Promise<string | undefined>;
|
|
250
|
+
openFile(path: string): Promise<void>;
|
|
251
|
+
readResource(uri: string, representation?: ResourceRepresentation): Promise<FileResource>;
|
|
252
|
+
watchResource(uri: string, onUpdate: () => void): () => void;
|
|
253
|
+
writeResource(uri: string, content: FileResourceContent, ifMatch?: string): Promise<FileResourceWriteResult>;
|
|
201
254
|
uploadFile(file: File, options?: UploadFileOptions): Promise<FileMetadata>;
|
|
202
255
|
getFileDownloadUrl(file: FileMetadata): Promise<{
|
|
203
256
|
downloadUrl: string;
|
|
@@ -210,7 +263,7 @@ export interface Adaptor {
|
|
|
210
263
|
}
|
|
211
264
|
/**
|
|
212
265
|
* Thrown when a host bridge method is called in a runtime that doesn't
|
|
213
|
-
* support it (e.g. `uploadFile` outside the
|
|
266
|
+
* support it (e.g. `uploadFile` outside the ChatGPT runtime).
|
|
214
267
|
*/
|
|
215
268
|
export declare class NotSupportedError extends Error {
|
|
216
269
|
readonly method: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Thrown when a host bridge method is called in a runtime that doesn't
|
|
3
|
-
* support it (e.g. `uploadFile` outside the
|
|
3
|
+
* support it (e.g. `uploadFile` outside the ChatGPT runtime).
|
|
4
4
|
*/
|
|
5
5
|
export class NotSupportedError extends Error {
|
|
6
6
|
method;
|