{ "id": "H6TZCHyiYOr1X6Xf", "name": "MAM Anime Series List", "nodes": [ { "parameters": {}, "id": "b3487fff-82e0-4b4d-bc57-01163e435ea2", "name": "Workflow Trigger", "position": [ 48, 304 ], "type": "n8n-nodes-base.executeWorkflowTrigger", "typeVersion": 1 }, { "parameters": { "authentication": "privateKey", "command": "find /mnt/nas/Anime/Audiobooks -mindepth 2 -maxdepth 2 -type d" }, "id": "ddae105c-cbb9-4747-8176-9df55a98cce5", "name": "List General Folders", "position": [ 272, 208 ], "type": "n8n-nodes-base.ssh", "typeVersion": 1, "credentials": { "sshPrivateKey": { "id": "vOzhicmbOwx1XDF8", "name": "seed-0.local.ben.io" } } }, { "parameters": { "jsCode": "const output = $input.item.json.stdout || \"\";\nconst lines = output.split(String.fromCharCode(10)).filter(l => l.trim());\nreturn lines.map(l => ({\n json: {\n smb_path: l.trim(),\n folder_name: l.split('/').pop()\n }\n}));" }, "id": "4a7486cd-5101-46fc-b1de-698b6c675fc8", "name": "Code", "position": [ 624, 128 ], "type": "n8n-nodes-base.code", "typeVersion": 2 }, { "parameters": { "promptType": "define", "text": "=### ROLE\nYou are an expert Data Extraction Specialist for an audiobook library (focus: Light Novels/Anime). You are currently \"blind\" to the book's details and MUST use the provided tools to discover the metadata. You cannot generate the final JSON without data from the tools.\n\n### INPUT DATA\n- **Folder Name:** {{ $json.folder_name }}\n- **SMB Path:** {{ $json.smb_path }}\n\n### STRICT PROCESS\n1. **Analyze Input:**\n - **ASIN Check:** Does 'Folder Name' start with an ASIN (e.g., 'B0...')?\n - **Context Extraction:** Parse the `smb_path`. The folder *above* the current one often holds the **Series Name**. Use this to anchor your search queries.\n\n2. **Execute Tools (Tiered Strategy):**\n *Goal: Identify Title, Author, and ASIN using the most quota-efficient tools first.*\n\n **TIER 1: Direct Lookup (High Confidence)**\n - IF ASIN found in folder: Call `audible_lookup_asin` immediately.\n\n **TIER 2: Primary Search (Google / Brave)**\n - IF NO ASIN: Clean the folder name. Remove text inside brackets `[...]` (e.g., [Yen Audio], [PZG]) and remove \"(Audiobook)\".\n - Construct a query: `\" Light Novel Audiobook\"`.\n - **Action:** Call `Google Search`, `brave_search`.\n - **Verification:** If the search finds an Audible link or a clear Goodreads/Wikipedia entry, use `audible_search_book` to confirm the ASIN, or `audible_lookup_asin` on a ASIN to confirm match to book you are searching for.\n - **Fallback:** If the first tool yields poor results (no clear match), try the *other* Tier 1 tool (e.g., if Google failed, try Brave).\n\n **TIER 3: Deep Search (Tavily - Low Priority)**\n - **Condition:** Only proceed here if Tier 1 and 2 failed or produced conflicting data.\n - **Action:** Call `tavily_search` with a detailed query.\n - **Extraction:** If an `audible.com/series/` URL was found in previous steps, use `tavily_extract` on that URL to scrape the full book list for accurate volume mapping.\n\n3. **Verify:**\n - Does the tool result match the Author/Series found in the `smb_path` context?\n - Ensure you haven't confused the Manga adaptation for the Light Novel.\n\n4. **Finalize:** Construct the JSON output using strictly the data returned by the tools.\n\n### OUTPUT RULES\n- Your final response must be valid JSON.\n- If all items in template are not filled out, set \"identified\" to `false`.\n\n### JSON TEMPLATE (Fill with TOOL DATA only)\n{\n \"title\": \"\",\n \"series\": \"\",\n \"volume_num\": \"\",\n \"asin\": \"\",\n \"author\": \"\",\n \"smb_path\": \"{{ $json.smb_path }}\",\n \"folder_name\": \"{{ $json.folder_name }}\",\n \"identified\": true,\n \"failure_reason\": null\n}", "hasOutputParser": true, "options": { "maxIterations": 10, "returnIntermediateSteps": false, "enableStreaming": false } }, "type": "@n8n/n8n-nodes-langchain.agent", "typeVersion": 3, "position": [ 1904, 240 ], "id": "9f9c7b50-2fd4-48ac-9080-a74158f58285", "name": "Lookup Agent", "onError": "continueErrorOutput" }, { "parameters": { "query": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Query', ``, 'string') }}", "options": { "topic": "general", "search_depth": "basic", "max_results": 3, "include_domains": [ "audible.com", "amazon.com" ] } }, "type": "@tavily/n8n-nodes-tavily.tavilyTool", "typeVersion": 1, "position": [ 1952, 608 ], "id": "e2f55ae4-2858-4b74-a355-f33b127396fb", "name": "tavily_search", "credentials": { "tavilyApi": { "id": "y1IVnGq2Wiqy3HBf", "name": "Tavily account" } } }, { "parameters": { "operation": "upsert", "schema": { "__rl": true, "mode": "list", "value": "public" }, "table": { "__rl": true, "value": "smb_general_books", "mode": "list", "cachedResultName": "smb_general_books" }, "columns": { "mappingMode": "defineBelow", "value": { "identified": "={{ $('Merge').item.json.output.identified }}", "needs_review": false, "volume_num": "={{ $('Merge').item.json.output.volume_num }}", "smb_path": "={{ $('Merge').item.json.output.smb_path }}", "book_folder": "={{ $('Merge').item.json.output.folder_name }}", "author_folder": "={{ $('Merge').item.json.output.author }}", "book_name": "={{ $('Merge').item.json.output.title }}", "series_name": "={{ $('Merge').item.json.output.series }}", "audible_asin": "={{ $('Merge').item.json.output.asin }}", "failure_reason": "={{ $('Merge').item.json.output.failure_reason }}", "category": "anime", "created_at": "={{ $now }}", "updated_at": "={{ $now }}" }, "matchingColumns": [ "smb_path" ], "schema": [ { "id": "id", "displayName": "id", "required": false, "defaultMatch": true, "display": true, "type": "string", "canBeUsedToMatch": true, "removed": false }, { "id": "smb_path", "displayName": "smb_path", "required": true, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": true, "removed": false }, { "id": "book_folder", "displayName": "book_folder", "required": true, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": false }, { "id": "author_folder", "displayName": "author_folder", "required": true, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": false }, { "id": "book_name", "displayName": "book_name", "required": false, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": false }, { "id": "series_name", "displayName": "series_name", "required": false, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": false }, { "id": "audible_asin", "displayName": "audible_asin", "required": false, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": false }, { "id": "identified", "displayName": "identified", "required": false, "defaultMatch": false, "display": true, "type": "boolean", "canBeUsedToMatch": false }, { "id": "needs_review", "displayName": "needs_review", "required": false, "defaultMatch": false, "display": true, "type": "boolean", "canBeUsedToMatch": false }, { "id": "retry_stage", "displayName": "retry_stage", "required": false, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": false }, { "id": "failure_reason", "displayName": "failure_reason", "required": false, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": false }, { "id": "category", "displayName": "category", "required": false, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": false }, { "id": "volume_num", "displayName": "volume_num", "required": false, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": false }, { "id": "created_at", "displayName": "created_at", "required": false, "defaultMatch": false, "display": true, "type": "dateTime", "canBeUsedToMatch": false }, { "id": "updated_at", "displayName": "updated_at", "required": false, "defaultMatch": false, "display": true, "type": "dateTime", "canBeUsedToMatch": false } ], "attemptToConvertTypes": false, "convertFieldsToString": false }, "options": {} }, "type": "n8n-nodes-base.postgres", "typeVersion": 2.6, "position": [ 3184, 224 ], "id": "a9cf32b5-56aa-4754-a36a-f6f0f37f6d16", "name": "Insert or update rows in a table", "credentials": { "postgres": { "id": "9grzZwW7Br6SzdV8", "name": "n8n-media" } }, "onError": "continueErrorOutput" }, { "parameters": { "options": { "reset": false } }, "type": "n8n-nodes-base.splitInBatches", "typeVersion": 3, "position": [ 1536, 208 ], "id": "32dc1b6a-c722-412e-b6a3-ce9282501b37", "name": "Loop Over Items" }, { "parameters": { "toolDescription": "google_search accepts title and author and returns the first page of google search results.", "method": "POST", "url": "https://google.serper.dev/search", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "X-API-KEY", "value": "dea8a4e00208f156de1253b4dc4d32f56a1d72bd" } ] }, "sendBody": true, "bodyParameters": { "parameters": [ { "name": "q", "value": "=site:audible.com {{ $fromAI('query') }}" } ] }, "options": {} }, "type": "n8n-nodes-base.httpRequestTool", "typeVersion": 4.3, "position": [ 2064, 752 ], "id": "92174474-1946-4ede-a8fa-4df134d46cbf", "name": "google_search" }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 3 }, "conditions": [ { "id": "b89944ac-44d6-47a6-8824-bc990db96084", "leftValue": "={{ $json.smb_path }}", "rightValue": "Pack", "operator": { "type": "string", "operation": "notContains" } }, { "id": "4801810b-0ceb-4c17-893f-4591279754a8", "leftValue": "={{ $json.folder_name }}", "rightValue": ".@__thumb", "operator": { "type": "string", "operation": "notEquals" } }, { "id": "fccbabbf-14ab-42fc-9b9c-4941c229c764", "leftValue": "={{ $json.smb_path }}", "rightValue": "Progressive", "operator": { "type": "string", "operation": "notContains" } } ], "combinator": "and" }, "options": {} }, "type": "n8n-nodes-base.filter", "typeVersion": 2.3, "position": [ 1152, 208 ], "id": "04d076e5-c037-431d-b573-e0bfdabaab7d", "name": "Filter Unwanted", "notesInFlow": true, "notes": "- Filter non-book folders\n- Filter Aptiv workout audio" }, { "parameters": { "mode": "combine", "combineBy": "combineByPosition", "options": {} }, "type": "n8n-nodes-base.merge", "typeVersion": 3.2, "position": [ 2448, 240 ], "id": "e91c22e9-b231-4334-8318-c5fa03f89fb5", "name": "Merge" }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 3 }, "conditions": [ { "id": "0b89f507-1f5c-446b-912c-f94d94320483", "leftValue": "={{ $json.status }}", "rightValue": "FAIL", "operator": { "type": "string", "operation": "notEquals" } }, { "id": "d308a2e3-28d8-4922-bfc0-4836a5adc612", "leftValue": "={{ $('Merge').item.json.output.identified }}", "rightValue": true, "operator": { "type": "boolean", "operation": "equals" } } ], "combinator": "and" }, "options": {} }, "type": "n8n-nodes-base.if", "typeVersion": 2.3, "position": [ 2928, 240 ], "id": "540cbeb8-2020-4c64-be9c-07b13ba241b2", "name": "verified" }, { "parameters": {}, "type": "n8n-nodes-base.noOp", "typeVersion": 1, "position": [ 3472, 736 ], "id": "c407ab66-7d47-4246-b9b1-2cc22e9e8aec", "name": "Formatting" }, { "parameters": { "schemaType": "manual", "inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"title\": { \"type\": \"string\" },\n \"series\": { \"type\": [\"string\", \"null\"] },\n \"volume_num\": { \n \"type\": [\"string\", \"number\", \"null\"],\n \"description\": \"The volume number (can be string '3' or number 3)\" \n },\n \"asin\": { \"type\": [\"string\", \"null\"] },\n \"author\": { \"type\": \"string\" },\n \"smb_path\": { \"type\": \"string\" },\n \"folder_name\": { \"type\": \"string\" },\n \"identified\": { \"type\": \"boolean\" },\n \"failure_reason\": { \n \"type\": [\"string\", \"null\"],\n \"description\": \"Reason for failure, or null if successful\" \n }\n },\n \"required\": [\n \"title\",\n \"series\",\n \"volume_num\",\n \"asin\",\n \"author\",\n \"smb_path\",\n \"folder_name\",\n \"identified\",\n \"failure_reason\"\n ]\n}", "autoFix": true }, "type": "@n8n/n8n-nodes-langchain.outputParserStructured", "typeVersion": 1.3, "position": [ 2128, 448 ], "id": "190844e8-ad9c-4406-8c29-d9d6f543869e", "name": "Structured Output Parser" }, { "parameters": { "mode": "combine", "fieldsToMatchString": "smb_path", "joinMode": "keepNonMatches", "outputDataFrom": "input1", "options": {} }, "id": "f053ed65-f54a-4da2-8f5f-d2d10b8a4dcd", "name": "Filter Existing", "position": [ 944, 208 ], "type": "n8n-nodes-base.merge", "typeVersion": 3.2 }, { "parameters": { "model": { "__rl": true, "value": "lightning_ai/lightning-ai/gpt-oss-120b", "mode": "list", "cachedResultName": "lightning_ai/lightning-ai/gpt-oss-120b" }, "responsesApiEnabled": false, "options": { "responseFormat": "json_object", "temperature": 0 } }, "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", "typeVersion": 1.3, "position": [ 2208, 640 ], "id": "884680ff-1bc3-4ff5-bb29-47eca4083f4c", "name": "Ollama - gpt-oss:20b - Validator", "credentials": { "openAiApi": { "id": "sxSUdecXdMfKPuTu", "name": "llm-proxy.ext.ben.io" } } }, { "parameters": { "rule": { "interval": [ {} ] } }, "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.3, "position": [ 48, 144 ], "id": "240e422b-cb1b-4e78-895c-1e4892bf0036", "name": "Schedule Trigger" }, { "parameters": { "operation": "select", "schema": { "__rl": true, "mode": "list", "value": "public" }, "table": { "__rl": true, "value": "smb_general_books", "mode": "list", "cachedResultName": "smb_general_books" }, "returnAll": true, "where": { "values": [ { "column": "category", "value": "anime" } ] }, "options": {} }, "type": "n8n-nodes-base.postgres", "typeVersion": 2.6, "position": [ 592, 320 ], "id": "8b322485-f5bc-4ef5-ac3e-74e8438b7ed1", "name": "Select rows from a table", "executeOnce": true, "credentials": { "postgres": { "id": "9grzZwW7Br6SzdV8", "name": "n8n-media" } } }, { "parameters": { "description": "Call this tool to retrieve a list of the top brave search results.", "workflowId": { "__rl": true, "value": "VUwFjFF2UhNout2T", "mode": "list", "cachedResultUrl": "/workflow/VUwFjFF2UhNout2T", "cachedResultName": "tool_brave_search" }, "workflowInputs": { "mappingMode": "defineBelow", "value": { "query": "=site:audible.com {{ $fromAI('query') }}" }, "matchingColumns": [ "query" ], "schema": [ { "id": "query", "displayName": "query", "required": false, "defaultMatch": false, "display": true, "canBeUsedToMatch": true, "type": "string", "removed": false } ], "attemptToConvertTypes": false, "convertFieldsToString": false } }, "type": "@n8n/n8n-nodes-langchain.toolWorkflow", "typeVersion": 2.2, "position": [ 2352, 672 ], "id": "e485683e-6882-4ff5-b739-bd703d109693", "name": "brave_search" }, { "parameters": { "model": { "__rl": true, "value": "zenmux/minimax-m2.5-free", "mode": "list", "cachedResultName": "zenmux/minimax-m2.5-free" }, "responsesApiEnabled": false, "options": { "temperature": 0.1 } }, "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", "typeVersion": 1.3, "position": [ 1760, 448 ], "id": "c12548ff-b760-416d-8f63-f8eb57bb66d8", "name": "OpenAI Chat Model", "credentials": { "openAiApi": { "id": "sxSUdecXdMfKPuTu", "name": "llm-proxy.ext.ben.io" } } }, { "parameters": { "promptType": "define", "text": "=### ROLE\nYou are a Quality Assurance Auditor.\n**Golden Rule:** The folder missing data is never a failure reason.\n\n### INPUTS\n1. **Source Folder:** {{ $json.folder_name }}\n2. **Source Path:** {{ $json.smb_path }}\n3. **Candidate Metadata:**\n{{ JSON.stringify($json.output) }}\n\n### VALIDATION RULES (Pass/Fail Criteria)\nYou must evaluate the Candidate Metadata against the Source Folder on these specific points. If ANY point fails, the entire validation fails.\n\n#### 1. Title & Series Check (Hierarchy Rule)\n - **Series Match:** If the Folder Name significantly matches the **Candidate Series** (e.g. Folder \"Vampire Hunter D\", Candidate Series \"Vampire Hunter D\"), then the **Candidate Title** is ACCEPTED as valid enrichment.\n - **Title Match:** If the Folder Name matches the **Candidate Title**, that is also a PASS.\n - **FAIL Condition:** Fail ONLY if the Folder Name matches *neither* the Candidate Title *nor* the Candidate Series.\n - *Example PASS:* Folder \"Vampire Hunter D Vol 8\", Candidate Series \"Vampire Hunter D\", Candidate Title \"Mysterious Journey\". (Matches Series).\n\n\n3. **Volume/Series Logic (Conflict Check ONLY):**\n - **Enrichment is Allowed:** If the folder does NOT mention a series or volume, but the Candidate DOES, this is ACCEPTABLE. Do not fail.\n - **Volume 1** may not have a volume number in the title, this is always acceptable.\n - **Contradiction Check:** Only fail if the folder *explicitly* lists a number that conflicts with the Candidate.\n - *Example FAIL:* Folder says \"Book 4\", Candidate says \"volume_num: 8\".\n - *Example PASS:* Folder says \"Star Wars\", Candidate says \"Series: Star Wars, Vol: 6\". (Enrichment).\n\n4. **ASIN Presence:**\n - If the folder contains an ASIN (starts with 'B0'), does the candidate ASIN match it exactly?\n - The Candidate Metadata ASIN MUST be present to pass.\n\n### OUTPUT FORMAT\nOutput a single JSON object. Do not output markdown or text.\n\n{\n \"status\": \"PASS\" | \"FAIL\",\n \"reason\": \"Brief explanation of why it failed (or 'Verified' if passed)\",\n}", "batching": {} }, "type": "@n8n/n8n-nodes-langchain.chainLlm", "typeVersion": 1.7, "position": [ 2624, 240 ], "id": "df0e56d2-92ad-4ec9-b7f1-1044b3d9eb72", "name": "QA Agent" }, { "parameters": { "sendTo": "me@ben.io", "subject": "Anime Series List Update", "message": "=This is an update that your Anime Audiobook Library, we've identified the following new books:\n\n{{ $json.email_summary }}\n\n", "options": { "appendAttribution": true, "senderName": "n8n Anime Series List" } }, "type": "n8n-nodes-base.gmail", "typeVersion": 2.2, "position": [ 2272, 16 ], "id": "6c328083-2cf9-4485-81bb-ba5b5fa3988e", "name": "Send a message", "webhookId": "d5463123-d50d-4eab-86c9-f71d18587d54", "credentials": { "gmailOAuth2": { "id": "Os1ux3h3zFlC2XkG", "name": "Gmail account" } } }, { "parameters": { "jsCode": "// Get all items from the previous node\nconst items = $input.all();\n\n// Create an HTML list of the books\nconst bookList = items.map(item => {\n return `
  • ${item.json.book_name} by ${item.json.author_folder}
  • `;\n}).join('');\n\n// Return an ARRAY containing the single summary item\nreturn [{\n json: {\n email_summary: `
      ${bookList}
    `,\n count: items.length\n }\n}];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 2016, 16 ], "id": "9657e35b-b89a-4d94-9ce2-41ba8ee70062", "name": "Code in JavaScript" }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 3 }, "conditions": [ { "id": "c7daf60b-1af4-4764-a657-a1d66d30e1ee", "leftValue": "={{ $json.book_name }}", "rightValue": "PASS", "operator": { "type": "string", "operation": "exists", "singleValue": true } } ], "combinator": "and" }, "options": {} }, "type": "n8n-nodes-base.if", "typeVersion": 2.3, "position": [ 1744, 64 ], "id": "d03ed1a1-1a8f-4863-97f8-2db150e77b68", "name": "If" }, { "parameters": { "description": "Call this tool to lookup an Author and Book Name from Audible.", "workflowId": { "__rl": true, "value": "Z_YHsJaf_pyFQR6e7VuLo", "mode": "list", "cachedResultUrl": "/workflow/Z_YHsJaf_pyFQR6e7VuLo", "cachedResultName": "search_audible" }, "workflowInputs": { "mappingMode": "defineBelow", "value": { "book-name": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('book-name', ``, 'string') }}", "author": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('author', ``, 'string') }}" }, "matchingColumns": [], "schema": [ { "id": "book-name", "displayName": "book-name", "required": false, "defaultMatch": false, "display": true, "canBeUsedToMatch": true, "type": "string", "removed": false }, { "id": "author", "displayName": "author", "required": false, "defaultMatch": false, "display": true, "canBeUsedToMatch": true, "type": "string", "removed": false }, { "id": "asin", "displayName": "asin", "required": false, "defaultMatch": false, "display": true, "canBeUsedToMatch": true, "type": "string", "removed": true } ], "attemptToConvertTypes": false, "convertFieldsToString": false } }, "type": "@n8n/n8n-nodes-langchain.toolWorkflow", "typeVersion": 2.2, "position": [ 1776, 608 ], "id": "81007b3e-3baa-4f95-bcb5-6e73fdcb91a0", "name": "audible_search_book" }, { "parameters": { "description": "Call this tool to lookup an ASIN from Audible.", "workflowId": { "__rl": true, "value": "Z_YHsJaf_pyFQR6e7VuLo", "mode": "list", "cachedResultUrl": "/workflow/Z_YHsJaf_pyFQR6e7VuLo", "cachedResultName": "search_audible" }, "workflowInputs": { "mappingMode": "defineBelow", "value": { "asin": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('asin', ``, 'string') }}" }, "matchingColumns": [], "schema": [ { "id": "book-name", "displayName": "book-name", "required": false, "defaultMatch": false, "display": true, "canBeUsedToMatch": true, "type": "string", "removed": true }, { "id": "author", "displayName": "author", "required": false, "defaultMatch": false, "display": true, "canBeUsedToMatch": true, "type": "string", "removed": true }, { "id": "asin", "displayName": "asin", "required": false, "defaultMatch": false, "display": true, "canBeUsedToMatch": true, "type": "string", "removed": false } ], "attemptToConvertTypes": false, "convertFieldsToString": false } }, "type": "@n8n/n8n-nodes-langchain.toolWorkflow", "typeVersion": 2.2, "position": [ 1600, 608 ], "id": "dd7f49fd-2bd1-4e06-9402-5087db1c3a1e", "name": "audible_lookup_asin" } ], "connections": { "Code": { "main": [ [ { "index": 0, "node": "Filter Existing", "type": "main" } ] ] }, "List General Folders": { "main": [ [ { "index": 0, "node": "Code", "type": "main" }, { "node": "Select rows from a table", "type": "main", "index": 0 } ] ] }, "Workflow Trigger": { "main": [ [ { "index": 0, "node": "List General Folders", "type": "main" } ] ] }, "tavily_search": { "ai_tool": [ [ { "node": "Lookup Agent", "type": "ai_tool", "index": 0 } ] ] }, "Lookup Agent": { "main": [ [ { "node": "Merge", "type": "main", "index": 0 } ] ] }, "Loop Over Items": { "main": [ [ { "node": "If", "type": "main", "index": 0 } ], [ { "node": "Lookup Agent", "type": "main", "index": 0 }, { "node": "Merge", "type": "main", "index": 1 } ] ] }, "google_search": { "ai_tool": [ [ { "node": "Lookup Agent", "type": "ai_tool", "index": 0 } ] ] }, "Filter Unwanted": { "main": [ [ { "node": "Loop Over Items", "type": "main", "index": 0 } ] ] }, "Merge": { "main": [ [ { "node": "QA Agent", "type": "main", "index": 0 } ] ] }, "verified": { "main": [ [ { "node": "Insert or update rows in a table", "type": "main", "index": 0 } ], [ { "node": "Formatting", "type": "main", "index": 0 } ] ] }, "Insert or update rows in a table": { "main": [ [ { "node": "Formatting", "type": "main", "index": 0 } ], [ { "node": "Formatting", "type": "main", "index": 0 } ] ] }, "Formatting": { "main": [ [ { "node": "Loop Over Items", "type": "main", "index": 0 } ] ] }, "Structured Output Parser": { "ai_outputParser": [ [ { "node": "Lookup Agent", "type": "ai_outputParser", "index": 0 } ] ] }, "Filter Existing": { "main": [ [ { "node": "Filter Unwanted", "type": "main", "index": 0 } ] ] }, "Ollama - gpt-oss:20b - Validator": { "ai_languageModel": [ [ { "node": "Structured Output Parser", "type": "ai_languageModel", "index": 0 }, { "node": "QA Agent", "type": "ai_languageModel", "index": 0 } ] ] }, "Schedule Trigger": { "main": [ [ { "node": "List General Folders", "type": "main", "index": 0 } ] ] }, "Select rows from a table": { "main": [ [ { "node": "Filter Existing", "type": "main", "index": 1 } ] ] }, "brave_search": { "ai_tool": [ [ { "node": "Lookup Agent", "type": "ai_tool", "index": 0 } ] ] }, "OpenAI Chat Model": { "ai_languageModel": [ [ { "node": "Lookup Agent", "type": "ai_languageModel", "index": 0 } ] ] }, "QA Agent": { "main": [ [ { "node": "verified", "type": "main", "index": 0 } ] ] }, "Code in JavaScript": { "main": [ [ { "node": "Send a message", "type": "main", "index": 0 } ] ] }, "If": { "main": [ [ { "node": "Code in JavaScript", "type": "main", "index": 0 } ] ] }, "audible_search_book": { "ai_tool": [ [ { "node": "Lookup Agent", "type": "ai_tool", "index": 0 } ] ] }, "audible_lookup_asin": { "ai_tool": [ [ { "node": "Lookup Agent", "type": "ai_tool", "index": 0 } ] ] } }, "settings": { "executionOrder": "v1", "callerPolicy": "workflowsFromSameOwner", "availableInMCP": false }, "triggerCount": 1, "versionId": "3d6dd137-edea-4f87-b0aa-b8e81362e8b5", "owner": { "type": "personal", "projectId": "FeLO36wNUAcn61Wj", "projectName": "Ben W ", "personalEmail": "admin@ben.io" }, "parentFolderId": "6tDyZCwqELStb6Ik", "isArchived": false }