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 rahul080 views

説明

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
Price無料
Views0
最終更新11/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
          }
        ]
      ]
    }
  }
}

相关工作流