AI Agents Masterclass #8 - n8n AI Agent

This commit is contained in:
Cole Medin
2024-08-18 13:16:12 -05:00
parent 1497547ff4
commit 3be0c4348b
5 changed files with 398 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
# Rename this file to .env once you have filled in the below environment variables!
# The URL of your webhook to start the N8N workflow (get this from the first node (Webhook) of the workflow)
WEBHOOK_URL=
# This is the Auth password for the webhook in N8N that you set up when creating the webhook
# Also make sure the name of your Header Auth in N8N is "Authorization" or you will get a 403 error!
WEBHOOK_AUTH=

View File

@@ -0,0 +1,83 @@
from dotenv import load_dotenv
import streamlit as st
import requests
import uuid
import json
import os
from langchain_core.messages import AIMessage, HumanMessage
"""
This Python script is an example of how to use Streamlit with
an n8n AI Agent as a webhook (API endpoint). This code pretty much just
defines a Streamlit UI that interacts with the n8n AI Agent for
each user message and displays the AI response from n8n back to the
UI just like other AI Agents in this masterclass. All chat history
and tool calling is managed within the n8n workflow.
"""
load_dotenv()
webhook_url = os.getenv('WEBHOOK_URL')
webhook_auth = os.getenv('WEBHOOK_AUTH')
@st.cache_resource
def get_session_id():
return str(uuid.uuid4())
session_id = get_session_id()
def prompt_ai(user_input):
payload = {
"chatInput": user_input,
"sessionId": session_id
}
headers = {
"Authorization": f"Bearer {webhook_auth}",
"Content-Type": "application/json"
}
response = requests.post(webhook_url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~ Main Function with UI Creation ~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def main():
st.title("N8N Asana Chatbot")
# Initialize chat history
if "messages" not in st.session_state:
st.session_state.messages = []
# Display chat messages from history on app rerun
for message in st.session_state.messages:
message_json = json.loads(message.json())
message_type = message_json["type"]
if message_type in ["human", "ai", "system"]:
with st.chat_message(message_type):
st.markdown(message_json["content"])
# React to user input
if prompt := st.chat_input("What would you like to do today?"):
# Display user message in chat message container
st.chat_message("user").markdown(prompt)
# Add user message to chat history
st.session_state.messages.append(HumanMessage(content=prompt))
# Display assistant response in chat message container
with st.chat_message("assistant"):
response = prompt_ai(prompt)
st.markdown(response["output"])
st.session_state.messages.append(AIMessage(content=response["output"]))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,234 @@
{
"name": "Asana AI Agent",
"nodes": [
{
"parameters": {
"model": "gpt-4o-mini",
"options": {}
},
"id": "555cd8d7-331e-43dd-8dae-cfe225c04f89",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1,
"position": [
1260,
580
],
"credentials": {
"openAiApi": {
"id": "JJjD91oisPv9cs01",
"name": "OpenAi account"
}
}
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "={{ $('When chat message received').item.json.sessionId }}"
},
"id": "1c63f69f-bc07-4a3c-b832-59c5bb575a48",
"name": "Window Buffer Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.2,
"position": [
1380,
600
]
},
{
"parameters": {
"options": {}
},
"id": "76db7743-f5ae-410d-8eff-73a465b57fa9",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
1860,
360
]
},
{
"parameters": {
"name": "Asana",
"description": "Call this tool to create a task in Asana. Give two parameters - the name of the task and the day it is due in the format YYYY-MM-DD",
"workflowId": "nCnW5wOp1qjTpOvp",
"responsePropertyName": "permalink_url",
"fields": {
"values": [
{}
]
},
"specifyInputSchema": true,
"jsonSchemaExample": "{\n\t\"name\": \"Study for Test\",\n \"due_date\": \"2024-07-13\"\n}"
},
"id": "f0dbf665-1a80-4ea8-ae51-7c0f421a7a56",
"name": "Call n8n Workflow Tool",
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"typeVersion": 1.1,
"position": [
1560,
580
]
},
{
"parameters": {
"options": {}
},
"id": "d9019c17-0180-4dbe-8e85-60474aaafe93",
"name": "Date & Time",
"type": "n8n-nodes-base.dateTime",
"typeVersion": 2,
"position": [
1000,
360
]
},
{
"parameters": {
"httpMethod": "POST",
"path": "asana_chatbot",
"authentication": "headerAuth",
"responseMode": "responseNode",
"options": {}
},
"id": "0a1664a4-4ade-4f2c-9692-cbcd343aae17",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
640,
180
],
"webhookId": "59003970-6f1f-4dfe-b7ea-1ef8e1c7a5d1",
"credentials": {
"httpHeaderAuth": {
"id": "FWbnHWdNKFyEHa1W",
"name": "Header Auth account"
}
}
},
{
"parameters": {
"promptType": "define",
"text": "={{ $('When chat message received').item.json.chatInput }}",
"options": {
"systemMessage": "=You are a helpful assistant who helps create tasks in Asana. The current date is {{ $json.currentDate }}"
}
},
"id": "3822b0eb-cd1b-419c-b12e-97f98ef0f604",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.6,
"position": [
1260,
360
]
},
{
"parameters": {
"options": {}
},
"id": "27ede384-f66c-4ad5-9659-e5851c43e626",
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"typeVersion": 1.1,
"position": [
640,
360
],
"webhookId": "aaf606e6-c311-472c-88ec-6267dd5255e2"
}
],
"pinData": {},
"connections": {
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Window Buffer Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Call n8n Workflow Tool": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Date & Time": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "Date & Time",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "Date & Time",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "ffbc203b-f652-43b2-84fb-4f899a0d977c",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "620f0d7e3114cb344761d7d45a21ef2a32096f91d8696e7057756042e1999e2c"
},
"id": "HF7kvnDcr2SUOYaE",
"tags": []
}

View File

@@ -0,0 +1,68 @@
{
"name": "Create Asana Task",
"nodes": [
{
"parameters": {},
"id": "f7d7e146-3f88-4701-87ab-1aa09df7a83d",
"name": "Execute Workflow Trigger",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"typeVersion": 1,
"position": [
820,
360
]
},
{
"parameters": {
"workspace": "1207638003439377",
"name": "={{ $json.query.name }}",
"otherProperties": {
"due_on": "={{ $json.query.due_date }}T00:00:00",
"projects": [
"1207790694984047"
]
}
},
"id": "163fab0b-947d-4b62-b17f-b6a420a10104",
"name": "Asana",
"type": "n8n-nodes-base.asana",
"typeVersion": 1,
"position": [
1040,
360
],
"alwaysOutputData": false,
"credentials": {
"asanaApi": {
"id": "3SVncDjuaKuQ7AQo",
"name": "Asana account"
}
}
}
],
"pinData": {},
"connections": {
"Execute Workflow Trigger": {
"main": [
[
{
"node": "Asana",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "2295c979-5624-47bf-89d6-5d784e3c9a6e",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "620f0d7e3114cb344761d7d45a21ef2a32096f91d8696e7057756042e1999e2c"
},
"id": "nCnW5wOp1qjTpOvp",
"tags": []
}

View File

@@ -0,0 +1,5 @@
python-dotenv==0.13.0
langchain==0.2.6
langchain-core==0.2.10
streamlit==1.36.0
requests==2.32.3