Skip to content

feat(nodes): add n8n workflow-automation node#1231

Open
kgarg2468 wants to merge 4 commits into
rocketride-org:developfrom
kgarg2468:feat/RR-1230-n8n-node
Open

feat(nodes): add n8n workflow-automation node#1231
kgarg2468 wants to merge 4 commits into
rocketride-org:developfrom
kgarg2468:feat/RR-1230-n8n-node

Conversation

@kgarg2468

@kgarg2468 kgarg2468 commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add tool_n8n — a dual node (pipeline step and agent tool, like db_postgres) that triggers self-hosted n8n workflows from a RocketRide pipeline or agent and consumes their results (sync or async).
  • RR→n8n via webhook trigger + the public REST API (list/inspect workflows, poll executions); n8n→RR + round-trips documented with importable templates.
  • Rich I/O (structured payloads + files/binary both ways), broad webhook auth (none/header/basic/bearer/JWT), SSRF containment, read-only gating, deploy-aware reachability preflight, configurable timeouts, and n8n execution deep-links.

Type

feature (new pipeline + agent-tool node) + docs + tests

Testing

  • Tests added or updated — nodes/test/test_tool_n8n.py
  • Tested locally — ruff clean; 283 unit + contract tests pass; 15/15 live e2e against a real n8n (sync, async, sequential, round-trip, binary send/receive, non-webhook reach)
  • ./builder test passes — couldn't run the C++ builder locally (toolchain not installed); the identical test_contracts.py passes via pytest; CI runs the wrapper

Checklist

  • Commit messages follow conventional commits
  • No secrets or credentials included
  • Wiki updated (if applicable) — docs at docs/README-n8n.md + node README.md
  • Breaking changes documented (if applicable) — none (purely additive)

Linked Issue

Closes #1230

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • n8n integration: trigger workflows, chain round-trips, sync/async modes, payload formats, binary file support, webhook auth, read-only mode, and workflow/execution controls with deep-link observability
  • Documentation

    • Comprehensive n8n integration guide, setup/reachability notes, webhook contracts, and environment variable usage
  • Examples

    • Multiple runnable examples: round-trip, dispatch, fanout, agent, and call-workflow flows
  • Tests

    • Unit tests for webhook flows, auth, polling/retries, payloads, and binary reassembly
  • Chores

    • Broadened config allowlist regex for scanning rules

Add `tool_n8n`, a dual node (pipeline step + agent tool) that triggers
self-hosted n8n workflows and consumes their results. Mirrors tool_github
(multi-fn REST + sibling client module) and db_postgres (dual classType).

- RR->n8n: webhook trigger -- sync (Respond-to-Webhook) or async polling of
  executions via a correlation id; public REST API to list/inspect workflows
  and executions; activate/deactivate gated by a read-only toggle.
- Rich I/O: simple or structured payloads (documents + metadata); files/binary
  both ways via multipart (image/audio/video lanes); table output lane.
- Safety/DX: SSRF containment (agent never picks the host); none/header/basic/
  bearer/JWT webhook auth; TLS-verify toggle; deploy-aware reachability
  preflight (host.docker.internal hint); 404->activate and ack->Respond-node
  guidance; configurable sync/async timeouts; n8n execution deep-links.
- n8n->RR + round-trips documented (docs/README-n8n.md) with importable
  templates under examples/n8n/ (fan-out, agent, round-trip, dispatcher).

Verified: ruff clean, 283 unit + contract tests, 15/15 live e2e against a real
n8n (sync / async / sequential / round-trip / binary / non-webhook reach).

Closes rocketride-org#1230

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added docs Documentation module:nodes Python pipeline nodes labels Jun 11, 2026
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a dual-mode n8n integration (tool_n8n): HTTP client, IGlobal config, IInstance tool+pipeline faces (SSRF guards, sync/async polling, binary handling), service/schema and package init, runnable examples/docs, requirements/service wiring, and comprehensive unit tests.

Changes

n8n workflow-automation integration node

Layer / File(s) Summary
Service registration & global config
nodes/src/nodes/tool_n8n/services.json, nodes/src/nodes/tool_n8n/IGlobal.py, nodes/src/nodes/tool_n8n/requirements.txt, nodes/src/nodes/requirements.txt, nodes/src/nodes/tool_n8n/__init__.py
Registers the tool_n8n:// service, installs package-local requirements at import, and bootstraps/validates global config (base URL, API key, default workflow, mode, payload mode, timeouts, TLS verify, read-only, webhook auth).
HTTP client and async helpers
nodes/src/nodes/tool_n8n/n8n_client.py, nodes/src/nodes/tool_n8n/requirements.txt
Deploy-aware n8n REST client: call(), trigger_webhook(), multipart support, response parsing (binary/JSON/text), GET-only retry/backoff with Retry-After, workflow lookup by webhook path, execution polling (wait_for_execution), preflight/container-aware messaging, and response shapers.
Instance init & tool orchestration
nodes/src/nodes/tool_n8n/IInstance.py (init + tool face)
Instance initialization, SSRF-safe _safe_path, preflight probe, sync vs async _run_webhook orchestration with correlation id + polling, and tool-facing methods (trigger_workflow, list_workflows, get_workflow, list_executions, get_execution, activate_workflow, deactivate_workflow).
Pipeline lifecycle, payloads & multipart
nodes/src/nodes/tool_n8n/IInstance.py (pipeline face)
Per-object buffering (open/write*), document metadata coercion, AVI chunk reassembly with _MAX_BINARY_BYTES guard, _build_payload (simple/structured), _build_multipart for files, and closing() emission to text, answers, documents, table, and AVI lanes.
Documentation & runnable examples
docs/README-n8n.md, nodes/src/nodes/tool_n8n/README.md, examples/README.md, examples/n8n/*.workflow.json, examples/n8n/*.pipe, .gitleaks.toml
Adds full integration docs, node README, runnable workflow/pipes demonstrating RR↔n8n round-trips, setup/reachability notes, environment-variable placeholders, and gitleaks allowlist tweaks for variable names.
Tests
nodes/test/test_tool_n8n.py
Extensive pure-unit tests covering ack detection, auth mapping, preflight messaging, workflow/execution shaping, SSRF guards, polling/timeouts/correlation, retry/backoff behavior, payload modes, binary reassembly/multipart, emission, and deeplink enrichment.

Sequence Diagram(s)

sequenceDiagram
  participant RocketRide as RocketRide
  participant Webhook as n8n Webhook
  participant API as n8n API
  RocketRide->>Webhook: POST workflow payload
  alt Sync response
    Webhook-->>RocketRide: Return webhook result
  else Async start
    Webhook-->>RocketRide: Return started acknowledgment
    RocketRide->>API: Poll executions by workflow and correlation id
    API-->>RocketRide: Return execution result
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • jmaionchi
  • stepmikhaylov
  • Rod-Christensen
  • asclearuc

🐰 I hopped through webhooks, headers, and keys,
Into workflows that hum like the bees.
Sync or async, with binaries in tow,
RocketRide and n8n now gracefully flow.
Cheers from the rabbit — may automations grow!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(nodes): add n8n workflow-automation node' directly and clearly describes the main change: adding a new n8n integration node to the codebase.
Linked Issues check ✅ Passed All primary coding objectives from issue #1230 are fully implemented: dual-node pattern, RR→n8n webhook triggering (sync/async), REST operations (list/inspect/activate/deactivate), rich I/O support (structured payloads, multipart binary), safety features (SSRF containment, auth modes, TLS toggle, reachability preflight), and documentation/examples.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #1230 objectives. Additions include node implementation (IGlobal, IInstance, n8n_client), configuration (services.json), comprehensive documentation, example templates, tests, and dependency pinning for security—all within scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
🤖 Internal: Discord sync marker

Auto-managed by the Discord notification workflow. Stores the linked Discord message ID. Do not edit or delete.

The pipe-file/services-json API-key rules allowlist `${VAR}` placeholders,
but the regex `[A-Z_]+` excluded digits — so `${ROCKETRIDE_N8N_KEY}` and
`${ROCKETRIDE_N8N_URL}` (the `8` in n8n) were flagged as secrets while
digit-free names like `${ROCKETRIDE_OPENAI_KEY}` were not. Widen the
allowlist to `[A-Z0-9_]+` so digit-containing env-var names are recognized.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/README-n8n.md`:
- Around line 56-61: Update the fenced code blocks in README-n8n.md to include a
language identifier to satisfy markdownlint MD040: change the opening ``` fences
that wrap the ASCII diagrams (the two blocks shown around the n8n dispatcher /
RR pipeline diagrams) to use ```text so both diagram code fences start with
```text; ensure you update both occurrences (the block at lines ~56-61 and the
other at ~91-97) and leave the diagram content unchanged.

In `@examples/README.md`:
- Around line 88-90: The fenced code block in the examples README is missing a
language tag (MD040); update the fence for the snippet `webhook -> tool_n8n
(triggers n8n workflow "rocketride-demo") -> response` to use a language tag
`text` so the block starts with ```text and ends with ```, ensuring the linter
no longer flags MD040.

In `@nodes/src/nodes/tool_n8n/IInstance.py`:
- Around line 103-115: The _safe_path function currently blocks URLs but allows
path traversal, dot segments, and query/fragment syntax; update _safe_path to
also reject any path containing '?' or '#' and to validate each '/'-separated
segment (no empty segments, no '.' or '..', and only allow a safe charset like
alphanumerics, hyphen, underscore, and maybe dot if desired) so only plain
webhook path segments are accepted before passing into trigger_webhook; ensure
you keep the existing checks (scheme, whitespace) and return the normalized path
without leading slashes.

In `@nodes/src/nodes/tool_n8n/n8n_client.py`:
- Around line 319-321: The timestamp comparison currently compares strings;
instead parse both started_after and summary.get('startedAt') into
timezone-aware datetimes before comparing to avoid lexicographic errors. In the
block that checks started_after (the variables started_after and
summary.get('startedAt') in the if condition), convert summary.get('startedAt')
(handle trailing "Z" or other ISO variants) and started_after to datetime
objects (e.g., using dateutil.parser.isoparse or normalizing "Z" to "+00:00" and
using datetime.fromisoformat) and then perform the comparison; keep the
checked.add(eid) and continue behavior the same when the parsed summary time is
earlier than started_after.

In `@nodes/src/nodes/tool_n8n/README.md`:
- Around line 57-67: Update the README configuration table to match the node
schema in nodes/src/nodes/tool_n8n/services.json: add a "Sync timeout" row (show
default and description) and expand the "Webhook auth" row to list supported
values including bearer and jwt (not just none/header/basic), and verify default
values and descriptions for "Async timeout", "Webhook auth", "Read-only mode",
and "Verify TLS certificate" match the corresponding keys in services.json
(e.g., Webhook auth, syncTimeout, asyncTimeout, readOnly) so the table reflects
the actual contract users configure.

In `@nodes/src/nodes/tool_n8n/requirements.txt`:
- Line 1: The requirements file only pins requests (requests>=2.34.2) and does
not constrain idna, allowing a vulnerable transitive idna to be resolved; add a
pinned safe idna version (the patched fixed release) by adding an explicit
idna==<fixed_version> (or idna>=<fixed_version> if you prefer a floor) either
into the shared nodes/src/nodes/requirements.txt (preferred) or directly into
nodes/src/nodes/tool_n8n/requirements.txt alongside the existing
requests>=2.34.2 entry so the node can no longer resolve the vulnerable idna.

In `@nodes/src/nodes/tool_n8n/services.json`:
- Around line 18-20: The services metadata currently lists outputs for "image",
"audio", and "video" as ["image","text","answers"] but omits "table", which
prevents binary-input pipelines from wiring IInstance.closing() structured
outputs; update the entries for "image", "audio", and "video" in
nodes/src/nodes/tool_n8n/services.json to include "table" alongside the existing
outputs so the binary routes advertise the same "table" lane as text/documents
and can accept structured dict/list results from IInstance.closing().
- Around line 181-193: The smoke test "test" case is missing required workflow
config so IInstance.closing() exits immediately; update the test case in the
"test" block to supply a valid workflow (or switch the "profiles" to one that
defines tool_n8n.workflow) so the harness has a configured workflow before
running — reference the "test" object, the "profiles": ["default"] entry, and
the tool_n8n.workflow setting and ensure the case includes the workflow ID or
uses a profile that sets it so the harness proceeds to call n8n when
ROCKETRIDE_N8N_KEY is present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0062e832-546d-428b-b06e-b4634b94a878

📥 Commits

Reviewing files that changed from the base of the PR and between 1995c64 and 6a1c438.

⛔ Files ignored due to path filters (1)
  • nodes/src/nodes/tool_n8n/n8n.svg is excluded by !**/*.svg
📒 Files selected for processing (17)
  • docs/README-n8n.md
  • examples/README.md
  • examples/n8n-call-rocketride.workflow.json
  • examples/n8n-roundtrip.pipe
  • examples/n8n/n8n-agent.pipe
  • examples/n8n/n8n-dispatch.workflow.json
  • examples/n8n/n8n-fanout.pipe
  • examples/n8n/n8n-roundtrip-target.pipe
  • examples/n8n/n8n-roundtrip.pipe
  • nodes/src/nodes/tool_n8n/IGlobal.py
  • nodes/src/nodes/tool_n8n/IInstance.py
  • nodes/src/nodes/tool_n8n/README.md
  • nodes/src/nodes/tool_n8n/__init__.py
  • nodes/src/nodes/tool_n8n/n8n_client.py
  • nodes/src/nodes/tool_n8n/requirements.txt
  • nodes/src/nodes/tool_n8n/services.json
  • nodes/test/test_tool_n8n.py

Comment thread docs/README-n8n.md Outdated
Comment thread examples/README.md Outdated
Comment thread nodes/src/nodes/tool_n8n/IInstance.py Outdated
Comment thread nodes/src/nodes/tool_n8n/IInstance.py
Comment thread nodes/src/nodes/tool_n8n/n8n_client.py Outdated
Comment thread nodes/src/nodes/tool_n8n/README.md
Comment thread nodes/src/nodes/tool_n8n/requirements.txt
Comment thread nodes/src/nodes/tool_n8n/services.json Outdated
Comment thread nodes/src/nodes/tool_n8n/services.json
Resolve the 9 actionable items from the PR rocketride-org#1231 review:
- SSRF: _safe_path rejects path traversal, query/fragment, and backslashes
- Normalize tool-face results (binary -> descriptor, JSON scalars -> string)
  to the advertised object/array/string/null schema
- Compare async execution timestamps as tz-aware datetimes, not strings
- Pin idna>=3.10 (GHSA-65pc-fj4g-8rjx) in node + shared requirements
- Advertise the table lane on image/audio/video routes
- Smoke test requires ROCKETRIDE_N8N_WORKFLOW so a workflow is configured
- Sync the README config table (Sync timeout; bearer/jwt webhook auth)
- MD040: add a language to the README/example fenced diagrams
- Extend the unit suite (path guard, result normalization, timestamp compare)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
nodes/src/nodes/tool_n8n/README.md (1)

28-33: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

The lane table understates the non-binary outputs this node can emit.

closing() writes successful non-binary results to text, answers, and documents whenever those listeners are connected, plus table for dict/list results. The current rows omit documents for text/questions, and omit answers for documents, so readers can miss supported downstream wiring.

Suggested doc update
-| `text`      | `text`, `answers`, `table`   | Sends the text to the configured workflow; emits the result   |
-| `questions` | `answers`, `text`, `table`   | Sends the question text to the workflow; emits the result     |
-| `documents` | `documents`, `text`, `table` | Sends the documents to the workflow; emits the result         |
+| `text`      | `text`, `answers`, `documents`, `table`      | Sends the text to the configured workflow; emits the result |
+| `questions` | `text`, `answers`, `documents`, `table`      | Sends the question text to the workflow; emits the result   |
+| `documents` | `text`, `answers`, `documents`, `table`      | Sends the documents to the workflow; emits the result       |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nodes/src/nodes/tool_n8n/README.md` around lines 28 - 33, The lane table is
missing some non-binary outputs emitted by closing(): update the table rows so
that the `text` and `questions` input lanes list outputs `text`, `answers`,
`documents`, `table` and the `documents` input lane lists `documents`, `text`,
`answers`, `table`; ensure the `image`/`audio`/`video` row still lists binary
and `text` outputs and that `table` remains included for dict/list results to
reflect the actual emissions by closing().
nodes/test/test_tool_n8n.py (1)

99-110: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

The bootstrap still leaks stubbed dependencies through the cached nodes.tool_n8n.* modules.

Popping rocketlib/requests/ai.common.* from sys.modules is not enough here: nodes.tool_n8n.n8n_client and nodes.tool_n8n.IInstance stay cached with those MagicMock-backed imports already bound. Any later test importing these modules in the same pytest session will reuse the stubbed module objects, so suite behavior becomes order-dependent.

Suggested fix
 client = importlib.import_module('nodes.tool_n8n.n8n_client')
 instance_mod = importlib.import_module('nodes.tool_n8n.IInstance')

 # Drop the stubs we injected so they never leak into the shared pytest session.
 for _name in _added_stubs:
     sys.modules.pop(_name, None)
+for _name in ('nodes.tool_n8n.n8n_client', 'nodes.tool_n8n.IInstance'):
+    sys.modules.pop(_name, None)

This keeps the local client / instance_mod references usable in this file while letting later imports load fresh modules with real dependencies.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nodes/test/test_tool_n8n.py` around lines 99 - 110, The test imports modules
while stubbed dependencies are present, leaving nodes.tool_n8n.n8n_client and
nodes.tool_n8n.IInstance cached with MagicMock-backed imports and causing later
tests to reuse the stubbed module objects; after creating local references
client and instance_mod, remove those module entries from sys.modules (e.g.,
sys.modules.pop('nodes.tool_n8n.n8n_client', None) and
sys.modules.pop('nodes.tool_n8n.IInstance', None)) so the local variables remain
usable but subsequent imports will load fresh real modules; keep the existing
stub cleanup loop for _added_stubs and ensure this pop happens after assigning
client and instance_mod.
nodes/src/nodes/tool_n8n/IInstance.py (1)

472-488: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

payload_mode='simple' is ignored as soon as a file is attached.

_build_payload() preserves the simple-mode contract by sending {'data': ...}, but _build_multipart() always switches to text/documents. That means the same workflow sees a different request shape depending on whether binary is present, which breaks back-compat for simple-mode webhooks and contradicts the documented payload contract.

Suggested fix
 def _build_multipart(self):
     """Build (text fields, files) for a multipart POST when binary input is present."""
     fields: Dict[str, Any] = {}
     text = ''.join(self._text_parts)
-    if text:
-        fields['text'] = text
-    if self._documents:
-        fields['documents'] = json.dumps(self._documents, default=str)
+    if self.IGlobal.payload_mode == 'structured':
+        if text:
+            fields['text'] = text
+        if self._documents:
+            fields['documents'] = json.dumps(self._documents, default=str)
+    else:
+        data = text + ''.join(d.get('content', '') for d in self._documents)
+        if data:
+            fields['data'] = data
     files: Dict[str, Any] = {}
     counters: Dict[str, int] = {}
     for item in self._binary:
         kind = item['kind']
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nodes/src/nodes/tool_n8n/IInstance.py` around lines 472 - 488, The multipart
builder currently always emits fields 'text'/'documents', breaking
payload_mode='simple'; update _build_multipart to respect self.payload_mode (or
payload_mode attribute used by _build_payload) and when it's 'simple' build the
same simple-mode shape by setting fields['data'] to the combined text or
JSON-serialized documents (instead of 'text'/'documents'), while still attaching
files into files dict the same way; reference _build_multipart, _build_payload,
self._text_parts, self._documents and self._binary when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@nodes/src/nodes/tool_n8n/IInstance.py`:
- Around line 472-488: The multipart builder currently always emits fields
'text'/'documents', breaking payload_mode='simple'; update _build_multipart to
respect self.payload_mode (or payload_mode attribute used by _build_payload) and
when it's 'simple' build the same simple-mode shape by setting fields['data'] to
the combined text or JSON-serialized documents (instead of 'text'/'documents'),
while still attaching files into files dict the same way; reference
_build_multipart, _build_payload, self._text_parts, self._documents and
self._binary when making the change.

In `@nodes/src/nodes/tool_n8n/README.md`:
- Around line 28-33: The lane table is missing some non-binary outputs emitted
by closing(): update the table rows so that the `text` and `questions` input
lanes list outputs `text`, `answers`, `documents`, `table` and the `documents`
input lane lists `documents`, `text`, `answers`, `table`; ensure the
`image`/`audio`/`video` row still lists binary and `text` outputs and that
`table` remains included for dict/list results to reflect the actual emissions
by closing().

In `@nodes/test/test_tool_n8n.py`:
- Around line 99-110: The test imports modules while stubbed dependencies are
present, leaving nodes.tool_n8n.n8n_client and nodes.tool_n8n.IInstance cached
with MagicMock-backed imports and causing later tests to reuse the stubbed
module objects; after creating local references client and instance_mod, remove
those module entries from sys.modules (e.g.,
sys.modules.pop('nodes.tool_n8n.n8n_client', None) and
sys.modules.pop('nodes.tool_n8n.IInstance', None)) so the local variables remain
usable but subsequent imports will load fresh real modules; keep the existing
stub cleanup loop for _added_stubs and ensure this pop happens after assigning
client and instance_mod.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 416753b1-0928-482b-ae81-975dea9261f9

📥 Commits

Reviewing files that changed from the base of the PR and between 6564b0d and 084a206.

📒 Files selected for processing (9)
  • docs/README-n8n.md
  • examples/README.md
  • nodes/src/nodes/requirements.txt
  • nodes/src/nodes/tool_n8n/IInstance.py
  • nodes/src/nodes/tool_n8n/README.md
  • nodes/src/nodes/tool_n8n/n8n_client.py
  • nodes/src/nodes/tool_n8n/requirements.txt
  • nodes/src/nodes/tool_n8n/services.json
  • nodes/test/test_tool_n8n.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
examples/README.md (1)

106-113: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language tag to this fenced block.

This snippet will still trigger MD040; mark it as text so the README stays lint-clean. citeturn0search0

Suggested patch
-```
+```text
 chat -> LlamaIndex agent -> response
               |
         +-----+-----+
@@
-```
+```
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/README.md` around lines 106 - 113, The fenced code block containing
the ASCII diagram "chat -> LlamaIndex agent -> response" should include a
language tag to satisfy MD040; update the opening fence from ``` to ```text in
the README examples block so the diagram is marked as plain text (ensure only
the opening backticks are changed for the block that contains the ASCII art).

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@examples/README.md`:
- Around line 106-113: The fenced code block containing the ASCII diagram "chat
-> LlamaIndex agent -> response" should include a language tag to satisfy MD040;
update the opening fence from ``` to ```text in the README examples block so the
diagram is marked as plain text (ensure only the opening backticks are changed
for the block that contains the ASCII art).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 07d32de4-6019-4185-9413-4df0197d4b4f

📥 Commits

Reviewing files that changed from the base of the PR and between 084a206 and 860a290.

📒 Files selected for processing (1)
  • examples/README.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation module:nodes Python pipeline nodes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add n8n workflow-automation node (tool_n8n)

1 participant