Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: new AI tutorial #2799

Closed
wants to merge 48 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
ae43a90
add style for info-based foldout
evilnick Jan 30, 2025
a5c3110
add static image of tutorial workflow
evilnick Jan 30, 2025
e00f1d9
Add outline of tutorial
evilnick Jan 30, 2025
15b0a36
formatting
evilnick Jan 30, 2025
0456d8c
tweaks
evilnick Jan 30, 2025
67a6ba9
text tweaks
evilnick Jan 30, 2025
b3933c8
Changes per comments
evilnick Jan 30, 2025
cf0f7c6
fix headings
evilnick Jan 30, 2025
77b160a
add ai agent step
evilnick Jan 30, 2025
45686bb
additional steps
evilnick Feb 3, 2025
84c54bd
typo on image name
evilnick Feb 3, 2025
5b2b6d2
additional steps
evilnick Feb 6, 2025
962c4d2
Add character limits to Execution Data node (#2789)
imchairmanm Jan 27, 2025
058279b
DOC-1329: Update AWS Secrets Manager docs (#2787)
MarcL Jan 27, 2025
6060c1e
Add keys extension (#2791)
evilnick Jan 28, 2025
71b3c79
Fix node name in common issues section (#2792)
imchairmanm Jan 29, 2025
89ef419
Add DeepSeek and OpenRouter chat nodes and creds (#2790)
imchairmanm Jan 29, 2025
56c3db7
:rocket: Release note 1.77.0 (#2794)
Joffcom Jan 29, 2025
e602b1a
Update latest and next version numbers (#2797)
Joffcom Jan 29, 2025
0065f79
Update structured output parser common issues with advice on working …
imchairmanm Jan 29, 2025
5237116
Keyboard shortcuts (#2775)
evilnick Jan 29, 2025
1d3dfcd
Update keyboard-shortcuts.md for tiny formatting issue
evilnick Jan 29, 2025
48ca05f
Update source control docs with new behavior (#2795)
imchairmanm Jan 31, 2025
99eb86a
Update issue templates (#2802)
evilnick Jan 31, 2025
12bd159
Doc 1323/add a first iteration of a glossary (#2801)
imchairmanm Jan 31, 2025
bdc3d2a
Update cloud IPs (03-02-2025) (#2803)
njibhu Feb 3, 2025
2a4d1e7
:rocket: Release note 1.76.2 (#2805)
Joffcom Feb 3, 2025
e292411
:rocket: Release note 1.77.1 (#2804)
Joffcom Feb 3, 2025
fa8a0c4
Update latest and next version numbers (#2806)
Joffcom Feb 3, 2025
e5ca582
Update nextcloud.md: replace "dav" with "webdav" (#2807)
jtmusson Feb 3, 2025
a8f5a7e
Change name of node from G Suite Admin to Goolge Workspace Admin (#2809)
imchairmanm Feb 4, 2025
2799a4d
add new agent tools to list (#2808)
evilnick Feb 4, 2025
69d4e11
Updated Telegram Trigger node docs with all new supported triggers (#…
olegtsvetkov Feb 4, 2025
4ced0f7
add reference category to integration types
evilnick Feb 4, 2025
73adf9f
:rocket: Release note 1.76.3 (#2810)
Joffcom Feb 4, 2025
98407b6
:rocket: Release note 1.77.2 (#2811)
Joffcom Feb 4, 2025
0e88609
Update latest and next version numbers (#2815)
Joffcom Feb 4, 2025
45b1da1
add content/priority to frontmatter (#2813)
evilnick Feb 5, 2025
877ce20
add pageinfo.py tool (#2816)
evilnick Feb 5, 2025
712842c
Doc 1279 execute workflow (#2817)
evilnick Feb 5, 2025
415ed56
Add information about automatic AI parameters (#2820)
evilnick Feb 5, 2025
8686f95
Sync insiders submodule to latest version (#2818)
imchairmanm Feb 6, 2025
dd5166c
DOC-1281/gemini credentials don't use custom host (#2773)
evilnick Feb 6, 2025
c6d150d
add steps
evilnick Feb 6, 2025
8d7ed2b
text updates
evilnick Feb 6, 2025
1b22301
add tools link
evilnick Feb 6, 2025
9ed98dc
typo
evilnick Feb 6, 2025
954dc82
remove extranneous elipsis
evilnick Feb 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
24 changes: 24 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: Bug report
about: Create a report to help us fix and improve docs
title: "[DOCS-ISSUE] - "
labels: bug
assignees: ''

---

**NOTE!**

This is for issues with _documentation_ of **n8n**. If the problem you are having is actually a bug in the software, please [file a bug here instead](https://github.com/n8n-io/n8n/issues).

**Where is the bug/mistake?**
Please help us by pasting in the URL of the page or telling us the title.

**What problem did you find?**
A clear and concise description of what is wrong.

**Can you suggest a fix?**
For some issues, like a broken link, it will help us resolve them faster if you can indicate what you think the correct information would be.

**Additional context**
Add any other context about the problem here.
19 changes: 19 additions & 0 deletions .github/ISSUE_TEMPLATE/new-docs-request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
name: New docs request
about: Suggest additional pages or information to improve docs
title: "[DOCS-REQUEST] - "
labels: enhancement
assignees: ''

---

Thanks for helping us improve docs! Please give us as much information as you can about the changes you'd like to see.

**What information is missing?**


**Describe the page/pages you'd like**


**Additional context**
Add any other context or screenshots about the feature request here.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ __pycache__/

## Ignore pyenv configuration
.python-version

## Ignore ephemeral doc-tool output

output.csv
_doctools/*.csv
94 changes: 94 additions & 0 deletions _doctools/pageinfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env python3
import os
import yaml
import argparse
import re
import glob
import csv

OUTPUT_CSV = "pageinfo.csv"

def extract_frontmatter_and_content(filepath):
"""Extracts frontmatter and main content from a Markdown file."""
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()

# Match YAML frontmatter with regex (--- as delimiter)
match = re.match(r"^---\n(.*?)\n---\n(.*)", content, re.DOTALL)

if match:
try:
frontmatter = yaml.safe_load(match.group(1)) # Parse YAML
except yaml.YAMLError:
frontmatter = None # Invalid YAML
main_content = match.group(2).strip()
else:
frontmatter = None
main_content = content.strip()

return frontmatter, main_content

def count_words(text):
"""Counts the number of words in the given text."""
# yes, this is fairly simplistic, but a general idea is fine for most uses
return len(text.split())

def find_markdown_files(directory):
"""Recursively finds all markdown files in the given directory."""
return glob.glob(os.path.join(directory, "**", "*.md"), recursive=True)

def save_to_csv(data, filename=OUTPUT_CSV):
"""Saves extracted data to a CSV file with dynamic contentType columns."""
max_types = max((len(row[1]) if isinstance(row[1], list) else 1) for row in data)
headers = ["Filename", "WordCount"] + [f"ContentType_{i+1}" for i in range(max_types)]

with open(filename, "w", newline="", encoding="utf-8") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(headers) # Write CSV header

for filename, content_type, word_count in data:
if isinstance(content_type, list):
row = [filename, word_count] + content_type + [""] * (max_types - len(content_type))
else:
row = [filename, word_count, content_type] + [""] * (max_types - 1)
writer.writerow(row)

def main(directory,print_output):
"""Finds Markdown files, extracts 'contentType' and word count, then prints and saves results."""
md_files = find_markdown_files(directory)
extracted_data = []

for file in md_files:
frontmatter, main_content = extract_frontmatter_and_content(file)
word_count = count_words(main_content)

if frontmatter and "contentType" in frontmatter:
content_type = frontmatter["contentType"]
else:
content_type = ""

# Convert list to comma-separated string for printing
if isinstance(content_type, list):
content_str = ", ".join(content_type)
else:
content_str = str(content_type)

if print_output:
print(f"File: {file}")
print(f"Word Count: {word_count}")
print(f"contentType: {content_str}\n")

extracted_data.append([file, content_type, word_count])

if extracted_data:
save_to_csv(extracted_data)
print(f"Results saved to {OUTPUT_CSV}")

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Extract contentType and word count from Markdown files.")
parser.add_argument("--dir", type=str, default="../docs", help="Directory to scan (default: '../docs')")
parser.add_argument("--print", action="store_true", help="Print output to console (default: False, only CSV)")

args = parser.parse_args()
main(args.dir, args.print)

6 changes: 3 additions & 3 deletions _snippets/flow-logic/subworkflow-data-flow.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
As an example, imagine you have an Execute Workflow node in **Workflow A**. The Execute Workflow node calls another workflow called **Workflow B**:
As an example, imagine you have an Execute Sub-workflow node in **Workflow A**. The Execute Sub-workflow node calls another workflow called **Workflow B**:

1. The Execute Workflow node passes the data to the Execute Workflow Trigger node of **Workflow B**.
2. The last node of **Workflow B** sends the data back to the Execute Workflow node in **Workflow A**.
1. The Execute Sub-workflow node passes the data to the Execute Sub-workflow Trigger node (titled "When executed by another node" in the canvas) of **Workflow B**.
2. The last node of **Workflow B** sends the data back to the Execute Sub-workflow node in **Workflow A**.
12 changes: 6 additions & 6 deletions _snippets/flow-logic/subworkflow-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
1. Create a new workflow.

/// note | Create sub-workflows from existing workflows
You can optionally create a sub-workflow directly from an existing parent workflow using the [Execute Workflow](/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflow/) node. In the node, select the **Database** and **From list** options and select **Create a sub-workflow** in the list.
You can optionally create a sub-workflow directly from an existing parent workflow using the [Execute Sub-workflow](/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflow/) node. In the node, select the **Database** and **From list** options and select **Create a sub-workflow** in the list.
///

1. **Optional**: configure which workflows can call the sub-workflow:
1. Select the **Options** <span class="inline-image">![Options menu](/_images/common-icons/three-dot-options-menu.png){.off-glb}</span> menu > **Settings**. n8n opens the **Workflow settings** modal.
1. Change the **This workflow can be called by** setting. Refer to [Workflow settings](/workflows/settings/) for more information on configuring your workflows.
1. Add the **Execute Workflow Trigger** node.
1. Add the **Execute Sub-workflow** trigger node (if you are searching under trigger nodes, this is also titled **When Executed by Another Workflow**).
1. Set the **Input data mode** to choose how you will define the sub-workflow's input data:
* **Define using fields below**: Choose this mode to define individual input names and data types that the calling workflow needs to provide.
* **Define using JSON example**: Choose this mode to provide an example JSON object that demonstrates the expected input items and their types.
Expand All @@ -26,7 +26,7 @@ This requires the ability to [load data from previous executions](/workflows/exe

If you want to load data into your sub-workflow to use while building it:

1. Create the sub-workflow and add the **Execute Workflow Trigger**.
1. Create the sub-workflow and add the **Execute Sub-workflow Trigger**.
1. Set the node's **Input data mode** to **Accept all data** or define the input items using fields or JSON if they're already known.
1. In the sub-workflow [settings](/workflows/settings/), set **Save successful production executions** to **Save**.
1. Skip ahead to setting up the parent workflow, and run it.
Expand All @@ -40,8 +40,8 @@ You can now pin example data in the trigger node, enabling you to work with real
### Call the sub-workflow

1. Open the workflow where you want to call the sub-workflow.
1. Add the **Execute Workflow** node.
1. In the **Execute Workflow** node, set the sub-workflow you want to call. You can choose to call the workflow by ID, load a workflow from a local file, add workflow JSON as a parameter in the node, or target a workflow by URL.
1. Add the **Execute Sub-workflow** node.
1. In the **Execute Sub-workflow** node, set the sub-workflow you want to call. You can choose to call the workflow by ID, load a workflow from a local file, add workflow JSON as a parameter in the node, or target a workflow by URL.

/// note | Find your workflow ID
Your sub-workflow's ID is the alphanumeric string at the end of its URL.
Expand All @@ -52,4 +52,4 @@ You can now pin example data in the trigger node, enabling you to work with real

When your workflow executes, it will send data to the sub-workflow, and run it.

You can follow the execution flow from the parent workflow to the sub-workflow by opening the Execute Workflow node and selecting the **View sub-execution** link. Likewise, the sub-workflow's execution contains a link back to the parent workflow's execution to navigate in the other direction.
You can follow the execution flow from the parent workflow to the sub-workflow by opening the Execute Sub-workflow node and selecting the **View sub-execution** link. Likewise, the sub-workflow's execution contains a link back to the parent workflow's execution to navigate in the other direction.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ Set values to pass to the workflow you're calling.
These values appear in the output data of the trigger node in the workflow you call. You can access these values in expressions in the workflow. For example, if you have:

* **Workflow Values** with a **Name** of `myCustomValue`
* A workflow with an Execute Workflow Trigger node as its trigger
* A workflow with an Execute Sub-workflow Trigger node as its trigger

The expression to access the value of `myCustomValue` is `{{ $('Execute Workflow Trigger').item.json.myCustomValue }}`.
The expression to access the value of `myCustomValue` is `{{ $('Execute Sub-workflow Trigger').item.json.myCustomValue }}`.
7 changes: 7 additions & 0 deletions _snippets/integrations/builtin/core-nodes/code-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ n8n provides built-in methods and variables for working with data and accessing

The syntax to use the built-in methods and variables is `$variableName` or `$methodName()`. Type `$` in the Code node or expressions editor to see a list of suggested methods and variables.

### Keyboard shortcuts

The Code node editing environment supports time-saving and useful keyboard shortcuts for a range of operations from autocompletion to code-folding and using multiple-cursors. A full list can be found in the [list of keyboard shortcuts](/integrations/builtin/core-nodes/n8n-nodes-base.code/keyboard-shortcuts).

## Python

Expand All @@ -66,6 +69,10 @@ n8n provides built-in methods and variables for working with data and accessing

The syntax to use the built-in methods and variables is `_variableName` or `_methodName()`. Type `_` in the Code node to see a list of suggested methods and variables.

### Keyboard shortcuts

The Code node editing environment supports time-saving and useful keyboard shortcuts for a range of operations from autocompletion to code-folding and using multiple-cursors. A full list can be found in the [list of keyboard shortcuts](/integrations/builtin/core-nodes/n8n-nodes-base.code/keyboard-shortcuts).

## File system and HTTP requests

You can't access the file system or make HTTP requests. Use the following nodes instead:
Expand Down
4 changes: 2 additions & 2 deletions _snippets/self-hosting/installation/latest-next-version.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// note | Latest and Next versions
n8n releases a new minor version most weeks. The `latest` version is for production use. `next` is the most recent release. You should treat `next` as a beta: it may be unstable. To report issues, use the [forum](https://community.n8n.io/c/questions/12){:target=_blank .external-link}.

Current `latest`: 1.75.2
Current `next`: 1.76.1
Current `latest`: 1.76.3
Current `next`: 1.77.2
///
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/// info | Feature availability
* Available on Enterprise.
* You need access to the n8n instance owner account or an admin account to set up source control, and to send work to and from Git.
* You need to be an n8n instance owner, admin, or project owner to set up source control, and to send work to and from Git.
///
4 changes: 2 additions & 2 deletions _snippets/source-control-environments/push.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ To push work to Git:

1. Select **Push** <span class="inline-image">![Push icon](/_images/source-control-environments/push-icon.png){.off-glb}</span> in the main menu.

--8<-- "_snippets/source-control/push-pull-menu-state.md"
--8<-- "_snippets/source-control-environments/push-pull-menu-state.md"

1. In the **Commit and push changes** modal, select which workflows you want to push. n8n automatically pushes tags, and variable and credential stubs.
1. In the **Commit and push changes** modal, select which workflows you want to push. You can filter by status (new, modified, deleted) and search for workflows. n8n automatically pushes tags, and variable and credential stubs.
1. Enter a commit message. This should be a one sentence description of the changes you're making.
1. Select **Commit and Push**. n8n sends the work to Git, and displays a success message on completion.
2 changes: 1 addition & 1 deletion _submodules/insiders
4 changes: 3 additions & 1 deletion docs-site-feature-tests/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Other images like this should expand on click:

## Links

[This link should open in a new tab](https://example.com/){:target=_blank .external-link}
[This link should open in a new tab](https://example.com/)

[This link should open in the same tab](/try-it-out/quickstart/)

Expand Down Expand Up @@ -74,3 +74,5 @@ You should see a list of 5 HTTP Request templates
You should see the AI Glossary below

--8<-- "_glossary/ai-glossary.md"

Link to [workflows](/glossary/#workflow-n8n){ data-preview } glossary definition with preview.
14 changes: 14 additions & 0 deletions docs/_extra/css/extra.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@
}


.md-typeset .admonition.explanation,
.md-typeset details.explanation {
border-color: var(--color-primary);
}
.md-typeset .explanation > .admonition-title,
.md-typeset .explanation > summary {
background-color: var(--color-background-light);
}
.md-typeset .explanation > .admonition-title::before,
.md-typeset .explanation > summary::before {
background-color: rgb(43, 155, 70);
-webkit-mask-image: var(--md-admonition-icon--info);
mask-image: var(--md-admonition-icon--info);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This adds a further style for an 'info' themed expandable section, similar to the existing 'details' one. The styling is taken from the default for material, but we can debate appropriate colours etc.

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it. Yeah, I think changes to the styling are fine. I think if we're going with green, it'd be good to try to riff off of the green we already use for the theme. That being said, with the website style changes coming, it might not matter all too much.



/* light mode */
Expand Down
Binary file added docs/_images/advanced-ai/ai-intro01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_images/advanced-ai/ai-stars.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions docs/_workflows/advanced-ai/tutorials/chat_01.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "AI tutorial",
"nodes": [
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"typeVersion": 1.1,
"position": [
-200,
-40
],
"id": "a2d42e1f-36df-4a6a-a3b4-99a162074d11",
"name": "When chat message received",
"webhookId": "97c1a41f-8ef0-4d63-a924-92eb634384d3"
}
],
"pinData": {},
"connections": {},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "b1641385-c6b0-48a8-8e26-20d1f6bd7fda",
"meta": {
"instanceId": "cb484ba7b742928a2048bf8829668bed5b5ad9787579adea888f05980292a4a7"
},
"id": "l05TkWXXYbOiuL4o",
"tags": []
}
56 changes: 56 additions & 0 deletions docs/_workflows/advanced-ai/tutorials/chat_02.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "AI tutorial",
"nodes": [
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"typeVersion": 1.1,
"position": [
-300,
-40
],
"id": "a2d42e1f-36df-4a6a-a3b4-99a162074d11",
"name": "When chat message received",
"webhookId": "97c1a41f-8ef0-4d63-a924-92eb634384d3"
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.7,
"position": [
-80,
-40
],
"id": "0f61a10f-668f-42f7-b835-cf3efb60082a",
"name": "AI Agent"
}
],
"pinData": {},
"connections": {
"When chat message received": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "b1641385-c6b0-48a8-8e26-20d1f6bd7fda",
"meta": {
"instanceId": "cb484ba7b742928a2048bf8829668bed5b5ad9787579adea888f05980292a4a7"
},
"id": "l05TkWXXYbOiuL4o",
"tags": []
}
Loading
Loading