💻 feat: Deeper MCP UI integration in the Chat UI (#9669)

* 💻 feat: deeper MCP UI integration in the chat UI using plugins

---------

Co-authored-by: Samuel Path <samuel.path@shopify.com>
Co-authored-by: Pierre-Luc Godin <pierreluc.godin@shopify.com>

* 💻 refactor: Migrate MCP UI resources from index-based to ID-based referencing

- Replace index-based resource markers with stable resource IDs
- Update plugin to parse \ui{resourceId} format instead of \ui0
- Refactor components to use useMessagesOperations instead of useSubmitMessage
- Add ShareMessagesProvider for UI resources in share view
- Add useConversationUIResources hook for cross-turn resource lookups
- Update parsers to generate resource IDs from content hashes
- Update all tests to use resource IDs instead of indices
- Add sandbox permissions for iframe popups
- Remove deprecated MCP tool context instructions

---------

Co-authored-by: Pierre-Luc Godin <pierreluc.godin@shopify.com>
This commit is contained in:
Samuel Path 2025-12-11 22:02:38 +01:00 committed by Danny Avila
parent 4a0fbb07bc
commit 304bba853c
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
27 changed files with 1545 additions and 122 deletions

View file

@ -124,3 +124,59 @@ export const normalizeLayout = (layout: number[]) => {
return normalizedLayout;
};
export const handleUIAction = async (result: any, ask: any) => {
const supportedTypes = ['intent', 'tool', 'prompt'];
const { type, payload } = result;
if (!supportedTypes.includes(type)) {
return;
}
let messageText = '';
if (type === 'intent') {
const { intent, params } = payload;
messageText = `The user clicked a button in an embedded UI Resource, and we got a message of type \`intent\`.
The intent is \`${intent}\` and the params are:
\`\`\`json
${JSON.stringify(params, null, 2)}
\`\`\`
Execute the intent that is mentioned in the message using the tools available to you.
`;
} else if (type === 'tool') {
const { toolName, params } = payload;
messageText = `The user clicked a button in an embedded UI Resource, and we got a message of type \`tool\`.
The tool name is \`${toolName}\` and the params are:
\`\`\`json
${JSON.stringify(params, null, 2)}
\`\`\`
Execute the tool that is mentioned in the message using the tools available to you.
`;
} else if (type === 'prompt') {
const { prompt } = payload;
messageText = `The user clicked a button in an embedded UI Resource, and we got a message of type \`prompt\`.
The prompt is:
\`\`\`
${prompt}
\`\`\`
Execute the intention of the prompt that is mentioned in the message using the tools available to you.
`;
}
console.log('About to submit message:', messageText);
try {
await ask({ text: messageText });
console.log('Message submitted successfully');
} catch (error) {
console.error('Error submitting message:', error);
}
};