{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "6aee89e6-1147-415b-aa55-af6fceb67fee",
      "name": "Form: Add to KB",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        1456,
        880
      ],
      "parameters": {
        "options": {},
        "formTitle": "Add to KB",
        "formFields": {
          "values": [
            {
              "fieldType": "textarea",
              "fieldLabel": "content",
              "placeholder": "\ud83d\udcdd Paste your past post or idea here\u2026",
              "requiredField": true
            },
            {
              "fieldLabel": "topic",
              "placeholder": "\ud83d\udcac e.g. creator_mindset, ai_automation, productivity"
            }
          ]
        },
        "formDescription": "Paste your past posts or notes. Optionally tag topic and mark as style sample."
      },
      "typeVersion": 2.2
    },
    {
      "id": "20b70111-5194-41fb-8ea4-07c71dfdfa00",
      "name": "Normalize (ingest)",
      "type": "n8n-nodes-base.set",
      "position": [
        1680,
        880
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={{ ({ content: $json.fields.content, topic: ($json.fields.topic || ''), style: 'true' }) }}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "e513bb3f-3cfe-420a-8365-d9cc20d2a90b",
      "name": "Embeddings OpenAI (ingest)",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        1904,
        896
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c63114f2-ef60-4796-b8af-5f434382eaba",
      "name": "Document Loader (+metadata)",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        2032,
        896
      ],
      "parameters": {
        "options": {
          "metadata": {
            "metadataValues": [
              {
                "name": "source",
                "value": "user_ingest"
              },
              {
                "name": "style",
                "value": "true"
              },
              {
                "name": "topic",
                "value": "={{ $json.topic || '' }}"
              }
            ]
          }
        },
        "jsonData": "={{ $json.content }}",
        "jsonMode": "expressionData"
      },
      "typeVersion": 1
    },
    {
      "id": "5d45d346-d224-4c1e-86ba-18a0e3b75a9f",
      "name": "Text Splitter",
      "type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
      "position": [
        2112,
        1104
      ],
      "parameters": {
        "options": {},
        "chunkSize": 1200,
        "chunkOverlap": 150
      },
      "typeVersion": 1
    },
    {
      "id": "3a99f2d4-e71d-4617-8a9c-2aa321211a29",
      "name": "VectorStore (Supabase)",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        1936,
        672
      ],
      "parameters": {
        "mode": "insert",
        "options": {
          "queryName": "match_documents"
        },
        "tableName": {
          "__rl": true,
          "mode": "list",
          "value": "documents"
        }
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e4fad627-65a6-46f0-8128-b4ce1027a9bc",
      "name": "End Page (ingest)",
      "type": "n8n-nodes-base.form",
      "position": [
        2400,
        880
      ],
      "parameters": {
        "options": {},
        "operation": "completion",
        "completionTitle": "={{ $json.metadata.topic }}",
        "completionMessage": "={{ $json.pageContent }}"
      },
      "typeVersion": 2.3
    },
    {
      "id": "d37dad08-4b54-42b5-9f68-209ad7fa0578",
      "name": "Form: Generate",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        1456,
        1392
      ],
      "parameters": {
        "options": {},
        "formTitle": "Generate Posts",
        "formFields": {
          "values": [
            {
              "fieldLabel": "topic"
            },
            {
              "fieldType": "number",
              "fieldLabel": "topK",
              "placeholder": "Default 5"
            },
            {
              "fieldLabel": "hint",
              "placeholder": "Optional hint (e.g., Consistency vs creativity)"
            }
          ]
        },
        "formDescription": "Create post/quote/reply/image_prompt from your knowledge base."
      },
      "typeVersion": 2.2
    },
    {
      "id": "d00d4e20-2590-43ef-bedb-519184336051",
      "name": "Build Params",
      "type": "n8n-nodes-base.set",
      "position": [
        1680,
        1392
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={{ ({ topic: $json.fields.topic || '', style: 'true', topK: Number($json.fields.topK || 5), hint: $json.fields.hint || '', filters: { topic: ($json.fields.topic || ''), style: true } }) }}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "9f41f462-fcdf-4794-a3f2-b86faec6be4b",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1904,
        1616
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "c4c2de4b-432d-4a88-afc4-23c6daca5754",
      "name": "KB (Supabase VectorStore)",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        2032,
        1616
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "options": {
          "queryName": "match_documents"
        },
        "toolName": "kb_vectorstore",
        "tableName": {
          "__rl": true,
          "mode": "id",
          "value": "documents"
        },
        "toolDescription": "KB search over Supabase `documents` (use filters like {\"topic\":\"creator_mindset\",\"style\":\"true\"})"
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "214659b2-a7a9-4e0f-8a3f-c9dfd7c4778e",
      "name": "Generator Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1936,
        1392
      ],
      "parameters": {
        "text": "=You are a content engineer for X posts.\nUse the KB (tool) to fetch up to {{$json.topK || 5}} relevant snippets using {{$json.filters}}.\nThen output **JSON only** with keys exactly:\n{\"post\",\"quote\",\"reply\",\"image_prompt\"}\n- post: one original tweet (<=230 chars, no hashtags/links)\n- quote: sharp quote-tweet for a given topic/link (<=200 chars)\n- reply: constructive reply (<=180 chars, end with a short question)\n- image_prompt: brief photoreal/graphic prompt\nKeep tone aligned to retrieved examples. Topic: {{$json.topic}}. Hint: {{$json.hint}}",
        "options": {
          "systemMessage": "Be concise, concrete, and aligned to prior high-engagement style."
        },
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "3769f432-c187-45fe-9451-d278a83c52ff",
      "name": "Edit Fields (format HTML)",
      "type": "n8n-nodes-base.set",
      "position": [
        2400,
        1392
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={{ (() => { const cur = Array.isArray($json) ? $json[0] : $json; let o = {}; try { o = typeof cur.output === 'string' ? JSON.parse(cur.output) : (cur.output || {}); } catch(e) { o = {}; } return { completionTitle: '\ud83c\udfaf Generated Results', completionMessage: `<div style=\\\"font-family:sans-serif; line-height:1.5;\\\"><h3>\ud83d\udcdd Post</h3><p>${o.post ?? ''}</p><hr/><h3>\ud83d\udcac Quote</h3><p>${o.quote ?? ''}</p><hr/><h3>\ud83d\udcad Reply</h3><p>${o.reply ?? ''}</p><hr/><h3>\ud83c\udfa8 Image Prompt</h3><p>${o.image_prompt ?? ''}</p></div>` }; })() }}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "b7f522ca-5478-4f41-8926-93cd1677a4d6",
      "name": "End Page (generate)",
      "type": "n8n-nodes-base.form",
      "position": [
        2624,
        1392
      ],
      "parameters": {
        "options": {},
        "operation": "completion",
        "completionTitle": "={{ $json.completionTitle }}",
        "completionMessage": "={{ $json.completionMessage }}"
      },
      "typeVersion": 2.3
    },
    {
      "id": "7f01e91f-0fa7-4fb3-a75a-75bca886ec1d",
      "name": "Sticky: Overview (yellow)1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        608,
        560
      ],
      "parameters": {
        "color": 7,
        "width": 540,
        "height": 416,
        "content": "## Self-Learning X Content Engine (Creator RAG Booster)\n\n### How it works\nThis workflow builds a small knowledge base from your past posts. Ingested text is cleaned, chunked, embedded, and stored in Supabase. The generator then retrieves relevant snippets and creates one post, one quote-tweet, one reply, and one image prompt.\n\n### Setup steps\n1. Add your OpenAI + Supabase creds.\n2. Use **Add to KB** to ingest 10\u201320 samples per topic.\n3. Go to **Generate Posts** \u2192 choose topic, topK, hint.\n4. View results on the final page.\n5. Add more samples for better tone accuracy."
      },
      "typeVersion": 1
    },
    {
      "id": "fafe155c-76c5-4cf3-93fe-1a0ffa94aedc",
      "name": "Sticky: Step ",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1360,
        672
      ],
      "parameters": {
        "width": 380,
        "height": 180,
        "content": "## Ingest (build KB)\nNormalize text \u2192 add metadata \u2192 split into chunks \u2192 embed \u2192 store in Supabase.\nUse **Add to KB** to add posts and notes."
      },
      "typeVersion": 1
    },
    {
      "id": "323fb28f-b2fc-457a-bae4-46d9e256778a",
      "name": "Sticky: Step 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1376,
        1200
      ],
      "parameters": {
        "width": 360,
        "content": "## Generate (use KB)\nSet topic + topK + optional hint.\nThe agent searches Supabase and returns a post, quote, reply, and image prompt."
      },
      "typeVersion": 1
    },
    {
      "id": "bb2f7f95-bad9-46bd-90ac-6985aa183af2",
      "name": "Sticky: Troubleshooting1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        688,
        1040
      ],
      "parameters": {
        "width": 360,
        "content": "## Troubleshooting\nBlank page \u2192 check form is Completion type.\nNo inserts \u2192 Supabase creds/RLS.\nGeneric tone \u2192 add more samples.\nOdd matches \u2192 adjust topic or topK."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Build Params": {
      "main": [
        [
          {
            "node": "Generator Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Text Splitter": {
      "ai_textSplitter": [
        [
          {
            "node": "Document Loader (+metadata)",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "Form: Generate": {
      "main": [
        [
          {
            "node": "Build Params",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Form: Add to KB": {
      "main": [
        [
          {
            "node": "Normalize (ingest)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generator Agent": {
      "main": [
        [
          {
            "node": "Edit Fields (format HTML)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generator Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Normalize (ingest)": {
      "main": [
        [
          {
            "node": "VectorStore (Supabase)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "VectorStore (Supabase)": {
      "main": [
        [
          {
            "node": "End Page (ingest)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields (format HTML)": {
      "main": [
        [
          {
            "node": "End Page (generate)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "KB (Supabase VectorStore)": {
      "ai_tool": [
        [
          {
            "node": "Generator Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI (ingest)": {
      "ai_embedding": [
        [
          {
            "node": "VectorStore (Supabase)",
            "type": "ai_embedding",
            "index": 0
          },
          {
            "node": "KB (Supabase VectorStore)",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Document Loader (+metadata)": {
      "ai_document": [
        [
          {
            "node": "VectorStore (Supabase)",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    }
  }
}