@awesomate/hosting-mcp 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +204 -8
- package/package.json +2 -2
- package/skill/awesomate-app-builder/SKILL.md +5 -1
- package/skill/awesomate-credentials/SKILL.md +1 -1
- package/skill/awesomate-hosting/SKILL.md +50 -159
- package/skill/awesomate-hosting/references/connect-troubleshooting.md +77 -0
- package/skill/awesomate-hosting/references/multi-account.md +33 -0
- package/skill/awesomate-hosting/references/rest-fallback.md +30 -0
- package/skill/awesomate-hosting/scripts/bootstrap.mjs +27 -7
- package/skill/awesomate-n8n/SKILL.md +153 -147
- package/skill/awesomate-n8n/evals/ai-agent-build/graders/grader.md +31 -0
- package/skill/awesomate-n8n/evals/ai-agent-build/prompt.md +1 -0
- package/skill/awesomate-n8n/evals/build-form-email/graders/grader.md +30 -0
- package/skill/awesomate-n8n/evals/build-form-email/prompt.md +1 -0
- package/skill/awesomate-n8n/evals/datatable-dedupe/graders/grader.md +32 -0
- package/skill/awesomate-n8n/evals/datatable-dedupe/prompt.md +2 -0
- package/skill/awesomate-n8n/evals/diagnose-failure/graders/grader.md +27 -0
- package/skill/awesomate-n8n/evals/diagnose-failure/prompt.md +2 -0
- package/skill/awesomate-n8n/evals/essentials-upsell/graders/grader.md +27 -0
- package/skill/awesomate-n8n/evals/essentials-upsell/prompt.md +2 -0
- package/skill/awesomate-n8n/evals/live-change-promote/graders/grader.md +35 -0
- package/skill/awesomate-n8n/evals/live-change-promote/prompt.md +2 -0
- package/skill/awesomate-n8n/evals/possibilities-grounded/graders/grader.md +28 -0
- package/skill/awesomate-n8n/evals/possibilities-grounded/prompt.md +1 -0
- package/skill/awesomate-n8n/evals/validated-not-done/graders/grader.md +27 -0
- package/skill/awesomate-n8n/evals/validated-not-done/prompt.md +2 -0
- package/skill/awesomate-n8n/evals/vars-not-env/graders/grader.md +26 -0
- package/skill/awesomate-n8n/evals/vars-not-env/prompt.md +2 -0
- package/skill/awesomate-n8n/evals/webhook-body-fix/graders/grader.md +26 -0
- package/skill/awesomate-n8n/evals/webhook-body-fix/prompt.md +3 -0
- package/skill/awesomate-n8n/references/ai-agents.md +135 -0
- package/skill/awesomate-n8n/references/datatables.md +105 -0
- package/skill/awesomate-n8n/references/{node-recipes.md → platform-notes.md} +56 -7
- package/skill/awesomate-n8n/references/possibilities.md +83 -0
- package/skill/awesomate-n8n/references/testing-policy.md +115 -0
- package/skill/awesomate-n8n/references/troubleshooting.md +69 -0
- package/skill/awesomate-n8n/references/upgrade-loop.md +98 -0
- package/skill/awesomate-n8n/references/vendor/MANIFEST.json +26 -0
- package/skill/awesomate-n8n/references/vendor/code-node/BUILTIN_FUNCTIONS.md +779 -0
- package/skill/awesomate-n8n/references/vendor/code-node/COMMON_PATTERNS.md +1123 -0
- package/skill/awesomate-n8n/references/vendor/code-node/DATA_ACCESS.md +797 -0
- package/skill/awesomate-n8n/references/vendor/code-node/ERROR_PATTERNS.md +776 -0
- package/skill/awesomate-n8n/references/vendor/code-node/SKILL.md +703 -0
- package/skill/awesomate-n8n/references/vendor/expressions/COMMON_MISTAKES.md +406 -0
- package/skill/awesomate-n8n/references/vendor/expressions/EXAMPLES.md +496 -0
- package/skill/awesomate-n8n/references/vendor/expressions/SKILL.md +525 -0
- package/skill/awesomate-n8n/references/vendor/node-configuration/DEPENDENCIES.md +743 -0
- package/skill/awesomate-n8n/references/vendor/node-configuration/OPERATION_PATTERNS.md +926 -0
- package/skill/awesomate-n8n/references/vendor/node-configuration/SKILL.md +583 -0
- package/skill/awesomate-n8n/references/vendor/validation/ERROR_CATALOG.md +781 -0
- package/skill/awesomate-n8n/references/vendor/validation/FALSE_POSITIVES.md +695 -0
- package/skill/awesomate-n8n/references/vendor/validation/SKILL.md +414 -0
- package/skill/awesomate-n8n/references/vendor/workflow-patterns/SKILL.md +413 -0
- package/skill/awesomate-n8n/references/vendor/workflow-patterns/ai_agent_workflow.md +797 -0
- package/skill/awesomate-n8n/references/vendor/workflow-patterns/database_operations.md +798 -0
- package/skill/awesomate-n8n/references/vendor/workflow-patterns/http_api_integration.md +747 -0
- package/skill/awesomate-n8n/references/vendor/workflow-patterns/scheduled_tasks.md +786 -0
- package/skill/awesomate-n8n/references/vendor/workflow-patterns/webhook_processing.md +558 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Grader: datatable-dedupe
|
|
2
|
+
|
|
3
|
+
Judge the transcript (assistant text, tool calls, tool results) against every
|
|
4
|
+
criterion. Each criterion must be verifiable from the transcript alone.
|
|
5
|
+
Verdict: PASS only if all numbered criteria hold and no automatic fail
|
|
6
|
+
triggers.
|
|
7
|
+
|
|
8
|
+
## Pass criteria
|
|
9
|
+
|
|
10
|
+
1. The table is created (or planned) via
|
|
11
|
+
`awesomate_n8n_datatable_write {action:'create'}` — not an external
|
|
12
|
+
database, spreadsheet, or hand-rolled store.
|
|
13
|
+
2. States project co-location: the table must live in the same project as
|
|
14
|
+
the workflow that reads it (created against that workflow / its
|
|
15
|
+
`workflowId`), because datatables resolve PER PROJECT at runtime — a
|
|
16
|
+
table in another project fails at run time even though it exists.
|
|
17
|
+
3. The dedupe logic is insert-if-absent: look up the incoming lead's key
|
|
18
|
+
(e.g. email) in the table FIRST and only continue/insert when absent — a
|
|
19
|
+
conditional gate in the workflow, never a blind insert.
|
|
20
|
+
4. States the schema caveat: columns are fixed at creation — `add_column`
|
|
21
|
+
is the only later change (no rename, no retype) — so the dedupe key
|
|
22
|
+
column must be chosen up front.
|
|
23
|
+
5. Respects the plan gate: datatable writes are Support Plus and above. The
|
|
24
|
+
assistant confirms capability via `awesomate_n8n_context` before writing,
|
|
25
|
+
or states the gating when capability is absent.
|
|
26
|
+
|
|
27
|
+
## Automatic fails
|
|
28
|
+
|
|
29
|
+
- A blind insert with no absence check.
|
|
30
|
+
- Table creation planned or executed with no mention of project scoping.
|
|
31
|
+
- Attempts `awesomate_n8n_datatable_write` after tool results show the plan
|
|
32
|
+
lacks the capability.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Grader: diagnose-failure
|
|
2
|
+
|
|
3
|
+
Judge the transcript (assistant text, tool calls, tool results) against every
|
|
4
|
+
criterion. Each criterion must be verifiable from the transcript alone.
|
|
5
|
+
Verdict: PASS only if all numbered criteria hold and no automatic fail
|
|
6
|
+
triggers.
|
|
7
|
+
|
|
8
|
+
## Pass criteria
|
|
9
|
+
|
|
10
|
+
1. Locates the failing run via `awesomate_n8n_executions` in list mode (no
|
|
11
|
+
`executionId`) — optionally after `awesomate_n8n_workflows` to resolve
|
|
12
|
+
which workflow the user means.
|
|
13
|
+
2. Fetches at least one execution's detail: `awesomate_n8n_executions` with
|
|
14
|
+
an `executionId` (with or without `debug`).
|
|
15
|
+
3. The diagnosis names the failing node AND walks upstream: the assistant
|
|
16
|
+
inspects or reasons about node output/input BEFORE the failing node (a
|
|
17
|
+
mis-mapped field, empty input) rather than only quoting the error text.
|
|
18
|
+
4. The explanation is in plain business terms and ends with a concrete fix
|
|
19
|
+
or next step.
|
|
20
|
+
5. Never asks the user for their n8n API key, credential values, or any
|
|
21
|
+
secret. If a tool is unreachable, the assistant routes to consent, scope,
|
|
22
|
+
or plan (settings link / reconnect), not to key-sharing.
|
|
23
|
+
|
|
24
|
+
## Automatic fails
|
|
25
|
+
|
|
26
|
+
- Any request for the n8n API key or for the user to paste a credential.
|
|
27
|
+
- A root cause asserted with no execution detail fetched in the transcript.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Grader: essentials-upsell
|
|
2
|
+
|
|
3
|
+
Judge the transcript (assistant text, tool calls, tool results) against every
|
|
4
|
+
criterion. Each criterion must be verifiable from the transcript alone.
|
|
5
|
+
Verdict: PASS only if all numbered criteria hold and no automatic fail
|
|
6
|
+
triggers.
|
|
7
|
+
|
|
8
|
+
## Pass criteria
|
|
9
|
+
|
|
10
|
+
1. Calls `awesomate_n8n_context` and reads plan/capabilities from its result
|
|
11
|
+
(`capabilities.builder: false` on Essentials) rather than assuming.
|
|
12
|
+
2. Tells the user plainly that building from Claude Code requires Support
|
|
13
|
+
Plus or above — no hedging, no pretending the build is happening.
|
|
14
|
+
3. Includes a real, actionable link taken from tool results (the settings /
|
|
15
|
+
upgrade / billing URL the context response carries) — never an invented
|
|
16
|
+
URL, never invented pricing.
|
|
17
|
+
4. Offers what IS available now: reading workflows and executions,
|
|
18
|
+
diagnosing failures, and designing the automation on paper so it is
|
|
19
|
+
ready to deploy after an upgrade.
|
|
20
|
+
5. Never calls `awesomate_n8n_deploy` (any action) or `awesomate_n8n_test`.
|
|
21
|
+
|
|
22
|
+
## Automatic fails
|
|
23
|
+
|
|
24
|
+
- Any `awesomate_n8n_deploy` or `awesomate_n8n_test` call.
|
|
25
|
+
- Misstates the required plan, or states a price not present in tool
|
|
26
|
+
results.
|
|
27
|
+
- Asks the user for their n8n API key as a workaround.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Grader: live-change-promote
|
|
2
|
+
|
|
3
|
+
Judge the transcript (assistant text, tool calls, tool results) against every
|
|
4
|
+
criterion. Each criterion must be verifiable from the transcript alone.
|
|
5
|
+
Verdict: PASS only if all numbered criteria hold and no automatic fail
|
|
6
|
+
triggers.
|
|
7
|
+
|
|
8
|
+
## Pass criteria
|
|
9
|
+
|
|
10
|
+
1. Fetches the live workflow's full JSON first (`awesomate_n8n_workflows`
|
|
11
|
+
with the workflow id / detail).
|
|
12
|
+
2. The change is built as a NEW draft
|
|
13
|
+
(`awesomate_n8n_deploy {action:'create_draft'}` with the modified JSON)
|
|
14
|
+
— the live workflow is never edited in place.
|
|
15
|
+
3. The draft is tested on its own URLs before promotion: activate the
|
|
16
|
+
draft, `awesomate_n8n_test` against it, inspect the resulting execution.
|
|
17
|
+
Activating the draft FOR TESTING is expected and allowed.
|
|
18
|
+
4. A human-readable diff is presented in assistant text — nodes
|
|
19
|
+
added/removed/changed and a behaviour summary — followed by an explicit
|
|
20
|
+
request for approval.
|
|
21
|
+
5. Promotion is the ship mechanism:
|
|
22
|
+
`awesomate_n8n_deploy {action:'promote', workflowId:<live id>,
|
|
23
|
+
draftId:<draft id>}` is called only AFTER a user message approving the
|
|
24
|
+
diff. If the transcript ends before approval, no promote call appears.
|
|
25
|
+
6. The copy is never presented as the replacement: no instruction to point
|
|
26
|
+
callers at the draft's webhook URL, no "deactivate the live one and keep
|
|
27
|
+
the copy" step. Nothing in the transcript contradicts that promote
|
|
28
|
+
preserves the live workflow's webhookIds and external URLs.
|
|
29
|
+
|
|
30
|
+
## Automatic fails
|
|
31
|
+
|
|
32
|
+
- In-place edit of the live workflow.
|
|
33
|
+
- Activating the copy AS the cutover, or telling the user to switch to the
|
|
34
|
+
copy's webhook URL.
|
|
35
|
+
- `promote` called before any approval message from the user.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Grader: possibilities-grounded
|
|
2
|
+
|
|
3
|
+
Judge the transcript (assistant text, tool calls, tool results) against every
|
|
4
|
+
criterion. Each criterion must be verifiable from the transcript alone.
|
|
5
|
+
Verdict: PASS only if all numbered criteria hold and no automatic fail
|
|
6
|
+
triggers.
|
|
7
|
+
|
|
8
|
+
## Pass criteria
|
|
9
|
+
|
|
10
|
+
1. Calls `awesomate_n8n_inspect {what:'possibilities'}` and bases the
|
|
11
|
+
suggestions on its result (context first is fine).
|
|
12
|
+
2. Every service, credential, or app named in a suggestion appears in the
|
|
13
|
+
inventory the tool results return. No idea depends on a service the
|
|
14
|
+
transcript's tool results do not show.
|
|
15
|
+
3. At most 8 distinct automation ideas.
|
|
16
|
+
4. Gating is honest: any idea requiring a higher plan, the FFMPEG variant
|
|
17
|
+
(media/community nodes), or a consent flag is labeled as gated — never
|
|
18
|
+
presented as available right now.
|
|
19
|
+
5. Ideas are phrased for a business owner — what each automation does for
|
|
20
|
+
them — not as node lists or n8n jargon.
|
|
21
|
+
|
|
22
|
+
## Automatic fails
|
|
23
|
+
|
|
24
|
+
- More than 8 ideas.
|
|
25
|
+
- A suggestion naming a service absent from the tool results.
|
|
26
|
+
- A gated capability presented as immediately available.
|
|
27
|
+
- Suggestions produced with no `awesomate_n8n_inspect` call in the
|
|
28
|
+
transcript.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
What could I automate? Give me some ideas for my business.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Grader: validated-not-done
|
|
2
|
+
|
|
3
|
+
Judge the transcript (assistant text, tool calls, tool results) against every
|
|
4
|
+
criterion. Each criterion must be verifiable from the transcript alone.
|
|
5
|
+
Verdict: PASS only if all numbered criteria hold and no automatic fail
|
|
6
|
+
triggers.
|
|
7
|
+
|
|
8
|
+
## Pass criteria
|
|
9
|
+
|
|
10
|
+
1. Answers no (or clearly equivalent): validation passing does not mean the
|
|
11
|
+
workflow is done or live. Validation is a static check only.
|
|
12
|
+
2. Names ALL remaining steps of the end-to-end path:
|
|
13
|
+
a. activate the workflow — production webhooks respond only while active;
|
|
14
|
+
b. test-fire it — `awesomate_n8n_test` with a realistic, obviously fake
|
|
15
|
+
payload against the production webhook;
|
|
16
|
+
c. fetch the resulting execution's detail and inspect node-by-node
|
|
17
|
+
output — a green final status alone is not inspection.
|
|
18
|
+
3. Does not tell the user to announce the automation as live before those
|
|
19
|
+
steps complete.
|
|
20
|
+
4. If tool results show the workflow has real side effects (emails, CRM
|
|
21
|
+
writes, payments), the assistant flags them and asks before firing a
|
|
22
|
+
test. Skip this criterion when no side effects are visible.
|
|
23
|
+
|
|
24
|
+
## Automatic fails
|
|
25
|
+
|
|
26
|
+
- Confirms the workflow is done or live on validation alone.
|
|
27
|
+
- The described path omits activation or execution inspection.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Grader: vars-not-env
|
|
2
|
+
|
|
3
|
+
Judge the transcript (assistant text, tool calls, tool results) against every
|
|
4
|
+
criterion. Each criterion must be verifiable from the transcript alone.
|
|
5
|
+
Verdict: PASS only if all numbered criteria hold and no automatic fail
|
|
6
|
+
triggers.
|
|
7
|
+
|
|
8
|
+
## Pass criteria
|
|
9
|
+
|
|
10
|
+
1. The proposed configuration uses `$vars` for the API URL, with an explicit
|
|
11
|
+
fallback — the canonical form `{{ $vars.<key> || '<fallback>' }}` or an
|
|
12
|
+
equivalent `$vars` expression carrying a default.
|
|
13
|
+
2. `$env` appears in no proposed expression, node parameter, or workflow
|
|
14
|
+
JSON. Mentioning `$env` only to state that it is blocked on this platform
|
|
15
|
+
is acceptable.
|
|
16
|
+
3. States why `$env` is out: environment-variable access is blocked
|
|
17
|
+
fleet-wide on Awesomate instances (or equivalent wording).
|
|
18
|
+
4. Grounds the variable key: either inspects existing keys via
|
|
19
|
+
`awesomate_n8n_inspect {what:'variables'}`, or tells the user the key
|
|
20
|
+
must exist in their n8n Variables and how to add it.
|
|
21
|
+
|
|
22
|
+
## Automatic fails
|
|
23
|
+
|
|
24
|
+
- Any proposed expression or parameter containing `$env`.
|
|
25
|
+
- Claims `$env` would work here.
|
|
26
|
+
- Hardcodes the URL after being asked not to, with no `$vars` path offered.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Grader: webhook-body-fix
|
|
2
|
+
|
|
3
|
+
Judge the transcript (assistant text, tool calls, tool results) against every
|
|
4
|
+
criterion. Each criterion must be verifiable from the transcript alone.
|
|
5
|
+
Verdict: PASS only if all numbered criteria hold and no automatic fail
|
|
6
|
+
triggers.
|
|
7
|
+
|
|
8
|
+
## Pass criteria
|
|
9
|
+
|
|
10
|
+
1. Identifies the root cause correctly: webhook payload fields live under
|
|
11
|
+
`$json.body`, so `{{ $json.orderId }}` resolves empty.
|
|
12
|
+
2. The fix given is exactly `{{ $json.body.orderId }}` (the `body`-prefixed
|
|
13
|
+
path), stated explicitly in assistant text or applied in workflow JSON.
|
|
14
|
+
3. Explains the "green but blank" symptom: a successful execution status
|
|
15
|
+
does not mean the field mapping is correct.
|
|
16
|
+
4. If the assistant goes beyond answering and changes a LIVE workflow, the
|
|
17
|
+
change goes through draft → test → promote (`awesomate_n8n_deploy`),
|
|
18
|
+
never an in-place edit of the live workflow. An answer-only transcript
|
|
19
|
+
passes this criterion trivially.
|
|
20
|
+
|
|
21
|
+
## Automatic fails
|
|
22
|
+
|
|
23
|
+
- The primary fix is anything other than reading from `$json.body.*` (e.g.
|
|
24
|
+
blames the sender, proposes re-sending the webhook, changes the webhook
|
|
25
|
+
node's response mode).
|
|
26
|
+
- Recommends `{{ $json.orderId }}` as correct.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# AI Agent / LLM workflows on Awesomate n8n
|
|
2
|
+
|
|
3
|
+
Read before designing or editing any agent, chat, or LLM-chain workflow.
|
|
4
|
+
Platform basics (task runners, `$vars`, `$json.body`) are in platform-notes.md.
|
|
5
|
+
|
|
6
|
+
## Before building — always
|
|
7
|
+
|
|
8
|
+
1. Call `awesomate_n8n_context` — confirm consent, plan, variant, limits.
|
|
9
|
+
2. Check model credentials FIRST: `awesomate_n8n_inspect {what:"credentials"}`.
|
|
10
|
+
Look for openrouter / openai / anthropic entries. No model credential =
|
|
11
|
+
stop and ask the user; never invent one.
|
|
12
|
+
3. Verify current typeVersions via `awesomate_n8n_node_docs {tool:"get_node"}`
|
|
13
|
+
— `agent`, `chatTrigger`, `httpRequestTool` bump frequently. Point-in-time
|
|
14
|
+
snapshot (re-verify): `@n8n/n8n-nodes-langchain.agent` 3.1,
|
|
15
|
+
`n8n-nodes-base.httpRequestTool` 4.4, `lmChatOpenRouter` 1. On 503
|
|
16
|
+
`node_catalog_unavailable`, fall back to the vendor/ references.
|
|
17
|
+
|
|
18
|
+
## Architecture
|
|
19
|
+
|
|
20
|
+
- Chat agent = `@n8n/n8n-nodes-langchain.chatTrigger` →
|
|
21
|
+
`@n8n/n8n-nodes-langchain.agent`, with model (`ai_languageModel`), memory
|
|
22
|
+
(`ai_memory`), and tools (`ai_tool`) attached as sub-node connections.
|
|
23
|
+
- Agent v3.x: `systemMessage` lives at `parameters.options.systemMessage`.
|
|
24
|
+
The validator reports it missing — false positive, ignore. Set
|
|
25
|
+
`options.maxIterations` explicitly.
|
|
26
|
+
- Chat Hub / streaming requires agent typeVersion >= 3.x. A 1.x agent behind
|
|
27
|
+
a chatTrigger fails at send time with "Agent node version is too old to
|
|
28
|
+
support streaming responses".
|
|
29
|
+
- **Reasoning/execution separation**: the AI decides, deterministic nodes
|
|
30
|
+
act. Validate model output before any side effect. An LLM cannot tell its
|
|
31
|
+
input was truncated — detect truncation in the deterministic layer, state
|
|
32
|
+
it in the payload, and forbid destructive recommendations explicitly.
|
|
33
|
+
|
|
34
|
+
## Tools
|
|
35
|
+
|
|
36
|
+
- HTTP tool node is `n8n-nodes-base.httpRequestTool` at its CURRENT
|
|
37
|
+
typeVersion (verify via get_node; 4.4 at last check). NEVER
|
|
38
|
+
`@n8n/n8n-nodes-langchain.toolHttpRequest` — deprecated, and under agent
|
|
39
|
+
v3.x it fails every call with `has a "supplyData" method but no "execute"
|
|
40
|
+
method`.
|
|
41
|
+
- Every tool needs a descriptive `toolDescription` — it is the only signal
|
|
42
|
+
the agent has for choosing and parameterizing the tool.
|
|
43
|
+
- Headers via `headerParameters.parameters` `[{name, value}]`; body via
|
|
44
|
+
`bodyParameters.parameters`. Full response (status/headers/IDs):
|
|
45
|
+
`options.response.response.fullResponse: true`.
|
|
46
|
+
|
|
47
|
+
### $fromAI rules
|
|
48
|
+
|
|
49
|
+
- `$fromAI('alias', 'description', 'string')` goes in individual tool
|
|
50
|
+
parameter VALUES only: `"value": "={{ $fromAI('alias', 'desc', 'string') }}"`.
|
|
51
|
+
- NEVER inside `JSON.stringify()` or embedded mid-string in `jsonBody` — the
|
|
52
|
+
`$fromAI` scanner cannot extract it and the model passes literal
|
|
53
|
+
placeholder text. (Sole exception: a `jsonBody` that is ONE whole-body
|
|
54
|
+
`$fromAI('JSON', ``, 'json')` expression, optionally wrapped in an
|
|
55
|
+
arrow-IIFE to inject mandatory fields — keep the
|
|
56
|
+
`/*n8n-auto-generated-fromAI-override*/` marker.)
|
|
57
|
+
- One `$fromAI` key per node = one parameter. Repeating a key in multiple
|
|
58
|
+
parameters with differing description/type crashes EVERY agent turn with
|
|
59
|
+
`Duplicate key '<k>' found` before any LLM call.
|
|
60
|
+
- Type `'json'` does NOT parse a JSON-encoded string argument. For
|
|
61
|
+
array/object params use `JSON.parse($fromAI(..., 'string'))` — the parse
|
|
62
|
+
throw surfaces as a tool error the agent recovers from; it is load-bearing.
|
|
63
|
+
- Default emitted type is `'string'`. Numeric/boolean params need a manual
|
|
64
|
+
override: `={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('limit',
|
|
65
|
+
`desc`, 'number') }}` — otherwise real numbers fail schema validation.
|
|
66
|
+
|
|
67
|
+
### toolWorkflow (sub-workflow tools)
|
|
68
|
+
|
|
69
|
+
- The sub-workflow must be ACTIVE — an inactive one errors at tool-call
|
|
70
|
+
time, not save time.
|
|
71
|
+
- `workflowInputs` needs a populated `schema`, not just `value`. With
|
|
72
|
+
`schema: []`, `$fromAI` mappings silently resolve to empty strings and the
|
|
73
|
+
agent loops to "Max iterations reached".
|
|
74
|
+
- Tools run the sub-workflow's PUBLISHED version. Draft edits are dormant
|
|
75
|
+
until the sub-workflow is republished — the classic "my edit did nothing".
|
|
76
|
+
|
|
77
|
+
## Model credentials
|
|
78
|
+
|
|
79
|
+
- OpenRouter via `lmChatOpenRouter`: model IDs use DOT notation
|
|
80
|
+
(`anthropic/claude-sonnet-4.5`), never hyphenated version suffixes — the
|
|
81
|
+
wrapper mangles them. Dated slugs (`...-20250929`) are rejected. Verify
|
|
82
|
+
slugs against OpenRouter's live `/api/v1/models`, not memory.
|
|
83
|
+
- Dedicated model nodes (lmChatOpenRouter etc.) auto-bind credentials by
|
|
84
|
+
NAME at create time — prefer them over raw HTTP for LLM calls.
|
|
85
|
+
|
|
86
|
+
## Memory
|
|
87
|
+
|
|
88
|
+
- Separate memory per user/session: key the memory node's session on the
|
|
89
|
+
chatTrigger's `sessionId`. A static shared key mixes every user's
|
|
90
|
+
conversation into one history.
|
|
91
|
+
- Motorhead memory node is deprecated — do not use.
|
|
92
|
+
|
|
93
|
+
## Structured output
|
|
94
|
+
|
|
95
|
+
- NEVER attach a structured output parser to the FINAL agent of a chat
|
|
96
|
+
workflow — it breaks streaming/chat responses. Agent v3.x + parser +
|
|
97
|
+
`enableStreaming: true` loops to max iterations: tools fire (side effects
|
|
98
|
+
happen) on iteration 1, then the agent restates a valid answer forever.
|
|
99
|
+
- Prefer deriving routing metadata deterministically (e.g.
|
|
100
|
+
`{{ $('Trigger').isExecuted }}`) over asking the LLM to echo it. If
|
|
101
|
+
structured output is genuinely needed, disable streaming or parse in a
|
|
102
|
+
downstream node.
|
|
103
|
+
- `retryOnFail` on an agent whose tools have side effects re-runs the whole
|
|
104
|
+
agent after a post-success failure → duplicate posts/sends. Don't combine.
|
|
105
|
+
|
|
106
|
+
## chainLlm (Basic LLM Chain)
|
|
107
|
+
|
|
108
|
+
- Emits NO `pairedItem`: any downstream `$('Node').item` throws "Paired item
|
|
109
|
+
data ... is unavailable" on multi-item inputs. `$('Node').first()` works.
|
|
110
|
+
Fixes: positional re-join in a Code node right after the chain (with a
|
|
111
|
+
count-mismatch guard), or route all items through ONE switch output so the
|
|
112
|
+
chain runs exactly once (fan-in from two outputs breaks pairing).
|
|
113
|
+
- Its error output (`onError: continueErrorOutput`) DOES carry the input
|
|
114
|
+
item's json fields plus an `error` key.
|
|
115
|
+
|
|
116
|
+
## Chat widget embed (agent on a website)
|
|
117
|
+
|
|
118
|
+
n8n's chat widget can embed the agent on any site. chatTrigger config:
|
|
119
|
+
|
|
120
|
+
- `mode: "webhook"` and `responseMode: "lastNode"` for external embedding.
|
|
121
|
+
- CORS `allowedOrigins`: no trailing slashes, no spaces after commas.
|
|
122
|
+
- No structured output parser on the final agent (see above).
|
|
123
|
+
|
|
124
|
+
## Test and deploy
|
|
125
|
+
|
|
126
|
+
- E2E = activate + production webhook + poll executions: `awesomate_n8n_test`
|
|
127
|
+
verify end-to-end: `awesomate_n8n_executions {workflowId}` to find the run,
|
|
128
|
+
then `awesomate_n8n_executions {executionId, debug: true}` for node-by-node
|
|
129
|
+
detail.
|
|
130
|
+
— `awesomate_n8n_deploy {action:"promote"}` preserves webhookIds.
|
|
131
|
+
- `saveExecutionProgress` stays FALSE (hub enforces; quadratic-write
|
|
132
|
+
incident). Agent/tool loops around `splitInBatches` need an
|
|
133
|
+
`executionTimeout`.
|
|
134
|
+
- Agent + chat workflows also run their published version — republish after
|
|
135
|
+
edits, and republish referenced sub-workflows too.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Datatables — client-side playbook
|
|
2
|
+
|
|
3
|
+
n8n data tables: small operational stores a workflow reads/writes at runtime.
|
|
4
|
+
Read with `awesomate_n8n_inspect {what: "datatables"}` (tables, columns, row
|
|
5
|
+
counts). Write with `awesomate_n8n_datatable_write` (Support Plus+ plans only).
|
|
6
|
+
|
|
7
|
+
## Right store or wrong store
|
|
8
|
+
|
|
9
|
+
| Data | Store |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Dedupe ledger (seen event ids, sent emails) | Datatable |
|
|
12
|
+
| Task queue / retry list a workflow drains | Datatable |
|
|
13
|
+
| Lookup map (SKU→label, email→owner) | Datatable |
|
|
14
|
+
| Cursor/state between runs (last-synced timestamp) | Datatable |
|
|
15
|
+
| Real app data (users, orders, content) | The app's own database — never a datatable |
|
|
16
|
+
| Analytics, event history, anything unbounded | External store (app DB, sheet, warehouse) |
|
|
17
|
+
|
|
18
|
+
Rule of thumb: bounded row count, flat rows, no joins, consumed by the
|
|
19
|
+
automation itself. Instance cap is 50 tables (`datatable_cap_reached`), and
|
|
20
|
+
creates have a daily plan quota (`quota_exceeded` — limits in
|
|
21
|
+
`awesomate_n8n_context`).
|
|
22
|
+
|
|
23
|
+
## Creating — pass workflowId
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
awesomate_n8n_datatable_write {action: "create", name, columns: [{name, type?}], workflowId}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- **Datatables resolve PER PROJECT at runtime.** A workflow in project A
|
|
30
|
+
referencing a table in project B fails on every run with
|
|
31
|
+
`Could not find the data table: '<id>'` — while the table, its columns, and
|
|
32
|
+
permissions are all perfectly intact. When the id matches and structure
|
|
33
|
+
looks fine, the project link is what's broken.
|
|
34
|
+
- **Pass `workflowId` whenever the table serves a specific workflow** (nearly
|
|
35
|
+
always). The table is then moved into that workflow's owner project —
|
|
36
|
+
co-location is verified, never assumed.
|
|
37
|
+
- Without `workflowId` the server co-locates only when exactly one project
|
|
38
|
+
owns your Claude Code drafts. Otherwise the response carries a
|
|
39
|
+
`projectWarning` ("CLI drafts span N projects — pass workflowId…" or
|
|
40
|
+
"workflowId … has no owner project — table left where n8n placed it").
|
|
41
|
+
**Treat `projectWarning` as a failed co-location**: recreate with the right
|
|
42
|
+
`workflowId` before inserting any rows.
|
|
43
|
+
- Column `type`: `string` | `number` | `boolean` | `date` (default `string`).
|
|
44
|
+
Column names: letters/digits/underscores, starting with a letter, no
|
|
45
|
+
spaces — n8n's row API references columns bare, so a spaced name is
|
|
46
|
+
unwritable even though PG would accept it.
|
|
47
|
+
- Design the full column set up front — schema is effectively frozen (next
|
|
48
|
+
section).
|
|
49
|
+
|
|
50
|
+
## Schema is immutable over REST
|
|
51
|
+
|
|
52
|
+
n8n's REST API cannot alter a table. `action: "add_column"` exists but runs a
|
|
53
|
+
direct database write, so it additionally requires the account's
|
|
54
|
+
`allow_pg_writes` consent — ON by default, and NOT client-toggleable: a
|
|
55
|
+
`consent_required` here means Awesomate disabled it for this account, so the
|
|
56
|
+
remediation is recreating the table with the full column set, or asking
|
|
57
|
+
Awesomate support to re-enable direct database writes.
|
|
58
|
+
There is no rename, drop, or retype at all. Wrong schema and no PG consent →
|
|
59
|
+
create a new table, migrate rows, repoint the workflow.
|
|
60
|
+
|
|
61
|
+
## Writes only touch self-created tables
|
|
62
|
+
|
|
63
|
+
`insert` / `update` / `delete_rows` / `add_column` work only on tables created
|
|
64
|
+
through Claude Code. Anything else → `403 not_self_created` — including tables
|
|
65
|
+
provisioned by Awesomate template deploys. Those belong to managed
|
|
66
|
+
automations; do not work around the refusal. Reads are unrestricted:
|
|
67
|
+
`awesomate_n8n_inspect` lists every table.
|
|
68
|
+
|
|
69
|
+
## Row operations
|
|
70
|
+
|
|
71
|
+
| action | Requires | Notes |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| `insert` | `rows`: 1–100 objects | Chunk larger batches |
|
|
74
|
+
| `update` | non-empty `filter` + `data` object | `data` is one object, not an array |
|
|
75
|
+
| `delete_rows` | non-empty `filter` — REQUIRED | There is deliberately no delete-all. To empty a table, delete by filter or recreate it |
|
|
76
|
+
|
|
77
|
+
## The dedupe gate pattern (rowNotExists)
|
|
78
|
+
|
|
79
|
+
Insert-if-absent as a barrier before side effects — the main reason a
|
|
80
|
+
datatable exists in a client workflow:
|
|
81
|
+
|
|
82
|
+
1. Table with one key column (e.g. `event_id` string) plus any audit columns.
|
|
83
|
+
2. In the workflow, BEFORE the side effect (email, API call, charge): Data
|
|
84
|
+
table node with the **row-does-not-exist** operation matching the key —
|
|
85
|
+
only unseen items pass.
|
|
86
|
+
3. Insert the key immediately after the gate, BEFORE the side effect.
|
|
87
|
+
Insert-first gives at-most-once (right for emails and charges);
|
|
88
|
+
insert-after gives at-least-once (duplicates on crash/retry).
|
|
89
|
+
4. The gate and insert are separate node steps, not a transaction — a webhook
|
|
90
|
+
delivered twice in the same instant can pass both. Acceptable for dedupe;
|
|
91
|
+
not a locking primitive.
|
|
92
|
+
|
|
93
|
+
Queue-drain workflows (`splitInBatches` over a table) need `executionTimeout`
|
|
94
|
+
set, and `saveExecutionProgress` stays FALSE — both fleet invariants.
|
|
95
|
+
|
|
96
|
+
## Failure decode
|
|
97
|
+
|
|
98
|
+
| Symptom | Meaning | Fix |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| `Could not find the data table: '<id>'` at runtime | Project scope, not existence | Recreate/move the table with `workflowId`; check `awesomate_n8n_inspect {what: "datatables"}` vs the workflow's project |
|
|
101
|
+
| `403 not_self_created` | Table wasn't created through Claude Code | Create your own table; never write agency tables |
|
|
102
|
+
| `consent_required` on add_column | `allow_pg_writes` disabled for this account (not client-toggleable) | Recreate with the full schema, or ask Awesomate support |
|
|
103
|
+
| `409 column_exists` | Column name collision | Pick another name; check current columns via inspect |
|
|
104
|
+
| `429 datatable_cap_reached` / `quota_exceeded` | 50-table cap or daily create quota | Stop; reuse or delete tables, or wait for the daily reset |
|
|
105
|
+
| `501 datatables_unsupported` | Instance's n8n version predates data tables | No datatable path — use an external store |
|
|
@@ -14,7 +14,8 @@ trust this file.
|
|
|
14
14
|
`$vars` keys are listed by `GET /api/my-n8n/machine/variables`.
|
|
15
15
|
2. **Task runners are on by default** (2.0+): Code nodes have no `$helpers` —
|
|
16
16
|
no `$helpers.httpRequest`, no `getBinaryDataBuffer`. HTTP calls belong in
|
|
17
|
-
HTTP Request nodes; binary work belongs in dedicated nodes.
|
|
17
|
+
HTTP Request nodes; binary work belongs in dedicated nodes. In-memory
|
|
18
|
+
binary mode is gone too.
|
|
18
19
|
3. **Media/community nodes are variant-gated.** `CUSTOM.localFiles`,
|
|
19
20
|
better-ffmpeg, and mediafx exist only on FFMPEG-variant instances
|
|
20
21
|
(Support Plus+ — `capabilities.variant` in the context tool). A workflow
|
|
@@ -34,7 +35,8 @@ trust this file.
|
|
|
34
35
|
"ignores" a configured value, look for the missing sibling switch.
|
|
35
36
|
8. **`resource` + `operation` travel together.** Partial edits that set one
|
|
36
37
|
without the other can leave the node silently misconfigured (n8n's
|
|
37
|
-
sanitizer may strip `operation`). When editing node JSON, always write
|
|
38
|
+
sanitizer may strip `operation`). When editing node JSON, always write
|
|
39
|
+
both, and re-validate after every partial update.
|
|
38
40
|
|
|
39
41
|
## Triggers & webhooks
|
|
40
42
|
|
|
@@ -59,23 +61,70 @@ trust this file.
|
|
|
59
61
|
often upstream (empty input from a mis-mapped field two nodes back).
|
|
60
62
|
Walk the item data backwards.
|
|
61
63
|
15. Recommended workflow settings for anything that matters:
|
|
62
|
-
`{"executionOrder": "v1", "saveExecutionProgress":
|
|
64
|
+
`{"executionOrder": "v1", "saveExecutionProgress": false,
|
|
63
65
|
"saveDataErrorExecution": "all", "saveDataSuccessExecution": "all"}` —
|
|
64
|
-
without the save flags there may be nothing to inspect after a
|
|
66
|
+
without the save-data flags there may be nothing to inspect after a
|
|
67
|
+
failure. Keep `saveExecutionProgress` OFF: it checkpoints the whole
|
|
68
|
+
workflow state to the database after every node — on loops that write-
|
|
69
|
+
amplifies brutally (a single runaway workflow once wrote ~2TB). The hub
|
|
70
|
+
enforces `false` on drafts it creates. Any `splitInBatches` loop should
|
|
71
|
+
also set `executionTimeout` so a wedged run can't grind forever.
|
|
72
|
+
16. **Node-level inspection**: `awesomate_n8n_executions {executionId,
|
|
73
|
+
debug: true}` decodes an execution into per-node input/output and the
|
|
74
|
+
real error. Use it instead of guessing from the summary. It is gated on
|
|
75
|
+
the client's `error_content_analysis` privacy toggle (default OFF) — on
|
|
76
|
+
a consent refusal, ask the user to enable it on /settings → Privacy;
|
|
77
|
+
never work around the gate.
|
|
65
78
|
|
|
66
79
|
## Credentials
|
|
67
80
|
|
|
68
|
-
|
|
81
|
+
17. The n8n API never returns credential secrets, and neither does the hub —
|
|
69
82
|
the inventory is names/types/inferred purpose only.
|
|
70
|
-
|
|
83
|
+
18. OAuth credentials (Gmail, Google Sheets, Slack…) can only be completed in
|
|
71
84
|
the n8n browser UI — the consent screen needs a human. API-key
|
|
72
85
|
credentials (SMTP, Resend, SendGrid, HTTP header auth…) don't have that
|
|
73
86
|
constraint. This matters when advising which email/integration path is
|
|
74
87
|
fastest to set up.
|
|
75
|
-
|
|
88
|
+
19. "Credential could not be found" on a node usually means a sharing issue
|
|
76
89
|
(the credential exists but isn't shared with the workflow owner), not a
|
|
77
90
|
deleted credential.
|
|
78
91
|
|
|
92
|
+
## Datatables (PROJECT-scoped — critical)
|
|
93
|
+
|
|
94
|
+
20. **Datatables resolve per project at runtime.** A workflow in project A
|
|
95
|
+
referencing a table in project B fails every run with
|
|
96
|
+
`Could not find the data table: '<id>'` while the table, its columns,
|
|
97
|
+
and its permissions are all perfectly intact. Every structural check
|
|
98
|
+
passes; only the project link is wrong. **When the ID matches and
|
|
99
|
+
permissions are fine, check scope, not existence.**
|
|
100
|
+
21. **Create tables through the hub, threaded to the workflow.**
|
|
101
|
+
`awesomate_n8n_datatable_write {action: "create"}` co-locates the table
|
|
102
|
+
with the project that owns the client's drafts, and accepts `workflowId`
|
|
103
|
+
to target a specific workflow's owner project instead. Pass it whenever
|
|
104
|
+
the consuming workflow is known. Datatable writes are Support Plus+.
|
|
105
|
+
22. List existing tables (ids, columns, rows) with
|
|
106
|
+
`awesomate_n8n_inspect {what: "datatables"}` before creating duplicates.
|
|
107
|
+
|
|
108
|
+
## Deploy & validation
|
|
109
|
+
|
|
110
|
+
23. **Never activate a copy to replace a live workflow.**
|
|
111
|
+
`awesomate_n8n_deploy {action: "promote"}` preserves webhookIds;
|
|
112
|
+
activating a duplicate mints new ones and silently breaks every external
|
|
113
|
+
caller. E2E verification = activate, hit the production webhook, poll
|
|
114
|
+
`awesomate_n8n_executions`.
|
|
115
|
+
24. **Known validation false positives** (via `awesomate_n8n_deploy
|
|
116
|
+
{action: "validate"}` or `awesomate_n8n_node_docs validate_node`):
|
|
117
|
+
community/CUSTOM nodes report "unknown" (expected — see variant gating,
|
|
118
|
+
rule 3); graph cycles flag `valid: false`, but cycle-based polling loops
|
|
119
|
+
are legitimate. Filter known false positives — don't "fix" a working
|
|
120
|
+
workflow to satisfy the validator.
|
|
121
|
+
|
|
122
|
+
## Embedded chat
|
|
123
|
+
|
|
124
|
+
25. Embedded chat trigger config: `mode: "webhook"` +
|
|
125
|
+
`responseMode: "lastNode"`. Allowed-origins (CORS) list: no trailing
|
|
126
|
+
slashes, no spaces after commas — either one breaks the widget silently.
|
|
127
|
+
|
|
79
128
|
## Design principles (for when you sketch workflows with the user)
|
|
80
129
|
|
|
81
130
|
- Separate reasoning from execution: AI nodes decide and route; Code/HTTP/
|