N
n8n Store
Workflow Market
Validate GitHub Configurations with AI and Log Issues to Sheets and Slack

Validate GitHub Configurations with AI and Log Issues to Sheets and Slack

by rahul08β€’0 views

Description

Categories

πŸš€ DevOpsπŸ€– AI & Machine Learning

Nodes Used

n8n-nodes-base.coden8n-nodes-base.mergen8n-nodes-base.slackn8n-nodes-base.githubn8n-nodes-base.githubn8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.stickyNoten8n-nodes-base.stickyNote
PriceGratis
Views0
Last Updated11/28/2025
workflow.json
{
  "id": "NDAfOVpefnu0AO5l",
  "meta": {
    "instanceId": "8443f10082278c46aa5cf3acf8ff0f70061a2c58bce76efac814b16290845177",
    "templateCredsSetupCompleted": true
  },
  "name": "Validate GitHub Configurations with AI and Log Issues to Sheets and Slack",
  "tags": [],
  "nodes": [
    {
      "id": "00b8e7a5-b837-42dc-af23-9a2d06336a56",
      "name": "Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1600,
        -352
      ],
      "parameters": {
        "color": 4,
        "width": 420,
        "height": 520,
        "content": "## πŸ” GitHub Config Validator\n\nAutomatically validates configuration consistency between repository configs and FAQ documentation using AI.\n\n**What it does:**\n- Monitors GitHub repo for push/PR events\n- Fetches config files and FAQ references\n- Uses AI to compare and detect mismatches\n- Logs discrepancies to Google Sheets\n- Sends Slack alerts for critical issues\n\n**Use Cases:**\n- DevOps config drift detection\n- Documentation accuracy validation\n- Automated compliance checking\n- Multi-environment config consistency\n\n**Business Value:**\n- Prevents production incidents from config drift\n- Ensures docs stay in sync with code\n- Reduces manual config review time\n- Maintains compliance standards"
      },
      "typeVersion": 1
    },
    {
      "id": "22574d71-89eb-4872-a6ec-17127c7c13ac",
      "name": "Setup Guide",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2000,
        -336
      ],
      "parameters": {
        "color": 2,
        "width": 380,
        "height": 540,
        "content": "## βš™οΈ Setup Instructions\n\n**Step 1: GitHub Configuration**\n- Create GitHub OAuth2 credential\n- Grant repo and webhook permissions\n- Configure webhook secret (optional)\n\n**Step 2: File Paths**\n- Config file: `config/app-config.json`\n- FAQ reference: `faq-config.json`\n- Adjust paths in nodes if different\n\n**Step 3: OpenAI Setup**\n- Add API key to credentials\n- Model: gpt-4o-mini ($0.03-0.05/run)\n- Max tokens: 4000\n\n**Step 4: Google Sheets**\n- Create sheet with columns (see below)\n- Connect OAuth2 credential\n\n**Step 5: Slack**\n- Add workspace OAuth2 token\n- Select notification channel\n- Customize alert template"
      },
      "typeVersion": 1
    },
    {
      "id": "54dbfff3-2cfb-4e0f-92de-eeb8ad467ef4",
      "name": "Trigger Configuration",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1152,
        -432
      ],
      "parameters": {
        "color": 2,
        "width": 320,
        "height": 332,
        "content": "## 🎯 GitHub Webhook Trigger\n\n**Events monitored:**\n- `push`: Code commits\n- `pull_request`: PR opened/updated\n\n**Triggers when:**\nConfig files in monitored paths change\n\n**Webhook setup:**\n- Automatically created by n8n\n- Payload URL provided after activation\n- Add to GitHub repo settings\n\n**Security:**\n- Use webhook secret (recommended)\n- Validate payload signatures\n- Restrict to specific branches"
      },
      "typeVersion": 1
    },
    {
      "id": "eabed35d-8708-4e30-9f50-de35746032b3",
      "name": "File Fetching Logic",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -976,
        176
      ],
      "parameters": {
        "color": 2,
        "width": 300,
        "height": 320,
        "content": "## πŸ“‚ File Fetching\n\n**Two parallel requests:**\n\n1. **Repository Config**\n   - Path: `config/app-config.json`\n   - Contains actual settings\n   - Direct from main/master branch\n\n2. **FAQ Reference**\n   - Path: `faq-config.json`\n   - Documentation of expected config\n   - Source of truth for validation\n\n**Both are JSON files** that get parsed and merged for AI comparison."
      },
      "typeVersion": 1
    },
    {
      "id": "7a19688d-84bd-4c7c-98bd-6649a0192ed4",
      "name": "Merge Strategy",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -512,
        -480
      ],
      "parameters": {
        "color": 2,
        "width": 280,
        "height": 360,
        "content": "## πŸ”€ Data Merging\n\n**Combines both configs:**\n- Repo config (actual)\n- FAQ config (expected)\n\n**Merge strategy:**\nCombines into single object for AI analysis\n\n**Output structure:**\n```json\n{\n  \"repoConfig\": {...},\n  \"faqConfig\": {...}\n}\n```\n\nReady for AI comparison"
      },
      "typeVersion": 1
    },
    {
      "id": "a446599d-12b9-4438-8795-e2b93b9a026d",
      "name": "AI Analysis Details",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        -480
      ],
      "parameters": {
        "color": 2,
        "width": 300,
        "height": 372,
        "content": "## πŸ€– AI Configuration Analysis\n\n**AI compares configs for:**\n- Mismatched values\n- Missing keys\n- Deprecated settings\n- Type inconsistencies\n- Security concerns\n\n**Severity Levels:**\n- `critical`: Breaking changes\n- `high`: Important mismatches\n- `medium`: Minor inconsistencies\n- `low`: Suggestions only\n\n**Output:**\nStructured JSON with issues array"
      },
      "typeVersion": 1
    },
    {
      "id": "93354c1a-1de0-44ab-808f-cf9ddbcc1b07",
      "name": "Data Processing",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        208,
        -448
      ],
      "parameters": {
        "color": 2,
        "width": 300,
        "height": 344,
        "content": "## πŸ“Š Results Processing\n\n**Extracts from AI output:**\n- Issue ID\n- Config key with problem\n- Expected vs actual values\n- Issue type and severity\n- Actionable recommendations\n- Confidence score\n\n**Handles:**\n- Multiple issues per run\n- No issues found (success case)\n- Parsing errors gracefully\n\n**Adds metadata:**\n- Timestamp\n- Summary of all issues"
      },
      "typeVersion": 1
    },
    {
      "id": "ee3b404c-ee6c-44d7-9123-c90b351f8160",
      "name": "Sheets Configuration",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        64
      ],
      "parameters": {
        "color": 2,
        "width": 320,
        "height": 388,
        "content": "## πŸ“ Google Sheets Schema\n\n**Required columns:**\n- `timestamp`: When detected\n- `configKey`: Field name\n- `faqReference`: Expected value\n- `actualConfig`: Current value\n- `issueType`: Category\n- `severity`: Priority level\n- `suggestion`: Fix recommendation\n- `confidence`: AI confidence\n- `issueId`: Unique identifier\n- `summary`: Overall summary\n\n**Operation:** Append (logs history)\n"
      },
      "typeVersion": 1
    },
    {
      "id": "133a9c1b-749f-4114-84ed-a23fd3e77d86",
      "name": "Slack Alerts",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        672,
        -496
      ],
      "parameters": {
        "color": 2,
        "width": 300,
        "height": 408,
        "content": "## πŸ’¬ Slack Notification\n\n**Alert includes:**\n- Config key with issue\n- Expected vs actual values\n- Issue type and severity\n- Actionable suggestion\n- Link to full report\n- Timestamp\n\n**Sent when:**\n- Any discrepancy detected\n- Critical/high severity issues\n\n**Customize:**\n- Channel selection\n- Message format\n- Severity filtering\n- @mention rules"
      },
      "typeVersion": 1
    },
    {
      "id": "edf48d61-2eff-4e52-91c8-1ff181c99a4c",
      "name": "GitHub Push or PR Event",
      "type": "n8n-nodes-base.githubTrigger",
      "position": [
        -1088,
        -96
      ],
      "webhookId": "8269983f-8b5a-4f61-87a7-fb4e58e11b6c",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $json.githubOwner }}"
        },
        "events": [
          "pull_request",
          "push"
        ],
        "options": {},
        "repository": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.githubRepo }}"
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "Ih8web2ia8dlggr6",
          "name": "GitHub account vivek"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "88bcabe0-4557-4f16-bba2-8e0523853fa3",
      "name": "Fetch Repository Config",
      "type": "n8n-nodes-base.github",
      "position": [
        -864,
        -192
      ],
      "webhookId": "9ad4450b-f494-4026-9ac9-d78c90169881",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $json.repository.owner.login }}"
        },
        "filePath": "config/app-config.json",
        "resource": "file",
        "operation": "get",
        "repository": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.repository.name }}"
        },
        "authentication": "oAuth2",
        "additionalParameters": {}
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "Ih8web2ia8dlggr6",
          "name": "GitHub account vivek"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "fe9f94a2-d9c9-4b51-832c-ae018daa821e",
      "name": "Fetch FAQ Reference Config",
      "type": "n8n-nodes-base.github",
      "position": [
        -864,
        0
      ],
      "webhookId": "b63918a7-17bc-4934-9007-3c8aa0b7aee9",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $json.repository.owner.login }}"
        },
        "filePath": "faq-config.json",
        "resource": "file",
        "operation": "get",
        "repository": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.repository.name }}"
        },
        "authentication": "oAuth2",
        "additionalParameters": {}
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "Ih8web2ia8dlggr6",
          "name": "GitHub account vivek"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "aaf24ba6-6338-4cd7-8451-b4add12fff46",
      "name": "Parse Repo Config JSON",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -640,
        -192
      ],
      "parameters": {
        "options": {},
        "operation": "fromJson"
      },
      "typeVersion": 1
    },
    {
      "id": "de433781-a62a-41e8-af75-6f659cc0bee6",
      "name": "Parse FAQ Config JSON",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -640,
        0
      ],
      "parameters": {
        "options": {},
        "operation": "fromJson"
      },
      "typeVersion": 1
    },
    {
      "id": "136b7b5e-c6c8-42db-ba9f-fea68d9e3db4",
      "name": "Merge Config Files",
      "type": "n8n-nodes-base.merge",
      "position": [
        -416,
        -96
      ],
      "parameters": {
        "mode": "combine",
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "1e9f58bd-32a7-4652-a224-08a013ad656e",
      "name": "AI Config Comparison Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -128,
        -96
      ],
      "parameters": {
        "text": "=You are comparing two configuration files:\n\n**Repository Config (Actual):**\n```json\n{{ JSON.stringify($json[0], null, 2) }}\n```\n\n**FAQ Reference Config (Expected):**\n```json\n{{ JSON.stringify($json[1], null, 2) }}\n```\n\n**Task:**\nCompare both configs and identify all discrepancies. For each issue, provide:\n- Unique ID\n- Config key path\n- Expected value (from FAQ)\n- Actual value (from repo)\n- Issue type (mismatch, missing, deprecated, type_error, security)\n- Severity (critical, high, medium, low)\n- Clear recommendation\n- Confidence score (0.0-1.0)\n\n**Important:**\n- Return ONLY valid JSON (no markdown, no extra text)\n- Use the exact schema provided\n- If no issues found, return empty issues array\n- Focus on actionable discrepancies",
        "options": {
          "systemMessage": "You are an expert DevOps configuration auditor and automation specialist.\n\n**Your expertise:**\n- Deep knowledge of config file best practices\n- Security-first mindset for credentials and secrets\n- Understanding of environment-specific variations\n- Ability to distinguish critical vs cosmetic differences\n\n**Analysis approach:**\n1. Compare key-by-key between repo config and FAQ reference\n2. Identify missing keys, mismatched values, type changes\n3. Assess security implications (exposed secrets, weak settings)\n4. Determine business impact and urgency\n5. Provide specific, actionable recommendations\n\n**Severity guidelines:**\n- `critical`: Breaking changes, security vulnerabilities, missing required fields\n- `high`: Important mismatches affecting functionality\n- `medium`: Minor inconsistencies, deprecated but working\n- `low`: Cosmetic differences, optional improvements\n\n**Output requirements:**\n- Strict JSON format only\n- No markdown formatting\n- No explanatory text outside JSON\n- Clear, concise recommendations"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.1
    },
    {
      "id": "f1dc1aff-caf8-4a0a-8c64-44fc69af9a22",
      "name": "OpenAI GPT-4o-mini",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -192,
        128
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {
          "maxTokens": 4000,
          "temperature": 0.3
        }
      },
      "credentials": {
        "openAiApi": {
          "id": "5Kzt6hGSZ1JHZqWN",
          "name": "OpenAi account 2"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "460f00a4-afff-4d0d-a922-cf6a865a5cd0",
      "name": "JSON Output Schema",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        80,
        128
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"result\": \"success or issues_found\",\n  \"summary\": \"Brief overview of findings\",\n  \"issues\": [\n    {\n      \"id\": \"unique_issue_id\",\n      \"key\": \"config.path.to.field\",\n      \"repo_value\": \"actual value in repository\",\n      \"faq_value\": \"expected value from FAQ\",\n      \"type\": \"mismatch | missing | deprecated | type_error | security\",\n      \"severity\": \"critical | high | medium | low\",\n      \"recommendation\": \"Specific action to resolve\",\n      \"confidence\": 0.95\n    }\n  ],\n  \"metadata\": {\n    \"checked_at\": \"ISO timestamp\",\n    \"comparison_source\": \"faq-config.json\"\n  }\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "f50d6106-4931-46ce-b0ec-c816c1e25c8b",
      "name": "Conversation Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        -64,
        128
      ],
      "parameters": {
        "sessionKey": "=\"config_validation_\" & $('GitHub Push or PR Event').item.json.repository.name",
        "sessionIdType": "customKey",
        "contextWindowLength": 3
      },
      "typeVersion": 1.3
    },
    {
      "id": "b40a6c22-c78e-43ba-90c6-2db71c74fe02",
      "name": "Format Issues for Logging",
      "type": "n8n-nodes-base.code",
      "position": [
        288,
        -96
      ],
      "parameters": {
        "jsCode": "// Extract and format AI comparison results for Google Sheets\nconst allItems = $input.all();\nlet issues = [];\n\ntry {\n  for (const item of allItems) {\n    const aiResponse = item.json;\n    \n    // Handle different output structures\n    let outputData;\n    if (aiResponse.output) {\n      outputData = [aiResponse.output];\n    } else if (Array.isArray(aiResponse)) {\n      outputData = aiResponse.map(entry => entry.output || entry);\n    } else {\n      outputData = [aiResponse];\n    }\n\n    // Process each output entry\n    for (const output of outputData) {\n      if (output.issues && Array.isArray(output.issues) && output.issues.length > 0) {\n        \n        // Map issues to Google Sheets format\n        const mappedIssues = output.issues.map(issue => ({\n          timestamp: new Date().toISOString(),\n          configKey: issue.key || 'N/A',\n          faqReference: issue.faq_value || 'N/A',\n          actualConfig: issue.repo_value || 'N/A',\n          issueType: issue.type || 'unknown',\n          severity: issue.severity || 'N/A',\n          suggestion: issue.recommendation || 'N/A',\n          confidence: issue.confidence ? issue.confidence.toFixed(2) : 'N/A',\n          issueId: issue.id || `issue_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n          summary: output.summary || 'No summary provided'\n        }));\n        \n        issues.push(...mappedIssues);\n      }\n    }\n  }\n\n  // Handle case when no issues found\n  if (issues.length === 0) {\n    issues = [{\n      timestamp: new Date().toISOString(),\n      configKey: 'No Issues',\n      faqReference: 'N/A',\n      actualConfig: 'N/A',\n      issueType: 'success',\n      severity: 'N/A',\n      suggestion: 'All configurations match FAQ reference',\n      confidence: '1.00',\n      issueId: `success_${Date.now()}`,\n      summary: 'βœ… No discrepancies found - configs are in sync'\n    }];\n  }\n\n} catch (error) {\n  // Error handling\n  console.error('Error processing AI output:', error);\n  issues = [{\n    timestamp: new Date().toISOString(),\n    configKey: 'Processing Error',\n    faqReference: 'Could not parse AI response',\n    actualConfig: error.message,\n    issueType: 'error',\n    severity: 'high',\n    suggestion: `Review AI output manually. Error: ${error.message}`,\n    confidence: 'N/A',\n    issueId: `error_${Date.now()}`,\n    summary: '⚠️ Processing error occurred during validation'\n  }];\n}\n\n// Return formatted data for Google Sheets\nreturn issues.map(issue => ({ json: issue }));"
      },
      "typeVersion": 2
    },
    {
      "id": "be1fa800-8b48-4d21-a953-da7e3fc34eeb",
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        512,
        -96
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "configKey",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "configKey",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "faqReference",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "faqReference",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "actualConfig",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "actualConfig",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "issueType",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "issueType",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "severity",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "severity",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "suggestion",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "suggestion",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "confidence",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "confidence",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "issueId",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "issueId",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "summary",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "summary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Config Discrepancies"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Workflow Overview').item.json.googleSheetId }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "kpPEOLCGn963qpoh",
          "name": "[email protected]"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "4df1bf84-2753-4472-aef7-4623439bfcf0",
      "name": "Send Slack Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        736,
        -96
      ],
      "webhookId": "ef90cacf-14c2-48cc-905f-b06d2c649b8d",
      "parameters": {
        "text": "=⚠️ *Config Mismatch Detected!*\n\n*Repository:* {{ $('GitHub Push or PR Event').item.json.repository.full_name }}\n*Branch:* {{ $('GitHub Push or PR Event').item.json.ref }}\n*Commit:* {{ $('GitHub Push or PR Event').item.json.after.substring(0, 7) }}\n\n━━━━━━━━━━━━━━━━━━━━\n\n{{ $('Format Issues for Logging').all().slice(0, 3).map((item, idx) => {\n  const severity = item.json.severity;\n  const emoji = severity === 'critical' ? 'πŸ”΄' : severity === 'high' ? '🟠' : severity === 'medium' ? '🟑' : '🟒';\n  return `${emoji} *Issue ${idx + 1}: ${item.json.configKey}*\\nβ€’ Type: ${item.json.issueType}\\nβ€’ Severity: ${item.json.severity}\\nβ€’ Expected: \\`${item.json.faqReference}\\`\\nβ€’ Actual: \\`${item.json.actualConfig}\\`\\nβ€’ Fix: ${item.json.suggestion}\\n`;\n}).join('\\n') }}\n\n*Total Issues:* {{ $('Format Issues for Logging').all().length }}\n\nπŸ“Š *Full Report:* <{{ $('Workflow Overview').item.json.sheetsReportUrl }}|View in Google Sheets>\n\n_Scanned: {{ new Date().toLocaleString('en-US', { timeZone: 'UTC' }) }} UTC_",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Workflow Overview').item.json.slackChannel }}"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "id": "rNqvWj9TfChPVRYY",
          "name": "Slack account vivek"
        }
      },
      "typeVersion": 2.2
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "f61bd7be-e6be-425b-8929-bc5536255b8f",
  "connections": {
    "JSON Output Schema": {
      "ai_outputParser": [
        [
          {
            "node": "AI Config Comparison Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Merge Config Files": {
      "main": [
        [
          {
            "node": "AI Config Comparison Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI GPT-4o-mini": {
      "ai_languageModel": [
        [
          {
            "node": "AI Config Comparison Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Conversation Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Config Comparison Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Log to Google Sheets": {
      "main": [
        [
          {
            "node": "Send Slack Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse FAQ Config JSON": {
      "main": [
        [
          {
            "node": "Merge Config Files",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Parse Repo Config JSON": {
      "main": [
        [
          {
            "node": "Merge Config Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Repository Config": {
      "main": [
        [
          {
            "node": "Parse Repo Config JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GitHub Push or PR Event": {
      "main": [
        [
          {
            "node": "Fetch Repository Config",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch FAQ Reference Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Issues for Logging": {
      "main": [
        [
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Config Comparison Agent": {
      "main": [
        [
          {
            "node": "Format Issues for Logging",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch FAQ Reference Config": {
      "main": [
        [
          {
            "node": "Parse FAQ Config JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

η›Έε…³ε·₯作桁