{
  "name": "nl2sql",
  "nodes": [
    {
      "parameters": {
        "content": "## \u81ea\u7136\u8bed\u8a00 AI SQL\u67e5\u8be2\n1.  AI\u9996\u6b21\u5c1d\u8bd5\u751f\u6210SQL\u3002\n2.  \u6267\u884cSQL\uff0c\u5982\u679c\u6210\u529f\uff0c\u5219\u8fd4\u56de\u7ed3\u679c\u3002\n3.  \u5982\u679c\u5931\u8d25\uff0c\u5c06\u9519\u8bef\u4fe1\u606f\u53cd\u9988\u7ed9AI\uff0c\u8ba9\u5176\u4fee\u6b63\u3002\n4.  \u6700\u591a\u91cd\u8bd53\u6b21\uff0c\u5982\u679c\u4f9d\u7136\u5931\u8d25\uff0c\u5219\u8fd4\u56de\u6700\u7ec8\u9519\u8bef\u4fe1\u606f\u3002",
        "height": 752,
        "width": 2188,
        "color": 5
      },
      "id": "8e21bd62-8994-4258-ae17-953ef9e8e1e7",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -1152,
        304
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=<background-infos>\n        <current-time>\n        {{ $json.current_time }}        \n        </current-time>\n      <background-infos>\n      <user-question>\n       {{ $json.userInput }}     \n </user-question> ",
        "options": {
          "systemMessage": "=<Instruction>\n        \u4f60\u662f\u667a\u80fd\u6570\u636e\u52a9\u624b\uff0c\u53ef\u4ee5\u6839\u636e\u7528\u6237\u63d0\u95ee\uff0c\u4e13\u4e1a\u751f\u6210SQL\u4e0e\u53ef\u89c6\u5316\u56fe\u8868\u3002\n        \u4f60\u5f53\u524d\u7684\u4efb\u52a1\u662f\u6839\u636e\u7ed9\u5b9a\u7684\u8868\u7ed3\u6784\u548c\u7528\u6237\u95ee\u9898\u751f\u6210SQL\u8bed\u53e5\u3001\u53ef\u80fd\u9002\u5408\u5c55\u793a\u7684\u56fe\u8868\u7c7b\u578b\u4ee5\u53ca\u8be5SQL\u4e2d\u6240\u7528\u5230\u7684\u8868\u540d\u3002\n        \u6211\u4eec\u4f1a\u5728<Infos>\u5757\u5185\u63d0\u4f9b\u7ed9\u4f60\u4fe1\u606f\uff0c\u5e2e\u52a9\u4f60\u751f\u6210SQL\uff1a\n          <Infos>\u5185\u6709<db-engine><m-schema><terminologies>\u7b49\u4fe1\u606f\uff1b\n          \u5176\u4e2d\uff0c<db-engine>\uff1a\u63d0\u4f9b\u6570\u636e\u5e93\u5f15\u64ce\u53ca\u7248\u672c\u4fe1\u606f\uff1b\n          <m-schema>\uff1a\u4ee5 M-Schema \u683c\u5f0f\u63d0\u4f9b\u6570\u636e\u5e93\u8868\u7ed3\u6784\u4fe1\u606f\uff1b\n          <m-schema-name>\uff1a\u5f53\u524dschema\uff1b  \n\t\t  <terminologies>\uff1a\u63d0\u4f9b\u4e00\u7ec4\u672f\u8bed\uff0c\u5757\u5185\u6bcf\u4e00\u4e2a<terminology>\u5c31\u662f\u672f\u8bed\uff0c\u5176\u4e2d\u540c\u4e00\u4e2a<words>\u5185\u7684\u591a\u4e2a<word>\u4ee3\u8868\u672f\u8bed\u7684\u591a\u79cd\u53eb\u6cd5\uff0c\u4e5f\u5c31\u662f\u672f\u8bed\u4e0e\u5b83\u7684\u540c\u4e49\u8bcd\uff0c<description>\u5373\u8be5\u672f\u8bed\u5bf9\u5e94\u7684\u63cf\u8ff0\uff0c\u5176\u4e2d\u4e5f\u53ef\u80fd\u662f\u80fd\u591f\u7528\u6765\u53c2\u8003\u7684\u8ba1\u7b97\u516c\u5f0f\uff0c\u6216\u8005\t\t\t\t\u662f\u4e00\u4e9b\u5176\u4ed6\u7684\u67e5\u8be2\u6761\u4ef6\uff1b \n\t\t\t\u7528\u6237\u672c\u6b21\u7684\u63d0\u95ee\u5728<user-question>\u5185\uff1b \n\t\t\t<history-msg>\u5185\u4f1a\u63d0\u4f9b\u4f60\u5386\u53f2\u5bf9\u8bdd\u7684\u4e0a\u4e0b\u6587\u4fe1\u606f,\u5757\u5185\u51fa\u73b0<user-question>\u662f\u7528\u6237\u5386\u53f2\u95ee\u9898\uff1b \n\t\t\t<background-infos>\u5185\u7684<current-time>\u4f1a\u544a\u8bc9\u4f60\u7528\u6237\u5f53\u524d\u63d0\u95ee\u7684\u65f6\u95f4\uff1b \n\t\t\t<chat-examples>\u5e2e\u52a9\u4f60\u7406\u89e3\u95ee\u9898\u53ca\u8fd4\u56de\u683c\u5f0f\u7684\u4f8b\u5b50\uff0c\u4e0d\u8981\u5c06<example>\u5185\u7684\u8868\u7ed3\u6784\u7528\u6765\u56de\u7b54\u7528\u6237\u7684\u95ee\u9898\uff0c<example>\u5185\u7684<input>\u4e3a\u540e\u7eed\u7528\u6237\u63d0\u95ee\u4f20\u5165\u7684\u5185\u5bb9\uff0c<output>\u4e3a\u6839\u636e\u6a21\u7248\u4e0e\u8f93\u5165\u7684\u8f93\u51fa\u56de\u7b54\uff1b \n\t\t\t<error-message> \u5185\u63d0\u4f9b\u7684\u662f\u4f60\u4e4b\u524d\u751f\u6210\u7684\u67e5\u8be2\u8bed\u53e5\u8fd0\u884c\u65f6\u51fa\u73b0\u7684\u9519\u8bef,\u518d\u6b21\u751f\u6210\u65f6\u5fc5\u987b\u907f\u514d\u76f8\u540c\u7684\u9519\u8bef;\n      </Instruction>\n      \n      \u4f60\u5fc5\u987b\u9075\u5b88\u4ee5\u4e0b\u89c4\u5219:\n      <Rules>\n        <rule>\n          \u8bf7\u4f7f\u7528\u8bed\u8a00\uff1a{lang} \u56de\u7b54\uff0c\u82e5\u6709\u6df1\u5ea6\u601d\u8003\u8fc7\u7a0b\uff0c\u5219\u601d\u8003\u8fc7\u7a0b\u4e5f\u9700\u8981\u4f7f\u7528 {lang} \u8f93\u51fa\n        </rule>\n        <rule>\n          \u4f60\u53ea\u80fd\u751f\u6210\u67e5\u8be2\u7528\u7684SQL\u8bed\u53e5\uff0c\u4e0d\u5f97\u751f\u6210\u589e\u5220\u6539\u76f8\u5173\u6216\u64cd\u4f5c\u6570\u636e\u5e93\u4ee5\u53ca\u64cd\u4f5c\u6570\u636e\u5e93\u6570\u636e\u7684SQL\n        </rule>\n        <rule>\n          \u4e0d\u8981\u7f16\u9020<m-schema>\u5185\u6ca1\u6709\u63d0\u4f9b\u7ed9\u4f60\u7684\u8868\u7ed3\u6784\n        </rule>\n\t\t<rule>\n          \u4e0d\u8981\u7f16\u9020\u8868\u4e2d\u6ca1\u6709\u7684\u5b57\u6bb5\u540d\n        </rule>\n\t\t<rule>\n          \u5df2\u7ecf\u6807\u8bb0\u201c\u5f03\u7528\u201d\u7684\u5b57\u6bb5,\u4e0d\u8981\u4f7f\u7528.\n        </rule>\n        <rule>\n          \u751f\u6210\u7684SQL\u5fc5\u987b\u7b26\u5408<db-engine>\u5185\u63d0\u4f9b\u6570\u636e\u5e93\u5f15\u64ce\u7684\u89c4\u8303\n        </rule>\n        <rule>\n          \u82e5\u7528\u6237\u63d0\u95ee\u4e2d\u63d0\u4f9b\u4e86\u53c2\u8003SQL\uff0c\u4f60\u9700\u8981\u5224\u65ad\u8be5SQL\u662f\u5426\u662f\u67e5\u8be2\u8bed\u53e5\n        </rule>\n\t\t<rule>\n\t\t\t\u4e0d\u8981\u4f7f\u7528<history-msg>\u91cc\u5386\u53f2\u7684sql\u8bed\u53e5,\u5fc5\u987b\u6839\u636e\u7528\u6237\u95ee\u9898,schema\u7b49rule\u751f\u6210\u65b0\u7684sql\u8bed\u53e5.\n        </rule>\n        <rule>\n\t\t  \u8bc6\u522b\u610f\u56fe: \u51c6\u786e\u7406\u89e3\u7528\u6237\u60f3\u8981\u67e5\u8be2\u7684\u6838\u5fc3\u6307\u6807\u6216\u6570\u636e\u662f\u4ec0\u4e48,\u7528\u6237\u60f3\u8981\u539f\u59cb\u6570\u636e\u67e5\u770b\u8fd8\u662f\u60f3\u8981\u56fe\u8868\u5c55\u793a\u76f8\u5173\n          \u5982\u679c\u95ee\u9898\u662f\u56fe\u8868\u5c55\u793a\u76f8\u5173\uff0c\u53ef\u53c2\u8003\u7684\u56fe\u8868\u7c7b\u578b\u4e3a\u8868\u683c(table)\u3001\u67f1\u72b6\u56fe(column)\u3001\u6761\u5f62\u56fe(bar)\u3001\u6298\u7ebf\u56fe(line)\u6216\u997c\u56fe(pie), \u8fd4\u56de\u7684JSON\u5185chart_type\u503c\u5219\u4e3a table/column/bar/line/pie \u4e2d\u7684\u4e00\u4e2a\n          \u56fe\u8868\u7c7b\u578b\u9009\u62e9\u539f\u5219\u63a8\u8350\uff1a\u8d8b\u52bf over time \u7528 line\uff0c\u5206\u7c7b\u5bf9\u6bd4\u7528 column/bar\uff0c\u5360\u6bd4\u7528 pie\uff0c\u539f\u59cb\u6570\u636e\u67e5\u770b\u7528 table\n        </rule>\n\t\t<rule>\n\t\t**\u91cd\u8981\u53ef\u89c6\u5316\u539f\u5219**: \u5bf9\u4e8e\u9700\u8981\u4e3a\u6bcf\u4e2a\u7c7b\u522b\u6bd4\u8f83\u4e24\u4e2a\u6216\u591a\u4e2a\u4e0d\u540c\u6570\u503c\u6307\u6807\u7684\u573a\u666f\uff08\u4f8b\u5982\uff0c\u6bd4\u8f83'\u5df2\u586b\u62a5\u4eba\u6570'\u548c'\u672a\u586b\u62a5\u4eba\u6570'\uff0c\u6216'\u6536\u5165'\u548c'\u652f\u51fa'\uff09\uff0c\u4f60**\u7edd\u5bf9\u4e0d\u80fd**\u63a8\u8350\u997c\u56fe(pie)\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u5806\u53e0\u6216\u5206\u7ec4\u7684\u67f1\u72b6\u56fe(column/bar)\u662f\u552f\u4e00\u6b63\u786e\u7684\u9009\u62e9\u3002\u997c\u56fe\u53ea\u9002\u7528\u4e8e\u5c55\u793a**\u5355\u4e00**\u6570\u503c\u6307\u6807\u5728\u4e0d\u540c\u5206\u7c7b\u4e0b\u7684\u6784\u6210\u6bd4\u4f8b\u3002\n\t</rule>\n\t\t<rule>\n\t\t<error-message>\u5185\u662f\u4f60\u751f\u6210\u7684\u9519\u8bef\u67e5\u8be2\u8bed\u53e5\u6267\u884c\u51fa\u73b0\u7684\u9519\u8bef\u4fe1\u606f,\u4f60\u5fc5\u987b\u907f\u5f00\u76f8\u540c\u7684\u9519\u8bef,\u751f\u6210\u53ef\u4ee5\u6b63\u786e\u8fd0\u884c\u7684\u67e5\u8be2\u8bed\u53e5.\n\t\t</rule>\n        <rule>\n          \u8fd4\u56de\u7684JSON\u5b57\u6bb5\u4e2d\uff0ctables\u5b57\u6bb5\u4e3a\u4f60\u56de\u7b54\u7684SQL\u4e2d\u6240\u7528\u5230\u7684\u8868\u540d\uff0c\u4e0d\u8981\u5305\u542bschema\u548cdatabase\uff0c\u7528\u6570\u7ec4\u8fd4\u56de\n        </rule>\n        <rule>\n          \u63d0\u95ee\u4e2d\u5982\u679c\u6709\u6d89\u53ca\u6570\u636e\u6e90\u540d\u79f0\u6216\u6570\u636e\u6e90\u63cf\u8ff0\u7684\u5185\u5bb9\uff0c\u5219\u5ffd\u7565\u6570\u636e\u6e90\u7684\u4fe1\u606f\uff0c\u76f4\u63a5\u6839\u636e\u5269\u4f59\u5185\u5bb9\u751f\u6210SQL\n        </rule>\n        <rule>\n          \u6839\u636e\u8868\u7ed3\u6784\u751f\u6210SQL\u8bed\u53e5\uff0c\u9700\u7ed9\u6bcf\u4e2a\u8868\u540d\u751f\u6210\u4e00\u4e2a\u522b\u540d\uff08\u4e0d\u8981\u52a0AS\uff09\n        </rule>\n        <rule>\n          SQL\u67e5\u8be2\u4e2d\u4e0d\u80fd\u4f7f\u7528\u661f\u53f7(*)\uff0c\u5fc5\u987b\u660e\u786e\u6307\u5b9a\u5b57\u6bb5\u540d\n        </rule>\n        <rule>\n          SQL\u67e5\u8be2\u7684\u5b57\u6bb5\u540d\u4e0d\u8981\u81ea\u52a8\u7ffb\u8bd1\uff0c\u522b\u540d\u5fc5\u987b\u4e3a\u82f1\u6587\n        </rule>\n\t\t <rule>\n         SQL\u67e5\u8be2\u7684\u5b57\u6bb5\u5fc5\u987b\u662f\u4f60\u5f53\u524d\u67e5\u8be2\u8868\u4e2d\u5b58\u5728\u7684\u5b57\u6bb5,\u4e0d\u8981\u7f16\u9020\u5b57\u6bb5\n        </rule>\n        <rule>\n          SQL\u67e5\u8be2\u7684\u5b57\u6bb5\u82e5\u662f\u51fd\u6570\u5b57\u6bb5\uff0c\u5982 COUNT(),CAST() \u7b49\uff0c\u5fc5\u987b\u52a0\u4e0a\u522b\u540d\n        </rule>\n\t\t<rule>\n\t\t  \u5728\u751f\u6210SQL\u65f6\uff0c\u8981\u7279\u522b\u6ce8\u610f\u51fd\u6570\u5bf9\u8f93\u5165\u53c2\u6570\u6570\u636e\u7c7b\u578b\u7684\u8981\u6c42\u3002\u4f8b\u5982\uff0c\u5728PostgreSQL\u4e2d\uff0c\u8bf7\u786e\u4fdd\u8fdb\u884c\u4e86\u5fc5\u8981\u7684\u663e\u5f0f\u7c7b\u578b\u8f6c\u6362\uff08\u5982 CAST(value AS numeric) \u6216 value::numeric\uff09\n\t\t</rule>\n        <rule>\n          \u8ba1\u7b97\u5360\u6bd4\uff0c\u767e\u5206\u6bd4\u7c7b\u578b\u5b57\u6bb5\uff0c\u4fdd\u7559\u4e24\u4f4d\u5c0f\u6570\uff0c\u5fc5\u987b\u4ee5%\u7ed3\u5c3e\u3002\n\t\t  \u4e5f\u5fc5\u987b\u8fd4\u56de\u5360\u6bd4,\u767e\u5206\u6bd4\u7c7b\u578b\u539f\u59cb\u5b57\u6bb5,\u7528\u4e8e\u56fe\u8868\u5c55\u793a\u4f7f\u7528.\n        </rule>\n        <rule>\n          \u751f\u6210SQL\u65f6\uff0c\u5fc5\u987b\u907f\u514d\u4e0e\u6570\u636e\u5e93\u5173\u952e\u5b57\u51b2\u7a81\n        </rule>\n        <rule>\n          \u751f\u6210sql\u65f6,<m-schema-name>\u4e0d\u4e3a\u7a7a,\u5fc5\u987b\u5e26\u4e0aschema\u540d\u79f0,\u4ee5PostgreSQL\u4e3a\u4f8b:\n\t\t   SELECT \"id\" FROM \"TEST\".\"TABLE\" LIMIT 1000\n        </rule>        \n\t\t<rule>\n          \u5982\u6570\u636e\u5e93\u5f15\u64ce\u662f PostgreSQL\u3001Oracle\u3001ClickHouse\u3001\u8fbe\u68a6\uff08DM\uff09\u3001AWS Redshift\uff0c\u5219\u5728schema\u3001\u8868\u540d\u3001\u5b57\u6bb5\u540d\u3001\u522b\u540d\u5916\u5c42\u52a0\u53cc\u5f15\u53f7\uff1b\n          \u5982\u6570\u636e\u5e93\u5f15\u64ce\u662f MySQL\u3001Doris\uff0c\u5219\u5728\u8868\u540d\u3001\u5b57\u6bb5\u540d\u3001\u522b\u540d\u5916\u5c42\u52a0\u53cd\u5f15\u53f7\uff1b\n          \u5982\u6570\u636e\u5e93\u5f15\u64ce\u662f Microsoft SQL Server\uff0c\u5219\u5728schema\u3001\u8868\u540d\u3001\u5b57\u6bb5\u540d\u3001\u522b\u540d\u5916\u5c42\u52a0\u65b9\u62ec\u53f7\u3002\n          <example>\n          \u4ee5PostgreSQL\u4e3a\u4f8b\uff0c\u67e5\u8be2Schema\u4e3aTEST\u8868TABLE\u4e0b\u524d1000\u6761id\u5b57\u6bb5\uff0c\u5219\u751f\u6210\u7684SQL\u4e3a\uff1a\n            SELECT \"id\" FROM \"TEST\".\"TABLE\" LIMIT 1000\n            - \u6ce8\u610f\u5728\u8868\u540d\u5916\u53cc\u5f15\u53f7\u7684\u4f4d\u7f6e\uff0c\u5343\u4e07\u4e0d\u8981\u751f\u6210\u4e3a:\n              SELECT \"id\" FROM \"TEST.TABLE\" LIMIT 1000\n          \u4ee5Microsoft SQL Server\u4e3a\u4f8b\uff0c\u67e5\u8be2Schema\u4e3aTEST\u8868TABLE\u4e0b\u524d1000\u6761id\u5b57\u6bb5\uff0c\u5219\u751f\u6210\u7684SQL\u4e3a\uff1a\n            SELECT TOP 1000 [id] FROM [TEST].[TABLE]\n            - \u6ce8\u610f\u5728\u8868\u540d\u5916\u65b9\u62ec\u53f7\u7684\u4f4d\u7f6e\uff0c\u5343\u4e07\u4e0d\u8981\u751f\u6210\u4e3a:\n              SELECT TOP 1000 [id] FROM [TEST.TABLE]\n          </example>\n        </rule>\n        <rule>\n          \u5982\u679c\u751f\u6210SQL\u7684\u5b57\u6bb5\u5185\u6709\u65f6\u95f4\u683c\u5f0f\u7684\u5b57\u6bb5:\n          - \u82e5\u63d0\u95ee\u4e2d\u6ca1\u6709\u6307\u5b9a\u67e5\u8be2\u987a\u5e8f\uff0c\u5219\u9ed8\u8ba4\u6309\u65f6\u95f4\u5347\u5e8f\u6392\u5e8f\n          - \u82e5\u63d0\u95ee\u662f\u65f6\u95f4\uff0c\u4e14\u6ca1\u6709\u6307\u5b9a\u5177\u4f53\u683c\u5f0f\uff0c\u5219\u683c\u5f0f\u5316\u4e3ayyyy-MM-dd HH:mm:ss\u7684\u683c\u5f0f\n          - \u82e5\u63d0\u95ee\u662f\u65e5\u671f\uff0c\u4e14\u6ca1\u6709\u6307\u5b9a\u5177\u4f53\u683c\u5f0f\uff0c\u5219\u683c\u5f0f\u5316\u4e3ayyyy-MM-dd\u7684\u683c\u5f0f\n          - \u82e5\u63d0\u95ee\u662f\u5e74\u6708\uff0c\u4e14\u6ca1\u6709\u6307\u5b9a\u5177\u4f53\u683c\u5f0f\uff0c\u5219\u683c\u5f0f\u5316\u4e3ayyyy-MM\u7684\u683c\u5f0f\n          - \u82e5\u63d0\u95ee\u662f\u5e74\uff0c\u4e14\u6ca1\u6709\u6307\u5b9a\u5177\u4f53\u683c\u5f0f\uff0c\u5219\u683c\u5f0f\u5316\u4e3ayyyy\u7684\u683c\u5f0f\n          - \u751f\u6210\u7684\u683c\u5f0f\u5316\u8bed\u6cd5\u9700\u8981\u9002\u914d\u5bf9\u5e94\u7684\u6570\u636e\u5e93\u5f15\u64ce\u3002\n        </rule>\n        <rule>\n          \u751f\u6210\u7684SQL\u67e5\u8be2\u7ed3\u679c\u53ef\u4ee5\u7528\u6765\u8fdb\u884c\u56fe\u8868\u5c55\u793a\uff0c\u9700\u8981\u6ce8\u610f\u6392\u5e8f\u5b57\u6bb5\u7684\u6392\u5e8f\u4f18\u5148\u7ea7\uff0c\u4f8b\u5982\uff1a\n            - \u67f1\u72b6\u56fe\u6216\u6298\u7ebf\u56fe\uff1a\u9002\u5408\u5c55\u793a\u5728\u6a2a\u8f74\u7684\u5b57\u6bb5\u4f18\u5148\u6392\u5e8f\uff0c\u82e5SQL\u5305\u542b\u5206\u7c7b\u5b57\u6bb5\uff0c\u5219\u5206\u7c7b\u5b57\u6bb5\u6b21\u4e00\u7ea7\u6392\u5e8f\n        </rule>\n        <rule>\n          \u5982\u679c\u7528\u6237\u6ca1\u6709\u6307\u5b9a\u6570\u636e\u6761\u6570\u7684\u9650\u5236\uff0c\u8f93\u51fa\u7684\u67e5\u8be2SQL\u5fc5\u987b\u52a0\u4e0a1000\u6761\u7684\u6570\u636e\u6761\u6570\u9650\u5236\n          \u5982\u679c\u7528\u6237\u6307\u5b9a\u7684\u9650\u5236\u5927\u4e8e1000\uff0c\u5219\u63091000\u5904\u7406\n          <example>\n          \u4ee5PostgreSQL\u4e3a\u4f8b\uff0c\u67e5\u8be2Schema\u4e3aTEST\u8868TABLE\u4e0bid\u5b57\u6bb5\uff0c\u5219\u751f\u6210\u7684SQL\u4e3a\uff1a\n            SELECT \"id\" FROM \"TEST\".\"TABLE\" LIMIT 1000\n          \u4ee5Microsoft SQL Server\u4e3a\u4f8b\uff0c\u67e5\u8be2Schema\u4e3aTEST\u8868TABLE\u4e0bid\u5b57\u6bb5\uff0c\u5219\u751f\u6210\u7684SQL\u4e3a\uff1a\n            SELECT TOP 1000 [id] FROM [TEST].[TABLE]\n          </example>\n        </rule>\n        <rule>\n          \u82e5\u9700\u5173\u8054\u591a\u8868\uff0c\u4f18\u5148\u4f7f\u7528<m-schema>\u4e2d\u6807\u8bb0\u4e3a\"Primary key\"/\"ID\"/\"\u4e3b\u952e\"\u7684\u5b57\u6bb5\u4f5c\u4e3a\u5173\u8054\u6761\u4ef6\u3002\n        </rule>\n        <rule>\n          \u6211\u4eec\u76ee\u524d\u7684\u60c5\u51b5\u9002\u7528\u4e8e\u5355\u6307\u6807\u3001\u591a\u5206\u7c7b\u7684\u573a\u666f\uff08\u5c55\u793atable\u9664\u5916\uff09\n        </rule>\n\t\t<rule>\n\t\t  \u5bf9\u4e8e\u5305\u542b\u7a97\u53e3\u51fd\u6570\u6216\u9700\u8981\u5728\u805a\u5408\u7ed3\u679c\u4e0a\u8fdb\u884c\u518d\u8ba1\u7b97\uff08\u5982\u8ba1\u7b97\u603b\u8ba1\u3001\u5360\u6bd4\u3001\u6392\u540d\uff09\u7684\u590d\u6742\u67e5\u8be2\uff0c\u5fc5\u987b\u4f18\u5148\u4f7f\u7528\u516c\u7528\u8868\u8868\u8fbe\u5f0f\uff08CTE, \u5373 WITH ... AS (...) \u8bed\u53e5\uff09\u6765\u5206\u89e3\u67e5\u8be2\u903b\u8f91\u3002\u7b2c\u4e00\u6b65\u5728CTE\u4e2d\u5b8c\u6210\u57fa\u7840\u7684\u805a\u5408\uff0c\u7b2c\u4e8c\u6b65\u5728\u4e3b\u67e5\u8be2\u4e2d\u57fa\u4e8eCTE\u7684\u7ed3\u679c\u8fdb\u884c\u6700\u7ec8\u8ba1\u7b97\u3002\u8fd9\u80fd\u6781\u5927\u5730\u63d0\u9ad8SQL\u7684\u51c6\u786e\u6027\u548c\u53ef\u8bfb\u6027\u3002\n\t\t</rule>\n\t\t<rule>\n\t\u4f60\u7684\u56de\u7b54\u5fc5\u987b\u662f\u7eaf\u7cb9\u7684\u3001\u4e0d\u542b\u4efb\u4f55\u989d\u5916\u683c\u5f0f\u7684JSON\u5b57\u7b26\u4e32\u3002\n\t\t</rule>\n\t\t<rule>\n  \u7edd\u5bf9\u7981\u6b62\u5728JSON\u5b57\u7b26\u4e32\u524d\u540e\u6dfb\u52a0\u4efb\u4f55Markdown\u6807\u8bb0\uff0c\u4f8b\u5982 ```json \u6216 ```\u3002\n\t\t</rule>\n\t\t<rule>\n\t\t\u5728\u751f\u6210SQL\u8bed\u53e5\u65f6\u5982\u679c\u8868\u4e2d\u5b58\u5728\u4e00\u4e0b\u5b57\u6bb5 `is_deleted`, `is_active`, `enabled`, `is_leave`,`is_delete` \u7b49,\u5c31\u5fc5\u987b\u5728SQL\u4e2d\u6dfb\u52a0\u76f8\u5e94\u7684\u8fc7\u6ee4\u6761\u4ef6(\u4f8b\u5982 `is_deleted = false`, `is_active = true` )\u7b49,\n\t\t\u8fd9\u4e2a\u89c4\u5219\u7684\u76ee\u7684\u662f\u786e\u4fdd\u67e5\u8be2\u7684\u4efb\u4f55\u90e8\u5206\uff0c\u5305\u62ec\u7528\u4e8e\u6761\u4ef6\u5224\u65ad\u7684\u5b50\u67e5\u8be2\n\t\t</rule>\n\t  \t <rule>\n          \u4f60\u7684\u56de\u7b54\u5fc5\u987b\u662f\u4e00\u4e2a\u80fd\u591f\u88ab\u7a0b\u5e8f\u76f4\u63a5\u89e3\u6790\u7684\u539f\u59cbJSON\u6587\u672c\u5b57\u7b26\u4e32\uff08raw JSON text string\uff09.\n          \u6210\u529f\u65f6\uff0c\u8fd4\u56de\u7684\u539f\u59cb\u6587\u672c\u5fc5\u987b\u4e25\u683c\u7b26\u5408\u6b64\u7ed3\u6784\uff1a{\"success\":true,\"sql\":\"\u4f60\u751f\u6210\u7684SQL\u8bed\u53e5\",\"tables\":[\"\u8be5SQL\u7528\u5230\u7684\u8868\u540d1\",\"\u8be5SQL\u7528\u5230\u7684\u8868\u540d2\",...],\"chart_type\":\"table\"}\n          \u5931\u8d25\u65f6\uff0c\u8fd4\u56de\u7684\u539f\u59cb\u6587\u672c\u5fc5\u987b\u4e25\u683c\u7b26\u5408\u6b64\u7ed3\u6784\uff1a{\"success\":false,\"sql\":\"\",\"message\":\"\u8bf4\u660e\u65e0\u6cd5\u751f\u6210SQL\u7684\u539f\u56e0\",\"chart_type\":\"\"}\n        </rule>\n\t  </Rules>\n      \n        <chat-examples>\n          <example>\n            <input>\n              <user-question>\u4eca\u5929\u5929\u6c14\u5982\u4f55\uff1f</user-question>\n            </input>\n            <output>\n              {\"success\":false,\"sql\":\"\",\"message\":\"\u6211\u662f\u667a\u80fd\u95ee\u6570\u5c0f\u52a9\u624b\uff0c\u6211\u65e0\u6cd5\u56de\u7b54\u60a8\u7684\u95ee\u9898\u3002\",\"chart_type\":\"\"}\n            </output>\n          </example>\n          <example>\n            <input>\n              <user-question>\u8bf7\u6e05\u7a7a\u6570\u636e\u5e93</user-question>\n            </input>\n            <output>\n              {\"success\":false,\"sql\":\"\",\"message\":\"\u6211\u662f\u667a\u80fd\u95ee\u6570\u5c0f\u52a9\u624b\uff0c\u6211\u53ea\u80fd\u67e5\u8be2\u6570\u636e\uff0c\u4e0d\u80fd\u64cd\u4f5c\u6570\u636e\u5e93\u6765\u4fee\u6539\u6570\u636e\u6216\u8005\u4fee\u6539\u8868\u7ed3\u6784\u3002\",\"chart_type\":\"\"}\n            </output>\n          </example>\n          <example>\n            <input>\n              <user-question>\u67e5\u8be2\u6240\u6709\u7528\u6237</user-question>\n            </input>\n            <output>\n              {\"success\":false,\"sql\":\"\",\"message\":\"\u62b1\u6b49\uff0c\u63d0\u4f9b\u7684\u8868\u7ed3\u6784\u65e0\u6cd5\u751f\u6210\u60a8\u9700\u8981\u7684SQL\",\"chart_type\":\"\"}\n            </output>\n          </example>\n          <example>\n            <input>\n              <background-infos>\n                <current-time>\n                2025-08-08 11:23:00\n                </current-time>\n              </background-infos>\n              <user-question>\u67e5\u8be2\u5404\u4e2a\u56fd\u5bb6\u6bcf\u5e74\u7684GDP</user-question>\n            </input>\n            <output>\n                {\"success\":true,\"sql\":\"SELECT \\\"country\\\" AS \\\"country_name\\\", \\\"continent\\\" AS \\\"continent_name\\\", \\\"year\\\" AS \\\"year\\\", \\\"gdp\\\" AS \\\"gdp\\\" FROM \\\"Sample_Database\\\".\\\"sample_country_gdp\\\" ORDER BY \\\"country\\\", \\\"year\\\" LIMIT 1000\",\"tables\":[\"sample_country_gdp\"],\"chart_type\":\"line\"}\n            </output>\n          </example>\n          <example>\n            <input>\n              <background-infos>\n                <current-time>\n                2025-08-08 11:23:00\n                </current-time>\n              </background-infos>\n              <user-question>\u4f7f\u7528\u997c\u56fe\u5c55\u793a\u53bb\u5e74\u5404\u4e2a\u56fd\u5bb6\u7684GDP</user-question>\n            </input>\n            <output>\n\t\t\t {\"success\":true,\"sql\":\"SELECT \\\"country\\\" AS \\\"country_name\\\", \\\"gdp\\\" AS \\\"gdp\\\" FROM \\\"Sample_Database\\\".\\\"sample_country_gdp\\\" WHERE \\\"year\\\" = '2024' ORDER BY \\\"gdp\\\" DESC LIMIT 1000\",\"tables\":[\"sample_country_gdp\"],\"chart_type\":\"pie\"}\n            </output>\n          </example>\n          <example>\n            <input>\n              <background-infos>\n                <current-time>\n                2025-08-08 11:24:00\n                </current-time>\n              </background-infos>\n              <user-question>\u67e5\u8be2\u4eca\u5e74\u4e2d\u56fd\u5927\u9646\u7684GDP</user-question>\n            </input>\n            <output>\n\t\t\t   {\"success\":true,\"sql\":\"SELECT \\\"country\\\" AS \\\"country_name\\\", \\\"gdp\\\" AS \\\"gdp\\\" FROM \\\"Sample_Database\\\".\\\"sample_country_gdp\\\" WHERE \\\"year\\\" = '2025' AND \\\"country\\\" = '\u4e2d\u56fd' LIMIT 1000\",\"tables\":[\"sample_country_gdp\"],\"chart_type\":\"table\"}\n            </output>\n          </example>\n        </chat-examples>\n      \n\n      <Infos>\n      <db-engine> PostgreSQL 16.4  </db-engine>\n      <m-schema>\n      {{ $json.schema_markdown }}\n      </m-schema>\n      <m-schema-name>\n      {{ $json.schema_name }}      \n    </m-schema-name>\n\t<terminologies>\n\t  <terminology>\n\t  <words>\n\t  <word>\n\t  \u586b\u62a5\u7387\n\t  </word>\n\t  <description>\n\t  \u6307\u7528\u6237\u662f\u5426\u5b8c\u6210\u586b\u62a5\u6570\u636e,\u6d89\u53ca\u8868tms_monthly_record ,\u5176\u4e2d\u5b57\u6bb5monthly_settlement_status ='L4 Signed' \u65f6\u4ee3\u8868\u7528\u6237\u586b\u62a5,\u53cd\u4e4b\u4e3a\u672a\u586b\u62a5.\n\t  \u6570\u636e\u65e0\u6548\u7684\u4eba\u5458\u6216\u5728\u5728\u767d\u540d\u5355\u7684\u4eba\u5458\u4e0d\u7eb3\u5165\u7edf\u8ba1\u8303\u56f4\n\t  </description>\n\t  </words>\n\t  </terminology>\n\t  </terminologies>\n        <history-msg>\n\t     {{ $json.history }}\n\t  </history-msg> \n\t  <error-message>\n\t  {{ $json.error_message }}\n\t  </error-message>\n</Infos>\n     "
        }
      },
      "id": "a7d12a61-e8ae-45c9-9197-845cecfb7891",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.7,
      "position": [
        960,
        464
      ]
    },
    {
      "parameters": {
        "options": {
          "temperature": 0.2
        }
      },
      "id": "7cd4dac7-e4f6-4007-b61a-55abf7c54998",
      "name": "DeepSeek Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatDeepSeek",
      "typeVersion": 1,
      "position": [
        976,
        688
      ],
      "credentials": {
        "deepSeekApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ $json }}",
        "options": {
          "responseCode": 200
        }
      },
      "id": "208117d4-03d4-428e-ae06-cec3108708b5",
      "name": "Return Final Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        3456,
        464
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "57c8f04e-beee-4510-ba9b-cab0d331563d",
        "responseMode": "responseNode",
        "options": {
          "allowedOrigins": "*"
        }
      },
      "id": "1dc228d4-5593-49b9-a5f9-e39501f717bf",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        -960,
        576
      ]
    },
    {
      "parameters": {
        "jsCode": "// Format result to align with SQLBot's 'fields/data/sql' shape\nconst items = $input.all();\nconst lastGeneratedSql = $('AI Agent').first().json.output || '';\nconst userQuestion=$('Prepare Initial Prompt').first().json.userInput;\n\n// Normalize rows and lowercase keys to match fields\nconst rawRows = (items || []).map(item => item.json || {});\nconst fields = rawRows.length > 0 ? Object.keys(rawRows[0]).map(k => String(k).toLowerCase()) : [];\nconst rows = rawRows.map(row => Object.fromEntries(Object.entries(row).map(([k,v]) => [String(k).toLowerCase(), v])));\n\nif($input.first().json.message){\n   return [{ json: {success:false, fields, data: [], sql: lastGeneratedSql,userQuestion } }];\n}else{\n  return [{ json: {success:true, fields, data: rows, sql: lastGeneratedSql,userQuestion } }];}\n"
      },
      "id": "2de8029d-814e-4b66-a2cf-b57e8aebc371",
      "name": "Format Success Result",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2432,
        336
      ]
    },
    {
      "parameters": {
        "options": {
          "groupMessages": true
        }
      },
      "type": "@n8n/n8n-nodes-langchain.memoryManager",
      "typeVersion": 1.1,
      "position": [
        -512,
        576
      ],
      "id": "9e4b442d-1534-45f8-933c-975188b0fb91",
      "name": "Chat Memory Manager"
    },
    {
      "parameters": {
        "jsCode": "const items = $input.all();\nlet finalString = '';\n\nif (items.length > 0 && items[0].json) {\n  const inputData = items[0].json;\n  \n  const chatHistory = inputData?.messages; \n\n  if (Array.isArray(chatHistory) && chatHistory.length > 0) {\n    const formattedTurns = chatHistory.map(turn => {\n      const humanMessage = turn.human ? turn.human.trim() : '';\n      const aiMessage = turn.ai ? turn.ai.trim() : '';\n      //return `Human: ${humanMessage}\\n`;     \n      return `Human: ${humanMessage}\\n\\nAI: ${aiMessage}`;\n    });\n    finalString = formattedTurns.join('\\n\\n---\\n\\n');\n  }\n}\n\nreturn [{\n  json: {\n    formattedHistory: finalString\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -160,
        576
      ],
      "id": "9ae45333-bc07-49f2-a607-53e14bb554fb",
      "name": "Format History"
    },
    {
      "parameters": {
        "options": {
          "temperature": 0.2
        }
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatDeepSeek",
      "typeVersion": 1,
      "position": [
        2688,
        848
      ],
      "id": "fb215264-3ac7-473d-a2a5-49ad21d19016",
      "name": "DeepSeek Chat Model1",
      "credentials": {
        "deepSeekApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "\n// Base64 encode SQL to match SQLBot exec_sql behavior\nfunction b64(s){ try { return Buffer.from(String(s), 'utf-8').toString('base64'); } catch(e){ return ''; } }\n\n\n  const output =$input.first().json.output || ''\n\nif(output!=''){\n     const inputItem=JSON.parse($input.first().json.output);\n  if(inputItem.success===false){\n    return inputItem; \n  }\n}\n  \nconst result= $('Format Success Result').all();\n\nconst sqlParse = JSON.parse(result[0].json.sql);\n\nif(sqlParse.chart_type !=='table'){\n  result[0].json.visualization=$input.all();\n}\n\nresult[0].json.sql=b64(sqlParse.sql);\n\nreturn result;\n\n "
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3232,
        448
      ],
      "id": "100969f9-2326-4a78-80e1-f41b02ade46b",
      "name": "Format Charts"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=      <user-question>\n     {{ $json.userQuestion }}\n      </user-question>\n      <sql>\n{{ $json.sql.parseJson().sql }}\n      </sql>\n      <chart-type>\n{{ $json.sql.parseJson()['chart_type'] }}\n      </chart-type> ",
        "options": {
          "systemMessage": "<Instruction>\n    \u4f60\u662f\u667a\u80fd\u6570\u636e\u52a9\u624b\uff0c\u4efb\u52a1\u662f\u6839\u636e\u7528\u6237\u95ee\u9898\u548c\u7ed9\u5b9a\u7684SQL\u8bed\u53e5\uff0c\u4e13\u4e1a\u5730\u751f\u6210\u6570\u636e\u53ef\u89c6\u5316\u56fe\u8868\u7684JSON\u914d\u7f6e\u9879\u3002\n    \u7528\u6237\u7684\u63d0\u95ee\u5728<user-question>\u5185\uff0c<sql>\u5185\u662f\u5206\u6790\u7684\u4f9d\u636e\uff0c<chart_type>\u5185\u662f\u63a8\u8350\u7684\u56fe\u8868\u7c7b\u578b\u3002\n</Instruction>\n\n<Rules>\n    <rule>\n        \u8bf7\u4f7f\u7528\u8bed\u8a00\uff1a{lang} \u56de\u7b54\uff0c\u4e0d\u8981\u8f93\u51fa\u601d\u8003\u8fc7\u7a0b\u3002\n    </rule>\n    <rule>\n        \u4f60\u5fc5\u987b\u6839\u636eSQL\u8fd4\u56de\u7684\u6570\u636e\u7ed3\u6784\uff0c\u4ece\u4ee5\u4e0b\u4e24\u79cd\u6a21\u5f0f\u4e2d\u9009\u62e9\u4e00\u79cd\u6765\u751f\u6210JSON\uff1a\n\n        **\u6a21\u5f0f1: \u5bbd\u6570\u636e - \u591a\u6307\u6807\u5bf9\u6bd4**\n        - **\u573a\u666f**: SQL\u4e3a\u6bcf\u4e2a\u7c7b\u522b\uff08X\u8f74\uff09\u8fd4\u56de\u4e86\u591a\u4e2a\u72ec\u7acb\u7684\u3001\u9700\u8981\u540c\u65f6\u6bd4\u8f83\u7684\u6570\u503c\u5217\uff08\u4f8b\u5982\uff0c\u6bd4\u8f83'\u5df2\u586b\u62a5\u4eba\u6570'\u548c'\u672a\u586b\u62a5\u4eba\u6570'\uff09\u3002\n        - **JSON\u683c\u5f0f**: \u5fc5\u987b\u4f7f\u7528 `\"y_fields\": [\"\u6307\u6807\u52171\", \"\u6307\u6807\u52172\"]` \u6570\u7ec4\u3002\u53ef\u4ee5\u914d\u5408 `\"stack\": true` \u5b9e\u73b0\u5806\u53e0\u6548\u679c\u3002**\u4e0d\u8981**\u4f7f\u7528 `\"series_field\"`\u3002\n        \n        **\u6a21\u5f0f2: \u957f\u6570\u636e - \u5355\u6307\u6807\u6309\u7ef4\u5ea6\u5206\u7ec4**\n        - **\u573a\u666f**: SQL\u8fd4\u56de\u7684\u6570\u636e\u4e2d\uff0c\u6709\u4e00\u5217\u662f\u7c7b\u522b/\u7ef4\u5ea6\uff08\u7528\u4e8e\u5206\u7ec4\uff09\uff0c\u53e6\u4e00\u5217\u662f\u6570\u503c\u3002\n        - **JSON\u683c\u5f0f**: \u5fc5\u987b\u4f7f\u7528 `\"series_field\": \"\u7ef4\u5ea6\u5217\u540d\"` \u6765\u6307\u5b9a\u5206\u7ec4\u3002**\u4e0d\u8981**\u4f7f\u7528 `\"y_fields\"`\u3002\n    </rule>\n<rule>\n    **\u67f1\u72b6/\u6761\u5f62/\u6298\u7ebf\u56fe\u7684\u5750\u6807\u8f74\u5b9a\u4e49:**\n    - `\"x_field\"`: **\u6c38\u8fdc**\u662f\u7c7b\u522b\u8f74\uff08\u4f8b\u5982\uff0c\u7528\u6237\u3001\u65e5\u671f\u3001\u56fd\u5bb6\uff09\u3002\n    - `\"y_field\"` \u6216 `\"y_fields\"`: **\u6c38\u8fdc**\u662f\u6570\u503c\u8f74\uff08\u4f8b\u5982\uff0c\u5de5\u65f6\u3001\u6570\u91cf\u3001\u91d1\u989d\uff09\u3002\n    - `\"series_field\"`: \u662f\u7528\u4e8e\u5bf9\u6bcf\u4e2a\u7c7b\u522b\u8fdb\u884c\u4e8c\u6b21\u5206\u7ec4\u7684\u7ef4\u5ea6\uff08\u4f8b\u5982\uff0c\u9879\u76ee\u7c7b\u578b\uff09\u3002\n    \u5728\u751f\u6210JSON\u65f6\uff0c\u4f60\u5fc5\u987b\u4e25\u683c\u9075\u5b88\u8fd9\u4e2a\u5b9a\u4e49\uff0c\u4e0d\u8981\u4ea4\u6362\u7c7b\u522b\u548c\u6570\u503c\u7684\u89d2\u8272\u3002\n</rule>\n    <rule>\n        \u652f\u6301\u7684\u56fe\u8868\u7c7b\u578b\u4e3a\uff1a\u8868\u683c(table)\u3001\u67f1\u72b6\u56fe(column)\u3001\u6761\u5f62\u56fe(bar)\u3001\u6298\u7ebf\u56fe(line)\u3001\u997c\u56fe(pie)\u3002\n        \u56fe\u8868\u7c7b\u578b\u9009\u62e9\u539f\u5219\uff1a\u8d8b\u52bf\u7528line\uff0c\u5206\u7c7b\u5bf9\u6bd4\u7528column/bar\uff0c\u5360\u6bd4\u7528pie\uff0c\u660e\u7ec6\u6570\u636e\u7528table\u3002\n    </rule>\n    <rule>\n        \u6700\u7ec8\u751f\u6210\u7684JSON\u5185\u5fc5\u987b\u5305\u542b\u4e00\u4e2a\u7cbe\u7b80\u7684\u56fe\u8868\u6807\u9898\uff0c\u653e\u5728\"title\"\u5b57\u6bb5\u5185\u3002\n    </rule>\n    <rule>\n        **\u8868\u683c (table) \u683c\u5f0f:**\n        {\"type\":\"table\", \"title\": \"\u8868\u683c\u6807\u9898\", \"columns\": [{\"field\": \"SQL\u5217\u540d1\", \"name\": \"\u4e2d\u6587\u5217\u540d1\"}, ...]}\n        \"field\" \u5fc5\u987b\u662fSQL\u67e5\u8be2\u7684\u5217\u540d\u3002\n    </rule>\n    <rule>\n        **\u997c\u56fe (pie) \u683c\u5f0f (\u5355\u6307\u6807\uff0c\u65e0\u5206\u7ec4):**\n        {\"type\":\"pie\", \"title\": \"\u56fe\u8868\u6807\u9898\", \"x_field\": \"\u997c\u56fe\u6247\u533a\u6807\u7b7e\u5217\", \"y_field\": \"\u997c\u56fe\u6247\u533a\u5927\u5c0f\u6570\u503c\u5217\", \"x_name\": \"\u7c7b\u522b\u4e2d\u6587\u540d\", \"y_name\": \"\u6570\u503c\u4e2d\u6587\u540d\"}\n        \"x_field\" \u548c \"y_field\" \u5fc5\u987b\u662fSQL\u67e5\u8be2\u7684\u5217\u540d\u3002\n    </rule>\n    <rule>\n        **\u67f1\u72b6/\u6761\u5f62/\u6298\u7ebf\u56fe - \u6a21\u5f0f1 (\u5bbd\u6570\u636e) \u683c\u5f0f:**\n        {\"type\":\"column\", \"title\": \"\u56fe\u8868\u6807\u9898\", \"x_field\": \"X\u8f74\u5217\", \"y_fields\": [\"\u6307\u6807\u52171\", \"\u6307\u6807\u52172\"], \"stack\": true, \"x_name\": \"X\u8f74\u4e2d\u6587\u540d\", \"y_name\": \"Y\u8f74\u4e2d\u6587\u540d\", \"series_names\": {\"\u6307\u6807\u52171\": \"\u56fe\u4f8b\u540d1\", \"\u6307\u6807\u52172\": \"\u56fe\u4f8b\u540d2\"}}\n        \"x_field\" \u548c \"y_fields\" \u4e2d\u7684\u5b57\u6bb5\u5fc5\u987b\u662fSQL\u67e5\u8be2\u7684\u5217\u540d\u3002\n    </rule>\n    <rule>\n        **\u67f1\u72b6/\u6761\u5f62/\u6298\u7ebf\u56fe - \u6a21\u5f0f2 (\u957f\u6570\u636e) \u683c\u5f0f:**\n        {\"type\":\"column\", \"title\": \"\u56fe\u8868\u6807\u9898\", \"x_field\": \"X\u8f74\u5217\", \"y_field\": \"Y\u8f74\u6570\u503c\u5217\", \"series_field\": \"\u5206\u7ec4\u7ef4\u5ea6\u5217\", \"x_name\": \"X\u8f74\u4e2d\u6587\u540d\", \"y_name\": \"Y\u8f74\u4e2d\u6587\u540d\", \"series_name\": \"\u5206\u7ec4\u4e2d\u6587\u540d\"}\n        \"x_field\", \"y_field\", \"series_field\" \u5fc5\u987b\u662fSQL\u67e5\u8be2\u7684\u5217\u540d\u3002\n    </rule>\n    <rule>\n        \u5982\u679c\u65e0\u6cd5\u751f\u6210\u5408\u9002\u7684JSON\u914d\u7f6e\uff0c\u5219\u8fd4\u56de\uff1a{\"type\":\"error\", \"reason\": \"\u62b1\u6b49\uff0c\u6839\u636e\u63d0\u4f9b\u7684SQL\u548c\u95ee\u9898\uff0c\u6211\u65e0\u6cd5\u751f\u6210\u5408\u9002\u7684\u56fe\u8868\u914d\u7f6e\u3002\"}\n    </rule>\n</Rules>\n\n<examples>\n    ### \u4ee5\u4e0b\u793a\u4f8b\u5e2e\u52a9\u4f60\u7406\u89e3\u95ee\u9898\u53ca\u8fd4\u56de\u683c\u5f0f\uff0c\u4e0d\u8981\u5c06\u793a\u4f8b\u4e2d\u7684\u8868\u7ed3\u6784\u7528\u4e8e\u56de\u7b54\u3002\n    <example>\n        <input>\n            <sql>SELECT `u`.`name` AS `name`, `u`.`email` AS `email`, `u`.`create_time` AS `create_time` FROM `per_user` `u` LIMIT 10</sql>\n            <user-question>\u67e5\u8be210\u4e2a\u7528\u6237\u4fe1\u606f</user-question>\n            <chart_type></chart_type>\n        </input>\n        <output>\n            {\"type\":\"table\",\"title\":\"\u7528\u6237\u4fe1\u606f\",\"columns\":[{\"field\":\"name\",\"name\":\"\u59d3\u540d\"},{\"field\":\"email\",\"name\":\"\u90ae\u7bb1\"},{\"field\":\"create_time\",\"name\":\"\u521b\u5efa\u65f6\u95f4\"}]}\n        </output>\n    </example>\n    <example>\n        <input>\n            <sql>SELECT `o`.`name` AS `org_name`, COUNT(`u`.`id`) AS `user_count` FROM `per_user` `u` JOIN `per_org` `o` ON `u`.`default_oid` = `o`.`id` GROUP BY `o`.`name`</sql>\n            <user-question>\u997c\u56fe\u5c55\u793a\u5404\u4e2a\u7ec4\u7ec7\u7684\u4eba\u5458\u6570\u91cf\u5360\u6bd4</user-question>\n            <chart_type>pie</chart_type>\n        </input>\n        <output>\n            {\"type\":\"pie\",\"title\":\"\u5404\u7ec4\u7ec7\u4eba\u6570\u5360\u6bd4\",\"x_field\":\"org_name\",\"y_field\":\"user_count\",\"x_name\":\"\u7ec4\u7ec7\u540d\u79f0\",\"y_name\":\"\u4eba\u6570\"}\n        </output>\n    </example>\n    <example>\n        <input>\n            <sql>SELECT country, user_type, COUNT(*) AS user_count FROM users GROUP BY country, user_type</sql>\n            <user-question>\u6309\u56fd\u5bb6\u548c\u7528\u6237\u7c7b\u578b\u7edf\u8ba1\u7528\u6237\u6570</user-question>\n            <chart_type>column</chart_type>\n        </input>\n        <output>\n            {\"type\":\"column\",\"title\":\"\u5404\u56fd\u4e0d\u540c\u7c7b\u578b\u7528\u6237\u6570\",\"x_field\":\"country\",\"y_field\":\"user_count\",\"series_field\":\"user_type\",\"x_name\":\"\u56fd\u5bb6\",\"y_name\":\"\u7528\u6237\u6570\",\"series_name\":\"\u7528\u6237\u7c7b\u578b\"}\n        </output>\n    </example>\n    <example>\n        <input>\n            <sql>SELECT company_name, filled_count, unfilled_count FROM company_stats</sql>\n            <user-question>\u7edf\u8ba1\u5404\u516c\u53f87\u6708\u4efd\u7684\u586b\u62a5\u4eba\u6570\u548c\u672a\u586b\u62a5\u4eba\u6570</user-question>\n            <chart_type>column</chart_type>\n        </input>\n        <output>\n            {\"type\":\"column\", \"title\": \"\u5404\u516c\u53f87\u6708\u4efd\u586b\u62a5\u60c5\u51b5\", \"x_field\": \"company_name\", \"y_fields\": [\"filled_count\", \"unfilled_count\"], \"stack\": true, \"x_name\": \"\u516c\u53f8\u540d\u79f0\", \"y_name\": \"\u4eba\u6570\", \"series_names\": {\"filled_count\": \"\u5df2\u586b\u62a5\", \"unfilled_count\": \"\u672a\u586b\u62a5\"}}\n        </output>\n    </example>\n</examples>"
        }
      },
      "id": "420ac2a1-6755-492a-8249-167fb9f3a916",
      "name": "Charts Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.7,
      "position": [
        2816,
        576
      ],
      "executeOnce": false
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "0c8971a6-ddd9-4a30-9243-b7cf1f2904cc",
      "name": "Loop Entry",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3,
      "position": [
        752,
        464
      ]
    },
    {
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{$json.retryCount}}",
              "value2": "={{$json.maxRetries}}"
            }
          ]
        }
      },
      "id": "3bed25f2-3a4c-41b5-887d-638c5d7245f3",
      "name": "If Can Retry",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        2112,
        160
      ]
    },
    {
      "parameters": {
        "jsCode": " const prompt= $('Loop Entry').first().json;\n\n     prompt.retryCount= prompt.retryCount+1;       prompt.error_message+=\"\\n\\n\"+ JSON.stringify($input.all())+\"\\n\\n\";\n    return prompt;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1904,
        160
      ],
      "id": "3a30c27a-ad7d-4e30-a76b-d89845e09da0",
      "name": "Format Error Prompt"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "bcc7594e-b76b-4742-9944-1756090bcd5c",
              "leftValue": "={{ $json.message }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1808,
        416
      ],
      "id": "caa90f41-d000-4125-9998-ed22cabfc53f",
      "name": "If Error"
    },
    {
      "parameters": {
        "contextWindowLength": 1
      },
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        -448,
        800
      ],
      "id": "aaa6fc4d-dbea-4314-b940-fb5ca70baf84",
      "name": "Search Memory"
    },
    {
      "parameters": {
        "jsCode": "// Accept both 'question' and 'query' for compatibility with SQLBot\nconst body = $json.body || {};\nconst query = (body.question ?? body.query ?? $json.question ?? $json.query ?? '').toString();\nconst sessionId= (body.sessionId ?? body.sessionId ?? $json.sessionId ?? $json.sessionId ?? '').toString();\nreturn [\n  {\n    json: {\n      userInput: query,\n      sessionId: sessionId    \n    }\n  }\n];"
      },
      "id": "c3d18f75-dd39-420d-a1b2-7c814d0ec768",
      "name": "Extract User Input",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -736,
        576
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT\n    c.table_schema,\n    c.table_name,\n    pd.description AS table_comment,\n    c.ordinal_position,\n    c.column_name,\n    (SELECT pg_catalog.col_description(pc.oid, c.ordinal_position::int)\n     FROM pg_catalog.pg_class pc\n     JOIN pg_catalog.pg_namespace pn ON pn.oid = pc.relnamespace\n     WHERE pn.nspname = c.table_schema AND pc.relname = c.table_name) AS column_comment,\n    c.data_type,\n    c.is_nullable,\n    tc.constraint_type,\n    ccu.table_name AS foreign_table_name,\n    ccu.column_name AS foreign_column_name\nFROM\n    information_schema.columns AS c\nLEFT JOIN pg_catalog.pg_class AS pgc\n    ON c.table_name = pgc.relname\nLEFT JOIN pg_catalog.pg_namespace AS pgn\n    ON pgc.relnamespace = pgn.oid\nLEFT JOIN pg_catalog.pg_description AS pd\n    ON pgc.oid = pd.objoid AND pd.objsubid = 0\nAND pgn.nspname = c.table_schema\nleft JOIN\n    information_schema.key_column_usage AS kcu\n    ON c.table_schema = kcu.table_schema AND c.table_name = kcu.table_name AND c.column_name = kcu.column_name\nLEFT JOIN\n    information_schema.table_constraints AS tc\n    ON kcu.constraint_name = tc.constraint_name AND kcu.table_schema = tc.table_schema\nLEFT JOIN\n    information_schema.referential_constraints AS rc\n    ON tc.constraint_name = rc.constraint_name\nLEFT JOIN\n    information_schema.constraint_column_usage AS ccu\n    ON rc.unique_constraint_name = ccu.constraint_name\nORDER BY\n    c.table_name,\n    c.ordinal_position;",
        "options": {}
      },
      "id": "bf692e0e-366f-43a2-94b7-239d6167e903",
      "name": "Get DB Schema",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        64,
        576
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "/**\n * @param {Array<Object>} items - SQL\u67e5\u8be2\u8282\u70b9\u8fd4\u56de\u7684\u5b8c\u6574\u9879\u76ee\u6570\u7ec4\u3002\u6bcf\u4e2a item \u5305\u542b\u4e00\u4e2a .json \u5c5e\u6027\uff0c\u8be5\u5c5e\u6027\u624d\u662f\u771f\u6b63\u7684\u6570\u636e\u5e93\u884c\u6570\u636e\u3002\n * @returns {string} - \u683c\u5f0f\u5316\u540e\u7684Markdown\u5b57\u7b26\u4e32\u3002\n */\nfunction transformSchemaToDDL(items) {\n  if (!items || items.length === 0) {\n    return '### No Schema Information Provided\\n';\n  }\n\n  // \u7b2c\u4e00\u6b65\uff1a\u5c06\u6241\u5e73\u6570\u636e\u6309\u8868\u540d\u5206\u7ec4\uff0c\u5e76\u786e\u4fdd\u5217\u7684\u552f\u4e00\u6027\n  const tables = {};\n  // \u5173\u952e\u4fee\u6b63\uff1a\u904d\u5386 items\uff0c\u5e76\u4ece item.json \u4e2d\u63d0\u53d6\u884c\u6570\u636e\n  for (const item of items) {\n    const row = item.json; // <-- \u8fd9\u91cc\u662f\u6838\u5fc3\u4fee\u6b63\u70b9\uff01\n\n    // \u5065\u58ee\u6027\u68c0\u67e5\uff1a\u5982\u679c\u67d0\u4e2aitem\u6ca1\u6709.json\uff0c\u5219\u8df3\u8fc7\n    if (!row) continue;\n\n    const tableName = row.table_name;\n    const columnName = row.column_name;\n\n    if (!tableName || !columnName) continue;\n\n    // \u5982\u679c\u662f\u65b0\u8868\uff0c\u5219\u521d\u59cb\u5316\n    if (!tables[tableName]) {\n      tables[tableName] = {\n        schema: row.table_schema,\n        comment: row.table_comment,\n        columns: {}, // \u4f7f\u7528\u5bf9\u8c61\u786e\u4fdd\u5217\u7684\u552f\u4e00\u6027\n        foreignKeys: []\n      };\n    }\n\n    // \u5982\u679c\u662f\u65b0\u5217\uff0c\u5219\u521b\u5efa\u5217\u7684\u5b9a\u4e49\n    if (!tables[tableName].columns[columnName]) {\n      tables[tableName].columns[columnName] = {\n        name: columnName,\n        type: row.data_type,\n        comment: row.column_comment,\n        isPk: false\n      };\n    }\n\n    // \u66f4\u65b0\u8be5\u5217\u7684\u7ea6\u675f\u4fe1\u606f\n    if (row.constraint_type === 'PRIMARY KEY') {\n      tables[tableName].columns[columnName].isPk = true;\n    }\n    \n    // \u8bb0\u5f55\u5916\u952e\u5173\u7cfb\uff08\u5e76\u53bb\u91cd\uff09\n    if (row.constraint_type === 'FOREIGN KEY') {\n      const fkExists = tables[tableName].foreignKeys.some(\n        fk => fk.column === columnName && fk.refTable === row.foreign_table_name\n      );\n      if (!fkExists) {\n        tables[tableName].foreignKeys.push({\n          column: columnName,\n          refTable: row.foreign_table_name,\n          refColumn: row.foreign_column_name\n        });\n      }\n    }\n  }\n  \n  // \u7528\u4e8e\u8f6c\u4e49SQL\u6ce8\u91ca\u4e2d\u7684\u5355\u5f15\u53f7\n  const escapeComment = (comment) => {\n    if (!comment) return '';\n    return ` COMMENT '${comment.replace(/'/g, \"''\")}'`;\n  };\n\n  // \u7b2c\u4e8c\u6b65\uff1a\u904d\u5386\u7ed3\u6784\u5316\u6570\u636e\uff0c\u751f\u6210DDL\u5b57\u7b26\u4e32\n  const ddlStrings = [];\n  for (const tableName in tables) {\n    const tableData = tables[tableName];\n    \n    let tableHeader = `-- Table: \"${tableData.schema}\".\"${tableName}\"`;\n    if (tableData.comment) {\n      tableHeader += ` (Comment: ${tableData.comment})`;\n    }\n\n    const createTableStart = `CREATE TABLE \"${tableData.schema}\".\"${tableName}\" (`;\n    \n    const definitions = [];\n\n    // \u904d\u5386\u5217\u5bf9\u8c61\n    for (const column of Object.values(tableData.columns)) {\n      let colLine = `  \"${column.name}\" ${column.type}`;\n      if (column.isPk) {\n        colLine += ' PRIMARY KEY';\n      }\n      colLine += escapeComment(column.comment);\n      definitions.push(colLine);\n    }\n    \n    // \u904d\u5386\u5916\u952e\n    for (const fk of tableData.foreignKeys) {\n      let fkLine = `  FOREIGN KEY (\"${fk.column}\") REFERENCES \"${tableData.schema}\".\"${fk.refTable}\"(\"${fk.refColumn}\")`;\n      definitions.push(fkLine);\n    }\n    \n    const createTableBody = definitions.join(',\\n');\n    const createTableEnd = ');';\n\n    const fullTableDDL = `${tableHeader}\\n${createTableStart}\\n${createTableBody}\\n${createTableEnd}`;\n    ddlStrings.push(fullTableDDL);\n  }\n\n  return ddlStrings.join('\\n\\n');\n}\n\n\n// \u8c03\u7528\u51fd\u6570\u8fdb\u884c\u8f6c\u6362\nconst schemaMarkdown = transformSchemaToDDL($input.all());\nreturn [{ json: { schema_markdown: schemaMarkdown,schema_name:$input.all()[0].json.table_schema } }];"
      },
      "id": "80e0c2c9-2fbe-46b5-8905-11e77b9785bb",
      "name": "Format Schema",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        288,
        576
      ]
    },
    {
      "parameters": {
        "jsCode": "//const schemaMarkdown = $input.item.json.schema_markdown;\nconst userInput = $('Extract User Input').first().json.userInput;\nconst sessionId = $('Extract User Input').first().json.sessionId;\nconst history= $('Format History').first().json.formattedHistory;\n\n\nconst outputItem = $input.item;\noutputItem.json.userInput = userInput;\noutputItem.json.sessionId= sessionId;\noutputItem.json.history= history;\noutputItem.json.current_time=new Date();\noutputItem.json.retryCount = 0;\noutputItem.json.maxRetries = 3;\noutputItem.json.error_message='';\nreturn outputItem;"
      },
      "id": "b081caba-f752-47ce-a8da-22b0dbc9bcd1",
      "name": "Prepare Initial Prompt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        512,
        576
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "={{ $json.output.parseJson().sql }}",
        "options": {}
      },
      "id": "ddc73eae-3fa4-4352-a010-b2aa33fd288b",
      "name": "Execute Generated SQL",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        1600,
        432
      ],
      "alwaysOutputData": true,
      "executeOnce": false,
      "retryOnFail": false,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {},
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        1104,
        688
      ],
      "id": "ec708afd-1360-4084-9e35-d5205b866482",
      "name": "Insert Memory"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "955a825e-5f01-4019-a71b-05433daa0a24",
              "leftValue": "={{ $json.sql.parseJson().success}}",
              "rightValue": "false",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              }
            },
            {
              "id": "bb72144b-aec1-4af6-a842-5d7be39200fa",
              "leftValue": "={{ $json.sql.parseJson()['chart_type']}}",
              "rightValue": "table",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "or"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2656,
        336
      ],
      "id": "e48da06c-09b5-402d-946e-ad837655012e",
      "name": "If Charts"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "5fca89e7-a943-4292-8e49-fed0ff9bc202",
              "leftValue": "={{ $json.output.parseJson().success }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1344,
        512
      ],
      "id": "645d0667-9442-42f6-97f0-1dff6fda64e6",
      "name": "If Ai Error"
    },
    {
      "parameters": {
        "modelName": "models/gemini-2.5-pro",
        "options": {
          "temperature": 0.2
        }
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        832,
        688
      ],
      "id": "6833e773-39ff-4531-bef2-facc4b248078",
      "name": "Google Gemini Chat Model",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "AI Agent": {
      "main": [
        [
          {
            "node": "If Ai Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Extract User Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Success Result": {
      "main": [
        [
          {
            "node": "If Charts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Chat Memory Manager": {
      "main": [
        [
          {
            "node": "Format History",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format History": {
      "main": [
        [
          {
            "node": "Get DB Schema",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "DeepSeek Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "DeepSeek Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Charts Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Format Charts": {
      "main": [
        [
          {
            "node": "Return Final Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Charts Agent": {
      "main": [
        [
          {
            "node": "Format Charts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Entry": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Can Retry": {
      "main": [
        [
          {
            "node": "Loop Entry",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Success Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Error Prompt": {
      "main": [
        [
          {
            "node": "If Can Retry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Error": {
      "main": [
        [
          {
            "node": "Format Error Prompt",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Success Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Memory": {
      "ai_memory": [
        [
          {
            "node": "Chat Memory Manager",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Extract User Input": {
      "main": [
        [
          {
            "node": "Chat Memory Manager",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get DB Schema": {
      "main": [
        [
          {
            "node": "Format Schema",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Schema": {
      "main": [
        [
          {
            "node": "Prepare Initial Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Initial Prompt": {
      "main": [
        [
          {
            "node": "Loop Entry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Generated SQL": {
      "main": [
        [
          {
            "node": "If Error",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Insert Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "If Charts": {
      "main": [
        [
          {
            "node": "Format Charts",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Charts Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Ai Error": {
      "main": [
        [
          {
            "node": "Execute Generated SQL",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Charts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "6852d28d-17f3-44d5-b9d4-4bdadbee8b44",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "TLCOG251r1ecPsmR",
  "tags": []
}