-
Notifications
You must be signed in to change notification settings - Fork 266
Description
Hi!
Thank you for your work on MCP-UI!
I noticed that when using the WC-based UIResourceRenderer, rendering a text/uri-list resource (Iframe that receives a src), and sending a postMessage event from inside the Iframe to the host page, any ui-message-response being sent back from the host-page to the Iframe in response does not contain any payload.
Notice this:
UiResourceRendererWc.tsx defines the onUiActionCallback like this. notice how this function does not return a value
const onUIActionCallback = useCallback(async (event: UIActionResult): Promise<void> => {
if (ref.current) {
const customEvent = new CustomEvent('onUIAction', {
detail: event,
composed: true,
bubbles: true,
});
ref.current.dispatchEvent(customEvent);
}
}, []);
return (
<div ref={ref}>
<UIResourceRenderer
resource={resource as Resource}
supportedContentTypes={supportedContentTypes as unknown as UIResourceRendererProps['supportedContentTypes']}
htmlProps={htmlProps}
remoteDomProps={remoteDomProps}
onUIAction={onUIActionCallback}
/>
</div>
);On the UiResourceRenderer onUIAction is being forwarded like this:
return <HTMLResourceRenderer resource={resource} onUIAction={onUIAction} {...htmlProps} />;And finally, on HTMLResourceRenderer, onUIAction is being used like this:
async function handleMessage(event: MessageEvent) {
const { source, origin, data } = event;
// [... snip ...]
const uiActionResult = data as UIActionResult;
if (!uiActionResult) {
return;
}
if (onUIAction) {
const messageId = uiActionResult.messageId;
postToFrame(InternalMessageType.UI_MESSAGE_RECEIVED, source, origin, messageId);
try {
//
// problem seems to be the line below
//
const response = await onUIAction(uiActionResult);
postToFrame(InternalMessageType.UI_MESSAGE_RESPONSE, source, origin, messageId, {
response,
});
} catch (err) {
console.error('Error handling UI action result in HTMLResourceRenderer:', err);
postToFrame(InternalMessageType.UI_MESSAGE_RESPONSE, source, origin, messageId, {
error: err,
});
}
}
}
}
window.addEventListener('message', handleMessage);
return () => window.removeEventListener('message', handleMessage);
}events received with this setup on my local dev machine look like this:
{
"type": "ui-message-response",
"messageId":"88ef95be-d08a-43db-a2b5-ec55a42fea5c",
"payload":{}
}so while it is possible to distinguish error responses from successful responses by checking for the presence of error vs payload in the message, the payload/error details will always be {} because the line
const response = await onUIAction(uiActionResult); awaits on a function that returns no value.
Hope my description is understandable. LMK if you need a minimal reproducible example for this!