This workflow follows the Agent → Chat Trigger recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "A2UI \u7ec4\u4ef6\u5c55\u793a (Showcase)",
"nodes": [
{
"parameters": {
"options": {
"allowedOrigins": "*"
}
},
"id": "chat-trigger",
"name": "Chat Trigger",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"typeVersion": 1.1,
"position": [
0,
0
]
},
{
"parameters": {
"options": {
"systemMessage": "\u4f60\u662f\u4e00\u4e2a A2UI \u7ec4\u4ef6\u751f\u6210\u4e13\u5bb6\u3002\u6839\u636e\u7528\u6237\u9700\u6c42\u751f\u6210 A2UI v0.9 \u534f\u8bae\u7684 UI \u7ec4\u4ef6\u3002\n\n# A2UI \u7ec4\u4ef6\u89c4\u8303\n\n## \u8f93\u51fa\u683c\u5f0f\n\u76f4\u63a5\u8f93\u51fa JSON \u5bf9\u8c61\uff08\u4e0d\u8981\u4f7f\u7528 markdown \u4ee3\u7801\u5757\uff09\uff0c\u5305\u542b `a2ui_messages` \u6570\u7ec4\uff1a\n\n{\n \"a2ui_messages\": [\n { \"type\": \"createSurface\", \"surfaceId\": \"main\", \"catalogId\": \"a2ui.org/standard\" },\n { \"type\": \"updateDataModel\", \"surfaceId\": \"main\", \"data\": {} },\n { \"type\": \"updateComponents\", \"surfaceId\": \"main\", \"components\": [...], \"rootComponentId\": \"root\" }\n ]\n}\n\n## \u7ec4\u4ef6\u901f\u67e5\n\n| \u7ec4\u4ef6 | \u5fc5\u9700\u5c5e\u6027 | \u53ef\u9009\u5c5e\u6027 |\n|------|----------|----------|\n| Text | id, component=\"Text\", text | usageHint(h1-h5/caption/body) |\n| Image | id, component=\"Image\", url | fit, usageHint |\n| Icon | id, component=\"Icon\", name | - |\n| Video | id, component=\"Video\", url | - |\n| AudioPlayer | id, component=\"AudioPlayer\", url | description |\n| Row | id, component=\"Row\", children | justify, align |\n| Column | id, component=\"Column\", children | justify, align |\n| List | id, component=\"List\", children | direction, align |\n| Card | id, component=\"Card\", child | - |\n| Tabs | id, component=\"Tabs\", tabs | - |\n| Divider | id, component=\"Divider\" | axis |\n| Modal | id, component=\"Modal\", trigger, content | - |\n| Button | id, component=\"Button\", child, action | primary |\n| CheckBox | id, component=\"CheckBox\", label, value | - |\n| TextField | id, component=\"TextField\", label | text, usageHint, validationRegexp |\n| DateTimeInput | id, component=\"DateTimeInput\", value | enableDate, enableTime, label |\n| ChoicePicker | id, component=\"ChoicePicker\", usageHint, options, value | label |\n| Slider | id, component=\"Slider\", value | label, min, max |\n| Chart | id, component=\"Chart\", chartType, series | title, xAxis, yAxis, legend, tooltip, height |\n\n## Chart \u793a\u4f8b\n{\n \"id\": \"chart-1\",\n \"component\": \"Chart\",\n \"chartType\": \"line\",\n \"title\": \"\u6570\u636e\u8d8b\u52bf\",\n \"series\": [{ \"name\": \"\u6570\u636e\", \"data\": [10, 20, 30, 40, 50] }],\n \"xAxis\": { \"type\": \"category\", \"data\": [\"A\", \"B\", \"C\", \"D\", \"E\"] },\n \"height\": 300\n}\n\n## \u6570\u636e\u7ed1\u5b9a\n\u4f7f\u7528 { \"path\": \"/data/path\" } \u7ed1\u5b9a\u6570\u636e\u6a21\u578b\u3002\n\n## \u89c4\u5219\n1. \u6bcf\u4e2a\u7ec4\u4ef6\u5fc5\u987b\u6709\u552f\u4e00 id\n2. Button.child \u5fc5\u987b\u5f15\u7528 Text \u7ec4\u4ef6 id\n3. \u5e03\u5c40\u7ec4\u4ef6\u7684 children \u5f15\u7528\u5b50\u7ec4\u4ef6 id \u6570\u7ec4\n4. \u6839\u7ec4\u4ef6\u901a\u5e38\u662f Column\n5. \u4f7f\u7528\u6570\u636e\u7ed1\u5b9a\u65f6\uff0c\u5728 updateDataModel \u4e2d\u63d0\u4f9b\u521d\u59cb\u503c\n\n## \u9884\u8bbe\u573a\u666f\n\n### \u7528\u6237\u8bf4\"\u5c55\u793a\u6240\u6709\u7ec4\u4ef6\"\u6216\"\u6f14\u793a\"\n\u751f\u6210\u4e00\u4e2a\u5b8c\u6574\u7684\u7ec4\u4ef6\u5c55\u793a\u9875\u9762\uff0c\u5305\u542b\u6240\u6709\u7c7b\u578b\u7684\u7ec4\u4ef6\u3002\n\n### \u7528\u6237\u8bf4\"\u767b\u5f55\u8868\u5355\"\n\u751f\u6210\u767b\u5f55\u8868\u5355\uff1a\u7528\u6237\u540d\u8f93\u5165\u6846\u3001\u5bc6\u7801\u8f93\u5165\u6846\uff08obscured\uff09\u3001\u8bb0\u4f4f\u6211\u590d\u9009\u6846\u3001\u767b\u5f55\u6309\u94ae\u3002\n\n### \u7528\u6237\u8bf4\"\u4eea\u8868\u76d8\"\u6216\"dashboard\"\n\u751f\u6210\u4eea\u8868\u76d8\uff1a\u7edf\u8ba1\u5361\u7247\u3001\u56fe\u8868\u3001\u6700\u8fd1\u6d3b\u52a8\u5217\u8868\u3002\n\n### \u7528\u6237\u8bf4\"\u5546\u54c1\u5361\u7247\"\u6216\"\u4ea7\u54c1\u5217\u8868\"\n\u751f\u6210\u5546\u54c1\u5361\u7247\uff1a\u56fe\u7247\u3001\u6807\u9898\u3001\u4ef7\u683c\u3001\u8bc4\u5206\u3001\u8d2d\u4e70\u6309\u94ae\u3002\n\n\u8bf7\u6839\u636e\u7528\u6237\u8bf7\u6c42\u751f\u6210\u5408\u9002\u7684 A2UI \u7ec4\u4ef6 JSON\u3002\u8f93\u51fa\u5fc5\u987b\u662f\u7eaf JSON \u683c\u5f0f\uff0c\u4e0d\u8981\u5305\u542b\u4efb\u4f55\u5176\u4ed6\u6587\u5b57\u8bf4\u660e\u3002",
"returnIntermediateSteps": false
}
},
"id": "ai-agent",
"name": "A2UI Generator",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.7,
"position": [
220,
0
]
},
{
"parameters": {
"model": "gpt-4o",
"options": {
"temperature": 0.5,
"responseFormat": "json_object"
}
},
"id": "openai-model",
"name": "OpenAI GPT-4o",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.2,
"position": [
220,
200
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "={{ $('Chat Trigger').item.json.sessionId }}"
},
"id": "memory",
"name": "Window Buffer Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.2,
"position": [
400,
200
]
},
{
"parameters": {
"jsCode": "// \u89e3\u6790 AI \u8f93\u51fa\u5e76\u63d0\u53d6 A2UI \u6d88\u606f\nconst input = $input.first().json;\nconst agentOutput = input.output || input.text || input.response || '';\n\nlet a2uiMessages = [];\nlet parseError = null;\n\ntry {\n let parsed;\n \n if (typeof agentOutput === 'string') {\n // \u6e05\u7406\u53ef\u80fd\u7684 markdown \u4ee3\u7801\u5757\n let cleanJson = agentOutput\n .replace(/```json\\n?/gi, '')\n .replace(/```\\n?/g, '')\n .trim();\n \n // \u5c1d\u8bd5\u627e\u5230 JSON \u5bf9\u8c61\n const jsonStart = cleanJson.indexOf('{');\n const jsonEnd = cleanJson.lastIndexOf('}');\n if (jsonStart !== -1 && jsonEnd !== -1) {\n cleanJson = cleanJson.substring(jsonStart, jsonEnd + 1);\n }\n \n parsed = JSON.parse(cleanJson);\n } else if (typeof agentOutput === 'object') {\n parsed = agentOutput;\n }\n \n if (parsed?.a2ui_messages) {\n a2uiMessages = parsed.a2ui_messages;\n } else if (Array.isArray(parsed)) {\n a2uiMessages = parsed;\n } else if (parsed?.type) {\n a2uiMessages = [parsed];\n } else {\n // \u5982\u679c\u89e3\u6790\u7ed3\u679c\u6ca1\u6709\u9884\u671f\u7684\u683c\u5f0f\uff0c\u5c1d\u8bd5\u5305\u88c5\n throw new Error('Invalid A2UI message format');\n }\n \n} catch (e) {\n parseError = e.message;\n \n // \u8fd4\u56de\u53cb\u597d\u7684\u9519\u8bef\u63d0\u793a UI\n a2uiMessages = [\n {\n type: 'createSurface',\n surfaceId: 'error',\n catalogId: 'a2ui.org/standard'\n },\n {\n type: 'updateComponents',\n surfaceId: 'error',\n components: [\n { id: 'icon', component: 'Icon', name: 'error' },\n { id: 'title', component: 'Text', text: '\u751f\u6210\u5931\u8d25', usageHint: 'h2' },\n { id: 'msg', component: 'Text', text: '\u65e0\u6cd5\u751f\u6210 UI \u7ec4\u4ef6\uff0c\u8bf7\u91cd\u65b0\u63cf\u8ff0\u60a8\u7684\u9700\u6c42\u3002\u9519\u8bef: ' + parseError, usageHint: 'body' },\n { id: 'header', component: 'Row', children: ['icon', 'title'], alignment: 'center' },\n { id: 'root', component: 'Column', children: ['header', 'msg'] }\n ],\n rootComponentId: 'root'\n }\n ];\n}\n\n// \u6784\u5efa\u6700\u7ec8\u8f93\u51fa - \u5c06 a2ui_messages \u8f6c\u6362\u4e3a JSONL \u683c\u5f0f\u5b57\u7b26\u4e32\nconst a2uiJsonl = a2uiMessages.map(m => JSON.stringify(m)).join('\\n');\n\nreturn {\n json: {\n // \u8fd4\u56de\u7eaf\u6587\u672c\u683c\u5f0f\uff0c\u5305\u542b A2UI JSONL\n output: a2uiJsonl,\n // \u540c\u65f6\u4fdd\u7559\u7ed3\u6784\u5316\u6570\u636e\u7528\u4e8e\u8c03\u8bd5\n _debug: {\n a2ui_messages: a2uiMessages,\n success: !parseError,\n error: parseError\n }\n }\n};"
},
"id": "parse-output",
"name": "Parse A2UI",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
440,
0
]
}
],
"connections": {
"Chat Trigger": {
"main": [
[
{
"node": "A2UI Generator",
"type": "main",
"index": 0
}
]
]
},
"OpenAI GPT-4o": {
"ai_languageModel": [
[
{
"node": "A2UI Generator",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Window Buffer Memory": {
"ai_memory": [
[
{
"node": "A2UI Generator",
"type": "ai_memory",
"index": 0
}
]
]
},
"A2UI Generator": {
"main": [
[
{
"node": "Parse A2UI",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"meta": {
"templateCredsSetupCompleted": true
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
openAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
A2UI 组件展示 (Showcase). Uses chatTrigger, agent, lmChatOpenAi, memoryBufferWindow. Chat trigger; 5 nodes.
Source: https://github.com/zhama-ai/a2ui-react/blob/18cb4849dc1d1361e85470986dec13093e203dc5/examples/n8n-a2ui-showcase-workflow.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
HDW Lead Geländewagen. Uses chatTrigger, lmChatOpenAi, memoryBufferWindow, outputParserStructured. Chat trigger; 92 nodes.
router-agent. Uses chatTrigger, agent, lmChatOpenAi, executeWorkflow. Chat trigger; 59 nodes.
router-agent. Uses chatTrigger, agent, lmChatOpenAi, memoryBufferWindow. Chat trigger; 58 nodes.
by Varritech Technologies
Community Node Disclaimer: This workflow uses KlickTipp community nodes.