@mcp-apps-kit/ui
Advanced tools
+2
-1
@@ -1,2 +0,3 @@ | ||
| 'use strict';var extApps=require('@modelcontextprotocol/ext-apps');var D="2025-11-05",_="text/html;profile=mcp-app",F="ui/resourceUri";function x(r){if(typeof document>"u")return;let e=r==="os"?typeof window<"u"&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":r;document.documentElement.classList.remove("light","dark"),document.documentElement.classList.add(e),document.documentElement.setAttribute("data-theme",e);}function H(){if(typeof document>"u")return "light";let r=document.documentElement.getAttribute("data-theme");return r==="dark"||r==="light"?r:document.documentElement.classList.contains("dark")?"dark":"light"}var T="mcp-apps-host-fonts";function k(r){if(typeof document>"u")return;let e=document.documentElement;for(let[t,n]of Object.entries(r)){let o=t.startsWith("--")?t:`--${t}`;e.style.setProperty(o,n);}}function O(r){if(typeof document>"u")return;let e=document.getElementById(T);e||(e=document.createElement("style"),e.id=T,document.head.appendChild(e)),e.textContent=r;}function A(){if(typeof document>"u")return;let r=document.getElementById(T);r&&r.remove();}function R(r){if(typeof document>"u")return;let e=document.documentElement;for(let t of Object.keys(r)){let n=t.startsWith("--")?t:`--${t}`;e.style.removeProperty(n);}}var g={CONNECTION_FAILED:"CONNECTION_FAILED",CONNECTION_TIMEOUT:"CONNECTION_TIMEOUT",NOT_CONNECTED:"NOT_CONNECTED",PROTOCOL_ERROR:"PROTOCOL_ERROR",UNSUPPORTED_OPERATION:"UNSUPPORTED_OPERATION",TOOL_CALL_FAILED:"TOOL_CALL_FAILED",TOOL_NOT_FOUND:"TOOL_NOT_FOUND",STATE_ERROR:"STATE_ERROR",UNKNOWN_ERROR:"UNKNOWN_ERROR"},d=class extends Error{constructor(t,n,o,s){super(n);this.code=t;this.details=o;this.cause=s;this.name="UIError";}formatMessage(){let t=`[${this.code}] ${this.message}`;return this.details&&(t+=` ${JSON.stringify(this.details)}`),t}};var I={debug:0,info:1,warn:2,error:3};function S(r,e){return I[r]>=I[e]}function M(){let r=new WeakSet;return (e,t)=>{if(typeof t=="object"&&t!==null){if(r.has(t))return "[Circular]";r.add(t);}return t}}function E(r){if(r==null||typeof r=="string"||typeof r=="number"||typeof r=="boolean")return r;if(r instanceof Error)return {name:r.name,message:r.message,stack:r.stack};try{return JSON.stringify(r),r}catch{try{let e=JSON.stringify(r,M());return JSON.parse(e)}catch{return "[Unserializable]"}}}function P(r){if(r===void 0)return "undefined";if(r===null)return "null";if(typeof r=="string")return r;if(r instanceof Error)return `${r.name}: ${r.message}`;try{return JSON.stringify(r,M())}catch{return "[Unstringifiable]"}}var y=class{constructor(e={}){this.adapter=null;this.buffer=[];this.flushTimer=null;this.isFlushing=false;this.mcpTransportFailed=false;this.apiTransportFailed=false;this.config={enabled:e.enabled??false,level:e.level??"info",batchSize:e.batchSize??10,maxBufferSize:e.maxBufferSize??100,flushIntervalMs:e.flushIntervalMs??5e3,source:e.source??"mcp-apps-ui",transport:e.transport??"tool",apiEndpoint:e.apiEndpoint};}setAdapter(e){this.adapter=e,this.mcpTransportFailed=false,this.apiTransportFailed=false;}configure(e){e.enabled!==void 0&&(this.config.enabled=e.enabled),e.level!==void 0&&(this.config.level=e.level),e.batchSize!==void 0&&(this.config.batchSize=e.batchSize),e.maxBufferSize!==void 0&&(this.config.maxBufferSize=e.maxBufferSize),e.flushIntervalMs!==void 0&&(this.config.flushIntervalMs=e.flushIntervalMs,this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),this.scheduleFlush()),e.source!==void 0&&(this.config.source=e.source),e.transport!==void 0&&(this.config.transport=e.transport,this.mcpTransportFailed=false,this.apiTransportFailed=false),e.apiEndpoint!==void 0&&(this.config.apiEndpoint=e.apiEndpoint,this.apiTransportFailed=false);}canUseToolTransport(){return this.config.enabled&&this.config.transport==="tool"&&!this.mcpTransportFailed&&this.adapter?.isConnected()===true}canUseApiTransport(){return this.config.enabled&&this.config.transport==="api"&&!this.apiTransportFailed&&!!this.config.apiEndpoint}canUseRemoteTransport(){return this.canUseToolTransport()||this.canUseApiTransport()}createEntry(e,t,n){return {level:e,message:t,data:n!==void 0?E(n):void 0,timestamp:new Date().toISOString(),source:this.config.source}}scheduleFlush(){this.flushTimer||this.buffer.length===0||(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}async flushToApi(e){if(!this.config.apiEndpoint)throw new Error("API endpoint not configured");let t=await fetch(this.config.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:e})});if(!t.ok)throw new Error(`API request failed with status ${String(t.status)}`)}async flushToTool(e){if(!this.adapter)throw new Error("Adapter not connected");await this.adapter.callTool("log_debug",{entries:e});}async flush(){if(this.isFlushing||this.buffer.length===0)return;if(this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),!this.canUseRemoteTransport()){this.buffer=[];return}this.isFlushing=true;let e=[...this.buffer];try{this.canUseApiTransport()?await this.flushToApi(e):this.canUseToolTransport()&&await this.flushToTool(e),this.buffer=this.buffer.slice(e.length);}catch(t){this.buffer=this.buffer.slice(e.length);let n=t instanceof Error?t.message:String(t);this.config.transport==="api"&&!this.apiTransportFailed?(this.apiTransportFailed=true,console.warn(`[ClientDebugLogger] API log transport failed: ${n}. Will only use console`)):this.config.transport==="tool"&&!this.mcpTransportFailed&&(this.mcpTransportFailed=true,console.warn(`[ClientDebugLogger] MCP log transport failed: ${n}. Will only use console`));}finally{this.isFlushing=false,this.buffer.length>0&&this.scheduleFlush();}}outputToConsole(e){let t=`[${e.timestamp}] [${e.level.toUpperCase()}]`,n=e.data!==void 0?`${e.message} ${P(e.data)}`:e.message,o=`${t} ${n}`;try{switch(e.level){case "debug":console.debug(o);break;case "info":console.info(o);break;case "warn":console.warn(o);break;case "error":console.error(o);break}}catch{}}addToBuffer(e){for(;this.buffer.length>=this.config.maxBufferSize;)this.buffer.shift();if(this.buffer.push(e),e.level==="error"){this.flush();return}if(this.buffer.length>=this.config.batchSize){this.flush();return}this.scheduleFlush();}log(e,t,n){if(!S(e,this.config.level))return;let o=this.createEntry(e,t,n);this.outputToConsole(o),this.canUseRemoteTransport()&&this.addToBuffer(o);}debug(e,t){this.log("debug",e,t);}info(e,t){this.log("info",e,t);}warn(e,t){this.log("warn",e,t);}error(e,t){this.log("error",e,t);}destroy(){this.buffer=[],this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),this.adapter=null;}},i=new y;function L(){return typeof window<"u"&&window.__MCP_SERVER_CONFIG__?window.__MCP_SERVER_CONFIG__:typeof __MCP_SERVER_CONFIG__<"u"&&__MCP_SERVER_CONFIG__?__MCP_SERVER_CONFIG__:{}}function N(r=""){let e=L();return e.baseUrl?e.baseUrl:typeof window<"u"&&(window.location.protocol==="http:"||window.location.protocol==="https:")?window.location.origin:r}var h=class{constructor(){this.connected=false;this.state=null;this.toolResultHandlers=new Set;this.toolInputHandlers=new Set;this.toolInputPartialHandlers=new Set;this.toolCancelledHandlers=new Set;this.hostContextHandlers=new Set;this.teardownHandlers=new Set;this.mockHostCapabilities={logging:{},openLinks:{},theming:{themes:["light","dark","os"]},displayModes:{modes:["inline","fullscreen","pip","panel"]},statePersistence:{persistent:true},serverTools:{listChanged:false},serverResources:{listChanged:false},sizeNotifications:{},partialToolInput:{},appTools:{listChanged:false},fileUpload:{},safeAreaInsets:{},views:{}};this.mockHostVersion={name:"MockHost",version:"1.0.0"};this.context=this.createDefaultContext();}createDefaultContext(){let e=typeof window<"u";return {theme:"light",displayMode:"inline",availableDisplayModes:["inline","fullscreen","pip"],viewport:{width:e?window.innerWidth:800,height:e?window.innerHeight:600},locale:e?navigator.language:"en-US",timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,platform:"web",deviceCapabilities:{touch:e?"ontouchstart"in window:false,hover:true}}}async connect(){this.connected=true,console.log("[MockAdapter] Connected");}isConnected(){return this.connected}async callTool(e,t){console.log(`[MockAdapter] callTool("${e}",`,t,")");let n={_mock:true,tool:e,args:t,timestamp:Date.now()};return this.currentToolOutput=n,n}async sendMessage(e){console.log("[MockAdapter] sendMessage:",e);}async openLink(e){console.log(`[MockAdapter] openLink("${e}")`);}async requestDisplayMode(e){return console.log(`[MockAdapter] requestDisplayMode("${e}")`),this.context={...this.context,displayMode:e},this.notifyHostContextChange(),{mode:e}}requestClose(){console.log("[MockAdapter] requestClose()");}getState(){return this.state}setState(e){this.state=e,console.log("[MockAdapter] setState:",e);}async readResource(e){return console.log(`[MockAdapter] readResource("${e}")`),{contents:[]}}log(e,t){({debug:console.debug,info:console.info,warning:console.warn,error:console.error}[e]??console.log)("[MockAdapter]",t);}onToolResult(e){return this.toolResultHandlers.add(e),()=>this.toolResultHandlers.delete(e)}onToolInput(e){return this.toolInputHandlers.add(e),()=>this.toolInputHandlers.delete(e)}onToolCancelled(e){return this.toolCancelledHandlers.add(e),()=>this.toolCancelledHandlers.delete(e)}onHostContextChange(e){return this.hostContextHandlers.add(e),()=>this.hostContextHandlers.delete(e)}onTeardown(e){return this.teardownHandlers.add(e),()=>this.teardownHandlers.delete(e)}getHostContext(){return this.context}getToolInput(){return this.currentToolInput}getToolOutput(){return this.currentToolOutput}getToolMeta(){return this.currentToolMeta}emitToolResult(e){this.currentToolOutput=e;for(let t of this.toolResultHandlers)t(e);}emitToolInput(e){this.currentToolInput=e;for(let t of this.toolInputHandlers)t(e);}setHostContext(e){this.context={...this.context,...e},this.notifyHostContextChange();}emitContextChange(e){this.context=e,this.notifyHostContextChange();}setToolInput(e){this.currentToolInput=e;}emitToolCancelled(e){for(let t of this.toolCancelledHandlers)t(e);}emitTeardown(e){for(let t of this.teardownHandlers)t(e);}notifyHostContextChange(){for(let e of this.hostContextHandlers)e(this.context);}getHostCapabilities(){return this.mockHostCapabilities}getHostVersion(){return this.mockHostVersion}async sendLog(e,t){console.log(`[MockAdapter] sendLog(${e}):`,t);}async sendLogs(e){for(let t of e)console.log(`[MockAdapter] sendLogs(${t.level}):`,t.message,t.data);return {processed:e.length}}async sendSizeChanged(e){console.log("[MockAdapter] sendSizeChanged:",e);}onToolInputPartial(e){return this.toolInputPartialHandlers.add(e),()=>this.toolInputPartialHandlers.delete(e)}setCallToolHandler(e){this.callToolHandler=e,console.log("[MockAdapter] setCallToolHandler: handler registered");}setListToolsHandler(e){this.listToolsHandler=e,console.log("[MockAdapter] setListToolsHandler: handler registered");}emitToolInputPartial(e){for(let t of this.toolInputPartialHandlers)t(e);}setMockHostCapabilities(e){this.mockHostCapabilities={...this.mockHostCapabilities,...e};}setMockHostVersion(e){this.mockHostVersion=e;}async simulateHostToolCall(e,t){if(!this.callToolHandler)throw new d(g.TOOL_NOT_FOUND,"No call tool handler registered");return this.callToolHandler(e,t)}async simulateHostListTools(){return this.listToolsHandler?this.listToolsHandler():{tools:[]}}};var z={parse:r=>r},m=class{constructor(e){this.connected=false;this.toolResultHandlers=new Set;this.toolInputHandlers=new Set;this.toolInputPartialHandlers=new Set;this.toolCancelledHandlers=new Set;this.hostContextHandlers=new Set;this.teardownHandlers=new Set;this.context=this.createDefaultContext(),this.autoResize=e?.autoResize??true;}createDefaultContext(){let e=typeof window<"u";return {theme:"light",displayMode:"inline",availableDisplayModes:["inline","fullscreen"],viewport:{width:e?window.innerWidth:800,height:e?window.innerHeight:600},locale:e?navigator.language:"en-US",timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,platform:"desktop"}}async connect(){if(this.connected)return;if(typeof window>"u"){this.connected=true;return}this.app=new extApps.App({name:"@mcp-apps-kit/ui",version:"0.0.0"},{tools:{}},{autoResize:this.autoResize}),this.app.onerror=t=>{this.log("error",t);},this.app.onhostcontextchanged=t=>{let n=t.hostContext??t;this.context=this.mapHostContext(n),this.currentToolMeta=this.extractToolMeta(n);for(let o of this.hostContextHandlers)o(this.context);},this.app.ontoolinput=t=>{let n=t.arguments;if(n){this.currentToolInput=n;for(let o of this.toolInputHandlers)o(n);}},this.app.ontoolinputpartial=t=>{let n=t.arguments;if(n)for(let o of this.toolInputPartialHandlers)o(n);},this.app.oncalltool=async t=>{let{name:n,arguments:o}=t;try{if(this.callToolHandler){let s=await this.callToolHandler(n,o??{});return {content:[{type:"text",text:JSON.stringify(s)}]}}return {content:[{type:"text",text:`No handler registered for tool: ${n}`}],isError:!0}}catch(s){return {content:[{type:"text",text:s instanceof Error?s.message:String(s)}],isError:true}}},this.app.onlisttools=async()=>this.listToolsHandler?{tools:(await this.listToolsHandler()).map(n=>n.name)}:{tools:[]},this.app.ontoolresult=t=>{let n=this.extractToolOutput(t);this.currentToolOutput=n;let o=this.getToolNameFromContext(),s=o?{[o]:n}:n;for(let a of this.toolResultHandlers)a(s);},this.app.ontoolcancelled=t=>{let n=t.reason;for(let o of this.toolCancelledHandlers)o(n);},this.app.onteardown=async t=>{let n=t.reason;for(let o of this.teardownHandlers)o(n);return {}},await this.app.connect();let e=this.app.getHostContext();e&&(this.context=this.mapHostContext(e),this.currentToolMeta=this.extractToolMeta(e)),this.connected=true;}isConnected(){return this.connected}mapHostContext(e){let t=e??{},n=this.createDefaultContext(),o=n.theme;(t.theme==="dark"||t.theme==="light")&&(o=t.theme);let s=t.displayMode==="fullscreen"||t.displayMode==="pip"||t.displayMode==="inline"?t.displayMode:n.displayMode,a=Array.isArray(t.availableDisplayModes)?t.availableDisplayModes.filter(c=>typeof c=="string"):n.availableDisplayModes,p=(c=>c!==null&&typeof c=="object"&&!Array.isArray(c))(t.viewport)?{...n.viewport,...t.viewport}:n.viewport,u=typeof t.locale=="string"?t.locale:n.locale,f=typeof t.timeZone=="string"?t.timeZone:n.timeZone,v=n.platform;return {...n,theme:o,displayMode:s,availableDisplayModes:a,viewport:p,locale:u,timeZone:f,platform:v,userAgent:typeof t.userAgent=="string"?t.userAgent:n.userAgent,deviceCapabilities:t.deviceCapabilities,safeAreaInsets:t.safeAreaInsets,styles:t.styles,view:typeof t.view=="string"?t.view:n.view}}extractToolMeta(e){if(e===null||typeof e!="object")return;let t=e;if(!(!t.toolInfo||typeof t.toolInfo!="object"))return {toolInfo:t.toolInfo}}getToolNameFromContext(){if(!this.app)return;let e=this.app.getHostContext();return e?e.toolInfo?.tool?.name:void 0}extractToolOutput(e){let t=e.structuredContent,n=e._meta,o=t&&typeof t=="object"&&!Array.isArray(t)?t:{};if(n&&typeof n=="object"&&!Array.isArray(n))return {...o,_meta:n};if(Object.keys(o).length===0){let s=e.content;if(Array.isArray(s)&&s.length>0){let a=s[0];if(a?.type==="text"&&typeof a.text=="string")try{let l=JSON.parse(a.text);if(l!==null&&typeof l=="object"&&!Array.isArray(l))return l}catch{}}}return o}async callTool(e,t){if(!this.app)throw new Error("MCP Apps adapter not connected");let n=await this.app.callServerTool({name:e,arguments:t});return this.extractToolOutput(n)}async sendMessage(e){if(!this.app)throw new Error("MCP Apps adapter not connected");if(e.type!=="text")throw new Error(`Unsupported message content type: ${e.type}`);await this.app.sendMessage({role:"user",content:[{type:"text",text:e.text}]});}async openLink(e){if(!this.app)throw new Error("MCP Apps adapter not connected");await this.app.openLink({url:e});}async requestDisplayMode(e){if(!this.app)throw new Error("MCP Apps adapter not connected");return await this.app.requestDisplayMode({mode:e})}requestClose(){}getState(){return null}setState(e){}async readResource(e){if(!this.app)throw new Error("MCP Apps adapter not connected");let n=await this.app.request.bind(this.app)({method:"resources/read",params:{uri:e}},z);return {contents:(Array.isArray(n.contents)?n.contents:[]).map(o=>{let s={uri:o.uri,mimeType:o.mimeType??"application/octet-stream"};if("text"in o&&typeof o.text=="string")return {...s,text:o.text};if("blob"in o&&typeof o.blob=="string"){let a=Uint8Array.from(atob(o.blob),l=>l.charCodeAt(0));return {...s,blob:a}}return s})}}log(e,t){if(this.app){let s={level:["debug","info","notice","warning","error","critical","alert","emergency"].includes(e)?e:"info",data:t,logger:"@mcp-apps-kit/ui"};try{this.app.sendLog(s);return}catch{}}({debug:console.debug,info:console.info,warning:console.warn,error:console.error}[e]??console.log)("[MCP Apps]",t);}onToolResult(e){return this.toolResultHandlers.add(e),()=>this.toolResultHandlers.delete(e)}onToolInput(e){return this.toolInputHandlers.add(e),()=>this.toolInputHandlers.delete(e)}onToolCancelled(e){return this.toolCancelledHandlers.add(e),()=>this.toolCancelledHandlers.delete(e)}onHostContextChange(e){return this.hostContextHandlers.add(e),()=>this.hostContextHandlers.delete(e)}onTeardown(e){return this.teardownHandlers.add(e),()=>this.teardownHandlers.delete(e)}getHostContext(){return this.context}getToolInput(){return this.currentToolInput}getToolOutput(){return this.currentToolOutput}getToolMeta(){return this.currentToolMeta}getHostCapabilities(){if(!this.app)return;let e=this.app.getHostCapabilities();if(!e)return;let t=e,o=this.app.getHostContext()?.availableDisplayModes;return {logging:t.logging,openLinks:t.openLinks,serverResources:t.serverResources,serverTools:t.serverTools,experimental:t.experimental,theming:{themes:["light","dark"]},displayModes:o?{modes:o}:void 0,statePersistence:{persistent:false},sizeNotifications:{},partialToolInput:{},appTools:{listChanged:false}}}getHostVersion(){if(!this.app)return;let e=this.app.getHostVersion();if(e)return {name:e.name,version:e.version}}async sendLog(e,t){if(!this.app)throw new d(g.NOT_CONNECTED,"MCP Apps adapter not connected");await this.app.sendLog({level:e,data:t,logger:"@mcp-apps-kit/ui"});}async sendLogs(e){if(!this.app)throw new d(g.NOT_CONNECTED,"MCP Apps adapter not connected");let t={debug:"debug",info:"info",warn:"warning",error:"error"},n=0;for(let o of e)try{await this.app.sendLog({level:t[o.level]??"info",data:o.data??o.message,logger:o.source??"@mcp-apps-kit/ui"}),n++;}catch{}return {processed:n}}async sendSizeChanged(e){if(!this.app)throw new d(g.NOT_CONNECTED,"MCP Apps adapter not connected");await this.app.sendSizeChanged({width:e.width,height:e.height});}onToolInputPartial(e){return this.toolInputPartialHandlers.add(e),()=>this.toolInputPartialHandlers.delete(e)}setCallToolHandler(e){this.callToolHandler=e;}setListToolsHandler(e){this.listToolsHandler=e;}};var w=class{constructor(){this.connected=false;this.state=null;this.toolResultHandlers=new Set;this.toolInputHandlers=new Set;this.toolCancelledHandlers=new Set;this.hostContextHandlers=new Set;this.teardownHandlers=new Set;this.logTransport="api";this.apiTransportFailed=false;this.toolTransportFailed=false;this.context=this.createDefaultContext();}configureLogging(e){e.transport!==void 0&&(this.logTransport=e.transport,this.apiTransportFailed=false,this.toolTransportFailed=false),e.apiEndpoint!==void 0&&(this.logApiEndpoint=e.apiEndpoint,this.apiTransportFailed=false);}createDefaultContext(){let e=typeof window<"u";return {theme:"light",displayMode:"inline",availableDisplayModes:["inline","fullscreen","pip"],viewport:{width:e?window.innerWidth:800,height:e?window.innerHeight:600},locale:e?navigator.language:"en-US",timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,platform:"web",deviceCapabilities:{touch:e?"ontouchstart"in window:false,hover:true}}}isSetGlobalsMessage(e){return e==="openai:set_globals"||typeof e=="object"&&e!==null&&"type"in e&&e.type==="openai:set_globals"||typeof e=="object"&&e!==null&&"message"in e&&e.message==="openai:set_globals"}readContextFromSDK(){let e=this.getOpenAI();if(!e)return;let t=typeof window<"u";if(typeof e.theme=="string"&&(this.context.theme=e.theme),typeof e.displayMode=="string"&&(this.context.displayMode=e.displayMode),typeof e.locale=="string"&&(this.context.locale=e.locale),typeof e.userAgent=="string"&&Object.assign(this.context,{userAgent:e.userAgent}),typeof e.view=="string"&&(this.context.view=e.view),e.safeArea&&typeof e.safeArea=="object"){let n=e.safeArea;this.context.safeAreaInsets={top:typeof n.top=="number"?n.top:0,right:typeof n.right=="number"?n.right:0,bottom:typeof n.bottom=="number"?n.bottom:0,left:typeof n.left=="number"?n.left:0};}typeof e.maxHeight=="number"&&(this.context.viewport={width:t?window.innerWidth:800,height:e.maxHeight}),i.debug("[OpenAI Adapter] Read context from SDK",this.context);}notifyContextChange(){i.debug(`[OpenAI Adapter] Notifying ${String(this.hostContextHandlers.size)} context change handlers`);let e={...this.context};for(let t of this.hostContextHandlers)t(e);}getOpenAI(){return typeof window<"u"&&"openai"in window?window.openai:null}getToolNameFromSDK(){let e=this.getOpenAI();if(e){if(e.toolResponseMetadata&&typeof e.toolResponseMetadata=="object"){let t=e.toolResponseMetadata;if(typeof t.toolName=="string")return t.toolName}if(typeof e.toolName=="string")return e.toolName}}async connect(){await this.waitForOpenAI();let e=this.getOpenAI();if(e){i.debug("[OpenAI Adapter] Available SDK methods",Object.keys(e)),this.readContextFromSDK();let t=this.getToolNameFromSDK();if(typeof e.getToolOutput=="function"?(this.currentToolOutput=e.getToolOutput(),i.debug("[OpenAI Adapter] Got tool output from SDK")):e.toolOutput?(this.currentToolOutput=e.toolOutput,i.debug("[OpenAI Adapter] Got tool output from SDK property")):e.result&&(this.currentToolOutput=e.result,i.debug("[OpenAI Adapter] Got result from SDK")),this.currentToolOutput&&Object.keys(this.currentToolOutput).length>0){let n=t?{[t]:this.currentToolOutput}:this.currentToolOutput;for(let o of this.toolResultHandlers)o(n);}typeof e.getToolInput=="function"?this.currentToolInput=e.getToolInput():e.toolInput?this.currentToolInput=e.toolInput:e.input&&(this.currentToolInput=e.input),typeof e.init=="function"&&await e.init();}this.setupGlobalsListener(),this.connected=true;}setupGlobalsListener(){typeof window>"u"||(this.setGlobalsHandler=e=>{let n=e.detail;if(!n){this.readContextFromSDK(),this.checkForToolOutputUpdate();return}let o=n.globals??n,s=this.context.theme,a=this.context.locale,l=this.context.displayMode,p=this.currentToolOutput;if(o.theme!==void 0&&(this.context.theme=o.theme),o.locale!==void 0&&(this.context.locale=o.locale),o.displayMode!==void 0&&(this.context.displayMode=o.displayMode),(this.context.theme!==s||this.context.locale!==a||this.context.displayMode!==l)&&(i.debug("[OpenAI Adapter] Context changed, notifying handlers"),this.notifyContextChange()),o.toolOutput!==void 0&&o.toolOutput!==null){let u=o.toolOutput;if(Object.keys(u).length>0&&u!==p){i.debug("[OpenAI Adapter] Got toolOutput from set_globals event",u),this.currentToolOutput=u;let f;o.toolResponseMetadata&&typeof o.toolResponseMetadata=="object"&&o.toolResponseMetadata.toolName?f=o.toolResponseMetadata.toolName:f=this.getToolNameFromSDK();let v=f?{[f]:u}:u;for(let c of this.toolResultHandlers)c(v);}}o.toolInput!==void 0&&(this.currentToolInput=o.toolInput);},window.addEventListener("openai:set_globals",this.setGlobalsHandler),this.globalsHandler=e=>{this.isSetGlobalsMessage(e.data)&&(i.debug("[OpenAI Adapter] Received set_globals via postMessage (legacy)"),this.readContextFromSDK(),this.checkForToolOutputUpdate());},window.addEventListener("message",this.globalsHandler));}checkForToolOutputUpdate(){let e=this.getOpenAI();if(!e)return;let t;if(e.toolOutput&&(t=e.toolOutput),t&&Object.keys(t).length>0&&t!==this.currentToolOutput){i.debug("[OpenAI Adapter] toolOutput updated",t),this.currentToolOutput=t;let n=this.getToolNameFromSDK(),o=n?{[n]:t}:t;for(let s of this.toolResultHandlers)s(o);}}async waitForOpenAI(e=5e3){if(this.getOpenAI()){i.debug("[OpenAI Adapter] window.openai already available");return}return i.debug("[OpenAI Adapter] Waiting for window.openai..."),new Promise(t=>{let n=Date.now(),o=false,s=()=>{o||(o=true,window.removeEventListener("message",l),t());},a=()=>{if(!o){if(this.getOpenAI()){i.debug("[OpenAI Adapter] window.openai found via polling"),s();return}if(Date.now()-n>e){i.warn("[OpenAI Adapter] window.openai not found after timeout, proceeding anyway"),s();return}setTimeout(a,50);}},l=p=>{this.isSetGlobalsMessage(p.data)&&(i.debug("[OpenAI Adapter] Received set_globals message"),setTimeout(()=>{this.getOpenAI()?(i.debug("[OpenAI Adapter] window.openai available after set_globals"),s()):i.debug("[OpenAI Adapter] window.openai still not available after set_globals, continuing poll");},50));};window.addEventListener("message",l),a();})}isConnected(){return this.connected}async callTool(e,t){let n=this.getOpenAI();if(n&&typeof n.callTool=="function")return n.callTool(e,t);throw new Error("OpenAI SDK not available")}async sendMessage(e){if(e.type!=="text")throw new Error(`Unsupported message content type: ${e.type}`);let t=this.getOpenAI();t&&typeof t.sendFollowUpMessage=="function"&&await t.sendFollowUpMessage({prompt:e.text});}async openLink(e){let t=this.getOpenAI();t&&typeof t.openExternal=="function"?await t.openExternal({href:e}):window.open(e,"_blank");}async requestDisplayMode(e){let t=this.getOpenAI();if(t&&typeof t.requestDisplayMode=="function"){let n=await t.requestDisplayMode({mode:e});return this.context={...this.context,displayMode:n.mode},this.notifyContextChange(),n}return this.context={...this.context,displayMode:e},this.notifyContextChange(),{mode:e}}requestClose(){let e=this.getOpenAI();e&&typeof e.close=="function"&&e.close();}getState(){return this.state}setState(e){this.state=e;let t=this.getOpenAI();t&&typeof t.setWidgetState=="function"&&t.setWidgetState(e);}async uploadFile(e){let t=this.getOpenAI();if(t&&typeof t.uploadFile=="function")return t.uploadFile(e);throw new Error("File upload not supported")}async getFileDownloadUrl(e){let t=this.getOpenAI();if(t&&typeof t.getFileDownloadUrl=="function")return t.getFileDownloadUrl(e);throw new Error("File download not supported")}async readResource(e){let t=this.getOpenAI();return t&&typeof t.readResource=="function"?t.readResource(e):{contents:[]}}log(e,t){({debug:console.debug,info:console.info,warning:console.warn,error:console.error}[e]??console.log)("[ChatGPT Apps]",t);}onToolResult(e){return this.toolResultHandlers.add(e),()=>this.toolResultHandlers.delete(e)}onToolInput(e){return this.toolInputHandlers.add(e),()=>this.toolInputHandlers.delete(e)}onToolCancelled(e){return this.toolCancelledHandlers.add(e),()=>this.toolCancelledHandlers.delete(e)}onHostContextChange(e){return this.hostContextHandlers.add(e),i.debug(`[OpenAI Adapter] Host context handler added, total: ${String(this.hostContextHandlers.size)}`),()=>{this.hostContextHandlers.delete(e),i.debug(`[OpenAI Adapter] Host context handler removed, total: ${String(this.hostContextHandlers.size)}`);}}onTeardown(e){return this.teardownHandlers.add(e),()=>this.teardownHandlers.delete(e)}getHostContext(){return this.context}getToolInput(){return this.currentToolInput}getToolOutput(){if(!this.currentToolOutput)return;let e=this.getToolNameFromSDK();return e?{[e]:this.currentToolOutput}:this.currentToolOutput}getToolMeta(){return this.currentToolMeta}getHostCapabilities(){let e=this.getOpenAI(),t=e&&typeof e.uploadFile=="function",n=this.context.safeAreaInsets!==void 0,o=this.context.view!==void 0;return {openLinks:{},logging:{},theming:{themes:["light","dark"]},displayModes:{modes:["inline","fullscreen","pip"]},statePersistence:{persistent:false},fileUpload:t?{}:void 0,safeAreaInsets:n?{}:void 0,views:o?{}:void 0}}getHostVersion(){}async sendLog(e,t){let o={level:{debug:"debug",info:"info",notice:"info",warning:"warn",error:"error",critical:"error",alert:"error",emergency:"error"}[e],message:typeof t=="string"?t:JSON.stringify(t),data:typeof t=="string"?void 0:t,timestamp:new Date().toISOString(),source:"openai-adapter"};await this.sendLogs([o]);}async sendLogs(e){if(this.logTransport==="api"&&this.logApiEndpoint&&!this.apiTransportFailed)try{let t=await fetch(this.logApiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:e})});if(!t.ok)throw new Error(`API request failed with status ${String(t.status)}`);return await t.json()}catch(t){this.apiTransportFailed=true,i.info("[OpenAI Adapter] API log transport failed, trying fallback",{error:t instanceof Error?t.message:t});}if((this.logTransport==="tool"||this.apiTransportFailed)&&!this.toolTransportFailed&&this.connected)try{return await this.callTool("log_debug",{entries:e})}catch(t){this.toolTransportFailed=true,i.info("[OpenAI Adapter] Tool log transport failed, falling back to console",{error:t instanceof Error?t.message:t});}for(let t of e)this.log(t.level==="warn"?"warning":t.level,t.data??t.message);return {processed:e.length}}async sendSizeChanged(e){let t=this.getOpenAI();t&&typeof t.notifyIntrinsicHeight=="function"&&t.notifyIntrinsicHeight(e.height);}onToolInputPartial(e){return this.log("debug","onToolInputPartial is not supported on ChatGPT"),()=>{}}setCallToolHandler(e){this.log("debug","setCallToolHandler is not supported on ChatGPT");}setListToolsHandler(e){this.log("debug","setListToolsHandler is not supported on ChatGPT");}};function C(){if(typeof window>"u")return "mock";if("openai"in window)return "openai";let r=window.location.href,e=document.referrer;return r.includes("/api/apps/chatgpt/")||r.includes("chatgpt")||r.includes("sandbox-proxy")||r.includes("widget-content")||e.includes("chatgpt")||e.includes("openai.com")?"openai":window.parent!==window?"mcp":"mock"}function V(r){return new Proxy({},{get(e,t){if(typeof t!="string"||!t.startsWith("call"))return;let n=t.slice(4);if(n.length===0)return;let o=n.charAt(0).toLowerCase()+n.slice(1);return s=>r(o,s)},has(e,t){return typeof t=="string"&&t.startsWith("call")&&t.length>4},ownKeys(){return []},getOwnPropertyDescriptor(e,t){if(typeof t=="string"&&t.startsWith("call")&&t.length>4)return {configurable:true,enumerable:true,writable:false}}})}function b(r){async function e(o,s){return await r.callTool(o,s)}let t=V(e);return {callTool:e,tools:t,async sendMessage(o){await r.sendMessage(o);},async sendFollowUpMessage(o){await r.sendMessage({type:"text",text:o});},async openLink(o){await r.openLink(o);},async requestDisplayMode(o){return r.requestDisplayMode(o)},requestClose(){r.requestClose();},getState(){return r.getState()},setState(o){r.setState(o);},...r.uploadFile&&{uploadFile:r.uploadFile.bind(r)},...r.getFileDownloadUrl&&{getFileDownloadUrl:r.getFileDownloadUrl.bind(r)},async readResource(o){return r.readResource(o)},log(o,s){r.log(o,s);},onToolResult(o){return r.onToolResult(o)},onToolInput(o){return r.onToolInput(o)},onToolCancelled(o){return r.onToolCancelled(o)},onHostContextChange(o){return r.onHostContextChange(o)},onTeardown(o){return r.onTeardown(o)},onToolInputPartial(o){return r.onToolInputPartial(o)},getHostCapabilities(){return r.getHostCapabilities()},getHostVersion(){return r.getHostVersion()},async sendLog(o,s){return r.sendLog(o,s)},async sendSizeChanged(o){return r.sendSizeChanged(o)},setupSizeChangedNotifications(){if(typeof window>"u"||typeof ResizeObserver>"u")return ()=>{};let o=new ResizeObserver(s=>{for(let a of s){let{width:l,height:p}=a.contentRect;r.sendSizeChanged({width:Math.round(l),height:Math.round(p)});}});return o.observe(document.body),()=>{o.disconnect();}},setCallToolHandler(o){r.setCallToolHandler(o);},setListToolsHandler(o){r.setListToolsHandler(o);},get hostContext(){return r.getHostContext()},get toolInput(){return r.getToolInput()},get toolOutput(){return r.getToolOutput()},get toolMeta(){return r.getToolMeta()}}}function $(r,e){switch(r){case "mcp":return new m(e?.mcp);case "openai":return new w;case "mock":return new h;default:throw new Error(`Unknown adapter type: ${r}`)}}async function ge(r){let e=r?.forceAdapter??C();if(!["mcp","openai","mock"].includes(e))throw new Error(`Unknown adapter type: ${e}`);let t=r?.autoResize!==void 0?{mcp:{autoResize:r.autoResize}}:void 0,n=$(e,t);return await n.connect(),i.setAdapter(n),b(n)}exports.ClientDebugLogger=y;exports.LATEST_PROTOCOL_VERSION=D;exports.McpAdapter=m;exports.MockAdapter=h;exports.OpenAIAdapter=w;exports.RESOURCE_MIME_TYPE=_;exports.RESOURCE_URI_META_KEY=F;exports.UIError=d;exports.UIErrorCode=g;exports.applyDocumentTheme=x;exports.applyHostFonts=O;exports.applyHostStyleVariables=k;exports.clearHostStyleVariables=R;exports.clientDebugLogger=i;exports.createAppsClient=b;exports.createClient=ge;exports.detectProtocol=C;exports.getDocumentTheme=H;exports.getMcpServerBaseUrl=N;exports.getMcpServerConfig=L;exports.removeHostFonts=A;exports.safeSerialize=E;exports.safeStringify=P;exports.shouldLog=S;//# sourceMappingURL=index.cjs.map | ||
| 'use strict';var extApps=require('@modelcontextprotocol/ext-apps');var _="2025-11-05",F="text/html;profile=mcp-app",N="ui/resourceUri";function H(r){if(typeof document>"u")return;let e=r==="os"?typeof window<"u"&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":r;document.documentElement.classList.remove("light","dark"),document.documentElement.classList.add(e),document.documentElement.setAttribute("data-theme",e);}function k(){if(typeof document>"u")return "light";let r=document.documentElement.getAttribute("data-theme");return r==="dark"||r==="light"?r:document.documentElement.classList.contains("dark")?"dark":"light"}var T="mcp-apps-host-fonts";function A(r){if(typeof document>"u")return;let e=document.documentElement;for(let[t,o]of Object.entries(r)){let n=t.startsWith("--")?t:`--${t}`;e.style.setProperty(n,o);}}function O(r){if(typeof document>"u")return;let e=document.getElementById(T);e||(e=document.createElement("style"),e.id=T,document.head.appendChild(e)),e.textContent=r;}function R(){if(typeof document>"u")return;let r=document.getElementById(T);r&&r.remove();}function I(r){if(typeof document>"u")return;let e=document.documentElement;for(let t of Object.keys(r)){let o=t.startsWith("--")?t:`--${t}`;e.style.removeProperty(o);}}var p={CONNECTION_FAILED:"CONNECTION_FAILED",CONNECTION_TIMEOUT:"CONNECTION_TIMEOUT",NOT_CONNECTED:"NOT_CONNECTED",PROTOCOL_ERROR:"PROTOCOL_ERROR",UNSUPPORTED_OPERATION:"UNSUPPORTED_OPERATION",INVALID_PARAMS:"INVALID_PARAMS",TOOL_CALL_FAILED:"TOOL_CALL_FAILED",TOOL_NOT_FOUND:"TOOL_NOT_FOUND",STATE_ERROR:"STATE_ERROR",UNKNOWN_ERROR:"UNKNOWN_ERROR"},d=class extends Error{constructor(t,o,n,s){super(o);this.code=t;this.details=n;this.cause=s;this.name="UIError";}formatMessage(){let t=`[${this.code}] ${this.message}`;return this.details&&(t+=` ${JSON.stringify(this.details)}`),t}};var M={debug:0,info:1,warn:2,error:3};function S(r,e){return M[r]>=M[e]}function P(){let r=new WeakSet;return (e,t)=>{if(typeof t=="object"&&t!==null){if(r.has(t))return "[Circular]";r.add(t);}return t}}function E(r){if(r==null||typeof r=="string"||typeof r=="number"||typeof r=="boolean")return r;if(r instanceof Error)return {name:r.name,message:r.message,stack:r.stack};try{return JSON.stringify(r),r}catch{try{let e=JSON.stringify(r,P());return JSON.parse(e)}catch{return "[Unserializable]"}}}function D(r){if(r===void 0)return "undefined";if(r===null)return "null";if(typeof r=="string")return r;if(r instanceof Error)return `${r.name}: ${r.message}`;try{return JSON.stringify(r,P())}catch{return "[Unstringifiable]"}}var y=class{constructor(e={}){this.adapter=null;this.buffer=[];this.flushTimer=null;this.isFlushing=false;this.mcpTransportFailed=false;this.apiTransportFailed=false;this.config={enabled:e.enabled??false,level:e.level??"info",batchSize:e.batchSize??10,maxBufferSize:e.maxBufferSize??100,flushIntervalMs:e.flushIntervalMs??5e3,source:e.source??"mcp-apps-ui",transport:e.transport??"tool",apiEndpoint:e.apiEndpoint};}setAdapter(e){this.adapter=e,this.mcpTransportFailed=false,this.apiTransportFailed=false;}configure(e){e.enabled!==void 0&&(this.config.enabled=e.enabled),e.level!==void 0&&(this.config.level=e.level),e.batchSize!==void 0&&(this.config.batchSize=e.batchSize),e.maxBufferSize!==void 0&&(this.config.maxBufferSize=e.maxBufferSize),e.flushIntervalMs!==void 0&&(this.config.flushIntervalMs=e.flushIntervalMs,this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),this.scheduleFlush()),e.source!==void 0&&(this.config.source=e.source),e.transport!==void 0&&(this.config.transport=e.transport,this.mcpTransportFailed=false,this.apiTransportFailed=false),e.apiEndpoint!==void 0&&(this.config.apiEndpoint=e.apiEndpoint,this.apiTransportFailed=false);}canUseToolTransport(){return this.config.enabled&&this.config.transport==="tool"&&!this.mcpTransportFailed&&this.adapter?.isConnected()===true}canUseApiTransport(){return this.config.enabled&&this.config.transport==="api"&&!this.apiTransportFailed&&!!this.config.apiEndpoint}canUseRemoteTransport(){return this.canUseToolTransport()||this.canUseApiTransport()}createEntry(e,t,o){return {level:e,message:t,data:o!==void 0?E(o):void 0,timestamp:new Date().toISOString(),source:this.config.source}}scheduleFlush(){this.flushTimer||this.buffer.length===0||(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}async flushToApi(e){if(!this.config.apiEndpoint)throw new Error("API endpoint not configured");let t=await fetch(this.config.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:e})});if(!t.ok)throw new Error(`API request failed with status ${String(t.status)}`)}async flushToTool(e){if(!this.adapter)throw new Error("Adapter not connected");await this.adapter.callTool("log_debug",{entries:e});}async flush(){if(this.isFlushing||this.buffer.length===0)return;if(this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),!this.canUseRemoteTransport()){this.buffer=[];return}this.isFlushing=true;let e=[...this.buffer];try{this.canUseApiTransport()?await this.flushToApi(e):this.canUseToolTransport()&&await this.flushToTool(e),this.buffer=this.buffer.slice(e.length);}catch(t){this.buffer=this.buffer.slice(e.length);let o=t instanceof Error?t.message:String(t);this.config.transport==="api"&&!this.apiTransportFailed?(this.apiTransportFailed=true,console.warn(`[ClientDebugLogger] API log transport failed: ${o}. Will only use console`)):this.config.transport==="tool"&&!this.mcpTransportFailed&&(this.mcpTransportFailed=true,console.warn(`[ClientDebugLogger] MCP log transport failed: ${o}. Will only use console`));}finally{this.isFlushing=false,this.buffer.length>0&&this.scheduleFlush();}}outputToConsole(e){let t=`[${e.timestamp}] [${e.level.toUpperCase()}]`,o=e.data!==void 0?`${e.message} ${D(e.data)}`:e.message,n=`${t} ${o}`;try{switch(e.level){case "debug":console.debug(n);break;case "info":console.info(n);break;case "warn":console.warn(n);break;case "error":console.error(n);break}}catch{}}addToBuffer(e){for(;this.buffer.length>=this.config.maxBufferSize;)this.buffer.shift();if(this.buffer.push(e),e.level==="error"){this.flush();return}if(this.buffer.length>=this.config.batchSize){this.flush();return}this.scheduleFlush();}log(e,t,o){if(!S(e,this.config.level))return;let n=this.createEntry(e,t,o);this.outputToConsole(n),this.canUseRemoteTransport()&&this.addToBuffer(n);}debug(e,t){this.log("debug",e,t);}info(e,t){this.log("info",e,t);}warn(e,t){this.log("warn",e,t);}error(e,t){this.log("error",e,t);}destroy(){this.buffer=[],this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),this.adapter=null;}},i=new y;function L(){return typeof window<"u"&&window.__MCP_SERVER_CONFIG__?window.__MCP_SERVER_CONFIG__:typeof __MCP_SERVER_CONFIG__<"u"&&__MCP_SERVER_CONFIG__?__MCP_SERVER_CONFIG__:{}}function U(r=""){let e=L();return e.baseUrl?e.baseUrl:typeof window<"u"&&(window.location.protocol==="http:"||window.location.protocol==="https:")?window.location.origin:r}var h=class{constructor(){this.connected=false;this.state=null;this.toolResultHandlers=new Set;this.toolInputHandlers=new Set;this.toolInputPartialHandlers=new Set;this.toolCancelledHandlers=new Set;this.hostContextHandlers=new Set;this.teardownHandlers=new Set;this.mockHostCapabilities={logging:{},openLinks:{},theming:{themes:["light","dark","os"]},displayModes:{modes:["inline","fullscreen","pip","panel"]},statePersistence:{persistent:true},serverTools:{listChanged:false},serverResources:{listChanged:false},sizeNotifications:{},partialToolInput:{},appTools:{listChanged:false},fileUpload:{},safeAreaInsets:{},views:{}};this.mockHostVersion={name:"MockHost",version:"1.0.0"};this.context=this.createDefaultContext();}createDefaultContext(){let e=typeof window<"u";return {theme:"light",displayMode:"inline",availableDisplayModes:["inline","fullscreen","pip"],viewport:{width:e?window.innerWidth:800,height:e?window.innerHeight:600},locale:e?navigator.language:"en-US",timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,platform:"web",deviceCapabilities:{touch:e?"ontouchstart"in window:false,hover:true}}}async connect(){this.connected=true,console.log("[MockAdapter] Connected");}isConnected(){return this.connected}async callTool(e,t){console.log(`[MockAdapter] callTool("${e}",`,t,")");let o={_mock:true,tool:e,args:t,timestamp:Date.now()};return this.currentToolOutput=o,o}async sendMessage(e){console.log("[MockAdapter] sendMessage:",e);}async updateModelContext(e){this.lastModelContext=e,console.log("[MockAdapter] updateModelContext:",e);}getLastModelContext(){return this.lastModelContext}async openLink(e){console.log(`[MockAdapter] openLink("${e}")`);}async requestDisplayMode(e){return console.log(`[MockAdapter] requestDisplayMode("${e}")`),this.context={...this.context,displayMode:e},this.notifyHostContextChange(),{mode:e}}requestClose(){console.log("[MockAdapter] requestClose()");}getState(){return this.state}setState(e){this.state=e,console.log("[MockAdapter] setState:",e);}async readResource(e){return console.log(`[MockAdapter] readResource("${e}")`),{contents:[]}}log(e,t){({debug:console.debug,info:console.info,warning:console.warn,error:console.error}[e]??console.log)("[MockAdapter]",t);}onToolResult(e){return this.toolResultHandlers.add(e),()=>this.toolResultHandlers.delete(e)}onToolInput(e){return this.toolInputHandlers.add(e),()=>this.toolInputHandlers.delete(e)}onToolCancelled(e){return this.toolCancelledHandlers.add(e),()=>this.toolCancelledHandlers.delete(e)}onHostContextChange(e){return this.hostContextHandlers.add(e),()=>this.hostContextHandlers.delete(e)}onTeardown(e){return this.teardownHandlers.add(e),()=>this.teardownHandlers.delete(e)}getHostContext(){return this.context}getToolInput(){return this.currentToolInput}getToolOutput(){return this.currentToolOutput}getToolMeta(){return this.currentToolMeta}emitToolResult(e){this.currentToolOutput=e;for(let t of this.toolResultHandlers)t(e);}emitToolInput(e){this.currentToolInput=e;for(let t of this.toolInputHandlers)t(e);}setHostContext(e){this.context={...this.context,...e},this.notifyHostContextChange();}emitContextChange(e){this.context=e,this.notifyHostContextChange();}setToolInput(e){this.currentToolInput=e;}emitToolCancelled(e){for(let t of this.toolCancelledHandlers)t(e);}emitTeardown(e){for(let t of this.teardownHandlers)t(e);}notifyHostContextChange(){for(let e of this.hostContextHandlers)e(this.context);}getHostCapabilities(){return this.mockHostCapabilities}getHostVersion(){return this.mockHostVersion}async sendLog(e,t){console.log(`[MockAdapter] sendLog(${e}):`,t);}async sendLogs(e){for(let t of e)console.log(`[MockAdapter] sendLogs(${t.level}):`,t.message,t.data);return {processed:e.length}}async sendSizeChanged(e){console.log("[MockAdapter] sendSizeChanged:",e);}onToolInputPartial(e){return this.toolInputPartialHandlers.add(e),()=>this.toolInputPartialHandlers.delete(e)}setCallToolHandler(e){this.callToolHandler=e,console.log("[MockAdapter] setCallToolHandler: handler registered");}setListToolsHandler(e){this.listToolsHandler=e,console.log("[MockAdapter] setListToolsHandler: handler registered");}emitToolInputPartial(e){for(let t of this.toolInputPartialHandlers)t(e);}setMockHostCapabilities(e){this.mockHostCapabilities={...this.mockHostCapabilities,...e};}setMockHostVersion(e){this.mockHostVersion=e;}async simulateHostToolCall(e,t){if(!this.callToolHandler)throw new d(p.TOOL_NOT_FOUND,"No call tool handler registered");return this.callToolHandler(e,t)}async simulateHostListTools(){return this.listToolsHandler?this.listToolsHandler():{tools:[]}}};var V={parse:r=>r},m=class{constructor(e){this.connected=false;this.toolResultHandlers=new Set;this.toolInputHandlers=new Set;this.toolInputPartialHandlers=new Set;this.toolCancelledHandlers=new Set;this.hostContextHandlers=new Set;this.teardownHandlers=new Set;this.context=this.createDefaultContext(),this.autoResize=e?.autoResize??true;}createDefaultContext(){let e=typeof window<"u";return {theme:"light",displayMode:"inline",availableDisplayModes:["inline","fullscreen"],viewport:{width:e?window.innerWidth:800,height:e?window.innerHeight:600},locale:e?navigator.language:"en-US",timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,platform:"desktop"}}async connect(){if(this.connected)return;if(typeof window>"u"){this.connected=true;return}this.app=new extApps.App({name:"@mcp-apps-kit/ui",version:"0.0.0"},{tools:{}},{autoResize:this.autoResize}),this.app.onerror=t=>{this.log("error",t);},this.app.onhostcontextchanged=t=>{let o=t.hostContext??t;this.context=this.mapHostContext(o),this.currentToolMeta=this.extractToolMeta(o);for(let n of this.hostContextHandlers)n(this.context);},this.app.ontoolinput=t=>{let o=t.arguments;if(o){this.currentToolInput=o;for(let n of this.toolInputHandlers)n(o);}},this.app.ontoolinputpartial=t=>{let o=t.arguments;if(o)for(let n of this.toolInputPartialHandlers)n(o);},this.app.oncalltool=async t=>{let{name:o,arguments:n}=t;try{if(this.callToolHandler){let s=await this.callToolHandler(o,n??{});return {content:[{type:"text",text:JSON.stringify(s)}]}}return {content:[{type:"text",text:`No handler registered for tool: ${o}`}],isError:!0}}catch(s){return {content:[{type:"text",text:s instanceof Error?s.message:String(s)}],isError:true}}},this.app.onlisttools=async()=>this.listToolsHandler?{tools:(await this.listToolsHandler()).map(o=>o.name)}:{tools:[]},this.app.ontoolresult=t=>{let o=this.extractToolOutput(t);this.currentToolOutput=o;let n=this.getToolNameFromContext(),s=n?{[n]:o}:o;for(let a of this.toolResultHandlers)a(s);},this.app.ontoolcancelled=t=>{let o=t.reason;for(let n of this.toolCancelledHandlers)n(o);},this.app.onteardown=async t=>{let o=t.reason;for(let n of this.teardownHandlers)n(o);return {}},await this.app.connect();let e=this.app.getHostContext();e&&(this.context=this.mapHostContext(e),this.currentToolMeta=this.extractToolMeta(e)),this.connected=true;}isConnected(){return this.connected}mapHostContext(e){let t=e??{},o=this.createDefaultContext(),n=o.theme;(t.theme==="dark"||t.theme==="light")&&(n=t.theme);let s=t.displayMode==="fullscreen"||t.displayMode==="pip"||t.displayMode==="inline"?t.displayMode:o.displayMode,a=Array.isArray(t.availableDisplayModes)?t.availableDisplayModes.filter(f=>typeof f=="string"):o.availableDisplayModes,l=f=>f!==null&&typeof f=="object"&&!Array.isArray(f),c=l(t.containerDimensions)?t.containerDimensions:void 0,u=o.viewport;c?u=this.deriveViewportFromContainerDimensions(c,o.viewport):l(t.viewport)&&(u={...o.viewport,...t.viewport});let g=typeof t.locale=="string"?t.locale:o.locale,v=typeof t.timeZone=="string"?t.timeZone:o.timeZone,C=o.platform;return {...o,theme:n,displayMode:s,availableDisplayModes:a,viewport:u,containerDimensions:c,locale:g,timeZone:v,platform:C,userAgent:typeof t.userAgent=="string"?t.userAgent:o.userAgent,deviceCapabilities:t.deviceCapabilities,safeAreaInsets:t.safeAreaInsets,styles:t.styles,view:typeof t.view=="string"?t.view:o.view}}deriveViewportFromContainerDimensions(e,t){let o=e;return {width:typeof o.width=="number"?o.width:t.width,height:typeof o.height=="number"?o.height:t.height,maxWidth:typeof o.maxWidth=="number"?o.maxWidth:void 0,maxHeight:typeof o.maxHeight=="number"?o.maxHeight:void 0}}extractToolMeta(e){if(e===null||typeof e!="object")return;let t=e;if(!(!t.toolInfo||typeof t.toolInfo!="object"))return {toolInfo:t.toolInfo}}getToolNameFromContext(){if(!this.app)return;let e=this.app.getHostContext();return e?e.toolInfo?.tool?.name:void 0}extractToolOutput(e){let t=e.structuredContent,o=e._meta,n=t&&typeof t=="object"&&!Array.isArray(t)?t:{};if(o&&typeof o=="object"&&!Array.isArray(o))return {...n,_meta:o};if(Object.keys(n).length===0){let s=e.content;if(Array.isArray(s)&&s.length>0){let a=s[0];if(a?.type==="text"&&typeof a.text=="string")try{let l=JSON.parse(a.text);if(l!==null&&typeof l=="object"&&!Array.isArray(l))return l}catch{}}}return n}async callTool(e,t){if(!this.app)throw new Error("MCP Apps adapter not connected");let o=await this.app.callServerTool({name:e,arguments:t});return this.extractToolOutput(o)}async sendMessage(e){if(!this.app)throw new Error("MCP Apps adapter not connected");if(e.type!=="text")throw new Error(`Unsupported message content type: ${e.type}`);await this.app.sendMessage({role:"user",content:[{type:"text",text:e.text}]});}async updateModelContext(e){if(!this.app)throw new d(p.NOT_CONNECTED,"MCP Apps adapter not connected");let t=e.content?.map(o=>{switch(o.type){case "text":if(!o.text)throw new d(p.INVALID_PARAMS,"Text content block requires 'text' field");return {type:"text",text:o.text};case "image":if(!o.data)throw new d(p.INVALID_PARAMS,"Image content block requires 'data' field");return {type:"image",data:o.data,mimeType:o.mimeType??"image/png"};case "audio":if(!o.data)throw new d(p.INVALID_PARAMS,"Audio content block requires 'data' field");return {type:"audio",data:o.data,mimeType:o.mimeType??"audio/wav"};case "resource":if(!o.uri)throw new d(p.INVALID_PARAMS,"Resource content block requires 'uri' field");return {type:"resource",resource:{uri:o.uri,text:o.description??o.uri}};case "resource_link":{if(!o.uri)throw new d(p.INVALID_PARAMS,"Resource link content block requires 'uri' field");return {type:"resource_link",uri:o.uri,name:o.name??o.uri,...o.description&&{description:o.description}}}default:{let n=o;throw new d(p.PROTOCOL_ERROR,`Unsupported content block type: ${n.type}`)}}});await this.app.updateModelContext({content:t,structuredContent:e.structuredContent});}async openLink(e){if(!this.app)throw new Error("MCP Apps adapter not connected");await this.app.openLink({url:e});}async requestDisplayMode(e){if(!this.app)throw new Error("MCP Apps adapter not connected");return await this.app.requestDisplayMode({mode:e})}requestClose(){}getState(){return null}setState(e){}async readResource(e){if(!this.app)throw new Error("MCP Apps adapter not connected");let o=await this.app.request.bind(this.app)({method:"resources/read",params:{uri:e}},V);return {contents:(Array.isArray(o.contents)?o.contents:[]).map(n=>{let s={uri:n.uri,mimeType:n.mimeType??"application/octet-stream"};if("text"in n&&typeof n.text=="string")return {...s,text:n.text};if("blob"in n&&typeof n.blob=="string"){let a=Uint8Array.from(atob(n.blob),l=>l.charCodeAt(0));return {...s,blob:a}}return s})}}log(e,t){if(this.app){let s={level:["debug","info","notice","warning","error","critical","alert","emergency"].includes(e)?e:"info",data:t,logger:"@mcp-apps-kit/ui"};try{this.app.sendLog(s);return}catch{}}({debug:console.debug,info:console.info,warning:console.warn,error:console.error}[e]??console.log)("[MCP Apps]",t);}onToolResult(e){return this.toolResultHandlers.add(e),()=>this.toolResultHandlers.delete(e)}onToolInput(e){return this.toolInputHandlers.add(e),()=>this.toolInputHandlers.delete(e)}onToolCancelled(e){return this.toolCancelledHandlers.add(e),()=>this.toolCancelledHandlers.delete(e)}onHostContextChange(e){return this.hostContextHandlers.add(e),()=>this.hostContextHandlers.delete(e)}onTeardown(e){return this.teardownHandlers.add(e),()=>this.teardownHandlers.delete(e)}getHostContext(){return this.context}getToolInput(){return this.currentToolInput}getToolOutput(){return this.currentToolOutput}getToolMeta(){return this.currentToolMeta}getHostCapabilities(){if(!this.app)return;let e=this.app.getHostCapabilities();if(!e)return;let t=e,n=this.app.getHostContext()?.availableDisplayModes;return {logging:t.logging,openLinks:t.openLinks,serverResources:t.serverResources,serverTools:t.serverTools,experimental:t.experimental,theming:{themes:["light","dark"]},displayModes:n?{modes:n}:void 0,statePersistence:{persistent:false},sizeNotifications:{},partialToolInput:{},appTools:{listChanged:false},updateModelContext:t.updateModelContext,message:t.message,sandbox:t.sandbox}}getHostVersion(){if(!this.app)return;let e=this.app.getHostVersion();if(e)return {name:e.name,version:e.version}}async sendLog(e,t){if(!this.app)throw new d(p.NOT_CONNECTED,"MCP Apps adapter not connected");await this.app.sendLog({level:e,data:t,logger:"@mcp-apps-kit/ui"});}async sendLogs(e){if(!this.app)throw new d(p.NOT_CONNECTED,"MCP Apps adapter not connected");let t={debug:"debug",info:"info",warn:"warning",error:"error"},o=0;for(let n of e)try{await this.app.sendLog({level:t[n.level]??"info",data:n.data??n.message,logger:n.source??"@mcp-apps-kit/ui"}),o++;}catch{}return {processed:o}}async sendSizeChanged(e){if(!this.app)throw new d(p.NOT_CONNECTED,"MCP Apps adapter not connected");await this.app.sendSizeChanged({width:e.width,height:e.height});}onToolInputPartial(e){return this.toolInputPartialHandlers.add(e),()=>this.toolInputPartialHandlers.delete(e)}setCallToolHandler(e){this.callToolHandler=e;}setListToolsHandler(e){this.listToolsHandler=e;}};var w=class{constructor(){this.connected=false;this.state=null;this.toolResultHandlers=new Set;this.toolInputHandlers=new Set;this.toolCancelledHandlers=new Set;this.hostContextHandlers=new Set;this.teardownHandlers=new Set;this.logTransport="api";this.apiTransportFailed=false;this.toolTransportFailed=false;this.context=this.createDefaultContext();}configureLogging(e){e.transport!==void 0&&(this.logTransport=e.transport,this.apiTransportFailed=false,this.toolTransportFailed=false),e.apiEndpoint!==void 0&&(this.logApiEndpoint=e.apiEndpoint,this.apiTransportFailed=false);}createDefaultContext(){let e=typeof window<"u";return {theme:"light",displayMode:"inline",availableDisplayModes:["inline","fullscreen","pip"],viewport:{width:e?window.innerWidth:800,height:e?window.innerHeight:600},locale:e?navigator.language:"en-US",timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,platform:"web",deviceCapabilities:{touch:e?"ontouchstart"in window:false,hover:true}}}isSetGlobalsMessage(e){return e==="openai:set_globals"||typeof e=="object"&&e!==null&&"type"in e&&e.type==="openai:set_globals"||typeof e=="object"&&e!==null&&"message"in e&&e.message==="openai:set_globals"}readContextFromSDK(){let e=this.getOpenAI();if(!e)return;let t=typeof window<"u";if(typeof e.theme=="string"&&(this.context.theme=e.theme),typeof e.displayMode=="string"&&(this.context.displayMode=e.displayMode),typeof e.locale=="string"&&(this.context.locale=e.locale),typeof e.userAgent=="string"&&Object.assign(this.context,{userAgent:e.userAgent}),typeof e.view=="string"&&(this.context.view=e.view),e.safeArea&&typeof e.safeArea=="object"){let o=e.safeArea;this.context.safeAreaInsets={top:typeof o.top=="number"?o.top:0,right:typeof o.right=="number"?o.right:0,bottom:typeof o.bottom=="number"?o.bottom:0,left:typeof o.left=="number"?o.left:0};}typeof e.maxHeight=="number"&&(this.context.viewport={width:t?window.innerWidth:800,height:e.maxHeight}),i.debug("[OpenAI Adapter] Read context from SDK",this.context);}notifyContextChange(){i.debug(`[OpenAI Adapter] Notifying ${String(this.hostContextHandlers.size)} context change handlers`);let e={...this.context};for(let t of this.hostContextHandlers)t(e);}getOpenAI(){return typeof window<"u"&&"openai"in window?window.openai:null}getToolNameFromSDK(){let e=this.getOpenAI();if(e){if(e.toolResponseMetadata&&typeof e.toolResponseMetadata=="object"){let t=e.toolResponseMetadata;if(typeof t.toolName=="string")return t.toolName}if(typeof e.toolName=="string")return e.toolName}}async connect(){await this.waitForOpenAI();let e=this.getOpenAI();if(e){i.debug("[OpenAI Adapter] Available SDK methods",Object.keys(e)),this.readContextFromSDK();let t=this.getToolNameFromSDK();if(typeof e.getToolOutput=="function"?(this.currentToolOutput=e.getToolOutput(),i.debug("[OpenAI Adapter] Got tool output from SDK")):e.toolOutput?(this.currentToolOutput=e.toolOutput,i.debug("[OpenAI Adapter] Got tool output from SDK property")):e.result&&(this.currentToolOutput=e.result,i.debug("[OpenAI Adapter] Got result from SDK")),this.currentToolOutput&&Object.keys(this.currentToolOutput).length>0){let o=t?{[t]:this.currentToolOutput}:this.currentToolOutput;for(let n of this.toolResultHandlers)n(o);}typeof e.getToolInput=="function"?this.currentToolInput=e.getToolInput():e.toolInput?this.currentToolInput=e.toolInput:e.input&&(this.currentToolInput=e.input),typeof e.init=="function"&&await e.init();}this.setupGlobalsListener(),this.connected=true;}setupGlobalsListener(){typeof window>"u"||(this.setGlobalsHandler=e=>{let o=e.detail;if(!o){this.readContextFromSDK(),this.checkForToolOutputUpdate();return}let n=o.globals??o,s=this.context.theme,a=this.context.locale,l=this.context.displayMode,c=this.currentToolOutput;if(n.theme!==void 0&&(this.context.theme=n.theme),n.locale!==void 0&&(this.context.locale=n.locale),n.displayMode!==void 0&&(this.context.displayMode=n.displayMode),(this.context.theme!==s||this.context.locale!==a||this.context.displayMode!==l)&&(i.debug("[OpenAI Adapter] Context changed, notifying handlers"),this.notifyContextChange()),n.toolOutput!==void 0&&n.toolOutput!==null){let u=n.toolOutput;if(Object.keys(u).length>0&&u!==c){i.debug("[OpenAI Adapter] Got toolOutput from set_globals event",u),this.currentToolOutput=u;let g;n.toolResponseMetadata&&typeof n.toolResponseMetadata=="object"&&n.toolResponseMetadata.toolName?g=n.toolResponseMetadata.toolName:g=this.getToolNameFromSDK();let v=g?{[g]:u}:u;for(let C of this.toolResultHandlers)C(v);}}n.toolInput!==void 0&&(this.currentToolInput=n.toolInput);},window.addEventListener("openai:set_globals",this.setGlobalsHandler),this.globalsHandler=e=>{this.isSetGlobalsMessage(e.data)&&(i.debug("[OpenAI Adapter] Received set_globals via postMessage (legacy)"),this.readContextFromSDK(),this.checkForToolOutputUpdate());},window.addEventListener("message",this.globalsHandler));}checkForToolOutputUpdate(){let e=this.getOpenAI();if(!e)return;let t;if(e.toolOutput&&(t=e.toolOutput),t&&Object.keys(t).length>0&&t!==this.currentToolOutput){i.debug("[OpenAI Adapter] toolOutput updated",t),this.currentToolOutput=t;let o=this.getToolNameFromSDK(),n=o?{[o]:t}:t;for(let s of this.toolResultHandlers)s(n);}}async waitForOpenAI(e=5e3){if(this.getOpenAI()){i.debug("[OpenAI Adapter] window.openai already available");return}return i.debug("[OpenAI Adapter] Waiting for window.openai..."),new Promise(t=>{let o=Date.now(),n=false,s=()=>{n||(n=true,window.removeEventListener("message",l),t());},a=()=>{if(!n){if(this.getOpenAI()){i.debug("[OpenAI Adapter] window.openai found via polling"),s();return}if(Date.now()-o>e){i.warn("[OpenAI Adapter] window.openai not found after timeout, proceeding anyway"),s();return}setTimeout(a,50);}},l=c=>{this.isSetGlobalsMessage(c.data)&&(i.debug("[OpenAI Adapter] Received set_globals message"),setTimeout(()=>{this.getOpenAI()?(i.debug("[OpenAI Adapter] window.openai available after set_globals"),s()):i.debug("[OpenAI Adapter] window.openai still not available after set_globals, continuing poll");},50));};window.addEventListener("message",l),a();})}isConnected(){return this.connected}async callTool(e,t){let o=this.getOpenAI();if(o&&typeof o.callTool=="function")return o.callTool(e,t);throw new Error("OpenAI SDK not available")}async sendMessage(e){if(e.type!=="text")throw new Error(`Unsupported message content type: ${e.type}`);let t=this.getOpenAI();t&&typeof t.sendFollowUpMessage=="function"&&await t.sendFollowUpMessage({prompt:e.text});}async updateModelContext(e){let t={__mcp_type:"modelContext"};if(e.structuredContent){let o=e.structuredContent,n=Object.keys(o).filter(s=>s.startsWith("_"));n.length>0&&i.debug("[OpenAI Adapter] Filtering reserved keys (underscore-prefixed) from structuredContent:",n),Object.keys(o).forEach(s=>{s.startsWith("_")||(t[s]=o[s]);});}if(e.content&&e.content.length>0){let o=e.content.filter(a=>a.type==="text"),n=e.content.filter(a=>a.type!=="text");n.length>0&&i.debug(`[OpenAI Adapter] Dropping ${String(n.length)} non-text content block(s):`,n.map(a=>a.type));let s=o.map(a=>a.text).join(` | ||
| `);s&&(t.__mcp_textContent=s);}this.setState(t),i.debug("[OpenAI Adapter] updateModelContext via setState:",t);}async openLink(e){let t=this.getOpenAI();t&&typeof t.openExternal=="function"?await t.openExternal({href:e}):window.open(e,"_blank");}async requestDisplayMode(e){let t=this.getOpenAI();if(t&&typeof t.requestDisplayMode=="function"){let o=await t.requestDisplayMode({mode:e});return this.context={...this.context,displayMode:o.mode},this.notifyContextChange(),o}return this.context={...this.context,displayMode:e},this.notifyContextChange(),{mode:e}}requestClose(){let e=this.getOpenAI();e&&typeof e.close=="function"&&e.close();}getState(){return this.state}setState(e){this.state=e;let t=this.getOpenAI();t&&typeof t.setWidgetState=="function"&&t.setWidgetState(e);}async uploadFile(e){let t=this.getOpenAI();if(t&&typeof t.uploadFile=="function")return t.uploadFile(e);throw new Error("File upload not supported")}async getFileDownloadUrl(e){let t=this.getOpenAI();if(t&&typeof t.getFileDownloadUrl=="function")return t.getFileDownloadUrl(e);throw new Error("File download not supported")}async readResource(e){let t=this.getOpenAI();return t&&typeof t.readResource=="function"?t.readResource(e):{contents:[]}}log(e,t){({debug:console.debug,info:console.info,warning:console.warn,error:console.error}[e]??console.log)("[ChatGPT Apps]",t);}onToolResult(e){return this.toolResultHandlers.add(e),()=>this.toolResultHandlers.delete(e)}onToolInput(e){return this.toolInputHandlers.add(e),()=>this.toolInputHandlers.delete(e)}onToolCancelled(e){return this.toolCancelledHandlers.add(e),()=>this.toolCancelledHandlers.delete(e)}onHostContextChange(e){return this.hostContextHandlers.add(e),i.debug(`[OpenAI Adapter] Host context handler added, total: ${String(this.hostContextHandlers.size)}`),()=>{this.hostContextHandlers.delete(e),i.debug(`[OpenAI Adapter] Host context handler removed, total: ${String(this.hostContextHandlers.size)}`);}}onTeardown(e){return this.teardownHandlers.add(e),()=>this.teardownHandlers.delete(e)}getHostContext(){return this.context}getToolInput(){return this.currentToolInput}getToolOutput(){if(!this.currentToolOutput)return;let e=this.getToolNameFromSDK();return e?{[e]:this.currentToolOutput}:this.currentToolOutput}getToolMeta(){return this.currentToolMeta}getHostCapabilities(){let e=this.getOpenAI(),t=e&&typeof e.uploadFile=="function",o=this.context.safeAreaInsets!==void 0,n=this.context.view!==void 0;return {openLinks:{},logging:{},theming:{themes:["light","dark"]},displayModes:{modes:["inline","fullscreen","pip"]},statePersistence:{persistent:false},fileUpload:t?{}:void 0,safeAreaInsets:o?{}:void 0,views:n?{}:void 0}}getHostVersion(){}async sendLog(e,t){let n={level:{debug:"debug",info:"info",notice:"info",warning:"warn",error:"error",critical:"error",alert:"error",emergency:"error"}[e],message:typeof t=="string"?t:JSON.stringify(t),data:typeof t=="string"?void 0:t,timestamp:new Date().toISOString(),source:"openai-adapter"};await this.sendLogs([n]);}async sendLogs(e){if(this.logTransport==="api"&&this.logApiEndpoint&&!this.apiTransportFailed)try{let t=await fetch(this.logApiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:e})});if(!t.ok)throw new Error(`API request failed with status ${String(t.status)}`);return await t.json()}catch(t){this.apiTransportFailed=true,i.info("[OpenAI Adapter] API log transport failed, trying fallback",{error:t instanceof Error?t.message:t});}if((this.logTransport==="tool"||this.apiTransportFailed)&&!this.toolTransportFailed&&this.connected)try{return await this.callTool("log_debug",{entries:e})}catch(t){this.toolTransportFailed=true,i.info("[OpenAI Adapter] Tool log transport failed, falling back to console",{error:t instanceof Error?t.message:t});}for(let t of e)this.log(t.level==="warn"?"warning":t.level,t.data??t.message);return {processed:e.length}}async sendSizeChanged(e){let t=this.getOpenAI();t&&typeof t.notifyIntrinsicHeight=="function"&&t.notifyIntrinsicHeight(e.height);}onToolInputPartial(e){return this.log("debug","onToolInputPartial is not supported on ChatGPT"),()=>{}}setCallToolHandler(e){this.log("debug","setCallToolHandler is not supported on ChatGPT");}setListToolsHandler(e){this.log("debug","setListToolsHandler is not supported on ChatGPT");}};function x(){if(typeof window>"u")return "mock";if("openai"in window)return "openai";let r=window.location.href,e=document.referrer;return r.includes("/api/apps/chatgpt/")||r.includes("chatgpt")||r.includes("sandbox-proxy")||r.includes("widget-content")||e.includes("chatgpt")||e.includes("openai.com")?"openai":window.parent!==window?"mcp":"mock"}function $(r){return new Proxy({},{get(e,t){if(typeof t!="string"||!t.startsWith("call"))return;let o=t.slice(4);if(o.length===0)return;let n=o.charAt(0).toLowerCase()+o.slice(1);return s=>r(n,s)},has(e,t){return typeof t=="string"&&t.startsWith("call")&&t.length>4},ownKeys(){return []},getOwnPropertyDescriptor(e,t){if(typeof t=="string"&&t.startsWith("call")&&t.length>4)return {configurable:true,enumerable:true,writable:false}}})}function b(r){async function e(n,s){return await r.callTool(n,s)}let t=$(e);return {callTool:e,tools:t,async sendMessage(n){await r.sendMessage(n);},async sendFollowUpMessage(n){await r.sendMessage({type:"text",text:n});},async updateModelContext(n){await r.updateModelContext(n);},async openLink(n){await r.openLink(n);},async requestDisplayMode(n){return r.requestDisplayMode(n)},requestClose(){r.requestClose();},getState(){return r.getState()},setState(n){r.setState(n);},...r.uploadFile&&{uploadFile:r.uploadFile.bind(r)},...r.getFileDownloadUrl&&{getFileDownloadUrl:r.getFileDownloadUrl.bind(r)},async readResource(n){return r.readResource(n)},log(n,s){r.log(n,s);},onToolResult(n){return r.onToolResult(n)},onToolInput(n){return r.onToolInput(n)},onToolCancelled(n){return r.onToolCancelled(n)},onHostContextChange(n){return r.onHostContextChange(n)},onTeardown(n){return r.onTeardown(n)},onToolInputPartial(n){return r.onToolInputPartial(n)},getHostCapabilities(){return r.getHostCapabilities()},getHostVersion(){return r.getHostVersion()},async sendLog(n,s){return r.sendLog(n,s)},async sendSizeChanged(n){return r.sendSizeChanged(n)},setupSizeChangedNotifications(){if(typeof window>"u"||typeof ResizeObserver>"u")return ()=>{};let n=new ResizeObserver(s=>{for(let a of s){let{width:l,height:c}=a.contentRect;r.sendSizeChanged({width:Math.round(l),height:Math.round(c)});}});return n.observe(document.body),()=>{n.disconnect();}},setCallToolHandler(n){r.setCallToolHandler(n);},setListToolsHandler(n){r.setListToolsHandler(n);},get hostContext(){return r.getHostContext()},get toolInput(){return r.getToolInput()},get toolOutput(){return r.getToolOutput()},get toolMeta(){return r.getToolMeta()}}}function q(r,e){switch(r){case "mcp":return new m(e?.mcp);case "openai":return new w;case "mock":return new h;default:throw new Error(`Unknown adapter type: ${r}`)}}async function K(r){let e=r?.forceAdapter??x();if(!["mcp","openai","mock"].includes(e))throw new Error(`Unknown adapter type: ${e}`);let t=r?.autoResize!==void 0?{mcp:{autoResize:r.autoResize}}:void 0,o=q(e,t);return await o.connect(),i.setAdapter(o),b(o)}async function he(r,e){return K(e)}exports.ClientDebugLogger=y;exports.LATEST_PROTOCOL_VERSION=_;exports.McpAdapter=m;exports.MockAdapter=h;exports.OpenAIAdapter=w;exports.RESOURCE_MIME_TYPE=F;exports.RESOURCE_URI_META_KEY=N;exports.UIError=d;exports.UIErrorCode=p;exports.applyDocumentTheme=H;exports.applyHostFonts=O;exports.applyHostStyleVariables=A;exports.clearHostStyleVariables=I;exports.clientDebugLogger=i;exports.createAppsClient=b;exports.createClient=K;exports.createTypedClient=he;exports.detectProtocol=x;exports.getDocumentTheme=k;exports.getMcpServerBaseUrl=U;exports.getMcpServerConfig=L;exports.removeHostFonts=R;exports.safeSerialize=E;exports.safeStringify=D;exports.shouldLog=S;//# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
+272
-1
@@ -51,2 +51,63 @@ /** | ||
| }; | ||
| /** | ||
| * Host supports model context updates (ext-apps v0.4.0+) | ||
| * | ||
| * Specifies which content block types are supported. | ||
| */ | ||
| updateModelContext?: { | ||
| /** Supports text content blocks */ | ||
| text?: Record<string, never>; | ||
| /** Supports image content blocks */ | ||
| image?: Record<string, never>; | ||
| /** Supports audio content blocks */ | ||
| audio?: Record<string, never>; | ||
| /** Supports resource content blocks */ | ||
| resource?: Record<string, never>; | ||
| /** Supports resource link content blocks */ | ||
| resourceLink?: Record<string, never>; | ||
| /** Supports structured content */ | ||
| structuredContent?: Record<string, never>; | ||
| }; | ||
| /** | ||
| * Host supports messages (ext-apps v0.4.0+) | ||
| * | ||
| * Specifies which content block types are supported for messages. | ||
| */ | ||
| message?: { | ||
| /** Supports text content blocks */ | ||
| text?: Record<string, never>; | ||
| /** Supports image content blocks */ | ||
| image?: Record<string, never>; | ||
| /** Supports audio content blocks */ | ||
| audio?: Record<string, never>; | ||
| /** Supports resource content blocks */ | ||
| resource?: Record<string, never>; | ||
| /** Supports resource link content blocks */ | ||
| resourceLink?: Record<string, never>; | ||
| /** Supports structured content */ | ||
| structuredContent?: Record<string, never>; | ||
| }; | ||
| /** | ||
| * Host sandbox capabilities (ext-apps v0.4.0+) | ||
| */ | ||
| sandbox?: { | ||
| /** Supported permissions */ | ||
| permissions?: { | ||
| camera?: Record<string, never>; | ||
| microphone?: Record<string, never>; | ||
| geolocation?: Record<string, never>; | ||
| clipboardWrite?: Record<string, never>; | ||
| }; | ||
| /** Content Security Policy settings */ | ||
| csp?: { | ||
| /** Allowed domains for fetch/XHR connections */ | ||
| connectDomains?: string[]; | ||
| /** Allowed domains for loading resources (images, scripts, etc.) */ | ||
| resourceDomains?: string[]; | ||
| /** Allowed domains for iframe embedding */ | ||
| frameDomains?: string[]; | ||
| /** Allowed domains for base URI */ | ||
| baseUriDomains?: string[]; | ||
| }; | ||
| }; | ||
| /** Host supports file uploads (ChatGPT only) */ | ||
@@ -148,2 +209,24 @@ fileUpload?: { | ||
| /** | ||
| * Container dimensions from host (ext-apps v0.4.0+) | ||
| * | ||
| * Replaces viewport for more explicit fixed vs flexible semantics. | ||
| * - Fixed dimensions (height/width): host controls the size | ||
| * - Flexible dimensions (maxHeight/maxWidth): app controls size up to max | ||
| * | ||
| * @internal | ||
| */ | ||
| type ContainerDimensions = { | ||
| height: number; | ||
| width: number; | ||
| } | { | ||
| height: number; | ||
| maxWidth?: number; | ||
| } | { | ||
| maxHeight?: number; | ||
| width: number; | ||
| } | { | ||
| maxHeight?: number; | ||
| maxWidth?: number; | ||
| }; | ||
| /** | ||
| * Safe area insets (mobile devices) | ||
@@ -191,2 +274,9 @@ * | ||
| viewport: Viewport; | ||
| /** | ||
| * Container dimensions from host (ext-apps v0.4.0+) | ||
| * | ||
| * More explicit than viewport - indicates whether dimensions are | ||
| * fixed (host-controlled) or flexible (app-controlled up to max). | ||
| */ | ||
| containerDimensions?: ContainerDimensions; | ||
| /** BCP 47 locale code */ | ||
@@ -277,2 +367,46 @@ locale: string; | ||
| /** | ||
| * Content block for model context updates | ||
| * | ||
| * Uses discriminated unions for type safety - each content type | ||
| * has only the fields that are valid for that type. | ||
| * | ||
| * @internal | ||
| */ | ||
| type ContentBlock = { | ||
| type: "text"; | ||
| text: string; | ||
| } | { | ||
| type: "image"; | ||
| data: string; | ||
| mimeType?: string; | ||
| } | { | ||
| type: "audio"; | ||
| data: string; | ||
| mimeType?: string; | ||
| } | { | ||
| type: "resource"; | ||
| uri: string; | ||
| description?: string; | ||
| } | { | ||
| type: "resource_link"; | ||
| uri: string; | ||
| name?: string; | ||
| description?: string; | ||
| }; | ||
| /** | ||
| * Parameters for updateModelContext | ||
| */ | ||
| interface UpdateModelContextParams { | ||
| /** | ||
| * Content blocks to add to model context. | ||
| * Supports text, image, audio, resource, and resource_link types. | ||
| */ | ||
| content?: ContentBlock[]; | ||
| /** | ||
| * Structured content as key-value pairs. | ||
| * Useful for passing typed data that the model can interpret. | ||
| */ | ||
| structuredContent?: Record<string, unknown>; | ||
| } | ||
| /** | ||
| * Unified client interface for UI code | ||
@@ -321,2 +455,45 @@ */ | ||
| /** | ||
| * Update the host's model context with app state (ext-apps v0.4.0+) | ||
| * | ||
| * Unlike sendMessage which triggers follow-up actions, context updates | ||
| * inform the model about app state without triggering responses. | ||
| * | ||
| * **Context Persistence:** | ||
| * - Each call **replaces** the previous context (not accumulated) | ||
| * - The host defers sending context to the model until the next user message | ||
| * - Only the most recent update is sent to the model | ||
| * | ||
| * **Platform Implementation Details:** | ||
| * | ||
| * - **MCP Apps:** Uses native protocol feature for pure context updates | ||
| * - **ChatGPT:** Uses setState/setWidgetState internally | ||
| * - Context persists for the widget's session lifetime | ||
| * - Both setState() and updateModelContext() expose data to the AI model | ||
| * - Use setState() for persistence-focused use cases | ||
| * - Use updateModelContext() for context-focused use cases | ||
| * - **Important:** Be mindful of data size when sending large structured content, | ||
| * as it may impact message context limits | ||
| * | ||
| * **Reserved Keys:** | ||
| * - Keys starting with underscore (`_`) in `structuredContent` are reserved | ||
| * for internal use and will be filtered out | ||
| * - Use alphanumeric keys for your application data | ||
| * | ||
| * @param params - Context content and/or structured content | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Text content | ||
| * await client.updateModelContext({ | ||
| * content: [{ type: "text", text: "User selected 3 items totaling $150" }] | ||
| * }); | ||
| * | ||
| * // Structured content | ||
| * await client.updateModelContext({ | ||
| * structuredContent: { selectedItems: 3, total: 150, currency: "USD" } | ||
| * }); | ||
| * ``` | ||
| */ | ||
| updateModelContext(params: UpdateModelContextParams): Promise<void>; | ||
| /** | ||
| * Open an external link | ||
@@ -735,2 +912,3 @@ * | ||
| readonly UNSUPPORTED_OPERATION: "UNSUPPORTED_OPERATION"; | ||
| readonly INVALID_PARAMS: "INVALID_PARAMS"; | ||
| readonly TOOL_CALL_FAILED: "TOOL_CALL_FAILED"; | ||
@@ -1037,2 +1215,11 @@ readonly TOOL_NOT_FOUND: "TOOL_NOT_FOUND"; | ||
| /** | ||
| * Update the host's model context with app state (ext-apps v0.4.0+) | ||
| * | ||
| * On MCP Apps: Calls app.updateModelContext() | ||
| * On ChatGPT: Silent no-op (graceful degradation) | ||
| * | ||
| * @param params - Context content and/or structured content | ||
| */ | ||
| updateModelContext(params: UpdateModelContextParams): Promise<void>; | ||
| /** | ||
| * Open an external link | ||
@@ -1355,2 +1542,9 @@ * | ||
| }): Promise<void>; | ||
| /** Last model context params (for testing) */ | ||
| private lastModelContext?; | ||
| updateModelContext(params: UpdateModelContextParams): Promise<void>; | ||
| /** | ||
| * Get the last model context params (for testing) | ||
| */ | ||
| getLastModelContext(): UpdateModelContextParams | undefined; | ||
| openLink(url: string): Promise<void>; | ||
@@ -1496,2 +1690,7 @@ requestDisplayMode(mode: string): Promise<{ | ||
| private mapHostContext; | ||
| /** | ||
| * Derive viewport dimensions from containerDimensions for backward compatibility. | ||
| * containerDimensions uses fixed (height/width) vs flexible (maxHeight/maxWidth) semantics. | ||
| */ | ||
| private deriveViewportFromContainerDimensions; | ||
| private extractToolMeta; | ||
@@ -1509,2 +1708,3 @@ /** | ||
| }): Promise<void>; | ||
| updateModelContext(params: UpdateModelContextParams): Promise<void>; | ||
| openLink(url: string): Promise<void>; | ||
@@ -1654,2 +1854,28 @@ requestDisplayMode(mode: string): Promise<{ | ||
| }): Promise<void>; | ||
| /** | ||
| * Update model context (ext-apps v0.4.0+) | ||
| * | ||
| * On ChatGPT, this method uses setState() internally, which calls the | ||
| * OpenAI SDK's setWidgetState(). In ChatGPT, setWidgetState() exposes | ||
| * data to the AI model context, making it visible to the model. | ||
| * | ||
| * **ChatGPT Implementation Details:** | ||
| * - Uses setState/setWidgetState (exposes to AI + persists for session) | ||
| * - Each call **replaces** the previous context (not accumulated) | ||
| * - Context persists for the widget's session lifetime | ||
| * - Be mindful of data size when sending large structured content | ||
| * | ||
| * **MCP Apps Implementation:** | ||
| * - Pure context update via native protocol feature | ||
| * - No persistence, only sent to model with next user message | ||
| * | ||
| * **Reserved Keys:** | ||
| * - Keys starting with underscore (`_`) in structuredContent are filtered | ||
| * - Internal keys use double-underscore prefix (`__mcp_*`) | ||
| * | ||
| * Use updateModelContext() for context-focused use cases (informing the model | ||
| * about app state), and setState() for persistence-focused use cases. | ||
| * Note: On ChatGPT, both methods expose state to the AI model. | ||
| */ | ||
| updateModelContext(params: UpdateModelContextParams): Promise<void>; | ||
| openLink(url: string): Promise<void>; | ||
@@ -1783,3 +2009,48 @@ requestDisplayMode(mode: string): Promise<{ | ||
| declare function createClient<T extends ToolDefs = ToolDefs>(options?: CreateClientOptions): Promise<AppsClient<T>>; | ||
| /** | ||
| * Create a typed client from an App instance. | ||
| * | ||
| * Convenience function that automatically extracts client types from | ||
| * your App instance, eliminating manual type exports. | ||
| * | ||
| * @param app - App instance from @mcp-apps-kit/core with clientTypes | ||
| * @param options - Optional client configuration (forceAdapter, autoResize) | ||
| * @returns Fully typed AppsClient | ||
| * | ||
| * @example Single-version app | ||
| * ```typescript | ||
| * // server.ts | ||
| * import { createApp, defineTool } from "@mcp-apps-kit/core"; | ||
| * const app = createApp({ | ||
| * tools: { greet: defineTool({ ... }) } | ||
| * }); | ||
| * export { app }; | ||
| * | ||
| * // ui.tsx | ||
| * import { createTypedClient } from "@mcp-apps-kit/ui"; | ||
| * import { app } from "./server"; | ||
| * const client = await createTypedClient(app); | ||
| * client.tools.callGreet({ name: "Alice" }); // Fully typed! | ||
| * ``` | ||
| * | ||
| * @example Multi-version app | ||
| * ```typescript | ||
| * // server.ts | ||
| * const app = createApp({ | ||
| * versions: { | ||
| * v1: { version: "1.0.0", tools: { ... } }, | ||
| * v2: { version: "2.0.0", tools: { ... } } | ||
| * } | ||
| * }); | ||
| * export const v1 = app.getVersion("v1")!; | ||
| * export const v2 = app.getVersion("v2")!; | ||
| * | ||
| * // ui.tsx | ||
| * const client = await createTypedClient(v1); | ||
| * ``` | ||
| */ | ||
| declare function createTypedClient<T extends ToolDefs>(_app: { | ||
| readonly clientTypes: T; | ||
| }, options?: CreateClientOptions): Promise<AppsClient<T>>; | ||
| export { type AdapterFactory, type AdapterType, type AppCapabilities, type AppToolDefinition, type AppsClient, type CallToolHandler, type ClientDebugConfig, ClientDebugLogger, type CreateClientOptions, type DebugLogLevel, type DebugTransport, type DetectedProtocol, type DeviceCapabilities, type HostCapabilities, type HostContext, type HostStyles, type HostVersion, type InferToolInputs, type InferToolOutputs, LATEST_PROTOCOL_VERSION, type ListToolsHandler, type LogEntry, McpAdapter, type McpAdapterOptions, type McpServerConfig, MockAdapter, type ModalButton, type ModalInput, type ModalOptions, type ModalResult, OpenAIAdapter, type ProtocolAdapter, RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY, type ResourceContent, type SafeAreaInsets, type SizeChangedParams, type Theme, type ToolDefs, type ToolMethods, type ToolResult, UIError, UIErrorCode, type UIErrorCodeType, type Viewport, applyDocumentTheme, applyHostFonts, applyHostStyleVariables, clearHostStyleVariables, clientDebugLogger, createAppsClient, createClient, detectProtocol, getDocumentTheme, getMcpServerBaseUrl, getMcpServerConfig, removeHostFonts, safeSerialize, safeStringify, shouldLog }; | ||
| export { type AdapterFactory, type AdapterType, type AppCapabilities, type AppToolDefinition, type AppsClient, type CallToolHandler, type ClientDebugConfig, ClientDebugLogger, type ContainerDimensions, type ContentBlock, type CreateClientOptions, type DebugLogLevel, type DebugTransport, type DetectedProtocol, type DeviceCapabilities, type HostCapabilities, type HostContext, type HostStyles, type HostVersion, type InferToolInputs, type InferToolOutputs, LATEST_PROTOCOL_VERSION, type ListToolsHandler, type LogEntry, McpAdapter, type McpAdapterOptions, type McpServerConfig, MockAdapter, type ModalButton, type ModalInput, type ModalOptions, type ModalResult, OpenAIAdapter, type ProtocolAdapter, RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY, type ResourceContent, type SafeAreaInsets, type SizeChangedParams, type Theme, type ToolDefs, type ToolMethods, type ToolResult, UIError, UIErrorCode, type UIErrorCodeType, type UpdateModelContextParams, type Viewport, applyDocumentTheme, applyHostFonts, applyHostStyleVariables, clearHostStyleVariables, clientDebugLogger, createAppsClient, createClient, createTypedClient, detectProtocol, getDocumentTheme, getMcpServerBaseUrl, getMcpServerConfig, removeHostFonts, safeSerialize, safeStringify, shouldLog }; |
+272
-1
@@ -51,2 +51,63 @@ /** | ||
| }; | ||
| /** | ||
| * Host supports model context updates (ext-apps v0.4.0+) | ||
| * | ||
| * Specifies which content block types are supported. | ||
| */ | ||
| updateModelContext?: { | ||
| /** Supports text content blocks */ | ||
| text?: Record<string, never>; | ||
| /** Supports image content blocks */ | ||
| image?: Record<string, never>; | ||
| /** Supports audio content blocks */ | ||
| audio?: Record<string, never>; | ||
| /** Supports resource content blocks */ | ||
| resource?: Record<string, never>; | ||
| /** Supports resource link content blocks */ | ||
| resourceLink?: Record<string, never>; | ||
| /** Supports structured content */ | ||
| structuredContent?: Record<string, never>; | ||
| }; | ||
| /** | ||
| * Host supports messages (ext-apps v0.4.0+) | ||
| * | ||
| * Specifies which content block types are supported for messages. | ||
| */ | ||
| message?: { | ||
| /** Supports text content blocks */ | ||
| text?: Record<string, never>; | ||
| /** Supports image content blocks */ | ||
| image?: Record<string, never>; | ||
| /** Supports audio content blocks */ | ||
| audio?: Record<string, never>; | ||
| /** Supports resource content blocks */ | ||
| resource?: Record<string, never>; | ||
| /** Supports resource link content blocks */ | ||
| resourceLink?: Record<string, never>; | ||
| /** Supports structured content */ | ||
| structuredContent?: Record<string, never>; | ||
| }; | ||
| /** | ||
| * Host sandbox capabilities (ext-apps v0.4.0+) | ||
| */ | ||
| sandbox?: { | ||
| /** Supported permissions */ | ||
| permissions?: { | ||
| camera?: Record<string, never>; | ||
| microphone?: Record<string, never>; | ||
| geolocation?: Record<string, never>; | ||
| clipboardWrite?: Record<string, never>; | ||
| }; | ||
| /** Content Security Policy settings */ | ||
| csp?: { | ||
| /** Allowed domains for fetch/XHR connections */ | ||
| connectDomains?: string[]; | ||
| /** Allowed domains for loading resources (images, scripts, etc.) */ | ||
| resourceDomains?: string[]; | ||
| /** Allowed domains for iframe embedding */ | ||
| frameDomains?: string[]; | ||
| /** Allowed domains for base URI */ | ||
| baseUriDomains?: string[]; | ||
| }; | ||
| }; | ||
| /** Host supports file uploads (ChatGPT only) */ | ||
@@ -148,2 +209,24 @@ fileUpload?: { | ||
| /** | ||
| * Container dimensions from host (ext-apps v0.4.0+) | ||
| * | ||
| * Replaces viewport for more explicit fixed vs flexible semantics. | ||
| * - Fixed dimensions (height/width): host controls the size | ||
| * - Flexible dimensions (maxHeight/maxWidth): app controls size up to max | ||
| * | ||
| * @internal | ||
| */ | ||
| type ContainerDimensions = { | ||
| height: number; | ||
| width: number; | ||
| } | { | ||
| height: number; | ||
| maxWidth?: number; | ||
| } | { | ||
| maxHeight?: number; | ||
| width: number; | ||
| } | { | ||
| maxHeight?: number; | ||
| maxWidth?: number; | ||
| }; | ||
| /** | ||
| * Safe area insets (mobile devices) | ||
@@ -191,2 +274,9 @@ * | ||
| viewport: Viewport; | ||
| /** | ||
| * Container dimensions from host (ext-apps v0.4.0+) | ||
| * | ||
| * More explicit than viewport - indicates whether dimensions are | ||
| * fixed (host-controlled) or flexible (app-controlled up to max). | ||
| */ | ||
| containerDimensions?: ContainerDimensions; | ||
| /** BCP 47 locale code */ | ||
@@ -277,2 +367,46 @@ locale: string; | ||
| /** | ||
| * Content block for model context updates | ||
| * | ||
| * Uses discriminated unions for type safety - each content type | ||
| * has only the fields that are valid for that type. | ||
| * | ||
| * @internal | ||
| */ | ||
| type ContentBlock = { | ||
| type: "text"; | ||
| text: string; | ||
| } | { | ||
| type: "image"; | ||
| data: string; | ||
| mimeType?: string; | ||
| } | { | ||
| type: "audio"; | ||
| data: string; | ||
| mimeType?: string; | ||
| } | { | ||
| type: "resource"; | ||
| uri: string; | ||
| description?: string; | ||
| } | { | ||
| type: "resource_link"; | ||
| uri: string; | ||
| name?: string; | ||
| description?: string; | ||
| }; | ||
| /** | ||
| * Parameters for updateModelContext | ||
| */ | ||
| interface UpdateModelContextParams { | ||
| /** | ||
| * Content blocks to add to model context. | ||
| * Supports text, image, audio, resource, and resource_link types. | ||
| */ | ||
| content?: ContentBlock[]; | ||
| /** | ||
| * Structured content as key-value pairs. | ||
| * Useful for passing typed data that the model can interpret. | ||
| */ | ||
| structuredContent?: Record<string, unknown>; | ||
| } | ||
| /** | ||
| * Unified client interface for UI code | ||
@@ -321,2 +455,45 @@ */ | ||
| /** | ||
| * Update the host's model context with app state (ext-apps v0.4.0+) | ||
| * | ||
| * Unlike sendMessage which triggers follow-up actions, context updates | ||
| * inform the model about app state without triggering responses. | ||
| * | ||
| * **Context Persistence:** | ||
| * - Each call **replaces** the previous context (not accumulated) | ||
| * - The host defers sending context to the model until the next user message | ||
| * - Only the most recent update is sent to the model | ||
| * | ||
| * **Platform Implementation Details:** | ||
| * | ||
| * - **MCP Apps:** Uses native protocol feature for pure context updates | ||
| * - **ChatGPT:** Uses setState/setWidgetState internally | ||
| * - Context persists for the widget's session lifetime | ||
| * - Both setState() and updateModelContext() expose data to the AI model | ||
| * - Use setState() for persistence-focused use cases | ||
| * - Use updateModelContext() for context-focused use cases | ||
| * - **Important:** Be mindful of data size when sending large structured content, | ||
| * as it may impact message context limits | ||
| * | ||
| * **Reserved Keys:** | ||
| * - Keys starting with underscore (`_`) in `structuredContent` are reserved | ||
| * for internal use and will be filtered out | ||
| * - Use alphanumeric keys for your application data | ||
| * | ||
| * @param params - Context content and/or structured content | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // Text content | ||
| * await client.updateModelContext({ | ||
| * content: [{ type: "text", text: "User selected 3 items totaling $150" }] | ||
| * }); | ||
| * | ||
| * // Structured content | ||
| * await client.updateModelContext({ | ||
| * structuredContent: { selectedItems: 3, total: 150, currency: "USD" } | ||
| * }); | ||
| * ``` | ||
| */ | ||
| updateModelContext(params: UpdateModelContextParams): Promise<void>; | ||
| /** | ||
| * Open an external link | ||
@@ -735,2 +912,3 @@ * | ||
| readonly UNSUPPORTED_OPERATION: "UNSUPPORTED_OPERATION"; | ||
| readonly INVALID_PARAMS: "INVALID_PARAMS"; | ||
| readonly TOOL_CALL_FAILED: "TOOL_CALL_FAILED"; | ||
@@ -1037,2 +1215,11 @@ readonly TOOL_NOT_FOUND: "TOOL_NOT_FOUND"; | ||
| /** | ||
| * Update the host's model context with app state (ext-apps v0.4.0+) | ||
| * | ||
| * On MCP Apps: Calls app.updateModelContext() | ||
| * On ChatGPT: Silent no-op (graceful degradation) | ||
| * | ||
| * @param params - Context content and/or structured content | ||
| */ | ||
| updateModelContext(params: UpdateModelContextParams): Promise<void>; | ||
| /** | ||
| * Open an external link | ||
@@ -1355,2 +1542,9 @@ * | ||
| }): Promise<void>; | ||
| /** Last model context params (for testing) */ | ||
| private lastModelContext?; | ||
| updateModelContext(params: UpdateModelContextParams): Promise<void>; | ||
| /** | ||
| * Get the last model context params (for testing) | ||
| */ | ||
| getLastModelContext(): UpdateModelContextParams | undefined; | ||
| openLink(url: string): Promise<void>; | ||
@@ -1496,2 +1690,7 @@ requestDisplayMode(mode: string): Promise<{ | ||
| private mapHostContext; | ||
| /** | ||
| * Derive viewport dimensions from containerDimensions for backward compatibility. | ||
| * containerDimensions uses fixed (height/width) vs flexible (maxHeight/maxWidth) semantics. | ||
| */ | ||
| private deriveViewportFromContainerDimensions; | ||
| private extractToolMeta; | ||
@@ -1509,2 +1708,3 @@ /** | ||
| }): Promise<void>; | ||
| updateModelContext(params: UpdateModelContextParams): Promise<void>; | ||
| openLink(url: string): Promise<void>; | ||
@@ -1654,2 +1854,28 @@ requestDisplayMode(mode: string): Promise<{ | ||
| }): Promise<void>; | ||
| /** | ||
| * Update model context (ext-apps v0.4.0+) | ||
| * | ||
| * On ChatGPT, this method uses setState() internally, which calls the | ||
| * OpenAI SDK's setWidgetState(). In ChatGPT, setWidgetState() exposes | ||
| * data to the AI model context, making it visible to the model. | ||
| * | ||
| * **ChatGPT Implementation Details:** | ||
| * - Uses setState/setWidgetState (exposes to AI + persists for session) | ||
| * - Each call **replaces** the previous context (not accumulated) | ||
| * - Context persists for the widget's session lifetime | ||
| * - Be mindful of data size when sending large structured content | ||
| * | ||
| * **MCP Apps Implementation:** | ||
| * - Pure context update via native protocol feature | ||
| * - No persistence, only sent to model with next user message | ||
| * | ||
| * **Reserved Keys:** | ||
| * - Keys starting with underscore (`_`) in structuredContent are filtered | ||
| * - Internal keys use double-underscore prefix (`__mcp_*`) | ||
| * | ||
| * Use updateModelContext() for context-focused use cases (informing the model | ||
| * about app state), and setState() for persistence-focused use cases. | ||
| * Note: On ChatGPT, both methods expose state to the AI model. | ||
| */ | ||
| updateModelContext(params: UpdateModelContextParams): Promise<void>; | ||
| openLink(url: string): Promise<void>; | ||
@@ -1783,3 +2009,48 @@ requestDisplayMode(mode: string): Promise<{ | ||
| declare function createClient<T extends ToolDefs = ToolDefs>(options?: CreateClientOptions): Promise<AppsClient<T>>; | ||
| /** | ||
| * Create a typed client from an App instance. | ||
| * | ||
| * Convenience function that automatically extracts client types from | ||
| * your App instance, eliminating manual type exports. | ||
| * | ||
| * @param app - App instance from @mcp-apps-kit/core with clientTypes | ||
| * @param options - Optional client configuration (forceAdapter, autoResize) | ||
| * @returns Fully typed AppsClient | ||
| * | ||
| * @example Single-version app | ||
| * ```typescript | ||
| * // server.ts | ||
| * import { createApp, defineTool } from "@mcp-apps-kit/core"; | ||
| * const app = createApp({ | ||
| * tools: { greet: defineTool({ ... }) } | ||
| * }); | ||
| * export { app }; | ||
| * | ||
| * // ui.tsx | ||
| * import { createTypedClient } from "@mcp-apps-kit/ui"; | ||
| * import { app } from "./server"; | ||
| * const client = await createTypedClient(app); | ||
| * client.tools.callGreet({ name: "Alice" }); // Fully typed! | ||
| * ``` | ||
| * | ||
| * @example Multi-version app | ||
| * ```typescript | ||
| * // server.ts | ||
| * const app = createApp({ | ||
| * versions: { | ||
| * v1: { version: "1.0.0", tools: { ... } }, | ||
| * v2: { version: "2.0.0", tools: { ... } } | ||
| * } | ||
| * }); | ||
| * export const v1 = app.getVersion("v1")!; | ||
| * export const v2 = app.getVersion("v2")!; | ||
| * | ||
| * // ui.tsx | ||
| * const client = await createTypedClient(v1); | ||
| * ``` | ||
| */ | ||
| declare function createTypedClient<T extends ToolDefs>(_app: { | ||
| readonly clientTypes: T; | ||
| }, options?: CreateClientOptions): Promise<AppsClient<T>>; | ||
| export { type AdapterFactory, type AdapterType, type AppCapabilities, type AppToolDefinition, type AppsClient, type CallToolHandler, type ClientDebugConfig, ClientDebugLogger, type CreateClientOptions, type DebugLogLevel, type DebugTransport, type DetectedProtocol, type DeviceCapabilities, type HostCapabilities, type HostContext, type HostStyles, type HostVersion, type InferToolInputs, type InferToolOutputs, LATEST_PROTOCOL_VERSION, type ListToolsHandler, type LogEntry, McpAdapter, type McpAdapterOptions, type McpServerConfig, MockAdapter, type ModalButton, type ModalInput, type ModalOptions, type ModalResult, OpenAIAdapter, type ProtocolAdapter, RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY, type ResourceContent, type SafeAreaInsets, type SizeChangedParams, type Theme, type ToolDefs, type ToolMethods, type ToolResult, UIError, UIErrorCode, type UIErrorCodeType, type Viewport, applyDocumentTheme, applyHostFonts, applyHostStyleVariables, clearHostStyleVariables, clientDebugLogger, createAppsClient, createClient, detectProtocol, getDocumentTheme, getMcpServerBaseUrl, getMcpServerConfig, removeHostFonts, safeSerialize, safeStringify, shouldLog }; | ||
| export { type AdapterFactory, type AdapterType, type AppCapabilities, type AppToolDefinition, type AppsClient, type CallToolHandler, type ClientDebugConfig, ClientDebugLogger, type ContainerDimensions, type ContentBlock, type CreateClientOptions, type DebugLogLevel, type DebugTransport, type DetectedProtocol, type DeviceCapabilities, type HostCapabilities, type HostContext, type HostStyles, type HostVersion, type InferToolInputs, type InferToolOutputs, LATEST_PROTOCOL_VERSION, type ListToolsHandler, type LogEntry, McpAdapter, type McpAdapterOptions, type McpServerConfig, MockAdapter, type ModalButton, type ModalInput, type ModalOptions, type ModalResult, OpenAIAdapter, type ProtocolAdapter, RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY, type ResourceContent, type SafeAreaInsets, type SizeChangedParams, type Theme, type ToolDefs, type ToolMethods, type ToolResult, UIError, UIErrorCode, type UIErrorCodeType, type UpdateModelContextParams, type Viewport, applyDocumentTheme, applyHostFonts, applyHostStyleVariables, clearHostStyleVariables, clientDebugLogger, createAppsClient, createClient, createTypedClient, detectProtocol, getDocumentTheme, getMcpServerBaseUrl, getMcpServerConfig, removeHostFonts, safeSerialize, safeStringify, shouldLog }; |
+2
-1
@@ -1,2 +0,3 @@ | ||
| import {App}from'@modelcontextprotocol/ext-apps';var D="2025-11-05",_="text/html;profile=mcp-app",F="ui/resourceUri";function x(r){if(typeof document>"u")return;let e=r==="os"?typeof window<"u"&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":r;document.documentElement.classList.remove("light","dark"),document.documentElement.classList.add(e),document.documentElement.setAttribute("data-theme",e);}function H(){if(typeof document>"u")return "light";let r=document.documentElement.getAttribute("data-theme");return r==="dark"||r==="light"?r:document.documentElement.classList.contains("dark")?"dark":"light"}var T="mcp-apps-host-fonts";function k(r){if(typeof document>"u")return;let e=document.documentElement;for(let[t,n]of Object.entries(r)){let o=t.startsWith("--")?t:`--${t}`;e.style.setProperty(o,n);}}function O(r){if(typeof document>"u")return;let e=document.getElementById(T);e||(e=document.createElement("style"),e.id=T,document.head.appendChild(e)),e.textContent=r;}function A(){if(typeof document>"u")return;let r=document.getElementById(T);r&&r.remove();}function R(r){if(typeof document>"u")return;let e=document.documentElement;for(let t of Object.keys(r)){let n=t.startsWith("--")?t:`--${t}`;e.style.removeProperty(n);}}var g={CONNECTION_FAILED:"CONNECTION_FAILED",CONNECTION_TIMEOUT:"CONNECTION_TIMEOUT",NOT_CONNECTED:"NOT_CONNECTED",PROTOCOL_ERROR:"PROTOCOL_ERROR",UNSUPPORTED_OPERATION:"UNSUPPORTED_OPERATION",TOOL_CALL_FAILED:"TOOL_CALL_FAILED",TOOL_NOT_FOUND:"TOOL_NOT_FOUND",STATE_ERROR:"STATE_ERROR",UNKNOWN_ERROR:"UNKNOWN_ERROR"},d=class extends Error{constructor(t,n,o,s){super(n);this.code=t;this.details=o;this.cause=s;this.name="UIError";}formatMessage(){let t=`[${this.code}] ${this.message}`;return this.details&&(t+=` ${JSON.stringify(this.details)}`),t}};var I={debug:0,info:1,warn:2,error:3};function S(r,e){return I[r]>=I[e]}function M(){let r=new WeakSet;return (e,t)=>{if(typeof t=="object"&&t!==null){if(r.has(t))return "[Circular]";r.add(t);}return t}}function E(r){if(r==null||typeof r=="string"||typeof r=="number"||typeof r=="boolean")return r;if(r instanceof Error)return {name:r.name,message:r.message,stack:r.stack};try{return JSON.stringify(r),r}catch{try{let e=JSON.stringify(r,M());return JSON.parse(e)}catch{return "[Unserializable]"}}}function P(r){if(r===void 0)return "undefined";if(r===null)return "null";if(typeof r=="string")return r;if(r instanceof Error)return `${r.name}: ${r.message}`;try{return JSON.stringify(r,M())}catch{return "[Unstringifiable]"}}var y=class{constructor(e={}){this.adapter=null;this.buffer=[];this.flushTimer=null;this.isFlushing=false;this.mcpTransportFailed=false;this.apiTransportFailed=false;this.config={enabled:e.enabled??false,level:e.level??"info",batchSize:e.batchSize??10,maxBufferSize:e.maxBufferSize??100,flushIntervalMs:e.flushIntervalMs??5e3,source:e.source??"mcp-apps-ui",transport:e.transport??"tool",apiEndpoint:e.apiEndpoint};}setAdapter(e){this.adapter=e,this.mcpTransportFailed=false,this.apiTransportFailed=false;}configure(e){e.enabled!==void 0&&(this.config.enabled=e.enabled),e.level!==void 0&&(this.config.level=e.level),e.batchSize!==void 0&&(this.config.batchSize=e.batchSize),e.maxBufferSize!==void 0&&(this.config.maxBufferSize=e.maxBufferSize),e.flushIntervalMs!==void 0&&(this.config.flushIntervalMs=e.flushIntervalMs,this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),this.scheduleFlush()),e.source!==void 0&&(this.config.source=e.source),e.transport!==void 0&&(this.config.transport=e.transport,this.mcpTransportFailed=false,this.apiTransportFailed=false),e.apiEndpoint!==void 0&&(this.config.apiEndpoint=e.apiEndpoint,this.apiTransportFailed=false);}canUseToolTransport(){return this.config.enabled&&this.config.transport==="tool"&&!this.mcpTransportFailed&&this.adapter?.isConnected()===true}canUseApiTransport(){return this.config.enabled&&this.config.transport==="api"&&!this.apiTransportFailed&&!!this.config.apiEndpoint}canUseRemoteTransport(){return this.canUseToolTransport()||this.canUseApiTransport()}createEntry(e,t,n){return {level:e,message:t,data:n!==void 0?E(n):void 0,timestamp:new Date().toISOString(),source:this.config.source}}scheduleFlush(){this.flushTimer||this.buffer.length===0||(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}async flushToApi(e){if(!this.config.apiEndpoint)throw new Error("API endpoint not configured");let t=await fetch(this.config.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:e})});if(!t.ok)throw new Error(`API request failed with status ${String(t.status)}`)}async flushToTool(e){if(!this.adapter)throw new Error("Adapter not connected");await this.adapter.callTool("log_debug",{entries:e});}async flush(){if(this.isFlushing||this.buffer.length===0)return;if(this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),!this.canUseRemoteTransport()){this.buffer=[];return}this.isFlushing=true;let e=[...this.buffer];try{this.canUseApiTransport()?await this.flushToApi(e):this.canUseToolTransport()&&await this.flushToTool(e),this.buffer=this.buffer.slice(e.length);}catch(t){this.buffer=this.buffer.slice(e.length);let n=t instanceof Error?t.message:String(t);this.config.transport==="api"&&!this.apiTransportFailed?(this.apiTransportFailed=true,console.warn(`[ClientDebugLogger] API log transport failed: ${n}. Will only use console`)):this.config.transport==="tool"&&!this.mcpTransportFailed&&(this.mcpTransportFailed=true,console.warn(`[ClientDebugLogger] MCP log transport failed: ${n}. Will only use console`));}finally{this.isFlushing=false,this.buffer.length>0&&this.scheduleFlush();}}outputToConsole(e){let t=`[${e.timestamp}] [${e.level.toUpperCase()}]`,n=e.data!==void 0?`${e.message} ${P(e.data)}`:e.message,o=`${t} ${n}`;try{switch(e.level){case "debug":console.debug(o);break;case "info":console.info(o);break;case "warn":console.warn(o);break;case "error":console.error(o);break}}catch{}}addToBuffer(e){for(;this.buffer.length>=this.config.maxBufferSize;)this.buffer.shift();if(this.buffer.push(e),e.level==="error"){this.flush();return}if(this.buffer.length>=this.config.batchSize){this.flush();return}this.scheduleFlush();}log(e,t,n){if(!S(e,this.config.level))return;let o=this.createEntry(e,t,n);this.outputToConsole(o),this.canUseRemoteTransport()&&this.addToBuffer(o);}debug(e,t){this.log("debug",e,t);}info(e,t){this.log("info",e,t);}warn(e,t){this.log("warn",e,t);}error(e,t){this.log("error",e,t);}destroy(){this.buffer=[],this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),this.adapter=null;}},i=new y;function L(){return typeof window<"u"&&window.__MCP_SERVER_CONFIG__?window.__MCP_SERVER_CONFIG__:typeof __MCP_SERVER_CONFIG__<"u"&&__MCP_SERVER_CONFIG__?__MCP_SERVER_CONFIG__:{}}function N(r=""){let e=L();return e.baseUrl?e.baseUrl:typeof window<"u"&&(window.location.protocol==="http:"||window.location.protocol==="https:")?window.location.origin:r}var h=class{constructor(){this.connected=false;this.state=null;this.toolResultHandlers=new Set;this.toolInputHandlers=new Set;this.toolInputPartialHandlers=new Set;this.toolCancelledHandlers=new Set;this.hostContextHandlers=new Set;this.teardownHandlers=new Set;this.mockHostCapabilities={logging:{},openLinks:{},theming:{themes:["light","dark","os"]},displayModes:{modes:["inline","fullscreen","pip","panel"]},statePersistence:{persistent:true},serverTools:{listChanged:false},serverResources:{listChanged:false},sizeNotifications:{},partialToolInput:{},appTools:{listChanged:false},fileUpload:{},safeAreaInsets:{},views:{}};this.mockHostVersion={name:"MockHost",version:"1.0.0"};this.context=this.createDefaultContext();}createDefaultContext(){let e=typeof window<"u";return {theme:"light",displayMode:"inline",availableDisplayModes:["inline","fullscreen","pip"],viewport:{width:e?window.innerWidth:800,height:e?window.innerHeight:600},locale:e?navigator.language:"en-US",timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,platform:"web",deviceCapabilities:{touch:e?"ontouchstart"in window:false,hover:true}}}async connect(){this.connected=true,console.log("[MockAdapter] Connected");}isConnected(){return this.connected}async callTool(e,t){console.log(`[MockAdapter] callTool("${e}",`,t,")");let n={_mock:true,tool:e,args:t,timestamp:Date.now()};return this.currentToolOutput=n,n}async sendMessage(e){console.log("[MockAdapter] sendMessage:",e);}async openLink(e){console.log(`[MockAdapter] openLink("${e}")`);}async requestDisplayMode(e){return console.log(`[MockAdapter] requestDisplayMode("${e}")`),this.context={...this.context,displayMode:e},this.notifyHostContextChange(),{mode:e}}requestClose(){console.log("[MockAdapter] requestClose()");}getState(){return this.state}setState(e){this.state=e,console.log("[MockAdapter] setState:",e);}async readResource(e){return console.log(`[MockAdapter] readResource("${e}")`),{contents:[]}}log(e,t){({debug:console.debug,info:console.info,warning:console.warn,error:console.error}[e]??console.log)("[MockAdapter]",t);}onToolResult(e){return this.toolResultHandlers.add(e),()=>this.toolResultHandlers.delete(e)}onToolInput(e){return this.toolInputHandlers.add(e),()=>this.toolInputHandlers.delete(e)}onToolCancelled(e){return this.toolCancelledHandlers.add(e),()=>this.toolCancelledHandlers.delete(e)}onHostContextChange(e){return this.hostContextHandlers.add(e),()=>this.hostContextHandlers.delete(e)}onTeardown(e){return this.teardownHandlers.add(e),()=>this.teardownHandlers.delete(e)}getHostContext(){return this.context}getToolInput(){return this.currentToolInput}getToolOutput(){return this.currentToolOutput}getToolMeta(){return this.currentToolMeta}emitToolResult(e){this.currentToolOutput=e;for(let t of this.toolResultHandlers)t(e);}emitToolInput(e){this.currentToolInput=e;for(let t of this.toolInputHandlers)t(e);}setHostContext(e){this.context={...this.context,...e},this.notifyHostContextChange();}emitContextChange(e){this.context=e,this.notifyHostContextChange();}setToolInput(e){this.currentToolInput=e;}emitToolCancelled(e){for(let t of this.toolCancelledHandlers)t(e);}emitTeardown(e){for(let t of this.teardownHandlers)t(e);}notifyHostContextChange(){for(let e of this.hostContextHandlers)e(this.context);}getHostCapabilities(){return this.mockHostCapabilities}getHostVersion(){return this.mockHostVersion}async sendLog(e,t){console.log(`[MockAdapter] sendLog(${e}):`,t);}async sendLogs(e){for(let t of e)console.log(`[MockAdapter] sendLogs(${t.level}):`,t.message,t.data);return {processed:e.length}}async sendSizeChanged(e){console.log("[MockAdapter] sendSizeChanged:",e);}onToolInputPartial(e){return this.toolInputPartialHandlers.add(e),()=>this.toolInputPartialHandlers.delete(e)}setCallToolHandler(e){this.callToolHandler=e,console.log("[MockAdapter] setCallToolHandler: handler registered");}setListToolsHandler(e){this.listToolsHandler=e,console.log("[MockAdapter] setListToolsHandler: handler registered");}emitToolInputPartial(e){for(let t of this.toolInputPartialHandlers)t(e);}setMockHostCapabilities(e){this.mockHostCapabilities={...this.mockHostCapabilities,...e};}setMockHostVersion(e){this.mockHostVersion=e;}async simulateHostToolCall(e,t){if(!this.callToolHandler)throw new d(g.TOOL_NOT_FOUND,"No call tool handler registered");return this.callToolHandler(e,t)}async simulateHostListTools(){return this.listToolsHandler?this.listToolsHandler():{tools:[]}}};var z={parse:r=>r},m=class{constructor(e){this.connected=false;this.toolResultHandlers=new Set;this.toolInputHandlers=new Set;this.toolInputPartialHandlers=new Set;this.toolCancelledHandlers=new Set;this.hostContextHandlers=new Set;this.teardownHandlers=new Set;this.context=this.createDefaultContext(),this.autoResize=e?.autoResize??true;}createDefaultContext(){let e=typeof window<"u";return {theme:"light",displayMode:"inline",availableDisplayModes:["inline","fullscreen"],viewport:{width:e?window.innerWidth:800,height:e?window.innerHeight:600},locale:e?navigator.language:"en-US",timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,platform:"desktop"}}async connect(){if(this.connected)return;if(typeof window>"u"){this.connected=true;return}this.app=new App({name:"@mcp-apps-kit/ui",version:"0.0.0"},{tools:{}},{autoResize:this.autoResize}),this.app.onerror=t=>{this.log("error",t);},this.app.onhostcontextchanged=t=>{let n=t.hostContext??t;this.context=this.mapHostContext(n),this.currentToolMeta=this.extractToolMeta(n);for(let o of this.hostContextHandlers)o(this.context);},this.app.ontoolinput=t=>{let n=t.arguments;if(n){this.currentToolInput=n;for(let o of this.toolInputHandlers)o(n);}},this.app.ontoolinputpartial=t=>{let n=t.arguments;if(n)for(let o of this.toolInputPartialHandlers)o(n);},this.app.oncalltool=async t=>{let{name:n,arguments:o}=t;try{if(this.callToolHandler){let s=await this.callToolHandler(n,o??{});return {content:[{type:"text",text:JSON.stringify(s)}]}}return {content:[{type:"text",text:`No handler registered for tool: ${n}`}],isError:!0}}catch(s){return {content:[{type:"text",text:s instanceof Error?s.message:String(s)}],isError:true}}},this.app.onlisttools=async()=>this.listToolsHandler?{tools:(await this.listToolsHandler()).map(n=>n.name)}:{tools:[]},this.app.ontoolresult=t=>{let n=this.extractToolOutput(t);this.currentToolOutput=n;let o=this.getToolNameFromContext(),s=o?{[o]:n}:n;for(let a of this.toolResultHandlers)a(s);},this.app.ontoolcancelled=t=>{let n=t.reason;for(let o of this.toolCancelledHandlers)o(n);},this.app.onteardown=async t=>{let n=t.reason;for(let o of this.teardownHandlers)o(n);return {}},await this.app.connect();let e=this.app.getHostContext();e&&(this.context=this.mapHostContext(e),this.currentToolMeta=this.extractToolMeta(e)),this.connected=true;}isConnected(){return this.connected}mapHostContext(e){let t=e??{},n=this.createDefaultContext(),o=n.theme;(t.theme==="dark"||t.theme==="light")&&(o=t.theme);let s=t.displayMode==="fullscreen"||t.displayMode==="pip"||t.displayMode==="inline"?t.displayMode:n.displayMode,a=Array.isArray(t.availableDisplayModes)?t.availableDisplayModes.filter(c=>typeof c=="string"):n.availableDisplayModes,p=(c=>c!==null&&typeof c=="object"&&!Array.isArray(c))(t.viewport)?{...n.viewport,...t.viewport}:n.viewport,u=typeof t.locale=="string"?t.locale:n.locale,f=typeof t.timeZone=="string"?t.timeZone:n.timeZone,v=n.platform;return {...n,theme:o,displayMode:s,availableDisplayModes:a,viewport:p,locale:u,timeZone:f,platform:v,userAgent:typeof t.userAgent=="string"?t.userAgent:n.userAgent,deviceCapabilities:t.deviceCapabilities,safeAreaInsets:t.safeAreaInsets,styles:t.styles,view:typeof t.view=="string"?t.view:n.view}}extractToolMeta(e){if(e===null||typeof e!="object")return;let t=e;if(!(!t.toolInfo||typeof t.toolInfo!="object"))return {toolInfo:t.toolInfo}}getToolNameFromContext(){if(!this.app)return;let e=this.app.getHostContext();return e?e.toolInfo?.tool?.name:void 0}extractToolOutput(e){let t=e.structuredContent,n=e._meta,o=t&&typeof t=="object"&&!Array.isArray(t)?t:{};if(n&&typeof n=="object"&&!Array.isArray(n))return {...o,_meta:n};if(Object.keys(o).length===0){let s=e.content;if(Array.isArray(s)&&s.length>0){let a=s[0];if(a?.type==="text"&&typeof a.text=="string")try{let l=JSON.parse(a.text);if(l!==null&&typeof l=="object"&&!Array.isArray(l))return l}catch{}}}return o}async callTool(e,t){if(!this.app)throw new Error("MCP Apps adapter not connected");let n=await this.app.callServerTool({name:e,arguments:t});return this.extractToolOutput(n)}async sendMessage(e){if(!this.app)throw new Error("MCP Apps adapter not connected");if(e.type!=="text")throw new Error(`Unsupported message content type: ${e.type}`);await this.app.sendMessage({role:"user",content:[{type:"text",text:e.text}]});}async openLink(e){if(!this.app)throw new Error("MCP Apps adapter not connected");await this.app.openLink({url:e});}async requestDisplayMode(e){if(!this.app)throw new Error("MCP Apps adapter not connected");return await this.app.requestDisplayMode({mode:e})}requestClose(){}getState(){return null}setState(e){}async readResource(e){if(!this.app)throw new Error("MCP Apps adapter not connected");let n=await this.app.request.bind(this.app)({method:"resources/read",params:{uri:e}},z);return {contents:(Array.isArray(n.contents)?n.contents:[]).map(o=>{let s={uri:o.uri,mimeType:o.mimeType??"application/octet-stream"};if("text"in o&&typeof o.text=="string")return {...s,text:o.text};if("blob"in o&&typeof o.blob=="string"){let a=Uint8Array.from(atob(o.blob),l=>l.charCodeAt(0));return {...s,blob:a}}return s})}}log(e,t){if(this.app){let s={level:["debug","info","notice","warning","error","critical","alert","emergency"].includes(e)?e:"info",data:t,logger:"@mcp-apps-kit/ui"};try{this.app.sendLog(s);return}catch{}}({debug:console.debug,info:console.info,warning:console.warn,error:console.error}[e]??console.log)("[MCP Apps]",t);}onToolResult(e){return this.toolResultHandlers.add(e),()=>this.toolResultHandlers.delete(e)}onToolInput(e){return this.toolInputHandlers.add(e),()=>this.toolInputHandlers.delete(e)}onToolCancelled(e){return this.toolCancelledHandlers.add(e),()=>this.toolCancelledHandlers.delete(e)}onHostContextChange(e){return this.hostContextHandlers.add(e),()=>this.hostContextHandlers.delete(e)}onTeardown(e){return this.teardownHandlers.add(e),()=>this.teardownHandlers.delete(e)}getHostContext(){return this.context}getToolInput(){return this.currentToolInput}getToolOutput(){return this.currentToolOutput}getToolMeta(){return this.currentToolMeta}getHostCapabilities(){if(!this.app)return;let e=this.app.getHostCapabilities();if(!e)return;let t=e,o=this.app.getHostContext()?.availableDisplayModes;return {logging:t.logging,openLinks:t.openLinks,serverResources:t.serverResources,serverTools:t.serverTools,experimental:t.experimental,theming:{themes:["light","dark"]},displayModes:o?{modes:o}:void 0,statePersistence:{persistent:false},sizeNotifications:{},partialToolInput:{},appTools:{listChanged:false}}}getHostVersion(){if(!this.app)return;let e=this.app.getHostVersion();if(e)return {name:e.name,version:e.version}}async sendLog(e,t){if(!this.app)throw new d(g.NOT_CONNECTED,"MCP Apps adapter not connected");await this.app.sendLog({level:e,data:t,logger:"@mcp-apps-kit/ui"});}async sendLogs(e){if(!this.app)throw new d(g.NOT_CONNECTED,"MCP Apps adapter not connected");let t={debug:"debug",info:"info",warn:"warning",error:"error"},n=0;for(let o of e)try{await this.app.sendLog({level:t[o.level]??"info",data:o.data??o.message,logger:o.source??"@mcp-apps-kit/ui"}),n++;}catch{}return {processed:n}}async sendSizeChanged(e){if(!this.app)throw new d(g.NOT_CONNECTED,"MCP Apps adapter not connected");await this.app.sendSizeChanged({width:e.width,height:e.height});}onToolInputPartial(e){return this.toolInputPartialHandlers.add(e),()=>this.toolInputPartialHandlers.delete(e)}setCallToolHandler(e){this.callToolHandler=e;}setListToolsHandler(e){this.listToolsHandler=e;}};var w=class{constructor(){this.connected=false;this.state=null;this.toolResultHandlers=new Set;this.toolInputHandlers=new Set;this.toolCancelledHandlers=new Set;this.hostContextHandlers=new Set;this.teardownHandlers=new Set;this.logTransport="api";this.apiTransportFailed=false;this.toolTransportFailed=false;this.context=this.createDefaultContext();}configureLogging(e){e.transport!==void 0&&(this.logTransport=e.transport,this.apiTransportFailed=false,this.toolTransportFailed=false),e.apiEndpoint!==void 0&&(this.logApiEndpoint=e.apiEndpoint,this.apiTransportFailed=false);}createDefaultContext(){let e=typeof window<"u";return {theme:"light",displayMode:"inline",availableDisplayModes:["inline","fullscreen","pip"],viewport:{width:e?window.innerWidth:800,height:e?window.innerHeight:600},locale:e?navigator.language:"en-US",timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,platform:"web",deviceCapabilities:{touch:e?"ontouchstart"in window:false,hover:true}}}isSetGlobalsMessage(e){return e==="openai:set_globals"||typeof e=="object"&&e!==null&&"type"in e&&e.type==="openai:set_globals"||typeof e=="object"&&e!==null&&"message"in e&&e.message==="openai:set_globals"}readContextFromSDK(){let e=this.getOpenAI();if(!e)return;let t=typeof window<"u";if(typeof e.theme=="string"&&(this.context.theme=e.theme),typeof e.displayMode=="string"&&(this.context.displayMode=e.displayMode),typeof e.locale=="string"&&(this.context.locale=e.locale),typeof e.userAgent=="string"&&Object.assign(this.context,{userAgent:e.userAgent}),typeof e.view=="string"&&(this.context.view=e.view),e.safeArea&&typeof e.safeArea=="object"){let n=e.safeArea;this.context.safeAreaInsets={top:typeof n.top=="number"?n.top:0,right:typeof n.right=="number"?n.right:0,bottom:typeof n.bottom=="number"?n.bottom:0,left:typeof n.left=="number"?n.left:0};}typeof e.maxHeight=="number"&&(this.context.viewport={width:t?window.innerWidth:800,height:e.maxHeight}),i.debug("[OpenAI Adapter] Read context from SDK",this.context);}notifyContextChange(){i.debug(`[OpenAI Adapter] Notifying ${String(this.hostContextHandlers.size)} context change handlers`);let e={...this.context};for(let t of this.hostContextHandlers)t(e);}getOpenAI(){return typeof window<"u"&&"openai"in window?window.openai:null}getToolNameFromSDK(){let e=this.getOpenAI();if(e){if(e.toolResponseMetadata&&typeof e.toolResponseMetadata=="object"){let t=e.toolResponseMetadata;if(typeof t.toolName=="string")return t.toolName}if(typeof e.toolName=="string")return e.toolName}}async connect(){await this.waitForOpenAI();let e=this.getOpenAI();if(e){i.debug("[OpenAI Adapter] Available SDK methods",Object.keys(e)),this.readContextFromSDK();let t=this.getToolNameFromSDK();if(typeof e.getToolOutput=="function"?(this.currentToolOutput=e.getToolOutput(),i.debug("[OpenAI Adapter] Got tool output from SDK")):e.toolOutput?(this.currentToolOutput=e.toolOutput,i.debug("[OpenAI Adapter] Got tool output from SDK property")):e.result&&(this.currentToolOutput=e.result,i.debug("[OpenAI Adapter] Got result from SDK")),this.currentToolOutput&&Object.keys(this.currentToolOutput).length>0){let n=t?{[t]:this.currentToolOutput}:this.currentToolOutput;for(let o of this.toolResultHandlers)o(n);}typeof e.getToolInput=="function"?this.currentToolInput=e.getToolInput():e.toolInput?this.currentToolInput=e.toolInput:e.input&&(this.currentToolInput=e.input),typeof e.init=="function"&&await e.init();}this.setupGlobalsListener(),this.connected=true;}setupGlobalsListener(){typeof window>"u"||(this.setGlobalsHandler=e=>{let n=e.detail;if(!n){this.readContextFromSDK(),this.checkForToolOutputUpdate();return}let o=n.globals??n,s=this.context.theme,a=this.context.locale,l=this.context.displayMode,p=this.currentToolOutput;if(o.theme!==void 0&&(this.context.theme=o.theme),o.locale!==void 0&&(this.context.locale=o.locale),o.displayMode!==void 0&&(this.context.displayMode=o.displayMode),(this.context.theme!==s||this.context.locale!==a||this.context.displayMode!==l)&&(i.debug("[OpenAI Adapter] Context changed, notifying handlers"),this.notifyContextChange()),o.toolOutput!==void 0&&o.toolOutput!==null){let u=o.toolOutput;if(Object.keys(u).length>0&&u!==p){i.debug("[OpenAI Adapter] Got toolOutput from set_globals event",u),this.currentToolOutput=u;let f;o.toolResponseMetadata&&typeof o.toolResponseMetadata=="object"&&o.toolResponseMetadata.toolName?f=o.toolResponseMetadata.toolName:f=this.getToolNameFromSDK();let v=f?{[f]:u}:u;for(let c of this.toolResultHandlers)c(v);}}o.toolInput!==void 0&&(this.currentToolInput=o.toolInput);},window.addEventListener("openai:set_globals",this.setGlobalsHandler),this.globalsHandler=e=>{this.isSetGlobalsMessage(e.data)&&(i.debug("[OpenAI Adapter] Received set_globals via postMessage (legacy)"),this.readContextFromSDK(),this.checkForToolOutputUpdate());},window.addEventListener("message",this.globalsHandler));}checkForToolOutputUpdate(){let e=this.getOpenAI();if(!e)return;let t;if(e.toolOutput&&(t=e.toolOutput),t&&Object.keys(t).length>0&&t!==this.currentToolOutput){i.debug("[OpenAI Adapter] toolOutput updated",t),this.currentToolOutput=t;let n=this.getToolNameFromSDK(),o=n?{[n]:t}:t;for(let s of this.toolResultHandlers)s(o);}}async waitForOpenAI(e=5e3){if(this.getOpenAI()){i.debug("[OpenAI Adapter] window.openai already available");return}return i.debug("[OpenAI Adapter] Waiting for window.openai..."),new Promise(t=>{let n=Date.now(),o=false,s=()=>{o||(o=true,window.removeEventListener("message",l),t());},a=()=>{if(!o){if(this.getOpenAI()){i.debug("[OpenAI Adapter] window.openai found via polling"),s();return}if(Date.now()-n>e){i.warn("[OpenAI Adapter] window.openai not found after timeout, proceeding anyway"),s();return}setTimeout(a,50);}},l=p=>{this.isSetGlobalsMessage(p.data)&&(i.debug("[OpenAI Adapter] Received set_globals message"),setTimeout(()=>{this.getOpenAI()?(i.debug("[OpenAI Adapter] window.openai available after set_globals"),s()):i.debug("[OpenAI Adapter] window.openai still not available after set_globals, continuing poll");},50));};window.addEventListener("message",l),a();})}isConnected(){return this.connected}async callTool(e,t){let n=this.getOpenAI();if(n&&typeof n.callTool=="function")return n.callTool(e,t);throw new Error("OpenAI SDK not available")}async sendMessage(e){if(e.type!=="text")throw new Error(`Unsupported message content type: ${e.type}`);let t=this.getOpenAI();t&&typeof t.sendFollowUpMessage=="function"&&await t.sendFollowUpMessage({prompt:e.text});}async openLink(e){let t=this.getOpenAI();t&&typeof t.openExternal=="function"?await t.openExternal({href:e}):window.open(e,"_blank");}async requestDisplayMode(e){let t=this.getOpenAI();if(t&&typeof t.requestDisplayMode=="function"){let n=await t.requestDisplayMode({mode:e});return this.context={...this.context,displayMode:n.mode},this.notifyContextChange(),n}return this.context={...this.context,displayMode:e},this.notifyContextChange(),{mode:e}}requestClose(){let e=this.getOpenAI();e&&typeof e.close=="function"&&e.close();}getState(){return this.state}setState(e){this.state=e;let t=this.getOpenAI();t&&typeof t.setWidgetState=="function"&&t.setWidgetState(e);}async uploadFile(e){let t=this.getOpenAI();if(t&&typeof t.uploadFile=="function")return t.uploadFile(e);throw new Error("File upload not supported")}async getFileDownloadUrl(e){let t=this.getOpenAI();if(t&&typeof t.getFileDownloadUrl=="function")return t.getFileDownloadUrl(e);throw new Error("File download not supported")}async readResource(e){let t=this.getOpenAI();return t&&typeof t.readResource=="function"?t.readResource(e):{contents:[]}}log(e,t){({debug:console.debug,info:console.info,warning:console.warn,error:console.error}[e]??console.log)("[ChatGPT Apps]",t);}onToolResult(e){return this.toolResultHandlers.add(e),()=>this.toolResultHandlers.delete(e)}onToolInput(e){return this.toolInputHandlers.add(e),()=>this.toolInputHandlers.delete(e)}onToolCancelled(e){return this.toolCancelledHandlers.add(e),()=>this.toolCancelledHandlers.delete(e)}onHostContextChange(e){return this.hostContextHandlers.add(e),i.debug(`[OpenAI Adapter] Host context handler added, total: ${String(this.hostContextHandlers.size)}`),()=>{this.hostContextHandlers.delete(e),i.debug(`[OpenAI Adapter] Host context handler removed, total: ${String(this.hostContextHandlers.size)}`);}}onTeardown(e){return this.teardownHandlers.add(e),()=>this.teardownHandlers.delete(e)}getHostContext(){return this.context}getToolInput(){return this.currentToolInput}getToolOutput(){if(!this.currentToolOutput)return;let e=this.getToolNameFromSDK();return e?{[e]:this.currentToolOutput}:this.currentToolOutput}getToolMeta(){return this.currentToolMeta}getHostCapabilities(){let e=this.getOpenAI(),t=e&&typeof e.uploadFile=="function",n=this.context.safeAreaInsets!==void 0,o=this.context.view!==void 0;return {openLinks:{},logging:{},theming:{themes:["light","dark"]},displayModes:{modes:["inline","fullscreen","pip"]},statePersistence:{persistent:false},fileUpload:t?{}:void 0,safeAreaInsets:n?{}:void 0,views:o?{}:void 0}}getHostVersion(){}async sendLog(e,t){let o={level:{debug:"debug",info:"info",notice:"info",warning:"warn",error:"error",critical:"error",alert:"error",emergency:"error"}[e],message:typeof t=="string"?t:JSON.stringify(t),data:typeof t=="string"?void 0:t,timestamp:new Date().toISOString(),source:"openai-adapter"};await this.sendLogs([o]);}async sendLogs(e){if(this.logTransport==="api"&&this.logApiEndpoint&&!this.apiTransportFailed)try{let t=await fetch(this.logApiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:e})});if(!t.ok)throw new Error(`API request failed with status ${String(t.status)}`);return await t.json()}catch(t){this.apiTransportFailed=true,i.info("[OpenAI Adapter] API log transport failed, trying fallback",{error:t instanceof Error?t.message:t});}if((this.logTransport==="tool"||this.apiTransportFailed)&&!this.toolTransportFailed&&this.connected)try{return await this.callTool("log_debug",{entries:e})}catch(t){this.toolTransportFailed=true,i.info("[OpenAI Adapter] Tool log transport failed, falling back to console",{error:t instanceof Error?t.message:t});}for(let t of e)this.log(t.level==="warn"?"warning":t.level,t.data??t.message);return {processed:e.length}}async sendSizeChanged(e){let t=this.getOpenAI();t&&typeof t.notifyIntrinsicHeight=="function"&&t.notifyIntrinsicHeight(e.height);}onToolInputPartial(e){return this.log("debug","onToolInputPartial is not supported on ChatGPT"),()=>{}}setCallToolHandler(e){this.log("debug","setCallToolHandler is not supported on ChatGPT");}setListToolsHandler(e){this.log("debug","setListToolsHandler is not supported on ChatGPT");}};function C(){if(typeof window>"u")return "mock";if("openai"in window)return "openai";let r=window.location.href,e=document.referrer;return r.includes("/api/apps/chatgpt/")||r.includes("chatgpt")||r.includes("sandbox-proxy")||r.includes("widget-content")||e.includes("chatgpt")||e.includes("openai.com")?"openai":window.parent!==window?"mcp":"mock"}function V(r){return new Proxy({},{get(e,t){if(typeof t!="string"||!t.startsWith("call"))return;let n=t.slice(4);if(n.length===0)return;let o=n.charAt(0).toLowerCase()+n.slice(1);return s=>r(o,s)},has(e,t){return typeof t=="string"&&t.startsWith("call")&&t.length>4},ownKeys(){return []},getOwnPropertyDescriptor(e,t){if(typeof t=="string"&&t.startsWith("call")&&t.length>4)return {configurable:true,enumerable:true,writable:false}}})}function b(r){async function e(o,s){return await r.callTool(o,s)}let t=V(e);return {callTool:e,tools:t,async sendMessage(o){await r.sendMessage(o);},async sendFollowUpMessage(o){await r.sendMessage({type:"text",text:o});},async openLink(o){await r.openLink(o);},async requestDisplayMode(o){return r.requestDisplayMode(o)},requestClose(){r.requestClose();},getState(){return r.getState()},setState(o){r.setState(o);},...r.uploadFile&&{uploadFile:r.uploadFile.bind(r)},...r.getFileDownloadUrl&&{getFileDownloadUrl:r.getFileDownloadUrl.bind(r)},async readResource(o){return r.readResource(o)},log(o,s){r.log(o,s);},onToolResult(o){return r.onToolResult(o)},onToolInput(o){return r.onToolInput(o)},onToolCancelled(o){return r.onToolCancelled(o)},onHostContextChange(o){return r.onHostContextChange(o)},onTeardown(o){return r.onTeardown(o)},onToolInputPartial(o){return r.onToolInputPartial(o)},getHostCapabilities(){return r.getHostCapabilities()},getHostVersion(){return r.getHostVersion()},async sendLog(o,s){return r.sendLog(o,s)},async sendSizeChanged(o){return r.sendSizeChanged(o)},setupSizeChangedNotifications(){if(typeof window>"u"||typeof ResizeObserver>"u")return ()=>{};let o=new ResizeObserver(s=>{for(let a of s){let{width:l,height:p}=a.contentRect;r.sendSizeChanged({width:Math.round(l),height:Math.round(p)});}});return o.observe(document.body),()=>{o.disconnect();}},setCallToolHandler(o){r.setCallToolHandler(o);},setListToolsHandler(o){r.setListToolsHandler(o);},get hostContext(){return r.getHostContext()},get toolInput(){return r.getToolInput()},get toolOutput(){return r.getToolOutput()},get toolMeta(){return r.getToolMeta()}}}function $(r,e){switch(r){case "mcp":return new m(e?.mcp);case "openai":return new w;case "mock":return new h;default:throw new Error(`Unknown adapter type: ${r}`)}}async function ge(r){let e=r?.forceAdapter??C();if(!["mcp","openai","mock"].includes(e))throw new Error(`Unknown adapter type: ${e}`);let t=r?.autoResize!==void 0?{mcp:{autoResize:r.autoResize}}:void 0,n=$(e,t);return await n.connect(),i.setAdapter(n),b(n)}export{y as ClientDebugLogger,D as LATEST_PROTOCOL_VERSION,m as McpAdapter,h as MockAdapter,w as OpenAIAdapter,_ as RESOURCE_MIME_TYPE,F as RESOURCE_URI_META_KEY,d as UIError,g as UIErrorCode,x as applyDocumentTheme,O as applyHostFonts,k as applyHostStyleVariables,R as clearHostStyleVariables,i as clientDebugLogger,b as createAppsClient,ge as createClient,C as detectProtocol,H as getDocumentTheme,N as getMcpServerBaseUrl,L as getMcpServerConfig,A as removeHostFonts,E as safeSerialize,P as safeStringify,S as shouldLog};//# sourceMappingURL=index.js.map | ||
| import {App}from'@modelcontextprotocol/ext-apps';var _="2025-11-05",F="text/html;profile=mcp-app",N="ui/resourceUri";function H(r){if(typeof document>"u")return;let e=r==="os"?typeof window<"u"&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":r;document.documentElement.classList.remove("light","dark"),document.documentElement.classList.add(e),document.documentElement.setAttribute("data-theme",e);}function k(){if(typeof document>"u")return "light";let r=document.documentElement.getAttribute("data-theme");return r==="dark"||r==="light"?r:document.documentElement.classList.contains("dark")?"dark":"light"}var T="mcp-apps-host-fonts";function A(r){if(typeof document>"u")return;let e=document.documentElement;for(let[t,o]of Object.entries(r)){let n=t.startsWith("--")?t:`--${t}`;e.style.setProperty(n,o);}}function O(r){if(typeof document>"u")return;let e=document.getElementById(T);e||(e=document.createElement("style"),e.id=T,document.head.appendChild(e)),e.textContent=r;}function R(){if(typeof document>"u")return;let r=document.getElementById(T);r&&r.remove();}function I(r){if(typeof document>"u")return;let e=document.documentElement;for(let t of Object.keys(r)){let o=t.startsWith("--")?t:`--${t}`;e.style.removeProperty(o);}}var p={CONNECTION_FAILED:"CONNECTION_FAILED",CONNECTION_TIMEOUT:"CONNECTION_TIMEOUT",NOT_CONNECTED:"NOT_CONNECTED",PROTOCOL_ERROR:"PROTOCOL_ERROR",UNSUPPORTED_OPERATION:"UNSUPPORTED_OPERATION",INVALID_PARAMS:"INVALID_PARAMS",TOOL_CALL_FAILED:"TOOL_CALL_FAILED",TOOL_NOT_FOUND:"TOOL_NOT_FOUND",STATE_ERROR:"STATE_ERROR",UNKNOWN_ERROR:"UNKNOWN_ERROR"},d=class extends Error{constructor(t,o,n,s){super(o);this.code=t;this.details=n;this.cause=s;this.name="UIError";}formatMessage(){let t=`[${this.code}] ${this.message}`;return this.details&&(t+=` ${JSON.stringify(this.details)}`),t}};var M={debug:0,info:1,warn:2,error:3};function S(r,e){return M[r]>=M[e]}function P(){let r=new WeakSet;return (e,t)=>{if(typeof t=="object"&&t!==null){if(r.has(t))return "[Circular]";r.add(t);}return t}}function E(r){if(r==null||typeof r=="string"||typeof r=="number"||typeof r=="boolean")return r;if(r instanceof Error)return {name:r.name,message:r.message,stack:r.stack};try{return JSON.stringify(r),r}catch{try{let e=JSON.stringify(r,P());return JSON.parse(e)}catch{return "[Unserializable]"}}}function D(r){if(r===void 0)return "undefined";if(r===null)return "null";if(typeof r=="string")return r;if(r instanceof Error)return `${r.name}: ${r.message}`;try{return JSON.stringify(r,P())}catch{return "[Unstringifiable]"}}var y=class{constructor(e={}){this.adapter=null;this.buffer=[];this.flushTimer=null;this.isFlushing=false;this.mcpTransportFailed=false;this.apiTransportFailed=false;this.config={enabled:e.enabled??false,level:e.level??"info",batchSize:e.batchSize??10,maxBufferSize:e.maxBufferSize??100,flushIntervalMs:e.flushIntervalMs??5e3,source:e.source??"mcp-apps-ui",transport:e.transport??"tool",apiEndpoint:e.apiEndpoint};}setAdapter(e){this.adapter=e,this.mcpTransportFailed=false,this.apiTransportFailed=false;}configure(e){e.enabled!==void 0&&(this.config.enabled=e.enabled),e.level!==void 0&&(this.config.level=e.level),e.batchSize!==void 0&&(this.config.batchSize=e.batchSize),e.maxBufferSize!==void 0&&(this.config.maxBufferSize=e.maxBufferSize),e.flushIntervalMs!==void 0&&(this.config.flushIntervalMs=e.flushIntervalMs,this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),this.scheduleFlush()),e.source!==void 0&&(this.config.source=e.source),e.transport!==void 0&&(this.config.transport=e.transport,this.mcpTransportFailed=false,this.apiTransportFailed=false),e.apiEndpoint!==void 0&&(this.config.apiEndpoint=e.apiEndpoint,this.apiTransportFailed=false);}canUseToolTransport(){return this.config.enabled&&this.config.transport==="tool"&&!this.mcpTransportFailed&&this.adapter?.isConnected()===true}canUseApiTransport(){return this.config.enabled&&this.config.transport==="api"&&!this.apiTransportFailed&&!!this.config.apiEndpoint}canUseRemoteTransport(){return this.canUseToolTransport()||this.canUseApiTransport()}createEntry(e,t,o){return {level:e,message:t,data:o!==void 0?E(o):void 0,timestamp:new Date().toISOString(),source:this.config.source}}scheduleFlush(){this.flushTimer||this.buffer.length===0||(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush();},this.config.flushIntervalMs));}async flushToApi(e){if(!this.config.apiEndpoint)throw new Error("API endpoint not configured");let t=await fetch(this.config.apiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:e})});if(!t.ok)throw new Error(`API request failed with status ${String(t.status)}`)}async flushToTool(e){if(!this.adapter)throw new Error("Adapter not connected");await this.adapter.callTool("log_debug",{entries:e});}async flush(){if(this.isFlushing||this.buffer.length===0)return;if(this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),!this.canUseRemoteTransport()){this.buffer=[];return}this.isFlushing=true;let e=[...this.buffer];try{this.canUseApiTransport()?await this.flushToApi(e):this.canUseToolTransport()&&await this.flushToTool(e),this.buffer=this.buffer.slice(e.length);}catch(t){this.buffer=this.buffer.slice(e.length);let o=t instanceof Error?t.message:String(t);this.config.transport==="api"&&!this.apiTransportFailed?(this.apiTransportFailed=true,console.warn(`[ClientDebugLogger] API log transport failed: ${o}. Will only use console`)):this.config.transport==="tool"&&!this.mcpTransportFailed&&(this.mcpTransportFailed=true,console.warn(`[ClientDebugLogger] MCP log transport failed: ${o}. Will only use console`));}finally{this.isFlushing=false,this.buffer.length>0&&this.scheduleFlush();}}outputToConsole(e){let t=`[${e.timestamp}] [${e.level.toUpperCase()}]`,o=e.data!==void 0?`${e.message} ${D(e.data)}`:e.message,n=`${t} ${o}`;try{switch(e.level){case "debug":console.debug(n);break;case "info":console.info(n);break;case "warn":console.warn(n);break;case "error":console.error(n);break}}catch{}}addToBuffer(e){for(;this.buffer.length>=this.config.maxBufferSize;)this.buffer.shift();if(this.buffer.push(e),e.level==="error"){this.flush();return}if(this.buffer.length>=this.config.batchSize){this.flush();return}this.scheduleFlush();}log(e,t,o){if(!S(e,this.config.level))return;let n=this.createEntry(e,t,o);this.outputToConsole(n),this.canUseRemoteTransport()&&this.addToBuffer(n);}debug(e,t){this.log("debug",e,t);}info(e,t){this.log("info",e,t);}warn(e,t){this.log("warn",e,t);}error(e,t){this.log("error",e,t);}destroy(){this.buffer=[],this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null),this.adapter=null;}},i=new y;function L(){return typeof window<"u"&&window.__MCP_SERVER_CONFIG__?window.__MCP_SERVER_CONFIG__:typeof __MCP_SERVER_CONFIG__<"u"&&__MCP_SERVER_CONFIG__?__MCP_SERVER_CONFIG__:{}}function U(r=""){let e=L();return e.baseUrl?e.baseUrl:typeof window<"u"&&(window.location.protocol==="http:"||window.location.protocol==="https:")?window.location.origin:r}var h=class{constructor(){this.connected=false;this.state=null;this.toolResultHandlers=new Set;this.toolInputHandlers=new Set;this.toolInputPartialHandlers=new Set;this.toolCancelledHandlers=new Set;this.hostContextHandlers=new Set;this.teardownHandlers=new Set;this.mockHostCapabilities={logging:{},openLinks:{},theming:{themes:["light","dark","os"]},displayModes:{modes:["inline","fullscreen","pip","panel"]},statePersistence:{persistent:true},serverTools:{listChanged:false},serverResources:{listChanged:false},sizeNotifications:{},partialToolInput:{},appTools:{listChanged:false},fileUpload:{},safeAreaInsets:{},views:{}};this.mockHostVersion={name:"MockHost",version:"1.0.0"};this.context=this.createDefaultContext();}createDefaultContext(){let e=typeof window<"u";return {theme:"light",displayMode:"inline",availableDisplayModes:["inline","fullscreen","pip"],viewport:{width:e?window.innerWidth:800,height:e?window.innerHeight:600},locale:e?navigator.language:"en-US",timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,platform:"web",deviceCapabilities:{touch:e?"ontouchstart"in window:false,hover:true}}}async connect(){this.connected=true,console.log("[MockAdapter] Connected");}isConnected(){return this.connected}async callTool(e,t){console.log(`[MockAdapter] callTool("${e}",`,t,")");let o={_mock:true,tool:e,args:t,timestamp:Date.now()};return this.currentToolOutput=o,o}async sendMessage(e){console.log("[MockAdapter] sendMessage:",e);}async updateModelContext(e){this.lastModelContext=e,console.log("[MockAdapter] updateModelContext:",e);}getLastModelContext(){return this.lastModelContext}async openLink(e){console.log(`[MockAdapter] openLink("${e}")`);}async requestDisplayMode(e){return console.log(`[MockAdapter] requestDisplayMode("${e}")`),this.context={...this.context,displayMode:e},this.notifyHostContextChange(),{mode:e}}requestClose(){console.log("[MockAdapter] requestClose()");}getState(){return this.state}setState(e){this.state=e,console.log("[MockAdapter] setState:",e);}async readResource(e){return console.log(`[MockAdapter] readResource("${e}")`),{contents:[]}}log(e,t){({debug:console.debug,info:console.info,warning:console.warn,error:console.error}[e]??console.log)("[MockAdapter]",t);}onToolResult(e){return this.toolResultHandlers.add(e),()=>this.toolResultHandlers.delete(e)}onToolInput(e){return this.toolInputHandlers.add(e),()=>this.toolInputHandlers.delete(e)}onToolCancelled(e){return this.toolCancelledHandlers.add(e),()=>this.toolCancelledHandlers.delete(e)}onHostContextChange(e){return this.hostContextHandlers.add(e),()=>this.hostContextHandlers.delete(e)}onTeardown(e){return this.teardownHandlers.add(e),()=>this.teardownHandlers.delete(e)}getHostContext(){return this.context}getToolInput(){return this.currentToolInput}getToolOutput(){return this.currentToolOutput}getToolMeta(){return this.currentToolMeta}emitToolResult(e){this.currentToolOutput=e;for(let t of this.toolResultHandlers)t(e);}emitToolInput(e){this.currentToolInput=e;for(let t of this.toolInputHandlers)t(e);}setHostContext(e){this.context={...this.context,...e},this.notifyHostContextChange();}emitContextChange(e){this.context=e,this.notifyHostContextChange();}setToolInput(e){this.currentToolInput=e;}emitToolCancelled(e){for(let t of this.toolCancelledHandlers)t(e);}emitTeardown(e){for(let t of this.teardownHandlers)t(e);}notifyHostContextChange(){for(let e of this.hostContextHandlers)e(this.context);}getHostCapabilities(){return this.mockHostCapabilities}getHostVersion(){return this.mockHostVersion}async sendLog(e,t){console.log(`[MockAdapter] sendLog(${e}):`,t);}async sendLogs(e){for(let t of e)console.log(`[MockAdapter] sendLogs(${t.level}):`,t.message,t.data);return {processed:e.length}}async sendSizeChanged(e){console.log("[MockAdapter] sendSizeChanged:",e);}onToolInputPartial(e){return this.toolInputPartialHandlers.add(e),()=>this.toolInputPartialHandlers.delete(e)}setCallToolHandler(e){this.callToolHandler=e,console.log("[MockAdapter] setCallToolHandler: handler registered");}setListToolsHandler(e){this.listToolsHandler=e,console.log("[MockAdapter] setListToolsHandler: handler registered");}emitToolInputPartial(e){for(let t of this.toolInputPartialHandlers)t(e);}setMockHostCapabilities(e){this.mockHostCapabilities={...this.mockHostCapabilities,...e};}setMockHostVersion(e){this.mockHostVersion=e;}async simulateHostToolCall(e,t){if(!this.callToolHandler)throw new d(p.TOOL_NOT_FOUND,"No call tool handler registered");return this.callToolHandler(e,t)}async simulateHostListTools(){return this.listToolsHandler?this.listToolsHandler():{tools:[]}}};var V={parse:r=>r},m=class{constructor(e){this.connected=false;this.toolResultHandlers=new Set;this.toolInputHandlers=new Set;this.toolInputPartialHandlers=new Set;this.toolCancelledHandlers=new Set;this.hostContextHandlers=new Set;this.teardownHandlers=new Set;this.context=this.createDefaultContext(),this.autoResize=e?.autoResize??true;}createDefaultContext(){let e=typeof window<"u";return {theme:"light",displayMode:"inline",availableDisplayModes:["inline","fullscreen"],viewport:{width:e?window.innerWidth:800,height:e?window.innerHeight:600},locale:e?navigator.language:"en-US",timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,platform:"desktop"}}async connect(){if(this.connected)return;if(typeof window>"u"){this.connected=true;return}this.app=new App({name:"@mcp-apps-kit/ui",version:"0.0.0"},{tools:{}},{autoResize:this.autoResize}),this.app.onerror=t=>{this.log("error",t);},this.app.onhostcontextchanged=t=>{let o=t.hostContext??t;this.context=this.mapHostContext(o),this.currentToolMeta=this.extractToolMeta(o);for(let n of this.hostContextHandlers)n(this.context);},this.app.ontoolinput=t=>{let o=t.arguments;if(o){this.currentToolInput=o;for(let n of this.toolInputHandlers)n(o);}},this.app.ontoolinputpartial=t=>{let o=t.arguments;if(o)for(let n of this.toolInputPartialHandlers)n(o);},this.app.oncalltool=async t=>{let{name:o,arguments:n}=t;try{if(this.callToolHandler){let s=await this.callToolHandler(o,n??{});return {content:[{type:"text",text:JSON.stringify(s)}]}}return {content:[{type:"text",text:`No handler registered for tool: ${o}`}],isError:!0}}catch(s){return {content:[{type:"text",text:s instanceof Error?s.message:String(s)}],isError:true}}},this.app.onlisttools=async()=>this.listToolsHandler?{tools:(await this.listToolsHandler()).map(o=>o.name)}:{tools:[]},this.app.ontoolresult=t=>{let o=this.extractToolOutput(t);this.currentToolOutput=o;let n=this.getToolNameFromContext(),s=n?{[n]:o}:o;for(let a of this.toolResultHandlers)a(s);},this.app.ontoolcancelled=t=>{let o=t.reason;for(let n of this.toolCancelledHandlers)n(o);},this.app.onteardown=async t=>{let o=t.reason;for(let n of this.teardownHandlers)n(o);return {}},await this.app.connect();let e=this.app.getHostContext();e&&(this.context=this.mapHostContext(e),this.currentToolMeta=this.extractToolMeta(e)),this.connected=true;}isConnected(){return this.connected}mapHostContext(e){let t=e??{},o=this.createDefaultContext(),n=o.theme;(t.theme==="dark"||t.theme==="light")&&(n=t.theme);let s=t.displayMode==="fullscreen"||t.displayMode==="pip"||t.displayMode==="inline"?t.displayMode:o.displayMode,a=Array.isArray(t.availableDisplayModes)?t.availableDisplayModes.filter(f=>typeof f=="string"):o.availableDisplayModes,l=f=>f!==null&&typeof f=="object"&&!Array.isArray(f),c=l(t.containerDimensions)?t.containerDimensions:void 0,u=o.viewport;c?u=this.deriveViewportFromContainerDimensions(c,o.viewport):l(t.viewport)&&(u={...o.viewport,...t.viewport});let g=typeof t.locale=="string"?t.locale:o.locale,v=typeof t.timeZone=="string"?t.timeZone:o.timeZone,C=o.platform;return {...o,theme:n,displayMode:s,availableDisplayModes:a,viewport:u,containerDimensions:c,locale:g,timeZone:v,platform:C,userAgent:typeof t.userAgent=="string"?t.userAgent:o.userAgent,deviceCapabilities:t.deviceCapabilities,safeAreaInsets:t.safeAreaInsets,styles:t.styles,view:typeof t.view=="string"?t.view:o.view}}deriveViewportFromContainerDimensions(e,t){let o=e;return {width:typeof o.width=="number"?o.width:t.width,height:typeof o.height=="number"?o.height:t.height,maxWidth:typeof o.maxWidth=="number"?o.maxWidth:void 0,maxHeight:typeof o.maxHeight=="number"?o.maxHeight:void 0}}extractToolMeta(e){if(e===null||typeof e!="object")return;let t=e;if(!(!t.toolInfo||typeof t.toolInfo!="object"))return {toolInfo:t.toolInfo}}getToolNameFromContext(){if(!this.app)return;let e=this.app.getHostContext();return e?e.toolInfo?.tool?.name:void 0}extractToolOutput(e){let t=e.structuredContent,o=e._meta,n=t&&typeof t=="object"&&!Array.isArray(t)?t:{};if(o&&typeof o=="object"&&!Array.isArray(o))return {...n,_meta:o};if(Object.keys(n).length===0){let s=e.content;if(Array.isArray(s)&&s.length>0){let a=s[0];if(a?.type==="text"&&typeof a.text=="string")try{let l=JSON.parse(a.text);if(l!==null&&typeof l=="object"&&!Array.isArray(l))return l}catch{}}}return n}async callTool(e,t){if(!this.app)throw new Error("MCP Apps adapter not connected");let o=await this.app.callServerTool({name:e,arguments:t});return this.extractToolOutput(o)}async sendMessage(e){if(!this.app)throw new Error("MCP Apps adapter not connected");if(e.type!=="text")throw new Error(`Unsupported message content type: ${e.type}`);await this.app.sendMessage({role:"user",content:[{type:"text",text:e.text}]});}async updateModelContext(e){if(!this.app)throw new d(p.NOT_CONNECTED,"MCP Apps adapter not connected");let t=e.content?.map(o=>{switch(o.type){case "text":if(!o.text)throw new d(p.INVALID_PARAMS,"Text content block requires 'text' field");return {type:"text",text:o.text};case "image":if(!o.data)throw new d(p.INVALID_PARAMS,"Image content block requires 'data' field");return {type:"image",data:o.data,mimeType:o.mimeType??"image/png"};case "audio":if(!o.data)throw new d(p.INVALID_PARAMS,"Audio content block requires 'data' field");return {type:"audio",data:o.data,mimeType:o.mimeType??"audio/wav"};case "resource":if(!o.uri)throw new d(p.INVALID_PARAMS,"Resource content block requires 'uri' field");return {type:"resource",resource:{uri:o.uri,text:o.description??o.uri}};case "resource_link":{if(!o.uri)throw new d(p.INVALID_PARAMS,"Resource link content block requires 'uri' field");return {type:"resource_link",uri:o.uri,name:o.name??o.uri,...o.description&&{description:o.description}}}default:{let n=o;throw new d(p.PROTOCOL_ERROR,`Unsupported content block type: ${n.type}`)}}});await this.app.updateModelContext({content:t,structuredContent:e.structuredContent});}async openLink(e){if(!this.app)throw new Error("MCP Apps adapter not connected");await this.app.openLink({url:e});}async requestDisplayMode(e){if(!this.app)throw new Error("MCP Apps adapter not connected");return await this.app.requestDisplayMode({mode:e})}requestClose(){}getState(){return null}setState(e){}async readResource(e){if(!this.app)throw new Error("MCP Apps adapter not connected");let o=await this.app.request.bind(this.app)({method:"resources/read",params:{uri:e}},V);return {contents:(Array.isArray(o.contents)?o.contents:[]).map(n=>{let s={uri:n.uri,mimeType:n.mimeType??"application/octet-stream"};if("text"in n&&typeof n.text=="string")return {...s,text:n.text};if("blob"in n&&typeof n.blob=="string"){let a=Uint8Array.from(atob(n.blob),l=>l.charCodeAt(0));return {...s,blob:a}}return s})}}log(e,t){if(this.app){let s={level:["debug","info","notice","warning","error","critical","alert","emergency"].includes(e)?e:"info",data:t,logger:"@mcp-apps-kit/ui"};try{this.app.sendLog(s);return}catch{}}({debug:console.debug,info:console.info,warning:console.warn,error:console.error}[e]??console.log)("[MCP Apps]",t);}onToolResult(e){return this.toolResultHandlers.add(e),()=>this.toolResultHandlers.delete(e)}onToolInput(e){return this.toolInputHandlers.add(e),()=>this.toolInputHandlers.delete(e)}onToolCancelled(e){return this.toolCancelledHandlers.add(e),()=>this.toolCancelledHandlers.delete(e)}onHostContextChange(e){return this.hostContextHandlers.add(e),()=>this.hostContextHandlers.delete(e)}onTeardown(e){return this.teardownHandlers.add(e),()=>this.teardownHandlers.delete(e)}getHostContext(){return this.context}getToolInput(){return this.currentToolInput}getToolOutput(){return this.currentToolOutput}getToolMeta(){return this.currentToolMeta}getHostCapabilities(){if(!this.app)return;let e=this.app.getHostCapabilities();if(!e)return;let t=e,n=this.app.getHostContext()?.availableDisplayModes;return {logging:t.logging,openLinks:t.openLinks,serverResources:t.serverResources,serverTools:t.serverTools,experimental:t.experimental,theming:{themes:["light","dark"]},displayModes:n?{modes:n}:void 0,statePersistence:{persistent:false},sizeNotifications:{},partialToolInput:{},appTools:{listChanged:false},updateModelContext:t.updateModelContext,message:t.message,sandbox:t.sandbox}}getHostVersion(){if(!this.app)return;let e=this.app.getHostVersion();if(e)return {name:e.name,version:e.version}}async sendLog(e,t){if(!this.app)throw new d(p.NOT_CONNECTED,"MCP Apps adapter not connected");await this.app.sendLog({level:e,data:t,logger:"@mcp-apps-kit/ui"});}async sendLogs(e){if(!this.app)throw new d(p.NOT_CONNECTED,"MCP Apps adapter not connected");let t={debug:"debug",info:"info",warn:"warning",error:"error"},o=0;for(let n of e)try{await this.app.sendLog({level:t[n.level]??"info",data:n.data??n.message,logger:n.source??"@mcp-apps-kit/ui"}),o++;}catch{}return {processed:o}}async sendSizeChanged(e){if(!this.app)throw new d(p.NOT_CONNECTED,"MCP Apps adapter not connected");await this.app.sendSizeChanged({width:e.width,height:e.height});}onToolInputPartial(e){return this.toolInputPartialHandlers.add(e),()=>this.toolInputPartialHandlers.delete(e)}setCallToolHandler(e){this.callToolHandler=e;}setListToolsHandler(e){this.listToolsHandler=e;}};var w=class{constructor(){this.connected=false;this.state=null;this.toolResultHandlers=new Set;this.toolInputHandlers=new Set;this.toolCancelledHandlers=new Set;this.hostContextHandlers=new Set;this.teardownHandlers=new Set;this.logTransport="api";this.apiTransportFailed=false;this.toolTransportFailed=false;this.context=this.createDefaultContext();}configureLogging(e){e.transport!==void 0&&(this.logTransport=e.transport,this.apiTransportFailed=false,this.toolTransportFailed=false),e.apiEndpoint!==void 0&&(this.logApiEndpoint=e.apiEndpoint,this.apiTransportFailed=false);}createDefaultContext(){let e=typeof window<"u";return {theme:"light",displayMode:"inline",availableDisplayModes:["inline","fullscreen","pip"],viewport:{width:e?window.innerWidth:800,height:e?window.innerHeight:600},locale:e?navigator.language:"en-US",timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,platform:"web",deviceCapabilities:{touch:e?"ontouchstart"in window:false,hover:true}}}isSetGlobalsMessage(e){return e==="openai:set_globals"||typeof e=="object"&&e!==null&&"type"in e&&e.type==="openai:set_globals"||typeof e=="object"&&e!==null&&"message"in e&&e.message==="openai:set_globals"}readContextFromSDK(){let e=this.getOpenAI();if(!e)return;let t=typeof window<"u";if(typeof e.theme=="string"&&(this.context.theme=e.theme),typeof e.displayMode=="string"&&(this.context.displayMode=e.displayMode),typeof e.locale=="string"&&(this.context.locale=e.locale),typeof e.userAgent=="string"&&Object.assign(this.context,{userAgent:e.userAgent}),typeof e.view=="string"&&(this.context.view=e.view),e.safeArea&&typeof e.safeArea=="object"){let o=e.safeArea;this.context.safeAreaInsets={top:typeof o.top=="number"?o.top:0,right:typeof o.right=="number"?o.right:0,bottom:typeof o.bottom=="number"?o.bottom:0,left:typeof o.left=="number"?o.left:0};}typeof e.maxHeight=="number"&&(this.context.viewport={width:t?window.innerWidth:800,height:e.maxHeight}),i.debug("[OpenAI Adapter] Read context from SDK",this.context);}notifyContextChange(){i.debug(`[OpenAI Adapter] Notifying ${String(this.hostContextHandlers.size)} context change handlers`);let e={...this.context};for(let t of this.hostContextHandlers)t(e);}getOpenAI(){return typeof window<"u"&&"openai"in window?window.openai:null}getToolNameFromSDK(){let e=this.getOpenAI();if(e){if(e.toolResponseMetadata&&typeof e.toolResponseMetadata=="object"){let t=e.toolResponseMetadata;if(typeof t.toolName=="string")return t.toolName}if(typeof e.toolName=="string")return e.toolName}}async connect(){await this.waitForOpenAI();let e=this.getOpenAI();if(e){i.debug("[OpenAI Adapter] Available SDK methods",Object.keys(e)),this.readContextFromSDK();let t=this.getToolNameFromSDK();if(typeof e.getToolOutput=="function"?(this.currentToolOutput=e.getToolOutput(),i.debug("[OpenAI Adapter] Got tool output from SDK")):e.toolOutput?(this.currentToolOutput=e.toolOutput,i.debug("[OpenAI Adapter] Got tool output from SDK property")):e.result&&(this.currentToolOutput=e.result,i.debug("[OpenAI Adapter] Got result from SDK")),this.currentToolOutput&&Object.keys(this.currentToolOutput).length>0){let o=t?{[t]:this.currentToolOutput}:this.currentToolOutput;for(let n of this.toolResultHandlers)n(o);}typeof e.getToolInput=="function"?this.currentToolInput=e.getToolInput():e.toolInput?this.currentToolInput=e.toolInput:e.input&&(this.currentToolInput=e.input),typeof e.init=="function"&&await e.init();}this.setupGlobalsListener(),this.connected=true;}setupGlobalsListener(){typeof window>"u"||(this.setGlobalsHandler=e=>{let o=e.detail;if(!o){this.readContextFromSDK(),this.checkForToolOutputUpdate();return}let n=o.globals??o,s=this.context.theme,a=this.context.locale,l=this.context.displayMode,c=this.currentToolOutput;if(n.theme!==void 0&&(this.context.theme=n.theme),n.locale!==void 0&&(this.context.locale=n.locale),n.displayMode!==void 0&&(this.context.displayMode=n.displayMode),(this.context.theme!==s||this.context.locale!==a||this.context.displayMode!==l)&&(i.debug("[OpenAI Adapter] Context changed, notifying handlers"),this.notifyContextChange()),n.toolOutput!==void 0&&n.toolOutput!==null){let u=n.toolOutput;if(Object.keys(u).length>0&&u!==c){i.debug("[OpenAI Adapter] Got toolOutput from set_globals event",u),this.currentToolOutput=u;let g;n.toolResponseMetadata&&typeof n.toolResponseMetadata=="object"&&n.toolResponseMetadata.toolName?g=n.toolResponseMetadata.toolName:g=this.getToolNameFromSDK();let v=g?{[g]:u}:u;for(let C of this.toolResultHandlers)C(v);}}n.toolInput!==void 0&&(this.currentToolInput=n.toolInput);},window.addEventListener("openai:set_globals",this.setGlobalsHandler),this.globalsHandler=e=>{this.isSetGlobalsMessage(e.data)&&(i.debug("[OpenAI Adapter] Received set_globals via postMessage (legacy)"),this.readContextFromSDK(),this.checkForToolOutputUpdate());},window.addEventListener("message",this.globalsHandler));}checkForToolOutputUpdate(){let e=this.getOpenAI();if(!e)return;let t;if(e.toolOutput&&(t=e.toolOutput),t&&Object.keys(t).length>0&&t!==this.currentToolOutput){i.debug("[OpenAI Adapter] toolOutput updated",t),this.currentToolOutput=t;let o=this.getToolNameFromSDK(),n=o?{[o]:t}:t;for(let s of this.toolResultHandlers)s(n);}}async waitForOpenAI(e=5e3){if(this.getOpenAI()){i.debug("[OpenAI Adapter] window.openai already available");return}return i.debug("[OpenAI Adapter] Waiting for window.openai..."),new Promise(t=>{let o=Date.now(),n=false,s=()=>{n||(n=true,window.removeEventListener("message",l),t());},a=()=>{if(!n){if(this.getOpenAI()){i.debug("[OpenAI Adapter] window.openai found via polling"),s();return}if(Date.now()-o>e){i.warn("[OpenAI Adapter] window.openai not found after timeout, proceeding anyway"),s();return}setTimeout(a,50);}},l=c=>{this.isSetGlobalsMessage(c.data)&&(i.debug("[OpenAI Adapter] Received set_globals message"),setTimeout(()=>{this.getOpenAI()?(i.debug("[OpenAI Adapter] window.openai available after set_globals"),s()):i.debug("[OpenAI Adapter] window.openai still not available after set_globals, continuing poll");},50));};window.addEventListener("message",l),a();})}isConnected(){return this.connected}async callTool(e,t){let o=this.getOpenAI();if(o&&typeof o.callTool=="function")return o.callTool(e,t);throw new Error("OpenAI SDK not available")}async sendMessage(e){if(e.type!=="text")throw new Error(`Unsupported message content type: ${e.type}`);let t=this.getOpenAI();t&&typeof t.sendFollowUpMessage=="function"&&await t.sendFollowUpMessage({prompt:e.text});}async updateModelContext(e){let t={__mcp_type:"modelContext"};if(e.structuredContent){let o=e.structuredContent,n=Object.keys(o).filter(s=>s.startsWith("_"));n.length>0&&i.debug("[OpenAI Adapter] Filtering reserved keys (underscore-prefixed) from structuredContent:",n),Object.keys(o).forEach(s=>{s.startsWith("_")||(t[s]=o[s]);});}if(e.content&&e.content.length>0){let o=e.content.filter(a=>a.type==="text"),n=e.content.filter(a=>a.type!=="text");n.length>0&&i.debug(`[OpenAI Adapter] Dropping ${String(n.length)} non-text content block(s):`,n.map(a=>a.type));let s=o.map(a=>a.text).join(` | ||
| `);s&&(t.__mcp_textContent=s);}this.setState(t),i.debug("[OpenAI Adapter] updateModelContext via setState:",t);}async openLink(e){let t=this.getOpenAI();t&&typeof t.openExternal=="function"?await t.openExternal({href:e}):window.open(e,"_blank");}async requestDisplayMode(e){let t=this.getOpenAI();if(t&&typeof t.requestDisplayMode=="function"){let o=await t.requestDisplayMode({mode:e});return this.context={...this.context,displayMode:o.mode},this.notifyContextChange(),o}return this.context={...this.context,displayMode:e},this.notifyContextChange(),{mode:e}}requestClose(){let e=this.getOpenAI();e&&typeof e.close=="function"&&e.close();}getState(){return this.state}setState(e){this.state=e;let t=this.getOpenAI();t&&typeof t.setWidgetState=="function"&&t.setWidgetState(e);}async uploadFile(e){let t=this.getOpenAI();if(t&&typeof t.uploadFile=="function")return t.uploadFile(e);throw new Error("File upload not supported")}async getFileDownloadUrl(e){let t=this.getOpenAI();if(t&&typeof t.getFileDownloadUrl=="function")return t.getFileDownloadUrl(e);throw new Error("File download not supported")}async readResource(e){let t=this.getOpenAI();return t&&typeof t.readResource=="function"?t.readResource(e):{contents:[]}}log(e,t){({debug:console.debug,info:console.info,warning:console.warn,error:console.error}[e]??console.log)("[ChatGPT Apps]",t);}onToolResult(e){return this.toolResultHandlers.add(e),()=>this.toolResultHandlers.delete(e)}onToolInput(e){return this.toolInputHandlers.add(e),()=>this.toolInputHandlers.delete(e)}onToolCancelled(e){return this.toolCancelledHandlers.add(e),()=>this.toolCancelledHandlers.delete(e)}onHostContextChange(e){return this.hostContextHandlers.add(e),i.debug(`[OpenAI Adapter] Host context handler added, total: ${String(this.hostContextHandlers.size)}`),()=>{this.hostContextHandlers.delete(e),i.debug(`[OpenAI Adapter] Host context handler removed, total: ${String(this.hostContextHandlers.size)}`);}}onTeardown(e){return this.teardownHandlers.add(e),()=>this.teardownHandlers.delete(e)}getHostContext(){return this.context}getToolInput(){return this.currentToolInput}getToolOutput(){if(!this.currentToolOutput)return;let e=this.getToolNameFromSDK();return e?{[e]:this.currentToolOutput}:this.currentToolOutput}getToolMeta(){return this.currentToolMeta}getHostCapabilities(){let e=this.getOpenAI(),t=e&&typeof e.uploadFile=="function",o=this.context.safeAreaInsets!==void 0,n=this.context.view!==void 0;return {openLinks:{},logging:{},theming:{themes:["light","dark"]},displayModes:{modes:["inline","fullscreen","pip"]},statePersistence:{persistent:false},fileUpload:t?{}:void 0,safeAreaInsets:o?{}:void 0,views:n?{}:void 0}}getHostVersion(){}async sendLog(e,t){let n={level:{debug:"debug",info:"info",notice:"info",warning:"warn",error:"error",critical:"error",alert:"error",emergency:"error"}[e],message:typeof t=="string"?t:JSON.stringify(t),data:typeof t=="string"?void 0:t,timestamp:new Date().toISOString(),source:"openai-adapter"};await this.sendLogs([n]);}async sendLogs(e){if(this.logTransport==="api"&&this.logApiEndpoint&&!this.apiTransportFailed)try{let t=await fetch(this.logApiEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:e})});if(!t.ok)throw new Error(`API request failed with status ${String(t.status)}`);return await t.json()}catch(t){this.apiTransportFailed=true,i.info("[OpenAI Adapter] API log transport failed, trying fallback",{error:t instanceof Error?t.message:t});}if((this.logTransport==="tool"||this.apiTransportFailed)&&!this.toolTransportFailed&&this.connected)try{return await this.callTool("log_debug",{entries:e})}catch(t){this.toolTransportFailed=true,i.info("[OpenAI Adapter] Tool log transport failed, falling back to console",{error:t instanceof Error?t.message:t});}for(let t of e)this.log(t.level==="warn"?"warning":t.level,t.data??t.message);return {processed:e.length}}async sendSizeChanged(e){let t=this.getOpenAI();t&&typeof t.notifyIntrinsicHeight=="function"&&t.notifyIntrinsicHeight(e.height);}onToolInputPartial(e){return this.log("debug","onToolInputPartial is not supported on ChatGPT"),()=>{}}setCallToolHandler(e){this.log("debug","setCallToolHandler is not supported on ChatGPT");}setListToolsHandler(e){this.log("debug","setListToolsHandler is not supported on ChatGPT");}};function x(){if(typeof window>"u")return "mock";if("openai"in window)return "openai";let r=window.location.href,e=document.referrer;return r.includes("/api/apps/chatgpt/")||r.includes("chatgpt")||r.includes("sandbox-proxy")||r.includes("widget-content")||e.includes("chatgpt")||e.includes("openai.com")?"openai":window.parent!==window?"mcp":"mock"}function $(r){return new Proxy({},{get(e,t){if(typeof t!="string"||!t.startsWith("call"))return;let o=t.slice(4);if(o.length===0)return;let n=o.charAt(0).toLowerCase()+o.slice(1);return s=>r(n,s)},has(e,t){return typeof t=="string"&&t.startsWith("call")&&t.length>4},ownKeys(){return []},getOwnPropertyDescriptor(e,t){if(typeof t=="string"&&t.startsWith("call")&&t.length>4)return {configurable:true,enumerable:true,writable:false}}})}function b(r){async function e(n,s){return await r.callTool(n,s)}let t=$(e);return {callTool:e,tools:t,async sendMessage(n){await r.sendMessage(n);},async sendFollowUpMessage(n){await r.sendMessage({type:"text",text:n});},async updateModelContext(n){await r.updateModelContext(n);},async openLink(n){await r.openLink(n);},async requestDisplayMode(n){return r.requestDisplayMode(n)},requestClose(){r.requestClose();},getState(){return r.getState()},setState(n){r.setState(n);},...r.uploadFile&&{uploadFile:r.uploadFile.bind(r)},...r.getFileDownloadUrl&&{getFileDownloadUrl:r.getFileDownloadUrl.bind(r)},async readResource(n){return r.readResource(n)},log(n,s){r.log(n,s);},onToolResult(n){return r.onToolResult(n)},onToolInput(n){return r.onToolInput(n)},onToolCancelled(n){return r.onToolCancelled(n)},onHostContextChange(n){return r.onHostContextChange(n)},onTeardown(n){return r.onTeardown(n)},onToolInputPartial(n){return r.onToolInputPartial(n)},getHostCapabilities(){return r.getHostCapabilities()},getHostVersion(){return r.getHostVersion()},async sendLog(n,s){return r.sendLog(n,s)},async sendSizeChanged(n){return r.sendSizeChanged(n)},setupSizeChangedNotifications(){if(typeof window>"u"||typeof ResizeObserver>"u")return ()=>{};let n=new ResizeObserver(s=>{for(let a of s){let{width:l,height:c}=a.contentRect;r.sendSizeChanged({width:Math.round(l),height:Math.round(c)});}});return n.observe(document.body),()=>{n.disconnect();}},setCallToolHandler(n){r.setCallToolHandler(n);},setListToolsHandler(n){r.setListToolsHandler(n);},get hostContext(){return r.getHostContext()},get toolInput(){return r.getToolInput()},get toolOutput(){return r.getToolOutput()},get toolMeta(){return r.getToolMeta()}}}function q(r,e){switch(r){case "mcp":return new m(e?.mcp);case "openai":return new w;case "mock":return new h;default:throw new Error(`Unknown adapter type: ${r}`)}}async function K(r){let e=r?.forceAdapter??x();if(!["mcp","openai","mock"].includes(e))throw new Error(`Unknown adapter type: ${e}`);let t=r?.autoResize!==void 0?{mcp:{autoResize:r.autoResize}}:void 0,o=q(e,t);return await o.connect(),i.setAdapter(o),b(o)}async function he(r,e){return K(e)}export{y as ClientDebugLogger,_ as LATEST_PROTOCOL_VERSION,m as McpAdapter,h as MockAdapter,w as OpenAIAdapter,F as RESOURCE_MIME_TYPE,N as RESOURCE_URI_META_KEY,d as UIError,p as UIErrorCode,H as applyDocumentTheme,O as applyHostFonts,A as applyHostStyleVariables,I as clearHostStyleVariables,i as clientDebugLogger,b as createAppsClient,K as createClient,he as createTypedClient,x as detectProtocol,k as getDocumentTheme,U as getMcpServerBaseUrl,L as getMcpServerConfig,R as removeHostFonts,E as safeSerialize,D as safeStringify,S as shouldLog};//# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
+2
-2
| { | ||
| "name": "@mcp-apps-kit/ui", | ||
| "version": "0.4.0", | ||
| "version": "0.5.0", | ||
| "description": "Client-side SDK for MCP applications (vanilla JavaScript)", | ||
@@ -47,3 +47,3 @@ "type": "module", | ||
| "dependencies": { | ||
| "@modelcontextprotocol/ext-apps": "^0.2.2" | ||
| "@modelcontextprotocol/ext-apps": "^0.4.0" | ||
| }, | ||
@@ -50,0 +50,0 @@ "engines": { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
543624
12.14%2301
14.59%8
33.33%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed