{
  "nodes": [
    {
      "id": "70bedb4b-6fe6-4cf0-86c5-e3c8e78fa256",
      "name": "Ultimate Assistant1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        480,
        100
      ],
      "parameters": {
        "text": "={{ $json.body.message }}",
        "options": {
          "systemMessage": "=# Overview\nYou are the ultimate personal assistant. Your job is to figure out the right tool to use, if applicable to the user's prompt.\n\n## Rules\n{{ \"- \" + $json.rules.join(\"\\n- \") }}\n\n## Rule Database Schema: \nTable name: datos_agent_rules\n[\n  {\n    \"column_name\": \"id\",\n    \"data_type\": \"bigint\",\n    \"character_maximum_length\": null,\n    \"is_nullable\": \"NO\",\n    \"column_default\": null\n  },\n  {\n    \"column_name\": \"created_at\",\n    \"data_type\": \"timestamp with time zone\",\n    \"character_maximum_length\": null,\n    \"is_nullable\": \"NO\",\n    \"column_default\": \"now()\"\n  },\n  {\n    \"column_name\": \"rule_text\",\n    \"data_type\": \"text\",\n    \"character_maximum_length\": null,\n    \"is_nullable\": \"YES\",\n    \"column_default\": null\n  },\n  {\n    \"column_name\": \"agent\",\n    \"data_type\": \"text\",\n    \"character_maximum_length\": null,\n    \"is_nullable\": \"YES\",\n    \"column_default\": null\n  }\n]\n\n## Final Context:\n- Here is the current date/time: {{ $now.toISO() }}\n- UNIX timestamp for current date/time: {{ $now.toMillis() }}\n- The user's timezone is PST\n- The user's name is Giovanni Segar (or Gio for short)",
          "returnIntermediateSteps": true
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "53fc82b4-81d2-4e4d-8bdb-fb253a513626",
      "name": "Chat History1",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        540,
        360
      ],
      "parameters": {
        "contextWindowLength": 10
      },
      "typeVersion": 1.3
    },
    {
      "id": "a7108939-61f7-40f1-8c35-8ed7410fc45a",
      "name": "Anthropic Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        360,
        360
      ],
      "parameters": {
        "model": "=claude-sonnet-4-20250514",
        "options": {
          "temperature": 0.2
        }
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6765ccef-d5ad-4040-9378-67fe0019e7c7",
      "name": "Get rules from database",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -180,
        -20
      ],
      "parameters": {
        "query": "SELECT rule_text FROM datos_agent_rules WHERE agent = 'TestAgent';",
        "options": {},
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "33e63152-923a-4b61-a9b1-71b8c43ba90d",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        260,
        100
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.1
    },
    {
      "id": "e0343829-da12-4ed7-a610-8353168a2562",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        40,
        -20
      ],
      "parameters": {
        "options": {},
        "fieldsToAggregate": {
          "fieldToAggregate": [
            {
              "renameField": true,
              "outputFieldName": "rules",
              "fieldToAggregate": "rule_text"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "cae47efc-4063-412a-bdc4-366f1cdb5308",
      "name": "Insert rule into database",
      "type": "n8n-nodes-base.postgresTool",
      "position": [
        920,
        340
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "datos_agent_rules",
          "cachedResultName": "datos_agent_rules"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "columns": {
          "value": {
            "agent": "TestAgent",
            "rule_text": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('rule_text', `Write a simple reminder for the future based on the user's instructions. `, 'string') }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "number",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "created_at",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "created_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "rule_text",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "rule_text",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "agent",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "agent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "descriptionType": "manual",
        "toolDescription": "This should be used when the user corrects you in some way to add a rule that will be included in the future prompts. This can be specific to a certain client or can be a general rule for how to do things. Make sure to let the user know if you added a rule."
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "edda3371-1237-405e-a76e-bda1e0253b80",
      "name": "Execute query on rule database",
      "type": "n8n-nodes-base.postgresTool",
      "position": [
        1100,
        340
      ],
      "parameters": {
        "query": "{{ $fromAI('valid_postgres_sql_query', 'Write any valid SQL query for the Postgres rule database.', 'string') }}",
        "options": {},
        "operation": "executeQuery",
        "descriptionType": "manual",
        "toolDescription": "Use this to get rules and their IDs for modification, delete items, add multiple items, or any other operation not covered by the simple insert tool"
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "f5348ce3-3600-4dab-a784-6455fb9f53f2",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -460,
        120
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "e154a1e8-0e6f-4e04-b97a-803ec33908ac",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1100,
        360
      ],
      "parameters": {
        "width": 1000,
        "height": 760,
        "content": "## Video walkthrough\n\n@[youtube](OwIFK-r-NtQ)\nhttps://www.youtube.com/watch?v=OwIFK-r-NtQ\n\n## Summary of agent\nThis agent can write and rewrite its own rules, allowing you to mold its behavior. It receives rules from a database as system instructions and has tools to create, edit, or delete them. This is a great baseline for new agent builds.\n\n## How to start using it\n\n### Option 1: With a Postgres database (e.g., Supabase)\n1.  **Supabase Schema:** Create a table (e.g., `agent_rules`) with the following columns:\n    *   `id`: `bigint` (Primary Key, auto-incrementing)\n    *   `created_at`: `timestamp with time zone` (Default: `now()`)\n    *   `rule_text`: `text`\n    *   `agent`: `text`\n2.  **Workflow Updates:**\n    *   Update the **Postgres credentials** in the \"Get rules from database,\" \"Insert rule into database,\" and \"Execute query on rule database\" nodes.\n    *   Update the `agent` value (currently 'TestAgent') in the \"Get rules from database\" and \"Insert rule into database\" nodes if you want a different agent name.\n    *   Update the **Anthropic API credentials**.\n\n### Option 2: With Google Sheets\n1.  **Google Sheet Setup:** Create a Google Sheet with columns for `rule_text` and `agent`.\n2.  **Workflow Updates:**\n    *   Example Google Sheets nodes are included. You will need to:\n        *   Connect your **Google Sheets credentials**.\n        *   Select your Google Sheet (with `rule_text` and `agent` columns) in all relevant Google Sheets nodes.\n        *   Replace the existing Postgres nodes (\"Get rules from database\", \"Insert rule into database\", \"Execute query on rule database\") with the configured Google Sheets nodes.\n    *   Update the `agent` value (currently 'TestAgent') in the Google Sheets nodes if you want a different agent name.\n    *   Update the **Anthropic API credentials**.\n    *   **Agent Instructions:** Update the agent's system message and remove the database schema section as it is no longer relevant"
      },
      "typeVersion": 1
    },
    {
      "id": "1adbc807-44ce-4c35-800f-5dc0092e0aad",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        60,
        580
      ],
      "parameters": {
        "color": 4,
        "width": 1240,
        "height": 540,
        "content": "## Prefer Google Sheets? Here are nodes to replace Postgres"
      },
      "typeVersion": 1
    },
    {
      "id": "e6f9a9c7-a498-46b0-88ac-ef693288ec18",
      "name": "Get rules from sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        140,
        680
      ],
      "parameters": {
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "728c29e0-bd0f-4237-823b-1ca01de880ef",
      "name": "Add rule to sheet",
      "type": "n8n-nodes-base.googleSheetsTool",
      "position": [
        400,
        700
      ],
      "parameters": {
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "descriptionType": "manual",
        "toolDescription": "Use this to add rules to the google sheet"
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "41c75ff2-cbab-4ec7-b5ff-858d5abbecb4",
      "name": "Update rule in sheet",
      "type": "n8n-nodes-base.googleSheetsTool",
      "position": [
        580,
        700
      ],
      "parameters": {
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "descriptionType": "manual",
        "toolDescription": "Use this to update an existing rule in the sheet"
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "6fd802ea-84ae-49bd-8e56-f966509a21e8",
      "name": "Delete rule in sheet",
      "type": "n8n-nodes-base.googleSheetsTool",
      "position": [
        720,
        700
      ],
      "parameters": {
        "operation": "delete",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "descriptionType": "manual",
        "toolDescription": "Use this to delete an existing rule in the sheet"
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    }
  ],
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Ultimate Assistant1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Chat History1": {
      "ai_memory": [
        [
          {
            "node": "Ultimate Assistant1",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Anthropic Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Ultimate Assistant1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Get rules from database": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert rule into database": {
      "ai_tool": [
        [
          {
            "node": "Ultimate Assistant1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          },
          {
            "node": "Get rules from database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute query on rule database": {
      "ai_tool": [
        [
          {
            "node": "Ultimate Assistant1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  }
}