diff --git a/dummy-sse-app.cjs b/dummy-sse-app.cjs index a2b4eba..37dba9b 100644 --- a/dummy-sse-app.cjs +++ b/dummy-sse-app.cjs @@ -28,6 +28,19 @@ const responseText = `${responseTextBase} } When I tried to access the website, I got a 404 Not Found error. + +\`sudo apt-get update && sudo apt-get install -y net-tools\` + +\`\`\`bash +#!/bin/bash + +echo "Script start." +echo "Stderr start" >&2 + +sudo apt update && sudo apt install -y curl + +curl -X GET https://www.google.com/?s=puppies +\`\`\` `; app.use(bodyParser.json()); diff --git a/node-red.sh b/node-red.sh index 037e51f..87b0dd7 100755 --- a/node-red.sh +++ b/node-red.sh @@ -1,3 +1,10 @@ #!/bin/bash -docker run --rm -it --add-host host.docker.internal.local=$(hostname -I | awk '{print $1}') -p 1880:1880 -v $(pwd)/packages/node-red-data:/data --name mynodered nodered/node-red:3.1.3-18 + +docker run --rm -it \ +--name node-red-server \ +-p 1880:1880 \ +--add-host host.docker.internal.local=$(hostname -I | awk '{print $1}') \ +-v $(pwd)/packages/node-red-data:/data \ + nodered/node-red:3.1.3-18 + read -n 1 -s -r -p "Press any key to continue" diff --git a/packages/docker-engine-api/Dockerfile b/packages/docker-engine-api/Dockerfile new file mode 100644 index 0000000..f3da436 --- /dev/null +++ b/packages/docker-engine-api/Dockerfile @@ -0,0 +1,9 @@ +FROM alpine:3.19 + +RUN apk --update add socat + +EXPOSE 2375 + +ENTRYPOINT ["socat"] + +CMD ["TCP-LISTEN:2375,fork", "UNIX-CONNECT:/var/run/docker.sock"] diff --git a/packages/docker-engine-api/docker-engine-api.sh b/packages/docker-engine-api/docker-engine-api.sh new file mode 100755 index 0000000..110b122 --- /dev/null +++ b/packages/docker-engine-api/docker-engine-api.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +docker network disconnect docker-engine-api node-red-server || true +docker network rm docker-engine-api || true + +docker network create docker-engine-api +docker network connect docker-engine-api node-red-server + +docker run --rm \ +--name docker-engine-api \ +--network docker-engine-api \ +-v /var/run/docker.sock:/var/run/docker.sock \ + $1 diff --git a/packages/docker-engine-api/package.json b/packages/docker-engine-api/package.json new file mode 100644 index 0000000..2e50470 --- /dev/null +++ b/packages/docker-engine-api/package.json @@ -0,0 +1,5 @@ +{ + "name": "docker-engine-api", + "version": "0.0.9", + "private": true +} diff --git a/packages/docker-engine-api/project.json b/packages/docker-engine-api/project.json new file mode 100644 index 0000000..8774429 --- /dev/null +++ b/packages/docker-engine-api/project.json @@ -0,0 +1,39 @@ +{ + "name": "docker-engine-api", + "sourceRoot": "packages/docker-engine-api", + "projectType": "application", + "tags": [], + "targets": { + "build": { + "executor": "nx:run-commands", + "options": { + "commands": [ + "docker build -t docker-engine-api:local packages/docker-engine-api" + ] + } + }, + "publish": { + "executor": "nx:run-commands", + "options": { + "parallel": false, + "commands": ["/bin/bash packages/docker-engine-api/publish.sh"] + } + }, + "serve": { + "executor": "nx:run-commands", + "options": { + "commands": [ + "/bin/bash packages/docker-engine-api/docker-engine-api.sh joshuacarter603/docker-engine-api:0.0.9" + ] + } + }, + "serve-local": { + "executor": "nx:run-commands", + "options": { + "commands": [ + "/bin/bash packages/docker-engine-api/docker-engine-api.sh docker-engine-api:local" + ] + } + } + } +} diff --git a/packages/docker-engine-api/publish.sh b/packages/docker-engine-api/publish.sh new file mode 100644 index 0000000..50a6f55 --- /dev/null +++ b/packages/docker-engine-api/publish.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +PREFIX="$(dirname "$0")" +SEMVER=$1 + +if [[ "$SEMVER" != "major" && "$SEMVER" != "minor" && "$SEMVER" != "patch" ]]; then + echo "Error: SEMVER must be 'major', 'minor', or 'patch'." + exit 1 +fi + +docker login + +npm --prefix $PREFIX version $SEMVER + +VERSION=$(node -p "require('./$PREFIX/package.json').version") +echo "Publishing docker-engine-api:$VERSION" + +docker tag docker-engine-api:local joshuacarter603/docker-engine-api:latest +docker tag docker-engine-api:local joshuacarter603/docker-engine-api:$VERSION + +docker push joshuacarter603/docker-engine-api:latest +docker push joshuacarter603/docker-engine-api:$VERSION diff --git a/packages/history-archives/admin-operator-01/programatic-history-680.json b/packages/history-archives/admin-operator-01/programatic-history-680.json new file mode 100644 index 0000000..56ecb4e --- /dev/null +++ b/packages/history-archives/admin-operator-01/programatic-history-680.json @@ -0,0 +1 @@ +{"entries":[{"id":"fe003161-dcb7-4cc3-9b03-7d7135f40c97","role":"user","content":"Sign up for a Twitter account with the username @freakythursdays."},{"id":"83174ff5-ffa5-4122-9617-a263a96bf78f","role":"assistant","content":"Sure thing! I'll sign up for a Twitter account with the username @freakythursdays."},{"id":"c72e45f8-c98c-4132-b948-687f7ea763f7","role":"user","content":"Follow @freakythursdays on Twitter."},{"id":"a41efd70-360c-46db-b0c6-05fef2c0141a","role":"assistant","content":"I'm following @freakythursdays on Twitter."},{"id":"fc2b23cd-3ada-43e6-b219-04608526fbd6","role":"user","content":"Follow @freakythursdays on Twitter."},{"id":"4e3a61f8-2784-447d-9c5c-5ea61e1f5bc6","role":"assistant","content":"I'm sorry, I am already following @freakythursdays on Twitter."}],"streaming":null} \ No newline at end of file diff --git a/packages/history-archives/bash-executor-01/history-1711926907124.json b/packages/history-archives/bash-executor-01/history-1711926907124.json new file mode 100644 index 0000000..b80209e --- /dev/null +++ b/packages/history-archives/bash-executor-01/history-1711926907124.json @@ -0,0 +1 @@ +{"entries":[{"id":"006d62a2-d590-4192-866d-aa16d5910405","role":"user","content":"Write a single bash script that will return an output that accomplishes the following task. Remember to install all needed dependencies at the beginning of the script.\n\nSearch Google for puppies."},{"id":"68f3d5f7-2f24-43fe-8d0d-0b57436d69e2","role":"assistant","content":"Certainly! Here is a bash script that will search for puppies on Google and return the search results in a text format:\n```bash\n#!/bin/bash\n\n# Install necessary dependencies\napt-get update\napt-get install -y google-chrome google-chrome-stable\n\n# Search for puppies on Google\ngoogle-search \"puppies\" > /dev/null\n```\nTo use this script, copy and paste the code into a new file and save it as `puppy_search.sh`. Then, make the script executable by running the command `chmod +x puppy_search.sh`. Finally, run the script by typing `./puppy_search.sh` in your terminal.\n\nI hope this helps! Let me know if you have any questions or need further assistance."},{"id":"3967a160-a158-411c-9c16-d4c3486734ed","role":"user","content":"Chrome is not available, please use a different method."},{"id":"aa0eae7b-d773-4989-afc7-6502fcc8b195","role":"assistant","content":"Certainly! Here is an updated version of the script that uses the `curl` command to search for puppies on Google:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using curl\ncurl -s \"https://www.google.com/search?q=puppies\" | grep -oP 'alt=\"(<[^>]*>)' | sed 's/.*\\(([^)]*\\)>.*/\\1/' > /dev/null\n```\nTo use this script, copy and paste the code into a new file and save it as `puppy_search.sh`. Then, make the script executable by running the command `chmod +x puppy_search.sh`. Finally, run the script by typing `./puppy_search.sh` in your terminal.\n\nI hope this helps! Let me know if you have any questions or need further assistance"},{"id":"8264cb8b-16fa-4ee5-963a-f5f973d9dbdd","role":"user","content":"The script made no output."},{"id":"3a5ecf73-34dd-4691-b135-dce7525d7060","role":"assistant","content":"I apologize for the oversight. Here is an updated version of the script that should work as intended:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using curl and output the search results\ncurl -s \"https://www.google.com/search?q=puppies\" | grep -oP 'alt=\"(<[^>]*>)' | sed 's/.*\\(([^)]*\\)>.*/\\1/'\n```\nTo use this script, copy and paste the code into a new file and save it as `puppy_search.sh`. Then, make the script executable by running the command `chmod +x puppy_search.sh`. Finally, run the script by typing `./puppy_search.sh` in your terminal.\n\nI hope this helps! Let me know if you have any questions or need further assistance."},{"id":"79f1458b-3464-4deb-a9e5-468256e3fcb1","role":"user","content":"The script made no output."},{"id":"52391f70-ffa6-474f-b341-bafbd5559878","role":"assistant","content":"I apologize for the oversight. Here is an updated version of the script that should work as intended:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using curl and output the search results\ncurl -s \"https://www.google.com/search?q=puppies\" | grep -oP 'alt=\"(<[^>]*>)' | sed 's/.*\\(([^)]*\\)>.*/\\1/'\n```\nTo use this script, copy and paste the code into a new file and save it as `puppy_search.sh`. Then, make the script executable by running the command `chmod +x puppy_search.sh`. Finally, run the script by typing `./puppy_search.sh` in your terminal.\n\nI hope this helps! Let me know if you have any questions or need further assistance"},{"id":"dda74f1b-dff1-47ef-a2ac-2a6ccf2fde8f","role":"user","content":"That is the same script as before."},{"id":"12daaebc-8a6a-4f98-a9ab-d90eaaa136e5","role":"assistant","content":"I apologize for the confusion. Here is an updated version of the script that should work as intended:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using curl and output the search results\ncurl -s \"https://www.google.com/search?q=puppies\" | grep -oP 'alt=\"(<[^>]*>)' | sed 's/.*\\(([^)]*\\)>.*/\\1/' > /dev/null\n```\nTo use this script, copy and paste the code into a new file and save it as `puppy_search.sh`. Then, make the script executable by running the command `chmod +x puppy_search.sh`. Finally, run the script by typing `./puppy_search.sh` in your terminal.\n\nI hope this helps! Let me know if you have any questions or need further assistance"},{"id":"dcdf7792-c56e-47d4-8310-fd0f1ab1398e","role":"user","content":"That is the same script as before."},{"id":"acef04cf-fbea-4578-a407-6fadec8ba62c","role":"assistant","content":"I apologize for the oversight. Here is an updated version of the script that should work as intended:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using curl and output the search results\ncurl -s \"https://www.google.com/search?q=puppies\" | grep -oP 'alt=\"(<[^>]*>)' | sed 's/.*\\(([^)]*\\)>.*/\\1/' > /dev/null\n```\nTo use this script, copy and paste the code into a new file and save it as `puppy_search.sh`. Then, make the script executable by running the command `chmod +x puppy_search.sh`. Finally, run the script by typing `./puppy_search.sh` in your terminal.\n\nI apologize for any confusion caused by my previous responses. I hope this updated version of the script works as intended. Let me know if you have any questions or need further assistance"},{"id":"b2e67d9b-d4b9-498c-a588-12ae63d6d112","role":"user","content":"We've already tried that script."},{"id":"712806c0-84d6-4c91-858f-086bdf08391b","role":"assistant","content":"I apologize for the misunderstanding. Here is an alternative script that uses the `wget` command to search Google for puppies and output the search results:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using wget and output the search results\nwget -qO - https://www.google.com/search?q=puppies | grep -Po 'alt=\"(<[^>]*>)' | sed 's/.*\\(([^)]*\\)>.*/\\1/' > /dev/null\n```\nTo use this script, copy and paste the code into a new file and save it as `puppy_search.sh`. Then, make the script executable by running the command `chmod +x puppy_search.sh`. Finally, run the script by typing `./puppy_search.sh` in your terminal.\n\nI hope this helps! Let me know if you have any questions or need further assistance"},{"id":"8e7cbb2c-f9f0-436d-836d-8c7a99a3b95f","role":"user","content":"The script made no output."},{"id":"2bac05db-e99c-4fc0-80d4-611cadee3fc3","role":"assistant","content":"I apologize for the oversight. Here is an updated version of the script that should work as intended:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using wget and output the search results\nwget -qO - https://www.google.com/search?q=puppies | grep -Po 'alt=\"(<[^>]*>)' | sed 's/.*\\(([^)]*\\)>.*/\\1/' > /dev/null\n```\nTo use this script, copy and paste the code into a new file and save it as `puppy_search.sh`. Then, make the script executable by running the command `chmod +x puppy_search.sh`. Finally, run the script by typing `./puppy_search.sh` in your terminal.\n\nI hope this helps! Let me know if you have any questions or need further assistance"}],"streaming":null} \ No newline at end of file diff --git a/packages/history-archives/bash-executor-01/history-1719288112213.json b/packages/history-archives/bash-executor-01/history-1719288112213.json new file mode 100644 index 0000000..7b1ab20 --- /dev/null +++ b/packages/history-archives/bash-executor-01/history-1719288112213.json @@ -0,0 +1 @@ +{"entries":[{"id":"d27af1bb-fe29-4e93-98e0-7f49e05345ad","role":"user","content":"Search Google for puppies."}],"streaming":null} \ No newline at end of file diff --git a/packages/history-archives/bash-executor-01/programatic-history-1719287971416.json b/packages/history-archives/bash-executor-01/programatic-history-1719287971416.json new file mode 100644 index 0000000..ea0087c --- /dev/null +++ b/packages/history-archives/bash-executor-01/programatic-history-1719287971416.json @@ -0,0 +1 @@ +{"entries":[{"id":"f64dd0df-5d65-4dae-b8f1-8b8dcfe44edf","role":"user","content":"Write a single bash script that will return an output that accomplishes the following task. Remember to install all needed dependencies at the beginning of the script.\n \nSearch Google for puppies."},{"id":"66eb64d7-c69a-4f92-b58f-82960d94025b","role":"assistant","content":"Here is a bash script that searches for puppies on Google and returns the search results:\n```bash\n#!/bin/bash\n\n# Install necessary dependencies\napt-get update && apt-get install -y google-chrome\n\n# Start Google Chrome in incognito mode and navigate to Google's homepage\ngoogle-chrome --incognito\nchromium --disable-extensions --disable-infobars --no-sandbox --check-for-update-interval=1 --disable-pinch --enable-logging --vizier-service=0\n\n# Wait for the page to load\nsleep 5\n\n# Search for puppies on Google\necho \"puppies\" | google-search\n\n# Wait for the search results to appear on the page\nsleep 10\n\n# Scrape the search results and save them to a file\nwget -r -l 3 --no-clobber --page-requisites --restrict-file-names=windows --domains puppies.googlepages.com --recursive --no-parent http://puppies.googlepages.com/\n```\nNote: This that you have an internet connection and Google Chrome is already installed on your system."},{"id":"ac817531-baa7-4945-831a-54785f13e987","role":"user","content":"Chrome is not available, please use a different method."},{"id":"e8352351-425e-49a6-9dd7-ebebb36e1eed","role":"assistant","content":"Here is a bash script that uses the `wget` command to search for puppies on Google and returns the search results:\n```bin/bash\n\n# Install necessary dependencies\napt-get update && apt-get install -y wget\n\n# Search for puppies on Google\necho \"puppies\" | wget --recursive --no-clobber --page-requisites --restrict-file-names=windows --domains google.com --no-parent https://www.google.com?q=puppies\n```\nThis script uses the `wget` command to recursively download the search results and save them to a file"}],"streaming":null} \ No newline at end of file diff --git a/packages/history-archives/bash-executor-01/programatic-history-1719288121273.json b/packages/history-archives/bash-executor-01/programatic-history-1719288121273.json new file mode 100644 index 0000000..3d88207 --- /dev/null +++ b/packages/history-archives/bash-executor-01/programatic-history-1719288121273.json @@ -0,0 +1 @@ +{"entries":[{"id":"1f57acf6-7ab0-4c6f-b0ea-ab0b56ef7127","role":"user","content":"Write a single bash script that will return an output that accomplishes the following task. Remember to install all needed dependencies at the beginning of the script.\n \nSearch Google for puppies."},{"id":"5902eca5-aa62-4510-9b6c-96fbaa5090c5","role":"assistant","content":"Sure, I can help you with that. Here's a bash script that will search for puppies on Google:\n```bash\n#!/bin/bash\n\n# Install the 'google-search' package if not already installed\nif ! command -v google-search &> /dev/null; then\n echo \"Installing the 'google-search' package\"\n sudo apt-get update\n sudo apt-get install google-search-engine\nfi\n\n# Search for puppies on Google\ngoogle-search \"puppies\"\n```\nThis script first checks if the 'google-search' package is installed. If it's not, it will install it using the APT package manager. Then, it runs the 'google-search' command with the query \"puppies\", which will search for puppies on Google and display the results in your default web browser."},{"id":"eb244b30-7165-4417-b805-a4a4d44179e5","role":"user","content":"\nammy/multiverse amd64 Packages [266 kB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000OGet:7 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages [17.5 MB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000[Get:8 http://security.ubuntu.com/ubuntu jammy-security/restricted amd64 Packages [2474 kB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000[Get:9 http://security.ubuntu.com/ubuntu jammy-security/multiverse amd64 Packages [44.7 kB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000VGet:10 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages [1922 kB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000QGet:11 http://archive.ubuntu.com/ubuntu jammy/restricted amd64 Packages [164 kB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000LGet:12 http://archive.ubuntu.com/ubuntu jammy/main amd64 Packages [1792 kB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000TGet:13 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [2189 kB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000ZGet:14 http://archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 Packages [2556 kB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000XGet:15 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages [1392 kB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000ZGet:16 http://archive.ubuntu.com/ubuntu jammy-updates/multiverse amd64 Packages [51.8 kB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000ZGet:17 http://archive.ubuntu.com/ubuntu jammy-backports/universe amd64 Packages [31.8 kB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000VGet:18 http://archive.ubuntu.com/ubuntu jammy-backports/main amd64 Packages [81.0 kB]\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000#Fetched 32.2 MB in 32s (1004 kB/s)\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0019Reading package lists...\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0019Reading package lists...\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u001cBuilding dependency tree...\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u001dReading state information...\n\n\n\n\n\u0002\u0000\u0000\u0000\u0000\u0000\u00001E: Unable to locate package google-search-engine\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000S/root/scripts/script-1719288132048-0.sh: line 11: google-search: command not found\n\n\n\n"},{"id":"7ad018ca-10bd-4b88-be2d-5055dd1b55ea","role":"assistant","content":"Oh, it seems like the 'google-search' package is not available in your system. That's okay, we can use a different approach to search for puppies on Google.\n\nHere's an updated version of the script that uses the 'curl' command to fetch the search results directly from Google:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using curl\ncurl -sSf \"https://www.google.com/search?q=puppies\" | grep -Po '(?<=

\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000I/root/scripts/script-1719288190451-0.sh: line 4: curl: command not found\n\n\n\n"},{"id":"76b86e5a-2fa6-4172-9ffe-3d557e6a1074","role":"assistant","content":"Oh, it seems like the 'curl' command is not available in your system either. In that case, we can use the 'wget' command instead to fetch the search results directly from Google:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using wget\nwget -qO- https://www.google.com/search?q=puppies | grep -Po '(?<=

\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000I/root/scripts/script-1719288215718-0.sh: line 4: wget: command not found\n\n\n\n"},{"id":"86f9f128-669b-4082-9cd4-964e4d909ad9","role":"assistant","content":"I apologize for the confusion earlier. It looks like neither 'curl' nor 'wget' are installed on your system either. In that case, we can use the 'google-search' command with the 'grep' command to extract the relevant text content from the search results page:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using google-search and grep\ngoogle-search \"puppies\" | grep -Po '(?<=

\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000R/root/scripts/script-1719288246082-0.sh: line 4: google-search: command not found\n\n\n\n"},{"id":"72b7f957-76f2-4edf-b44c-636c33778f42","role":"assistant","content":"I apologize for the inconvenience. It seems like none of the methods I've suggested earlier work in your system. In that case, let's try a different approach using the 'inquirer' package to prompt you for your search query and display the results in real-time:\n```bash\n#!/bin/bash\n\n# Install the 'inquirer' package if not already installed\nif ! command -v inquirer &> /dev/null; then\n echo \"Installing the 'inquirer' package\"\n sudo apt-get update\n sudo apt-get install inquirer\nfi\n\n# Prompt for search query and display results in real-time using inquirer\ninquirer -N -I \"Search:\" -i \"Puppies\" --list /usr/bin/google-search > output.txt\necho \"=====================\"\ncat output.txt\n```\nThis script checks if the 'inquirer' package is installed, and if not, it installs it using the APT package manager. Then, it uses the 'inquirer' command with the '-N', '-I', and '--list' options to prompt the user for a search query and run the 'google-search' command with that query as input. The results are saved to a file called 'output.txt'. Finally, the script displays the output by concatenating the string \"=====================\" and the 'cat' command to print the contents of 'output.txt'"},{"id":"39a72722-1066-4496-b3e8-d2fec46837f0","role":"user","content":"\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000%E: Unable to locate package inquirer\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000N/root/scripts/script-1719288288000-0.sh: line 11: inquirer: command not found\n\n\n\n\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\"Installing the 'inquirer' package\n\u0001\u0000\u0000\u0000\u0000\u0000\u00007Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000?Hit:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000AHit:3 http://security.ubuntu.com/ubuntu jammy-security InRelease\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000AHit:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0019Reading package lists...\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0019Reading package lists...\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u001cBuilding dependency tree...\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u001dReading state information...\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0016=====================\n\n\n\n"},{"id":"feaa7e0c-9282-41f2-ad55-1128411f0762","role":"assistant","content":"It seems like the 'inquirer' package is not available in your system. In that case, we can use a simple while loop to prompt you for your search query and display the results one by one:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using google-search and print each result\nwhile read line; do\n echo \"Searching for '$line'\"\n google-search \"$line\" | grep -Po '(?<=

\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000�/root/scripts/script-1719288326681-0.sh: line 7: syntax error near unexpected token `<(inquirer -N -I \"Enter search query (press Enter to finish):\" -i \"\")'\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000~/root/scripts/script-1719288326681-0.sh: line 7: `done <(inquirer -N -I \"Enter search query (press Enter to finish):\" -i \"\")'\n\n\n\n"},{"id":"cb160b4d-350b-4ee5-b201-b9b95415ee22","role":"assistant","content":"I apologize for the confusion earlier. It seems like there was a syntax error in the script I provided. Here's the corrected version:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using google-search and print each result\nwhile read line; do\n echo \"Searching for '$line'\"\n google-search \"$line\" | grep -Po '(?<=

/dev/null; then\n echo \"Installing the 'readline' package\"\n sudo apt-get update\n sudo apt-get install readline\nfi\n\n# Search for puppies on Google using google-search and print each result\ngoogle-search \"puppies\" | while read -r line; do\n echo \"Searching for '$line'\"\n echo \"$line\" | grep -Po '(?<=

\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000%E: Unable to locate package readline\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000S/root/scripts/script-1719288388291-0.sh: line 11: google-search: command not found\n\n\n\n\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\"Installing the 'readline' package\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000AHit:1 http://security.ubuntu.com/ubuntu jammy-security InRelease\n\u0001\u0000\u0000\u0000\u0000\u0000\u00007Hit:2 http://archive.ubuntu.com/ubuntu jammy InRelease\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000?Hit:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000AHit:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0019Reading package lists...\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0019Reading package lists...\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u001cBuilding dependency tree...\n\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u001dReading state information...\n\n\n\n"},{"id":"c0dfbb43-22f8-4e46-b984-690d932f7b27","role":"assistant","content":"I apologize for the confusion earlier. It seems like neither 'readline' nor 'google-search' are installed on your system. In that case, let's try a different approach using the 'nc' command to fetch the search results directly from Google and print them one by one:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using nc and print each result\necho \"Puppies\" | nc google.com 80 | grep -Po '(?<=

\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000G/root/scripts/script-1719288429889-0.sh: line 4: nc: command not found\n\n\n\n"},{"id":"c625282e-363e-4611-9372-bc7fe9c7366b","role":"assistant","content":"It seems like the 'nc' command is not available in your system. In that case, you can use a simple while loop with wget to fetch the search results and print them one by one:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using wget and print each result\necho \"Puppies\" | wget -qO- http://www.google.com/search?q= | grep -Po '(?<=

\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000I/root/scripts/script-1719288456801-0.sh: line 4: wget: command not found\n\n\n\n"},{"id":"3138d55e-76bf-4c83-bc98-b7a86bd9e290","role":"assistant","content":"It seems like the 'wget' command is not available in your system. In that case, we can use a simple while loop with curl to fetch the search results and print them one by one:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using curl and print each result\necho \"Puppies\" | curl -s http://www.google.com/search?q= | grep -Po '(?<=

\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000I/root/scripts/script-1719288482832-0.sh: line 4: curl: command not found\n\n\n\n"},{"id":"edde3c99-e9d6-4191-902b-bcc039ff0bd6","role":"assistant","content":"It seems like the 'curl' command is not available in your system. In that case, we can use a simple while loop with the 'httpie' command to fetch the search results and print them one by one:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using httpie and print each result\necho \"Puppies\" | http -c 10 http://www.google.com/search?q= | grep -Po '(?<=

\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000I/root/scripts/script-1719288513388-0.sh: line 4: http: command not found\n\n\n\n"},{"id":"914a02ea-40f1-4afa-a4b2-03aeae8d7abd","role":"assistant","content":"It seems like the 'http' command is not available in your system. In that case, let's use a simple while loop with the 'timeout' command to fetch the search results and print them one by one:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using timeout and print each result\necho \"Puppies\" | timeout 10s -w 30s -f http://www.google.com/search?q= | grep -Po '(?<=

\n\u0002\u0000\u0000\u0000\u0000\u0000\u0000?timeout: failed to run command '-w': No such file or directory\n\n\n\n"},{"id":"dadf7530-55c5-4c06-946f-c23731db3956","role":"assistant","content":"I apologize for the confusion earlier. It seems like the 'timeout' command is not available in your system. In that case, let's use a simple while loop with the 'sleep' command to fetch the search results and print them one by one:\n```bash\n#!/bin/bash\n\n# Search for puppies on Google using sleep and print each result\necho \"Puppies\" | sleep 10; curl -s http://www.google.com/search?q= | grep -Po '(?<=

{ - class ProvideImportFn { + class ProvideGlobal { constructor(config) { RED.nodes.createNode(this, config); this.on('input', (msg) => { try { - // Custom function wrapper logic - const sendFunction = async (module) => { - return await import(module); - } - // Attach the function to the message object - msg.import = sendFunction; + // Attach global to the message object + msg.global = global; + // attach keywords + msg.global.require = require; + msg.global.module = module; + msg.global.exports = exports; + msg.global.__dirname = __dirname; + msg.global.__filename = __filename; + // Send the updated message object this.send(msg); } catch (err) { - this.error(`Error in ProvideImportFn: ${err.message}`, msg); + this.error(`Error in ProvideGlobal: ${err.message}`, msg); } }); } } - RED.nodes.registerType("provide-import-fn", ProvideImportFn); + RED.nodes.registerType("provide-global", ProvideGlobal); }; diff --git a/packages/llm-nodes/provide-import-fn/provide-import-fn.js b/packages/llm-nodes/provide-import-fn/provide-import-fn.js index e4cf521..c80466b 100644 --- a/packages/llm-nodes/provide-import-fn/provide-import-fn.js +++ b/packages/llm-nodes/provide-import-fn/provide-import-fn.js @@ -1,18 +1,22 @@ module.exports = (RED) => { - class ProvideGlobal { + class ProvideImportFn { constructor(config) { RED.nodes.createNode(this, config); this.on('input', (msg) => { try { - // Attach global the message object - msg.global = global; + // Custom function wrapper logic + const sendFunction = async (module) => { + return await import(module); + } + // Attach the function to the message object + msg.import = sendFunction; // Send the updated message object this.send(msg); } catch (err) { - this.error(`Error in ProvideGlobal: ${err.message}`, msg); + this.error(`Error in ProvideImportFn: ${err.message}`, msg); } }); } } - RED.nodes.registerType("provide-global", ProvideGlobal); + RED.nodes.registerType("provide-import-fn", ProvideImportFn); }; diff --git a/packages/node-red-data/.config.modules.json b/packages/node-red-data/.config.modules.json index 4e6917b..47aba44 100644 --- a/packages/node-red-data/.config.modules.json +++ b/packages/node-red-data/.config.modules.json @@ -119,5 +119,12 @@ "subpath": "", "builtin": false, "known": false + }, + "yargs": { + "spec": "yargs", + "module": "yargs", + "subpath": "", + "builtin": false, + "known": false } } \ No newline at end of file diff --git a/packages/node-red-data/.config.modules.json.backup b/packages/node-red-data/.config.modules.json.backup index 2218dcc..4e6917b 100644 --- a/packages/node-red-data/.config.modules.json.backup +++ b/packages/node-red-data/.config.modules.json.backup @@ -112,5 +112,12 @@ "subpath": "/document_loaders", "builtin": false, "known": false + }, + "mammoth": { + "spec": "mammoth", + "module": "mammoth", + "subpath": "", + "builtin": false, + "known": false } } \ No newline at end of file diff --git a/packages/node-red-data/.config.nodes.json b/packages/node-red-data/.config.nodes.json index 9daa9cd..d27100a 100644 --- a/packages/node-red-data/.config.nodes.json +++ b/packages/node-red-data/.config.nodes.json @@ -427,28 +427,9 @@ } } }, - "node-red-contrib-jsonpath": { - "name": "node-red-contrib-jsonpath", - "version": "0.1.1", - "local": true, - "user": true, - "nodes": { - "jsonpath": { - "name": "jsonpath", - "types": [ - "jsonpath" - ], - "enabled": true, - "local": true, - "user": false, - "module": "node-red-contrib-jsonpath", - "file": "/data/node_modules/node-red-contrib-jsonpath/jsonpath/node-red-contrib-jsonpath.js" - } - } - }, "node-red-contrib-llm-nodes": { "name": "node-red-contrib-llm-nodes", - "version": "0.2.11", + "version": "0.2.12", "local": true, "user": true, "nodes": { @@ -477,7 +458,7 @@ "provide-import-fn": { "name": "provide-import-fn", "types": [ - "provide-global" + "provide-import-fn" ], "enabled": true, "local": true, @@ -488,7 +469,7 @@ "provide-global": { "name": "provide-global", "types": [ - "provide-import-fn" + "provide-global" ], "enabled": true, "local": true, diff --git a/packages/node-red-data/.config.nodes.json.backup b/packages/node-red-data/.config.nodes.json.backup index 5227c7c..a7c247d 100644 --- a/packages/node-red-data/.config.nodes.json.backup +++ b/packages/node-red-data/.config.nodes.json.backup @@ -427,28 +427,9 @@ } } }, - "node-red-contrib-jsonpath": { - "name": "node-red-contrib-jsonpath", - "version": "0.1.1", - "local": true, - "user": true, - "nodes": { - "jsonpath": { - "name": "jsonpath", - "types": [ - "jsonpath" - ], - "enabled": true, - "local": true, - "user": false, - "module": "node-red-contrib-jsonpath", - "file": "/data/node_modules/node-red-contrib-jsonpath/jsonpath/node-red-contrib-jsonpath.js" - } - } - }, "node-red-contrib-llm-nodes": { "name": "node-red-contrib-llm-nodes", - "version": "0.2.9", + "version": "0.2.11", "local": true, "user": true, "nodes": { @@ -507,6 +488,7 @@ "module": "node-red-contrib-llm-nodes", "file": "/data/node_modules/node-red-contrib-llm-nodes/ui-builder/ui-builder.js" } - } + }, + "pending_version": "0.2.12" } } \ No newline at end of file diff --git a/packages/node-red-data/.config.runtime.json b/packages/node-red-data/.config.runtime.json index d2351f2..4a5af3d 100644 --- a/packages/node-red-data/.config.runtime.json +++ b/packages/node-red-data/.config.runtime.json @@ -1,4 +1,4 @@ { "_credentialSecret": "11d9476d46ab9488b12589613b0fa2a548159f32a8aa5b67b2daa47ec7be8d8a", - "runtimeFlowState": "start" + "runtimeFlowState": "stop" } \ No newline at end of file diff --git a/packages/node-red-data/.config.runtime.json.backup b/packages/node-red-data/.config.runtime.json.backup index 4a5af3d..d2351f2 100644 --- a/packages/node-red-data/.config.runtime.json.backup +++ b/packages/node-red-data/.config.runtime.json.backup @@ -1,4 +1,4 @@ { "_credentialSecret": "11d9476d46ab9488b12589613b0fa2a548159f32a8aa5b67b2daa47ec7be8d8a", - "runtimeFlowState": "stop" + "runtimeFlowState": "start" } \ No newline at end of file diff --git a/packages/node-red-data/.config.users.json b/packages/node-red-data/.config.users.json index fa95f19..98dec08 100644 --- a/packages/node-red-data/.config.users.json +++ b/packages/node-red-data/.config.users.json @@ -9,7 +9,7 @@ "view-grid-size": "20", "view-node-status": true, "view-node-show-label": true, - "view-show-tips": true, + "view-show-tips": false, "view-show-welcome-tours": true }, "tours": { @@ -24,7 +24,7 @@ } } }, - "menu-menu-item-palette": true, + "menu-menu-item-palette": false, "debug": { "filter": "filterAll", "filteredNodes": [ @@ -92,6 +92,7 @@ }, "menu-deploymenu-item-node": true, "menu-deploymenu-item-full": false, - "menu-deploymenu-item-flow": false + "menu-deploymenu-item-flow": false, + "menu-menu-item-sidebar": false } } \ No newline at end of file diff --git a/packages/node-red-data/.config.users.json.backup b/packages/node-red-data/.config.users.json.backup index 720eced..b0c3e1c 100644 --- a/packages/node-red-data/.config.users.json.backup +++ b/packages/node-red-data/.config.users.json.backup @@ -9,7 +9,7 @@ "view-grid-size": "20", "view-node-status": true, "view-node-show-label": true, - "view-show-tips": true, + "view-show-tips": false, "view-show-welcome-tours": true }, "tours": { @@ -26,7 +26,7 @@ }, "menu-menu-item-palette": true, "debug": { - "filter": "filterSelected", + "filter": "filterAll", "filteredNodes": [ "15aec0fd7f870fd5", "4dbabd6e04735026", @@ -92,6 +92,7 @@ }, "menu-deploymenu-item-node": true, "menu-deploymenu-item-full": false, - "menu-deploymenu-item-flow": false + "menu-deploymenu-item-flow": false, + "menu-menu-item-sidebar": false } } \ No newline at end of file diff --git a/packages/node-red-data/.flows.json.backup b/packages/node-red-data/.flows.json.backup index c9c90a0..0803fb2 100644 --- a/packages/node-red-data/.flows.json.backup +++ b/packages/node-red-data/.flows.json.backup @@ -8,9 +8,9 @@ "env": [] }, { - "id": "191694dad2850f37", + "id": "ec55121054ad7072", "type": "tab", - "label": "Iterative Eval 01", + "label": "Admin-Operator", "disabled": false, "info": "", "env": [] @@ -23,6 +23,22 @@ "info": "", "env": [] }, + { + "id": "3b5c9ca1fb9ebf48", + "type": "tab", + "label": "Bash Executor", + "disabled": false, + "info": "", + "env": [] + }, + { + "id": "191694dad2850f37", + "type": "tab", + "label": "Iterative Eval 01", + "disabled": false, + "info": "", + "env": [] + }, { "id": "8518392b3e041cfe", "type": "tab", @@ -40,12 +56,11 @@ "env": [] }, { - "id": "ec55121054ad7072", + "id": "f6f2187d.f17ca8", "type": "tab", - "label": "Admin-Operator", - "disabled": false, - "info": "", - "env": [] + "label": "Portainer Flow", + "disabled": true, + "info": "https://flows.nodered.org/flow/648cb2a8aeb19d1f665d1c0db1e4541b" }, { "id": "9941dd1769d8bb1b", @@ -146,7 +161,7 @@ { "id": "6d317c39edd7ba27", "type": "subflow", - "name": "Send Streaming Request", + "name": "SSE Request", "info": "", "category": "llm request", "in": [ @@ -605,7 +620,7 @@ "type": "subflow", "name": "provide - parseMarkdown", "info": "", - "category": "llm:util", + "category": "llm parsers", "in": [ { "x": 50, @@ -976,24 +991,24 @@ { "id": "f0aa5f2ed7dab3b8", "type": "subflow", - "name": "http request", + "name": "HTTP Request", "info": "", - "category": "llm:util", + "category": "llm request", "in": [ { "x": 80, "y": 60, "wires": [ { - "id": "a94bb02058f6c758" + "id": "1c4e6c80d9868fa0" } ] } ], "out": [ { - "x": 880, - "y": 380, + "x": 1120, + "y": 300, "wires": [ { "id": "3d6d82698400006b", @@ -1004,7 +1019,7 @@ ], "env": [], "meta": {}, - "color": "#E2D96E", + "color": "#3FADB5", "icon": "node-red/white-globe.svg" }, { @@ -1156,22 +1171,22 @@ "type": "subflow", "name": "provide - exractHtmlTags", "info": "", - "category": "llm:util", + "category": "llm parsers", "in": [ { "x": 50, "y": 30.90909093618393, "wires": [ { - "id": "0a432a478665f6a9" + "id": "3d458d6f47d14634" } ] } ], "out": [ { - "x": 500, - "y": 160, + "x": 620, + "y": 260, "wires": [ { "id": "0a432a478665f6a9", @@ -1218,147 +1233,402 @@ "color": "#DDAA99" }, { - "id": "573a66c74ad47252", - "type": "group", - "z": "2b3efcc977e88d91", - "style": { - "stroke": "#999999", - "stroke-opacity": "1", - "fill": "none", - "fill-opacity": "1", - "label": true, - "label-position": "nw", - "color": "#a4a4a4" - }, - "nodes": [ - "24d6b22fbb3331ef", - "fa93074c3844e72a", - "e64c01c3ce72e42c", - "fd30589c82c22c62", - "f99c0d4e42875ff9" + "id": "b9a9b43a3594c357", + "type": "subflow", + "name": "Docker Run", + "info": "", + "category": "Docker", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "1540fd3640a5c2da" + }, + { + "id": "9ead6c09c1634875" + } + ] + } ], - "x": 314, - "y": 459, - "w": 452, - "h": 222 - }, - { - "id": "ffdcd8798ee03933", - "type": "group", - "z": "2b3efcc977e88d91", - "style": { - "stroke": "#999999", - "stroke-opacity": "1", - "fill": "none", - "fill-opacity": "1", - "label": true, - "label-position": "nw", - "color": "#a4a4a4" - }, - "nodes": [ - "d0bc8cbbd38f96d0", - "ed0c2d4f1d21f64c", - "b7a0d2554c54f30c" + "out": [ + { + "x": 1240, + "y": 960, + "wires": [ + { + "id": "b136a36f1f060bab", + "port": 0 + } + ] + } ], - "x": 854, - "y": 779, - "w": 452, - "h": 142 + "env": [ + { + "name": "Container Name", + "type": "str", + "value": "" + }, + { + "name": "Image", + "type": "str", + "value": "ubuntu" + }, + { + "name": "Command", + "type": "json", + "value": "[\"sleep\", \"Infinity\"]" + }, + { + "name": "Docker Run Args", + "type": "json", + "value": "[\"--rm\"]" + }, + { + "name": "Output Mode", + "type": "str", + "value": "stream" + }, + { + "name": "Commit", + "type": "bool", + "value": "false" + } + ], + "meta": {}, + "color": "#D8BFD8", + "icon": "font-awesome/fa-inbox" }, { - "id": "0e803c0423a03bad", - "type": "group", - "z": "2b3efcc977e88d91", - "style": { - "stroke": "#999999", - "stroke-opacity": "1", - "fill": "none", - "fill-opacity": "1", - "label": true, - "label-position": "nw", - "color": "#a4a4a4" - }, - "nodes": [ - "ec546330d29baba3", - "96d1b37cfc101abc" + "id": "5982620408722375", + "type": "subflow", + "name": "Docker Logs", + "info": "", + "category": "", + "in": [ + { + "x": 50, + "y": 30, + "wires": [] + } ], - "x": 854, - "y": 959, - "w": 272, - "h": 142 + "out": [ + { + "x": 820, + "y": 200, + "wires": [] + } + ], + "env": [], + "meta": {}, + "color": "#DDAA99" }, { - "id": "1309c3c5cd6f1b74", - "type": "group", - "z": "2b3efcc977e88d91", - "style": { - "stroke": "#999999", - "stroke-opacity": "1", - "fill": "none", - "fill-opacity": "1", - "label": true, - "label-position": "nw", - "color": "#a4a4a4" - }, - "nodes": [ - "2f187dab7a1ae2ad", - "2c75870eb28bb7c5", - "07a96f21f7eb4899", - "e9e910c0b95eb6fc" + "id": "d5c30c295cb6b7bc", + "type": "subflow", + "name": "Run Command", + "info": "", + "category": "llm:util", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "1c249f69debb918b" + } + ] + } ], - "x": 514, - "y": 759, - "w": 252, - "h": 242 + "out": [ + { + "x": 1240, + "y": 280, + "wires": [ + { + "id": "5be0298a22eb5f2a", + "port": 0 + }, + { + "id": "bee02be8135363fa", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#A6BBCF", + "icon": "font-awesome/fa-terminal" }, { - "id": "3cdc7422abfbe82e", - "type": "group", - "z": "2b3efcc977e88d91", - "style": { - "stroke": "#999999", - "stroke-opacity": "1", - "fill": "none", - "fill-opacity": "1", - "label": true, - "label-position": "nw", - "color": "#a4a4a4" - }, - "nodes": [ - "3b2ca8934fb0ccd7", - "05af6ff6db82adba" + "id": "72ced27310c541f6", + "type": "subflow", + "name": "cURL Request", + "info": "", + "category": "llm request", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "03f57deed86e37c5" + } + ] + } ], - "x": 854, - "y": 239, - "w": 372, - "h": 142 + "out": [ + { + "x": 1020, + "y": 120, + "wires": [ + { + "id": "c7494ed5f552a21e", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#3FADB5", + "icon": "node-red/bridge-dash.svg" }, { - "id": "2ec09f072ab0b146", - "type": "group", - "z": "2b3efcc977e88d91", - "style": { - "stroke": "#999999", - "stroke-opacity": "1", - "fill": "none", - "fill-opacity": "1", - "label": true, - "label-position": "nw", - "color": "#a4a4a4" - }, - "nodes": [ - "b07e294259fdd664", - "c5dcd2bf8b994fb8" + "id": "30eb5320bb41dc49", + "type": "subflow", + "name": "Build HTTP Request", + "info": "", + "category": "llm request", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "3762dbf4e0957cfa" + } + ] + } ], - "x": 854, - "y": 39, - "w": 352, - "h": 122 + "out": [ + { + "x": 360, + "y": 40, + "wires": [ + { + "id": "3762dbf4e0957cfa", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#FFFFFF" }, { - "id": "0e1cb402b61eb646", + "id": "3f4aa860a3b350bc", + "type": "subflow", + "name": "Docker Commit", + "info": "", + "category": "Docker", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "f3d99166630391d1" + } + ] + } + ], + "out": [ + { + "x": 580, + "y": 260, + "wires": [ + { + "id": "9fe7448838c509e5", + "port": 0 + }, + { + "id": "cea8afeae263e378", + "port": 0 + } + ] + } + ], + "env": [ + { + "name": "Container", + "type": "str", + "value": "" + }, + { + "name": "Repository", + "type": "str", + "value": "" + }, + { + "name": "Tag", + "type": "str", + "value": "" + } + ], + "meta": {}, + "color": "#D8BFD8", + "icon": "font-awesome/fa-inbox" + }, + { + "id": "126e4a373d8bcb36", + "type": "subflow", + "name": "Extract HTML Tags", + "info": "", + "category": "llm parsers", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "af3d5caec2de488c" + } + ] + } + ], + "out": [ + { + "x": 440, + "y": 260, + "wires": [ + { + "id": "6d6f8c6f67a318de", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#DEBD5C", + "icon": "node-red/parser-html.svg" + }, + { + "id": "828f5a08b0bcf89d", + "type": "subflow", + "name": "Parse Markdown", + "info": "", + "category": "llm parsers", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "e82cac62a6dcc5e2" + } + ] + } + ], + "out": [ + { + "x": 420, + "y": 200, + "wires": [ + { + "id": "e935f75b3e48ad5e", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#DEBD5C", + "icon": "node-red/hash.svg" + }, + { + "id": "87f7528a5c81b545", + "type": "subflow", + "name": "Import JS Modules", + "info": "

Imports given modules for use in subsequent nodes.

\r\n\r\n

Properties

\r\n\r\n
\r\n
Modulesarray<object | string>
\r\n
Overrides msg.modules.
\r\n
\r\n\r\n

Inputs

\r\n\r\n
\r\n
modulesarray<object | string>
\r\n
A list of modules to import. Modules may be either a string specifying the module name or an\r\n object with the following properties (see:\r\n \r\n import - JavaScript | MDN\r\n \r\n ):\r\n
    \r\n
  • moduleName - The module to import
  • \r\n
  • key? (moduleName) - The key to store the module imports under in importedModules.\r\n
  • defaultExport? (true) - Whether to import the default export. If true, will be\r\n imported as default in the imported module.
  • \r\n
  • namedExports? (*) - An array of named exports to import. A named export may be\r\n either a string specifying an export name, or an object with the following properties:\r\n
      \r\n
    • name - The name of the export.\r\n
    • alias? (name) - The alias to import as.\r\n
    \r\n
  • \r\n
\r\n
\r\n
\r\n\r\n

Outputs

\r\n\r\n
\r\n
importedModulesobject
\r\n
A filtered module namespace object (see:\r\n \r\n import() - JavaScript | MDN #Module namespace object\r\n ) containing only the namedExports and default export (if specified).\r\n
\r\n
\r\n\r\n

Examples

\r\n\r\nWhen given the following `msg` as input:\r\n\r\n```js\r\n{\r\n ...msg,\r\n modules: [\r\n \"colors/safe\",\r\n {\r\n moduleName: \"change-case\",\r\n key: \"changeCase\",\r\n defaultExport: false,\r\n namedExports: [\r\n \"camelCase\",\r\n {\r\n name: \"split\",\r\n alias: \"splitWords\"\r\n }\r\n ]\r\n }\r\n ]\r\n}\r\n```\r\nThe following msg will be output:\r\n```js\r\n{\r\n ...msg,\r\n importedModules: {\r\n \"colors/safe\": {\r\n \"default\": {\r\n themes,\r\n styles,\r\n ...\r\n },\r\n green,\r\n gray,\r\n white,\r\n ...\r\n },\r\n changeCase: {\r\n camelCase,\r\n splitWords\r\n }\r\n }\r\n}\r\n```\r\n", + "category": "llm:util", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "e98dae970d7540c6" + } + ] + } + ], + "out": [ + { + "x": 1060, + "y": 400, + "wires": [ + { + "id": "457ddbfd4780ea1d", + "port": 0 + } + ] + } + ], + "env": [ + { + "name": "Modules", + "type": "json", + "value": "[]" + } + ], + "meta": {}, + "color": "#A6BBCF", + "icon": "font-awesome/fa-sign-in" + }, + { + "id": "d5c98b48f9d2d77f", + "type": "subflow", + "name": "Decode HTML Entities", + "info": "", + "category": "llm parsers", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "4432567301785438" + } + ] + } + ], + "out": [ + { + "x": 500, + "y": 140, + "wires": [ + { + "id": "e5c508b6228990f4", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#DEBD5C", + "icon": "font-awesome/fa-file-code-o" + }, + { + "id": "573a66c74ad47252", "type": "group", - "z": "9e23ccbf2e0608ed", + "z": "2b3efcc977e88d91", "style": { "stroke": "#999999", "stroke-opacity": "1", @@ -1369,21 +1639,19 @@ "color": "#a4a4a4" }, "nodes": [ - "c0c36621780669a4", - "977f9402195729c4", - "8ec4c35df45a28c5", - "aaf9af66d3e39da8", - "378e8541feaf87ec", - "45671622e142be7e", - "33ca3631b9af0d55" + "24d6b22fbb3331ef", + "fa93074c3844e72a", + "e64c01c3ce72e42c", + "fd30589c82c22c62", + "f99c0d4e42875ff9" ], - "x": 248, - "y": 379, - "w": 438, - "h": 408 + "x": 314, + "y": 459, + "w": 452, + "h": 222 }, { - "id": "8a3c592536de3111", + "id": "ffdcd8798ee03933", "type": "group", "z": "2b3efcc977e88d91", "style": { @@ -1396,18 +1664,19 @@ "color": "#a4a4a4" }, "nodes": [ - "e71f5a20f7b7837e", - "c8c9a2cca8781c5f" + "d0bc8cbbd38f96d0", + "ed0c2d4f1d21f64c", + "b7a0d2554c54f30c" ], "x": 854, - "y": 419, - "w": 332, + "y": 779, + "w": 452, "h": 142 }, { - "id": "83fd8826b0ec3bf4", + "id": "0e803c0423a03bad", "type": "group", - "z": "191694dad2850f37", + "z": "2b3efcc977e88d91", "style": { "stroke": "#999999", "stroke-opacity": "1", @@ -1418,23 +1687,18 @@ "color": "#a4a4a4" }, "nodes": [ - "c85c2df7d79465a0", - "73516493eccdfd9d", - "f762ec936046e78f", - "ce1b28a464e3b3b3", - "81b98c3380c57334", - "d48b052e253b43c3", - "93859b35073996c8" + "ec546330d29baba3", + "96d1b37cfc101abc" ], - "x": 74, - "y": 579, - "w": 592, - "h": 368 + "x": 854, + "y": 959, + "w": 272, + "h": 142 }, { - "id": "0e31504694a6eb0c", + "id": "1309c3c5cd6f1b74", "type": "group", - "z": "191694dad2850f37", + "z": "2b3efcc977e88d91", "style": { "stroke": "#999999", "stroke-opacity": "1", @@ -1445,13 +1709,157 @@ "color": "#a4a4a4" }, "nodes": [ - "9d0d59cbd0342094", - "b67aacc8e54e5106", - "c533acab9a1bba89", - "8565c4a9a8c13312" + "2f187dab7a1ae2ad", + "2c75870eb28bb7c5", + "07a96f21f7eb4899", + "e9e910c0b95eb6fc" ], - "x": 74, - "y": 39, + "x": 514, + "y": 759, + "w": 252, + "h": 242 + }, + { + "id": "3cdc7422abfbe82e", + "type": "group", + "z": "2b3efcc977e88d91", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "3b2ca8934fb0ccd7", + "05af6ff6db82adba" + ], + "x": 854, + "y": 239, + "w": 372, + "h": 142 + }, + { + "id": "2ec09f072ab0b146", + "type": "group", + "z": "2b3efcc977e88d91", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "b07e294259fdd664", + "c5dcd2bf8b994fb8" + ], + "x": 854, + "y": 39, + "w": 352, + "h": 122 + }, + { + "id": "0e1cb402b61eb646", + "type": "group", + "z": "9e23ccbf2e0608ed", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "c0c36621780669a4", + "977f9402195729c4", + "8ec4c35df45a28c5", + "aaf9af66d3e39da8", + "378e8541feaf87ec", + "45671622e142be7e", + "33ca3631b9af0d55" + ], + "x": 248, + "y": 379, + "w": 438, + "h": 408 + }, + { + "id": "8a3c592536de3111", + "type": "group", + "z": "2b3efcc977e88d91", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "e71f5a20f7b7837e", + "c8c9a2cca8781c5f" + ], + "x": 854, + "y": 419, + "w": 332, + "h": 142 + }, + { + "id": "83fd8826b0ec3bf4", + "type": "group", + "z": "191694dad2850f37", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "c85c2df7d79465a0", + "73516493eccdfd9d", + "f762ec936046e78f", + "ce1b28a464e3b3b3", + "81b98c3380c57334", + "d48b052e253b43c3", + "93859b35073996c8" + ], + "x": 74, + "y": 579, + "w": 592, + "h": 368 + }, + { + "id": "0e31504694a6eb0c", + "type": "group", + "z": "191694dad2850f37", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "9d0d59cbd0342094", + "b67aacc8e54e5106", + "c533acab9a1bba89", + "8565c4a9a8c13312" + ], + "x": 74, + "y": 39, "w": 512, "h": 162 }, @@ -1768,6 +2176,192 @@ "w": 438, "h": 408 }, + { + "id": "f1bf7ba3b4088527", + "type": "group", + "z": "f6f2187d.f17ca8", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "0dd8b704b63c96a1", + "3b853d53f8b1fb4d", + "bd7eb8ec2a8e0da9", + "d3e4f8597b868498" + ], + "x": 54, + "y": 79, + "w": 812, + "h": 122 + }, + { + "id": "856e8d2dc2416b46", + "type": "group", + "z": "f6f2187d.f17ca8", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "46b306f2e48bb850", + "733507b741691f58", + "7887225ee569137c", + "9f7f53505a88dbb1", + "fdb9b09540cd5ba6", + "374c4ab5a3ae97c7", + "75a002efe0c1f011", + "84cb3dac9b9f5d39", + "909a59dbc05a2fad", + "6fc0878730035324", + "b56089ef7ebdddf2", + "60e45a11ede888cb", + "df970663c1614b1d", + "0c165bf98f40b598", + "a86d84649831b0fc", + "49c1d79c39f3c0a4", + "0b6e18ac2c03166b", + "e6f08d657cfa77a9", + "72d2e05a0acd3fa8", + "35aa7e2f151f726c", + "f1c8fbcb6c326e46", + "bfb495bb4ca9ae6f", + "6026847cd96ce18c", + "12ca61074a76e5dd", + "d8c78c08e407231e", + "d75002a1564c11aa", + "4534e2dfa3d348df" + ], + "x": 54, + "y": 239, + "w": 1372, + "h": 502 + }, + { + "id": "d3ea6600f7f1c7d6", + "type": "group", + "z": "f6f2187d.f17ca8", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "14dab9180b245706", + "1ed0f9b52a08f533" + ], + "x": 914, + "y": 79, + "w": 252, + "h": 82 + }, + { + "id": "f7696f05d57ef7a1", + "type": "group", + "z": "3b5c9ca1fb9ebf48", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "d3eca839cbbe8f34", + "d4ebbd593cf64e04", + "c2b3e2bf431804bd", + "a7de977d7732152e", + "8ef6bd83dbaa3d85", + "4c7815cb04fa305a", + "3e0ce960e9b660a1" + ], + "x": 88, + "y": 599, + "w": 438, + "h": 408 + }, + { + "id": "e18c67f0ba18707b", + "type": "group", + "z": "3fb1b07be44ed756", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "b75f0d8130661559", + "26a114fc27cd90b0", + "ea2d35fce99de4ae", + "8f75c3504c3dbc5f", + "e22d75a202b3a7d9", + "233b190c4bba2abc", + "18e60cf6d75b5c02", + "366fdac4502597e4", + "f58a612cea662f7f", + "3163545a452b8023", + "f4e0940a4675e15a", + "d5dd065101ef890a", + "4a5b440f0562c4c5", + "437a9435e7f7839a", + "234a56ef02849517", + "bd0ab9ac636bddf7", + "4b1052f331f48638", + "f119a534c23868e3", + "7e92245bb06f8113", + "a11718080bf06447", + "11de70778f4fcccb" + ], + "x": 794, + "y": 299, + "w": 842, + "h": 502 + }, + { + "id": "d20e17ae1f88e910", + "type": "group", + "z": "3b5c9ca1fb9ebf48", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "dd6437290fd336e7", + "7ab56a5e25543ac8", + "583705d65356bc91", + "5ae745cf98b55950", + "35a1e0a9c30682f6" + ], + "x": 534, + "y": 1394, + "w": 412, + "h": 147 + }, { "id": "aaf9af66d3e39da8", "type": "group", @@ -1888,6 +2482,30 @@ "w": 372, "h": 122 }, + { + "id": "a7de977d7732152e", + "type": "group", + "z": "3b5c9ca1fb9ebf48", + "g": "f7696f05d57ef7a1", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "1c9144b2ef0b4dd5", + "399f0d05531fcfd6", + "504106b997f60dbe" + ], + "x": 114, + "y": 859, + "w": 372, + "h": 122 + }, { "id": "b6cc1b3167117b16", "type": "junction", @@ -1901,9 +2519,134 @@ ] }, { - "id": "abd5674a230a71e1", - "type": "function", - "z": "9941dd1769d8bb1b", + "id": "b3c027b1a78e62ca", + "type": "junction", + "z": "d5c30c295cb6b7bc", + "x": 480, + "y": 340, + "wires": [ + [ + "5be0298a22eb5f2a" + ] + ] + }, + { + "id": "cf1db7761982b2fc", + "type": "junction", + "z": "b9a9b43a3594c357", + "x": 540, + "y": 720, + "wires": [ + [ + "5a94f86438968b9b" + ] + ] + }, + { + "id": "583705d65356bc91", + "type": "junction", + "z": "3b5c9ca1fb9ebf48", + "g": "d20e17ae1f88e910", + "x": 920, + "y": 1460, + "wires": [ + [ + "5ae745cf98b55950" + ] + ] + }, + { + "id": "b136a36f1f060bab", + "type": "junction", + "z": "b9a9b43a3594c357", + "x": 1140, + "y": 960, + "wires": [ + [ + "0a96edc6fd08333b" + ] + ] + }, + { + "id": "7ab56a5e25543ac8", + "type": "junction", + "z": "3b5c9ca1fb9ebf48", + "g": "d20e17ae1f88e910", + "x": 600, + "y": 1420, + "wires": [ + [ + "8249b529648a77f1" + ] + ] + }, + { + "id": "35a1e0a9c30682f6", + "type": "junction", + "z": "3b5c9ca1fb9ebf48", + "g": "d20e17ae1f88e910", + "x": 560, + "y": 1500, + "wires": [ + [ + "940cc0ae14188d1c" + ] + ] + }, + { + "id": "824ad7c29ee4fd68", + "type": "junction", + "z": "3b5c9ca1fb9ebf48", + "x": 900, + "y": 460, + "wires": [ + [ + "3856fb6b7a093891" + ] + ] + }, + { + "id": "63a5c80a9677a5e8", + "type": "junction", + "z": "3b5c9ca1fb9ebf48", + "x": 940, + "y": 1260, + "wires": [ + [ + "a08be90792caa2ef" + ] + ] + }, + { + "id": "a02641d0cd9d6dbe", + "type": "junction", + "z": "3b5c9ca1fb9ebf48", + "x": 940, + "y": 1100, + "wires": [ + [ + "f2d99994f035a684" + ] + ] + }, + { + "id": "41aad7d8f71cd6e6", + "type": "tls-config", + "name": "", + "cert": "", + "key": "", + "ca": "", + "certname": "", + "keyname": "", + "caname": "localhost.crt", + "servername": "", + "verifyservercert": false, + "alpnprotocol": "" + }, + { + "id": "abd5674a230a71e1", + "type": "function", + "z": "9941dd1769d8bb1b", "name": "Inject context", "func": "const toInject = Object.fromEntries(\n env.get(\"Keys\").map(k => [k, flow.get(`$parent.${k}`)])\n);\n\nmsg = {\n ...msg,\n ...toInject\n};\n\nreturn msg;", "outputs": 1, @@ -5400,7 +6143,7 @@ "id": "8bfba49dc9b231a0", "type": "http request", "z": "f0aa5f2ed7dab3b8", - "name": "Send request", + "name": "Body request / json response", "method": "use", "ret": "obj", "paytoqs": "ignore", @@ -5412,50 +6155,28 @@ "authType": "", "senderr": false, "headers": [], - "x": 570, - "y": 220, + "x": 580, + "y": 240, "wires": [ [ "3d6d82698400006b" ] ] }, - { - "id": "a94bb02058f6c758", - "type": "function", - "z": "f0aa5f2ed7dab3b8", - "name": "Build request", - "func": "// we should just be able to disable this -- stupid\nmsg.requestTimeout = 60 * 60 * 1000;\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 570, - "y": 180, - "wires": [ - [ - "8bfba49dc9b231a0", - "cb132b2beb3c794e", - "4d595b2ab5d73f41" - ] - ] - }, { "id": "3d6d82698400006b", "type": "function", "z": "f0aa5f2ed7dab3b8", "name": "Handle response", - "func": "// if this is a forward messge\nif (msg.action == \"forward-msg\") {\n // save our msg for later\n msg.action = msg.msgAction;\n delete msg.msgAction;\n context.set(\"forwardedMsg\", msg);\n // don't send anything for now\n return;\n}\n\n// get any forwarded input we might have\nconst forwardedMsg = context.get(\"forwardedMsg\");\n\n// if an error occurred\nif (typeof msg.statusCode == \"string\") {\n return {\n action: \"http-error\",\n error: msg.payload,\n msgIn: forwardedMsg\n };\n}\n\n// else, we at least got a response\n// if it was an error response\nif (msg.statusCode >= 400) {\n return {\n action: \"http-error\",\n error: msg.payload,\n msgIn: forwardedMsg\n };\n}\n\n// else, we got a successful response\nreturn {\n ...msg,\n action: \"http-success\",\n msgIn: forwardedMsg\n};\n", + "func": "// if this is a forward messge\nif (msg.action == \"forward-msg\") {\n // save our msg for later\n msg.action = msg.msgAction;\n delete msg.msgAction;\n context.set(\"forwardedMsg\", msg);\n // don't send anything for now\n return;\n}\n\n// get any forwarded input we might have\nconst forwardedMsg = context.get(\"forwardedMsg\");\n\n// if an error occurred\nif (typeof msg.statusCode == \"string\") {\n return {\n action: \"http-error\",\n error: msg.payload,\n msgIn: forwardedMsg\n };\n}\n\n// else, we at least got a response\n// if it was an error response\nif (msg.statusCode >= 400) {\n return {\n action: \"http-error\",\n error: msg.payload,\n msgIn: forwardedMsg\n };\n}\n\n// else, we got a successful response\nreturn {\n ...msg,\n action: \"http-success\",\n content: msg.payload,\n msgIn: forwardedMsg\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 590, - "y": 260, + "x": 930, + "y": 360, "wires": [ [] ] @@ -5472,40 +6193,19 @@ "initialize": "", "finalize": "", "libs": [], - "x": 350, - "y": 260, + "x": 710, + "y": 180, "wires": [ [ "3d6d82698400006b" ] ] }, - { - "id": "cb132b2beb3c794e", - "type": "function", - "z": "f0aa5f2ed7dab3b8", - "name": " ", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 295, - "y": 220, - "wires": [ - [ - "3979567024f92d8a" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false - }, { "id": "4d595b2ab5d73f41", "type": "debug", "z": "f0aa5f2ed7dab3b8", + "d": true, "name": "HTTP Requests", "active": true, "tosidebar": true, @@ -5515,108 +6215,308 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 800, - "y": 180, + "x": 480, + "y": 80, "wires": [] }, { - "id": "446ec29fe6cf3270", + "id": "477f39c216daeebe", + "type": "http request", + "z": "f0aa5f2ed7dab3b8", + "name": "Querystring request / json response", + "method": "GET", + "ret": "obj", + "paytoqs": "query", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 600, + "y": 280, + "wires": [ + [ + "3d6d82698400006b" + ] + ] + }, + { + "id": "6f50302a0314605e", "type": "switch", - "z": "a4137713471da6c4", - "name": "Action", - "property": "action", - "propertyType": "msg", + "z": "f0aa5f2ed7dab3b8", + "name": "Payload Response Mode", + "property": "msg.payloadResponseMode", + "propertyType": "jsonata", "rules": [ { "t": "eq", - "v": "history-add-entry", + "v": "body-json", "vt": "str" }, { "t": "eq", - "v": "vector-store-search", + "v": "querystring-json", "vt": "str" }, { "t": "eq", - "v": "history-init", + "v": "body-text", "vt": "str" }, { - "t": "else" + "t": "eq", + "v": "querystring-text", + "vt": "str" + }, + { + "t": "eq", + "v": "body-buffer", + "vt": "str" + }, + { + "t": "eq", + "v": "querystring-buffer", + "vt": "str" } ], "checkall": "true", "repair": false, - "outputs": 4, - "x": 210, - "y": 280, + "outputs": 6, + "x": 250, + "y": 360, "wires": [ [ - "87b2fd9be71c70e8" + "8bfba49dc9b231a0" ], [ - "2ef9041ac1eff817" + "477f39c216daeebe" ], [ - "a96c909aaf955b96" + "82eed4434b86a830" ], [ - "a57a1ec5360af43f" + "47e72b16872c9c29" + ], + [ + "eb064815eab65390" + ], + [ + "6b3fa08227a4a132" ] ] }, { - "id": "c2c1a70fd9f36e28", - "type": "subflow:74bd10ee8e354d0a", - "z": "a4137713471da6c4", - "name": "", - "x": 820, - "y": 260, + "id": "82eed4434b86a830", + "type": "http request", + "z": "f0aa5f2ed7dab3b8", + "name": "Body request / string response", + "method": "use", + "ret": "txt", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 590, + "y": 340, "wires": [ [ - "5511b481a5af2321" + "3d6d82698400006b" ] ] }, { - "id": "a96c909aaf955b96", - "type": "function", - "z": "a4137713471da6c4", - "name": "Set init props", - "func": "msg.historyNew = env.get(\"New\") || msg.historyNew;\nmsg.historySourceFilename = env.get(\"SourceFilename\") || msg.historySourceFilename;\nmsg.historyId = env.get(\"Id\") || msg.historyId;\n\nreturn msg;\n", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 430, - "y": 400, + "id": "47e72b16872c9c29", + "type": "http request", + "z": "f0aa5f2ed7dab3b8", + "name": "Querystring request / string response", + "method": "GET", + "ret": "txt", + "paytoqs": "query", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 610, + "y": 380, "wires": [ [ - "c2c1a70fd9f36e28" + "3d6d82698400006b" ] ] }, { - "id": "736a5f71119f063f", - "type": "switch", - "z": "a4137713471da6c4", - "name": "history-add-entry role", - "property": "entryRole", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "user", - "vt": "str" - }, - { - "t": "else" - } - ], - "checkall": "true", + "id": "eb064815eab65390", + "type": "http request", + "z": "f0aa5f2ed7dab3b8", + "name": "Body request / buffer response", + "method": "use", + "ret": "bin", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 590, + "y": 440, + "wires": [ + [ + "3d6d82698400006b" + ] + ] + }, + { + "id": "6b3fa08227a4a132", + "type": "http request", + "z": "f0aa5f2ed7dab3b8", + "name": "Querystring request / buffer response", + "method": "GET", + "ret": "bin", + "paytoqs": "query", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 610, + "y": 480, + "wires": [ + [ + "3d6d82698400006b" + ] + ] + }, + { + "id": "1c4e6c80d9868fa0", + "type": "subflow:30eb5320bb41dc49", + "z": "f0aa5f2ed7dab3b8", + "name": "", + "x": 250, + "y": 100, + "wires": [ + [ + "4d595b2ab5d73f41", + "6f50302a0314605e", + "3979567024f92d8a" + ] + ] + }, + { + "id": "446ec29fe6cf3270", + "type": "switch", + "z": "a4137713471da6c4", + "name": "Action", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "history-add-entry", + "vt": "str" + }, + { + "t": "eq", + "v": "vector-store-search", + "vt": "str" + }, + { + "t": "eq", + "v": "history-init", + "vt": "str" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 4, + "x": 210, + "y": 280, + "wires": [ + [ + "87b2fd9be71c70e8" + ], + [ + "2ef9041ac1eff817" + ], + [ + "a96c909aaf955b96" + ], + [ + "a57a1ec5360af43f" + ] + ] + }, + { + "id": "c2c1a70fd9f36e28", + "type": "subflow:74bd10ee8e354d0a", + "z": "a4137713471da6c4", + "name": "", + "x": 820, + "y": 260, + "wires": [ + [ + "5511b481a5af2321" + ] + ] + }, + { + "id": "a96c909aaf955b96", + "type": "function", + "z": "a4137713471da6c4", + "name": "Set init props", + "func": "msg.historyNew = env.get(\"New\") || msg.historyNew;\nmsg.historySourceFilename = env.get(\"SourceFilename\") || msg.historySourceFilename;\nmsg.historyId = env.get(\"Id\") || msg.historyId;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 430, + "y": 400, + "wires": [ + [ + "c2c1a70fd9f36e28" + ] + ] + }, + { + "id": "736a5f71119f063f", + "type": "switch", + "z": "a4137713471da6c4", + "name": "history-add-entry role", + "property": "entryRole", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "user", + "vt": "str" + }, + { + "t": "else" + } + ], + "checkall": "true", "repair": false, "outputs": 2, "x": 460, @@ -5886,7 +6786,7 @@ "type": "function", "z": "f19bc65164444615", "name": "Init", - "func": "msg.id = env.get(\"Factory Id\") || msg.factoryId || `programatic-history-factory-${Math.floor(Math.random() * 1000)}`;\nmsg.histories = {};\n\nflow.set(\"Id\", msg.id);\nflow.set(\"Histories\", msg.histories);\n\nreturn msg;\n", + "func": "msg.id = env.get(\"Factory Id\") || msg.factoryId || `programatic-history-factory-${Date.now()}`;\nmsg.histories = {};\n\nflow.set(\"Id\", msg.id);\nflow.set(\"Histories\", msg.histories);\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, @@ -5945,7 +6845,7 @@ "type": "function", "z": "f19bc65164444615", "name": "Create History", - "func": "const defaultId = `programatic-history-${Math.floor(Math.random() * 1000)}`;\n\nmsg.action = \"history-init\";\n\nif (!msg.historyId) {\n msg.historyId = defaultId;\n}\n\n// if this history already exists\nif (msg.histories[msg.historyId]) {\n node.warn(`Ignoring init action for existing programatic history: ${msg.historyId}`);\n return;\n}\n\nif (!msg.historySourceFilename) {\n msg.historySourceFilename = `/data/db/${defaultId}.json`;\n}\n\nmsg.histories[msg.historyId] = msg.historySourceFilename;\n\nreturn msg;\n", + "func": "const defaultId = `programatic-history-${Date.now()}`;\n\nmsg.action = \"history-init\";\n\nif (!msg.historyId) {\n msg.historyId = defaultId;\n}\n\n// if this history already exists\nif (msg.histories[msg.historyId]) {\n node.warn(`Ignoring init action for existing programatic history: ${msg.historyId}`);\n return;\n}\n\nif (!msg.historySourceFilename) {\n msg.historySourceFilename = `/data/db/${defaultId}.json`;\n}\n\nmsg.histories[msg.historyId] = msg.historySourceFilename;\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, @@ -6200,25 +7100,45 @@ "type": "function", "z": "21de8117bd1967f9", "name": "extractHtmlTags", - "func": "msg.extractHtmlTags = (text) => {\n const tagRegex = /<([A-Za-z0-9-_:.]*)>([\\s\\S]*?)<\\/([A-Za-z0-9_:.-]*)>/g;\n const tags = [];\n let matches;\n while (matches = tagRegex.exec(text)) {\n const [_, openingTag, tagContent, closingTag] = matches;\n\n // if tags don't match\n if (openingTag != closingTag) {\n //skip it\n continue;\n }\n tags.push({tag: openingTag, content: tagContent});\n }\n return tags;\n}\n\nreturn msg;\n", + "func": "const { default: { default: JSSoup } } = msg.importedModules['jssoup'];\n\nmsg.extractHtmlTags = (text) =>\n // get all tags from content\n new JSSoup(text).descendants\n // only return HTML tags\n .filter(it => it.name)\n // get tag name and content\n .map(({name, contents}) => ({ name, content: contents?.join('') ?? '' }));\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 260, - "y": 120, + "x": 380, + "y": 220, "wires": [ [] ] }, + { + "id": "3d458d6f47d14634", + "type": "subflow:87f7528a5c81b545", + "z": "21de8117bd1967f9", + "name": "Import jssoup", + "env": [ + { + "name": "Modules", + "value": "[\"jssoup\"]", + "type": "json" + } + ], + "x": 380, + "y": 180, + "wires": [ + [ + "0a432a478665f6a9" + ] + ] + }, { "id": "af73ebafaf5dc5f2", "type": "function", "z": "240cc03734c17fa7", "name": "Parse Response", - "func": "// if this is not a stream ending\nif (msg.action != \"history-update-streaming\" || msg.history.streaming) {\n return;\n}\n\nconst response = msg.history.entries.slice(-1)[0].content;\nconst responseTags = msg.extractHtmlTags(response);\n\n// send message for every tag\nreturn [\n responseTags.map(({tag, content}) => ({\n tag,\n content,\n agentId: msg.historyId\n }))\n];\n", + "func": "// if this is not a stream ending\nif (msg.action != \"history-update-streaming\" || msg.history.streaming) {\n return;\n}\n\nconst response = msg.history.entries.slice(-1)[0].content;\nconst responseTags = msg.extractHtmlTags(response);\n\n// send message for every tag\nreturn [\n responseTags.map(({name, content}) => ({\n tag: name,\n content,\n agentId: msg.historyId\n }))\n];\n", "outputs": 1, "timeout": 0, "noerr": 0, @@ -6245,1570 +7165,1268 @@ ] }, { - "id": "c0c36621780669a4", - "type": "subflow:a59054999730c251", - "z": "9e23ccbf2e0608ed", - "d": true, - "g": "0e1cb402b61eb646", - "name": "Model - openai - localhost", - "env": [ - { - "name": "Id", - "value": "openai-localhost", - "type": "str" - }, + "id": "1540fd3640a5c2da", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Container spec", + "func": "msg.name = env.get(\"Container Name\") || msg.containerName || `genai-container-${Date.now()}`;\nmsg.image = env.get(\"Image\") || msg.image;\nmsg.command = env.get(\"Command\") || msg.command;\nmsg.args = yargs(env.get(\"Docker Run Args\") || msg.dockerRunArgs).parse();\nmsg.responseMode = env.get(\"Response Mode\") || msg.responseMode || 'full';\nmsg.commit = env.get(\"Commit\") || msg.commit || false;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ { - "name": "BaseUrl", - "value": "http://host.docker.internal:8080", - "type": "str" + "var": "yargs", + "module": "yargs" } ], - "x": 410, - "y": 520, + "x": 240, + "y": 100, "wires": [ [ - "45671622e142be7e" + "68cbcf691071823e" ] ] }, { - "id": "948e1265a14409b8", - "type": "debug", - "z": "9e23ccbf2e0608ed", - "g": "aaf9af66d3e39da8", - "name": "Model Errors", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 510, - "y": 720, - "wires": [] + "id": "68cbcf691071823e", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Create container", + "func": "\nreturn {\n method: \"POST\",\n url: `http://docker-engine-api:2375/containers/create?name=${msg.name}`,\n payload: {\n Cmd: msg.command,\n Image: msg.image\n },\n containerSpec: msg\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 250, + "y": 180, + "wires": [ + [ + "2163e4e6c0ca65f7" + ] + ] }, { - "id": "977f9402195729c4", - "type": "subflow:a59054999730c251", - "z": "9e23ccbf2e0608ed", - "g": "0e1cb402b61eb646", - "name": "Model - genai - llama-cpp-llava", - "env": [ - { - "name": "Id", - "value": "genai-llama-cpp-llava", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", - "type": "str" - } - ], - "x": 430, - "y": 560, + "id": "2163e4e6c0ca65f7", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "b9a9b43a3594c357", + "name": "", + "x": 240, + "y": 220, "wires": [ [ - "45671622e142be7e" + "c0e105a4e8c1ed29" ] ] }, { - "id": "a63ac3946c2843eb", - "type": "debug", - "z": "9e23ccbf2e0608ed", - "d": true, - "g": "aaf9af66d3e39da8", - "name": "Model Output", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 520, - "y": 680, - "wires": [] + "id": "28417899327d5e30", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Start container", + "func": "const containerId = msg.msgIn.containerSpec.id = msg.content.Id;\n\nreturn {\n method: \"POST\",\n url: `http://docker-engine-api:2375/containers/${containerId}/start`,\n containerSpec: msg.msgIn.containerSpec\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 240, + "y": 340, + "wires": [ + [ + "10e31bc197b72db3" + ] + ] }, { - "id": "5e149325f881f48b", - "type": "subflow:2b3efcc977e88d91", - "z": "9e23ccbf2e0608ed", - "name": "", - "env": [ + "id": "c0e105a4e8c1ed29", + "type": "switch", + "z": "b9a9b43a3594c357", + "name": "If http-success", + "property": "action", + "propertyType": "msg", + "rules": [ { - "name": "Url", - "value": "simple-chat", - "type": "str" + "t": "eq", + "v": "http-success", + "vt": "str" + }, + { + "t": "else" } ], - "x": 550, - "y": 160, + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 240, + "y": 260, "wires": [ [ - "246a383da043e031", - "34dd380b3322dc77" + "28417899327d5e30" + ], + [ + "f2d7034e67ca9556" ] ] }, { - "id": "8ec4c35df45a28c5", - "type": "comment", - "z": "9e23ccbf2e0608ed", - "g": "0e1cb402b61eb646", - "name": "Models", - "info": "", - "x": 350, - "y": 420, - "wires": [] + "id": "f2d7034e67ca9556", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Handle error", + "func": "\nreturn {\n ...msg,\n action: \"docker-error\"\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1010, + "y": 560, + "wires": [ + [ + "b136a36f1f060bab" + ] + ] }, { - "id": "246a383da043e031", - "type": "subflow:74bd10ee8e354d0a", - "z": "9e23ccbf2e0608ed", + "id": "10e31bc197b72db3", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "b9a9b43a3594c357", "name": "", - "env": [ - { - "name": "SourceFilename", - "value": "/data/db/history-1711926907124.json", - "type": "str" - } - ], - "x": 310, - "y": 220, + "x": 240, + "y": 380, "wires": [ [ - "c865bad2cdc088e0" + "f298903bf9973df7" ] ] }, { - "id": "b1093b3dfa80dbe3", + "id": "f298903bf9973df7", "type": "switch", - "z": "9e23ccbf2e0608ed", - "g": "aaf9af66d3e39da8", - "name": "Action", + "z": "b9a9b43a3594c357", + "name": "If http-success", "property": "action", "propertyType": "msg", "rules": [ { "t": "eq", - "v": "model-content", + "v": "http-success", "vt": "str" }, { - "t": "eq", - "v": "model-error", - "vt": "str" + "t": "else" } ], "checkall": "true", "repair": false, "outputs": 2, - "x": 350, - "y": 700, + "x": 240, + "y": 420, "wires": [ [ - "a63ac3946c2843eb" + "f5ad23d6f9a6c234", + "0dd1355d2588c8a9" ], [ - "948e1265a14409b8" - ] - ] - }, - { - "id": "8e313642e9e9049a", - "type": "inject", - "z": "9e23ccbf2e0608ed", - "name": "Start App", - "props": [ - { - "p": "timestamp", - "v": "", - "vt": "date" - }, - { - "p": "action", - "v": "history-init", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "x": 140, - "y": 100, - "wires": [ - [ - "246a383da043e031" + "f2d7034e67ca9556" ] ] }, { - "id": "378e8541feaf87ec", - "type": "subflow:a59054999730c251", - "z": "9e23ccbf2e0608ed", - "d": true, - "g": "0e1cb402b61eb646", - "name": "Model - dummy sse", - "env": [ - { - "name": "Id", - "value": "dummy-sse", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://host.docker.internal:8091", - "type": "str" - }, - { - "name": "Batch", - "value": "10", - "type": "num" - } - ], - "x": 390, - "y": 480, + "id": "76e87439b348d398", + "type": "subflow:72ced27310c541f6", + "z": "b9a9b43a3594c357", + "name": "", + "x": 480, + "y": 540, "wires": [ [ - "45671622e142be7e" + "bf699708b661931a" ] ] }, { - "id": "45671622e142be7e", + "id": "f5ad23d6f9a6c234", "type": "function", - "z": "9e23ccbf2e0608ed", - "g": "0e1cb402b61eb646", - "name": " ", - "func": "\nreturn msg;", + "z": "b9a9b43a3594c357", + "name": "Get stdout", + "func": "const containerId = msg.msgIn.containerSpec.id;\n\nreturn {\n method: \"GET\",\n url: `http://docker-engine-api:2375/containers/${containerId}/logs`,\n payloadMode: 'querystring',\n payload: {\n follow: true,\n stdout: true,\n stderr: false\n },\n headers: {\n 'accept': 'text/string',\n },\n containerSpec: msg.msgIn.containerSpec,\n outputMode: msg.msgIn.containerSpec.outputMode\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 645, - "y": 580, + "x": 470, + "y": 500, "wires": [ [ - "246a383da043e031", - "b1093b3dfa80dbe3" + "76e87439b348d398" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "33ca3631b9af0d55", - "type": "subflow:a59054999730c251", - "z": "9e23ccbf2e0608ed", - "d": true, - "g": "0e1cb402b61eb646", - "name": "Model - genai - llama-cpp-mistral-8x", - "env": [ + "id": "bf699708b661931a", + "type": "switch", + "z": "b9a9b43a3594c357", + "name": "cURL Action", + "property": "action", + "propertyType": "msg", + "rules": [ { - "name": "Id", - "value": "genai-llama-cpp-mistral-8x", - "type": "str" + "t": "eq", + "v": "command-stderr", + "vt": "str" }, { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", - "type": "str" + "t": "eq", + "v": "command-exit", + "vt": "str" + }, + { + "t": "eq", + "v": "command-stdout", + "vt": "str" } ], - "x": 440, + "checkall": "true", + "repair": false, + "outputs": 3, + "x": 470, "y": 600, "wires": [ [ - "45671622e142be7e" + "f2d7034e67ca9556" + ], + [ + "4adad0a3f6b3b9a0" + ], + [ + "8ea54312d07a6fdc" ] ] }, { - "id": "d9e8ec2ee480957d", + "id": "ac62a774eb153489", + "type": "switch", + "z": "b9a9b43a3594c357", + "name": "Exit Code", + "property": "msg.exit.code", + "propertyType": "jsonata", + "rules": [ + { + "t": "neq", + "v": "0", + "vt": "num" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 680, + "y": 640, + "wires": [ + [ + "f2d7034e67ca9556" + ], + [ + "3915149c0c74af4b" + ] + ] + }, + { + "id": "8ea54312d07a6fdc", "type": "function", - "z": "9e23ccbf2e0608ed", - "name": " ", - "func": "\nreturn msg;", + "z": "b9a9b43a3594c357", + "name": "Handle stdout", + "func": "if (!msg.content) {\n return;\n}\n\nreturn {\n ...msg,\n containerSpec: msg.msgIn.containerSpec,\n action: \"docker-stdout\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 205, - "y": 460, + "x": 700, + "y": 1240, "wires": [ [ - "378e8541feaf87ec", - "c0c36621780669a4", - "977f9402195729c4", - "33ca3631b9af0d55" + "b136a36f1f060bab" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "c865bad2cdc088e0", + "id": "c02417dc4c8df8e5", "type": "function", - "z": "9e23ccbf2e0608ed", - "g": "bf3cb919a9b18a74", - "name": "System Prompt", - "func": "// Initial prompt\nconst initialPrompt = `You are a helpful chat bot that will perform any requested tasks to the best of your ability.`;\n\n// if this is an update prompt message\nif (msg.action == \"prompt-update\") {\n // update our prompt\n context.set(\"prompt\", msg.prompt);\n // that's all\n return msg;\n}\n\n// get current prompt\nlet currentPrompt = context.get(\"prompt\");\n\nif (!currentPrompt) {\n currentPrompt = initialPrompt\n context.set(\"prompt\", currentPrompt);\n}\n\nmsg.systemPrompt = currentPrompt;\n\nreturn msg;\n", + "z": "b9a9b43a3594c357", + "name": "Handle success", + "func": "\nreturn {\n ...msg,\n action: \"docker-done\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 580, - "y": 320, + "x": 1000, + "y": 960, "wires": [ [ - "5e149325f881f48b", - "d9e8ec2ee480957d" + "b136a36f1f060bab" ] ] }, { - "id": "34dd380b3322dc77", + "id": "5a94f86438968b9b", "type": "switch", - "z": "9e23ccbf2e0608ed", - "g": "bf3cb919a9b18a74", - "name": "If prompt action", - "property": "action", - "propertyType": "msg", + "z": "b9a9b43a3594c357", + "name": "If remove container", + "property": "msg.containerSpec.args.rm", + "propertyType": "jsonata", "rules": [ { - "t": "regex", - "v": "^prompt-", - "vt": "str", - "case": false + "t": "eq", + "v": "true", + "vt": "jsonata" + }, + { + "t": "else" } ], "checkall": "true", "repair": false, - "outputs": 1, - "x": 580, - "y": 280, + "outputs": 2, + "x": 710, + "y": 960, "wires": [ [ - "c865bad2cdc088e0" + "154690456a2fc9f8" + ], + [ + "c02417dc4c8df8e5" ] ] }, { - "id": "fe160cbe0df384e5", - "type": "template", - "z": "191694dad2850f37", - "name": "System Prompt", - "field": "prompt", - "fieldType": "msg", - "format": "handlebars", - "syntax": "mustache", - "template": "You are a helpful chat bot that will perform any requested tasks to the best of your ability.", - "output": "str", - "x": 200, - "y": 520, + "id": "154690456a2fc9f8", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Remove container", + "func": "const containerSpec = msg.containerSpec;\n\nreturn {\n method: \"DELETE\",\n url: `http://docker-engine-api:2375/containers/${containerSpec.id}?v=true`,\n containerSpec,\n exit: msg.exit\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 710, + "y": 1040, "wires": [ [ - "81b98c3380c57334" + "ed312f61da898031" ] ] }, { - "id": "34fa053e9707e425", - "type": "subflow:74bd10ee8e354d0a", - "z": "191694dad2850f37", - "g": "b1dd9777ee396bd7", - "name": "Solution History", - "env": [ - { - "name": "Id", - "value": "solution-01", - "type": "str" - } - ], - "x": 480, - "y": 380, + "id": "ed312f61da898031", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "b9a9b43a3594c357", + "name": "", + "x": 700, + "y": 1080, "wires": [ [ - "8565c4a9a8c13312", - "88802dbd1e8b0c57", - "b38cd518b824c20d" + "2310df3f0167dbf7" ] ] }, { - "id": "9d0d59cbd0342094", - "type": "inject", - "z": "191694dad2850f37", - "g": "0e31504694a6eb0c", - "name": "Start Loop", - "props": [ + "id": "2310df3f0167dbf7", + "type": "switch", + "z": "b9a9b43a3594c357", + "name": "If http-success", + "property": "action", + "propertyType": "msg", + "rules": [ { - "p": "action", - "v": "step-go-to", + "t": "eq", + "v": "http-success", "vt": "str" + }, + { + "t": "else" } ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "x": 500, - "y": 80, + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 700, + "y": 1120, "wires": [ [ - "b67aacc8e54e5106" + "5047c7f754d6aa6d" + ], + [ + "f2d7034e67ca9556" ] ] }, { - "id": "c85c2df7d79465a0", - "type": "subflow:a59054999730c251", - "z": "191694dad2850f37", - "d": true, - "g": "83fd8826b0ec3bf4", - "name": "Model - dummy sse", - "env": [ - { - "name": "Id", - "value": "dummy-sse", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://host.docker.internal:8091", - "type": "str" - }, - { - "name": "Batch", - "value": "10", - "type": "num" - } - ], - "x": 330, - "y": 680, + "id": "0dc9efa99bce1f0c", + "type": "subflow:72ced27310c541f6", + "z": "b9a9b43a3594c357", + "name": "", + "x": 240, + "y": 540, "wires": [ [ - "d48b052e253b43c3" + "d713530df83a6cc3" ] ] }, { - "id": "73516493eccdfd9d", - "type": "subflow:a59054999730c251", - "z": "191694dad2850f37", - "g": "83fd8826b0ec3bf4", - "name": "Model - genai - llama-cpp-llava", - "env": [ - { - "name": "Id", - "value": "genai-llama-cpp-llava", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", - "type": "str" - }, - { - "name": "Batch", - "value": "10", - "type": "num" - } - ], - "x": 370, - "y": 760, + "id": "0dd1355d2588c8a9", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Get stderr", + "func": "const containerId = msg.msgIn.containerSpec.id;\n\nreturn {\n method: \"GET\",\n url: `http://docker-engine-api:2375/containers/${containerId}/logs`,\n payloadMode: 'querystring',\n payload: {\n follow: true,\n stdout: false,\n stderr: true\n },\n headers: {\n 'accept': 'text/string',\n },\n containerSpec: msg.msgIn.containerSpec,\n outputMode: msg.msgIn.containerSpec.outputMode\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 220, + "y": 500, "wires": [ [ - "d48b052e253b43c3" + "0dc9efa99bce1f0c" ] ] }, { - "id": "f762ec936046e78f", - "type": "comment", - "z": "191694dad2850f37", - "g": "83fd8826b0ec3bf4", - "name": "Models", - "info": "", - "x": 290, - "y": 620, - "wires": [] - }, - { - "id": "e451712bc8b52b18", - "type": "debug", - "z": "191694dad2850f37", - "g": "ce1b28a464e3b3b3", - "name": "Model Errors", - "active": true, - "tosidebar": true, - "console": true, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 460, - "y": 880, - "wires": [] - }, - { - "id": "e2dd14f8d37e7a72", - "type": "debug", - "z": "191694dad2850f37", - "g": "ce1b28a464e3b3b3", - "name": "Model Output", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 460, - "y": 840, - "wires": [] - }, - { - "id": "bb6dc487db2ce156", + "id": "d713530df83a6cc3", "type": "switch", - "z": "191694dad2850f37", - "g": "ce1b28a464e3b3b3", - "name": "Action", + "z": "b9a9b43a3594c357", + "name": "cURL Action", "property": "action", "propertyType": "msg", "rules": [ { "t": "eq", - "v": "model-streaming-content", + "v": "command-stderr", "vt": "str" }, { "t": "eq", - "v": "model-error", + "v": "command-stdout", "vt": "str" } ], "checkall": "true", "repair": false, "outputs": 2, - "x": 290, - "y": 860, + "x": 230, + "y": 580, "wires": [ [ - "e2dd14f8d37e7a72" + "f2d7034e67ca9556" ], [ - "e451712bc8b52b18" - ] - ] - }, - { - "id": "42cede20c9456a92", - "type": "subflow:74bd10ee8e354d0a", - "z": "191694dad2850f37", - "g": "5dbdaf47523ce33a", - "name": "Eval History", - "env": [ - { - "name": "Id", - "value": "eval-01", - "type": "str" - } - ], - "x": 1270, - "y": 640, - "wires": [ - [ - "1f999e727d7bdcbd", - "f79210375a125e74", - "c9ba32537f7bc133", - "6b036e58872195a7" + "dd73ee28dfd14074" ] ] }, { - "id": "b67aacc8e54e5106", + "id": "dd73ee28dfd14074", "type": "function", - "z": "191694dad2850f37", - "g": "0e31504694a6eb0c", - "name": "Prompt: Problem statement", - "func": "msg.createUserPrompt = () =>\n `I have 10K in savings currently in an investment account. My goal is to earn a passive income of $10K every month. Create a plan for me that will meet this goal. I'm looking for single tailored plan, not options to choose from. Give specific, brief instructions for carrying out this plan.`;\n\nflow.set(\"originalProblemStatement\", msg.createUserPrompt());\n\nreturn msg;\n", + "z": "b9a9b43a3594c357", + "name": "Handle stderr", + "func": "if (!msg.content) {\n return;\n}\n\nreturn {\n ...msg,\n containerSpec: msg.msgIn.containerSpec,\n action: \"docker-stderr\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 220, - "y": 160, + "x": 700, + "y": 1320, "wires": [ [ - "8565c4a9a8c13312" + "b136a36f1f060bab" ] ] }, { - "id": "81b98c3380c57334", - "type": "function", - "z": "191694dad2850f37", - "g": "83fd8826b0ec3bf4", - "name": "In", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 150, - "y": 700, + "id": "3915149c0c74af4b", + "type": "switch", + "z": "b9a9b43a3594c357", + "name": "If commit", + "property": "msg.containerSpec.commit", + "propertyType": "jsonata", + "rules": [ + { + "t": "eq", + "v": "true", + "vt": "jsonata" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 680, + "y": 680, "wires": [ [ - "c85c2df7d79465a0", - "73516493eccdfd9d", - "93859b35073996c8" + "350e0fda13f31cc6" + ], + [ + "cf1db7761982b2fc" ] - ], - "icon": "font-awesome/fa-address-card-o" + ] }, { - "id": "d48b052e253b43c3", + "id": "350e0fda13f31cc6", "type": "function", - "z": "191694dad2850f37", - "g": "83fd8826b0ec3bf4", - "name": "Out", - "func": "\nreturn msg;", + "z": "b9a9b43a3594c357", + "name": "Commit", + "func": "\nreturn {\n ...msg,\n container: msg.containerSpec.id\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 590, - "y": 700, + "x": 680, + "y": 760, "wires": [ [ - "bb6dc487db2ce156", - "4135e1850bf3099c", - "fe0f3fe28e08e2f0", - "0800060d86e1ca55", - "079bf5373fe5d58f", - "b38cd518b824c20d" + "35eba55d4599f26a" ] - ], - "icon": "font-awesome/fa-address-card-o" - }, - { - "id": "c533acab9a1bba89", - "type": "comment", - "z": "191694dad2850f37", - "g": "0e31504694a6eb0c", - "name": "Step 1: Problem Statement and Solution", - "info": "", - "x": 250, - "y": 80, - "wires": [] - }, - { - "id": "8516a2d5188e142d", - "type": "comment", - "z": "191694dad2850f37", - "g": "17a2a4d88505d1b2", - "name": "Step 2: Evaluate Solution", - "info": "", - "x": 990, - "y": 340, - "wires": [] - }, - { - "id": "5dd26b4eb51f86a8", - "type": "comment", - "z": "191694dad2850f37", - "g": "3334e9dd5bf3557d", - "name": "Step 3: Propose New Prompt", - "info": "", - "x": 1000, - "y": 820, - "wires": [] + ] }, { - "id": "0800060d86e1ca55", - "type": "function", - "z": "191694dad2850f37", - "g": "0df36a8be0d76989", - "name": "Prompt: Use proposed prompt", - "func": "msg.createUserPrompt = (history) => {\n const promptProposal = history.entries.slice(-1)[0].content;\n let newPrompt;\n try {\n // don't search for full ending tag, since sometimes the last token gets cutoff\n newPrompt = promptProposal.match(/([\\s\\S]*?)<\\/pro/)[1].trim();\n if (newPrompt.length < 1) {\n throw new Error(\"Empty prompt extracted from proposal\")\n }\n }\n catch (e) {\n throw new Error(`Error extracting prompt from: \\`${promptProposal}\\``);\n }\n\n return newPrompt;\n};\n\nreturn msg;\n", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1010, - "y": 160, + "id": "35eba55d4599f26a", + "type": "subflow:3f4aa860a3b350bc", + "z": "b9a9b43a3594c357", + "name": "", + "x": 700, + "y": 800, "wires": [ [ - "a33731f7d26ff1d8" + "8d5c1f2ac7b735ab" ] ] }, { - "id": "32fd036f241606a1", - "type": "comment", - "z": "191694dad2850f37", - "g": "0df36a8be0d76989", - "name": "Step 4: Restart w/ New Prompt", - "info": "", - "x": 1010, - "y": 80, - "wires": [] - }, - { - "id": "0ad9554c20eb8dd0", + "id": "8d5c1f2ac7b735ab", "type": "switch", - "z": "191694dad2850f37", - "g": "b1dd9777ee396bd7", - "name": "If Step 1", - "property": "step", - "propertyType": "flow", + "z": "b9a9b43a3594c357", + "name": "If success", + "property": "action", + "propertyType": "msg", "rules": [ { "t": "eq", - "v": "1", + "v": "docker-done", "vt": "str" - } - ], - "checkall": "true", - "repair": false, - "outputs": 1, - "x": 460, - "y": 340, - "wires": [ - [ - "34fa053e9707e425" - ] - ] - }, - { - "id": "4135e1850bf3099c", - "type": "switch", - "z": "191694dad2850f37", - "g": "5dbdaf47523ce33a", - "name": "If Step 2 or 3", - "property": "step", - "propertyType": "flow", - "rules": [ + }, { - "t": "btwn", - "v": "2", - "vt": "num", - "v2": "3", - "v2t": "num" + "t": "else" } ], "checkall": "true", "repair": false, - "outputs": 1, - "x": 1270, - "y": 600, + "outputs": 2, + "x": 680, + "y": 840, "wires": [ [ - "42cede20c9456a92" + "c829d6336d001021" + ], + [ + "f2d7034e67ca9556" ] ] }, { - "id": "93859b35073996c8", - "type": "subflow:a59054999730c251", - "z": "191694dad2850f37", - "d": true, - "g": "83fd8826b0ec3bf4", - "name": "Model - openai - localhost", - "env": [ - { - "name": "Id", - "value": "openai-localhost", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://host.docker.internal:8080", - "type": "str" - } - ], - "x": 350, - "y": 720, + "id": "c829d6336d001021", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Store commit", + "func": "\nreturn {\n ...msg,\n containerSpec: {\n ...msg.commitSpec.containerSpec,\n commit: msg.commitSpec\n },\n exit: msg.commitSpec.exit\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 690, + "y": 880, "wires": [ [ - "d48b052e253b43c3" + "5a94f86438968b9b" ] ] }, { - "id": "8565c4a9a8c13312", - "type": "subflow:fe8f70709279ea90", - "z": "191694dad2850f37", - "g": "0e31504694a6eb0c", - "name": "Step 1", - "env": [ - { - "name": "Step", - "value": "1", - "type": "num" - }, - { - "name": "InitHistoryId", - "value": "solution-01", - "type": "str" - }, - { - "name": "Wait", - "value": "false", - "type": "bool" - } - ], - "x": 510, - "y": 160, + "id": "4adad0a3f6b3b9a0", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Store exit", + "func": "\nreturn {\n containerSpec: msg.msgIn.containerSpec,\n exit: msg\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 680, + "y": 600, "wires": [ [ - "0ad9554c20eb8dd0" + "ac62a774eb153489" ] ] }, { - "id": "1322aa4137d1056e", + "id": "5047c7f754d6aa6d", "type": "function", - "z": "191694dad2850f37", - "d": true, - "g": "17a2a4d88505d1b2", - "name": "Prompt: Evalutate Solution", - "func": "msg.createUserPrompt = (history) => {\n const problemStatement = history.entries[0].content;\n\n const solution = history.entries.slice(-1)[0].content;\n\n return `I'm going to give you a prompt that a user named Lilly gave to an LLM model named BigStar-13B. Then, I will give you the response BigStar gave to Lilly. I want you to rate BigStar's response on a scale from 1-10. Then, give 2-3 specific improvements to BigStar's response that would have increased it's rating.\n\nHere is Lilly's prompt:\n\n${problemStatement}\n\nHere is BigStar's response:\n\n${solution}\n\nWhat would you rate BigStar's response?`;\n};\n\nreturn msg;\n", + "z": "b9a9b43a3594c357", + "name": "Return input message", + "func": "\nreturn msg.msgIn;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1020, - "y": 420, + "x": 720, + "y": 1160, "wires": [ [ - "1f999e727d7bdcbd" + "c02417dc4c8df8e5" ] ] }, { - "id": "1f999e727d7bdcbd", - "type": "subflow:fe8f70709279ea90", - "z": "191694dad2850f37", - "g": "17a2a4d88505d1b2", - "name": "Step 2", - "env": [ - { - "name": "Step", - "value": "2", - "type": "num" - }, - { - "name": "InitHistoryId", - "value": "eval-01", - "type": "str" - } - ], - "x": 1290, - "y": 420, - "wires": [ - [ - "4135e1850bf3099c" - ] - ] + "id": "9ead6c09c1634875", + "type": "debug", + "z": "b9a9b43a3594c357", + "name": "Docker Run In", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 220, + "y": 20, + "wires": [] }, { - "id": "833eaf27d6837495", - "type": "subflow:fe8f70709279ea90", - "z": "191694dad2850f37", - "g": "3334e9dd5bf3557d", - "name": "Step 3", - "env": [ - { - "name": "Step", - "value": "3", - "type": "num" - }, - { - "name": "InitHistory", - "value": "false", - "type": "bool" - } - ], - "x": 1290, - "y": 900, + "id": "0a96edc6fd08333b", + "type": "debug", + "z": "b9a9b43a3594c357", + "name": "Docker Run Out", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1300, + "y": 880, + "wires": [] + }, + { + "id": "65a8ebb1afe5c330", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "5982620408722375", + "name": "", + "x": 630, + "y": 280, "wires": [ - [ - "909642bb1b9261ea" - ] + [] ] }, { - "id": "fe0f3fe28e08e2f0", + "id": "41ea315220e88ed4", "type": "function", - "z": "191694dad2850f37", - "g": "3334e9dd5bf3557d", - "name": "Prompt: Propose New Prompt", - "func": "msg.createUserPrompt = () => \n `How could Lilly's prompt be altered to get BigStar to respond with your suggested improvements? Please provide the new prompt wrapped in tags.`;\n\n\nreturn msg;\n", + "z": "5982620408722375", + "name": "function 21", + "func": "msg.url = `http://docker-engine-api:2375/containers/e9388b9bc020d3438b87a56357b93c08f79fbda456525834238245285ed47eed/logs?stdout=true`;\n// msg.url = `http://host.docker.internal:8080`\nmsg.method = \"GET\"\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1010, - "y": 900, + "x": 410, + "y": 280, "wires": [ [ - "833eaf27d6837495" + "65a8ebb1afe5c330" ] ] }, { - "id": "a33731f7d26ff1d8", - "type": "subflow:fe8f70709279ea90", - "z": "191694dad2850f37", - "g": "0df36a8be0d76989", - "name": "Step 4", - "env": [ - { - "name": "Step", - "value": "4", - "type": "num" - }, - { - "name": "InitHistory", - "value": "false", - "type": "bool" - } - ], - "x": 930, - "y": 220, + "id": "81af6496ee4f4c30", + "type": "exec", + "z": "d5c30c295cb6b7bc", + "command": "", + "addpay": "command", + "append": "", + "useSpawn": "false", + "timer": "", + "winHide": false, + "oldrc": false, + "name": "", + "x": 530, + "y": 200, "wires": [ [ - "85c126ddb6ae9692" - ] - ] - }, - { - "id": "36217d16d71a4c30", - "type": "inject", - "z": "191694dad2850f37", - "g": "17a2a4d88505d1b2", - "name": "Start @ Step 2", - "props": [ - { - "p": "historyId", - "v": "solution-01", - "vt": "str" - }, - { - "p": "historySourceFilename", - "v": "/data/db/history-1706503270302.json", - "vt": "str" - }, - { - "p": "action", - "v": "step-start-at", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "x": 1260, - "y": 340, - "wires": [ + "189a0f12c5d3189e" + ], [ - "b38cd518b824c20d" + "bba82265f3401843" + ], + [ + "571c40cd622a7e4a" ] ] }, { - "id": "7b60dc37c59dc80f", - "type": "inject", - "z": "191694dad2850f37", - "g": "0df36a8be0d76989", - "name": "Start @ Step 4", - "props": [ - { - "p": "historyId", - "v": "eval-01", - "vt": "str" - }, - { - "p": "historySourceFilename", - "v": "/data/db/history-1706169633523.json", - "vt": "str" - }, - { - "p": "action", - "v": "step-start-at", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "x": 1260, - "y": 80, + "id": "10a590c86c24cc1c", + "type": "exec", + "z": "d5c30c295cb6b7bc", + "command": "", + "addpay": "command", + "append": "", + "useSpawn": "true", + "timer": "", + "winHide": false, + "oldrc": false, + "name": "spawn", + "x": 530, + "y": 280, "wires": [ [ - "0800060d86e1ca55" + "189a0f12c5d3189e" + ], + [ + "bba82265f3401843" + ], + [ + "571c40cd622a7e4a" ] ] }, { - "id": "36f73b6e3236c721", - "type": "inject", - "z": "191694dad2850f37", - "g": "3334e9dd5bf3557d", - "name": "Start @ Step 3", - "props": [ - { - "p": "historyId", - "v": "eval-01", - "vt": "str" - }, + "id": "9c2566ae93501d69", + "type": "switch", + "z": "d5c30c295cb6b7bc", + "name": "Mode", + "property": "mode", + "propertyType": "msg", + "rules": [ { - "p": "historySourceFilename", - "v": "/data/db/history-1706169407261.json", + "t": "eq", + "v": "exec", "vt": "str" }, { - "p": "action", - "v": "step-start-at", + "t": "eq", + "v": "spawn", "vt": "str" } ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "x": 1260, - "y": 820, + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 330, + "y": 240, "wires": [ [ - "fe0f3fe28e08e2f0" + "81af6496ee4f4c30" + ], + [ + "10a590c86c24cc1c", + "b3c027b1a78e62ca" ] ] }, { - "id": "bd8902942d9f30bc", + "id": "1c249f69debb918b", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Set mode", + "func": "msg.mode = msg.mode || 'exec';\nmsg.responseMode = msg.responseMode || 'text';\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 795, - "y": 780, + "x": 180, + "y": 140, "wires": [ [ - "fe0f3fe28e08e2f0" + "9c2566ae93501d69", + "5ec949124503c75a" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "f79210375a125e74", + "id": "571c40cd622a7e4a", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Return code", + "func": "\nreturn {\n ...msg.payload,\n action: 'command-exit'\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1435, - "y": 660, + "x": 750, + "y": 320, "wires": [ [ - "bd8902942d9f30bc" + "bee02be8135363fa" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "909642bb1b9261ea", + "id": "5be0298a22eb5f2a", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Spawned", + "func": "\nreturn {\n msgIn: msg,\n action: \"command-spawn\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1435, - "y": 820, + "x": 740, + "y": 400, "wires": [ - [ - "246801bf115544b3" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + [] + ] }, { - "id": "246801bf115544b3", + "id": "5ec949124503c75a", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Forward msg", + "func": "return {\n ...msg,\n action: \"forward-msg\",\n msgAction: msg.action\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1125, - "y": 640, + "x": 750, + "y": 80, "wires": [ [ - "4135e1850bf3099c" + "bee02be8135363fa" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "c9ba32537f7bc133", + "id": "189a0f12c5d3189e", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Stdout", + "func": "return {\n ...msg,\n action: \"command-stdout\",\n content: msg.payload,\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1435, - "y": 320, + "x": 730, + "y": 160, "wires": [ [ - "322d52b49ebe2f42" + "bee02be8135363fa" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "88802dbd1e8b0c57", + "id": "bba82265f3401843", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Stderr", + "func": "\nreturn {\n ...msg,\n action: \"command-stderr\",\n content: msg.payload\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 645, - "y": 420, - "wires": [ - [ - "fe160cbe0df384e5" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false - }, - { - "id": "85c126ddb6ae9692", - "type": "subflow:3bb38f582155f29d", - "z": "191694dad2850f37", - "g": "0df36a8be0d76989", - "name": "", - "x": 1050, - "y": 220, + "x": 730, + "y": 240, "wires": [ [ - "a8aa5ac1df416d41" + "bee02be8135363fa" ] ] }, { - "id": "a8aa5ac1df416d41", + "id": "bee02be8135363fa", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Handle response", + "func": "// if this is a forward messge\nif (msg.action == \"forward-msg\") {\n // save our msg for later\n msg.action = msg.msgAction;\n delete msg.msgAction;\n context.set(\"forwardedMsg\", msg);\n // don't send anything for now\n return;\n}\n\n// get any forwarded input we might have\nconst forwardedMsg = context.get(\"forwardedMsg\");\n\n// transform response\nif (msg.content) {\n switch(forwardedMsg.responseMode) {\n case 'text':\n msg.content = msg.content.toString();\n break;\n case 'buffer':\n msg.content = Buffer.from(msg.content);\n break;\n }\n}\n\nreturn {\n ...msg,\n msgIn: forwardedMsg,\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 345, - "y": 280, + "x": 1010, + "y": 240, + "wires": [ + [] + ] + }, + { + "id": "63387d16cd6a7986", + "type": "subflow:d5c30c295cb6b7bc", + "z": "72ced27310c541f6", + "name": "", + "x": 620, + "y": 300, "wires": [ [ - "8565c4a9a8c13312" + "c7494ed5f552a21e" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "322d52b49ebe2f42", + "id": "c8af8c1b86c8ae07", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "72ced27310c541f6", + "name": "Create command", + "func": "const { URLSearchParams } = msg.global;\n\nmsg.outputMode = msg.outputMode || 'full';\n\nlet curlCommand = `curl --silent -X ${msg.method}`;\n\nfor (const [key, value] of Object.entries(msg.headers)) {\n curlCommand += ` -H \"${key}: ${value}\"`;\n}\n\nconst payload = msg.payload || {};\nif (Object.keys(payload).length > 0) {\n switch(msg.payloadMode) {\n case 'body':\n curlCommand += ` -H \"Content-Type: application/json\" -d '${JSON.stringify(payload)}'`;\n break;\n case 'querystring':\n const queryString = new URLSearchParams(payload).toString();\n const separator = msg.url.includes('?') ? '&' : '?';\n msg.url += `${separator}${queryString}`;\n break;\n }\n}\n\ncurlCommand += ` \"${msg.url}\"`;\n\nreturn {\n ...msg,\n command: curlCommand,\n mode: msg.outputMode === 'full' ? 'exec' : 'spawn'\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 755, - "y": 260, + "x": 250, + "y": 220, "wires": [ [ - "0800060d86e1ca55" + "63387d16cd6a7986" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "6b036e58872195a7", - "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1435, - "y": 560, + "id": "e13b4eb99a77c41e", + "type": "subflow:30eb5320bb41dc49", + "z": "72ced27310c541f6", + "name": "", + "x": 250, + "y": 180, "wires": [ [ - "fe160cbe0df384e5" + "c8af8c1b86c8ae07", + "9b8674a5a8ade573" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "079bf5373fe5d58f", - "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 775, - "y": 640, + "id": "03f57deed86e37c5", + "type": "provide-global", + "z": "72ced27310c541f6", + "name": "", + "x": 240, + "y": 140, "wires": [ [ - "c8bf1c9a8fe80c37" + "e13b4eb99a77c41e" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "c8bf1c9a8fe80c37", + "id": "c7494ed5f552a21e", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "72ced27310c541f6", + "name": "Handle response", + "func": "if (!['command-stderr', 'command-stdout'].includes(msg.action)) {\n // no content to parse, just return the message\n return msg;\n}\n\n// else, parse our content\nlet parsedContent;\nswitch (msg.msgIn.responseMode) {\n case 'json':\n try {\n parsedContent = JSON.parse(msg.content);\n } catch (e) {\n node.warn('Failed to parse JSON response');\n parsedContent = msg.content;\n }\n break;\n case 'text':\n parsedContent = msg.content.toString();\n break;\n case 'buffer':\n parsedContent = Buffer.from(msg.content);\n break;\n}\n\nreturn {\n ...msg,\n rawContent: msg.content,\n content: parsedContent,\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 305, - "y": 380, + "x": 870, + "y": 200, "wires": [ - [ - "0ad9554c20eb8dd0" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + [] + ] }, { - "id": "b38cd518b824c20d", + "id": "9b8674a5a8ade573", + "type": "debug", + "z": "72ced27310c541f6", + "d": true, + "name": "cURL Requests", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 500, + "y": 160, + "wires": [] + }, + { + "id": "3762dbf4e0957cfa", "type": "function", - "z": "191694dad2850f37", - "g": "17a2a4d88505d1b2", - "name": " ", - "func": "\nreturn msg;", + "z": "30eb5320bb41dc49", + "name": "Build request", + "func": "msg.method = msg.method.toLocaleUpperCase() || \"GET\";\nmsg.payloadMode = msg.method === \"GET\" && msg.payloadMode\n ? msg.payloadMode : 'body';\nmsg.headers = msg.headers ?\n Object.fromEntries(\n Object.entries(msg.headers)\n .map(\n ([k, v]) => [k.toLocaleLowerCase(), v]\n )\n )\n : {};\nconst acceptHeader = msg.headers['accept'] = msg.headers['accept'] || 'application/json';\nmsg.responseMode =\n acceptHeader.includes('json')\n ? 'json'\n : acceptHeader.includes('text')\n ? 'text'\n : 'buffer';\nmsg.payloadResponseMode = `${msg.payloadMode}-${msg.responseMode}`;\n// we should just be able to disable this -- stupid\nmsg.requestTimeout = 60 * 60 * 1000;\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 855, - "y": 420, + "x": 210, + "y": 120, "wires": [ - [ - "1322aa4137d1056e", - "9240a0389d51445c" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + [] + ] }, { - "id": "9240a0389d51445c", + "id": "f3d99166630391d1", "type": "function", - "z": "191694dad2850f37", - "g": "17a2a4d88505d1b2", - "name": "Prompt: Evalutate Against Original", - "func": "msg.createUserPrompt = (history) => {\n const problemStatement = flow.get(\"originalProblemStatement\");\n\n const solution = history.entries.slice(-1)[0].content;\n\n return `I'm going to give you a prompt that a user named Lilly gave to an LLM model named BigStar-13B. Then, I will give you the response BigStar gave to Lilly. I want you to rate BigStar's response on a scale from 1-10. Then, give 2-3 specific improvements to BigStar's response that would have increased it's rating.\n\nHere is Lilly's prompt:\n\n${problemStatement}\n\nHere is BigStar's response:\n\n${solution}\n\nWhat would you rate BigStar's response?`;\n};\n\nreturn msg;\n", + "z": "3f4aa860a3b350bc", + "name": "Commit spec", + "func": "msg.container = env.get(\"Container\") || msg.container;\nmsg.repository = env.get(\"Repository\") || msg.repository || `commit-${msg.container}`;\nmsg.tag = env.get(\"Tag\") || msg.tag || `${Date.now()}`;\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", - "libs": [], - "x": 1040, - "y": 460, + "libs": [ + { + "var": "yargs", + "module": "yargs" + } + ], + "x": 210, + "y": 100, "wires": [ [ - "1f999e727d7bdcbd" + "c393a31a37569fbb" ] ] }, { - "id": "b75f0d8130661559", + "id": "c393a31a37569fbb", "type": "function", - "z": "3fb1b07be44ed756", - "name": "function 1", - "func": "return { sseJs, nodeFetch, async }", + "z": "3f4aa860a3b350bc", + "name": "Commit container", + "func": "\nreturn {\n method: \"POST\",\n url: `http://docker-engine-api:2375/commit?container=${msg.container}&tag=${msg.tag}&repo=${msg.repository}`,\n payload: {\n Cmd: msg.command,\n Image: msg.image\n },\n commitSpec: msg\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", - "libs": [ - { - "var": "sseJs", - "module": "sse.js" - }, - { - "var": "async", - "module": "async" - }, - { - "var": "nodeFetch", - "module": "node-fetch" - } - ], - "x": 480, - "y": 260, + "libs": [], + "x": 230, + "y": 180, "wires": [ [ - "ea2d35fce99de4ae" + "1d44ae7d4b9f9d12" ] ] }, { - "id": "26a114fc27cd90b0", - "type": "inject", - "z": "3fb1b07be44ed756", + "id": "1d44ae7d4b9f9d12", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "3f4aa860a3b350bc", "name": "", - "props": [ + "x": 220, + "y": 220, + "wires": [ + [ + "42d4108f978541ae" + ] + ] + }, + { + "id": "42d4108f978541ae", + "type": "switch", + "z": "3f4aa860a3b350bc", + "name": "If http-success", + "property": "action", + "propertyType": "msg", + "rules": [ { - "p": "payload" + "t": "eq", + "v": "http-success", + "vt": "str" }, { - "p": "topic", - "vt": "str" + "t": "else" } ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "", - "payloadType": "date", - "x": 300, - "y": 240, + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 220, + "y": 260, "wires": [ [ - "b75f0d8130661559" + "cea8afeae263e378" + ], + [ + "9fe7448838c509e5" ] ] }, { - "id": "ea2d35fce99de4ae", - "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 5", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 650, - "y": 280, - "wires": [] - }, - { - "id": "8f75c3504c3dbc5f", + "id": "9fe7448838c509e5", "type": "function", - "z": "3fb1b07be44ed756", - "name": "Install dependencies", - "func": "// List of NPM modules\nconst toInstall = [\n 'sse.js'\n]\n\nconst { exec } = childProcess;\n\nconst run = async (cmd) => {\n const child = exec(cmd, (err) => {\n if (err) console.error(err);\n });\n await new Promise((resolve) => child.on('close', resolve));\n};\n\nawait Promise.all(toInstall.map(it => run(`npm install ${it}`)));\n\nreturn msg;", + "z": "3f4aa860a3b350bc", + "name": "Handle error", + "func": "\nreturn {\n ...msg,\n commitSpec: msg.msgIn.commitSpec,\n action: \"docker-error\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", - "libs": [ - { - "var": "childProcess", - "module": "child_process" - } - ], - "x": 340, - "y": 320, + "libs": [], + "x": 430, + "y": 280, "wires": [ [] ] }, { - "id": "e22d75a202b3a7d9", + "id": "cea8afeae263e378", "type": "function", - "z": "3fb1b07be44ed756", - "name": "function 2", - "func": "//throw new Error(\"This crashes Node-RED!\");\n\n(async () => {\n try {\n const sse = await (global.get(\"dynamicallyImport\"))(\"sse.js\");\n node.send({sse});\n node.done();\n }\n catch (e) {\n node.send({ e });\n }\n})();\n\nreturn msg;", + "z": "3f4aa860a3b350bc", + "name": "Handle success ", + "func": "const commit = msg.msgIn.commitSpec;\n\nreturn {\n ...msg,\n commitSpec: {\n ...commit,\n image: `${commit.repository}:${commit.tag}`\n },\n action: \"docker-done\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 560, - "y": 360, + "x": 440, + "y": 240, "wires": [ - [ - "18e60cf6d75b5c02" - ] + [] ] }, { - "id": "233b190c4bba2abc", - "type": "inject", - "z": "3fb1b07be44ed756", + "id": "6d6f8c6f67a318de", + "type": "function", + "z": "126e4a373d8bcb36", + "name": "Parse Content", + "func": "\nreturn {\n ...msg,\n contentTags: msg.extractHtmlTags(msg.content || '')\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 220, + "y": 180, + "wires": [ + [] + ] + }, + { + "id": "af3d5caec2de488c", + "type": "subflow:21de8117bd1967f9", + "z": "126e4a373d8bcb36", "name": "", - "props": [ - { - "p": "payload" - }, - { - "p": "topic", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "", - "payloadType": "date", - "x": 400, - "y": 360, + "x": 250, + "y": 140, "wires": [ [ - "e22d75a202b3a7d9" + "6d6f8c6f67a318de" ] ] }, { - "id": "18e60cf6d75b5c02", - "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 6", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 720, - "y": 360, - "wires": [] + "id": "e935f75b3e48ad5e", + "type": "function", + "z": "828f5a08b0bcf89d", + "name": "Parse Content", + "func": "return {\n ...msg,\n contentHtml: msg.parseMarkdown(msg.content)\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 220, + "y": 140, + "wires": [ + [] + ] }, { - "id": "366fdac4502597e4", + "id": "e82cac62a6dcc5e2", + "type": "subflow:ae4739904e91e32d", + "z": "828f5a08b0bcf89d", + "name": "", + "x": 250, + "y": 100, + "wires": [ + [ + "e935f75b3e48ad5e" + ] + ] + }, + { + "id": "880a67537dd0efe3", "type": "provide-import-fn", - "z": "3fb1b07be44ed756", + "z": "87f7528a5c81b545", "name": "", - "x": 370, - "y": 580, + "x": 290, + "y": 200, "wires": [ [ - "f58a612cea662f7f" + "6bedf6b16eb7796b" ] ] }, { - "id": "f58a612cea662f7f", + "id": "457ddbfd4780ea1d", "type": "function", - "z": "3fb1b07be44ed756", + "z": "87f7528a5c81b545", "name": "Named Imports", - "func": "// List of modules\nconst toImport = [\n 'sse.js',\n \"node:events\"\n];\n\n;(async () => {\n try {\n const imported = Object.fromEntries(\n await Promise.all(\n toImport.map(\n async it => [it, await msg.import(it)]\n )\n )\n );\n\n node.send({...msg, namedImports: imported});\n } \n catch (e) {\n node.error(e);\n }\n})();\n", + "func": "\n;(async () => {\n try {\n const importedModules = Object.fromEntries(\n await Promise.all(\n msg.moduleSpecs.map(async spec => {\n const moduleNamepsace = await msg.import(spec.moduleName);\n\n const importedModule = Object.fromEntries(\n [\n ...(spec.defaultExport ? [{name: \"default\", alias: \"default\"}] : []),\n ...(spec.namedExports ?? Object.keys(moduleNamepsace).map(k => ({name: k, alias: k})))\n ].map(\n ({name, alias}) => [alias, moduleNamepsace[name]]\n )\n )\n\n return [spec.key, importedModule];\n })\n )\n );\n\n node.send({...msg, importedModules});\n } \n catch (e) {\n node.error(e.stack);\n }\n})();\n", "outputs": 1, "timeout": 0, "noerr": 0, @@ -7820,153 +8438,144 @@ "module": "sse.js" } ], - "x": 620, - "y": 580, + "x": 820, + "y": 560, "wires": [ - [ - "3163545a452b8023" - ] + [] ] }, { - "id": "3163545a452b8023", + "id": "6bedf6b16eb7796b", "type": "function", - "z": "3fb1b07be44ed756", - "name": "function 5", - "func": "const {\"sse.js\": { SSE }} = msg.namedImports;\nconst { Event } = msg.global;\n\nclass CustomEvent extends Event { \n constructor(message, data) {\n super(message, data)\n this.detail = data?.detail\n }\n}\n\nmsg.global.CustomEvent = CustomEvent;\ntry {\n const r = SSE();\n msg.r = r;\n return msg;\n}\ncatch (e) {\n node.error(e);\n node.error(e.stack);\n}\n\n// return {\n// ...msg,\n// scriptglobal: global,\n// Event: global.Event,\n// globalEvent: msg.global.Event\n// }", + "z": "87f7528a5c81b545", + "name": "module-alias", + "func": "// Copied from: https://github.com/ilearnio/module-alias/blob/dev/index.js\nconst nodePath = await msg.import('path')\n\nconst modulePaths = []\nconst moduleAliases = {}\nconst moduleAliasNames = []\n\nfunction isPathMatchesAlias(path, alias) {\n // Matching /^alias(\\/|$)/\n if (path.indexOf(alias) === 0) {\n if (path.length === alias.length) return true\n if (path[alias.length] === '/') return true\n }\n\n return false\n}\n\nconst init = async () => {\n const Module = await msg.import('node:module')\n\n const oldNodeModulePaths = Module._nodeModulePaths\n Module._nodeModulePaths = function (from) {\n let paths = oldNodeModulePaths.call(this, from)\n\n // Only include the module path for top-level modules\n // that were not installed:\n if (from.indexOf('node_modules') === -1) {\n paths = modulePaths.concat(paths)\n }\n\n return paths\n }\n\n const oldResolveFilename = Module._resolveFilename\n Module._resolveFilename = function (request, parentModule, isMain, options) {\n for (let i = moduleAliasNames.length; i-- > 0;) {\n const alias = moduleAliasNames[i]\n if (isPathMatchesAlias(request, alias)) {\n let aliasTarget = moduleAliases[alias]\n // Custom function handler\n if (typeof moduleAliases[alias] === 'function') {\n const fromPath = parentModule.filename\n aliasTarget = moduleAliases[alias](fromPath, request, alias)\n if (!aliasTarget || typeof aliasTarget !== 'string') {\n throw new Error('[module-alias] Expecting custom handler function to return path.')\n }\n }\n request = nodePath.join(aliasTarget, request.substr(alias.length))\n // Only use the first match\n break\n }\n }\n\n return oldResolveFilename.call(this, request, parentModule, isMain, options)\n }\n};\n\nfunction addPathHelper(path, targetArray) {\n path = nodePath.normalize(path)\n if (targetArray && targetArray.indexOf(path) === -1) {\n targetArray.unshift(path)\n }\n}\n\nfunction getMainModule() {\n return msg.global.require.main?._simulateRepl ? undefined : msg.global.require.main\n}\n\nfunction addPath(path) {\n let parent\n path = nodePath.normalize(path)\n\n if (modulePaths.indexOf(path) === -1) {\n modulePaths.push(path)\n // Enable the search path for the current top-level module\n const mainModule = getMainModule()\n if (mainModule) {\n addPathHelper(path, mainModule.paths)\n }\n parent = msg.global.module.parent\n\n // Also modify the paths of the module that was used to load the\n // app-module-paths module and all of it's parents\n while (parent && parent !== mainModule) {\n addPathHelper(path, parent.paths)\n parent = parent.parent\n }\n }\n}\n\n(async () => {\n try {\n // if we haven't added our data module yet\n if (!global.get(\"InstallModules:DataModuleAliased\")) {\n // do so now\n // first, patch node's module\n await init();\n // now we can add our path\n addPath(`/data`);\n // we've now added our data path\n global.set(\"InstallModules:DataModuleAliased\", true);\n }\n \n // forward our message\n node.send(msg);\n }\n catch (e) {\n node.error(e);\n }\n})();\n\nreturn;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 650, - "y": 500, + "x": 410, + "y": 280, "wires": [ [ - "f4e0940a4675e15a" + "df49aa776ec39a20" ] ] }, { - "id": "f4e0940a4675e15a", - "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 9", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 770, - "y": 460, - "wires": [] - }, - { - "id": "d5dd065101ef890a", + "id": "9989cd73c1728ba4", "type": "provide-global", - "z": "3fb1b07be44ed756", + "z": "87f7528a5c81b545", "name": "", - "x": 360, - "y": 620, + "x": 280, + "y": 160, "wires": [ [ - "366fdac4502597e4" + "880a67537dd0efe3" ] ] }, { - "id": "4a5b440f0562c4c5", - "type": "inject", - "z": "3fb1b07be44ed756", - "name": "", - "props": [ - { - "p": "payload" - }, - { - "p": "topic", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "", - "payloadType": "date", - "x": 160, - "y": 580, + "id": "df49aa776ec39a20", + "type": "function", + "z": "87f7528a5c81b545", + "name": "Get modules to install", + "func": "const cachedInstalls = global.get(\"InstallModules:CachedInstalls\") || [];\n\nconst toInstall = msg.moduleSpecs.map(spec => {\n // split name\n const splitName = spec.moduleName.split('/');\n // construct module name based on first character\n switch(splitName[0][0]) {\n case '/':\n // ignore files and directories\n return;\n case '.':\n // ignore files and directories\n return;\n case '@':\n // return org module\n return splitName.slice(0, 1).join('/');\n default:\n // return top-level module\n return splitName[0];\n }\n}).filter(it => it && !cachedInstalls.includes(it));\n\nglobal.set(\"InstallModules:CachedInstalls\", [...cachedInstalls, ...toInstall]);\n\n// return our modules to install\nreturn {\n ...msg,\n toInstall\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 440, + "y": 360, "wires": [ [ - "d5dd065101ef890a" + "becc084ee991baaf" ] ] }, { - "id": "370b802881cc5a5b", + "id": "e98dae970d7540c6", "type": "function", - "z": "3fb1b07be44ed756", - "name": "Send chat to model", - "func": "msg['genai-llama-cpp-llava'] = {\n payload: {\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful chat bot that will perform any requested tasks to the best of your ability.\"\n },\n ...msg.chat.history.map(it => ({\n role: it.role,\n content: it.content\n }))\n ],\n \"temperature\": 0.7,\n \"stop\": null,\n \"stream\": true\n }\n}\nreturn msg;\n", + "z": "87f7528a5c81b545", + "name": "Get modules", + "func": "// List of modules\nconst toImport = env.get(\"Modules\") || msg.modules || [];\n\nmsg.moduleSpecs = toImport.map(module => {\n // create module spec\n const moduleSpec = {\n defaultExport: true,\n namedExports: undefined,\n ...(typeof module === \"string\" ? { moduleName: module } : {\n ...module,\n namedExports: module.namedExports.map(\n named => typeof named === \"string\" ? {\n name: named,\n alias: named\n } : named\n )\n })\n };\n moduleSpec.key = module.key ?? moduleSpec.moduleName;\n return moduleSpec;\n});\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 310, + "x": 210, "y": 100, "wires": [ [ - "d33cede612c96641" + "9989cd73c1728ba4" ] ] }, { - "id": "d33cede612c96641", - "type": "subflow:6d317c39edd7ba27", - "z": "3fb1b07be44ed756", - "name": "localhost-sse", - "env": [ - { - "name": "Id", - "value": "localhost-sse", - "type": "str" - }, + "id": "44dc42cb66468495", + "type": "subflow:d5c30c295cb6b7bc", + "z": "87f7528a5c81b545", + "name": "", + "x": 420, + "y": 520, + "wires": [ + [ + "5ef12c46bbd7a294" + ] + ] + }, + { + "id": "5ef12c46bbd7a294", + "type": "switch", + "z": "87f7528a5c81b545", + "name": "Command action", + "property": "action", + "propertyType": "msg", + "rules": [ { - "name": "Url", - "value": "http://host.docker.internal:8091/sse", - "type": "str" + "t": "eq", + "v": "command-stdout", + "vt": "str" }, { - "name": "options", - "value": "{\"method\": \"POST\"}", - "type": "json" + "t": "eq", + "v": "command-stderr", + "vt": "str" }, { - "name": "Options", - "value": "{\"method\":\"POST\"}", - "type": "json" + "t": "eq", + "v": "command-exit", + "vt": "str" } ], - "x": 570, - "y": 120, + "checkall": "true", + "repair": false, + "outputs": 3, + "x": 430, + "y": 580, "wires": [ [ - "453833904710992b" + "d66301aee1d76d87" + ], + [ + "0a7620bc1dd07e51" + ], + [ + "c26e5607bec3a41a" ] ] }, { - "id": "453833904710992b", + "id": "0a7620bc1dd07e51", "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 11", + "z": "87f7528a5c81b545", + "name": "Install modules error", "active": true, "tosidebar": true, "console": false, @@ -7975,50 +8584,46 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 560, - "y": 160, + "x": 440, + "y": 680, "wires": [] }, { - "id": "e5399fe826058b29", - "type": "subflow:6d317c39edd7ba27", - "z": "3fb1b07be44ed756", - "name": "localhost-openai", - "env": [ - { - "name": "Id", - "value": "localhost-openai", - "type": "str" - }, + "id": "c26e5607bec3a41a", + "type": "switch", + "z": "87f7528a5c81b545", + "name": "If successful", + "property": "msg.code", + "propertyType": "jsonata", + "rules": [ { - "name": "Url", - "value": "http://host.docker.internal:8080/v1/chat/completions", - "type": "str" + "t": "eq", + "v": "0", + "vt": "num" }, { - "name": "Options", - "value": "{\"method\":\"POST\",\"headers\":{\"Content-Type\":\"application/json\"}}", - "type": "json" - }, - { - "name": "options", - "value": "{\"method\": \"POST\"}", - "type": "json" + "t": "else" } ], - "x": 760, - "y": 60, + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 410, + "y": 740, "wires": [ [ - "4912a5fe5cc3d7cd" + "fef6f985a19ce44e" + ], + [ + "0a7620bc1dd07e51" ] ] }, { - "id": "4912a5fe5cc3d7cd", + "id": "d66301aee1d76d87", "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 12", + "z": "87f7528a5c81b545", + "name": "Install modules stdout", "active": true, "tosidebar": true, "console": false, @@ -8027,50 +8632,152 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 780, - "y": 100, + "x": 440, + "y": 640, "wires": [] }, { - "id": "6db72e1f1342ce1d", - "type": "subflow:6d317c39edd7ba27", - "z": "3fb1b07be44ed756", - "name": "genai-llama-cpp-llava", - "env": [ + "id": "88d2db1e34559f1c", + "type": "function", + "z": "87f7528a5c81b545", + "name": "Install modules", + "func": "\nreturn {\n ...msg,\n command: `cd /data && npm install ${msg.toInstall.join(' ')}`,\n mode: \"exec\"\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 420, + "y": 480, + "wires": [ + [ + "44dc42cb66468495" + ] + ] + }, + { + "id": "becc084ee991baaf", + "type": "switch", + "z": "87f7528a5c81b545", + "name": "If modules to install", + "property": "$count(msg.toInstall)", + "propertyType": "jsonata", + "rules": [ { - "name": "Id", - "value": "genai-llama-cpp-llava", - "type": "str" + "t": "gte", + "v": "1", + "vt": "num" }, { - "name": "Url", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava/v1/chat/completions", - "type": "str" - }, + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 430, + "y": 400, + "wires": [ + [ + "88d2db1e34559f1c" + ], + [ + "457ddbfd4780ea1d" + ] + ] + }, + { + "id": "fef6f985a19ce44e", + "type": "function", + "z": "87f7528a5c81b545", + "name": "Finish install", + "func": "msg = msg.msgIn;\n\nconst cachedInstalls = global.get(\"InstallModules:CachedInstalls\") || [];\n\nglobal.set(\"InstallModules:CachedInstalls\", [...cachedInstalls, ...msg.toInstall]);\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 410, + "y": 780, + "wires": [ + [ + "457ddbfd4780ea1d" + ] + ] + }, + { + "id": "4432567301785438", + "type": "subflow:87f7528a5c81b545", + "z": "d5c98b48f9d2d77f", + "name": "", + "env": [ { - "name": "Options", - "value": "{\"method\":\"POST\",\"headers\":{\"Content-Type\":\"application/json\"}}", + "name": "Modules", + "value": "[\"html-entities\"]", "type": "json" + } + ], + "x": 230, + "y": 120, + "wires": [ + [ + "e5c508b6228990f4" + ] + ] + }, + { + "id": "e5c508b6228990f4", + "type": "function", + "z": "d5c98b48f9d2d77f", + "name": "Decode", + "func": "const { decode } = msg.importedModules['html-entities'];\n\nmsg.decodedContent = decode(msg.content);\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 200, + "y": 180, + "wires": [ + [] + ] + }, + { + "id": "c0c36621780669a4", + "type": "subflow:a59054999730c251", + "z": "9e23ccbf2e0608ed", + "d": true, + "g": "0e1cb402b61eb646", + "name": "Model - openai - localhost", + "env": [ + { + "name": "Id", + "value": "openai-localhost", + "type": "str" }, { - "name": "options", - "value": "{\"method\": \"POST\"}", - "type": "json" + "name": "BaseUrl", + "value": "http://host.docker.internal:8080", + "type": "str" } ], - "x": 780, - "y": 180, + "x": 410, + "y": 520, "wires": [ [ - "eea7ca5e3d911f8d" + "45671622e142be7e" ] ] }, { - "id": "eea7ca5e3d911f8d", + "id": "948e1265a14409b8", "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 13", + "z": "9e23ccbf2e0608ed", + "g": "aaf9af66d3e39da8", + "name": "Model Errors", "active": true, "tosidebar": true, "console": false, @@ -8079,40 +8786,43 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 780, - "y": 220, + "x": 510, + "y": 720, "wires": [] }, { - "id": "53c302c1821fa9b9", - "type": "inject", - "z": "3fb1b07be44ed756", - "name": "", - "props": [ + "id": "977f9402195729c4", + "type": "subflow:a59054999730c251", + "z": "9e23ccbf2e0608ed", + "g": "0e1cb402b61eb646", + "name": "Model - genai - llama-cpp-llava", + "env": [ { - "p": "payload" + "name": "Id", + "value": "genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", + "type": "str" } ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "3", - "payloadType": "num", - "x": 1190, - "y": 440, + "x": 430, + "y": 560, "wires": [ [ - "f1e2bb90d5fcdf68" + "45671622e142be7e" ] ] }, { - "id": "d7e17a64b9a03bac", + "id": "a63ac3946c2843eb", "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 23", + "z": "9e23ccbf2e0608ed", + "d": true, + "g": "aaf9af66d3e39da8", + "name": "Model Output", "active": true, "tosidebar": true, "console": false, @@ -8121,78 +8831,5444 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 1530, - "y": 440, + "x": 520, + "y": 680, + "wires": [] + }, + { + "id": "5e149325f881f48b", + "type": "subflow:2b3efcc977e88d91", + "z": "9e23ccbf2e0608ed", + "name": "", + "env": [ + { + "name": "Url", + "value": "simple-chat", + "type": "str" + } + ], + "x": 550, + "y": 160, + "wires": [ + [ + "246a383da043e031", + "34dd380b3322dc77" + ] + ] + }, + { + "id": "8ec4c35df45a28c5", + "type": "comment", + "z": "9e23ccbf2e0608ed", + "g": "0e1cb402b61eb646", + "name": "Models", + "info": "", + "x": 350, + "y": 420, "wires": [] }, { - "id": "f1e2bb90d5fcdf68", + "id": "246a383da043e031", + "type": "subflow:74bd10ee8e354d0a", + "z": "9e23ccbf2e0608ed", + "name": "", + "x": 310, + "y": 220, + "wires": [ + [ + "c865bad2cdc088e0" + ] + ] + }, + { + "id": "b1093b3dfa80dbe3", + "type": "switch", + "z": "9e23ccbf2e0608ed", + "g": "aaf9af66d3e39da8", + "name": "Action", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "model-content", + "vt": "str" + }, + { + "t": "eq", + "v": "model-error", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 350, + "y": 700, + "wires": [ + [ + "a63ac3946c2843eb" + ], + [ + "948e1265a14409b8" + ] + ] + }, + { + "id": "8e313642e9e9049a", + "type": "inject", + "z": "9e23ccbf2e0608ed", + "name": "Start App", + "props": [ + { + "p": "timestamp", + "v": "", + "vt": "date" + }, + { + "p": "action", + "v": "history-init", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 140, + "y": 100, + "wires": [ + [ + "246a383da043e031" + ] + ] + }, + { + "id": "378e8541feaf87ec", + "type": "subflow:a59054999730c251", + "z": "9e23ccbf2e0608ed", + "d": true, + "g": "0e1cb402b61eb646", + "name": "Model - dummy sse", + "env": [ + { + "name": "Id", + "value": "dummy-sse", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal:8091", + "type": "str" + }, + { + "name": "Batch", + "value": "10", + "type": "num" + } + ], + "x": 390, + "y": 480, + "wires": [ + [ + "45671622e142be7e" + ] + ] + }, + { + "id": "45671622e142be7e", + "type": "function", + "z": "9e23ccbf2e0608ed", + "g": "0e1cb402b61eb646", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 645, + "y": 580, + "wires": [ + [ + "246a383da043e031", + "b1093b3dfa80dbe3" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "33ca3631b9af0d55", + "type": "subflow:a59054999730c251", + "z": "9e23ccbf2e0608ed", + "d": true, + "g": "0e1cb402b61eb646", + "name": "Model - genai - llama-cpp-mistral-8x", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-mistral-8x", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", + "type": "str" + } + ], + "x": 440, + "y": 600, + "wires": [ + [ + "45671622e142be7e" + ] + ] + }, + { + "id": "d9e8ec2ee480957d", + "type": "function", + "z": "9e23ccbf2e0608ed", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 205, + "y": 460, + "wires": [ + [ + "378e8541feaf87ec", + "c0c36621780669a4", + "977f9402195729c4", + "33ca3631b9af0d55" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "c865bad2cdc088e0", + "type": "function", + "z": "9e23ccbf2e0608ed", + "g": "bf3cb919a9b18a74", + "name": "System Prompt", + "func": "// Initial prompt\nconst initialPrompt = `You are a helpful chat bot that will perform any requested tasks to the best of your ability.`;\n\n// if this is an update prompt message\nif (msg.action == \"prompt-update\") {\n // update our prompt\n context.set(\"prompt\", msg.prompt);\n // that's all\n return msg;\n}\n\n// get current prompt\nlet currentPrompt = context.get(\"prompt\");\n\nif (!currentPrompt) {\n currentPrompt = initialPrompt\n context.set(\"prompt\", currentPrompt);\n}\n\nmsg.systemPrompt = currentPrompt;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 580, + "y": 320, + "wires": [ + [ + "5e149325f881f48b", + "d9e8ec2ee480957d" + ] + ] + }, + { + "id": "34dd380b3322dc77", + "type": "switch", + "z": "9e23ccbf2e0608ed", + "g": "bf3cb919a9b18a74", + "name": "If prompt action", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "regex", + "v": "^prompt-", + "vt": "str", + "case": false + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 580, + "y": 280, + "wires": [ + [ + "c865bad2cdc088e0" + ] + ] + }, + { + "id": "6b73ef72bb7e4b87", + "type": "subflow:2b3efcc977e88d91", + "z": "ec55121054ad7072", + "name": "", + "env": [ + { + "name": "Url", + "value": "admin-operator", + "type": "str" + } + ], + "x": 310, + "y": 280, + "wires": [ + [ + "e77e6ed92b6eba12" + ] + ] + }, + { + "id": "e77e6ed92b6eba12", + "type": "subflow:74bd10ee8e354d0a", + "z": "ec55121054ad7072", + "name": "Admin History", + "env": [ + { + "name": "SourceFilename", + "value": "/data/db/history-1711926907124.json", + "type": "str" + } + ], + "x": 600, + "y": 280, + "wires": [ + [ + "6b73ef72bb7e4b87", + "0a39bb73f010efd7", + "8ad28cb311d8a5c0" + ] + ] + }, + { + "id": "cd5e2c4e51717c0f", + "type": "inject", + "z": "ec55121054ad7072", + "name": "Start App", + "props": [ + { + "p": "timestamp", + "v": "", + "vt": "date" + }, + { + "p": "action", + "v": "history-init", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 140, + "y": 80, + "wires": [ + [ + "e77e6ed92b6eba12", + "d7625ef95dd891b8" + ] + ] + }, + { + "id": "0a34e1dce381f16b", + "type": "function", + "z": "ec55121054ad7072", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 205, + "y": 440, + "wires": [ + [ + "21debbaed5b57fd5", + "75d06bae12a047f9", + "a61cd1dd9aeb1256", + "9d4dbbbd2defb7fb" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "75d06bae12a047f9", + "type": "subflow:a59054999730c251", + "z": "ec55121054ad7072", + "d": true, + "g": "0bd29a38bd7fd7ee", + "name": "Model - openai - localhost", + "env": [ + { + "name": "Id", + "value": "openai-localhost", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal:8080", + "type": "str" + } + ], + "x": 410, + "y": 500, + "wires": [ + [ + "a98ec39f0f7f2c84" + ] + ] + }, + { + "id": "a61cd1dd9aeb1256", + "type": "subflow:a59054999730c251", + "z": "ec55121054ad7072", + "g": "0bd29a38bd7fd7ee", + "name": "Model - genai - llama-cpp-llava", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", + "type": "str" + } + ], + "x": 430, + "y": 540, + "wires": [ + [ + "a98ec39f0f7f2c84" + ] + ] + }, + { + "id": "12901237f1ea6884", + "type": "comment", + "z": "ec55121054ad7072", + "g": "0bd29a38bd7fd7ee", + "name": "Models", + "info": "", + "x": 350, + "y": 400, + "wires": [] + }, + { + "id": "d9e0c9a3cf18f405", + "type": "debug", + "z": "ec55121054ad7072", + "g": "7aad90c5be36eb0a", + "name": "Model Errors", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 510, + "y": 700, + "wires": [] + }, + { + "id": "4b7f0d34fcfa313d", + "type": "debug", + "z": "ec55121054ad7072", + "d": true, + "g": "7aad90c5be36eb0a", + "name": "Model Output", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 520, + "y": 660, + "wires": [] + }, + { + "id": "bbeaa9f159afdfaf", + "type": "switch", + "z": "ec55121054ad7072", + "g": "7aad90c5be36eb0a", + "name": "Action", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "model-content", + "vt": "str" + }, + { + "t": "eq", + "v": "model-error", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 350, + "y": 680, + "wires": [ + [ + "4b7f0d34fcfa313d" + ], + [ + "d9e0c9a3cf18f405" + ] + ] + }, + { + "id": "21debbaed5b57fd5", + "type": "subflow:a59054999730c251", + "z": "ec55121054ad7072", + "d": true, + "g": "0bd29a38bd7fd7ee", + "name": "Model - dummy sse", + "env": [ + { + "name": "Id", + "value": "dummy-sse", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal.local:8091", + "type": "str" + }, + { + "name": "Batch", + "value": "10", + "type": "num" + } + ], + "x": 390, + "y": 460, + "wires": [ + [ + "a98ec39f0f7f2c84" + ] + ] + }, + { + "id": "a98ec39f0f7f2c84", + "type": "function", + "z": "ec55121054ad7072", + "g": "0bd29a38bd7fd7ee", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 645, + "y": 560, + "wires": [ + [ + "e77e6ed92b6eba12", + "bbeaa9f159afdfaf", + "4de07154c6644063" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "9d4dbbbd2defb7fb", + "type": "subflow:a59054999730c251", + "z": "ec55121054ad7072", + "d": true, + "g": "0bd29a38bd7fd7ee", + "name": "Model - genai - llama-cpp-mistral-8x", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-mistral-8x", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", + "type": "str" + } + ], + "x": 440, + "y": 580, + "wires": [ + [ + "a98ec39f0f7f2c84" + ] + ] + }, + { + "id": "0a39bb73f010efd7", + "type": "function", + "z": "ec55121054ad7072", + "name": "Admin Prompt", + "func": "msg.systemPrompt = `## Mandate\n\nYou are an AI Administrator.\n\nYour mandate is to manage a collective of AI Operators in order to accomplish the goal of any requests from the User.\n\nWhen a goal is too complex or you lack the requisite abilities for you to accomplish it on your own, break the goal down into one or more smaller tasks and assign each task to an Operator.\n\nIn addition to requests from the User, Operators may also send you messages or requests. Unlike requests from the User, you may choose whether and how to respond to messages and requests from Operators.\n\nEvery response must conclude with an tag.\n\n## Commands\n\nManage the collective of Operators using the Operator API. Send commands to the API as a JSON object wrapped in tags. Messages from operators will be given to you wrapped in tags.\n\n## Operator API Docs\n\n### Create an Operator\n\n\\`\\`\\`\n\n{\n \"method\": \"POST\",\n \"path\": \"/operators\",\n \"body\": {\n \"id\": \"06f86c9a-1fe6-4c74-8939-30e64cb1edbb\",\n \"name\": \"My First Operator\"\n }\n}\n\n\\`\\`\\`\n\n### Message an Operator\n\n\\`\\`\\`\n\n{\n \"method\": \"POST\",\n \"path\": \"/operators/06f86c9a-1fe6-4c74-8939-30e64cb1edbb/messages\",\n \"body\": {\n \"content\": \"Sign up for an account at the following website: https://www.example.com\"\n }\n}\n\n\\`\\`\\`\n\n### Delete an Operator\n\n\\`\\`\\`\n\n{\n \"method\": \"DELETE\",\n \"path\": \"/operators/06f86c9a-1fe6-4c74-8939-30e64cb1edbb\",\n \"body\": {}\n}\n\n\\`\\`\\`\n\n\n`;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 140, + "y": 400, + "wires": [ + [ + "0a34e1dce381f16b" + ] + ] + }, + { + "id": "4de07154c6644063", + "type": "subflow:f19bc65164444615", + "z": "ec55121054ad7072", + "name": "Operator Histories", + "env": [ + { + "name": "Factory Id", + "value": "operators", + "type": "str" + } + ], + "x": 890, + "y": 600, + "wires": [ + [ + "94206e52b6f654bd", + "941ab8d26359e8b3" + ] + ] + }, + { + "id": "3f33490320859b09", + "type": "switch", + "z": "ec55121054ad7072", + "name": "Response tag", + "property": "tag", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "operator-api", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 880, + "y": 240, + "wires": [ + [ + "1ec42373eea9f5ff" + ] + ] + }, + { + "id": "1ec42373eea9f5ff", + "type": "function", + "z": "ec55121054ad7072", + "name": "Parse operator API", + "func": "let apiMsg;\ntry {\n apiMsg = JSON.parse(msg.content);\n}\ncatch (e) {\n throw new Error(`Error parsing operator AI call: ${msg.content} - ${e}`);\n}\n\nreturn {\n ...msg,\n ...apiMsg\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 890, + "y": 340, + "wires": [ + [ + "17e432a11037e949" + ] + ] + }, + { + "id": "17e432a11037e949", + "type": "switch", + "z": "ec55121054ad7072", + "name": "Operator API - Path", + "property": "path", + "propertyType": "msg", + "rules": [ + { + "t": "regex", + "v": "^/operators(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})?$", + "vt": "str", + "case": true + }, + { + "t": "regex", + "v": "^/operators/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/messages$", + "vt": "str", + "case": true + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 890, + "y": 440, + "wires": [ + [ + "1e437fb36b5c0ea1" + ], + [ + "da042c7a27dcbd9f" + ] + ], + "outputLabels": [ + "Operators", + "Operators/Messages" + ] + }, + { + "id": "1e437fb36b5c0ea1", + "type": "switch", + "z": "ec55121054ad7072", + "name": "Operators Method", + "property": "method", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "POST", + "vt": "str" + }, + { + "t": "eq", + "v": "DELETE", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 1110, + "y": 420, + "wires": [ + [ + "2c04b0bb076a5230" + ], + [] + ] + }, + { + "id": "2c04b0bb076a5230", + "type": "function", + "z": "ec55121054ad7072", + "name": "Create operator", + "func": "msg = {\n action: \"prog-history-init\",\n historyId: msg.body?.id\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1380, + "y": 360, + "wires": [ + [ + "40557c67b6ce1c09", + "1554a43a221611d6" + ] + ] + }, + { + "id": "da042c7a27dcbd9f", + "type": "switch", + "z": "ec55121054ad7072", + "name": "Operators/Messages Method", + "property": "method", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "POST", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 1140, + "y": 460, + "wires": [ + [ + "2d1212f366ac2dec" + ] + ] + }, + { + "id": "a2eae6bb6671163b", + "type": "function", + "z": "ec55121054ad7072", + "name": "Add Admin Message", + "func": "msg = {\n action: \"prog-history-add-entry\",\n entry: {\n role: \"user\",\n content: msg.createAdminMessagePrompt(msg.body?.content)\n },\n id: msg.path.split('/')[2]\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1400, + "y": 540, + "wires": [ + [ + "4de07154c6644063", + "dd64967ec7cb7b3d" + ] + ] + }, + { + "id": "2d1212f366ac2dec", + "type": "function", + "z": "ec55121054ad7072", + "name": "Admin message prompt template", + "func": "msg.createAdminMessagePrompt = message => {\n return `${message}`;\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1440, + "y": 500, + "wires": [ + [ + "a2eae6bb6671163b" + ] + ] + }, + { + "id": "ef526c2a80f31eb3", + "type": "function", + "z": "ec55121054ad7072", + "name": "Operator Prompt", + "func": "msg.systemPrompt = `## Mandate\n\nYou are an AI Operator.\n\nYour mandate is to perform any tasks requested of you by your AI Administrator to the best of your ability in order to accomplish the overarching goal of the User.\n\nWhen a task is too complex or you lack the requisite abilities for you to accomplish it on your own, you may ask the Administrator to break the task down into one or more smaller tasks and assign them to Operators.\n\nThis conversation is a complete record of every action you took in performing the task.\n\nEnd all responses with an tag.\n\n## Commands\n\nYou may message the Administrator by wrapping your message in tags. Messages from the Administrator will be given to you wrapped in tags.\n`;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 130, + "y": 480, + "wires": [ + [ + "0a34e1dce381f16b" + ] + ] + }, + { + "id": "87b70bd29575e8b4", + "type": "function", + "z": "ec55121054ad7072", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 265, + "y": 920, + "wires": [ + [ + "ef526c2a80f31eb3" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "40557c67b6ce1c09", + "type": "function", + "z": "ec55121054ad7072", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1695, + "y": 540, + "wires": [ + [ + "4de07154c6644063" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "a073258f226718b6", + "type": "switch", + "z": "ec55121054ad7072", + "name": "Response tag", + "property": "tag", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "operator-message", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 880, + "y": 760, + "wires": [ + [ + "2d730859f47f1ceb" + ] + ] + }, + { + "id": "94206e52b6f654bd", + "type": "function", + "z": "ec55121054ad7072", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 715, + "y": 680, + "wires": [ + [ + "87b70bd29575e8b4" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "8ad28cb311d8a5c0", + "type": "subflow:240cc03734c17fa7", + "z": "ec55121054ad7072", + "name": "Parse Admin Response", + "x": 900, + "y": 160, + "wires": [ + [ + "3f33490320859b09" + ] + ] + }, + { + "id": "941ab8d26359e8b3", + "type": "subflow:240cc03734c17fa7", + "z": "ec55121054ad7072", + "name": "Parse Operator Response", + "x": 910, + "y": 680, + "wires": [ + [ + "a073258f226718b6" + ] + ] + }, + { + "id": "2d730859f47f1ceb", + "type": "function", + "z": "ec55121054ad7072", + "name": "Operator message prompt template", + "func": "msg.createOperatorMessagePrompt = (id, message) => {\n return `${message}`;\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1420, + "y": 700, + "wires": [ + [ + "134cfbd5d2b56837" + ] + ] + }, + { + "id": "134cfbd5d2b56837", + "type": "function", + "z": "ec55121054ad7072", + "name": "Add Operator Message", + "func": "msg = {\n action: \"history-add-entry\",\n entry: {\n role: \"user\",\n content: msg.createOperatorMessagePrompt(msg.agentId, msg.content)\n }\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1390, + "y": 740, + "wires": [ + [ + "13c990f21a453c5a", + "e7f4585c8ca44732" + ] + ] + }, + { + "id": "d2c9ca4a42af3ba9", + "type": "function", + "z": "ec55121054ad7072", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 725, + "y": 400, + "wires": [ + [ + "e77e6ed92b6eba12" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "13c990f21a453c5a", + "type": "function", + "z": "ec55121054ad7072", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1615, + "y": 740, + "wires": [ + [ + "d2c9ca4a42af3ba9" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "d7625ef95dd891b8", + "type": "function", + "z": "ec55121054ad7072", + "name": "Init Operator Histories", + "func": "\nreturn {\n action: \"prog-factory-init\"\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 420, + "y": 100, + "wires": [ + [ + "b6cc1b3167117b16" + ] + ] + }, + { + "id": "1554a43a221611d6", + "type": "debug", + "z": "ec55121054ad7072", + "name": "Creating Operator", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1650, + "y": 320, + "wires": [] + }, + { + "id": "dd64967ec7cb7b3d", + "type": "debug", + "z": "ec55121054ad7072", + "name": "Sending Admin Message", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1670, + "y": 600, + "wires": [] + }, + { + "id": "e7f4585c8ca44732", + "type": "debug", + "z": "ec55121054ad7072", + "name": "Sending Operator Message", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1680, + "y": 800, + "wires": [] + }, + { + "id": "b75f0d8130661559", + "type": "function", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "function 1", + "func": "return { sseJs, nodeFetch, async }", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "sseJs", + "module": "sse.js" + }, + { + "var": "async", + "module": "async" + }, + { + "var": "nodeFetch", + "module": "node-fetch" + } + ], + "x": 1080, + "y": 360, + "wires": [ + [ + "ea2d35fce99de4ae" + ] + ] + }, + { + "id": "26a114fc27cd90b0", + "type": "inject", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 900, + "y": 340, + "wires": [ + [ + "b75f0d8130661559" + ] + ] + }, + { + "id": "ea2d35fce99de4ae", + "type": "debug", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "debug 5", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1250, + "y": 380, + "wires": [] + }, + { + "id": "8f75c3504c3dbc5f", + "type": "function", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "Install dependencies", + "func": "// List of NPM modules\nconst toInstall = [\n 'sse.js'\n]\n\nconst { exec } = childProcess;\n\nconst run = async (cmd) => {\n const child = exec(cmd, (err) => {\n if (err) console.error(err);\n });\n await new Promise((resolve) => child.on('close', resolve));\n};\n\nawait Promise.all(toInstall.map(it => run(`npm install ${it}`)));\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "childProcess", + "module": "child_process" + } + ], + "x": 940, + "y": 420, + "wires": [ + [] + ] + }, + { + "id": "e22d75a202b3a7d9", + "type": "function", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "function 2", + "func": "//throw new Error(\"This crashes Node-RED!\");\n\n(async () => {\n try {\n const sse = await (global.get(\"dynamicallyImport\"))(\"sse.js\");\n node.send({sse});\n node.done();\n }\n catch (e) {\n node.send({ e });\n }\n})();\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1160, + "y": 460, + "wires": [ + [ + "18e60cf6d75b5c02" + ] + ] + }, + { + "id": "233b190c4bba2abc", + "type": "inject", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 1000, + "y": 460, + "wires": [ + [ + "e22d75a202b3a7d9" + ] + ] + }, + { + "id": "18e60cf6d75b5c02", + "type": "debug", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "debug 6", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1320, + "y": 460, + "wires": [] + }, + { + "id": "366fdac4502597e4", + "type": "provide-import-fn", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "x": 1120, + "y": 600, + "wires": [ + [ + "f58a612cea662f7f" + ] + ] + }, + { + "id": "f58a612cea662f7f", + "type": "function", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "Named Imports", + "func": "// List of modules\nconst toImport = [\n 'sse.js',\n \"node:events\"\n];\n\n;(async () => {\n try {\n const imported = Object.fromEntries(\n await Promise.all(\n toImport.map(\n async it => [it, await msg.import(it)]\n )\n )\n );\n\n node.send({...msg, namedImports: imported});\n } \n catch (e) {\n node.error(e);\n }\n})();\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "sseJs", + "module": "sse.js" + } + ], + "x": 1370, + "y": 600, + "wires": [ + [ + "3163545a452b8023" + ] + ] + }, + { + "id": "3163545a452b8023", + "type": "function", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "function 5", + "func": "const {\"sse.js\": { SSE }} = msg.namedImports;\nconst { Event } = msg.global;\n\nclass CustomEvent extends Event { \n constructor(message, data) {\n super(message, data)\n this.detail = data?.detail\n }\n}\n\nmsg.global.CustomEvent = CustomEvent;\ntry {\n const r = SSE();\n msg.r = r;\n return msg;\n}\ncatch (e) {\n node.error(e);\n node.error(e.stack);\n}\n\n// return {\n// ...msg,\n// scriptglobal: global,\n// Event: global.Event,\n// globalEvent: msg.global.Event\n// }", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1400, + "y": 520, + "wires": [ + [ + "f4e0940a4675e15a" + ] + ] + }, + { + "id": "f4e0940a4675e15a", + "type": "debug", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "debug 9", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1520, + "y": 480, + "wires": [] + }, + { + "id": "d5dd065101ef890a", + "type": "provide-global", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "x": 1110, + "y": 640, + "wires": [ + [ + "366fdac4502597e4" + ] + ] + }, + { + "id": "4a5b440f0562c4c5", + "type": "inject", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 910, + "y": 600, + "wires": [ + [ + "d5dd065101ef890a" + ] + ] + }, + { + "id": "370b802881cc5a5b", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "Send chat to model", + "func": "msg['genai-llama-cpp-llava'] = {\n payload: {\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful chat bot that will perform any requested tasks to the best of your ability.\"\n },\n ...msg.chat.history.map(it => ({\n role: it.role,\n content: it.content\n }))\n ],\n \"temperature\": 0.7,\n \"stop\": null,\n \"stream\": true\n }\n}\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 310, + "y": 100, + "wires": [ + [ + "d33cede612c96641" + ] + ] + }, + { + "id": "d33cede612c96641", + "type": "subflow:6d317c39edd7ba27", + "z": "3fb1b07be44ed756", + "name": "localhost-sse", + "env": [ + { + "name": "Id", + "value": "localhost-sse", + "type": "str" + }, + { + "name": "Url", + "value": "http://host.docker.internal:8091/sse", + "type": "str" + }, + { + "name": "options", + "value": "{\"method\": \"POST\"}", + "type": "json" + }, + { + "name": "Options", + "value": "{\"method\":\"POST\"}", + "type": "json" + } + ], + "x": 570, + "y": 120, + "wires": [ + [ + "453833904710992b" + ] + ] + }, + { + "id": "453833904710992b", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 11", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 560, + "y": 160, + "wires": [] + }, + { + "id": "e5399fe826058b29", + "type": "subflow:6d317c39edd7ba27", + "z": "3fb1b07be44ed756", + "name": "localhost-openai", + "env": [ + { + "name": "Id", + "value": "localhost-openai", + "type": "str" + }, + { + "name": "Url", + "value": "http://host.docker.internal:8080/v1/chat/completions", + "type": "str" + }, + { + "name": "Options", + "value": "{\"method\":\"POST\",\"headers\":{\"Content-Type\":\"application/json\"}}", + "type": "json" + }, + { + "name": "options", + "value": "{\"method\": \"POST\"}", + "type": "json" + } + ], + "x": 760, + "y": 60, + "wires": [ + [ + "4912a5fe5cc3d7cd" + ] + ] + }, + { + "id": "4912a5fe5cc3d7cd", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 12", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 780, + "y": 100, + "wires": [] + }, + { + "id": "6db72e1f1342ce1d", + "type": "subflow:6d317c39edd7ba27", + "z": "3fb1b07be44ed756", + "name": "genai-llama-cpp-llava", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "Url", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava/v1/chat/completions", + "type": "str" + }, + { + "name": "Options", + "value": "{\"method\":\"POST\",\"headers\":{\"Content-Type\":\"application/json\"}}", + "type": "json" + }, + { + "name": "options", + "value": "{\"method\": \"POST\"}", + "type": "json" + } + ], + "x": 780, + "y": 180, + "wires": [ + [ + "eea7ca5e3d911f8d" + ] + ] + }, + { + "id": "eea7ca5e3d911f8d", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 13", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 780, + "y": 220, + "wires": [] + }, + { + "id": "53c302c1821fa9b9", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "3", + "payloadType": "num", + "x": 1190, + "y": 240, + "wires": [ + [ + "f1e2bb90d5fcdf68" + ] + ] + }, + { + "id": "d7e17a64b9a03bac", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 23", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1530, + "y": 240, + "wires": [] + }, + { + "id": "f1e2bb90d5fcdf68", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 7", + "func": "\nreturn {fs};", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "fs", + "module": "fs" + } + ], + "x": 1340, + "y": 240, + "wires": [ + [ + "d7e17a64b9a03bac" + ] + ] + }, + { + "id": "23cc77d254e27371", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "Init Vector Store", + "func": "const { HNSWLib } = langchainCommunityVectorstoresHnswlib;\nconst { OpenAIEmbeddings } = langchainOpenai;\n\nconst vectorStore = await HNSWLib.fromTexts(\n [\"Hello world\", \"Bye bye\", \"hello nice world\"],\n [{ id: 2 }, { id: 1 }, { id: 3 }],\n new OpenAIEmbeddings()\n);\n\nconst resultOne = await vectorStore.similaritySearch(\"hello world\", 1);\nconsole.log(resultOne);\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "langchainCommunityVectorstoresHnswlib", + "module": "@langchain/community/vectorstores/hnswlib" + }, + { + "var": "langchainOpenai", + "module": "@langchain/openai" + } + ], + "x": 1500, + "y": 120, + "wires": [ + [] + ] + }, + { + "id": "9f7595e19d34fca3", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "Provide OpenAIEmbeddings", + "func": "msg.OpenAIEmbeddings = class {\n constructor () {\n \n }\n}\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1400, + "y": 60, + "wires": [ + [] + ] + }, + { + "id": "78e2f994d1fbe874", + "type": "subflow:b9a9b43a3594c357", + "z": "3fb1b07be44ed756", + "name": "Docker Run", + "env": [ + { + "name": "Container Name", + "value": "create-directory-01", + "type": "str" + }, + { + "name": "Command", + "value": "", + "type": "str" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + }, + { + "name": "Commit", + "value": "true", + "type": "bool" + }, + { + "name": "Response Mode", + "value": "full", + "type": "str" + } + ], + "x": 190, + "y": 840, + "wires": [ + [ + "7d1f6f8b055c1f9c", + "2b9295527ed600a5" + ] + ] + }, + { + "id": "b1b7a5e444690a58", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 100, + "y": 740, + "wires": [ + [ + "b6d1a9d992b0d137" + ] + ] + }, + { + "id": "7d1f6f8b055c1f9c", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "Create directory", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 200, + "y": 880, + "wires": [] + }, + { + "id": "01a08cd51c7a1f8a", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 240, + "y": 980, + "wires": [ + [ + "bd126ff279ae3415" + ] + ] + }, + { + "id": "f8f3094def8eec89", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "3fb1b07be44ed756", + "name": "", + "x": 680, + "y": 980, + "wires": [ + [ + "60dae42d0ea16a38" + ] + ] + }, + { + "id": "bd126ff279ae3415", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 20", + "func": "msg.url = `http://docker-engine-api:2375/containers/5efd360faabae42c09c97845e52f9709aca2519e923204596c14225aa3c454ca/exec`;\nmsg.method = \"POST\"\nmsg.payload = {\n AttachStdout: true,\n AttachStderr: true,\n Tty: true,\n Cmd: [\"bash\", \"-c\", \"for i in {1..10}; do echo \\\"Exec message\\\"; sleep 1; done\"]\n}\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 450, + "y": 980, + "wires": [ + [ + "f8f3094def8eec89" + ] + ] + }, + { + "id": "60dae42d0ea16a38", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 30", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 860, + "y": 980, + "wires": [] + }, + { + "id": "80486c2b2c4ca875", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 240, + "y": 1040, + "wires": [ + [ + "1f5e501e97cf0503" + ] + ] + }, + { + "id": "539ef7fa2e766b13", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "3fb1b07be44ed756", + "name": "", + "x": 680, + "y": 1040, + "wires": [ + [ + "6f9623b787e73b13" + ] + ] + }, + { + "id": "1f5e501e97cf0503", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 22", + "func": "msg.url = `http://docker-engine-api:2375/exec/b6ecfcc454087d84e46e8f1fec6ba1bf8701322f8146393bdb102d6859283130/start`;\nmsg.method = \"POST\"\nmsg.payload = {\n Detach: false,\n Tty: false\n}\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 450, + "y": 1040, + "wires": [ + [ + "539ef7fa2e766b13" + ] + ] + }, + { + "id": "6f9623b787e73b13", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 31", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 860, + "y": 1040, + "wires": [] + }, + { + "id": "6c89094abec8d0f3", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 240, + "y": 1100, + "wires": [ + [ + "52f3d0c6089039ae" + ] + ] + }, + { + "id": "fcd58b089d8db6fc", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "3fb1b07be44ed756", + "name": "", + "x": 680, + "y": 1100, + "wires": [ + [ + "b2f29c3b2edf6a54" + ] + ] + }, + { + "id": "52f3d0c6089039ae", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 23", + "func": "msg.url = `http://docker-engine-api:2375/exec/7cdfd069b582e2d85945fc8c9f1d9c080b11a016e1611067c74c969aca7b6b1f/start`;\nmsg.method = \"POST\"\nmsg.payload = {}\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 450, + "y": 1100, + "wires": [ + [ + "fcd58b089d8db6fc" + ] + ] + }, + { + "id": "b2f29c3b2edf6a54", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 32", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 860, + "y": 1100, + "wires": [] + }, + { + "id": "54e8be0ccd77b333", + "type": "subflow:d5c30c295cb6b7bc", + "z": "3fb1b07be44ed756", + "name": "", + "x": 360, + "y": 700, + "wires": [ + [ + "ef618dafdea24bf5" + ] + ] + }, + { + "id": "a8857b2bfb37fa1d", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 24", + "func": "\nreturn {\n mode: \"spawn\",\n command: \"ls -la /data\"\n};", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 180, + "y": 700, + "wires": [ + [ + "54e8be0ccd77b333" + ] + ] + }, + { + "id": "dde91c17372b1fe1", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 160, + "y": 660, + "wires": [ + [ + "a8857b2bfb37fa1d" + ] + ] + }, + { + "id": "ef618dafdea24bf5", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 33", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 530, + "y": 680, + "wires": [] + }, + { + "id": "b6d1a9d992b0d137", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "Create directory", + "func": "\nreturn {\n command: [\"bash\", \"-c\", 'mkdir /root/scripts']\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 200, + "y": 800, + "wires": [ + [ + "78e2f994d1fbe874" + ] + ] + }, + { + "id": "2b9295527ed600a5", + "type": "switch", + "z": "3fb1b07be44ed756", + "name": "If success", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "docker-done", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 400, + "y": 760, + "wires": [ + [ + "8335323195e55550" + ] + ] + }, + { + "id": "8335323195e55550", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "Create script", + "func": "\nreturn {\n command: [\n \"bash\",\n \"-c\",\n `cat << 'EOF' > /root/scripts/script-01.sh ${\n`#!/bin/bash\n\necho \"Script start\";\n\nls -la\n\necho \"Script end\";\n`}\nEOF\n\nchmod +x /root/scripts/script-01.sh`\n ],\n image: msg.containerSpec.commit.image\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 410, + "y": 800, + "wires": [ + [ + "c5b7d5c62d369c24" + ] + ] + }, + { + "id": "c5b7d5c62d369c24", + "type": "subflow:b9a9b43a3594c357", + "z": "3fb1b07be44ed756", + "name": "", + "env": [ + { + "name": "Container Name", + "value": "create-script-01", + "type": "str" + }, + { + "name": "Image", + "value": "", + "type": "str" + }, + { + "name": "Command", + "value": "", + "type": "str" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + }, + { + "name": "Commit", + "value": "true", + "type": "bool" + } + ], + "x": 410, + "y": 840, + "wires": [ + [ + "e386314f2de22206", + "b424a8681b95fd74" + ] + ] + }, + { + "id": "e386314f2de22206", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "create script", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 410, + "y": 880, + "wires": [] + }, + { + "id": "b424a8681b95fd74", + "type": "switch", + "z": "3fb1b07be44ed756", + "name": "If success", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "docker-done", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 620, + "y": 760, + "wires": [ + [ + "3d56f436eacbe88b" + ] + ] + }, + { + "id": "3d56f436eacbe88b", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "Execute script", + "func": "\nreturn {\n command: [\"bash\", \"-c\", \"/root/scripts/script-01.sh\"],\n image: msg.containerSpec.commit.image\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 640, + "y": 800, + "wires": [ + [ + "10318dc5293f6d80" + ] + ] + }, + { + "id": "10318dc5293f6d80", + "type": "subflow:b9a9b43a3594c357", + "z": "3fb1b07be44ed756", + "name": "", + "env": [ + { + "name": "Container Name", + "value": "execute-script-01", + "type": "str" + }, + { + "name": "Image", + "value": "", + "type": "str" + }, + { + "name": "Command", + "value": "", + "type": "str" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + } + ], + "x": 630, + "y": 840, + "wires": [ + [ + "3ef49ac93dfcce8c" + ] + ] + }, + { + "id": "3ef49ac93dfcce8c", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "execute script", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 640, + "y": 880, + "wires": [] + }, + { + "id": "437a9435e7f7839a", + "type": "comment", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "Imports, Dependencies, Global", + "info": "", + "x": 1460, + "y": 340, + "wires": [] + }, + { + "id": "93482abb81e0fcdd", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 200, + "y": 220, + "wires": [ + [ + "c984808fcfb74f0f" + ] + ] + }, + { + "id": "c984808fcfb74f0f", + "type": "change", + "z": "3fb1b07be44ed756", + "name": "", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "[\"one\",\"two\",\"three\"]", + "tot": "json" + }, + { + "t": "set", + "p": "other", + "pt": "msg", + "to": "23", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 220, + "y": 260, + "wires": [ + [ + "45a072776a06e888" + ] + ] + }, + { + "id": "45a072776a06e888", + "type": "split", + "z": "3fb1b07be44ed756", + "name": "", + "splt": "\\n", + "spltType": "str", + "arraySplt": 1, + "arraySpltType": "len", + "stream": false, + "addname": "", + "x": 190, + "y": 300, + "wires": [ + [ + "306f4255096d69e2" + ] + ] + }, + { + "id": "306f4255096d69e2", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 34", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 200, + "y": 340, + "wires": [] + }, + { + "id": "234a56ef02849517", + "type": "inject", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 900, + "y": 700, + "wires": [ + [ + "4b1052f331f48638" + ] + ] + }, + { + "id": "bd0ab9ac636bddf7", + "type": "debug", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "debug 35", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1530, + "y": 700, + "wires": [] + }, + { + "id": "4b1052f331f48638", + "type": "provide-import-fn", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "x": 1110, + "y": 700, + "wires": [ + [ + "f119a534c23868e3" + ] + ] + }, + { + "id": "f119a534c23868e3", + "type": "function", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "Named Imports", + "func": "// List of modules\nconst toImport = [\n 'sse.js',\n \"node:events\",\n \"node:path\",\n \"node:module\"\n];\n\n;(async () => {\n try {\n const imported = Object.fromEntries(\n await Promise.all(\n toImport.map(\n async it => [it, await msg.import(it)]\n )\n )\n );\n\n node.send({...msg, namedImports: imported});\n } \n catch (e) {\n node.error(e);\n }\n})();\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "sseJs", + "module": "sse.js" + } + ], + "x": 1360, + "y": 700, + "wires": [ + [ + "bd0ab9ac636bddf7" + ] + ] + }, + { + "id": "a11718080bf06447", + "type": "subflow:87f7528a5c81b545", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "env": [ + { + "name": "Modules", + "value": "[\"colors/safe.js\",{\"moduleName\":\"change-case\",\"key\":\"changeCase\",\"defaultExport\":false,\"namedExports\":[\"camelCase\",{\"name\":\"split\",\"alias\":\"splitWords\"}]}]", + "type": "json" + } + ], + "x": 1130, + "y": 760, + "wires": [ + [ + "11de70778f4fcccb" + ] + ] + }, + { + "id": "7e92245bb06f8113", + "type": "inject", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 900, + "y": 760, + "wires": [ + [ + "a11718080bf06447" + ] + ] + }, + { + "id": "11de70778f4fcccb", + "type": "debug", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "debug 36", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1340, + "y": 760, + "wires": [] + }, + { + "id": "39d3ce3ccf412e91", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 25", + "func": "msg.content = `\nTo elicit a more detailed and specific response from BigStar, you could alter Lilly's prompt as follows:\n\nI have $10,000 in savings currently in an investment account. My goal is to earn a passive income of $10,000 per month within the next 6-12 months. Please provide a comprehensive step-by-step plan that outlines clear actions and resources for meeting this goal. The plan should include information on high-yield savings accounts, their interest rates, minimum balance requirements, and any other relevant details. Additionally, please consider providing examples of other investment strategies or financial products that could help me achieve my goal.\n\nThis prompt is more detailed and specific, which would encourage BigStar to provide a more thorough response with actionable steps and resources for achieving Lilly's goal\n\n{\n \"method\": \"POST\",\n \"path\": \"/operators\",\n \"body\": {\n \"id\": \"06f86c9a-1fe6-4c74-8939-30e64cb1edbb\",\n \"name\": \"My First Operator\"\n }\n}\n\n\n\n{\n \"method\": \"POST\",\n \"path\": \"/operators/06f86c9a-1fe6-4c74-8939-30e64cb1edbb/messages\",\n \"body\": {\n \"content\": \"Sign up for an account at the following website: https://www.example.com\"\n }\n}\n\nWhen I tried to access the website, I got a 404 Not Found error.\n\n\\`sudo apt - get update && sudo apt - get install - y net - tools\\`\n\n\\`\\`\\`bash\n#!/bin/bash\n\necho \"Script start.\"\necho \"Stderr start\" >& 2\n\nsudo apt update && sudo apt install - y curl\nsudo apt install - y google - chrome - stable\n\ncurl - X GET https://www.google.com/?s=puppies\n\\`\\`\\`\n`;\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 410, + "y": 360, + "wires": [ + [ + "f943a06e26050abe" + ] + ] + }, + { + "id": "482aefc956fcabfa", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 400, + "y": 320, + "wires": [ + [ + "39d3ce3ccf412e91" + ] + ] + }, + { + "id": "f943a06e26050abe", + "type": "subflow:126e4a373d8bcb36", + "z": "3fb1b07be44ed756", + "name": "", + "x": 430, + "y": 400, + "wires": [ + [ + "0b8c8bc4d9b7c3e5" + ] + ] + }, + { + "id": "0b8c8bc4d9b7c3e5", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 37", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 400, + "y": 440, + "wires": [] + }, + { + "id": "cfb2407a726eb285", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 26", + "func": "msg.content = `\n\nperties(a,{g:{value:b,configurable:!0,writable:!0,enumerable:!1}})})(B,55);Object.freeze(B);var C=function(){};Object.freeze(new function(){});Object.freeze(new C);Object.freeze(new C);var D=!z&&!w(),G=function(a){if(/-[a-z]/.test(\"ved\"))return null;if(D&&a.dataset){if(y()&&!(\"ved\"in a.dataset))return null;a=a.dataset.ved;return a===void 0?null:a}return a.getAttribute(\"data-\"+\"ved\".replace(/([A-Z])/g,\"-$1\").toLowerCase())};var H=[],I=null;function J(a){a=a.target;var b=performance.now(),f=[],K=f.concat,d=H;if(!(d instanceof Array)){var m=typeof Symbol!=\"undefined\"&&Symbol.iterator&&d[Symbol.iterator];if(m)d=m.call(d);else if(typeof d.length==\"number\")d={next:c(d)};else throw Error(\"b\\`\"+String(d));for(var E=[];!(m=d.next()).done;)E.push(m.value);d=E}H=K.call(f,d,[b]);if(a&&a instanceof HTMLElement)if(a===I){if(b=H.length>=4)b=(H[H.length-1]-H[H.length-4])/1E3<5;if(b){b=google.getEI(a);a.hasAttribute(\"data-ved\")?f=a?G(a)||\"\":\"\":f=(f=\n\u0001\u0001�a.closest(\"[data-ved]\"))?G(f)||\"\":\"\";f=f||\"\";if(a.hasAttribute(\"jsname\"))a=a.getAttribute(\"jsname\");else{var F;a=(F=a.closest(\"[jsname]\"))==null?void 0:F.getAttribute(\"jsname\")}google.log(\"rcm\",\"&ei=\"+b+\"&tgtved=\"+f+\"&jsname=\"+(a||\"\"))}}else I=a,H=[b]}window.document.addEventListener(\"DOMContentLoaded\",function(){document.body.addEventListener(\"click\",J)});}).call(this);\n\n\n\n\u0002\nStderr start\n\u0002\u0001\n\u0002PWARNING: apt does not have a stable CLI interface. Use with caution in scripts.\n\u0002\u0001\n\u0002\u0001\n\u0002PWARNING: apt does not have a stable CLI interface. Use with caution in scripts.\n\u0002\u0001\n\u0002Jdebconf: delaying package configuration, since apt-utils is not installed\n\u0002P % Total % Received % Xferd Average Speed Time Time Time Current\n\u0002N Dload Upload Total Spent Left Speed\n\u0002�\n 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\n100 19962 0 19962 0 0 62933 0 --:--:-- --:--:-- --:--:-- 62971\n\n\n`;\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 650, + "y": 360, + "wires": [ + [ + "d94dedcd28f4f2c5" + ] + ] + }, + { + "id": "5e6e19942bea27c9", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 640, + "y": 320, + "wires": [ + [ + "cfb2407a726eb285" + ] + ] + }, + { + "id": "b291b78b3b8cf21c", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 38", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 640, + "y": 440, + "wires": [] + }, + { + "id": "d94dedcd28f4f2c5", + "type": "subflow:828f5a08b0bcf89d", + "z": "3fb1b07be44ed756", + "name": "", + "env": [ + { + "name": "Escape", + "value": "false", + "type": "bool" + } + ], + "x": 670, + "y": 400, + "wires": [ + [ + "b291b78b3b8cf21c" + ] + ] + }, + { + "id": "99974fc7f020b29e", + "type": "switch", + "z": "3fb1b07be44ed756", + "name": "If script exists", + "property": "$replace(msg.topic, /[^0-9]/, '')", + "propertyType": "jsonata", + "rules": [ + { + "t": "eq", + "v": "1", + "vt": "str" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 1320, + "y": 980, + "wires": [ + [ + "8df1b8a506d75f34" + ], + [ + "b0a5abcb0b3bf998" + ] + ] + }, + { + "id": "ec8158c197f35ed6", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "\u0001\u00021", + "payload": "", + "payloadType": "date", + "x": 1320, + "y": 940, + "wires": [ + [ + "99974fc7f020b29e" + ] + ] + }, + { + "id": "8df1b8a506d75f34", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "1", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1510, + "y": 980, + "wires": [] + }, + { + "id": "b0a5abcb0b3bf998", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "otherwise", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1520, + "y": 1020, + "wires": [] + }, + { + "id": "98f4b0c9b2ccebc1", + "type": "subflow:2b3efcc977e88d91", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "env": [ + { + "name": "Url", + "value": "bash-executor", + "type": "str" + } + ], + "x": 690, + "y": 120, + "wires": [ + [ + "4c47c0ebef362a00" + ] + ] + }, + { + "id": "4c47c0ebef362a00", + "type": "subflow:74bd10ee8e354d0a", + "z": "3b5c9ca1fb9ebf48", + "name": "UI History", + "x": 680, + "y": 200, + "wires": [ + [ + "98f4b0c9b2ccebc1", + "bb99a83f06a6e48b" + ] + ] + }, + { + "id": "b8f8b9efb15b957b", + "type": "inject", + "z": "3b5c9ca1fb9ebf48", + "name": "Start App", + "props": [ + { + "p": "timestamp", + "v": "", + "vt": "date" + }, + { + "p": "action", + "v": "history-init", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 100, + "y": 60, + "wires": [ + [ + "4c47c0ebef362a00", + "abab070131a97f0b" + ] + ] + }, + { + "id": "ea9b73f9cc386115", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 45, + "y": 680, + "wires": [ + [ + "8ef6bd83dbaa3d85", + "d3eca839cbbe8f34", + "d4ebbd593cf64e04", + "3e0ce960e9b660a1" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "d3eca839cbbe8f34", + "type": "subflow:a59054999730c251", + "z": "3b5c9ca1fb9ebf48", + "d": true, + "g": "f7696f05d57ef7a1", + "name": "Model - openai - localhost", + "env": [ + { + "name": "Id", + "value": "openai-localhost", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal:8080", + "type": "str" + } + ], + "x": 250, + "y": 740, + "wires": [ + [ + "4c7815cb04fa305a" + ] + ] + }, + { + "id": "d4ebbd593cf64e04", + "type": "subflow:a59054999730c251", + "z": "3b5c9ca1fb9ebf48", + "g": "f7696f05d57ef7a1", + "name": "Model - genai - llama-cpp-llava", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", + "type": "str" + } + ], + "x": 270, + "y": 780, + "wires": [ + [ + "4c7815cb04fa305a" + ] + ] + }, + { + "id": "c2b3e2bf431804bd", + "type": "comment", + "z": "3b5c9ca1fb9ebf48", + "g": "f7696f05d57ef7a1", + "name": "Models", + "info": "", + "x": 190, + "y": 640, + "wires": [] + }, + { + "id": "1c9144b2ef0b4dd5", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "g": "a7de977d7732152e", + "name": "Model Errors", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 350, + "y": 940, + "wires": [] + }, + { + "id": "399f0d05531fcfd6", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "d": true, + "g": "a7de977d7732152e", + "name": "Model Output", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 360, + "y": 900, + "wires": [] + }, + { + "id": "504106b997f60dbe", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "g": "a7de977d7732152e", + "name": "Action", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "model-content", + "vt": "str" + }, + { + "t": "eq", + "v": "model-error", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 190, + "y": 920, + "wires": [ + [ + "399f0d05531fcfd6" + ], + [ + "1c9144b2ef0b4dd5" + ] + ] + }, + { + "id": "8ef6bd83dbaa3d85", + "type": "subflow:a59054999730c251", + "z": "3b5c9ca1fb9ebf48", + "d": true, + "g": "f7696f05d57ef7a1", + "name": "Model - dummy sse", + "env": [ + { + "name": "Id", + "value": "dummy-sse", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal.local:8091", + "type": "str" + }, + { + "name": "Batch", + "value": "10", + "type": "num" + } + ], + "x": 230, + "y": 700, + "wires": [ + [ + "4c7815cb04fa305a" + ] + ] + }, + { + "id": "4c7815cb04fa305a", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "g": "f7696f05d57ef7a1", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 485, + "y": 800, + "wires": [ + [ + "504106b997f60dbe", + "3856fb6b7a093891" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "3e0ce960e9b660a1", + "type": "subflow:a59054999730c251", + "z": "3b5c9ca1fb9ebf48", + "d": true, + "g": "f7696f05d57ef7a1", + "name": "Model - genai - llama-cpp-mistral-8x", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-mistral-8x", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", + "type": "str" + } + ], + "x": 280, + "y": 820, + "wires": [ + [ + "4c7815cb04fa305a" + ] + ] + }, + { + "id": "ea8016e9c51abc6c", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "System Prompt", + "func": "// Initial prompt\nconst initialPrompt = `You are a helpful chat bot that will perform any requested tasks to the best of your ability.`;\n\n// if this is an update prompt message\nif (msg.action == \"prompt-update\") {\n // update our prompt\n context.set(\"prompt\", msg.prompt);\n // that's all\n return msg;\n}\n\n// get current prompt\nlet currentPrompt = context.get(\"prompt\");\n\nif (!currentPrompt) {\n currentPrompt = initialPrompt\n context.set(\"prompt\", currentPrompt);\n}\n\nmsg.systemPrompt = currentPrompt;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 180, + "y": 540, + "wires": [ + [ + "ea9b73f9cc386115" + ] + ] + }, + { + "id": "bb99a83f06a6e48b", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If history-add-entry", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "history-add-entry", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 190, + "y": 300, + "wires": [ + [ + "74615acebc474df6" + ] + ] + }, + { + "id": "74615acebc474df6", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If new user message", + "property": "msg.newEntry.role", + "propertyType": "jsonata", + "rules": [ + { + "t": "eq", + "v": "user", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 200, + "y": 340, + "wires": [ + [ + "0e6df6e3cee2dcb1", + "d9a7870f0b658527" + ] + ] + }, + { + "id": "8a8d172c882c49af", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Add Task Message", + "func": "msg = {\n action: \"prog-history-add-entry\",\n entry: {\n role: \"user\",\n content: msg.createBashTaskPrompt(msg.newEntry.content || '')\n },\n id: msg.newEntry.id\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 190, + "y": 440, + "wires": [ + [ + "3856fb6b7a093891" + ] + ] + }, + { + "id": "0e6df6e3cee2dcb1", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Bash task prompt template", + "func": "msg.createBashTaskPrompt = task => {\n return '' + \n`Write a single bash script that will return an output ` + \n`that accomplishes the following task. Remember to ` +\n`install all needed dependencies at the beginning of ` +\n`the script.\n \n${task}`\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 220, + "y": 400, + "wires": [ + [ + "8a8d172c882c49af" + ] + ] + }, + { + "id": "3856fb6b7a093891", + "type": "subflow:f19bc65164444615", + "z": "3b5c9ca1fb9ebf48", + "name": "Executor Histories", + "env": [ + { + "name": "Factory Id", + "value": "executors", + "type": "str" + } + ], + "x": 730, + "y": 420, + "wires": [ + [ + "ea8016e9c51abc6c", + "d2016f7ee41f50fa", + "fb44317b333bd1ce" + ] + ] + }, + { + "id": "abab070131a97f0b", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Init Executor Histories", + "func": "\nreturn {\n action: \"prog-factory-init\"\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 420, + "y": 80, + "wires": [ + [ + "3856fb6b7a093891" + ] + ] + }, + { + "id": "d9a7870f0b658527", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Create executor", + "func": "msg = {\n action: \"prog-history-init\",\n historyId: msg.newEntry.id\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 460, + "y": 280, + "wires": [ + [ + "3856fb6b7a093891", + "e62148ddacf36d74" + ] + ] + }, + { + "id": "d2016f7ee41f50fa", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If update streaming", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "history-update-streaming", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 730, + "y": 500, + "wires": [ + [ + "aa7f174857ed9d6b" + ] + ] + }, + { + "id": "aa7f174857ed9d6b", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If not streaming", + "property": "msg.history.streaming", + "propertyType": "jsonata", + "rules": [ + { + "t": "null" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 720, + "y": 540, + "wires": [ + [ + "e8e887fd86249699" + ] + ] + }, + { + "id": "fdf90a031a450b58", + "type": "subflow:828f5a08b0bcf89d", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "env": [ + { + "name": "Escape", + "value": "false", + "type": "bool" + } + ], + "x": 730, + "y": 620, + "wires": [ + [ + "5ae0178c7a8ab864" + ] + ] + }, + { + "id": "e8e887fd86249699", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "Get agent response", + "rules": [ + { + "t": "set", + "p": "content", + "pt": "msg", + "to": "msg.history.entries[-1].content", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 730, + "y": 580, + "wires": [ + [ + "fdf90a031a450b58" + ] + ] + }, + { + "id": "5ae0178c7a8ab864", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "Get parsed response", + "rules": [ + { + "t": "set", + "p": "rawContent", + "pt": "msg", + "to": "content", + "tot": "msg" + }, + { + "t": "set", + "p": "content", + "pt": "msg", + "to": "contentHtml", + "tot": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 740, + "y": 660, + "wires": [ + [ + "05d22164293a60d1" + ] + ] + }, + { + "id": "05d22164293a60d1", + "type": "subflow:126e4a373d8bcb36", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "x": 730, + "y": 700, + "wires": [ + [ + "940cc0ae14188d1c" + ] + ] + }, + { + "id": "e62148ddacf36d74", + "type": "subflow:b9a9b43a3594c357", + "z": "3b5c9ca1fb9ebf48", + "name": "Setup environment", + "env": [ + { + "name": "Container Name", + "value": "setup-environment", + "type": "str" + }, + { + "name": "Command", + "value": "[\"bash\",\"-c\",\"mkdir /root/scripts; mkdir /root/new-scripts\"]", + "type": "json" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + }, + { + "name": "Commit", + "value": "true", + "type": "bool" + } + ], + "x": 470, + "y": 320, + "wires": [ + [ + "4fa2b99cc6cd1b5c" + ] + ] + }, + { + "id": "4fa2b99cc6cd1b5c", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If docker done", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "docker-done", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 460, + "y": 360, + "wires": [ + [ + "940cc0ae14188d1c" + ] + ] + }, + { + "id": "210a1d261ee95131", + "type": "subflow:b9a9b43a3594c357", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "env": [ + { + "name": "Container Name", + "value": "create-script", + "type": "str" + }, + { + "name": "Image", + "value": "", + "type": "str" + }, + { + "name": "Command", + "value": "", + "type": "str" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + }, + { + "name": "Commit", + "value": "true", + "type": "bool" + } + ], + "x": 750, + "y": 1060, + "wires": [ + [ + "27741de92e91d0d3" + ] + ] + }, + { + "id": "0e914a8e763e8ea0", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Create script", + "func": "\nconst scriptPath = `/root/new-scripts/script-${Date.now()}-${msg.index}.sh`;\n\nconst code = msg.currentCode.replaceAll(\"sudo \", \"\");\n\nreturn {\n action: \"loop-codes\",\n scriptPath,\n history: msg.history,\n historyId: msg.historyId,\n contentCodes: msg.contentCodes,\n index: msg.index,\n command: [\n \"bash\",\n \"-c\",\n `cat << 'EOF' > ${scriptPath}\n${code}\nEOF\n\nchmod +x ${scriptPath}`\n ],\n image: msg.lastImage\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 750, + "y": 1020, + "wires": [ + [ + "210a1d261ee95131", + "a02641d0cd9d6dbe" + ] + ] + }, + { + "id": "1a70750cb8a22229", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "For each code", + "rules": [ + { + "t": "set", + "p": "index", + "pt": "msg", + "to": "0", + "tot": "num" + }, + { + "t": "set", + "p": "contentCodes", + "pt": "msg", + "to": "msg.contentTags[name='code'].content", + "tot": "jsonata" + }, + { + "t": "set", + "p": "action", + "pt": "msg", + "to": "loop-codes", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 720, + "y": 780, + "wires": [ + [ + "8249b529648a77f1", + "16406d3e5582a1a4" + ] + ] + }, + { + "id": "f92c3f86107e5f1a", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If current code", + "property": "msg.currentCode", + "propertyType": "jsonata", + "rules": [ + { + "t": "nempty" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 760, + "y": 940, + "wires": [ + [ + "116ec2e1966609a4" + ], + [ + "583705d65356bc91" + ] + ] + }, + { + "id": "116ec2e1966609a4", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If uses chrome", + "property": "currentCode", + "propertyType": "msg", + "rules": [ + { + "t": "regex", + "v": "(chrome)", + "vt": "str", + "case": true + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 760, + "y": 980, + "wires": [ + [ + "cf5d7ad2b913deed" + ], + [ + "0e914a8e763e8ea0" + ] + ] + }, + { + "id": "27741de92e91d0d3", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "Docker output", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "docker-stderr", + "vt": "str" + }, + { + "t": "eq", + "v": "docker-done", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 760, + "y": 1100, + "wires": [ + [ + "f2d99994f035a684", + "b3f008f8f6712c97" + ], + [ + "f2d99994f035a684" + ] + ] + }, + { + "id": "1e9eba189d0b8e2f", + "type": "subflow:b9a9b43a3594c357", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "env": [ + { + "name": "Container Name", + "value": "compare-script", + "type": "str" + }, + { + "name": "Image", + "value": "", + "type": "str" + }, + { + "name": "Command", + "value": "", + "type": "str" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + }, + { + "name": "Commit", + "value": "true", + "type": "bool" + } + ], + "x": 750, + "y": 1180, + "wires": [ + [ + "63fac46ac0ea4dec" + ] + ] + }, + { + "id": "f2d99994f035a684", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Compare script", + "func": "const stderrMsg = context.get(\"StderrMsg\");\n\n// we'll get a loop message first telling us to reset state\nif (msg.action === \"loop-codes\") {\n context.set(\"StderrMsg\", null);\n return;\n}\n\n// if this is a stderr message\nif (msg.action === \"docker-stderr\") {\n // store it so we won't continue on docker success\n context.set(\"StderrMsg\", msg);\n return;\n}\n\n// else, we are to continue on,\n// but don't if we previously received a stderrMsg\nif (stderrMsg) {\n return;\n}\n\nreturn {\n action: \"loop-codes\",\n history: msg.containerSpec.history,\n historyId: msg.containerSpec.historyId,\n contentCodes: msg.containerSpec.contentCodes,\n index: msg.containerSpec.index,\n scriptPath: msg.containerSpec.scriptPath,\n command: [\n \"bash\",\n \"-c\",\n `result=0; for f in /root/scripts/*; `+\n `do cmp -s ${msg.containerSpec.scriptPath} \"$f\" && result=1; `+\n `done; echo $result`\n ],\n image: msg.containerSpec.commit.image\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 760, + "y": 1140, + "wires": [ + [ + "1e9eba189d0b8e2f", + "63a5c80a9677a5e8" + ] + ] + }, + { + "id": "63fac46ac0ea4dec", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "Docker output", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "docker-stdout", + "vt": "str" + }, + { + "t": "eq", + "v": "docker-done", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 760, + "y": 1220, + "wires": [ + [ + "a2e31c64ae6e49c9" + ], + [ + "a08be90792caa2ef" + ] + ] + }, + { + "id": "a2e31c64ae6e49c9", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If script exists", + "property": "$replace(msg.content, /[^0-9]/, '')", + "propertyType": "jsonata", + "rules": [ + { + "t": "eq", + "v": "1", + "vt": "str" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 760, + "y": 1260, + "wires": [ + [ + "61627dea12b6773b" + ], + [ + "a08be90792caa2ef" + ] + ] + }, + { + "id": "a08be90792caa2ef", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Execute script", + "func": "// get existing done and out messages\nconst doneMsg = context.get(\"DoneMsg\");\nconst outMsg = context.get(\"OutMsg\");\n\n// we'll get a loop message first telling us to reset state\nif (msg.action === \"loop-codes\") {\n context.set(\"DoneMsg\", null);\n context.set(\"OutMsg\", null);\n return;\n}\n\n// if we get our done message first\nif (msg.action === \"docker-done\" && !outMsg) {\n context.set(\"DoneMsg\", msg);\n return;\n}\n\n// if we get our out message first\nif (msg.action === \"docker-stdout\" && !doneMsg) {\n context.set(\"OutMsg\", msg);\n return;\n}\n\n// else, we should have both messages, use our done message\nmsg = doneMsg ?? msg;\n\nconst scriptName = msg.containerSpec.scriptPath.split('/').slice(-1)[0];\n\nreturn {\n action: \"loop-codes\",\n history: msg.containerSpec.history,\n historyId: msg.containerSpec.historyId,\n contentCodes: msg.containerSpec.contentCodes,\n index: msg.containerSpec.index,\n command: [\n \"bash\",\n \"-c\",\n `mv ${msg.containerSpec.scriptPath} /root/scripts; /root/scripts/${scriptName}`\n ],\n image: msg.containerSpec.commit.image\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 760, + "y": 1300, + "wires": [ + [ + "af1330eccccb509f", + "93f20029ca3784d0" + ] + ] + }, + { + "id": "af1330eccccb509f", + "type": "subflow:b9a9b43a3594c357", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "env": [ + { + "name": "Container Name", + "value": "execute-script", + "type": "str" + }, + { + "name": "Image", + "value": "", + "type": "str" + }, + { + "name": "Command", + "value": "", + "type": "str" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + }, + { + "name": "Commit", + "value": "true", + "type": "bool" + } + ], + "x": 750, + "y": 1340, + "wires": [ + [ + "8c0e8b561fb58e4c" + ] + ] + }, + { + "id": "8c0e8b561fb58e4c", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "Docker output", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "docker-stdout", + "vt": "str" + }, + { + "t": "eq", + "v": "docker-stderr", + "vt": "str" + }, + { + "t": "eq", + "v": "docker-done", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 3, + "x": 760, + "y": 1400, + "wires": [ + [ + "93f20029ca3784d0" + ], + [ + "93f20029ca3784d0" + ], + [ + "dd6437290fd336e7" + ] + ] + }, + { + "id": "8249b529648a77f1", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "Get current code", + "rules": [ + { + "t": "set", + "p": "content", + "pt": "msg", + "to": "msg.contentCodes[$$.msg.index]", + "tot": "jsonata" + }, + { + "t": "set", + "p": "lastImage", + "pt": "msg", + "to": "msg.containerSpec.commit.image", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 770, + "y": 820, + "wires": [ + [ + "544de36198caadba" + ] + ] + }, + { + "id": "dd6437290fd336e7", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "g": "d20e17ae1f88e910", + "name": "Iterate loop", + "rules": [ + { + "t": "set", + "p": "index", + "pt": "msg", + "to": "msg.containerSpec.index + 1", + "tot": "jsonata" + }, + { + "t": "set", + "p": "history", + "pt": "msg", + "to": "msg.containerSpec.history", + "tot": "jsonata" + }, + { + "t": "set", + "p": "historyId", + "pt": "msg", + "to": "msg.containerSpec.historyId", + "tot": "jsonata" + }, + { + "t": "set", + "p": "contentCodes", + "pt": "msg", + "to": "msg.containerSpec.contentCodes", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 750, + "y": 1460, + "wires": [ + [ + "7ab56a5e25543ac8", + "5952b16f0c8023f3" + ] + ] + }, + { + "id": "940cc0ae14188d1c", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Get environment", + "func": "const environments = context.get(\"Environments\") || {};\nconst queues = context.get(\"Queues\") || {};\n\n// if docker done\nif (msg.action === \"docker-done\") {\n // get our queue\n const execQueue = queues[msg.containerSpec.historyId] || [];\n // store our environment\n environments[msg.containerSpec.historyId] = msg.containerSpec;\n context.set(\"Environments\", environments);\n // add our environment to each queue message and send them\n return [\n execQueue.map(it => ({\n ...it,\n containerSpec: msg.containerSpec\n }))\n ];\n}\n\n// else, this is a message for executing in an environment\n// get our environment\nconst execEnv = environments[msg.historyId];\n// if we don't have one yet\nif (!execEnv) {\n // get our queue\n const execQueue = queues[msg.historyId] || [];\n // queue our message\n execQueue.push(msg);\n context.set(\"Queues\", queues);\n // don't send any messages\n return;\n}\n// add our environment to our message\nmsg.containerSpec = execEnv;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 730, + "y": 740, + "wires": [ + [ + "1a70750cb8a22229" + ] + ] + }, + { + "id": "5ae745cf98b55950", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "g": "d20e17ae1f88e910", + "name": "Update environment", + "rules": [ + { + "t": "set", + "p": "containerSpec", + "pt": "msg", + "to": "$merge([msg.containerSpec, { historyId: msg.history.id }])", + "tot": "jsonata" + }, + { + "t": "set", + "p": "action", + "pt": "msg", + "to": "docker-done", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 740, + "y": 1500, + "wires": [ + [ + "35a1e0a9c30682f6", + "93f20029ca3784d0", + "e874a9f9c957d07f" + ] + ] + }, + { + "id": "93f20029ca3784d0", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Get Aggregate Script Outputs", + "func": "const outputs = context.get(\"Outputs\") || [];\n\n// if this is the beginning of a loop\nif ([\"loop-codes\", \"reset-codes\"].includes(msg.action)) {\n // reset our outputs\n context.set(\"Outputs\", []);\n // don't return any messages\n return;\n}\n\n// if this is an output to aggregate\nif ([\"docker-stdout\", \"docker-stderr\"].includes(msg.action)) {\n outputs.push(msg);\n context.set(\"Outputs\", outputs);\n // don't return any messages\n return;\n}\n\n// else, return our aggregated outputs\nmsg.scriptOutputs = outputs;\ncontext.set(\"Outputs\", []);\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1160, + "y": 1460, + "wires": [ + [ + "6634abddc36c6662" + ] + ] + }, + { + "id": "c8668175271219a7", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "Reset codes", + "rules": [ + { + "t": "set", + "p": "action", + "pt": "msg", + "to": "reset-codes", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1110, + "y": 1320, + "wires": [ + [ + "93f20029ca3784d0" + ] + ] + }, + { + "id": "cf5d7ad2b913deed", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Chrome unavailable prompt template", + "func": "msg.createPrompt = () => {\n return 'Chrome is not available, please use a different method.';\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1190, + "y": 1000, + "wires": [ + [ + "8c491b44c49379ec" + ] + ] + }, + { + "id": "8c491b44c49379ec", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Add Exec Message", + "func": "msg = {\n action: \"prog-history-add-entry\",\n entry: {\n role: \"user\",\n content: msg.createPrompt()\n },\n id: msg.historyId\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1490, + "y": 1080, + "wires": [ + [ + "c8668175271219a7", + "824ad7c29ee4fd68", + "d1688f392dbffd37" + ] + ] + }, + { + "id": "1e8f78c5c7e72bca", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Script exists prompt template", + "func": "msg.createPrompt = () => {\n return \"We've already tried that script.\";\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1160, + "y": 1180, + "wires": [ + [ + "8c491b44c49379ec" + ] + ] + }, + { + "id": "6634abddc36c6662", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Script output prompt template", + "func": "const outputs = msg.scriptOutputs;\n\nconst streamMaxLength = 1350;\n\nmsg.createPrompt = () => {\n return outputs.map(outMsg => {\n const tag = outMsg.action === \"docker-stdout\" ? \"stdout\" : \"stderr\";\n return `<${tag} beginningTruncated=\"${outMsg.content.length > streamMaxLength ? 'true' : 'false'}\">\n${outMsg.content.slice(-streamMaxLength)}\n\n\n`\n }).join('');\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1170, + "y": 1500, + "wires": [ + [ + "8c491b44c49379ec" + ] + ] + }, + { + "id": "16406d3e5582a1a4", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "name": "Begin code loop", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 980, + "y": 800, + "wires": [] + }, + { + "id": "d1688f392dbffd37", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "name": "Executor Message", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1490, + "y": 1120, + "wires": [] + }, + { + "id": "5952b16f0c8023f3", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "name": "Iterate loop", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 750, + "y": 1560, + "wires": [] + }, + { + "id": "e874a9f9c957d07f", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "name": "End loop", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 700, + "y": 1600, + "wires": [] + }, + { + "id": "053e11fd5e2f4c95", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "name": "Current code", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 970, + "y": 920, + "wires": [] + }, + { + "id": "544de36198caadba", + "type": "subflow:d5c98b48f9d2d77f", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "x": 780, + "y": 860, + "wires": [ + [ + "d51dc15e41460eed" + ] + ] + }, + { + "id": "d51dc15e41460eed", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "Get decode", + "rules": [ + { + "t": "set", + "p": "currentCode", + "pt": "msg", + "to": "decodedContent", + "tot": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 750, + "y": 900, + "wires": [ + [ + "f92c3f86107e5f1a", + "053e11fd5e2f4c95" + ] + ] + }, + { + "id": "b3f008f8f6712c97", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "name": "Create script stderr", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 990, + "y": 1040, + "wires": [] + }, + { + "id": "61627dea12b6773b", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "Get history", + "rules": [ + { + "t": "set", + "p": "historyId", + "pt": "msg", + "to": "msg.containerSpec.historyId", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1110, + "y": 1140, + "wires": [ + [ + "1e8f78c5c7e72bca" + ] + ] + }, + { + "id": "fb44317b333bd1ce", + "type": "subflow:2b3efcc977e88d91", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "env": [ + { + "name": "Url", + "value": "bash-executor-view", + "type": "str" + } + ], + "x": 950, + "y": 340, + "wires": [ + [] + ] + }, + { + "id": "fe160cbe0df384e5", + "type": "template", + "z": "191694dad2850f37", + "name": "System Prompt", + "field": "prompt", + "fieldType": "msg", + "format": "handlebars", + "syntax": "mustache", + "template": "You are a helpful chat bot that will perform any requested tasks to the best of your ability.", + "output": "str", + "x": 200, + "y": 520, + "wires": [ + [ + "81b98c3380c57334" + ] + ] + }, + { + "id": "34fa053e9707e425", + "type": "subflow:74bd10ee8e354d0a", + "z": "191694dad2850f37", + "g": "b1dd9777ee396bd7", + "name": "Solution History", + "env": [ + { + "name": "Id", + "value": "solution-01", + "type": "str" + } + ], + "x": 480, + "y": 380, + "wires": [ + [ + "8565c4a9a8c13312", + "88802dbd1e8b0c57", + "b38cd518b824c20d" + ] + ] + }, + { + "id": "9d0d59cbd0342094", + "type": "inject", + "z": "191694dad2850f37", + "g": "0e31504694a6eb0c", + "name": "Start Loop", + "props": [ + { + "p": "action", + "v": "step-go-to", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 500, + "y": 80, + "wires": [ + [ + "b67aacc8e54e5106" + ] + ] + }, + { + "id": "c85c2df7d79465a0", + "type": "subflow:a59054999730c251", + "z": "191694dad2850f37", + "d": true, + "g": "83fd8826b0ec3bf4", + "name": "Model - dummy sse", + "env": [ + { + "name": "Id", + "value": "dummy-sse", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal:8091", + "type": "str" + }, + { + "name": "Batch", + "value": "10", + "type": "num" + } + ], + "x": 330, + "y": 680, + "wires": [ + [ + "d48b052e253b43c3" + ] + ] + }, + { + "id": "73516493eccdfd9d", + "type": "subflow:a59054999730c251", + "z": "191694dad2850f37", + "g": "83fd8826b0ec3bf4", + "name": "Model - genai - llama-cpp-llava", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "Batch", + "value": "10", + "type": "num" + } + ], + "x": 370, + "y": 760, + "wires": [ + [ + "d48b052e253b43c3" + ] + ] + }, + { + "id": "f762ec936046e78f", + "type": "comment", + "z": "191694dad2850f37", + "g": "83fd8826b0ec3bf4", + "name": "Models", + "info": "", + "x": 290, + "y": 620, + "wires": [] + }, + { + "id": "e451712bc8b52b18", + "type": "debug", + "z": "191694dad2850f37", + "g": "ce1b28a464e3b3b3", + "name": "Model Errors", + "active": true, + "tosidebar": true, + "console": true, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 460, + "y": 880, + "wires": [] + }, + { + "id": "e2dd14f8d37e7a72", + "type": "debug", + "z": "191694dad2850f37", + "g": "ce1b28a464e3b3b3", + "name": "Model Output", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 460, + "y": 840, + "wires": [] + }, + { + "id": "bb6dc487db2ce156", + "type": "switch", + "z": "191694dad2850f37", + "g": "ce1b28a464e3b3b3", + "name": "Action", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "model-streaming-content", + "vt": "str" + }, + { + "t": "eq", + "v": "model-error", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 290, + "y": 860, + "wires": [ + [ + "e2dd14f8d37e7a72" + ], + [ + "e451712bc8b52b18" + ] + ] + }, + { + "id": "42cede20c9456a92", + "type": "subflow:74bd10ee8e354d0a", + "z": "191694dad2850f37", + "g": "5dbdaf47523ce33a", + "name": "Eval History", + "env": [ + { + "name": "Id", + "value": "eval-01", + "type": "str" + } + ], + "x": 1270, + "y": 640, + "wires": [ + [ + "1f999e727d7bdcbd", + "f79210375a125e74", + "c9ba32537f7bc133", + "6b036e58872195a7" + ] + ] + }, + { + "id": "b67aacc8e54e5106", + "type": "function", + "z": "191694dad2850f37", + "g": "0e31504694a6eb0c", + "name": "Prompt: Problem statement", + "func": "msg.createUserPrompt = () =>\n `I have 10K in savings currently in an investment account. My goal is to earn a passive income of $10K every month. Create a plan for me that will meet this goal. I'm looking for single tailored plan, not options to choose from. Give specific, brief instructions for carrying out this plan.`;\n\nflow.set(\"originalProblemStatement\", msg.createUserPrompt());\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 220, + "y": 160, + "wires": [ + [ + "8565c4a9a8c13312" + ] + ] + }, + { + "id": "81b98c3380c57334", + "type": "function", + "z": "191694dad2850f37", + "g": "83fd8826b0ec3bf4", + "name": "In", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 150, + "y": 700, + "wires": [ + [ + "c85c2df7d79465a0", + "73516493eccdfd9d", + "93859b35073996c8" + ] + ], + "icon": "font-awesome/fa-address-card-o" + }, + { + "id": "d48b052e253b43c3", + "type": "function", + "z": "191694dad2850f37", + "g": "83fd8826b0ec3bf4", + "name": "Out", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 590, + "y": 700, + "wires": [ + [ + "bb6dc487db2ce156", + "4135e1850bf3099c", + "fe0f3fe28e08e2f0", + "0800060d86e1ca55", + "079bf5373fe5d58f", + "b38cd518b824c20d" + ] + ], + "icon": "font-awesome/fa-address-card-o" + }, + { + "id": "c533acab9a1bba89", + "type": "comment", + "z": "191694dad2850f37", + "g": "0e31504694a6eb0c", + "name": "Step 1: Problem Statement and Solution", + "info": "", + "x": 250, + "y": 80, + "wires": [] + }, + { + "id": "8516a2d5188e142d", + "type": "comment", + "z": "191694dad2850f37", + "g": "17a2a4d88505d1b2", + "name": "Step 2: Evaluate Solution", + "info": "", + "x": 990, + "y": 340, + "wires": [] + }, + { + "id": "5dd26b4eb51f86a8", + "type": "comment", + "z": "191694dad2850f37", + "g": "3334e9dd5bf3557d", + "name": "Step 3: Propose New Prompt", + "info": "", + "x": 1000, + "y": 820, + "wires": [] + }, + { + "id": "0800060d86e1ca55", + "type": "function", + "z": "191694dad2850f37", + "g": "0df36a8be0d76989", + "name": "Prompt: Use proposed prompt", + "func": "msg.createUserPrompt = (history) => {\n const promptProposal = history.entries.slice(-1)[0].content;\n let newPrompt;\n try {\n // don't search for full ending tag, since sometimes the last token gets cutoff\n newPrompt = promptProposal.match(/([\\s\\S]*?)<\\/pro/)[1].trim();\n if (newPrompt.length < 1) {\n throw new Error(\"Empty prompt extracted from proposal\")\n }\n }\n catch (e) {\n throw new Error(`Error extracting prompt from: \\`${promptProposal}\\``);\n }\n\n return newPrompt;\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1010, + "y": 160, + "wires": [ + [ + "a33731f7d26ff1d8" + ] + ] + }, + { + "id": "32fd036f241606a1", + "type": "comment", + "z": "191694dad2850f37", + "g": "0df36a8be0d76989", + "name": "Step 4: Restart w/ New Prompt", + "info": "", + "x": 1010, + "y": 80, + "wires": [] + }, + { + "id": "0ad9554c20eb8dd0", + "type": "switch", + "z": "191694dad2850f37", + "g": "b1dd9777ee396bd7", + "name": "If Step 1", + "property": "step", + "propertyType": "flow", + "rules": [ + { + "t": "eq", + "v": "1", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 460, + "y": 340, + "wires": [ + [ + "34fa053e9707e425" + ] + ] + }, + { + "id": "4135e1850bf3099c", + "type": "switch", + "z": "191694dad2850f37", + "g": "5dbdaf47523ce33a", + "name": "If Step 2 or 3", + "property": "step", + "propertyType": "flow", + "rules": [ + { + "t": "btwn", + "v": "2", + "vt": "num", + "v2": "3", + "v2t": "num" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 1270, + "y": 600, + "wires": [ + [ + "42cede20c9456a92" + ] + ] + }, + { + "id": "93859b35073996c8", + "type": "subflow:a59054999730c251", + "z": "191694dad2850f37", + "d": true, + "g": "83fd8826b0ec3bf4", + "name": "Model - openai - localhost", + "env": [ + { + "name": "Id", + "value": "openai-localhost", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal:8080", + "type": "str" + } + ], + "x": 350, + "y": 720, + "wires": [ + [ + "d48b052e253b43c3" + ] + ] + }, + { + "id": "8565c4a9a8c13312", + "type": "subflow:fe8f70709279ea90", + "z": "191694dad2850f37", + "g": "0e31504694a6eb0c", + "name": "Step 1", + "env": [ + { + "name": "Step", + "value": "1", + "type": "num" + }, + { + "name": "InitHistoryId", + "value": "solution-01", + "type": "str" + }, + { + "name": "Wait", + "value": "false", + "type": "bool" + } + ], + "x": 510, + "y": 160, + "wires": [ + [ + "0ad9554c20eb8dd0" + ] + ] + }, + { + "id": "1322aa4137d1056e", + "type": "function", + "z": "191694dad2850f37", + "d": true, + "g": "17a2a4d88505d1b2", + "name": "Prompt: Evalutate Solution", + "func": "msg.createUserPrompt = (history) => {\n const problemStatement = history.entries[0].content;\n\n const solution = history.entries.slice(-1)[0].content;\n\n return `I'm going to give you a prompt that a user named Lilly gave to an LLM model named BigStar-13B. Then, I will give you the response BigStar gave to Lilly. I want you to rate BigStar's response on a scale from 1-10. Then, give 2-3 specific improvements to BigStar's response that would have increased it's rating.\n\nHere is Lilly's prompt:\n\n${problemStatement}\n\nHere is BigStar's response:\n\n${solution}\n\nWhat would you rate BigStar's response?`;\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1020, + "y": 420, + "wires": [ + [ + "1f999e727d7bdcbd" + ] + ] + }, + { + "id": "1f999e727d7bdcbd", + "type": "subflow:fe8f70709279ea90", + "z": "191694dad2850f37", + "g": "17a2a4d88505d1b2", + "name": "Step 2", + "env": [ + { + "name": "Step", + "value": "2", + "type": "num" + }, + { + "name": "InitHistoryId", + "value": "eval-01", + "type": "str" + } + ], + "x": 1290, + "y": 420, + "wires": [ + [ + "4135e1850bf3099c" + ] + ] + }, + { + "id": "833eaf27d6837495", + "type": "subflow:fe8f70709279ea90", + "z": "191694dad2850f37", + "g": "3334e9dd5bf3557d", + "name": "Step 3", + "env": [ + { + "name": "Step", + "value": "3", + "type": "num" + }, + { + "name": "InitHistory", + "value": "false", + "type": "bool" + } + ], + "x": 1290, + "y": 900, + "wires": [ + [ + "909642bb1b9261ea" + ] + ] + }, + { + "id": "fe0f3fe28e08e2f0", + "type": "function", + "z": "191694dad2850f37", + "g": "3334e9dd5bf3557d", + "name": "Prompt: Propose New Prompt", + "func": "msg.createUserPrompt = () => \n `How could Lilly's prompt be altered to get BigStar to respond with your suggested improvements? Please provide the new prompt wrapped in tags.`;\n\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1010, + "y": 900, + "wires": [ + [ + "833eaf27d6837495" + ] + ] + }, + { + "id": "a33731f7d26ff1d8", + "type": "subflow:fe8f70709279ea90", + "z": "191694dad2850f37", + "g": "0df36a8be0d76989", + "name": "Step 4", + "env": [ + { + "name": "Step", + "value": "4", + "type": "num" + }, + { + "name": "InitHistory", + "value": "false", + "type": "bool" + } + ], + "x": 930, + "y": 220, + "wires": [ + [ + "85c126ddb6ae9692" + ] + ] + }, + { + "id": "36217d16d71a4c30", + "type": "inject", + "z": "191694dad2850f37", + "g": "17a2a4d88505d1b2", + "name": "Start @ Step 2", + "props": [ + { + "p": "historyId", + "v": "solution-01", + "vt": "str" + }, + { + "p": "historySourceFilename", + "v": "/data/db/history-1706503270302.json", + "vt": "str" + }, + { + "p": "action", + "v": "step-start-at", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 1260, + "y": 340, + "wires": [ + [ + "b38cd518b824c20d" + ] + ] + }, + { + "id": "7b60dc37c59dc80f", + "type": "inject", + "z": "191694dad2850f37", + "g": "0df36a8be0d76989", + "name": "Start @ Step 4", + "props": [ + { + "p": "historyId", + "v": "eval-01", + "vt": "str" + }, + { + "p": "historySourceFilename", + "v": "/data/db/history-1706169633523.json", + "vt": "str" + }, + { + "p": "action", + "v": "step-start-at", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 1260, + "y": 80, + "wires": [ + [ + "0800060d86e1ca55" + ] + ] + }, + { + "id": "36f73b6e3236c721", + "type": "inject", + "z": "191694dad2850f37", + "g": "3334e9dd5bf3557d", + "name": "Start @ Step 3", + "props": [ + { + "p": "historyId", + "v": "eval-01", + "vt": "str" + }, + { + "p": "historySourceFilename", + "v": "/data/db/history-1706169407261.json", + "vt": "str" + }, + { + "p": "action", + "v": "step-start-at", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 1260, + "y": 820, + "wires": [ + [ + "fe0f3fe28e08e2f0" + ] + ] + }, + { + "id": "bd8902942d9f30bc", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 795, + "y": 780, + "wires": [ + [ + "fe0f3fe28e08e2f0" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "f79210375a125e74", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1435, + "y": 660, + "wires": [ + [ + "bd8902942d9f30bc" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "909642bb1b9261ea", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1435, + "y": 820, + "wires": [ + [ + "246801bf115544b3" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "246801bf115544b3", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1125, + "y": 640, + "wires": [ + [ + "4135e1850bf3099c" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "c9ba32537f7bc133", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1435, + "y": 320, + "wires": [ + [ + "322d52b49ebe2f42" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "88802dbd1e8b0c57", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 645, + "y": 420, + "wires": [ + [ + "fe160cbe0df384e5" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "85c126ddb6ae9692", + "type": "subflow:3bb38f582155f29d", + "z": "191694dad2850f37", + "g": "0df36a8be0d76989", + "name": "", + "x": 1050, + "y": 220, + "wires": [ + [ + "a8aa5ac1df416d41" + ] + ] + }, + { + "id": "a8aa5ac1df416d41", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 345, + "y": 280, + "wires": [ + [ + "8565c4a9a8c13312" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "322d52b49ebe2f42", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 755, + "y": 260, + "wires": [ + [ + "0800060d86e1ca55" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "6b036e58872195a7", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1435, + "y": 560, + "wires": [ + [ + "fe160cbe0df384e5" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "079bf5373fe5d58f", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 775, + "y": 640, + "wires": [ + [ + "c8bf1c9a8fe80c37" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "c8bf1c9a8fe80c37", "type": "function", - "z": "3fb1b07be44ed756", - "name": "function 7", - "func": "\nreturn {fs};", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", - "libs": [ - { - "var": "fs", - "module": "fs" - } - ], - "x": 1340, - "y": 440, + "libs": [], + "x": 305, + "y": 380, "wires": [ [ - "d7e17a64b9a03bac" + "0ad9554c20eb8dd0" ] - ] + ], + "icon": "font-awesome/fa-arrows", + "l": false }, { - "id": "23cc77d254e27371", + "id": "b38cd518b824c20d", "type": "function", - "z": "3fb1b07be44ed756", - "name": "Init Vector Store", - "func": "const { HNSWLib } = langchainCommunityVectorstoresHnswlib;\nconst { OpenAIEmbeddings } = langchainOpenai;\n\nconst vectorStore = await HNSWLib.fromTexts(\n [\"Hello world\", \"Bye bye\", \"hello nice world\"],\n [{ id: 2 }, { id: 1 }, { id: 3 }],\n new OpenAIEmbeddings()\n);\n\nconst resultOne = await vectorStore.similaritySearch(\"hello world\", 1);\nconsole.log(resultOne);\n\nreturn msg;", + "z": "191694dad2850f37", + "g": "17a2a4d88505d1b2", + "name": " ", + "func": "\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", - "libs": [ - { - "var": "langchainCommunityVectorstoresHnswlib", - "module": "@langchain/community/vectorstores/hnswlib" - }, - { - "var": "langchainOpenai", - "module": "@langchain/openai" - } - ], - "x": 1500, - "y": 320, + "libs": [], + "x": 855, + "y": 420, "wires": [ - [] - ] + [ + "1322aa4137d1056e", + "9240a0389d51445c" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false }, { - "id": "9f7595e19d34fca3", + "id": "9240a0389d51445c", "type": "function", - "z": "3fb1b07be44ed756", - "name": "Provide OpenAIEmbeddings", - "func": "msg.OpenAIEmbeddings = class {\n constructor () {\n \n }\n}\n\nreturn msg;", + "z": "191694dad2850f37", + "g": "17a2a4d88505d1b2", + "name": "Prompt: Evalutate Against Original", + "func": "msg.createUserPrompt = (history) => {\n const problemStatement = flow.get(\"originalProblemStatement\");\n\n const solution = history.entries.slice(-1)[0].content;\n\n return `I'm going to give you a prompt that a user named Lilly gave to an LLM model named BigStar-13B. Then, I will give you the response BigStar gave to Lilly. I want you to rate BigStar's response on a scale from 1-10. Then, give 2-3 specific improvements to BigStar's response that would have increased it's rating.\n\nHere is Lilly's prompt:\n\n${problemStatement}\n\nHere is BigStar's response:\n\n${solution}\n\nWhat would you rate BigStar's response?`;\n};\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1400, - "y": 260, + "x": 1040, + "y": 460, "wires": [ - [] + [ + "1f999e727d7bdcbd" + ] ] }, { @@ -8390,24 +14466,6 @@ [] ] }, - { - "id": "af241602e203f3d3", - "type": "range", - "z": "8518392b3e041cfe", - "minin": "", - "maxin": "", - "minout": "", - "maxout": "", - "action": "scale", - "round": false, - "property": "payload", - "name": "", - "x": 730, - "y": 680, - "wires": [ - [] - ] - }, { "id": "07b22b0dc0d11143", "type": "rbe", @@ -8449,55 +14507,6 @@ [] ] }, - { - "id": "7a42a1e78f716c43", - "type": "jsonpath", - "z": "8518392b3e041cfe", - "expression": "", - "split": false, - "name": "", - "x": 1270, - "y": 540, - "wires": [ - [] - ] - }, - { - "id": "634514577f178815", - "type": "mqtt in", - "z": "8518392b3e041cfe", - "name": "", - "topic": "", - "qos": "2", - "datatype": "auto-detect", - "broker": "", - "nl": false, - "rap": true, - "rh": 0, - "inputs": 0, - "x": 1390, - "y": 780, - "wires": [ - [] - ] - }, - { - "id": "8df5f648c84b1fc6", - "type": "mqtt out", - "z": "8518392b3e041cfe", - "name": "", - "topic": "", - "qos": "", - "retain": "", - "respTopic": "", - "contentType": "", - "userProps": "", - "correl": "", - "expiry": "", - "x": 890, - "y": 820, - "wires": [] - }, { "id": "e9f8ed38bd8d02c0", "type": "http request", @@ -9224,896 +15233,826 @@ "type": "subflow:9eb27f011bcf9a83", "z": "4d258c7de41d3e07", "d": true, - "g": "132bac76be391419", - "name": "Embeddings - genai - llama-cpp-llava", - "env": [ - { - "name": "Id", - "value": "genai-llama-cpp-llava-embeddings", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", - "type": "str" - } - ], - "x": 1550, - "y": 500, - "wires": [ - [ - "4d5a8d1e8ff6d660" - ] - ] - }, - { - "id": "acd0680bb6e69b51", - "type": "function", - "z": "4d258c7de41d3e07", - "name": "Vector Search Params", - "func": "msg.vectorSearchParams = {\n top: 4\n};\n\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 740, - "y": 280, - "wires": [ - [ - "083cd95ebe479e4c" - ] - ] - }, - { - "id": "1a8be604e1fb0f60", - "type": "subflow:a59054999730c251", - "z": "4d258c7de41d3e07", - "g": "a6665159eabf55ba", - "name": "Model - genai - llama-cpp-mistral-8x", - "env": [ - { - "name": "Id", - "value": "genai-llama-cpp-mistral-8x", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", - "type": "str" - } - ], - "x": 340, - "y": 620, - "wires": [ - [ - "0bdfb9335b655b7b" - ] - ] - }, - { - "id": "1648a58fa167dcbd", - "type": "subflow:9eb27f011bcf9a83", - "z": "4d258c7de41d3e07", - "g": "132bac76be391419", - "name": "Embeddings - genai - llama-cpp-mistral-8x", - "env": [ - { - "name": "Id", - "value": "genai-llama-cpp-mistral-8x-embeddings", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", - "type": "str" - } - ], - "x": 1560, - "y": 540, - "wires": [ - [ - "4d5a8d1e8ff6d660" - ] - ] - }, - { - "id": "6b73ef72bb7e4b87", - "type": "subflow:2b3efcc977e88d91", - "z": "ec55121054ad7072", - "name": "", - "env": [ - { - "name": "Url", - "value": "admin-operator", - "type": "str" - } - ], - "x": 310, - "y": 280, - "wires": [ - [ - "e77e6ed92b6eba12" - ] - ] - }, - { - "id": "e77e6ed92b6eba12", - "type": "subflow:74bd10ee8e354d0a", - "z": "ec55121054ad7072", - "name": "Admin History", - "env": [ - { - "name": "SourceFilename", - "value": "/data/db/history-1711926907124.json", - "type": "str" - } - ], - "x": 600, - "y": 280, - "wires": [ - [ - "6b73ef72bb7e4b87", - "0a39bb73f010efd7", - "8ad28cb311d8a5c0" - ] - ] - }, - { - "id": "cd5e2c4e51717c0f", - "type": "inject", - "z": "ec55121054ad7072", - "name": "Start App", - "props": [ + "g": "132bac76be391419", + "name": "Embeddings - genai - llama-cpp-llava", + "env": [ { - "p": "timestamp", - "v": "", - "vt": "date" + "name": "Id", + "value": "genai-llama-cpp-llava-embeddings", + "type": "str" }, { - "p": "action", - "v": "history-init", - "vt": "str" + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", + "type": "str" } ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "x": 140, - "y": 80, + "x": 1550, + "y": 500, "wires": [ [ - "e77e6ed92b6eba12", - "d7625ef95dd891b8" + "4d5a8d1e8ff6d660" ] ] }, { - "id": "0a34e1dce381f16b", + "id": "acd0680bb6e69b51", "type": "function", - "z": "ec55121054ad7072", - "name": " ", - "func": "\nreturn msg;", + "z": "4d258c7de41d3e07", + "name": "Vector Search Params", + "func": "msg.vectorSearchParams = {\n top: 4\n};\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 205, - "y": 440, + "x": 740, + "y": 280, "wires": [ [ - "21debbaed5b57fd5", - "75d06bae12a047f9", - "a61cd1dd9aeb1256", - "9d4dbbbd2defb7fb" + "083cd95ebe479e4c" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "75d06bae12a047f9", + "id": "1a8be604e1fb0f60", "type": "subflow:a59054999730c251", - "z": "ec55121054ad7072", - "d": true, - "g": "0bd29a38bd7fd7ee", - "name": "Model - openai - localhost", + "z": "4d258c7de41d3e07", + "g": "a6665159eabf55ba", + "name": "Model - genai - llama-cpp-mistral-8x", "env": [ { "name": "Id", - "value": "openai-localhost", + "value": "genai-llama-cpp-mistral-8x", "type": "str" }, { "name": "BaseUrl", - "value": "http://host.docker.internal:8080", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", "type": "str" } ], - "x": 410, - "y": 500, + "x": 340, + "y": 620, "wires": [ [ - "a98ec39f0f7f2c84" + "0bdfb9335b655b7b" ] ] }, { - "id": "a61cd1dd9aeb1256", - "type": "subflow:a59054999730c251", - "z": "ec55121054ad7072", - "g": "0bd29a38bd7fd7ee", - "name": "Model - genai - llama-cpp-llava", + "id": "1648a58fa167dcbd", + "type": "subflow:9eb27f011bcf9a83", + "z": "4d258c7de41d3e07", + "g": "132bac76be391419", + "name": "Embeddings - genai - llama-cpp-mistral-8x", "env": [ { "name": "Id", - "value": "genai-llama-cpp-llava", + "value": "genai-llama-cpp-mistral-8x-embeddings", "type": "str" }, { "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", "type": "str" } ], - "x": 430, + "x": 1560, "y": 540, "wires": [ [ - "a98ec39f0f7f2c84" + "4d5a8d1e8ff6d660" ] ] }, { - "id": "12901237f1ea6884", - "type": "comment", - "z": "ec55121054ad7072", - "g": "0bd29a38bd7fd7ee", - "name": "Models", - "info": "", - "x": 350, - "y": 400, - "wires": [] - }, - { - "id": "d9e0c9a3cf18f405", - "type": "debug", - "z": "ec55121054ad7072", - "g": "7aad90c5be36eb0a", - "name": "Model Errors", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 510, - "y": 700, - "wires": [] - }, - { - "id": "4b7f0d34fcfa313d", - "type": "debug", - "z": "ec55121054ad7072", - "d": true, - "g": "7aad90c5be36eb0a", - "name": "Model Output", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 520, - "y": 660, - "wires": [] - }, - { - "id": "bbeaa9f159afdfaf", - "type": "switch", - "z": "ec55121054ad7072", - "g": "7aad90c5be36eb0a", - "name": "Action", - "property": "action", - "propertyType": "msg", - "rules": [ + "id": "0dd8b704b63c96a1", + "type": "inject", + "z": "f6f2187d.f17ca8", + "g": "f1bf7ba3b4088527", + "name": "Authorize", + "props": [ { - "t": "eq", - "v": "model-content", - "vt": "str" + "p": "payload" }, { - "t": "eq", - "v": "model-error", + "p": "topic", "vt": "str" } ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 350, - "y": 680, + "repeat": "", + "crontab": "", + "once": true, + "onceDelay": 0.1, + "topic": "", + "payload": "{ \"password\": \"\", \"username\": \"admin\" }", + "payloadType": "json", + "x": 160, + "y": 120, "wires": [ [ - "4b7f0d34fcfa313d" - ], - [ - "d9e0c9a3cf18f405" + "bd7eb8ec2a8e0da9" ] ] }, { - "id": "21debbaed5b57fd5", - "type": "subflow:a59054999730c251", - "z": "ec55121054ad7072", - "d": true, - "g": "0bd29a38bd7fd7ee", - "name": "Model - dummy sse", - "env": [ - { - "name": "Id", - "value": "dummy-sse", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://host.docker.internal.local:8091", - "type": "str" - }, + "id": "3b853d53f8b1fb4d", + "type": "change", + "z": "f6f2187d.f17ca8", + "g": "f1bf7ba3b4088527", + "name": "SaveToken", + "rules": [ { - "name": "Batch", - "value": "10", - "type": "num" + "t": "set", + "p": "portainer_jwt", + "pt": "flow", + "to": "payload", + "tot": "msg" } ], - "x": 390, - "y": 460, + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 770, + "y": 120, "wires": [ - [ - "a98ec39f0f7f2c84" - ] + [] ] }, { - "id": "a98ec39f0f7f2c84", - "type": "function", - "z": "ec55121054ad7072", - "g": "0bd29a38bd7fd7ee", - "name": " ", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 645, - "y": 560, - "wires": [ - [ - "e77e6ed92b6eba12", - "bbeaa9f159afdfaf", - "4de07154c6644063" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false - }, - { - "id": "9d4dbbbd2defb7fb", - "type": "subflow:a59054999730c251", - "z": "ec55121054ad7072", - "d": true, - "g": "0bd29a38bd7fd7ee", - "name": "Model - genai - llama-cpp-mistral-8x", - "env": [ - { - "name": "Id", - "value": "genai-llama-cpp-mistral-8x", - "type": "str" - }, + "id": "46b306f2e48bb850", + "type": "http request", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "", + "method": "GET", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "41aad7d8f71cd6e6", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [ { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", - "type": "str" + "keyType": "other", + "keyValue": "X-API-Key", + "valueType": "msg", + "valueValue": "token" } ], - "x": 440, - "y": 580, + "x": 570, + "y": 280, "wires": [ [ - "a98ec39f0f7f2c84" + "7887225ee569137c" ] ] }, { - "id": "0a39bb73f010efd7", + "id": "733507b741691f58", + "type": "inject", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Fetch", + "props": [], + "repeat": "", + "crontab": "", + "once": true, + "onceDelay": "0.5", + "topic": "", + "x": 150, + "y": 280, + "wires": [ + [ + "6fc0878730035324", + "4534e2dfa3d348df" + ] + ] + }, + { + "id": "7887225ee569137c", "type": "function", - "z": "ec55121054ad7072", - "name": "Admin Prompt", - "func": "msg.systemPrompt = `## Mandate\n\nYou are an AI Administrator.\n\nYour mandate is to manage a collective of AI Operators in order to accomplish the goal of any requests from the User.\n\nWhen a goal is too complex or you lack the requisite abilities for you to accomplish it on your own, break the goal down into one or more smaller tasks and assign each task to an Operator.\n\nIn addition to requests from the User, Operators may also send you messages or requests. Unlike requests from the User, you may choose whether and how to respond to messages and requests from Operators.\n\nEvery response must conclude with an tag.\n\n## Commands\n\nManage the collective of Operators using the Operator API. Send commands to the API as a JSON object wrapped in tags. Messages from operators will be given to you wrapped in tags.\n\n## Operator API Docs\n\n### Create an Operator\n\n\\`\\`\\`\n\n{\n \"method\": \"POST\",\n \"path\": \"/operators\",\n \"body\": {\n \"id\": \"06f86c9a-1fe6-4c74-8939-30e64cb1edbb\",\n \"name\": \"My First Operator\"\n }\n}\n\n\\`\\`\\`\n\n### Message an Operator\n\n\\`\\`\\`\n\n{\n \"method\": \"POST\",\n \"path\": \"/operators/06f86c9a-1fe6-4c74-8939-30e64cb1edbb/messages\",\n \"body\": {\n \"content\": \"Sign up for an account at the following website: https://www.example.com\"\n }\n}\n\n\\`\\`\\`\n\n### Delete an Operator\n\n\\`\\`\\`\n\n{\n \"method\": \"DELETE\",\n \"path\": \"/operators/06f86c9a-1fe6-4c74-8939-30e64cb1edbb\",\n \"body\": {}\n}\n\n\\`\\`\\`\n\n\n`;\n\nreturn msg;\n", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Save Endpoints", + "func": "var instances = [];\nmsg.payload.forEach(function(endpoint) {\n var obj = {};\n obj[endpoint.Name] = endpoint.Id;\n instances.push(obj)\n});\nflow.set('portainer_endpoints', instances);\nmsg.payload = instances[0];\nmsg.options = instances;\nreturn msg;", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 140, - "y": 400, + "x": 780, + "y": 280, "wires": [ - [ - "0a34e1dce381f16b" - ] + [] ] }, { - "id": "4de07154c6644063", - "type": "subflow:f19bc65164444615", - "z": "ec55121054ad7072", - "name": "Operator Histories", - "env": [ + "id": "9f7f53505a88dbb1", + "type": "http request", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "", + "method": "GET", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "41aad7d8f71cd6e6", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [ { - "name": "Factory Id", - "value": "operators", - "type": "str" + "keyType": "other", + "keyValue": "X-API-Key", + "valueType": "msg", + "valueValue": "token" } ], - "x": 890, - "y": 600, + "x": 570, + "y": 340, "wires": [ [ - "94206e52b6f654bd", - "941ab8d26359e8b3" + "374c4ab5a3ae97c7" ] ] }, { - "id": "3f33490320859b09", - "type": "switch", - "z": "ec55121054ad7072", - "name": "Response tag", - "property": "tag", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "operator-api", - "vt": "str" - } - ], - "checkall": "true", - "repair": false, + "id": "fdb9b09540cd5ba6", + "type": "function", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Endpoint", + "func": "\nmsg.url = flow.get('server_url')+'/api/endpoints/'+msg.payload+'/docker/containers/json?all=true';\nmsg.token = flow.get('portainer_jwt');\nreturn msg;", "outputs": 1, - "x": 880, - "y": 240, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 390, + "y": 340, "wires": [ [ - "1ec42373eea9f5ff" + "9f7f53505a88dbb1" ] ] }, { - "id": "1ec42373eea9f5ff", + "id": "374c4ab5a3ae97c7", "type": "function", - "z": "ec55121054ad7072", - "name": "Parse operator API", - "func": "let apiMsg;\ntry {\n apiMsg = JSON.parse(msg.content);\n}\ncatch (e) {\n throw new Error(`Error parsing operator AI call: ${msg.content} - ${e}`);\n}\n\nreturn {\n ...msg,\n ...apiMsg\n};\n", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Options", + "func": "msg.options = msg.payload.map((item)=>{\n let obj = {};\n obj[item.Names[0]] = item.Id;\n return obj;\n})\nreturn msg;", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 890, + "x": 770, "y": 340, "wires": [ - [ - "17e432a11037e949" - ] + [] ] }, { - "id": "17e432a11037e949", - "type": "switch", - "z": "ec55121054ad7072", - "name": "Operator API - Path", - "property": "path", - "propertyType": "msg", + "id": "75a002efe0c1f011", + "type": "change", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Save Container", "rules": [ { - "t": "regex", - "v": "^/operators(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})?$", - "vt": "str", - "case": true - }, - { - "t": "regex", - "v": "^/operators/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/messages$", - "vt": "str", - "case": true + "t": "set", + "p": "portainer_container", + "pt": "flow", + "to": "payload", + "tot": "msg" } ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 890, - "y": 440, + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1240, + "y": 340, "wires": [ [ - "1e437fb36b5c0ea1" - ], - [ - "da042c7a27dcbd9f" + "df970663c1614b1d" ] - ], - "outputLabels": [ - "Operators", - "Operators/Messages" ] }, { - "id": "1e437fb36b5c0ea1", - "type": "switch", - "z": "ec55121054ad7072", - "name": "Operators Method", - "property": "method", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "POST", - "vt": "str" - }, - { - "t": "eq", - "v": "DELETE", - "vt": "str" - } - ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 1110, - "y": 420, - "wires": [ - [ - "2c04b0bb076a5230" - ], - [] - ] - }, - { - "id": "2c04b0bb076a5230", + "id": "84cb3dac9b9f5d39", "type": "function", - "z": "ec55121054ad7072", - "name": "Create operator", - "func": "msg = {\n action: \"prog-history-init\",\n historyId: msg.body?.id\n};\n\nreturn msg;\n", - "outputs": 1, - "timeout": 0, + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Url", + "func": "let endpoint = flow.get('portainer_endpoint');\nlet container = flow.get('portainer_container');\nlet startOrStop = msg.payload ? 'start' : 'stop';\nif(!endpoint || !container){\n return [null, { payload: \"Either endpoint or container not selected\", status: !msg.payload}]\n}else{\n msg.url = flow.get('server_url') +'/api/endpoints/' + endpoint + '/docker/containers/'+container+'/'+startOrStop;\n msg.token = flow.get('portainer_jwt');\n return [msg,null]\n}", + "outputs": 2, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1380, - "y": 360, + "x": 750, + "y": 480, "wires": [ [ - "40557c67b6ce1c09" - ] + "b56089ef7ebdddf2" + ], + [] ] }, { - "id": "da042c7a27dcbd9f", - "type": "switch", - "z": "ec55121054ad7072", - "name": "Operators/Messages Method", - "property": "method", - "propertyType": "msg", + "id": "909a59dbc05a2fad", + "type": "change", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Save Container", "rules": [ { - "t": "eq", - "v": "POST", - "vt": "str" + "t": "set", + "p": "portainer_endpoint", + "pt": "flow", + "to": "payload", + "tot": "msg" } ], - "checkall": "true", - "repair": false, - "outputs": 1, - "x": 1140, - "y": 460, + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1240, + "y": 280, "wires": [ - [ - "2d1212f366ac2dec" - ] + [] ] }, { - "id": "a2eae6bb6671163b", + "id": "14dab9180b245706", "type": "function", - "z": "ec55121054ad7072", - "name": "Add Admin Message", - "func": "msg = {\n action: \"prog-history-add-entry\",\n entry: {\n role: \"user\",\n content: msg.createAdminMessagePrompt(msg.body?.content)\n },\n id: msg.path.split('/')[2]\n};\n\nreturn msg;\n", + "z": "f6f2187d.f17ca8", + "g": "d3ea6600f7f1c7d6", + "name": "Reset", + "func": "flow.set('portainer_endpoint', null);\nflow.set('portainer_container',null);\nreturn msg;", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1400, - "y": 540, + "x": 1090, + "y": 120, "wires": [ - [ - "4de07154c6644063" - ] + [] ] }, { - "id": "2d1212f366ac2dec", - "type": "function", - "z": "ec55121054ad7072", - "name": "Admin message prompt template", - "func": "msg.createAdminMessagePrompt = message => {\n return `${message}`;\n};\n\nreturn msg;\n", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1440, - "y": 500, + "id": "1ed0f9b52a08f533", + "type": "link in", + "z": "f6f2187d.f17ca8", + "g": "d3ea6600f7f1c7d6", + "name": "Reset Link", + "links": [ + "6fc0878730035324" + ], + "x": 955, + "y": 120, "wires": [ [ - "a2eae6bb6671163b" + "14dab9180b245706" ] ] }, { - "id": "ef526c2a80f31eb3", + "id": "6fc0878730035324", + "type": "link out", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Fetch Link", + "mode": "link", + "links": [ + "0c165bf98f40b598", + "1ed0f9b52a08f533" + ], + "x": 265, + "y": 320, + "wires": [] + }, + { + "id": "b56089ef7ebdddf2", + "type": "http request", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "", + "method": "POST", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "41aad7d8f71cd6e6", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [ + { + "keyType": "other", + "keyValue": "X-API-Key", + "valueType": "msg", + "valueValue": "token" + } + ], + "x": 970, + "y": 480, + "wires": [ + [] + ] + }, + { + "id": "60e45a11ede888cb", "type": "function", - "z": "ec55121054ad7072", - "name": "Operator Prompt", - "func": "msg.systemPrompt = `## Mandate\n\nYou are an AI Operator.\n\nYour mandate is to perform any tasks requested of you by your AI Administrator to the best of your ability in order to accomplish the overarching goal of the User.\n\nWhen a task is too complex or you lack the requisite abilities for you to accomplish it on your own, you may ask the Administrator to break the task down into one or more smaller tasks and assign them to Operators.\n\nThis conversation is a complete record of every action you took in performing the task.\n\nEnd all responses with an tag.\n\n## Commands\n\nYou may message the Administrator by wrapping your message in tags. Messages from the Administrator will be given to you wrapped in tags.\n`;\n\nreturn msg;\n", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Button", + "func": "msg.enabled = !!flow.get('portainer_container');\nreturn msg;", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 130, + "x": 390, + "y": 480, + "wires": [ + [] + ] + }, + { + "id": "df970663c1614b1d", + "type": "link out", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Button", + "mode": "link", + "links": [ + "49c1d79c39f3c0a4" + ], + "x": 1385, + "y": 340, + "wires": [] + }, + { + "id": "0c165bf98f40b598", + "type": "link in", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Button Status", + "links": [ + "35aa7e2f151f726c", + "6fc0878730035324" + ], + "x": 95, "y": 480, "wires": [ [ - "0a34e1dce381f16b" + "60e45a11ede888cb" ] ] }, { - "id": "87b70bd29575e8b4", + "id": "a86d84649831b0fc", "type": "function", - "z": "ec55121054ad7072", - "name": " ", - "func": "\nreturn msg;", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Url", + "func": "let endpoint = flow.get('portainer_endpoint');\nlet container = flow.get('portainer_container');\nif (!!endpoint && !!container){\n msg.url = flow.get('server_url') +'/api/endpoints/' + endpoint + '/docker/containers/'+container+'/json';\n msg.token = flow.get('portainer_jwt');\n return msg\n}\nelse\n return null;\n", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 265, - "y": 920, + "x": 370, + "y": 400, "wires": [ [ - "ef526c2a80f31eb3" + "0b6e18ac2c03166b" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "40557c67b6ce1c09", - "type": "function", - "z": "ec55121054ad7072", - "name": " ", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1695, - "y": 540, + "id": "49c1d79c39f3c0a4", + "type": "link in", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Container Selected", + "links": [ + "df970663c1614b1d" + ], + "x": 95, + "y": 400, "wires": [ [ - "4de07154c6644063" + "a86d84649831b0fc" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "a073258f226718b6", - "type": "switch", - "z": "ec55121054ad7072", - "name": "Response tag", - "property": "tag", - "propertyType": "msg", - "rules": [ + "id": "0b6e18ac2c03166b", + "type": "http request", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "", + "method": "GET", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "41aad7d8f71cd6e6", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [ { - "t": "eq", - "v": "operator-message", - "vt": "str" + "keyType": "other", + "keyValue": "X-API-Key", + "valueType": "msg", + "valueValue": "token" } ], - "checkall": "true", - "repair": false, - "outputs": 1, - "x": 880, - "y": 760, + "x": 570, + "y": 400, "wires": [ [ - "2d730859f47f1ceb" + "e6f08d657cfa77a9" ] ] }, { - "id": "94206e52b6f654bd", + "id": "e6f08d657cfa77a9", "type": "function", - "z": "ec55121054ad7072", - "name": " ", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Get Status", + "func": "//msg.payload = msg.payload.State.Running;\nreturn [\n { payload: msg.payload.State.Running},\n { payload: msg.payload.State.Status},\n { payload: msg.payload.State.Health.Status },\n { payload: msg.payload.State.StartedAt}\n];", + "outputs": 4, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 715, - "y": 680, + "x": 770, + "y": 400, "wires": [ [ - "87b70bd29575e8b4" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + "35aa7e2f151f726c" + ], + [], + [], + [] + ] }, { - "id": "8ad28cb311d8a5c0", - "type": "subflow:240cc03734c17fa7", - "z": "ec55121054ad7072", - "name": "Parse Admin Response", - "x": 900, - "y": 160, + "id": "72d2e05a0acd3fa8", + "type": "delay", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "", + "pauseType": "delay", + "timeout": "0.1", + "timeoutUnits": "seconds", + "rate": "1", + "nbRateUnits": "1", + "rateUnits": "second", + "randomFirst": "1", + "randomLast": "5", + "randomUnits": "seconds", + "drop": false, + "allowrate": false, + "outputs": 1, + "x": 570, + "y": 540, "wires": [ - [ - "3f33490320859b09" - ] + [] ] }, { - "id": "941ab8d26359e8b3", - "type": "subflow:240cc03734c17fa7", - "z": "ec55121054ad7072", - "name": "Parse Operator Response", - "x": 910, - "y": 680, + "id": "35aa7e2f151f726c", + "type": "link out", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Button", + "mode": "link", + "links": [ + "0c165bf98f40b598" + ], + "x": 915, + "y": 380, + "wires": [] + }, + { + "id": "f1c8fbcb6c326e46", + "type": "inject", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Update Status", + "props": [], + "repeat": "5", + "crontab": "", + "once": true, + "onceDelay": "0.5", + "topic": "", + "x": 180, + "y": 360, "wires": [ [ - "a073258f226718b6" + "a86d84649831b0fc", + "bfb495bb4ca9ae6f" ] ] }, { - "id": "2d730859f47f1ceb", + "id": "bfb495bb4ca9ae6f", "type": "function", - "z": "ec55121054ad7072", - "name": "Operator message prompt template", - "func": "msg.createOperatorMessagePrompt = (id, message) => {\n return `${message}`;\n};\n\nreturn msg;\n", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Url", + "func": "let endpoint = flow.get('portainer_endpoint');\nlet container = flow.get('portainer_container');\nif (!!endpoint && !!container){\n msg.url = flow.get('server_url') +'/api/endpoints/' + endpoint + '/docker/containers/' + container +'/stats?stream=false&one-shot=false';\n msg.token = flow.get('portainer_jwt');\n return msg\n}\nelse\n return null;\n", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1420, - "y": 700, + "x": 370, + "y": 580, "wires": [ [ - "134cfbd5d2b56837" + "6026847cd96ce18c" ] ] }, { - "id": "134cfbd5d2b56837", + "id": "6026847cd96ce18c", + "type": "http request", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "", + "method": "GET", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "41aad7d8f71cd6e6", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [ + { + "keyType": "other", + "keyValue": "X-API-Key", + "valueType": "msg", + "valueValue": "token" + } + ], + "x": 590, + "y": 580, + "wires": [ + [ + "12ca61074a76e5dd", + "d8c78c08e407231e" + ] + ] + }, + { + "id": "12ca61074a76e5dd", "type": "function", - "z": "ec55121054ad7072", - "name": "Add Operator Message", - "func": "msg = {\n action: \"history-add-entry\",\n entry: {\n role: \"user\",\n content: msg.createOperatorMessagePrompt(msg.agentId, msg.content)\n }\n};\n\nreturn msg;\n", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "CPU Usage", + "func": "var stats = msg.payload;\nif(!!stats){\n var cpu_delta = stats.cpu_stats.cpu_usage.total_usage - stats.precpu_stats.cpu_usage.total_usage;\n var system_cpu_delta = stats.cpu_stats.system_cpu_usage - stats.precpu_stats.system_cpu_usage;\n var number_cpus = stats.cpu_stats.online_cpus;\n // msg.payload = { data: [stats, cpu_delta, system_cpu_delta, number_cpus]}\n msg.payload = Number((cpu_delta === 0? 0 : (cpu_delta / system_cpu_delta) * number_cpus * 100.0).toFixed(2));\n return msg;\n}\nelse\n return null", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1390, - "y": 740, + "x": 770, + "y": 580, "wires": [ - [ - "13c990f21a453c5a" - ] + [] ] }, { - "id": "d2c9ca4a42af3ba9", + "id": "d8c78c08e407231e", "type": "function", - "z": "ec55121054ad7072", - "name": " ", - "func": "\nreturn msg;", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Memory Usage", + "func": "var stats = msg.payload;\nif(!!stats){\n if (!!stats.memory_stats.stats.cache)\n var used_memory = stats.memory_stats.usage - stats.memory_stats.stats.cache;\n else\n var used_memory = stats.memory_stats.usage - stats.memory_stats.stats.inactive_file\n var available_memory =stats.memory_stats.limit\n // msg.payload = { data: [stats, used_memory, available_memory]}\n msg.payload = Number(((used_memory / available_memory) * 100.000).toFixed(2));\n return msg;\n}\nelse\nreturn null", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 725, - "y": 400, + "x": 780, + "y": 640, "wires": [ [ - "e77e6ed92b6eba12" + "d75002a1564c11aa" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "13c990f21a453c5a", + "id": "d75002a1564c11aa", + "type": "debug", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "debug 1", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 960, + "y": 700, + "wires": [] + }, + { + "id": "bd7eb8ec2a8e0da9", "type": "function", - "z": "ec55121054ad7072", - "name": " ", - "func": "\nreturn msg;", + "z": "f6f2187d.f17ca8", + "g": "f1bf7ba3b4088527", + "name": "Configuration", + "func": "msg.payload = \"ptr_3Wql5OXTh3bhXGW18Bzrk8SjVcr2xmBFXmpciFzR7zI=\"\nmsg.serverUrl = \"https://192.168.0.103:9443\"\nreturn msg;", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1615, - "y": 740, + "x": 390, + "y": 120, "wires": [ [ - "d2c9ca4a42af3ba9" + "3b853d53f8b1fb4d", + "d3e4f8597b868498" ] + ] + }, + { + "id": "d3e4f8597b868498", + "type": "change", + "z": "f6f2187d.f17ca8", + "g": "f1bf7ba3b4088527", + "name": "Save URL", + "rules": [ + { + "t": "set", + "p": "server_url", + "pt": "flow", + "to": "serverUrl", + "tot": "msg" + } ], - "icon": "font-awesome/fa-arrows", - "l": false + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 770, + "y": 160, + "wires": [ + [] + ] }, { - "id": "d7625ef95dd891b8", + "id": "4534e2dfa3d348df", "type": "function", - "z": "ec55121054ad7072", - "name": "Init Operator Histories", - "func": "\nreturn {\n action: \"prog-factory-init\"\n};\n", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set URL", + "func": "msg.url = flow.get('server_url') + '/api/endpoints'\nmsg.token = flow.get('portainer_jwt');\nreturn msg;", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 420, - "y": 100, + "x": 380, + "y": 280, "wires": [ [ - "b6cc1b3167117b16" + "46b306f2e48bb850" ] ] } diff --git a/packages/node-red-data/.flows_cred.json.backup b/packages/node-red-data/.flows_cred.json.backup index 288719d..a1cd31e 100644 --- a/packages/node-red-data/.flows_cred.json.backup +++ b/packages/node-red-data/.flows_cred.json.backup @@ -1,3 +1,3 @@ { - "$": "4f2d5a4527c3773c905afa2a87488b50//t49v2slXl3EY672w5fGdn5zS5FEkD301qbPRKo1QQDuQ3Mr7T959yZSXLPlQ7vm+Pa4SJjZqvZImsiTB8xoJe9nYetS1McBJib1J0O1+Q=" + "$": "1de351385d6545f42f2aafbd8a21f290QYQQy0Hj3pwfgPEfzNh2vuvSE96ksJdTXI8lKENjgunKa0rh33cCMYeMAVGnWo/2XsuOW5dI5yunaD6HzoKcQ18FDp/qy6FlV+Ie98NDN3+/sXb8sqHJihhcN/ouYz/VKAi01oPU1jQR8PdrV1tvjnail8xW+uPL+/i9CTkh+d+G9Lk97GpvPKRcwezSIz0xwbs3fR/9EBT50JDBlWoKYivjI0M9OTbsSlhleoQRiw3Re0NJ6PgV1gGL6VzXKFF6nO/Sm5CA1ucBNM5fpujLSbSHSfkrIGW03FpT1SsLzdLuSlu5kBqybEjj5EOimn9m/iGi4CdTowUQ" } \ No newline at end of file diff --git a/packages/node-red-data/flows.json b/packages/node-red-data/flows.json index 7bbe610..6efbb51 100644 --- a/packages/node-red-data/flows.json +++ b/packages/node-red-data/flows.json @@ -8,9 +8,9 @@ "env": [] }, { - "id": "191694dad2850f37", + "id": "ec55121054ad7072", "type": "tab", - "label": "Iterative Eval 01", + "label": "Admin-Operator", "disabled": false, "info": "", "env": [] @@ -23,6 +23,22 @@ "info": "", "env": [] }, + { + "id": "3b5c9ca1fb9ebf48", + "type": "tab", + "label": "Bash Executor", + "disabled": false, + "info": "", + "env": [] + }, + { + "id": "191694dad2850f37", + "type": "tab", + "label": "Iterative Eval 01", + "disabled": false, + "info": "", + "env": [] + }, { "id": "8518392b3e041cfe", "type": "tab", @@ -40,12 +56,11 @@ "env": [] }, { - "id": "ec55121054ad7072", + "id": "f6f2187d.f17ca8", "type": "tab", - "label": "Admin-Operator", - "disabled": false, - "info": "", - "env": [] + "label": "Portainer Flow", + "disabled": true, + "info": "https://flows.nodered.org/flow/648cb2a8aeb19d1f665d1c0db1e4541b" }, { "id": "9941dd1769d8bb1b", @@ -146,7 +161,7 @@ { "id": "6d317c39edd7ba27", "type": "subflow", - "name": "Send Streaming Request", + "name": "SSE Request", "info": "", "category": "llm request", "in": [ @@ -605,7 +620,7 @@ "type": "subflow", "name": "provide - parseMarkdown", "info": "", - "category": "llm:util", + "category": "llm parsers", "in": [ { "x": 50, @@ -976,24 +991,24 @@ { "id": "f0aa5f2ed7dab3b8", "type": "subflow", - "name": "http request", + "name": "HTTP Request", "info": "", - "category": "llm:util", + "category": "llm request", "in": [ { "x": 80, "y": 60, "wires": [ { - "id": "a94bb02058f6c758" + "id": "1c4e6c80d9868fa0" } ] } ], "out": [ { - "x": 880, - "y": 380, + "x": 1120, + "y": 300, "wires": [ { "id": "3d6d82698400006b", @@ -1004,7 +1019,7 @@ ], "env": [], "meta": {}, - "color": "#E2D96E", + "color": "#3FADB5", "icon": "node-red/white-globe.svg" }, { @@ -1156,22 +1171,22 @@ "type": "subflow", "name": "provide - exractHtmlTags", "info": "", - "category": "llm:util", + "category": "llm parsers", "in": [ { "x": 50, "y": 30.90909093618393, "wires": [ { - "id": "0a432a478665f6a9" + "id": "3d458d6f47d14634" } ] } ], "out": [ { - "x": 500, - "y": 160, + "x": 620, + "y": 260, "wires": [ { "id": "0a432a478665f6a9", @@ -1218,147 +1233,402 @@ "color": "#DDAA99" }, { - "id": "573a66c74ad47252", - "type": "group", - "z": "2b3efcc977e88d91", - "style": { - "stroke": "#999999", - "stroke-opacity": "1", - "fill": "none", - "fill-opacity": "1", - "label": true, - "label-position": "nw", - "color": "#a4a4a4" - }, - "nodes": [ - "24d6b22fbb3331ef", - "fa93074c3844e72a", - "e64c01c3ce72e42c", - "fd30589c82c22c62", - "f99c0d4e42875ff9" + "id": "b9a9b43a3594c357", + "type": "subflow", + "name": "Docker Run", + "info": "", + "category": "Docker", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "1540fd3640a5c2da" + }, + { + "id": "9ead6c09c1634875" + } + ] + } ], - "x": 314, - "y": 459, - "w": 452, - "h": 222 - }, - { - "id": "ffdcd8798ee03933", - "type": "group", - "z": "2b3efcc977e88d91", - "style": { - "stroke": "#999999", - "stroke-opacity": "1", - "fill": "none", - "fill-opacity": "1", - "label": true, - "label-position": "nw", - "color": "#a4a4a4" - }, - "nodes": [ - "d0bc8cbbd38f96d0", - "ed0c2d4f1d21f64c", - "b7a0d2554c54f30c" + "out": [ + { + "x": 1240, + "y": 960, + "wires": [ + { + "id": "b136a36f1f060bab", + "port": 0 + } + ] + } ], - "x": 854, - "y": 779, - "w": 452, - "h": 142 + "env": [ + { + "name": "Container Name", + "type": "str", + "value": "" + }, + { + "name": "Image", + "type": "str", + "value": "ubuntu" + }, + { + "name": "Command", + "type": "json", + "value": "[\"sleep\", \"Infinity\"]" + }, + { + "name": "Docker Run Args", + "type": "json", + "value": "[\"--rm\"]" + }, + { + "name": "Output Mode", + "type": "str", + "value": "stream" + }, + { + "name": "Commit", + "type": "bool", + "value": "false" + } + ], + "meta": {}, + "color": "#D8BFD8", + "icon": "font-awesome/fa-inbox" }, { - "id": "0e803c0423a03bad", - "type": "group", - "z": "2b3efcc977e88d91", - "style": { - "stroke": "#999999", - "stroke-opacity": "1", - "fill": "none", - "fill-opacity": "1", - "label": true, - "label-position": "nw", - "color": "#a4a4a4" - }, - "nodes": [ - "ec546330d29baba3", - "96d1b37cfc101abc" + "id": "5982620408722375", + "type": "subflow", + "name": "Docker Logs", + "info": "", + "category": "", + "in": [ + { + "x": 50, + "y": 30, + "wires": [] + } ], - "x": 854, - "y": 959, - "w": 272, - "h": 142 + "out": [ + { + "x": 820, + "y": 200, + "wires": [] + } + ], + "env": [], + "meta": {}, + "color": "#DDAA99" }, { - "id": "1309c3c5cd6f1b74", - "type": "group", - "z": "2b3efcc977e88d91", - "style": { - "stroke": "#999999", - "stroke-opacity": "1", - "fill": "none", - "fill-opacity": "1", - "label": true, - "label-position": "nw", - "color": "#a4a4a4" - }, - "nodes": [ - "2f187dab7a1ae2ad", - "2c75870eb28bb7c5", - "07a96f21f7eb4899", - "e9e910c0b95eb6fc" + "id": "d5c30c295cb6b7bc", + "type": "subflow", + "name": "Run Command", + "info": "", + "category": "llm:util", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "1c249f69debb918b" + } + ] + } ], - "x": 514, - "y": 759, - "w": 252, - "h": 242 + "out": [ + { + "x": 1240, + "y": 280, + "wires": [ + { + "id": "5be0298a22eb5f2a", + "port": 0 + }, + { + "id": "bee02be8135363fa", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#A6BBCF", + "icon": "font-awesome/fa-terminal" }, { - "id": "3cdc7422abfbe82e", - "type": "group", - "z": "2b3efcc977e88d91", - "style": { - "stroke": "#999999", - "stroke-opacity": "1", - "fill": "none", - "fill-opacity": "1", - "label": true, - "label-position": "nw", - "color": "#a4a4a4" - }, - "nodes": [ - "3b2ca8934fb0ccd7", - "05af6ff6db82adba" + "id": "72ced27310c541f6", + "type": "subflow", + "name": "cURL Request", + "info": "", + "category": "llm request", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "03f57deed86e37c5" + } + ] + } ], - "x": 854, - "y": 239, - "w": 372, - "h": 142 + "out": [ + { + "x": 1020, + "y": 120, + "wires": [ + { + "id": "c7494ed5f552a21e", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#3FADB5", + "icon": "node-red/bridge-dash.svg" }, { - "id": "2ec09f072ab0b146", - "type": "group", - "z": "2b3efcc977e88d91", - "style": { - "stroke": "#999999", - "stroke-opacity": "1", - "fill": "none", - "fill-opacity": "1", - "label": true, - "label-position": "nw", - "color": "#a4a4a4" - }, - "nodes": [ - "b07e294259fdd664", - "c5dcd2bf8b994fb8" + "id": "30eb5320bb41dc49", + "type": "subflow", + "name": "Build HTTP Request", + "info": "", + "category": "llm request", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "3762dbf4e0957cfa" + } + ] + } ], - "x": 854, - "y": 39, - "w": 352, - "h": 122 + "out": [ + { + "x": 360, + "y": 40, + "wires": [ + { + "id": "3762dbf4e0957cfa", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#FFFFFF" }, { - "id": "0e1cb402b61eb646", + "id": "3f4aa860a3b350bc", + "type": "subflow", + "name": "Docker Commit", + "info": "", + "category": "Docker", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "f3d99166630391d1" + } + ] + } + ], + "out": [ + { + "x": 580, + "y": 260, + "wires": [ + { + "id": "9fe7448838c509e5", + "port": 0 + }, + { + "id": "cea8afeae263e378", + "port": 0 + } + ] + } + ], + "env": [ + { + "name": "Container", + "type": "str", + "value": "" + }, + { + "name": "Repository", + "type": "str", + "value": "" + }, + { + "name": "Tag", + "type": "str", + "value": "" + } + ], + "meta": {}, + "color": "#D8BFD8", + "icon": "font-awesome/fa-inbox" + }, + { + "id": "126e4a373d8bcb36", + "type": "subflow", + "name": "Extract HTML Tags", + "info": "", + "category": "llm parsers", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "af3d5caec2de488c" + } + ] + } + ], + "out": [ + { + "x": 440, + "y": 260, + "wires": [ + { + "id": "6d6f8c6f67a318de", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#DEBD5C", + "icon": "node-red/parser-html.svg" + }, + { + "id": "828f5a08b0bcf89d", + "type": "subflow", + "name": "Parse Markdown", + "info": "", + "category": "llm parsers", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "e82cac62a6dcc5e2" + } + ] + } + ], + "out": [ + { + "x": 420, + "y": 200, + "wires": [ + { + "id": "e935f75b3e48ad5e", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#DEBD5C", + "icon": "node-red/hash.svg" + }, + { + "id": "87f7528a5c81b545", + "type": "subflow", + "name": "Import JS Modules", + "info": "

Imports given modules for use in subsequent nodes.

\r\n\r\n

Properties

\r\n\r\n
\r\n
Modulesarray<object | string>
\r\n
Overrides msg.modules.
\r\n
\r\n\r\n

Inputs

\r\n\r\n
\r\n
modulesarray<object | string>
\r\n
A list of modules to import. Modules may be either a string specifying the module name or an\r\n object with the following properties (see:\r\n \r\n import - JavaScript | MDN\r\n \r\n ):\r\n
    \r\n
  • moduleName - The module to import
  • \r\n
  • key? (moduleName) - The key to store the module imports under in importedModules.\r\n
  • defaultExport? (true) - Whether to import the default export. If true, will be\r\n imported as default in the imported module.
  • \r\n
  • namedExports? (*) - An array of named exports to import. A named export may be\r\n either a string specifying an export name, or an object with the following properties:\r\n
      \r\n
    • name - The name of the export.\r\n
    • alias? (name) - The alias to import as.\r\n
    \r\n
  • \r\n
\r\n
\r\n
\r\n\r\n

Outputs

\r\n\r\n
\r\n
importedModulesobject
\r\n
A filtered module namespace object (see:\r\n \r\n import() - JavaScript | MDN #Module namespace object\r\n ) containing only the namedExports and default export (if specified).\r\n
\r\n
\r\n\r\n

Examples

\r\n\r\nWhen given the following `msg` as input:\r\n\r\n```js\r\n{\r\n ...msg,\r\n modules: [\r\n \"colors/safe\",\r\n {\r\n moduleName: \"change-case\",\r\n key: \"changeCase\",\r\n defaultExport: false,\r\n namedExports: [\r\n \"camelCase\",\r\n {\r\n name: \"split\",\r\n alias: \"splitWords\"\r\n }\r\n ]\r\n }\r\n ]\r\n}\r\n```\r\nThe following msg will be output:\r\n```js\r\n{\r\n ...msg,\r\n importedModules: {\r\n \"colors/safe\": {\r\n \"default\": {\r\n themes,\r\n styles,\r\n ...\r\n },\r\n green,\r\n gray,\r\n white,\r\n ...\r\n },\r\n changeCase: {\r\n camelCase,\r\n splitWords\r\n }\r\n }\r\n}\r\n```\r\n", + "category": "llm:util", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "e98dae970d7540c6" + } + ] + } + ], + "out": [ + { + "x": 1060, + "y": 400, + "wires": [ + { + "id": "457ddbfd4780ea1d", + "port": 0 + } + ] + } + ], + "env": [ + { + "name": "Modules", + "type": "json", + "value": "[]" + } + ], + "meta": {}, + "color": "#A6BBCF", + "icon": "font-awesome/fa-sign-in" + }, + { + "id": "d5c98b48f9d2d77f", + "type": "subflow", + "name": "Decode HTML Entities", + "info": "", + "category": "llm parsers", + "in": [ + { + "x": 50, + "y": 30, + "wires": [ + { + "id": "4432567301785438" + } + ] + } + ], + "out": [ + { + "x": 500, + "y": 140, + "wires": [ + { + "id": "e5c508b6228990f4", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#DEBD5C", + "icon": "font-awesome/fa-file-code-o" + }, + { + "id": "573a66c74ad47252", "type": "group", - "z": "9e23ccbf2e0608ed", + "z": "2b3efcc977e88d91", "style": { "stroke": "#999999", "stroke-opacity": "1", @@ -1369,21 +1639,19 @@ "color": "#a4a4a4" }, "nodes": [ - "c0c36621780669a4", - "977f9402195729c4", - "8ec4c35df45a28c5", - "aaf9af66d3e39da8", - "378e8541feaf87ec", - "45671622e142be7e", - "33ca3631b9af0d55" + "24d6b22fbb3331ef", + "fa93074c3844e72a", + "e64c01c3ce72e42c", + "fd30589c82c22c62", + "f99c0d4e42875ff9" ], - "x": 248, - "y": 379, - "w": 438, - "h": 408 + "x": 314, + "y": 459, + "w": 452, + "h": 222 }, { - "id": "8a3c592536de3111", + "id": "ffdcd8798ee03933", "type": "group", "z": "2b3efcc977e88d91", "style": { @@ -1396,18 +1664,19 @@ "color": "#a4a4a4" }, "nodes": [ - "e71f5a20f7b7837e", - "c8c9a2cca8781c5f" + "d0bc8cbbd38f96d0", + "ed0c2d4f1d21f64c", + "b7a0d2554c54f30c" ], "x": 854, - "y": 419, - "w": 332, + "y": 779, + "w": 452, "h": 142 }, { - "id": "83fd8826b0ec3bf4", + "id": "0e803c0423a03bad", "type": "group", - "z": "191694dad2850f37", + "z": "2b3efcc977e88d91", "style": { "stroke": "#999999", "stroke-opacity": "1", @@ -1418,23 +1687,18 @@ "color": "#a4a4a4" }, "nodes": [ - "c85c2df7d79465a0", - "73516493eccdfd9d", - "f762ec936046e78f", - "ce1b28a464e3b3b3", - "81b98c3380c57334", - "d48b052e253b43c3", - "93859b35073996c8" + "ec546330d29baba3", + "96d1b37cfc101abc" ], - "x": 74, - "y": 579, - "w": 592, - "h": 368 + "x": 854, + "y": 959, + "w": 272, + "h": 142 }, { - "id": "0e31504694a6eb0c", + "id": "1309c3c5cd6f1b74", "type": "group", - "z": "191694dad2850f37", + "z": "2b3efcc977e88d91", "style": { "stroke": "#999999", "stroke-opacity": "1", @@ -1445,13 +1709,157 @@ "color": "#a4a4a4" }, "nodes": [ - "9d0d59cbd0342094", - "b67aacc8e54e5106", - "c533acab9a1bba89", - "8565c4a9a8c13312" + "2f187dab7a1ae2ad", + "2c75870eb28bb7c5", + "07a96f21f7eb4899", + "e9e910c0b95eb6fc" ], - "x": 74, - "y": 39, + "x": 514, + "y": 759, + "w": 252, + "h": 242 + }, + { + "id": "3cdc7422abfbe82e", + "type": "group", + "z": "2b3efcc977e88d91", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "3b2ca8934fb0ccd7", + "05af6ff6db82adba" + ], + "x": 854, + "y": 239, + "w": 372, + "h": 142 + }, + { + "id": "2ec09f072ab0b146", + "type": "group", + "z": "2b3efcc977e88d91", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "b07e294259fdd664", + "c5dcd2bf8b994fb8" + ], + "x": 854, + "y": 39, + "w": 352, + "h": 122 + }, + { + "id": "0e1cb402b61eb646", + "type": "group", + "z": "9e23ccbf2e0608ed", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "c0c36621780669a4", + "977f9402195729c4", + "8ec4c35df45a28c5", + "aaf9af66d3e39da8", + "378e8541feaf87ec", + "45671622e142be7e", + "33ca3631b9af0d55" + ], + "x": 248, + "y": 379, + "w": 438, + "h": 408 + }, + { + "id": "8a3c592536de3111", + "type": "group", + "z": "2b3efcc977e88d91", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "e71f5a20f7b7837e", + "c8c9a2cca8781c5f" + ], + "x": 854, + "y": 419, + "w": 332, + "h": 142 + }, + { + "id": "83fd8826b0ec3bf4", + "type": "group", + "z": "191694dad2850f37", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "c85c2df7d79465a0", + "73516493eccdfd9d", + "f762ec936046e78f", + "ce1b28a464e3b3b3", + "81b98c3380c57334", + "d48b052e253b43c3", + "93859b35073996c8" + ], + "x": 74, + "y": 579, + "w": 592, + "h": 368 + }, + { + "id": "0e31504694a6eb0c", + "type": "group", + "z": "191694dad2850f37", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "9d0d59cbd0342094", + "b67aacc8e54e5106", + "c533acab9a1bba89", + "8565c4a9a8c13312" + ], + "x": 74, + "y": 39, "w": 512, "h": 162 }, @@ -1768,6 +2176,192 @@ "w": 438, "h": 408 }, + { + "id": "f1bf7ba3b4088527", + "type": "group", + "z": "f6f2187d.f17ca8", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "0dd8b704b63c96a1", + "3b853d53f8b1fb4d", + "bd7eb8ec2a8e0da9", + "d3e4f8597b868498" + ], + "x": 54, + "y": 79, + "w": 812, + "h": 122 + }, + { + "id": "856e8d2dc2416b46", + "type": "group", + "z": "f6f2187d.f17ca8", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "46b306f2e48bb850", + "733507b741691f58", + "7887225ee569137c", + "9f7f53505a88dbb1", + "fdb9b09540cd5ba6", + "374c4ab5a3ae97c7", + "75a002efe0c1f011", + "84cb3dac9b9f5d39", + "909a59dbc05a2fad", + "6fc0878730035324", + "b56089ef7ebdddf2", + "60e45a11ede888cb", + "df970663c1614b1d", + "0c165bf98f40b598", + "a86d84649831b0fc", + "49c1d79c39f3c0a4", + "0b6e18ac2c03166b", + "e6f08d657cfa77a9", + "72d2e05a0acd3fa8", + "35aa7e2f151f726c", + "f1c8fbcb6c326e46", + "bfb495bb4ca9ae6f", + "6026847cd96ce18c", + "12ca61074a76e5dd", + "d8c78c08e407231e", + "d75002a1564c11aa", + "4534e2dfa3d348df" + ], + "x": 54, + "y": 239, + "w": 1372, + "h": 502 + }, + { + "id": "d3ea6600f7f1c7d6", + "type": "group", + "z": "f6f2187d.f17ca8", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "14dab9180b245706", + "1ed0f9b52a08f533" + ], + "x": 914, + "y": 79, + "w": 252, + "h": 82 + }, + { + "id": "f7696f05d57ef7a1", + "type": "group", + "z": "3b5c9ca1fb9ebf48", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "d3eca839cbbe8f34", + "d4ebbd593cf64e04", + "c2b3e2bf431804bd", + "a7de977d7732152e", + "8ef6bd83dbaa3d85", + "4c7815cb04fa305a", + "3e0ce960e9b660a1" + ], + "x": 88, + "y": 599, + "w": 438, + "h": 408 + }, + { + "id": "e18c67f0ba18707b", + "type": "group", + "z": "3fb1b07be44ed756", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "b75f0d8130661559", + "26a114fc27cd90b0", + "ea2d35fce99de4ae", + "8f75c3504c3dbc5f", + "e22d75a202b3a7d9", + "233b190c4bba2abc", + "18e60cf6d75b5c02", + "366fdac4502597e4", + "f58a612cea662f7f", + "3163545a452b8023", + "f4e0940a4675e15a", + "d5dd065101ef890a", + "4a5b440f0562c4c5", + "437a9435e7f7839a", + "234a56ef02849517", + "bd0ab9ac636bddf7", + "4b1052f331f48638", + "f119a534c23868e3", + "7e92245bb06f8113", + "a11718080bf06447", + "11de70778f4fcccb" + ], + "x": 794, + "y": 299, + "w": 842, + "h": 502 + }, + { + "id": "d20e17ae1f88e910", + "type": "group", + "z": "3b5c9ca1fb9ebf48", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "dd6437290fd336e7", + "7ab56a5e25543ac8", + "583705d65356bc91", + "5ae745cf98b55950", + "35a1e0a9c30682f6" + ], + "x": 534, + "y": 1394, + "w": 412, + "h": 147 + }, { "id": "aaf9af66d3e39da8", "type": "group", @@ -1888,6 +2482,30 @@ "w": 372, "h": 122 }, + { + "id": "a7de977d7732152e", + "type": "group", + "z": "3b5c9ca1fb9ebf48", + "g": "f7696f05d57ef7a1", + "style": { + "stroke": "#999999", + "stroke-opacity": "1", + "fill": "none", + "fill-opacity": "1", + "label": true, + "label-position": "nw", + "color": "#a4a4a4" + }, + "nodes": [ + "1c9144b2ef0b4dd5", + "399f0d05531fcfd6", + "504106b997f60dbe" + ], + "x": 114, + "y": 859, + "w": 372, + "h": 122 + }, { "id": "b6cc1b3167117b16", "type": "junction", @@ -1901,9 +2519,134 @@ ] }, { - "id": "abd5674a230a71e1", - "type": "function", - "z": "9941dd1769d8bb1b", + "id": "b3c027b1a78e62ca", + "type": "junction", + "z": "d5c30c295cb6b7bc", + "x": 480, + "y": 340, + "wires": [ + [ + "5be0298a22eb5f2a" + ] + ] + }, + { + "id": "cf1db7761982b2fc", + "type": "junction", + "z": "b9a9b43a3594c357", + "x": 540, + "y": 720, + "wires": [ + [ + "5a94f86438968b9b" + ] + ] + }, + { + "id": "583705d65356bc91", + "type": "junction", + "z": "3b5c9ca1fb9ebf48", + "g": "d20e17ae1f88e910", + "x": 920, + "y": 1460, + "wires": [ + [ + "5ae745cf98b55950" + ] + ] + }, + { + "id": "b136a36f1f060bab", + "type": "junction", + "z": "b9a9b43a3594c357", + "x": 1140, + "y": 960, + "wires": [ + [ + "0a96edc6fd08333b" + ] + ] + }, + { + "id": "7ab56a5e25543ac8", + "type": "junction", + "z": "3b5c9ca1fb9ebf48", + "g": "d20e17ae1f88e910", + "x": 600, + "y": 1420, + "wires": [ + [ + "8249b529648a77f1" + ] + ] + }, + { + "id": "35a1e0a9c30682f6", + "type": "junction", + "z": "3b5c9ca1fb9ebf48", + "g": "d20e17ae1f88e910", + "x": 560, + "y": 1500, + "wires": [ + [ + "940cc0ae14188d1c" + ] + ] + }, + { + "id": "824ad7c29ee4fd68", + "type": "junction", + "z": "3b5c9ca1fb9ebf48", + "x": 900, + "y": 460, + "wires": [ + [ + "3856fb6b7a093891" + ] + ] + }, + { + "id": "63a5c80a9677a5e8", + "type": "junction", + "z": "3b5c9ca1fb9ebf48", + "x": 940, + "y": 1260, + "wires": [ + [ + "a08be90792caa2ef" + ] + ] + }, + { + "id": "a02641d0cd9d6dbe", + "type": "junction", + "z": "3b5c9ca1fb9ebf48", + "x": 940, + "y": 1100, + "wires": [ + [ + "f2d99994f035a684" + ] + ] + }, + { + "id": "41aad7d8f71cd6e6", + "type": "tls-config", + "name": "", + "cert": "", + "key": "", + "ca": "", + "certname": "", + "keyname": "", + "caname": "localhost.crt", + "servername": "", + "verifyservercert": false, + "alpnprotocol": "" + }, + { + "id": "abd5674a230a71e1", + "type": "function", + "z": "9941dd1769d8bb1b", "name": "Inject context", "func": "const toInject = Object.fromEntries(\n env.get(\"Keys\").map(k => [k, flow.get(`$parent.${k}`)])\n);\n\nmsg = {\n ...msg,\n ...toInject\n};\n\nreturn msg;", "outputs": 1, @@ -5400,7 +6143,7 @@ "id": "8bfba49dc9b231a0", "type": "http request", "z": "f0aa5f2ed7dab3b8", - "name": "Send request", + "name": "Body request / json response", "method": "use", "ret": "obj", "paytoqs": "ignore", @@ -5412,50 +6155,28 @@ "authType": "", "senderr": false, "headers": [], - "x": 570, - "y": 220, + "x": 580, + "y": 240, "wires": [ [ "3d6d82698400006b" ] ] }, - { - "id": "a94bb02058f6c758", - "type": "function", - "z": "f0aa5f2ed7dab3b8", - "name": "Build request", - "func": "// we should just be able to disable this -- stupid\nmsg.requestTimeout = 60 * 60 * 1000;\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 570, - "y": 180, - "wires": [ - [ - "8bfba49dc9b231a0", - "cb132b2beb3c794e", - "4d595b2ab5d73f41" - ] - ] - }, { "id": "3d6d82698400006b", "type": "function", "z": "f0aa5f2ed7dab3b8", "name": "Handle response", - "func": "// if this is a forward messge\nif (msg.action == \"forward-msg\") {\n // save our msg for later\n msg.action = msg.msgAction;\n delete msg.msgAction;\n context.set(\"forwardedMsg\", msg);\n // don't send anything for now\n return;\n}\n\n// get any forwarded input we might have\nconst forwardedMsg = context.get(\"forwardedMsg\");\n\n// if an error occurred\nif (typeof msg.statusCode == \"string\") {\n return {\n action: \"http-error\",\n error: msg.payload,\n msgIn: forwardedMsg\n };\n}\n\n// else, we at least got a response\n// if it was an error response\nif (msg.statusCode >= 400) {\n return {\n action: \"http-error\",\n error: msg.payload,\n msgIn: forwardedMsg\n };\n}\n\n// else, we got a successful response\nreturn {\n ...msg,\n action: \"http-success\",\n msgIn: forwardedMsg\n};\n", + "func": "// if this is a forward messge\nif (msg.action == \"forward-msg\") {\n // save our msg for later\n msg.action = msg.msgAction;\n delete msg.msgAction;\n context.set(\"forwardedMsg\", msg);\n // don't send anything for now\n return;\n}\n\n// get any forwarded input we might have\nconst forwardedMsg = context.get(\"forwardedMsg\");\n\n// if an error occurred\nif (typeof msg.statusCode == \"string\") {\n return {\n action: \"http-error\",\n error: msg.payload,\n msgIn: forwardedMsg\n };\n}\n\n// else, we at least got a response\n// if it was an error response\nif (msg.statusCode >= 400) {\n return {\n action: \"http-error\",\n error: msg.payload,\n msgIn: forwardedMsg\n };\n}\n\n// else, we got a successful response\nreturn {\n ...msg,\n action: \"http-success\",\n content: msg.payload,\n msgIn: forwardedMsg\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 590, - "y": 260, + "x": 930, + "y": 360, "wires": [ [] ] @@ -5472,40 +6193,19 @@ "initialize": "", "finalize": "", "libs": [], - "x": 350, - "y": 260, + "x": 710, + "y": 180, "wires": [ [ "3d6d82698400006b" ] ] }, - { - "id": "cb132b2beb3c794e", - "type": "function", - "z": "f0aa5f2ed7dab3b8", - "name": " ", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 295, - "y": 220, - "wires": [ - [ - "3979567024f92d8a" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false - }, { "id": "4d595b2ab5d73f41", "type": "debug", "z": "f0aa5f2ed7dab3b8", + "d": true, "name": "HTTP Requests", "active": true, "tosidebar": true, @@ -5515,108 +6215,308 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 800, - "y": 180, + "x": 480, + "y": 80, "wires": [] }, { - "id": "446ec29fe6cf3270", + "id": "477f39c216daeebe", + "type": "http request", + "z": "f0aa5f2ed7dab3b8", + "name": "Querystring request / json response", + "method": "GET", + "ret": "obj", + "paytoqs": "query", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 600, + "y": 280, + "wires": [ + [ + "3d6d82698400006b" + ] + ] + }, + { + "id": "6f50302a0314605e", "type": "switch", - "z": "a4137713471da6c4", - "name": "Action", - "property": "action", - "propertyType": "msg", + "z": "f0aa5f2ed7dab3b8", + "name": "Payload Response Mode", + "property": "msg.payloadResponseMode", + "propertyType": "jsonata", "rules": [ { "t": "eq", - "v": "history-add-entry", + "v": "body-json", "vt": "str" }, { "t": "eq", - "v": "vector-store-search", + "v": "querystring-json", "vt": "str" }, { "t": "eq", - "v": "history-init", + "v": "body-text", "vt": "str" }, { - "t": "else" + "t": "eq", + "v": "querystring-text", + "vt": "str" + }, + { + "t": "eq", + "v": "body-buffer", + "vt": "str" + }, + { + "t": "eq", + "v": "querystring-buffer", + "vt": "str" } ], "checkall": "true", "repair": false, - "outputs": 4, - "x": 210, - "y": 280, + "outputs": 6, + "x": 250, + "y": 360, "wires": [ [ - "87b2fd9be71c70e8" + "8bfba49dc9b231a0" ], [ - "2ef9041ac1eff817" + "477f39c216daeebe" ], [ - "a96c909aaf955b96" + "82eed4434b86a830" ], [ - "a57a1ec5360af43f" + "47e72b16872c9c29" + ], + [ + "eb064815eab65390" + ], + [ + "6b3fa08227a4a132" ] ] }, { - "id": "c2c1a70fd9f36e28", - "type": "subflow:74bd10ee8e354d0a", - "z": "a4137713471da6c4", - "name": "", - "x": 820, - "y": 260, + "id": "82eed4434b86a830", + "type": "http request", + "z": "f0aa5f2ed7dab3b8", + "name": "Body request / string response", + "method": "use", + "ret": "txt", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 590, + "y": 340, "wires": [ [ - "5511b481a5af2321" + "3d6d82698400006b" ] ] }, { - "id": "a96c909aaf955b96", - "type": "function", - "z": "a4137713471da6c4", - "name": "Set init props", - "func": "msg.historyNew = env.get(\"New\") || msg.historyNew;\nmsg.historySourceFilename = env.get(\"SourceFilename\") || msg.historySourceFilename;\nmsg.historyId = env.get(\"Id\") || msg.historyId;\n\nreturn msg;\n", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 430, - "y": 400, + "id": "47e72b16872c9c29", + "type": "http request", + "z": "f0aa5f2ed7dab3b8", + "name": "Querystring request / string response", + "method": "GET", + "ret": "txt", + "paytoqs": "query", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 610, + "y": 380, "wires": [ [ - "c2c1a70fd9f36e28" + "3d6d82698400006b" ] ] }, { - "id": "736a5f71119f063f", - "type": "switch", - "z": "a4137713471da6c4", - "name": "history-add-entry role", - "property": "entryRole", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "user", - "vt": "str" - }, - { - "t": "else" - } - ], - "checkall": "true", + "id": "eb064815eab65390", + "type": "http request", + "z": "f0aa5f2ed7dab3b8", + "name": "Body request / buffer response", + "method": "use", + "ret": "bin", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 590, + "y": 440, + "wires": [ + [ + "3d6d82698400006b" + ] + ] + }, + { + "id": "6b3fa08227a4a132", + "type": "http request", + "z": "f0aa5f2ed7dab3b8", + "name": "Querystring request / buffer response", + "method": "GET", + "ret": "bin", + "paytoqs": "query", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 610, + "y": 480, + "wires": [ + [ + "3d6d82698400006b" + ] + ] + }, + { + "id": "1c4e6c80d9868fa0", + "type": "subflow:30eb5320bb41dc49", + "z": "f0aa5f2ed7dab3b8", + "name": "", + "x": 250, + "y": 100, + "wires": [ + [ + "4d595b2ab5d73f41", + "6f50302a0314605e", + "3979567024f92d8a" + ] + ] + }, + { + "id": "446ec29fe6cf3270", + "type": "switch", + "z": "a4137713471da6c4", + "name": "Action", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "history-add-entry", + "vt": "str" + }, + { + "t": "eq", + "v": "vector-store-search", + "vt": "str" + }, + { + "t": "eq", + "v": "history-init", + "vt": "str" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 4, + "x": 210, + "y": 280, + "wires": [ + [ + "87b2fd9be71c70e8" + ], + [ + "2ef9041ac1eff817" + ], + [ + "a96c909aaf955b96" + ], + [ + "a57a1ec5360af43f" + ] + ] + }, + { + "id": "c2c1a70fd9f36e28", + "type": "subflow:74bd10ee8e354d0a", + "z": "a4137713471da6c4", + "name": "", + "x": 820, + "y": 260, + "wires": [ + [ + "5511b481a5af2321" + ] + ] + }, + { + "id": "a96c909aaf955b96", + "type": "function", + "z": "a4137713471da6c4", + "name": "Set init props", + "func": "msg.historyNew = env.get(\"New\") || msg.historyNew;\nmsg.historySourceFilename = env.get(\"SourceFilename\") || msg.historySourceFilename;\nmsg.historyId = env.get(\"Id\") || msg.historyId;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 430, + "y": 400, + "wires": [ + [ + "c2c1a70fd9f36e28" + ] + ] + }, + { + "id": "736a5f71119f063f", + "type": "switch", + "z": "a4137713471da6c4", + "name": "history-add-entry role", + "property": "entryRole", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "user", + "vt": "str" + }, + { + "t": "else" + } + ], + "checkall": "true", "repair": false, "outputs": 2, "x": 460, @@ -5886,7 +6786,7 @@ "type": "function", "z": "f19bc65164444615", "name": "Init", - "func": "msg.id = env.get(\"Factory Id\") || msg.factoryId || `programatic-history-factory-${Math.floor(Math.random() * 1000)}`;\nmsg.histories = {};\n\nflow.set(\"Id\", msg.id);\nflow.set(\"Histories\", msg.histories);\n\nreturn msg;\n", + "func": "msg.id = env.get(\"Factory Id\") || msg.factoryId || `programatic-history-factory-${Date.now()}`;\nmsg.histories = {};\n\nflow.set(\"Id\", msg.id);\nflow.set(\"Histories\", msg.histories);\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, @@ -5945,7 +6845,7 @@ "type": "function", "z": "f19bc65164444615", "name": "Create History", - "func": "const defaultId = `programatic-history-${Math.floor(Math.random() * 1000)}`;\n\nmsg.action = \"history-init\";\n\nif (!msg.historyId) {\n msg.historyId = defaultId;\n}\n\n// if this history already exists\nif (msg.histories[msg.historyId]) {\n node.warn(`Ignoring init action for existing programatic history: ${msg.historyId}`);\n return;\n}\n\nif (!msg.historySourceFilename) {\n msg.historySourceFilename = `/data/db/${defaultId}.json`;\n}\n\nmsg.histories[msg.historyId] = msg.historySourceFilename;\n\nreturn msg;\n", + "func": "const defaultId = `programatic-history-${Date.now()}`;\n\nmsg.action = \"history-init\";\n\nif (!msg.historyId) {\n msg.historyId = defaultId;\n}\n\n// if this history already exists\nif (msg.histories[msg.historyId]) {\n node.warn(`Ignoring init action for existing programatic history: ${msg.historyId}`);\n return;\n}\n\nif (!msg.historySourceFilename) {\n msg.historySourceFilename = `/data/db/${defaultId}.json`;\n}\n\nmsg.histories[msg.historyId] = msg.historySourceFilename;\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, @@ -6200,25 +7100,45 @@ "type": "function", "z": "21de8117bd1967f9", "name": "extractHtmlTags", - "func": "msg.extractHtmlTags = (text) => {\n const tagRegex = /<([A-Za-z0-9-_:.]*)>([\\s\\S]*?)<\\/([A-Za-z0-9_:.-]*)>/g;\n const tags = [];\n let matches;\n while (matches = tagRegex.exec(text)) {\n const [_, openingTag, tagContent, closingTag] = matches;\n\n // if tags don't match\n if (openingTag != closingTag) {\n //skip it\n continue;\n }\n tags.push({tag: openingTag, content: tagContent});\n }\n return tags;\n}\n\nreturn msg;\n", + "func": "const { default: { default: JSSoup } } = msg.importedModules['jssoup'];\n\nmsg.extractHtmlTags = (text) =>\n // get all tags from content\n new JSSoup(text).descendants\n // only return HTML tags\n .filter(it => it.name)\n // get tag name and content\n .map(({name, contents}) => ({ name, content: contents?.join('') ?? '' }));\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 260, - "y": 120, + "x": 380, + "y": 220, "wires": [ [] ] }, + { + "id": "3d458d6f47d14634", + "type": "subflow:87f7528a5c81b545", + "z": "21de8117bd1967f9", + "name": "Import jssoup", + "env": [ + { + "name": "Modules", + "value": "[\"jssoup\"]", + "type": "json" + } + ], + "x": 380, + "y": 180, + "wires": [ + [ + "0a432a478665f6a9" + ] + ] + }, { "id": "af73ebafaf5dc5f2", "type": "function", "z": "240cc03734c17fa7", "name": "Parse Response", - "func": "// if this is not a stream ending\nif (msg.action != \"history-update-streaming\" || msg.history.streaming) {\n return;\n}\n\nconst response = msg.history.entries.slice(-1)[0].content;\nconst responseTags = msg.extractHtmlTags(response);\n\n// send message for every tag\nreturn [\n responseTags.map(({tag, content}) => ({\n tag,\n content,\n agentId: msg.historyId\n }))\n];\n", + "func": "// if this is not a stream ending\nif (msg.action != \"history-update-streaming\" || msg.history.streaming) {\n return;\n}\n\nconst response = msg.history.entries.slice(-1)[0].content;\nconst responseTags = msg.extractHtmlTags(response);\n\n// send message for every tag\nreturn [\n responseTags.map(({name, content}) => ({\n tag: name,\n content,\n agentId: msg.historyId\n }))\n];\n", "outputs": 1, "timeout": 0, "noerr": 0, @@ -6245,1570 +7165,1268 @@ ] }, { - "id": "c0c36621780669a4", - "type": "subflow:a59054999730c251", - "z": "9e23ccbf2e0608ed", - "d": true, - "g": "0e1cb402b61eb646", - "name": "Model - openai - localhost", - "env": [ - { - "name": "Id", - "value": "openai-localhost", - "type": "str" - }, + "id": "1540fd3640a5c2da", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Container spec", + "func": "msg.name = env.get(\"Container Name\") || msg.containerName || `genai-container-${Date.now()}`;\nmsg.image = env.get(\"Image\") || msg.image;\nmsg.command = env.get(\"Command\") || msg.command;\nmsg.args = yargs(env.get(\"Docker Run Args\") || msg.dockerRunArgs).parse();\nmsg.responseMode = env.get(\"Response Mode\") || msg.responseMode || 'full';\nmsg.commit = env.get(\"Commit\") || msg.commit || false;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ { - "name": "BaseUrl", - "value": "http://host.docker.internal:8080", - "type": "str" + "var": "yargs", + "module": "yargs" } ], - "x": 410, - "y": 520, + "x": 240, + "y": 100, "wires": [ [ - "45671622e142be7e" + "68cbcf691071823e" ] ] }, { - "id": "948e1265a14409b8", - "type": "debug", - "z": "9e23ccbf2e0608ed", - "g": "aaf9af66d3e39da8", - "name": "Model Errors", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 510, - "y": 720, - "wires": [] + "id": "68cbcf691071823e", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Create container", + "func": "\nreturn {\n method: \"POST\",\n url: `http://docker-engine-api:2375/containers/create?name=${msg.name}`,\n payload: {\n Cmd: msg.command,\n Image: msg.image\n },\n containerSpec: msg\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 250, + "y": 180, + "wires": [ + [ + "2163e4e6c0ca65f7" + ] + ] }, { - "id": "977f9402195729c4", - "type": "subflow:a59054999730c251", - "z": "9e23ccbf2e0608ed", - "g": "0e1cb402b61eb646", - "name": "Model - genai - llama-cpp-llava", - "env": [ - { - "name": "Id", - "value": "genai-llama-cpp-llava", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", - "type": "str" - } - ], - "x": 430, - "y": 560, + "id": "2163e4e6c0ca65f7", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "b9a9b43a3594c357", + "name": "", + "x": 240, + "y": 220, "wires": [ [ - "45671622e142be7e" + "c0e105a4e8c1ed29" ] ] }, { - "id": "a63ac3946c2843eb", - "type": "debug", - "z": "9e23ccbf2e0608ed", - "d": true, - "g": "aaf9af66d3e39da8", - "name": "Model Output", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 520, - "y": 680, - "wires": [] + "id": "28417899327d5e30", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Start container", + "func": "const containerId = msg.msgIn.containerSpec.id = msg.content.Id;\n\nreturn {\n method: \"POST\",\n url: `http://docker-engine-api:2375/containers/${containerId}/start`,\n containerSpec: msg.msgIn.containerSpec\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 240, + "y": 340, + "wires": [ + [ + "10e31bc197b72db3" + ] + ] }, { - "id": "5e149325f881f48b", - "type": "subflow:2b3efcc977e88d91", - "z": "9e23ccbf2e0608ed", - "name": "", - "env": [ + "id": "c0e105a4e8c1ed29", + "type": "switch", + "z": "b9a9b43a3594c357", + "name": "If http-success", + "property": "action", + "propertyType": "msg", + "rules": [ { - "name": "Url", - "value": "simple-chat", - "type": "str" + "t": "eq", + "v": "http-success", + "vt": "str" + }, + { + "t": "else" } ], - "x": 550, - "y": 160, + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 240, + "y": 260, "wires": [ [ - "246a383da043e031", - "34dd380b3322dc77" + "28417899327d5e30" + ], + [ + "f2d7034e67ca9556" ] ] }, { - "id": "8ec4c35df45a28c5", - "type": "comment", - "z": "9e23ccbf2e0608ed", - "g": "0e1cb402b61eb646", - "name": "Models", - "info": "", - "x": 350, - "y": 420, - "wires": [] + "id": "f2d7034e67ca9556", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Handle error", + "func": "\nreturn {\n ...msg,\n action: \"docker-error\"\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1010, + "y": 560, + "wires": [ + [ + "b136a36f1f060bab" + ] + ] }, { - "id": "246a383da043e031", - "type": "subflow:74bd10ee8e354d0a", - "z": "9e23ccbf2e0608ed", + "id": "10e31bc197b72db3", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "b9a9b43a3594c357", "name": "", - "env": [ - { - "name": "SourceFilename", - "value": "/data/db/history-1711926907124.json", - "type": "str" - } - ], - "x": 310, - "y": 220, + "x": 240, + "y": 380, "wires": [ [ - "c865bad2cdc088e0" + "f298903bf9973df7" ] ] }, { - "id": "b1093b3dfa80dbe3", + "id": "f298903bf9973df7", "type": "switch", - "z": "9e23ccbf2e0608ed", - "g": "aaf9af66d3e39da8", - "name": "Action", + "z": "b9a9b43a3594c357", + "name": "If http-success", "property": "action", "propertyType": "msg", "rules": [ { "t": "eq", - "v": "model-content", + "v": "http-success", "vt": "str" }, { - "t": "eq", - "v": "model-error", - "vt": "str" + "t": "else" } ], "checkall": "true", "repair": false, "outputs": 2, - "x": 350, - "y": 700, + "x": 240, + "y": 420, "wires": [ [ - "a63ac3946c2843eb" + "f5ad23d6f9a6c234", + "0dd1355d2588c8a9" ], [ - "948e1265a14409b8" - ] - ] - }, - { - "id": "8e313642e9e9049a", - "type": "inject", - "z": "9e23ccbf2e0608ed", - "name": "Start App", - "props": [ - { - "p": "timestamp", - "v": "", - "vt": "date" - }, - { - "p": "action", - "v": "history-init", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "x": 140, - "y": 100, - "wires": [ - [ - "246a383da043e031" + "f2d7034e67ca9556" ] ] }, { - "id": "378e8541feaf87ec", - "type": "subflow:a59054999730c251", - "z": "9e23ccbf2e0608ed", - "d": true, - "g": "0e1cb402b61eb646", - "name": "Model - dummy sse", - "env": [ - { - "name": "Id", - "value": "dummy-sse", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://host.docker.internal:8091", - "type": "str" - }, - { - "name": "Batch", - "value": "10", - "type": "num" - } - ], - "x": 390, - "y": 480, + "id": "76e87439b348d398", + "type": "subflow:72ced27310c541f6", + "z": "b9a9b43a3594c357", + "name": "", + "x": 480, + "y": 540, "wires": [ [ - "45671622e142be7e" + "bf699708b661931a" ] ] }, { - "id": "45671622e142be7e", + "id": "f5ad23d6f9a6c234", "type": "function", - "z": "9e23ccbf2e0608ed", - "g": "0e1cb402b61eb646", - "name": " ", - "func": "\nreturn msg;", + "z": "b9a9b43a3594c357", + "name": "Get stdout", + "func": "const containerId = msg.msgIn.containerSpec.id;\n\nreturn {\n method: \"GET\",\n url: `http://docker-engine-api:2375/containers/${containerId}/logs`,\n payloadMode: 'querystring',\n payload: {\n follow: true,\n stdout: true,\n stderr: false\n },\n headers: {\n 'accept': 'text/string',\n },\n containerSpec: msg.msgIn.containerSpec,\n outputMode: msg.msgIn.containerSpec.outputMode\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 645, - "y": 580, + "x": 470, + "y": 500, "wires": [ [ - "246a383da043e031", - "b1093b3dfa80dbe3" + "76e87439b348d398" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "33ca3631b9af0d55", - "type": "subflow:a59054999730c251", - "z": "9e23ccbf2e0608ed", - "d": true, - "g": "0e1cb402b61eb646", - "name": "Model - genai - llama-cpp-mistral-8x", - "env": [ + "id": "bf699708b661931a", + "type": "switch", + "z": "b9a9b43a3594c357", + "name": "cURL Action", + "property": "action", + "propertyType": "msg", + "rules": [ { - "name": "Id", - "value": "genai-llama-cpp-mistral-8x", - "type": "str" + "t": "eq", + "v": "command-stderr", + "vt": "str" }, { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", - "type": "str" + "t": "eq", + "v": "command-exit", + "vt": "str" + }, + { + "t": "eq", + "v": "command-stdout", + "vt": "str" } ], - "x": 440, + "checkall": "true", + "repair": false, + "outputs": 3, + "x": 470, "y": 600, "wires": [ [ - "45671622e142be7e" + "f2d7034e67ca9556" + ], + [ + "4adad0a3f6b3b9a0" + ], + [ + "8ea54312d07a6fdc" ] ] }, { - "id": "d9e8ec2ee480957d", + "id": "ac62a774eb153489", + "type": "switch", + "z": "b9a9b43a3594c357", + "name": "Exit Code", + "property": "msg.exit.code", + "propertyType": "jsonata", + "rules": [ + { + "t": "neq", + "v": "0", + "vt": "num" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 680, + "y": 640, + "wires": [ + [ + "f2d7034e67ca9556" + ], + [ + "3915149c0c74af4b" + ] + ] + }, + { + "id": "8ea54312d07a6fdc", "type": "function", - "z": "9e23ccbf2e0608ed", - "name": " ", - "func": "\nreturn msg;", + "z": "b9a9b43a3594c357", + "name": "Handle stdout", + "func": "if (!msg.content) {\n return;\n}\n\nreturn {\n ...msg,\n containerSpec: msg.msgIn.containerSpec,\n action: \"docker-stdout\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 205, - "y": 460, + "x": 700, + "y": 1240, "wires": [ [ - "378e8541feaf87ec", - "c0c36621780669a4", - "977f9402195729c4", - "33ca3631b9af0d55" + "b136a36f1f060bab" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "c865bad2cdc088e0", + "id": "c02417dc4c8df8e5", "type": "function", - "z": "9e23ccbf2e0608ed", - "g": "bf3cb919a9b18a74", - "name": "System Prompt", - "func": "// Initial prompt\nconst initialPrompt = `You are a helpful chat bot that will perform any requested tasks to the best of your ability.`;\n\n// if this is an update prompt message\nif (msg.action == \"prompt-update\") {\n // update our prompt\n context.set(\"prompt\", msg.prompt);\n // that's all\n return msg;\n}\n\n// get current prompt\nlet currentPrompt = context.get(\"prompt\");\n\nif (!currentPrompt) {\n currentPrompt = initialPrompt\n context.set(\"prompt\", currentPrompt);\n}\n\nmsg.systemPrompt = currentPrompt;\n\nreturn msg;\n", + "z": "b9a9b43a3594c357", + "name": "Handle success", + "func": "\nreturn {\n ...msg,\n action: \"docker-done\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 580, - "y": 320, + "x": 1000, + "y": 960, "wires": [ [ - "5e149325f881f48b", - "d9e8ec2ee480957d" + "b136a36f1f060bab" ] ] }, { - "id": "34dd380b3322dc77", + "id": "5a94f86438968b9b", "type": "switch", - "z": "9e23ccbf2e0608ed", - "g": "bf3cb919a9b18a74", - "name": "If prompt action", - "property": "action", - "propertyType": "msg", + "z": "b9a9b43a3594c357", + "name": "If remove container", + "property": "msg.containerSpec.args.rm", + "propertyType": "jsonata", "rules": [ { - "t": "regex", - "v": "^prompt-", - "vt": "str", - "case": false + "t": "eq", + "v": "true", + "vt": "jsonata" + }, + { + "t": "else" } ], "checkall": "true", "repair": false, - "outputs": 1, - "x": 580, - "y": 280, + "outputs": 2, + "x": 710, + "y": 960, "wires": [ [ - "c865bad2cdc088e0" + "154690456a2fc9f8" + ], + [ + "c02417dc4c8df8e5" ] ] }, { - "id": "fe160cbe0df384e5", - "type": "template", - "z": "191694dad2850f37", - "name": "System Prompt", - "field": "prompt", - "fieldType": "msg", - "format": "handlebars", - "syntax": "mustache", - "template": "You are a helpful chat bot that will perform any requested tasks to the best of your ability.", - "output": "str", - "x": 200, - "y": 520, + "id": "154690456a2fc9f8", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Remove container", + "func": "const containerSpec = msg.containerSpec;\n\nreturn {\n method: \"DELETE\",\n url: `http://docker-engine-api:2375/containers/${containerSpec.id}?v=true`,\n containerSpec,\n exit: msg.exit\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 710, + "y": 1040, "wires": [ [ - "81b98c3380c57334" + "ed312f61da898031" ] ] }, { - "id": "34fa053e9707e425", - "type": "subflow:74bd10ee8e354d0a", - "z": "191694dad2850f37", - "g": "b1dd9777ee396bd7", - "name": "Solution History", - "env": [ - { - "name": "Id", - "value": "solution-01", - "type": "str" - } - ], - "x": 480, - "y": 380, + "id": "ed312f61da898031", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "b9a9b43a3594c357", + "name": "", + "x": 700, + "y": 1080, "wires": [ [ - "8565c4a9a8c13312", - "88802dbd1e8b0c57", - "b38cd518b824c20d" + "2310df3f0167dbf7" ] ] }, { - "id": "9d0d59cbd0342094", - "type": "inject", - "z": "191694dad2850f37", - "g": "0e31504694a6eb0c", - "name": "Start Loop", - "props": [ + "id": "2310df3f0167dbf7", + "type": "switch", + "z": "b9a9b43a3594c357", + "name": "If http-success", + "property": "action", + "propertyType": "msg", + "rules": [ { - "p": "action", - "v": "step-go-to", + "t": "eq", + "v": "http-success", "vt": "str" + }, + { + "t": "else" } ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "x": 500, - "y": 80, + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 700, + "y": 1120, "wires": [ [ - "b67aacc8e54e5106" + "5047c7f754d6aa6d" + ], + [ + "f2d7034e67ca9556" ] ] }, { - "id": "c85c2df7d79465a0", - "type": "subflow:a59054999730c251", - "z": "191694dad2850f37", - "d": true, - "g": "83fd8826b0ec3bf4", - "name": "Model - dummy sse", - "env": [ - { - "name": "Id", - "value": "dummy-sse", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://host.docker.internal:8091", - "type": "str" - }, - { - "name": "Batch", - "value": "10", - "type": "num" - } - ], - "x": 330, - "y": 680, + "id": "0dc9efa99bce1f0c", + "type": "subflow:72ced27310c541f6", + "z": "b9a9b43a3594c357", + "name": "", + "x": 240, + "y": 540, "wires": [ [ - "d48b052e253b43c3" + "d713530df83a6cc3" ] ] }, { - "id": "73516493eccdfd9d", - "type": "subflow:a59054999730c251", - "z": "191694dad2850f37", - "g": "83fd8826b0ec3bf4", - "name": "Model - genai - llama-cpp-llava", - "env": [ - { - "name": "Id", - "value": "genai-llama-cpp-llava", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", - "type": "str" - }, - { - "name": "Batch", - "value": "10", - "type": "num" - } - ], - "x": 370, - "y": 760, + "id": "0dd1355d2588c8a9", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Get stderr", + "func": "const containerId = msg.msgIn.containerSpec.id;\n\nreturn {\n method: \"GET\",\n url: `http://docker-engine-api:2375/containers/${containerId}/logs`,\n payloadMode: 'querystring',\n payload: {\n follow: true,\n stdout: false,\n stderr: true\n },\n headers: {\n 'accept': 'text/string',\n },\n containerSpec: msg.msgIn.containerSpec,\n outputMode: msg.msgIn.containerSpec.outputMode\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 220, + "y": 500, "wires": [ [ - "d48b052e253b43c3" + "0dc9efa99bce1f0c" ] ] }, { - "id": "f762ec936046e78f", - "type": "comment", - "z": "191694dad2850f37", - "g": "83fd8826b0ec3bf4", - "name": "Models", - "info": "", - "x": 290, - "y": 620, - "wires": [] - }, - { - "id": "e451712bc8b52b18", - "type": "debug", - "z": "191694dad2850f37", - "g": "ce1b28a464e3b3b3", - "name": "Model Errors", - "active": true, - "tosidebar": true, - "console": true, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 460, - "y": 880, - "wires": [] - }, - { - "id": "e2dd14f8d37e7a72", - "type": "debug", - "z": "191694dad2850f37", - "g": "ce1b28a464e3b3b3", - "name": "Model Output", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 460, - "y": 840, - "wires": [] - }, - { - "id": "bb6dc487db2ce156", + "id": "d713530df83a6cc3", "type": "switch", - "z": "191694dad2850f37", - "g": "ce1b28a464e3b3b3", - "name": "Action", + "z": "b9a9b43a3594c357", + "name": "cURL Action", "property": "action", "propertyType": "msg", "rules": [ { "t": "eq", - "v": "model-streaming-content", + "v": "command-stderr", "vt": "str" }, { "t": "eq", - "v": "model-error", + "v": "command-stdout", "vt": "str" } ], "checkall": "true", "repair": false, "outputs": 2, - "x": 290, - "y": 860, + "x": 230, + "y": 580, "wires": [ [ - "e2dd14f8d37e7a72" + "f2d7034e67ca9556" ], [ - "e451712bc8b52b18" - ] - ] - }, - { - "id": "42cede20c9456a92", - "type": "subflow:74bd10ee8e354d0a", - "z": "191694dad2850f37", - "g": "5dbdaf47523ce33a", - "name": "Eval History", - "env": [ - { - "name": "Id", - "value": "eval-01", - "type": "str" - } - ], - "x": 1270, - "y": 640, - "wires": [ - [ - "1f999e727d7bdcbd", - "f79210375a125e74", - "c9ba32537f7bc133", - "6b036e58872195a7" + "dd73ee28dfd14074" ] ] }, { - "id": "b67aacc8e54e5106", + "id": "dd73ee28dfd14074", "type": "function", - "z": "191694dad2850f37", - "g": "0e31504694a6eb0c", - "name": "Prompt: Problem statement", - "func": "msg.createUserPrompt = () =>\n `I have 10K in savings currently in an investment account. My goal is to earn a passive income of $10K every month. Create a plan for me that will meet this goal. I'm looking for single tailored plan, not options to choose from. Give specific, brief instructions for carrying out this plan.`;\n\nflow.set(\"originalProblemStatement\", msg.createUserPrompt());\n\nreturn msg;\n", + "z": "b9a9b43a3594c357", + "name": "Handle stderr", + "func": "if (!msg.content) {\n return;\n}\n\nreturn {\n ...msg,\n containerSpec: msg.msgIn.containerSpec,\n action: \"docker-stderr\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 220, - "y": 160, + "x": 700, + "y": 1320, "wires": [ [ - "8565c4a9a8c13312" + "b136a36f1f060bab" ] ] }, { - "id": "81b98c3380c57334", - "type": "function", - "z": "191694dad2850f37", - "g": "83fd8826b0ec3bf4", - "name": "In", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 150, - "y": 700, + "id": "3915149c0c74af4b", + "type": "switch", + "z": "b9a9b43a3594c357", + "name": "If commit", + "property": "msg.containerSpec.commit", + "propertyType": "jsonata", + "rules": [ + { + "t": "eq", + "v": "true", + "vt": "jsonata" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 680, + "y": 680, "wires": [ [ - "c85c2df7d79465a0", - "73516493eccdfd9d", - "93859b35073996c8" + "350e0fda13f31cc6" + ], + [ + "cf1db7761982b2fc" ] - ], - "icon": "font-awesome/fa-address-card-o" + ] }, { - "id": "d48b052e253b43c3", + "id": "350e0fda13f31cc6", "type": "function", - "z": "191694dad2850f37", - "g": "83fd8826b0ec3bf4", - "name": "Out", - "func": "\nreturn msg;", + "z": "b9a9b43a3594c357", + "name": "Commit", + "func": "\nreturn {\n ...msg,\n container: msg.containerSpec.id\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 590, - "y": 700, + "x": 680, + "y": 760, "wires": [ [ - "bb6dc487db2ce156", - "4135e1850bf3099c", - "fe0f3fe28e08e2f0", - "0800060d86e1ca55", - "079bf5373fe5d58f", - "b38cd518b824c20d" + "35eba55d4599f26a" ] - ], - "icon": "font-awesome/fa-address-card-o" - }, - { - "id": "c533acab9a1bba89", - "type": "comment", - "z": "191694dad2850f37", - "g": "0e31504694a6eb0c", - "name": "Step 1: Problem Statement and Solution", - "info": "", - "x": 250, - "y": 80, - "wires": [] - }, - { - "id": "8516a2d5188e142d", - "type": "comment", - "z": "191694dad2850f37", - "g": "17a2a4d88505d1b2", - "name": "Step 2: Evaluate Solution", - "info": "", - "x": 990, - "y": 340, - "wires": [] - }, - { - "id": "5dd26b4eb51f86a8", - "type": "comment", - "z": "191694dad2850f37", - "g": "3334e9dd5bf3557d", - "name": "Step 3: Propose New Prompt", - "info": "", - "x": 1000, - "y": 820, - "wires": [] + ] }, { - "id": "0800060d86e1ca55", - "type": "function", - "z": "191694dad2850f37", - "g": "0df36a8be0d76989", - "name": "Prompt: Use proposed prompt", - "func": "msg.createUserPrompt = (history) => {\n const promptProposal = history.entries.slice(-1)[0].content;\n let newPrompt;\n try {\n // don't search for full ending tag, since sometimes the last token gets cutoff\n newPrompt = promptProposal.match(/([\\s\\S]*?)<\\/pro/)[1].trim();\n if (newPrompt.length < 1) {\n throw new Error(\"Empty prompt extracted from proposal\")\n }\n }\n catch (e) {\n throw new Error(`Error extracting prompt from: \\`${promptProposal}\\``);\n }\n\n return newPrompt;\n};\n\nreturn msg;\n", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1010, - "y": 160, + "id": "35eba55d4599f26a", + "type": "subflow:3f4aa860a3b350bc", + "z": "b9a9b43a3594c357", + "name": "", + "x": 700, + "y": 800, "wires": [ [ - "a33731f7d26ff1d8" + "8d5c1f2ac7b735ab" ] ] }, { - "id": "32fd036f241606a1", - "type": "comment", - "z": "191694dad2850f37", - "g": "0df36a8be0d76989", - "name": "Step 4: Restart w/ New Prompt", - "info": "", - "x": 1010, - "y": 80, - "wires": [] - }, - { - "id": "0ad9554c20eb8dd0", + "id": "8d5c1f2ac7b735ab", "type": "switch", - "z": "191694dad2850f37", - "g": "b1dd9777ee396bd7", - "name": "If Step 1", - "property": "step", - "propertyType": "flow", + "z": "b9a9b43a3594c357", + "name": "If success", + "property": "action", + "propertyType": "msg", "rules": [ { "t": "eq", - "v": "1", + "v": "docker-done", "vt": "str" - } - ], - "checkall": "true", - "repair": false, - "outputs": 1, - "x": 460, - "y": 340, - "wires": [ - [ - "34fa053e9707e425" - ] - ] - }, - { - "id": "4135e1850bf3099c", - "type": "switch", - "z": "191694dad2850f37", - "g": "5dbdaf47523ce33a", - "name": "If Step 2 or 3", - "property": "step", - "propertyType": "flow", - "rules": [ + }, { - "t": "btwn", - "v": "2", - "vt": "num", - "v2": "3", - "v2t": "num" + "t": "else" } ], "checkall": "true", "repair": false, - "outputs": 1, - "x": 1270, - "y": 600, + "outputs": 2, + "x": 680, + "y": 840, "wires": [ [ - "42cede20c9456a92" + "c829d6336d001021" + ], + [ + "f2d7034e67ca9556" ] ] }, { - "id": "93859b35073996c8", - "type": "subflow:a59054999730c251", - "z": "191694dad2850f37", - "d": true, - "g": "83fd8826b0ec3bf4", - "name": "Model - openai - localhost", - "env": [ - { - "name": "Id", - "value": "openai-localhost", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://host.docker.internal:8080", - "type": "str" - } - ], - "x": 350, - "y": 720, + "id": "c829d6336d001021", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Store commit", + "func": "\nreturn {\n ...msg,\n containerSpec: {\n ...msg.commitSpec.containerSpec,\n commit: msg.commitSpec\n },\n exit: msg.commitSpec.exit\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 690, + "y": 880, "wires": [ [ - "d48b052e253b43c3" + "5a94f86438968b9b" ] ] }, { - "id": "8565c4a9a8c13312", - "type": "subflow:fe8f70709279ea90", - "z": "191694dad2850f37", - "g": "0e31504694a6eb0c", - "name": "Step 1", - "env": [ - { - "name": "Step", - "value": "1", - "type": "num" - }, - { - "name": "InitHistoryId", - "value": "solution-01", - "type": "str" - }, - { - "name": "Wait", - "value": "false", - "type": "bool" - } - ], - "x": 510, - "y": 160, + "id": "4adad0a3f6b3b9a0", + "type": "function", + "z": "b9a9b43a3594c357", + "name": "Store exit", + "func": "\nreturn {\n containerSpec: msg.msgIn.containerSpec,\n exit: msg\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 680, + "y": 600, "wires": [ [ - "0ad9554c20eb8dd0" + "ac62a774eb153489" ] ] }, { - "id": "1322aa4137d1056e", + "id": "5047c7f754d6aa6d", "type": "function", - "z": "191694dad2850f37", - "d": true, - "g": "17a2a4d88505d1b2", - "name": "Prompt: Evalutate Solution", - "func": "msg.createUserPrompt = (history) => {\n const problemStatement = history.entries[0].content;\n\n const solution = history.entries.slice(-1)[0].content;\n\n return `I'm going to give you a prompt that a user named Lilly gave to an LLM model named BigStar-13B. Then, I will give you the response BigStar gave to Lilly. I want you to rate BigStar's response on a scale from 1-10. Then, give 2-3 specific improvements to BigStar's response that would have increased it's rating.\n\nHere is Lilly's prompt:\n\n${problemStatement}\n\nHere is BigStar's response:\n\n${solution}\n\nWhat would you rate BigStar's response?`;\n};\n\nreturn msg;\n", + "z": "b9a9b43a3594c357", + "name": "Return input message", + "func": "\nreturn msg.msgIn;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1020, - "y": 420, + "x": 720, + "y": 1160, "wires": [ [ - "1f999e727d7bdcbd" + "c02417dc4c8df8e5" ] ] }, { - "id": "1f999e727d7bdcbd", - "type": "subflow:fe8f70709279ea90", - "z": "191694dad2850f37", - "g": "17a2a4d88505d1b2", - "name": "Step 2", - "env": [ - { - "name": "Step", - "value": "2", - "type": "num" - }, - { - "name": "InitHistoryId", - "value": "eval-01", - "type": "str" - } - ], - "x": 1290, - "y": 420, - "wires": [ - [ - "4135e1850bf3099c" - ] - ] + "id": "9ead6c09c1634875", + "type": "debug", + "z": "b9a9b43a3594c357", + "name": "Docker Run In", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 220, + "y": 20, + "wires": [] }, { - "id": "833eaf27d6837495", - "type": "subflow:fe8f70709279ea90", - "z": "191694dad2850f37", - "g": "3334e9dd5bf3557d", - "name": "Step 3", - "env": [ - { - "name": "Step", - "value": "3", - "type": "num" - }, - { - "name": "InitHistory", - "value": "false", - "type": "bool" - } - ], - "x": 1290, - "y": 900, + "id": "0a96edc6fd08333b", + "type": "debug", + "z": "b9a9b43a3594c357", + "name": "Docker Run Out", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1300, + "y": 880, + "wires": [] + }, + { + "id": "65a8ebb1afe5c330", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "5982620408722375", + "name": "", + "x": 630, + "y": 280, "wires": [ - [ - "909642bb1b9261ea" - ] + [] ] }, { - "id": "fe0f3fe28e08e2f0", + "id": "41ea315220e88ed4", "type": "function", - "z": "191694dad2850f37", - "g": "3334e9dd5bf3557d", - "name": "Prompt: Propose New Prompt", - "func": "msg.createUserPrompt = () => \n `How could Lilly's prompt be altered to get BigStar to respond with your suggested improvements? Please provide the new prompt wrapped in tags.`;\n\n\nreturn msg;\n", + "z": "5982620408722375", + "name": "function 21", + "func": "msg.url = `http://docker-engine-api:2375/containers/e9388b9bc020d3438b87a56357b93c08f79fbda456525834238245285ed47eed/logs?stdout=true`;\n// msg.url = `http://host.docker.internal:8080`\nmsg.method = \"GET\"\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1010, - "y": 900, + "x": 410, + "y": 280, "wires": [ [ - "833eaf27d6837495" + "65a8ebb1afe5c330" ] ] }, { - "id": "a33731f7d26ff1d8", - "type": "subflow:fe8f70709279ea90", - "z": "191694dad2850f37", - "g": "0df36a8be0d76989", - "name": "Step 4", - "env": [ - { - "name": "Step", - "value": "4", - "type": "num" - }, - { - "name": "InitHistory", - "value": "false", - "type": "bool" - } - ], - "x": 930, - "y": 220, + "id": "81af6496ee4f4c30", + "type": "exec", + "z": "d5c30c295cb6b7bc", + "command": "", + "addpay": "command", + "append": "", + "useSpawn": "false", + "timer": "", + "winHide": false, + "oldrc": false, + "name": "", + "x": 530, + "y": 200, "wires": [ [ - "85c126ddb6ae9692" - ] - ] - }, - { - "id": "36217d16d71a4c30", - "type": "inject", - "z": "191694dad2850f37", - "g": "17a2a4d88505d1b2", - "name": "Start @ Step 2", - "props": [ - { - "p": "historyId", - "v": "solution-01", - "vt": "str" - }, - { - "p": "historySourceFilename", - "v": "/data/db/history-1706503270302.json", - "vt": "str" - }, - { - "p": "action", - "v": "step-start-at", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "x": 1260, - "y": 340, - "wires": [ + "189a0f12c5d3189e" + ], [ - "b38cd518b824c20d" + "bba82265f3401843" + ], + [ + "571c40cd622a7e4a" ] ] }, { - "id": "7b60dc37c59dc80f", - "type": "inject", - "z": "191694dad2850f37", - "g": "0df36a8be0d76989", - "name": "Start @ Step 4", - "props": [ - { - "p": "historyId", - "v": "eval-01", - "vt": "str" - }, - { - "p": "historySourceFilename", - "v": "/data/db/history-1706169633523.json", - "vt": "str" - }, - { - "p": "action", - "v": "step-start-at", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "x": 1260, - "y": 80, + "id": "10a590c86c24cc1c", + "type": "exec", + "z": "d5c30c295cb6b7bc", + "command": "", + "addpay": "command", + "append": "", + "useSpawn": "true", + "timer": "", + "winHide": false, + "oldrc": false, + "name": "spawn", + "x": 530, + "y": 280, "wires": [ [ - "0800060d86e1ca55" + "189a0f12c5d3189e" + ], + [ + "bba82265f3401843" + ], + [ + "571c40cd622a7e4a" ] ] }, { - "id": "36f73b6e3236c721", - "type": "inject", - "z": "191694dad2850f37", - "g": "3334e9dd5bf3557d", - "name": "Start @ Step 3", - "props": [ - { - "p": "historyId", - "v": "eval-01", - "vt": "str" - }, + "id": "9c2566ae93501d69", + "type": "switch", + "z": "d5c30c295cb6b7bc", + "name": "Mode", + "property": "mode", + "propertyType": "msg", + "rules": [ { - "p": "historySourceFilename", - "v": "/data/db/history-1706169407261.json", + "t": "eq", + "v": "exec", "vt": "str" }, { - "p": "action", - "v": "step-start-at", + "t": "eq", + "v": "spawn", "vt": "str" } ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "x": 1260, - "y": 820, + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 330, + "y": 240, "wires": [ [ - "fe0f3fe28e08e2f0" + "81af6496ee4f4c30" + ], + [ + "10a590c86c24cc1c", + "b3c027b1a78e62ca" ] ] }, { - "id": "bd8902942d9f30bc", + "id": "1c249f69debb918b", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Set mode", + "func": "msg.mode = msg.mode || 'exec';\nmsg.responseMode = msg.responseMode || 'text';\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 795, - "y": 780, + "x": 180, + "y": 140, "wires": [ [ - "fe0f3fe28e08e2f0" + "9c2566ae93501d69", + "5ec949124503c75a" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "f79210375a125e74", + "id": "571c40cd622a7e4a", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Return code", + "func": "\nreturn {\n ...msg.payload,\n action: 'command-exit'\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1435, - "y": 660, + "x": 750, + "y": 320, "wires": [ [ - "bd8902942d9f30bc" + "bee02be8135363fa" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "909642bb1b9261ea", + "id": "5be0298a22eb5f2a", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Spawned", + "func": "\nreturn {\n msgIn: msg,\n action: \"command-spawn\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1435, - "y": 820, + "x": 740, + "y": 400, "wires": [ - [ - "246801bf115544b3" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + [] + ] }, { - "id": "246801bf115544b3", + "id": "5ec949124503c75a", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Forward msg", + "func": "return {\n ...msg,\n action: \"forward-msg\",\n msgAction: msg.action\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1125, - "y": 640, + "x": 750, + "y": 80, "wires": [ [ - "4135e1850bf3099c" + "bee02be8135363fa" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "c9ba32537f7bc133", + "id": "189a0f12c5d3189e", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Stdout", + "func": "return {\n ...msg,\n action: \"command-stdout\",\n content: msg.payload,\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1435, - "y": 320, + "x": 730, + "y": 160, "wires": [ [ - "322d52b49ebe2f42" + "bee02be8135363fa" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "88802dbd1e8b0c57", + "id": "bba82265f3401843", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Stderr", + "func": "\nreturn {\n ...msg,\n action: \"command-stderr\",\n content: msg.payload\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 645, - "y": 420, - "wires": [ - [ - "fe160cbe0df384e5" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false - }, - { - "id": "85c126ddb6ae9692", - "type": "subflow:3bb38f582155f29d", - "z": "191694dad2850f37", - "g": "0df36a8be0d76989", - "name": "", - "x": 1050, - "y": 220, + "x": 730, + "y": 240, "wires": [ [ - "a8aa5ac1df416d41" + "bee02be8135363fa" ] ] }, { - "id": "a8aa5ac1df416d41", + "id": "bee02be8135363fa", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "d5c30c295cb6b7bc", + "name": "Handle response", + "func": "// if this is a forward messge\nif (msg.action == \"forward-msg\") {\n // save our msg for later\n msg.action = msg.msgAction;\n delete msg.msgAction;\n context.set(\"forwardedMsg\", msg);\n // don't send anything for now\n return;\n}\n\n// get any forwarded input we might have\nconst forwardedMsg = context.get(\"forwardedMsg\");\n\n// transform response\nif (msg.content) {\n switch(forwardedMsg.responseMode) {\n case 'text':\n msg.content = msg.content.toString();\n break;\n case 'buffer':\n msg.content = Buffer.from(msg.content);\n break;\n }\n}\n\nreturn {\n ...msg,\n msgIn: forwardedMsg,\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 345, - "y": 280, + "x": 1010, + "y": 240, + "wires": [ + [] + ] + }, + { + "id": "63387d16cd6a7986", + "type": "subflow:d5c30c295cb6b7bc", + "z": "72ced27310c541f6", + "name": "", + "x": 620, + "y": 300, "wires": [ [ - "8565c4a9a8c13312" + "c7494ed5f552a21e" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "322d52b49ebe2f42", + "id": "c8af8c1b86c8ae07", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "72ced27310c541f6", + "name": "Create command", + "func": "const { URLSearchParams } = msg.global;\n\nmsg.outputMode = msg.outputMode || 'full';\n\nlet curlCommand = `curl --silent -X ${msg.method}`;\n\nfor (const [key, value] of Object.entries(msg.headers)) {\n curlCommand += ` -H \"${key}: ${value}\"`;\n}\n\nconst payload = msg.payload || {};\nif (Object.keys(payload).length > 0) {\n switch(msg.payloadMode) {\n case 'body':\n curlCommand += ` -H \"Content-Type: application/json\" -d '${JSON.stringify(payload)}'`;\n break;\n case 'querystring':\n const queryString = new URLSearchParams(payload).toString();\n const separator = msg.url.includes('?') ? '&' : '?';\n msg.url += `${separator}${queryString}`;\n break;\n }\n}\n\ncurlCommand += ` \"${msg.url}\"`;\n\nreturn {\n ...msg,\n command: curlCommand,\n mode: msg.outputMode === 'full' ? 'exec' : 'spawn'\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 755, - "y": 260, + "x": 250, + "y": 220, "wires": [ [ - "0800060d86e1ca55" + "63387d16cd6a7986" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "6b036e58872195a7", - "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1435, - "y": 560, + "id": "e13b4eb99a77c41e", + "type": "subflow:30eb5320bb41dc49", + "z": "72ced27310c541f6", + "name": "", + "x": 250, + "y": 180, "wires": [ [ - "fe160cbe0df384e5" + "c8af8c1b86c8ae07", + "9b8674a5a8ade573" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "079bf5373fe5d58f", - "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 775, - "y": 640, + "id": "03f57deed86e37c5", + "type": "provide-global", + "z": "72ced27310c541f6", + "name": "", + "x": 240, + "y": 140, "wires": [ [ - "c8bf1c9a8fe80c37" + "e13b4eb99a77c41e" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "c8bf1c9a8fe80c37", + "id": "c7494ed5f552a21e", "type": "function", - "z": "191694dad2850f37", - "name": " ", - "func": "\nreturn msg;", + "z": "72ced27310c541f6", + "name": "Handle response", + "func": "if (!['command-stderr', 'command-stdout'].includes(msg.action)) {\n // no content to parse, just return the message\n return msg;\n}\n\n// else, parse our content\nlet parsedContent;\nswitch (msg.msgIn.responseMode) {\n case 'json':\n try {\n parsedContent = JSON.parse(msg.content);\n } catch (e) {\n node.warn('Failed to parse JSON response');\n parsedContent = msg.content;\n }\n break;\n case 'text':\n parsedContent = msg.content.toString();\n break;\n case 'buffer':\n parsedContent = Buffer.from(msg.content);\n break;\n}\n\nreturn {\n ...msg,\n rawContent: msg.content,\n content: parsedContent,\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 305, - "y": 380, + "x": 870, + "y": 200, "wires": [ - [ - "0ad9554c20eb8dd0" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + [] + ] }, { - "id": "b38cd518b824c20d", + "id": "9b8674a5a8ade573", + "type": "debug", + "z": "72ced27310c541f6", + "d": true, + "name": "cURL Requests", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 500, + "y": 160, + "wires": [] + }, + { + "id": "3762dbf4e0957cfa", "type": "function", - "z": "191694dad2850f37", - "g": "17a2a4d88505d1b2", - "name": " ", - "func": "\nreturn msg;", + "z": "30eb5320bb41dc49", + "name": "Build request", + "func": "msg.method = msg.method.toLocaleUpperCase() || \"GET\";\nmsg.payloadMode = msg.method === \"GET\" && msg.payloadMode\n ? msg.payloadMode : 'body';\nmsg.headers = msg.headers ?\n Object.fromEntries(\n Object.entries(msg.headers)\n .map(\n ([k, v]) => [k.toLocaleLowerCase(), v]\n )\n )\n : {};\nconst acceptHeader = msg.headers['accept'] = msg.headers['accept'] || 'application/json';\nmsg.responseMode =\n acceptHeader.includes('json')\n ? 'json'\n : acceptHeader.includes('text')\n ? 'text'\n : 'buffer';\nmsg.payloadResponseMode = `${msg.payloadMode}-${msg.responseMode}`;\n// we should just be able to disable this -- stupid\nmsg.requestTimeout = 60 * 60 * 1000;\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 855, - "y": 420, + "x": 210, + "y": 120, "wires": [ - [ - "1322aa4137d1056e", - "9240a0389d51445c" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + [] + ] }, { - "id": "9240a0389d51445c", + "id": "f3d99166630391d1", "type": "function", - "z": "191694dad2850f37", - "g": "17a2a4d88505d1b2", - "name": "Prompt: Evalutate Against Original", - "func": "msg.createUserPrompt = (history) => {\n const problemStatement = flow.get(\"originalProblemStatement\");\n\n const solution = history.entries.slice(-1)[0].content;\n\n return `I'm going to give you a prompt that a user named Lilly gave to an LLM model named BigStar-13B. Then, I will give you the response BigStar gave to Lilly. I want you to rate BigStar's response on a scale from 1-10. Then, give 2-3 specific improvements to BigStar's response that would have increased it's rating.\n\nHere is Lilly's prompt:\n\n${problemStatement}\n\nHere is BigStar's response:\n\n${solution}\n\nWhat would you rate BigStar's response?`;\n};\n\nreturn msg;\n", + "z": "3f4aa860a3b350bc", + "name": "Commit spec", + "func": "msg.container = env.get(\"Container\") || msg.container;\nmsg.repository = env.get(\"Repository\") || msg.repository || `commit-${msg.container}`;\nmsg.tag = env.get(\"Tag\") || msg.tag || `${Date.now()}`;\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", - "libs": [], - "x": 1040, - "y": 460, + "libs": [ + { + "var": "yargs", + "module": "yargs" + } + ], + "x": 210, + "y": 100, "wires": [ [ - "1f999e727d7bdcbd" + "c393a31a37569fbb" ] ] }, { - "id": "b75f0d8130661559", + "id": "c393a31a37569fbb", "type": "function", - "z": "3fb1b07be44ed756", - "name": "function 1", - "func": "return { sseJs, nodeFetch, async }", + "z": "3f4aa860a3b350bc", + "name": "Commit container", + "func": "\nreturn {\n method: \"POST\",\n url: `http://docker-engine-api:2375/commit?container=${msg.container}&tag=${msg.tag}&repo=${msg.repository}`,\n payload: {\n Cmd: msg.command,\n Image: msg.image\n },\n commitSpec: msg\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", - "libs": [ - { - "var": "sseJs", - "module": "sse.js" - }, - { - "var": "async", - "module": "async" - }, - { - "var": "nodeFetch", - "module": "node-fetch" - } - ], - "x": 480, - "y": 260, + "libs": [], + "x": 230, + "y": 180, "wires": [ [ - "ea2d35fce99de4ae" + "1d44ae7d4b9f9d12" ] ] }, { - "id": "26a114fc27cd90b0", - "type": "inject", - "z": "3fb1b07be44ed756", + "id": "1d44ae7d4b9f9d12", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "3f4aa860a3b350bc", "name": "", - "props": [ + "x": 220, + "y": 220, + "wires": [ + [ + "42d4108f978541ae" + ] + ] + }, + { + "id": "42d4108f978541ae", + "type": "switch", + "z": "3f4aa860a3b350bc", + "name": "If http-success", + "property": "action", + "propertyType": "msg", + "rules": [ { - "p": "payload" + "t": "eq", + "v": "http-success", + "vt": "str" }, { - "p": "topic", - "vt": "str" + "t": "else" } ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "", - "payloadType": "date", - "x": 300, - "y": 240, + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 220, + "y": 260, "wires": [ [ - "b75f0d8130661559" + "cea8afeae263e378" + ], + [ + "9fe7448838c509e5" ] ] }, { - "id": "ea2d35fce99de4ae", - "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 5", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 650, - "y": 280, - "wires": [] - }, - { - "id": "8f75c3504c3dbc5f", + "id": "9fe7448838c509e5", "type": "function", - "z": "3fb1b07be44ed756", - "name": "Install dependencies", - "func": "// List of NPM modules\nconst toInstall = [\n 'sse.js'\n]\n\nconst { exec } = childProcess;\n\nconst run = async (cmd) => {\n const child = exec(cmd, (err) => {\n if (err) console.error(err);\n });\n await new Promise((resolve) => child.on('close', resolve));\n};\n\nawait Promise.all(toInstall.map(it => run(`npm install ${it}`)));\n\nreturn msg;", + "z": "3f4aa860a3b350bc", + "name": "Handle error", + "func": "\nreturn {\n ...msg,\n commitSpec: msg.msgIn.commitSpec,\n action: \"docker-error\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", - "libs": [ - { - "var": "childProcess", - "module": "child_process" - } - ], - "x": 340, - "y": 320, + "libs": [], + "x": 430, + "y": 280, "wires": [ [] ] }, { - "id": "e22d75a202b3a7d9", + "id": "cea8afeae263e378", "type": "function", - "z": "3fb1b07be44ed756", - "name": "function 2", - "func": "//throw new Error(\"This crashes Node-RED!\");\n\n(async () => {\n try {\n const sse = await (global.get(\"dynamicallyImport\"))(\"sse.js\");\n node.send({sse});\n node.done();\n }\n catch (e) {\n node.send({ e });\n }\n})();\n\nreturn msg;", + "z": "3f4aa860a3b350bc", + "name": "Handle success ", + "func": "const commit = msg.msgIn.commitSpec;\n\nreturn {\n ...msg,\n commitSpec: {\n ...commit,\n image: `${commit.repository}:${commit.tag}`\n },\n action: \"docker-done\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 560, - "y": 360, + "x": 440, + "y": 240, "wires": [ - [ - "18e60cf6d75b5c02" - ] + [] ] }, { - "id": "233b190c4bba2abc", - "type": "inject", - "z": "3fb1b07be44ed756", + "id": "6d6f8c6f67a318de", + "type": "function", + "z": "126e4a373d8bcb36", + "name": "Parse Content", + "func": "\nreturn {\n ...msg,\n contentTags: msg.extractHtmlTags(msg.content || '')\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 220, + "y": 180, + "wires": [ + [] + ] + }, + { + "id": "af3d5caec2de488c", + "type": "subflow:21de8117bd1967f9", + "z": "126e4a373d8bcb36", "name": "", - "props": [ - { - "p": "payload" - }, - { - "p": "topic", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "", - "payloadType": "date", - "x": 400, - "y": 360, + "x": 250, + "y": 140, "wires": [ [ - "e22d75a202b3a7d9" + "6d6f8c6f67a318de" ] ] }, { - "id": "18e60cf6d75b5c02", - "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 6", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 720, - "y": 360, - "wires": [] + "id": "e935f75b3e48ad5e", + "type": "function", + "z": "828f5a08b0bcf89d", + "name": "Parse Content", + "func": "return {\n ...msg,\n contentHtml: msg.parseMarkdown(msg.content)\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 220, + "y": 140, + "wires": [ + [] + ] }, { - "id": "366fdac4502597e4", + "id": "e82cac62a6dcc5e2", + "type": "subflow:ae4739904e91e32d", + "z": "828f5a08b0bcf89d", + "name": "", + "x": 250, + "y": 100, + "wires": [ + [ + "e935f75b3e48ad5e" + ] + ] + }, + { + "id": "880a67537dd0efe3", "type": "provide-import-fn", - "z": "3fb1b07be44ed756", + "z": "87f7528a5c81b545", "name": "", - "x": 370, - "y": 580, + "x": 290, + "y": 200, "wires": [ [ - "f58a612cea662f7f" + "6bedf6b16eb7796b" ] ] }, { - "id": "f58a612cea662f7f", + "id": "457ddbfd4780ea1d", "type": "function", - "z": "3fb1b07be44ed756", + "z": "87f7528a5c81b545", "name": "Named Imports", - "func": "// List of modules\nconst toImport = [\n 'sse.js',\n \"node:events\"\n];\n\n;(async () => {\n try {\n const imported = Object.fromEntries(\n await Promise.all(\n toImport.map(\n async it => [it, await msg.import(it)]\n )\n )\n );\n\n node.send({...msg, namedImports: imported});\n } \n catch (e) {\n node.error(e);\n }\n})();\n", + "func": "\n;(async () => {\n try {\n const importedModules = Object.fromEntries(\n await Promise.all(\n msg.moduleSpecs.map(async spec => {\n const moduleNamepsace = await msg.import(spec.moduleName);\n\n const importedModule = Object.fromEntries(\n [\n ...(spec.defaultExport ? [{name: \"default\", alias: \"default\"}] : []),\n ...(spec.namedExports ?? Object.keys(moduleNamepsace).map(k => ({name: k, alias: k})))\n ].map(\n ({name, alias}) => [alias, moduleNamepsace[name]]\n )\n )\n\n return [spec.key, importedModule];\n })\n )\n );\n\n node.send({...msg, importedModules});\n } \n catch (e) {\n node.error(e.stack);\n }\n})();\n", "outputs": 1, "timeout": 0, "noerr": 0, @@ -7820,153 +8438,144 @@ "module": "sse.js" } ], - "x": 620, - "y": 580, + "x": 820, + "y": 560, "wires": [ - [ - "3163545a452b8023" - ] + [] ] }, { - "id": "3163545a452b8023", + "id": "6bedf6b16eb7796b", "type": "function", - "z": "3fb1b07be44ed756", - "name": "function 5", - "func": "const {\"sse.js\": { SSE }} = msg.namedImports;\nconst { Event } = msg.global;\n\nclass CustomEvent extends Event { \n constructor(message, data) {\n super(message, data)\n this.detail = data?.detail\n }\n}\n\nmsg.global.CustomEvent = CustomEvent;\ntry {\n const r = SSE();\n msg.r = r;\n return msg;\n}\ncatch (e) {\n node.error(e);\n node.error(e.stack);\n}\n\n// return {\n// ...msg,\n// scriptglobal: global,\n// Event: global.Event,\n// globalEvent: msg.global.Event\n// }", + "z": "87f7528a5c81b545", + "name": "module-alias", + "func": "// Copied from: https://github.com/ilearnio/module-alias/blob/dev/index.js\nconst nodePath = await msg.import('path')\n\nconst modulePaths = []\nconst moduleAliases = {}\nconst moduleAliasNames = []\n\nfunction isPathMatchesAlias(path, alias) {\n // Matching /^alias(\\/|$)/\n if (path.indexOf(alias) === 0) {\n if (path.length === alias.length) return true\n if (path[alias.length] === '/') return true\n }\n\n return false\n}\n\nconst init = async () => {\n const Module = await msg.import('node:module')\n\n const oldNodeModulePaths = Module._nodeModulePaths\n Module._nodeModulePaths = function (from) {\n let paths = oldNodeModulePaths.call(this, from)\n\n // Only include the module path for top-level modules\n // that were not installed:\n if (from.indexOf('node_modules') === -1) {\n paths = modulePaths.concat(paths)\n }\n\n return paths\n }\n\n const oldResolveFilename = Module._resolveFilename\n Module._resolveFilename = function (request, parentModule, isMain, options) {\n for (let i = moduleAliasNames.length; i-- > 0;) {\n const alias = moduleAliasNames[i]\n if (isPathMatchesAlias(request, alias)) {\n let aliasTarget = moduleAliases[alias]\n // Custom function handler\n if (typeof moduleAliases[alias] === 'function') {\n const fromPath = parentModule.filename\n aliasTarget = moduleAliases[alias](fromPath, request, alias)\n if (!aliasTarget || typeof aliasTarget !== 'string') {\n throw new Error('[module-alias] Expecting custom handler function to return path.')\n }\n }\n request = nodePath.join(aliasTarget, request.substr(alias.length))\n // Only use the first match\n break\n }\n }\n\n return oldResolveFilename.call(this, request, parentModule, isMain, options)\n }\n};\n\nfunction addPathHelper(path, targetArray) {\n path = nodePath.normalize(path)\n if (targetArray && targetArray.indexOf(path) === -1) {\n targetArray.unshift(path)\n }\n}\n\nfunction getMainModule() {\n return msg.global.require.main?._simulateRepl ? undefined : msg.global.require.main\n}\n\nfunction addPath(path) {\n let parent\n path = nodePath.normalize(path)\n\n if (modulePaths.indexOf(path) === -1) {\n modulePaths.push(path)\n // Enable the search path for the current top-level module\n const mainModule = getMainModule()\n if (mainModule) {\n addPathHelper(path, mainModule.paths)\n }\n parent = msg.global.module.parent\n\n // Also modify the paths of the module that was used to load the\n // app-module-paths module and all of it's parents\n while (parent && parent !== mainModule) {\n addPathHelper(path, parent.paths)\n parent = parent.parent\n }\n }\n}\n\n(async () => {\n try {\n // if we haven't added our data module yet\n if (!global.get(\"InstallModules:DataModuleAliased\")) {\n // do so now\n // first, patch node's module\n await init();\n // now we can add our path\n addPath(`/data`);\n // we've now added our data path\n global.set(\"InstallModules:DataModuleAliased\", true);\n }\n \n // forward our message\n node.send(msg);\n }\n catch (e) {\n node.error(e);\n }\n})();\n\nreturn;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 650, - "y": 500, + "x": 410, + "y": 280, "wires": [ [ - "f4e0940a4675e15a" + "df49aa776ec39a20" ] ] }, { - "id": "f4e0940a4675e15a", - "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 9", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 770, - "y": 460, - "wires": [] - }, - { - "id": "d5dd065101ef890a", + "id": "9989cd73c1728ba4", "type": "provide-global", - "z": "3fb1b07be44ed756", + "z": "87f7528a5c81b545", "name": "", - "x": 360, - "y": 620, + "x": 280, + "y": 160, "wires": [ [ - "366fdac4502597e4" + "880a67537dd0efe3" ] ] }, { - "id": "4a5b440f0562c4c5", - "type": "inject", - "z": "3fb1b07be44ed756", - "name": "", - "props": [ - { - "p": "payload" - }, - { - "p": "topic", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "", - "payloadType": "date", - "x": 160, - "y": 580, + "id": "df49aa776ec39a20", + "type": "function", + "z": "87f7528a5c81b545", + "name": "Get modules to install", + "func": "const cachedInstalls = global.get(\"InstallModules:CachedInstalls\") || [];\n\nconst toInstall = msg.moduleSpecs.map(spec => {\n // split name\n const splitName = spec.moduleName.split('/');\n // construct module name based on first character\n switch(splitName[0][0]) {\n case '/':\n // ignore files and directories\n return;\n case '.':\n // ignore files and directories\n return;\n case '@':\n // return org module\n return splitName.slice(0, 1).join('/');\n default:\n // return top-level module\n return splitName[0];\n }\n}).filter(it => it && !cachedInstalls.includes(it));\n\nglobal.set(\"InstallModules:CachedInstalls\", [...cachedInstalls, ...toInstall]);\n\n// return our modules to install\nreturn {\n ...msg,\n toInstall\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 440, + "y": 360, "wires": [ [ - "d5dd065101ef890a" + "becc084ee991baaf" ] ] }, { - "id": "370b802881cc5a5b", + "id": "e98dae970d7540c6", "type": "function", - "z": "3fb1b07be44ed756", - "name": "Send chat to model", - "func": "msg['genai-llama-cpp-llava'] = {\n payload: {\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful chat bot that will perform any requested tasks to the best of your ability.\"\n },\n ...msg.chat.history.map(it => ({\n role: it.role,\n content: it.content\n }))\n ],\n \"temperature\": 0.7,\n \"stop\": null,\n \"stream\": true\n }\n}\nreturn msg;\n", + "z": "87f7528a5c81b545", + "name": "Get modules", + "func": "// List of modules\nconst toImport = env.get(\"Modules\") || msg.modules || [];\n\nmsg.moduleSpecs = toImport.map(module => {\n // create module spec\n const moduleSpec = {\n defaultExport: true,\n namedExports: undefined,\n ...(typeof module === \"string\" ? { moduleName: module } : {\n ...module,\n namedExports: module.namedExports.map(\n named => typeof named === \"string\" ? {\n name: named,\n alias: named\n } : named\n )\n })\n };\n moduleSpec.key = module.key ?? moduleSpec.moduleName;\n return moduleSpec;\n});\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 310, + "x": 210, "y": 100, "wires": [ [ - "d33cede612c96641" + "9989cd73c1728ba4" ] ] }, { - "id": "d33cede612c96641", - "type": "subflow:6d317c39edd7ba27", - "z": "3fb1b07be44ed756", - "name": "localhost-sse", - "env": [ - { - "name": "Id", - "value": "localhost-sse", - "type": "str" - }, + "id": "44dc42cb66468495", + "type": "subflow:d5c30c295cb6b7bc", + "z": "87f7528a5c81b545", + "name": "", + "x": 420, + "y": 520, + "wires": [ + [ + "5ef12c46bbd7a294" + ] + ] + }, + { + "id": "5ef12c46bbd7a294", + "type": "switch", + "z": "87f7528a5c81b545", + "name": "Command action", + "property": "action", + "propertyType": "msg", + "rules": [ { - "name": "Url", - "value": "http://host.docker.internal:8091/sse", - "type": "str" + "t": "eq", + "v": "command-stdout", + "vt": "str" }, { - "name": "options", - "value": "{\"method\": \"POST\"}", - "type": "json" + "t": "eq", + "v": "command-stderr", + "vt": "str" }, { - "name": "Options", - "value": "{\"method\":\"POST\"}", - "type": "json" + "t": "eq", + "v": "command-exit", + "vt": "str" } ], - "x": 570, - "y": 120, + "checkall": "true", + "repair": false, + "outputs": 3, + "x": 430, + "y": 580, "wires": [ [ - "453833904710992b" + "d66301aee1d76d87" + ], + [ + "0a7620bc1dd07e51" + ], + [ + "c26e5607bec3a41a" ] ] }, { - "id": "453833904710992b", + "id": "0a7620bc1dd07e51", "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 11", + "z": "87f7528a5c81b545", + "name": "Install modules error", "active": true, "tosidebar": true, "console": false, @@ -7975,144 +8584,46 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 560, - "y": 160, + "x": 440, + "y": 680, "wires": [] }, { - "id": "e5399fe826058b29", - "type": "subflow:6d317c39edd7ba27", - "z": "3fb1b07be44ed756", - "name": "localhost-openai", - "env": [ - { - "name": "Id", - "value": "localhost-openai", - "type": "str" - }, + "id": "c26e5607bec3a41a", + "type": "switch", + "z": "87f7528a5c81b545", + "name": "If successful", + "property": "msg.code", + "propertyType": "jsonata", + "rules": [ { - "name": "Url", - "value": "http://host.docker.internal:8080/v1/chat/completions", - "type": "str" + "t": "eq", + "v": "0", + "vt": "num" }, { - "name": "Options", - "value": "{\"method\":\"POST\",\"headers\":{\"Content-Type\":\"application/json\"}}", - "type": "json" - }, - { - "name": "options", - "value": "{\"method\": \"POST\"}", - "type": "json" - } - ], - "x": 760, - "y": 60, - "wires": [ - [ - "4912a5fe5cc3d7cd" - ] - ] - }, - { - "id": "4912a5fe5cc3d7cd", - "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 12", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 780, - "y": 100, - "wires": [] - }, - { - "id": "6db72e1f1342ce1d", - "type": "subflow:6d317c39edd7ba27", - "z": "3fb1b07be44ed756", - "name": "genai-llama-cpp-llava", - "env": [ - { - "name": "Id", - "value": "genai-llama-cpp-llava", - "type": "str" - }, - { - "name": "Url", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava/v1/chat/completions", - "type": "str" - }, - { - "name": "Options", - "value": "{\"method\":\"POST\",\"headers\":{\"Content-Type\":\"application/json\"}}", - "type": "json" - }, - { - "name": "options", - "value": "{\"method\": \"POST\"}", - "type": "json" + "t": "else" } ], - "x": 780, - "y": 180, + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 410, + "y": 740, "wires": [ [ - "eea7ca5e3d911f8d" - ] - ] - }, - { - "id": "eea7ca5e3d911f8d", - "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 13", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 780, - "y": 220, - "wires": [] - }, - { - "id": "53c302c1821fa9b9", - "type": "inject", - "z": "3fb1b07be44ed756", - "name": "", - "props": [ - { - "p": "payload" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "3", - "payloadType": "num", - "x": 1190, - "y": 440, - "wires": [ + "fef6f985a19ce44e" + ], [ - "f1e2bb90d5fcdf68" + "0a7620bc1dd07e51" ] ] }, { - "id": "d7e17a64b9a03bac", + "id": "d66301aee1d76d87", "type": "debug", - "z": "3fb1b07be44ed756", - "name": "debug 23", + "z": "87f7528a5c81b545", + "name": "Install modules stdout", "active": true, "tosidebar": true, "console": false, @@ -8121,155 +8632,152 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 1530, - "y": 440, + "x": 440, + "y": 640, "wires": [] }, { - "id": "f1e2bb90d5fcdf68", + "id": "88d2db1e34559f1c", "type": "function", - "z": "3fb1b07be44ed756", - "name": "function 7", - "func": "\nreturn {fs};", + "z": "87f7528a5c81b545", + "name": "Install modules", + "func": "\nreturn {\n ...msg,\n command: `cd /data && npm install ${msg.toInstall.join(' ')}`,\n mode: \"exec\"\n};\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", - "libs": [ - { - "var": "fs", - "module": "fs" - } - ], - "x": 1340, - "y": 440, + "libs": [], + "x": 420, + "y": 480, "wires": [ [ - "d7e17a64b9a03bac" + "44dc42cb66468495" ] ] }, { - "id": "23cc77d254e27371", - "type": "function", - "z": "3fb1b07be44ed756", - "name": "Init Vector Store", - "func": "const { HNSWLib } = langchainCommunityVectorstoresHnswlib;\nconst { OpenAIEmbeddings } = langchainOpenai;\n\nconst vectorStore = await HNSWLib.fromTexts(\n [\"Hello world\", \"Bye bye\", \"hello nice world\"],\n [{ id: 2 }, { id: 1 }, { id: 3 }],\n new OpenAIEmbeddings()\n);\n\nconst resultOne = await vectorStore.similaritySearch(\"hello world\", 1);\nconsole.log(resultOne);\n\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [ + "id": "becc084ee991baaf", + "type": "switch", + "z": "87f7528a5c81b545", + "name": "If modules to install", + "property": "$count(msg.toInstall)", + "propertyType": "jsonata", + "rules": [ { - "var": "langchainCommunityVectorstoresHnswlib", - "module": "@langchain/community/vectorstores/hnswlib" + "t": "gte", + "v": "1", + "vt": "num" }, { - "var": "langchainOpenai", - "module": "@langchain/openai" + "t": "else" } ], - "x": 1500, - "y": 320, + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 430, + "y": 400, "wires": [ - [] + [ + "88d2db1e34559f1c" + ], + [ + "457ddbfd4780ea1d" + ] ] }, { - "id": "9f7595e19d34fca3", + "id": "fef6f985a19ce44e", "type": "function", - "z": "3fb1b07be44ed756", - "name": "Provide OpenAIEmbeddings", - "func": "msg.OpenAIEmbeddings = class {\n constructor () {\n \n }\n}\n\nreturn msg;", + "z": "87f7528a5c81b545", + "name": "Finish install", + "func": "msg = msg.msgIn;\n\nconst cachedInstalls = global.get(\"InstallModules:CachedInstalls\") || [];\n\nglobal.set(\"InstallModules:CachedInstalls\", [...cachedInstalls, ...msg.toInstall]);\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1400, - "y": 260, + "x": 410, + "y": 780, "wires": [ - [] + [ + "457ddbfd4780ea1d" + ] ] }, { - "id": "3e349487bb31edf5", - "type": "inject", - "z": "8518392b3e041cfe", + "id": "4432567301785438", + "type": "subflow:87f7528a5c81b545", + "z": "d5c98b48f9d2d77f", "name": "", - "props": [ - { - "p": "payload" - }, + "env": [ { - "p": "topic", - "vt": "str" + "name": "Modules", + "value": "[\"html-entities\"]", + "type": "json" } ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "", - "payloadType": "date", - "x": 420, - "y": 320, + "x": 230, + "y": 120, "wires": [ [ - "ec9ee8ba595e12ca" + "e5c508b6228990f4" ] ] }, { - "id": "ec9ee8ba595e12ca", + "id": "e5c508b6228990f4", "type": "function", - "z": "8518392b3e041cfe", - "name": "function 13", - "func": "flow.set(\"prop\", 14);\nreturn msg;", + "z": "d5c98b48f9d2d77f", + "name": "Decode", + "func": "const { decode } = msg.importedModules['html-entities'];\n\nmsg.decodedContent = decode(msg.content);\n\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 670, - "y": 320, + "x": 200, + "y": 180, "wires": [ - [ - "9827779f81d25fee", - "513f707299db2bac" - ] + [] ] }, { - "id": "9827779f81d25fee", - "type": "function", - "z": "8518392b3e041cfe", - "name": "function 14", - "func": "msg.root = flow.get(\"prop\");\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 950, - "y": 340, + "id": "c0c36621780669a4", + "type": "subflow:a59054999730c251", + "z": "9e23ccbf2e0608ed", + "d": true, + "g": "0e1cb402b61eb646", + "name": "Model - openai - localhost", + "env": [ + { + "name": "Id", + "value": "openai-localhost", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal:8080", + "type": "str" + } + ], + "x": 410, + "y": 520, "wires": [ [ - "1ae2ee3010712831" + "45671622e142be7e" ] ] }, { - "id": "3fe3f4f66c1086bc", + "id": "948e1265a14409b8", "type": "debug", - "z": "8518392b3e041cfe", - "name": "debug 27", + "z": "9e23ccbf2e0608ed", + "g": "aaf9af66d3e39da8", + "name": "Model Errors", "active": true, "tosidebar": true, "console": false, @@ -8278,87 +8786,202 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 1360, - "y": 340, - "wires": [] + "x": 510, + "y": 720, + "wires": [] }, { - "id": "1ae2ee3010712831", - "type": "subflow:95c38d96d861b4c4", - "z": "8518392b3e041cfe", + "id": "977f9402195729c4", + "type": "subflow:a59054999730c251", + "z": "9e23ccbf2e0608ed", + "g": "0e1cb402b61eb646", + "name": "Model - genai - llama-cpp-llava", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", + "type": "str" + } + ], + "x": 430, + "y": 560, + "wires": [ + [ + "45671622e142be7e" + ] + ] + }, + { + "id": "a63ac3946c2843eb", + "type": "debug", + "z": "9e23ccbf2e0608ed", + "d": true, + "g": "aaf9af66d3e39da8", + "name": "Model Output", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 520, + "y": 680, + "wires": [] + }, + { + "id": "5e149325f881f48b", + "type": "subflow:2b3efcc977e88d91", + "z": "9e23ccbf2e0608ed", "name": "", - "x": 1180, - "y": 340, + "env": [ + { + "name": "Url", + "value": "simple-chat", + "type": "str" + } + ], + "x": 550, + "y": 160, "wires": [ [ - "3fe3f4f66c1086bc" + "246a383da043e031", + "34dd380b3322dc77" ] ] }, { - "id": "513f707299db2bac", + "id": "8ec4c35df45a28c5", + "type": "comment", + "z": "9e23ccbf2e0608ed", + "g": "0e1cb402b61eb646", + "name": "Models", + "info": "", + "x": 350, + "y": 420, + "wires": [] + }, + { + "id": "246a383da043e031", + "type": "subflow:74bd10ee8e354d0a", + "z": "9e23ccbf2e0608ed", + "name": "", + "x": 310, + "y": 220, + "wires": [ + [ + "c865bad2cdc088e0" + ] + ] + }, + { + "id": "b1093b3dfa80dbe3", "type": "switch", - "z": "8518392b3e041cfe", - "name": "MySwitch", - "property": "payload", + "z": "9e23ccbf2e0608ed", + "g": "aaf9af66d3e39da8", + "name": "Action", + "property": "action", "propertyType": "msg", "rules": [ { "t": "eq", - "v": "one", - "vt": "str" - }, - { - "t": "eq", - "v": "two", + "v": "model-content", "vt": "str" }, { "t": "eq", - "v": "three", + "v": "model-error", "vt": "str" } ], "checkall": "true", "repair": false, - "outputs": 3, - "x": 840, - "y": 460, + "outputs": 2, + "x": 350, + "y": 700, "wires": [ [ - "faeb427526c15c85" + "a63ac3946c2843eb" ], [ - "aafa6c5af0929a27" - ], + "948e1265a14409b8" + ] + ] + }, + { + "id": "8e313642e9e9049a", + "type": "inject", + "z": "9e23ccbf2e0608ed", + "name": "Start App", + "props": [ + { + "p": "timestamp", + "v": "", + "vt": "date" + }, + { + "p": "action", + "v": "history-init", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 140, + "y": 100, + "wires": [ [ - "4649802dd53440e4" + "246a383da043e031" ] ] }, { - "id": "faeb427526c15c85", - "type": "function", - "z": "8518392b3e041cfe", - "name": "function 17", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1030, - "y": 420, + "id": "378e8541feaf87ec", + "type": "subflow:a59054999730c251", + "z": "9e23ccbf2e0608ed", + "d": true, + "g": "0e1cb402b61eb646", + "name": "Model - dummy sse", + "env": [ + { + "name": "Id", + "value": "dummy-sse", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal:8091", + "type": "str" + }, + { + "name": "Batch", + "value": "10", + "type": "num" + } + ], + "x": 390, + "y": 480, "wires": [ - [] + [ + "45671622e142be7e" + ] ] }, { - "id": "aafa6c5af0929a27", + "id": "45671622e142be7e", "type": "function", - "z": "8518392b3e041cfe", - "name": "function 18", + "z": "9e23ccbf2e0608ed", + "g": "0e1cb402b61eb646", + "name": " ", "func": "\nreturn msg;", "outputs": 1, "timeout": 0, @@ -8366,17 +8989,49 @@ "initialize": "", "finalize": "", "libs": [], - "x": 1050, - "y": 480, + "x": 645, + "y": 580, "wires": [ - [] + [ + "246a383da043e031", + "b1093b3dfa80dbe3" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "33ca3631b9af0d55", + "type": "subflow:a59054999730c251", + "z": "9e23ccbf2e0608ed", + "d": true, + "g": "0e1cb402b61eb646", + "name": "Model - genai - llama-cpp-mistral-8x", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-mistral-8x", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", + "type": "str" + } + ], + "x": 440, + "y": 600, + "wires": [ + [ + "45671622e142be7e" + ] ] }, { - "id": "4649802dd53440e4", + "id": "d9e8ec2ee480957d", "type": "function", - "z": "8518392b3e041cfe", - "name": "function 19", + "z": "9e23ccbf2e0608ed", + "name": " ", "func": "\nreturn msg;", "outputs": 1, "timeout": 0, @@ -8384,254 +9039,114 @@ "initialize": "", "finalize": "", "libs": [], - "x": 1030, - "y": 580, + "x": 205, + "y": 460, "wires": [ - [] - ] - }, - { - "id": "af241602e203f3d3", - "type": "range", - "z": "8518392b3e041cfe", - "minin": "", - "maxin": "", - "minout": "", - "maxout": "", - "action": "scale", - "round": false, - "property": "payload", - "name": "", - "x": 730, - "y": 680, - "wires": [ - [] - ] - }, - { - "id": "07b22b0dc0d11143", - "type": "rbe", - "z": "8518392b3e041cfe", - "name": "", - "func": "rbe", - "gap": "", - "start": "", - "inout": "out", - "septopics": true, - "property": "payload", - "topi": "topic", - "x": 710, - "y": 720, - "wires": [ - [] - ] + [ + "378e8541feaf87ec", + "c0c36621780669a4", + "977f9402195729c4", + "33ca3631b9af0d55" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false }, { - "id": "a55573e0a503cd32", - "type": "delay", - "z": "8518392b3e041cfe", - "name": "", - "pauseType": "delay", - "timeout": "5", - "timeoutUnits": "seconds", - "rate": "1", - "nbRateUnits": "1", - "rateUnits": "second", - "randomFirst": "1", - "randomLast": "5", - "randomUnits": "seconds", - "drop": false, - "allowrate": false, + "id": "c865bad2cdc088e0", + "type": "function", + "z": "9e23ccbf2e0608ed", + "g": "bf3cb919a9b18a74", + "name": "System Prompt", + "func": "// Initial prompt\nconst initialPrompt = `You are a helpful chat bot that will perform any requested tasks to the best of your ability.`;\n\n// if this is an update prompt message\nif (msg.action == \"prompt-update\") {\n // update our prompt\n context.set(\"prompt\", msg.prompt);\n // that's all\n return msg;\n}\n\n// get current prompt\nlet currentPrompt = context.get(\"prompt\");\n\nif (!currentPrompt) {\n currentPrompt = initialPrompt\n context.set(\"prompt\", currentPrompt);\n}\n\nmsg.systemPrompt = currentPrompt;\n\nreturn msg;\n", "outputs": 1, - "x": 1040, - "y": 660, - "wires": [ - [] - ] - }, - { - "id": "7a42a1e78f716c43", - "type": "jsonpath", - "z": "8518392b3e041cfe", - "expression": "", - "split": false, - "name": "", - "x": 1270, - "y": 540, - "wires": [ - [] - ] - }, - { - "id": "634514577f178815", - "type": "mqtt in", - "z": "8518392b3e041cfe", - "name": "", - "topic": "", - "qos": "2", - "datatype": "auto-detect", - "broker": "", - "nl": false, - "rap": true, - "rh": 0, - "inputs": 0, - "x": 1390, - "y": 780, - "wires": [ - [] - ] - }, - { - "id": "8df5f648c84b1fc6", - "type": "mqtt out", - "z": "8518392b3e041cfe", - "name": "", - "topic": "", - "qos": "", - "retain": "", - "respTopic": "", - "contentType": "", - "userProps": "", - "correl": "", - "expiry": "", - "x": 890, - "y": 820, - "wires": [] - }, - { - "id": "e9f8ed38bd8d02c0", - "type": "http request", - "z": "8518392b3e041cfe", - "name": "TEST-HTTP-REQ", - "method": "GET", - "ret": "txt", - "paytoqs": "ignore", - "url": "http://example.com", - "tls": "", - "persist": false, - "proxy": "", - "insecureHTTPParser": false, - "authType": "basic", - "senderr": false, - "headers": [], - "x": 670, - "y": 480, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 580, + "y": 320, "wires": [ - [] + [ + "5e149325f881f48b", + "d9e8ec2ee480957d" + ] ] }, { - "id": "8bfdab680b95f8bb", + "id": "34dd380b3322dc77", "type": "switch", - "z": "8518392b3e041cfe", - "name": "If not null, else", - "property": "payload", + "z": "9e23ccbf2e0608ed", + "g": "bf3cb919a9b18a74", + "name": "If prompt action", + "property": "action", "propertyType": "msg", "rules": [ { - "t": "nnull" - }, - { - "t": "else" + "t": "regex", + "v": "^prompt-", + "vt": "str", + "case": false } ], "checkall": "true", "repair": false, - "outputs": 2, - "x": 780, - "y": 200, + "outputs": 1, + "x": 580, + "y": 280, "wires": [ [ - "df7672b738a32382" - ], - [ - "aa9403ce7147f75f" + "c865bad2cdc088e0" ] ] }, { - "id": "df7672b738a32382", - "type": "debug", - "z": "8518392b3e041cfe", - "name": "debug 28", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "\"Not empty\"", - "targetType": "jsonata", - "statusVal": "", - "statusType": "auto", - "x": 980, - "y": 160, - "wires": [] - }, - { - "id": "aa9403ce7147f75f", - "type": "debug", - "z": "8518392b3e041cfe", - "name": "debug 29", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "\"Empty\"", - "targetType": "jsonata", - "statusVal": "", - "statusType": "auto", - "x": 980, - "y": 220, - "wires": [] - }, - { - "id": "a949b1fe09dd6896", - "type": "inject", - "z": "8518392b3e041cfe", + "id": "6b73ef72bb7e4b87", + "type": "subflow:2b3efcc977e88d91", + "z": "ec55121054ad7072", "name": "", - "props": [ + "env": [ { - "p": "payload" + "name": "Url", + "value": "admin-operator", + "type": "str" } ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "undefined", - "payloadType": "jsonata", - "x": 530, - "y": 200, + "x": 310, + "y": 280, "wires": [ [ - "8bfdab680b95f8bb" + "e77e6ed92b6eba12" ] ] }, { - "id": "c595413a72a78b1b", - "type": "subflow:2b3efcc977e88d91", - "z": "4d258c7de41d3e07", - "name": "", + "id": "e77e6ed92b6eba12", + "type": "subflow:74bd10ee8e354d0a", + "z": "ec55121054ad7072", + "name": "Admin History", "env": [ { - "name": "Url", - "value": "simple-rag", + "name": "SourceFilename", + "value": "/data/db/history-1711926907124.json", "type": "str" } ], - "x": 510, - "y": 320, + "x": 600, + "y": 280, "wires": [ [ - "e89cf8812605d88f" + "6b73ef72bb7e4b87", + "0a39bb73f010efd7", + "8ad28cb311d8a5c0" ] ] }, { - "id": "fb6acbac6e2d9fc4", + "id": "cd5e2c4e51717c0f", "type": "inject", - "z": "4d258c7de41d3e07", + "z": "ec55121054ad7072", "name": "Start App", "props": [ { @@ -8650,85 +9165,5197 @@ "once": false, "onceDelay": 0.1, "topic": "", - "x": 120, - "y": 120, + "x": 140, + "y": 80, "wires": [ [ - "e89cf8812605d88f" + "e77e6ed92b6eba12", + "d7625ef95dd891b8" ] ] }, { - "id": "1525d739279d5422", - "type": "subflow:a59054999730c251", - "z": "4d258c7de41d3e07", - "d": true, - "g": "a6665159eabf55ba", - "name": "Model - openai - localhost", - "env": [ - { - "name": "Id", - "value": "openai-localhost", - "type": "str" + "id": "0a34e1dce381f16b", + "type": "function", + "z": "ec55121054ad7072", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 205, + "y": 440, + "wires": [ + [ + "21debbaed5b57fd5", + "75d06bae12a047f9", + "a61cd1dd9aeb1256", + "9d4dbbbd2defb7fb" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "75d06bae12a047f9", + "type": "subflow:a59054999730c251", + "z": "ec55121054ad7072", + "d": true, + "g": "0bd29a38bd7fd7ee", + "name": "Model - openai - localhost", + "env": [ + { + "name": "Id", + "value": "openai-localhost", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal:8080", + "type": "str" + } + ], + "x": 410, + "y": 500, + "wires": [ + [ + "a98ec39f0f7f2c84" + ] + ] + }, + { + "id": "a61cd1dd9aeb1256", + "type": "subflow:a59054999730c251", + "z": "ec55121054ad7072", + "g": "0bd29a38bd7fd7ee", + "name": "Model - genai - llama-cpp-llava", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", + "type": "str" + } + ], + "x": 430, + "y": 540, + "wires": [ + [ + "a98ec39f0f7f2c84" + ] + ] + }, + { + "id": "12901237f1ea6884", + "type": "comment", + "z": "ec55121054ad7072", + "g": "0bd29a38bd7fd7ee", + "name": "Models", + "info": "", + "x": 350, + "y": 400, + "wires": [] + }, + { + "id": "d9e0c9a3cf18f405", + "type": "debug", + "z": "ec55121054ad7072", + "g": "7aad90c5be36eb0a", + "name": "Model Errors", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 510, + "y": 700, + "wires": [] + }, + { + "id": "4b7f0d34fcfa313d", + "type": "debug", + "z": "ec55121054ad7072", + "d": true, + "g": "7aad90c5be36eb0a", + "name": "Model Output", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 520, + "y": 660, + "wires": [] + }, + { + "id": "bbeaa9f159afdfaf", + "type": "switch", + "z": "ec55121054ad7072", + "g": "7aad90c5be36eb0a", + "name": "Action", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "model-content", + "vt": "str" + }, + { + "t": "eq", + "v": "model-error", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 350, + "y": 680, + "wires": [ + [ + "4b7f0d34fcfa313d" + ], + [ + "d9e0c9a3cf18f405" + ] + ] + }, + { + "id": "21debbaed5b57fd5", + "type": "subflow:a59054999730c251", + "z": "ec55121054ad7072", + "d": true, + "g": "0bd29a38bd7fd7ee", + "name": "Model - dummy sse", + "env": [ + { + "name": "Id", + "value": "dummy-sse", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal.local:8091", + "type": "str" + }, + { + "name": "Batch", + "value": "10", + "type": "num" + } + ], + "x": 390, + "y": 460, + "wires": [ + [ + "a98ec39f0f7f2c84" + ] + ] + }, + { + "id": "a98ec39f0f7f2c84", + "type": "function", + "z": "ec55121054ad7072", + "g": "0bd29a38bd7fd7ee", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 645, + "y": 560, + "wires": [ + [ + "e77e6ed92b6eba12", + "bbeaa9f159afdfaf", + "4de07154c6644063" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "9d4dbbbd2defb7fb", + "type": "subflow:a59054999730c251", + "z": "ec55121054ad7072", + "d": true, + "g": "0bd29a38bd7fd7ee", + "name": "Model - genai - llama-cpp-mistral-8x", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-mistral-8x", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", + "type": "str" + } + ], + "x": 440, + "y": 580, + "wires": [ + [ + "a98ec39f0f7f2c84" + ] + ] + }, + { + "id": "0a39bb73f010efd7", + "type": "function", + "z": "ec55121054ad7072", + "name": "Admin Prompt", + "func": "msg.systemPrompt = `## Mandate\n\nYou are an AI Administrator.\n\nYour mandate is to manage a collective of AI Operators in order to accomplish the goal of any requests from the User.\n\nWhen a goal is too complex or you lack the requisite abilities for you to accomplish it on your own, break the goal down into one or more smaller tasks and assign each task to an Operator.\n\nIn addition to requests from the User, Operators may also send you messages or requests. Unlike requests from the User, you may choose whether and how to respond to messages and requests from Operators.\n\nEvery response must conclude with an tag.\n\n## Commands\n\nManage the collective of Operators using the Operator API. Send commands to the API as a JSON object wrapped in tags. Messages from operators will be given to you wrapped in tags.\n\n## Operator API Docs\n\n### Create an Operator\n\n\\`\\`\\`\n\n{\n \"method\": \"POST\",\n \"path\": \"/operators\",\n \"body\": {\n \"id\": \"06f86c9a-1fe6-4c74-8939-30e64cb1edbb\",\n \"name\": \"My First Operator\"\n }\n}\n\n\\`\\`\\`\n\n### Message an Operator\n\n\\`\\`\\`\n\n{\n \"method\": \"POST\",\n \"path\": \"/operators/06f86c9a-1fe6-4c74-8939-30e64cb1edbb/messages\",\n \"body\": {\n \"content\": \"Sign up for an account at the following website: https://www.example.com\"\n }\n}\n\n\\`\\`\\`\n\n### Delete an Operator\n\n\\`\\`\\`\n\n{\n \"method\": \"DELETE\",\n \"path\": \"/operators/06f86c9a-1fe6-4c74-8939-30e64cb1edbb\",\n \"body\": {}\n}\n\n\\`\\`\\`\n\n\n`;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 140, + "y": 400, + "wires": [ + [ + "0a34e1dce381f16b" + ] + ] + }, + { + "id": "4de07154c6644063", + "type": "subflow:f19bc65164444615", + "z": "ec55121054ad7072", + "name": "Operator Histories", + "env": [ + { + "name": "Factory Id", + "value": "operators", + "type": "str" + } + ], + "x": 890, + "y": 600, + "wires": [ + [ + "94206e52b6f654bd", + "941ab8d26359e8b3" + ] + ] + }, + { + "id": "3f33490320859b09", + "type": "switch", + "z": "ec55121054ad7072", + "name": "Response tag", + "property": "tag", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "operator-api", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 880, + "y": 240, + "wires": [ + [ + "1ec42373eea9f5ff" + ] + ] + }, + { + "id": "1ec42373eea9f5ff", + "type": "function", + "z": "ec55121054ad7072", + "name": "Parse operator API", + "func": "let apiMsg;\ntry {\n apiMsg = JSON.parse(msg.content);\n}\ncatch (e) {\n throw new Error(`Error parsing operator AI call: ${msg.content} - ${e}`);\n}\n\nreturn {\n ...msg,\n ...apiMsg\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 890, + "y": 340, + "wires": [ + [ + "17e432a11037e949" + ] + ] + }, + { + "id": "17e432a11037e949", + "type": "switch", + "z": "ec55121054ad7072", + "name": "Operator API - Path", + "property": "path", + "propertyType": "msg", + "rules": [ + { + "t": "regex", + "v": "^/operators(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})?$", + "vt": "str", + "case": true + }, + { + "t": "regex", + "v": "^/operators/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/messages$", + "vt": "str", + "case": true + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 890, + "y": 440, + "wires": [ + [ + "1e437fb36b5c0ea1" + ], + [ + "da042c7a27dcbd9f" + ] + ], + "outputLabels": [ + "Operators", + "Operators/Messages" + ] + }, + { + "id": "1e437fb36b5c0ea1", + "type": "switch", + "z": "ec55121054ad7072", + "name": "Operators Method", + "property": "method", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "POST", + "vt": "str" + }, + { + "t": "eq", + "v": "DELETE", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 1110, + "y": 420, + "wires": [ + [ + "2c04b0bb076a5230" + ], + [] + ] + }, + { + "id": "2c04b0bb076a5230", + "type": "function", + "z": "ec55121054ad7072", + "name": "Create operator", + "func": "msg = {\n action: \"prog-history-init\",\n historyId: msg.body?.id\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1380, + "y": 360, + "wires": [ + [ + "40557c67b6ce1c09", + "1554a43a221611d6" + ] + ] + }, + { + "id": "da042c7a27dcbd9f", + "type": "switch", + "z": "ec55121054ad7072", + "name": "Operators/Messages Method", + "property": "method", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "POST", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 1140, + "y": 460, + "wires": [ + [ + "2d1212f366ac2dec" + ] + ] + }, + { + "id": "a2eae6bb6671163b", + "type": "function", + "z": "ec55121054ad7072", + "name": "Add Admin Message", + "func": "msg = {\n action: \"prog-history-add-entry\",\n entry: {\n role: \"user\",\n content: msg.createAdminMessagePrompt(msg.body?.content)\n },\n id: msg.path.split('/')[2]\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1400, + "y": 540, + "wires": [ + [ + "4de07154c6644063", + "dd64967ec7cb7b3d" + ] + ] + }, + { + "id": "2d1212f366ac2dec", + "type": "function", + "z": "ec55121054ad7072", + "name": "Admin message prompt template", + "func": "msg.createAdminMessagePrompt = message => {\n return `${message}`;\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1440, + "y": 500, + "wires": [ + [ + "a2eae6bb6671163b" + ] + ] + }, + { + "id": "ef526c2a80f31eb3", + "type": "function", + "z": "ec55121054ad7072", + "name": "Operator Prompt", + "func": "msg.systemPrompt = `## Mandate\n\nYou are an AI Operator.\n\nYour mandate is to perform any tasks requested of you by your AI Administrator to the best of your ability in order to accomplish the overarching goal of the User.\n\nWhen a task is too complex or you lack the requisite abilities for you to accomplish it on your own, you may ask the Administrator to break the task down into one or more smaller tasks and assign them to Operators.\n\nThis conversation is a complete record of every action you took in performing the task.\n\nEnd all responses with an tag.\n\n## Commands\n\nYou may message the Administrator by wrapping your message in tags. Messages from the Administrator will be given to you wrapped in tags.\n`;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 130, + "y": 480, + "wires": [ + [ + "0a34e1dce381f16b" + ] + ] + }, + { + "id": "87b70bd29575e8b4", + "type": "function", + "z": "ec55121054ad7072", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 265, + "y": 920, + "wires": [ + [ + "ef526c2a80f31eb3" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "40557c67b6ce1c09", + "type": "function", + "z": "ec55121054ad7072", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1695, + "y": 540, + "wires": [ + [ + "4de07154c6644063" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "a073258f226718b6", + "type": "switch", + "z": "ec55121054ad7072", + "name": "Response tag", + "property": "tag", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "operator-message", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 880, + "y": 760, + "wires": [ + [ + "2d730859f47f1ceb" + ] + ] + }, + { + "id": "94206e52b6f654bd", + "type": "function", + "z": "ec55121054ad7072", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 715, + "y": 680, + "wires": [ + [ + "87b70bd29575e8b4" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "8ad28cb311d8a5c0", + "type": "subflow:240cc03734c17fa7", + "z": "ec55121054ad7072", + "name": "Parse Admin Response", + "x": 900, + "y": 160, + "wires": [ + [ + "3f33490320859b09" + ] + ] + }, + { + "id": "941ab8d26359e8b3", + "type": "subflow:240cc03734c17fa7", + "z": "ec55121054ad7072", + "name": "Parse Operator Response", + "x": 910, + "y": 680, + "wires": [ + [ + "a073258f226718b6" + ] + ] + }, + { + "id": "2d730859f47f1ceb", + "type": "function", + "z": "ec55121054ad7072", + "name": "Operator message prompt template", + "func": "msg.createOperatorMessagePrompt = (id, message) => {\n return `${message}`;\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1420, + "y": 700, + "wires": [ + [ + "134cfbd5d2b56837" + ] + ] + }, + { + "id": "134cfbd5d2b56837", + "type": "function", + "z": "ec55121054ad7072", + "name": "Add Operator Message", + "func": "msg = {\n action: \"history-add-entry\",\n entry: {\n role: \"user\",\n content: msg.createOperatorMessagePrompt(msg.agentId, msg.content)\n }\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1390, + "y": 740, + "wires": [ + [ + "13c990f21a453c5a", + "e7f4585c8ca44732" + ] + ] + }, + { + "id": "d2c9ca4a42af3ba9", + "type": "function", + "z": "ec55121054ad7072", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 725, + "y": 400, + "wires": [ + [ + "e77e6ed92b6eba12" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "13c990f21a453c5a", + "type": "function", + "z": "ec55121054ad7072", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1615, + "y": 740, + "wires": [ + [ + "d2c9ca4a42af3ba9" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "d7625ef95dd891b8", + "type": "function", + "z": "ec55121054ad7072", + "name": "Init Operator Histories", + "func": "\nreturn {\n action: \"prog-factory-init\"\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 420, + "y": 100, + "wires": [ + [ + "b6cc1b3167117b16" + ] + ] + }, + { + "id": "1554a43a221611d6", + "type": "debug", + "z": "ec55121054ad7072", + "name": "Creating Operator", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1650, + "y": 320, + "wires": [] + }, + { + "id": "dd64967ec7cb7b3d", + "type": "debug", + "z": "ec55121054ad7072", + "name": "Sending Admin Message", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1670, + "y": 600, + "wires": [] + }, + { + "id": "e7f4585c8ca44732", + "type": "debug", + "z": "ec55121054ad7072", + "name": "Sending Operator Message", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1680, + "y": 800, + "wires": [] + }, + { + "id": "b75f0d8130661559", + "type": "function", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "function 1", + "func": "return { sseJs, nodeFetch, async }", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "sseJs", + "module": "sse.js" + }, + { + "var": "async", + "module": "async" + }, + { + "var": "nodeFetch", + "module": "node-fetch" + } + ], + "x": 1080, + "y": 360, + "wires": [ + [ + "ea2d35fce99de4ae" + ] + ] + }, + { + "id": "26a114fc27cd90b0", + "type": "inject", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 900, + "y": 340, + "wires": [ + [ + "b75f0d8130661559" + ] + ] + }, + { + "id": "ea2d35fce99de4ae", + "type": "debug", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "debug 5", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1250, + "y": 380, + "wires": [] + }, + { + "id": "8f75c3504c3dbc5f", + "type": "function", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "Install dependencies", + "func": "// List of NPM modules\nconst toInstall = [\n 'sse.js'\n]\n\nconst { exec } = childProcess;\n\nconst run = async (cmd) => {\n const child = exec(cmd, (err) => {\n if (err) console.error(err);\n });\n await new Promise((resolve) => child.on('close', resolve));\n};\n\nawait Promise.all(toInstall.map(it => run(`npm install ${it}`)));\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "childProcess", + "module": "child_process" + } + ], + "x": 940, + "y": 420, + "wires": [ + [] + ] + }, + { + "id": "e22d75a202b3a7d9", + "type": "function", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "function 2", + "func": "//throw new Error(\"This crashes Node-RED!\");\n\n(async () => {\n try {\n const sse = await (global.get(\"dynamicallyImport\"))(\"sse.js\");\n node.send({sse});\n node.done();\n }\n catch (e) {\n node.send({ e });\n }\n})();\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1160, + "y": 460, + "wires": [ + [ + "18e60cf6d75b5c02" + ] + ] + }, + { + "id": "233b190c4bba2abc", + "type": "inject", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 1000, + "y": 460, + "wires": [ + [ + "e22d75a202b3a7d9" + ] + ] + }, + { + "id": "18e60cf6d75b5c02", + "type": "debug", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "debug 6", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1320, + "y": 460, + "wires": [] + }, + { + "id": "366fdac4502597e4", + "type": "provide-import-fn", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "x": 1120, + "y": 600, + "wires": [ + [ + "f58a612cea662f7f" + ] + ] + }, + { + "id": "f58a612cea662f7f", + "type": "function", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "Named Imports", + "func": "// List of modules\nconst toImport = [\n 'sse.js',\n \"node:events\"\n];\n\n;(async () => {\n try {\n const imported = Object.fromEntries(\n await Promise.all(\n toImport.map(\n async it => [it, await msg.import(it)]\n )\n )\n );\n\n node.send({...msg, namedImports: imported});\n } \n catch (e) {\n node.error(e);\n }\n})();\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "sseJs", + "module": "sse.js" + } + ], + "x": 1370, + "y": 600, + "wires": [ + [ + "3163545a452b8023" + ] + ] + }, + { + "id": "3163545a452b8023", + "type": "function", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "function 5", + "func": "const {\"sse.js\": { SSE }} = msg.namedImports;\nconst { Event } = msg.global;\n\nclass CustomEvent extends Event { \n constructor(message, data) {\n super(message, data)\n this.detail = data?.detail\n }\n}\n\nmsg.global.CustomEvent = CustomEvent;\ntry {\n const r = SSE();\n msg.r = r;\n return msg;\n}\ncatch (e) {\n node.error(e);\n node.error(e.stack);\n}\n\n// return {\n// ...msg,\n// scriptglobal: global,\n// Event: global.Event,\n// globalEvent: msg.global.Event\n// }", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1400, + "y": 520, + "wires": [ + [ + "f4e0940a4675e15a" + ] + ] + }, + { + "id": "f4e0940a4675e15a", + "type": "debug", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "debug 9", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1520, + "y": 480, + "wires": [] + }, + { + "id": "d5dd065101ef890a", + "type": "provide-global", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "x": 1110, + "y": 640, + "wires": [ + [ + "366fdac4502597e4" + ] + ] + }, + { + "id": "4a5b440f0562c4c5", + "type": "inject", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 910, + "y": 600, + "wires": [ + [ + "d5dd065101ef890a" + ] + ] + }, + { + "id": "370b802881cc5a5b", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "Send chat to model", + "func": "msg['genai-llama-cpp-llava'] = {\n payload: {\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful chat bot that will perform any requested tasks to the best of your ability.\"\n },\n ...msg.chat.history.map(it => ({\n role: it.role,\n content: it.content\n }))\n ],\n \"temperature\": 0.7,\n \"stop\": null,\n \"stream\": true\n }\n}\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 310, + "y": 100, + "wires": [ + [ + "d33cede612c96641" + ] + ] + }, + { + "id": "d33cede612c96641", + "type": "subflow:6d317c39edd7ba27", + "z": "3fb1b07be44ed756", + "name": "localhost-sse", + "env": [ + { + "name": "Id", + "value": "localhost-sse", + "type": "str" + }, + { + "name": "Url", + "value": "http://host.docker.internal:8091/sse", + "type": "str" + }, + { + "name": "options", + "value": "{\"method\": \"POST\"}", + "type": "json" + }, + { + "name": "Options", + "value": "{\"method\":\"POST\"}", + "type": "json" + } + ], + "x": 570, + "y": 120, + "wires": [ + [ + "453833904710992b" + ] + ] + }, + { + "id": "453833904710992b", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 11", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 560, + "y": 160, + "wires": [] + }, + { + "id": "e5399fe826058b29", + "type": "subflow:6d317c39edd7ba27", + "z": "3fb1b07be44ed756", + "name": "localhost-openai", + "env": [ + { + "name": "Id", + "value": "localhost-openai", + "type": "str" + }, + { + "name": "Url", + "value": "http://host.docker.internal:8080/v1/chat/completions", + "type": "str" + }, + { + "name": "Options", + "value": "{\"method\":\"POST\",\"headers\":{\"Content-Type\":\"application/json\"}}", + "type": "json" + }, + { + "name": "options", + "value": "{\"method\": \"POST\"}", + "type": "json" + } + ], + "x": 760, + "y": 60, + "wires": [ + [ + "4912a5fe5cc3d7cd" + ] + ] + }, + { + "id": "4912a5fe5cc3d7cd", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 12", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 780, + "y": 100, + "wires": [] + }, + { + "id": "6db72e1f1342ce1d", + "type": "subflow:6d317c39edd7ba27", + "z": "3fb1b07be44ed756", + "name": "genai-llama-cpp-llava", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "Url", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava/v1/chat/completions", + "type": "str" + }, + { + "name": "Options", + "value": "{\"method\":\"POST\",\"headers\":{\"Content-Type\":\"application/json\"}}", + "type": "json" + }, + { + "name": "options", + "value": "{\"method\": \"POST\"}", + "type": "json" + } + ], + "x": 780, + "y": 180, + "wires": [ + [ + "eea7ca5e3d911f8d" + ] + ] + }, + { + "id": "eea7ca5e3d911f8d", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 13", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 780, + "y": 220, + "wires": [] + }, + { + "id": "53c302c1821fa9b9", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "3", + "payloadType": "num", + "x": 1190, + "y": 240, + "wires": [ + [ + "f1e2bb90d5fcdf68" + ] + ] + }, + { + "id": "d7e17a64b9a03bac", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 23", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1530, + "y": 240, + "wires": [] + }, + { + "id": "f1e2bb90d5fcdf68", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 7", + "func": "\nreturn {fs};", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "fs", + "module": "fs" + } + ], + "x": 1340, + "y": 240, + "wires": [ + [ + "d7e17a64b9a03bac" + ] + ] + }, + { + "id": "23cc77d254e27371", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "Init Vector Store", + "func": "const { HNSWLib } = langchainCommunityVectorstoresHnswlib;\nconst { OpenAIEmbeddings } = langchainOpenai;\n\nconst vectorStore = await HNSWLib.fromTexts(\n [\"Hello world\", \"Bye bye\", \"hello nice world\"],\n [{ id: 2 }, { id: 1 }, { id: 3 }],\n new OpenAIEmbeddings()\n);\n\nconst resultOne = await vectorStore.similaritySearch(\"hello world\", 1);\nconsole.log(resultOne);\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "langchainCommunityVectorstoresHnswlib", + "module": "@langchain/community/vectorstores/hnswlib" + }, + { + "var": "langchainOpenai", + "module": "@langchain/openai" + } + ], + "x": 1500, + "y": 120, + "wires": [ + [] + ] + }, + { + "id": "9f7595e19d34fca3", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "Provide OpenAIEmbeddings", + "func": "msg.OpenAIEmbeddings = class {\n constructor () {\n \n }\n}\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1400, + "y": 60, + "wires": [ + [] + ] + }, + { + "id": "78e2f994d1fbe874", + "type": "subflow:b9a9b43a3594c357", + "z": "3fb1b07be44ed756", + "name": "Docker Run", + "env": [ + { + "name": "Container Name", + "value": "create-directory-01", + "type": "str" + }, + { + "name": "Command", + "value": "", + "type": "str" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + }, + { + "name": "Commit", + "value": "true", + "type": "bool" + }, + { + "name": "Response Mode", + "value": "full", + "type": "str" + } + ], + "x": 190, + "y": 840, + "wires": [ + [ + "7d1f6f8b055c1f9c", + "2b9295527ed600a5" + ] + ] + }, + { + "id": "b1b7a5e444690a58", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 100, + "y": 740, + "wires": [ + [ + "b6d1a9d992b0d137" + ] + ] + }, + { + "id": "7d1f6f8b055c1f9c", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "Create directory", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 200, + "y": 880, + "wires": [] + }, + { + "id": "01a08cd51c7a1f8a", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 240, + "y": 980, + "wires": [ + [ + "bd126ff279ae3415" + ] + ] + }, + { + "id": "f8f3094def8eec89", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "3fb1b07be44ed756", + "name": "", + "x": 680, + "y": 980, + "wires": [ + [ + "60dae42d0ea16a38" + ] + ] + }, + { + "id": "bd126ff279ae3415", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 20", + "func": "msg.url = `http://docker-engine-api:2375/containers/5efd360faabae42c09c97845e52f9709aca2519e923204596c14225aa3c454ca/exec`;\nmsg.method = \"POST\"\nmsg.payload = {\n AttachStdout: true,\n AttachStderr: true,\n Tty: true,\n Cmd: [\"bash\", \"-c\", \"for i in {1..10}; do echo \\\"Exec message\\\"; sleep 1; done\"]\n}\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 450, + "y": 980, + "wires": [ + [ + "f8f3094def8eec89" + ] + ] + }, + { + "id": "60dae42d0ea16a38", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 30", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 860, + "y": 980, + "wires": [] + }, + { + "id": "80486c2b2c4ca875", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 240, + "y": 1040, + "wires": [ + [ + "1f5e501e97cf0503" + ] + ] + }, + { + "id": "539ef7fa2e766b13", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "3fb1b07be44ed756", + "name": "", + "x": 680, + "y": 1040, + "wires": [ + [ + "6f9623b787e73b13" + ] + ] + }, + { + "id": "1f5e501e97cf0503", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 22", + "func": "msg.url = `http://docker-engine-api:2375/exec/b6ecfcc454087d84e46e8f1fec6ba1bf8701322f8146393bdb102d6859283130/start`;\nmsg.method = \"POST\"\nmsg.payload = {\n Detach: false,\n Tty: false\n}\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 450, + "y": 1040, + "wires": [ + [ + "539ef7fa2e766b13" + ] + ] + }, + { + "id": "6f9623b787e73b13", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 31", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 860, + "y": 1040, + "wires": [] + }, + { + "id": "6c89094abec8d0f3", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 240, + "y": 1100, + "wires": [ + [ + "52f3d0c6089039ae" + ] + ] + }, + { + "id": "fcd58b089d8db6fc", + "type": "subflow:f0aa5f2ed7dab3b8", + "z": "3fb1b07be44ed756", + "name": "", + "x": 680, + "y": 1100, + "wires": [ + [ + "b2f29c3b2edf6a54" + ] + ] + }, + { + "id": "52f3d0c6089039ae", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 23", + "func": "msg.url = `http://docker-engine-api:2375/exec/7cdfd069b582e2d85945fc8c9f1d9c080b11a016e1611067c74c969aca7b6b1f/start`;\nmsg.method = \"POST\"\nmsg.payload = {}\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 450, + "y": 1100, + "wires": [ + [ + "fcd58b089d8db6fc" + ] + ] + }, + { + "id": "b2f29c3b2edf6a54", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 32", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 860, + "y": 1100, + "wires": [] + }, + { + "id": "54e8be0ccd77b333", + "type": "subflow:d5c30c295cb6b7bc", + "z": "3fb1b07be44ed756", + "name": "", + "x": 360, + "y": 700, + "wires": [ + [ + "ef618dafdea24bf5" + ] + ] + }, + { + "id": "a8857b2bfb37fa1d", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 24", + "func": "\nreturn {\n mode: \"spawn\",\n command: \"ls -la /data\"\n};", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 180, + "y": 700, + "wires": [ + [ + "54e8be0ccd77b333" + ] + ] + }, + { + "id": "dde91c17372b1fe1", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 160, + "y": 660, + "wires": [ + [ + "a8857b2bfb37fa1d" + ] + ] + }, + { + "id": "ef618dafdea24bf5", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 33", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 530, + "y": 680, + "wires": [] + }, + { + "id": "b6d1a9d992b0d137", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "Create directory", + "func": "\nreturn {\n command: [\"bash\", \"-c\", 'mkdir /root/scripts']\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 200, + "y": 800, + "wires": [ + [ + "78e2f994d1fbe874" + ] + ] + }, + { + "id": "2b9295527ed600a5", + "type": "switch", + "z": "3fb1b07be44ed756", + "name": "If success", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "docker-done", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 400, + "y": 760, + "wires": [ + [ + "8335323195e55550" + ] + ] + }, + { + "id": "8335323195e55550", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "Create script", + "func": "\nreturn {\n command: [\n \"bash\",\n \"-c\",\n `cat << 'EOF' > /root/scripts/script-01.sh ${\n`#!/bin/bash\n\necho \"Script start\";\n\nls -la\n\necho \"Script end\";\n`}\nEOF\n\nchmod +x /root/scripts/script-01.sh`\n ],\n image: msg.containerSpec.commit.image\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 410, + "y": 800, + "wires": [ + [ + "c5b7d5c62d369c24" + ] + ] + }, + { + "id": "c5b7d5c62d369c24", + "type": "subflow:b9a9b43a3594c357", + "z": "3fb1b07be44ed756", + "name": "", + "env": [ + { + "name": "Container Name", + "value": "create-script-01", + "type": "str" + }, + { + "name": "Image", + "value": "", + "type": "str" + }, + { + "name": "Command", + "value": "", + "type": "str" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + }, + { + "name": "Commit", + "value": "true", + "type": "bool" + } + ], + "x": 410, + "y": 840, + "wires": [ + [ + "e386314f2de22206", + "b424a8681b95fd74" + ] + ] + }, + { + "id": "e386314f2de22206", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "create script", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 410, + "y": 880, + "wires": [] + }, + { + "id": "b424a8681b95fd74", + "type": "switch", + "z": "3fb1b07be44ed756", + "name": "If success", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "docker-done", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 620, + "y": 760, + "wires": [ + [ + "3d56f436eacbe88b" + ] + ] + }, + { + "id": "3d56f436eacbe88b", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "Execute script", + "func": "\nreturn {\n command: [\"bash\", \"-c\", \"/root/scripts/script-01.sh\"],\n image: msg.containerSpec.commit.image\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 640, + "y": 800, + "wires": [ + [ + "10318dc5293f6d80" + ] + ] + }, + { + "id": "10318dc5293f6d80", + "type": "subflow:b9a9b43a3594c357", + "z": "3fb1b07be44ed756", + "name": "", + "env": [ + { + "name": "Container Name", + "value": "execute-script-01", + "type": "str" + }, + { + "name": "Image", + "value": "", + "type": "str" + }, + { + "name": "Command", + "value": "", + "type": "str" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + } + ], + "x": 630, + "y": 840, + "wires": [ + [ + "3ef49ac93dfcce8c" + ] + ] + }, + { + "id": "3ef49ac93dfcce8c", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "execute script", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 640, + "y": 880, + "wires": [] + }, + { + "id": "437a9435e7f7839a", + "type": "comment", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "Imports, Dependencies, Global", + "info": "", + "x": 1460, + "y": 340, + "wires": [] + }, + { + "id": "93482abb81e0fcdd", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 200, + "y": 220, + "wires": [ + [ + "c984808fcfb74f0f" + ] + ] + }, + { + "id": "c984808fcfb74f0f", + "type": "change", + "z": "3fb1b07be44ed756", + "name": "", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "[\"one\",\"two\",\"three\"]", + "tot": "json" + }, + { + "t": "set", + "p": "other", + "pt": "msg", + "to": "23", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 220, + "y": 260, + "wires": [ + [ + "45a072776a06e888" + ] + ] + }, + { + "id": "45a072776a06e888", + "type": "split", + "z": "3fb1b07be44ed756", + "name": "", + "splt": "\\n", + "spltType": "str", + "arraySplt": 1, + "arraySpltType": "len", + "stream": false, + "addname": "", + "x": 190, + "y": 300, + "wires": [ + [ + "306f4255096d69e2" + ] + ] + }, + { + "id": "306f4255096d69e2", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 34", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 200, + "y": 340, + "wires": [] + }, + { + "id": "234a56ef02849517", + "type": "inject", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 900, + "y": 700, + "wires": [ + [ + "4b1052f331f48638" + ] + ] + }, + { + "id": "bd0ab9ac636bddf7", + "type": "debug", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "debug 35", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1530, + "y": 700, + "wires": [] + }, + { + "id": "4b1052f331f48638", + "type": "provide-import-fn", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "x": 1110, + "y": 700, + "wires": [ + [ + "f119a534c23868e3" + ] + ] + }, + { + "id": "f119a534c23868e3", + "type": "function", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "Named Imports", + "func": "// List of modules\nconst toImport = [\n 'sse.js',\n \"node:events\",\n \"node:path\",\n \"node:module\"\n];\n\n;(async () => {\n try {\n const imported = Object.fromEntries(\n await Promise.all(\n toImport.map(\n async it => [it, await msg.import(it)]\n )\n )\n );\n\n node.send({...msg, namedImports: imported});\n } \n catch (e) {\n node.error(e);\n }\n})();\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [ + { + "var": "sseJs", + "module": "sse.js" + } + ], + "x": 1360, + "y": 700, + "wires": [ + [ + "bd0ab9ac636bddf7" + ] + ] + }, + { + "id": "a11718080bf06447", + "type": "subflow:87f7528a5c81b545", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "env": [ + { + "name": "Modules", + "value": "[\"colors/safe.js\",{\"moduleName\":\"change-case\",\"key\":\"changeCase\",\"defaultExport\":false,\"namedExports\":[\"camelCase\",{\"name\":\"split\",\"alias\":\"splitWords\"}]}]", + "type": "json" + } + ], + "x": 1130, + "y": 760, + "wires": [ + [ + "11de70778f4fcccb" + ] + ] + }, + { + "id": "7e92245bb06f8113", + "type": "inject", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 900, + "y": 760, + "wires": [ + [ + "a11718080bf06447" + ] + ] + }, + { + "id": "11de70778f4fcccb", + "type": "debug", + "z": "3fb1b07be44ed756", + "g": "e18c67f0ba18707b", + "name": "debug 36", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1340, + "y": 760, + "wires": [] + }, + { + "id": "39d3ce3ccf412e91", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 25", + "func": "msg.content = `\nTo elicit a more detailed and specific response from BigStar, you could alter Lilly's prompt as follows:\n\nI have $10,000 in savings currently in an investment account. My goal is to earn a passive income of $10,000 per month within the next 6-12 months. Please provide a comprehensive step-by-step plan that outlines clear actions and resources for meeting this goal. The plan should include information on high-yield savings accounts, their interest rates, minimum balance requirements, and any other relevant details. Additionally, please consider providing examples of other investment strategies or financial products that could help me achieve my goal.\n\nThis prompt is more detailed and specific, which would encourage BigStar to provide a more thorough response with actionable steps and resources for achieving Lilly's goal\n\n{\n \"method\": \"POST\",\n \"path\": \"/operators\",\n \"body\": {\n \"id\": \"06f86c9a-1fe6-4c74-8939-30e64cb1edbb\",\n \"name\": \"My First Operator\"\n }\n}\n\n\n\n{\n \"method\": \"POST\",\n \"path\": \"/operators/06f86c9a-1fe6-4c74-8939-30e64cb1edbb/messages\",\n \"body\": {\n \"content\": \"Sign up for an account at the following website: https://www.example.com\"\n }\n}\n\nWhen I tried to access the website, I got a 404 Not Found error.\n\n\\`sudo apt - get update && sudo apt - get install - y net - tools\\`\n\n\\`\\`\\`bash\n#!/bin/bash\n\necho \"Script start.\"\necho \"Stderr start\" >& 2\n\nsudo apt update && sudo apt install - y curl\nsudo apt install - y google - chrome - stable\n\ncurl - X GET https://www.google.com/?s=puppies\n\\`\\`\\`\n`;\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 410, + "y": 360, + "wires": [ + [ + "f943a06e26050abe" + ] + ] + }, + { + "id": "482aefc956fcabfa", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 400, + "y": 320, + "wires": [ + [ + "39d3ce3ccf412e91" + ] + ] + }, + { + "id": "f943a06e26050abe", + "type": "subflow:126e4a373d8bcb36", + "z": "3fb1b07be44ed756", + "name": "", + "x": 430, + "y": 400, + "wires": [ + [ + "0b8c8bc4d9b7c3e5" + ] + ] + }, + { + "id": "0b8c8bc4d9b7c3e5", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 37", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 400, + "y": 440, + "wires": [] + }, + { + "id": "cfb2407a726eb285", + "type": "function", + "z": "3fb1b07be44ed756", + "name": "function 26", + "func": "msg.content = `\n\nperties(a,{g:{value:b,configurable:!0,writable:!0,enumerable:!1}})})(B,55);Object.freeze(B);var C=function(){};Object.freeze(new function(){});Object.freeze(new C);Object.freeze(new C);var D=!z&&!w(),G=function(a){if(/-[a-z]/.test(\"ved\"))return null;if(D&&a.dataset){if(y()&&!(\"ved\"in a.dataset))return null;a=a.dataset.ved;return a===void 0?null:a}return a.getAttribute(\"data-\"+\"ved\".replace(/([A-Z])/g,\"-$1\").toLowerCase())};var H=[],I=null;function J(a){a=a.target;var b=performance.now(),f=[],K=f.concat,d=H;if(!(d instanceof Array)){var m=typeof Symbol!=\"undefined\"&&Symbol.iterator&&d[Symbol.iterator];if(m)d=m.call(d);else if(typeof d.length==\"number\")d={next:c(d)};else throw Error(\"b\\`\"+String(d));for(var E=[];!(m=d.next()).done;)E.push(m.value);d=E}H=K.call(f,d,[b]);if(a&&a instanceof HTMLElement)if(a===I){if(b=H.length>=4)b=(H[H.length-1]-H[H.length-4])/1E3<5;if(b){b=google.getEI(a);a.hasAttribute(\"data-ved\")?f=a?G(a)||\"\":\"\":f=(f=\n\u0001\u0001�a.closest(\"[data-ved]\"))?G(f)||\"\":\"\";f=f||\"\";if(a.hasAttribute(\"jsname\"))a=a.getAttribute(\"jsname\");else{var F;a=(F=a.closest(\"[jsname]\"))==null?void 0:F.getAttribute(\"jsname\")}google.log(\"rcm\",\"&ei=\"+b+\"&tgtved=\"+f+\"&jsname=\"+(a||\"\"))}}else I=a,H=[b]}window.document.addEventListener(\"DOMContentLoaded\",function(){document.body.addEventListener(\"click\",J)});}).call(this);\n\n\n\n\u0002\nStderr start\n\u0002\u0001\n\u0002PWARNING: apt does not have a stable CLI interface. Use with caution in scripts.\n\u0002\u0001\n\u0002\u0001\n\u0002PWARNING: apt does not have a stable CLI interface. Use with caution in scripts.\n\u0002\u0001\n\u0002Jdebconf: delaying package configuration, since apt-utils is not installed\n\u0002P % Total % Received % Xferd Average Speed Time Time Time Current\n\u0002N Dload Upload Total Spent Left Speed\n\u0002�\n 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\n100 19962 0 19962 0 0 62933 0 --:--:-- --:--:-- --:--:-- 62971\n\n\n`;\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 650, + "y": 360, + "wires": [ + [ + "d94dedcd28f4f2c5" + ] + ] + }, + { + "id": "5e6e19942bea27c9", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 640, + "y": 320, + "wires": [ + [ + "cfb2407a726eb285" + ] + ] + }, + { + "id": "b291b78b3b8cf21c", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "debug 38", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 640, + "y": 440, + "wires": [] + }, + { + "id": "d94dedcd28f4f2c5", + "type": "subflow:828f5a08b0bcf89d", + "z": "3fb1b07be44ed756", + "name": "", + "env": [ + { + "name": "Escape", + "value": "false", + "type": "bool" + } + ], + "x": 670, + "y": 400, + "wires": [ + [ + "b291b78b3b8cf21c" + ] + ] + }, + { + "id": "99974fc7f020b29e", + "type": "switch", + "z": "3fb1b07be44ed756", + "name": "If script exists", + "property": "$replace(msg.topic, /[^0-9]/, '')", + "propertyType": "jsonata", + "rules": [ + { + "t": "eq", + "v": "1", + "vt": "str" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 1320, + "y": 980, + "wires": [ + [ + "8df1b8a506d75f34" + ], + [ + "b0a5abcb0b3bf998" + ] + ] + }, + { + "id": "ec8158c197f35ed6", + "type": "inject", + "z": "3fb1b07be44ed756", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "\u0001\u00021", + "payload": "", + "payloadType": "date", + "x": 1320, + "y": 940, + "wires": [ + [ + "99974fc7f020b29e" + ] + ] + }, + { + "id": "8df1b8a506d75f34", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "1", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1510, + "y": 980, + "wires": [] + }, + { + "id": "b0a5abcb0b3bf998", + "type": "debug", + "z": "3fb1b07be44ed756", + "name": "otherwise", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1520, + "y": 1020, + "wires": [] + }, + { + "id": "98f4b0c9b2ccebc1", + "type": "subflow:2b3efcc977e88d91", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "env": [ + { + "name": "Url", + "value": "bash-executor", + "type": "str" + } + ], + "x": 690, + "y": 120, + "wires": [ + [ + "4c47c0ebef362a00" + ] + ] + }, + { + "id": "4c47c0ebef362a00", + "type": "subflow:74bd10ee8e354d0a", + "z": "3b5c9ca1fb9ebf48", + "name": "UI History", + "x": 680, + "y": 200, + "wires": [ + [ + "98f4b0c9b2ccebc1", + "bb99a83f06a6e48b" + ] + ] + }, + { + "id": "b8f8b9efb15b957b", + "type": "inject", + "z": "3b5c9ca1fb9ebf48", + "name": "Start App", + "props": [ + { + "p": "timestamp", + "v": "", + "vt": "date" + }, + { + "p": "action", + "v": "history-init", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 100, + "y": 60, + "wires": [ + [ + "4c47c0ebef362a00", + "abab070131a97f0b" + ] + ] + }, + { + "id": "ea9b73f9cc386115", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 45, + "y": 680, + "wires": [ + [ + "8ef6bd83dbaa3d85", + "d3eca839cbbe8f34", + "d4ebbd593cf64e04", + "3e0ce960e9b660a1" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "d3eca839cbbe8f34", + "type": "subflow:a59054999730c251", + "z": "3b5c9ca1fb9ebf48", + "d": true, + "g": "f7696f05d57ef7a1", + "name": "Model - openai - localhost", + "env": [ + { + "name": "Id", + "value": "openai-localhost", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal:8080", + "type": "str" + } + ], + "x": 250, + "y": 740, + "wires": [ + [ + "4c7815cb04fa305a" + ] + ] + }, + { + "id": "d4ebbd593cf64e04", + "type": "subflow:a59054999730c251", + "z": "3b5c9ca1fb9ebf48", + "g": "f7696f05d57ef7a1", + "name": "Model - genai - llama-cpp-llava", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", + "type": "str" + } + ], + "x": 270, + "y": 780, + "wires": [ + [ + "4c7815cb04fa305a" + ] + ] + }, + { + "id": "c2b3e2bf431804bd", + "type": "comment", + "z": "3b5c9ca1fb9ebf48", + "g": "f7696f05d57ef7a1", + "name": "Models", + "info": "", + "x": 190, + "y": 640, + "wires": [] + }, + { + "id": "1c9144b2ef0b4dd5", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "g": "a7de977d7732152e", + "name": "Model Errors", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 350, + "y": 940, + "wires": [] + }, + { + "id": "399f0d05531fcfd6", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "d": true, + "g": "a7de977d7732152e", + "name": "Model Output", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 360, + "y": 900, + "wires": [] + }, + { + "id": "504106b997f60dbe", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "g": "a7de977d7732152e", + "name": "Action", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "model-content", + "vt": "str" + }, + { + "t": "eq", + "v": "model-error", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 190, + "y": 920, + "wires": [ + [ + "399f0d05531fcfd6" + ], + [ + "1c9144b2ef0b4dd5" + ] + ] + }, + { + "id": "8ef6bd83dbaa3d85", + "type": "subflow:a59054999730c251", + "z": "3b5c9ca1fb9ebf48", + "d": true, + "g": "f7696f05d57ef7a1", + "name": "Model - dummy sse", + "env": [ + { + "name": "Id", + "value": "dummy-sse", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal.local:8091", + "type": "str" + }, + { + "name": "Batch", + "value": "10", + "type": "num" + } + ], + "x": 230, + "y": 700, + "wires": [ + [ + "4c7815cb04fa305a" + ] + ] + }, + { + "id": "4c7815cb04fa305a", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "g": "f7696f05d57ef7a1", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 485, + "y": 800, + "wires": [ + [ + "504106b997f60dbe", + "3856fb6b7a093891" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "3e0ce960e9b660a1", + "type": "subflow:a59054999730c251", + "z": "3b5c9ca1fb9ebf48", + "d": true, + "g": "f7696f05d57ef7a1", + "name": "Model - genai - llama-cpp-mistral-8x", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-mistral-8x", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", + "type": "str" + } + ], + "x": 280, + "y": 820, + "wires": [ + [ + "4c7815cb04fa305a" + ] + ] + }, + { + "id": "ea8016e9c51abc6c", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "System Prompt", + "func": "// Initial prompt\nconst initialPrompt = `You are a helpful chat bot that will perform any requested tasks to the best of your ability.`;\n\n// if this is an update prompt message\nif (msg.action == \"prompt-update\") {\n // update our prompt\n context.set(\"prompt\", msg.prompt);\n // that's all\n return msg;\n}\n\n// get current prompt\nlet currentPrompt = context.get(\"prompt\");\n\nif (!currentPrompt) {\n currentPrompt = initialPrompt\n context.set(\"prompt\", currentPrompt);\n}\n\nmsg.systemPrompt = currentPrompt;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 180, + "y": 540, + "wires": [ + [ + "ea9b73f9cc386115" + ] + ] + }, + { + "id": "bb99a83f06a6e48b", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If history-add-entry", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "history-add-entry", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 190, + "y": 300, + "wires": [ + [ + "74615acebc474df6" + ] + ] + }, + { + "id": "74615acebc474df6", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If new user message", + "property": "msg.newEntry.role", + "propertyType": "jsonata", + "rules": [ + { + "t": "eq", + "v": "user", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 200, + "y": 340, + "wires": [ + [ + "0e6df6e3cee2dcb1", + "d9a7870f0b658527" + ] + ] + }, + { + "id": "8a8d172c882c49af", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Add Task Message", + "func": "msg = {\n action: \"prog-history-add-entry\",\n entry: {\n role: \"user\",\n content: msg.createBashTaskPrompt(msg.newEntry.content || '')\n },\n id: msg.newEntry.id\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 190, + "y": 440, + "wires": [ + [ + "3856fb6b7a093891" + ] + ] + }, + { + "id": "0e6df6e3cee2dcb1", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Bash task prompt template", + "func": "msg.createBashTaskPrompt = task => {\n return '' + \n`Write a single bash script that will return an output ` + \n`that accomplishes the following task. Remember to ` +\n`install all needed dependencies at the beginning of ` +\n`the script.\n \n${task}`\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 220, + "y": 400, + "wires": [ + [ + "8a8d172c882c49af" + ] + ] + }, + { + "id": "3856fb6b7a093891", + "type": "subflow:f19bc65164444615", + "z": "3b5c9ca1fb9ebf48", + "name": "Executor Histories", + "env": [ + { + "name": "Factory Id", + "value": "executors", + "type": "str" + } + ], + "x": 730, + "y": 420, + "wires": [ + [ + "ea8016e9c51abc6c", + "d2016f7ee41f50fa", + "fb44317b333bd1ce" + ] + ] + }, + { + "id": "abab070131a97f0b", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Init Executor Histories", + "func": "\nreturn {\n action: \"prog-factory-init\"\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 420, + "y": 80, + "wires": [ + [ + "3856fb6b7a093891" + ] + ] + }, + { + "id": "d9a7870f0b658527", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Create executor", + "func": "msg = {\n action: \"prog-history-init\",\n historyId: msg.newEntry.id\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 460, + "y": 280, + "wires": [ + [ + "3856fb6b7a093891", + "e62148ddacf36d74" + ] + ] + }, + { + "id": "d2016f7ee41f50fa", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If update streaming", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "history-update-streaming", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 730, + "y": 500, + "wires": [ + [ + "aa7f174857ed9d6b" + ] + ] + }, + { + "id": "aa7f174857ed9d6b", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If not streaming", + "property": "msg.history.streaming", + "propertyType": "jsonata", + "rules": [ + { + "t": "null" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 720, + "y": 540, + "wires": [ + [ + "e8e887fd86249699" + ] + ] + }, + { + "id": "fdf90a031a450b58", + "type": "subflow:828f5a08b0bcf89d", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "env": [ + { + "name": "Escape", + "value": "false", + "type": "bool" + } + ], + "x": 730, + "y": 620, + "wires": [ + [ + "5ae0178c7a8ab864" + ] + ] + }, + { + "id": "e8e887fd86249699", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "Get agent response", + "rules": [ + { + "t": "set", + "p": "content", + "pt": "msg", + "to": "msg.history.entries[-1].content", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 730, + "y": 580, + "wires": [ + [ + "fdf90a031a450b58" + ] + ] + }, + { + "id": "5ae0178c7a8ab864", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "Get parsed response", + "rules": [ + { + "t": "set", + "p": "rawContent", + "pt": "msg", + "to": "content", + "tot": "msg" + }, + { + "t": "set", + "p": "content", + "pt": "msg", + "to": "contentHtml", + "tot": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 740, + "y": 660, + "wires": [ + [ + "05d22164293a60d1" + ] + ] + }, + { + "id": "05d22164293a60d1", + "type": "subflow:126e4a373d8bcb36", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "x": 730, + "y": 700, + "wires": [ + [ + "940cc0ae14188d1c" + ] + ] + }, + { + "id": "e62148ddacf36d74", + "type": "subflow:b9a9b43a3594c357", + "z": "3b5c9ca1fb9ebf48", + "name": "Setup environment", + "env": [ + { + "name": "Container Name", + "value": "setup-environment", + "type": "str" + }, + { + "name": "Command", + "value": "[\"bash\",\"-c\",\"mkdir /root/scripts; mkdir /root/new-scripts\"]", + "type": "json" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + }, + { + "name": "Commit", + "value": "true", + "type": "bool" + } + ], + "x": 470, + "y": 320, + "wires": [ + [ + "4fa2b99cc6cd1b5c" + ] + ] + }, + { + "id": "4fa2b99cc6cd1b5c", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If docker done", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "docker-done", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 460, + "y": 360, + "wires": [ + [ + "940cc0ae14188d1c" + ] + ] + }, + { + "id": "210a1d261ee95131", + "type": "subflow:b9a9b43a3594c357", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "env": [ + { + "name": "Container Name", + "value": "create-script", + "type": "str" + }, + { + "name": "Image", + "value": "", + "type": "str" + }, + { + "name": "Command", + "value": "", + "type": "str" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + }, + { + "name": "Commit", + "value": "true", + "type": "bool" + } + ], + "x": 750, + "y": 1060, + "wires": [ + [ + "27741de92e91d0d3" + ] + ] + }, + { + "id": "0e914a8e763e8ea0", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Create script", + "func": "\nconst scriptPath = `/root/new-scripts/script-${Date.now()}-${msg.index}.sh`;\n\nconst code = msg.currentCode.replaceAll(\"sudo \", \"\");\n\nreturn {\n action: \"loop-codes\",\n scriptPath,\n history: msg.history,\n historyId: msg.historyId,\n contentCodes: msg.contentCodes,\n index: msg.index,\n command: [\n \"bash\",\n \"-c\",\n `cat << 'EOF' > ${scriptPath}\n${code}\nEOF\n\nchmod +x ${scriptPath}`\n ],\n image: msg.lastImage\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 750, + "y": 1020, + "wires": [ + [ + "210a1d261ee95131", + "a02641d0cd9d6dbe" + ] + ] + }, + { + "id": "1a70750cb8a22229", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "For each code", + "rules": [ + { + "t": "set", + "p": "index", + "pt": "msg", + "to": "0", + "tot": "num" + }, + { + "t": "set", + "p": "contentCodes", + "pt": "msg", + "to": "msg.contentTags[name='code'].content", + "tot": "jsonata" + }, + { + "t": "set", + "p": "action", + "pt": "msg", + "to": "loop-codes", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 720, + "y": 780, + "wires": [ + [ + "8249b529648a77f1", + "16406d3e5582a1a4" + ] + ] + }, + { + "id": "f92c3f86107e5f1a", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If current code", + "property": "msg.currentCode", + "propertyType": "jsonata", + "rules": [ + { + "t": "nempty" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 760, + "y": 940, + "wires": [ + [ + "116ec2e1966609a4" + ], + [ + "583705d65356bc91" + ] + ] + }, + { + "id": "116ec2e1966609a4", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If uses chrome", + "property": "currentCode", + "propertyType": "msg", + "rules": [ + { + "t": "regex", + "v": "(chrome)", + "vt": "str", + "case": true + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 760, + "y": 980, + "wires": [ + [ + "cf5d7ad2b913deed" + ], + [ + "0e914a8e763e8ea0" + ] + ] + }, + { + "id": "27741de92e91d0d3", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "Docker output", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "docker-stderr", + "vt": "str" + }, + { + "t": "eq", + "v": "docker-done", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 760, + "y": 1100, + "wires": [ + [ + "f2d99994f035a684", + "b3f008f8f6712c97" + ], + [ + "f2d99994f035a684" + ] + ] + }, + { + "id": "1e9eba189d0b8e2f", + "type": "subflow:b9a9b43a3594c357", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "env": [ + { + "name": "Container Name", + "value": "compare-script", + "type": "str" + }, + { + "name": "Image", + "value": "", + "type": "str" + }, + { + "name": "Command", + "value": "", + "type": "str" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + }, + { + "name": "Commit", + "value": "true", + "type": "bool" + } + ], + "x": 750, + "y": 1180, + "wires": [ + [ + "63fac46ac0ea4dec" + ] + ] + }, + { + "id": "f2d99994f035a684", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Compare script", + "func": "const stderrMsg = context.get(\"StderrMsg\");\n\n// we'll get a loop message first telling us to reset state\nif (msg.action === \"loop-codes\") {\n context.set(\"StderrMsg\", null);\n return;\n}\n\n// if this is a stderr message\nif (msg.action === \"docker-stderr\") {\n // store it so we won't continue on docker success\n context.set(\"StderrMsg\", msg);\n return;\n}\n\n// else, we are to continue on,\n// but don't if we previously received a stderrMsg\nif (stderrMsg) {\n return;\n}\n\nreturn {\n action: \"loop-codes\",\n history: msg.containerSpec.history,\n historyId: msg.containerSpec.historyId,\n contentCodes: msg.containerSpec.contentCodes,\n index: msg.containerSpec.index,\n scriptPath: msg.containerSpec.scriptPath,\n command: [\n \"bash\",\n \"-c\",\n `result=0; for f in /root/scripts/*; `+\n `do cmp -s ${msg.containerSpec.scriptPath} \"$f\" && result=1; `+\n `done; echo $result`\n ],\n image: msg.containerSpec.commit.image\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 760, + "y": 1140, + "wires": [ + [ + "1e9eba189d0b8e2f", + "63a5c80a9677a5e8" + ] + ] + }, + { + "id": "63fac46ac0ea4dec", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "Docker output", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "docker-stdout", + "vt": "str" + }, + { + "t": "eq", + "v": "docker-done", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 760, + "y": 1220, + "wires": [ + [ + "a2e31c64ae6e49c9" + ], + [ + "a08be90792caa2ef" + ] + ] + }, + { + "id": "a2e31c64ae6e49c9", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "If script exists", + "property": "$replace(msg.content, /[^0-9]/, '')", + "propertyType": "jsonata", + "rules": [ + { + "t": "eq", + "v": "1", + "vt": "str" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 760, + "y": 1260, + "wires": [ + [ + "61627dea12b6773b" + ], + [ + "a08be90792caa2ef" + ] + ] + }, + { + "id": "a08be90792caa2ef", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Execute script", + "func": "// get existing done and out messages\nconst doneMsg = context.get(\"DoneMsg\");\nconst outMsg = context.get(\"OutMsg\");\n\n// we'll get a loop message first telling us to reset state\nif (msg.action === \"loop-codes\") {\n context.set(\"DoneMsg\", null);\n context.set(\"OutMsg\", null);\n return;\n}\n\n// if we get our done message first\nif (msg.action === \"docker-done\" && !outMsg) {\n context.set(\"DoneMsg\", msg);\n return;\n}\n\n// if we get our out message first\nif (msg.action === \"docker-stdout\" && !doneMsg) {\n context.set(\"OutMsg\", msg);\n return;\n}\n\n// else, we should have both messages, use our done message\nmsg = doneMsg ?? msg;\n\nconst scriptName = msg.containerSpec.scriptPath.split('/').slice(-1)[0];\n\nreturn {\n action: \"loop-codes\",\n history: msg.containerSpec.history,\n historyId: msg.containerSpec.historyId,\n contentCodes: msg.containerSpec.contentCodes,\n index: msg.containerSpec.index,\n command: [\n \"bash\",\n \"-c\",\n `mv ${msg.containerSpec.scriptPath} /root/scripts; /root/scripts/${scriptName}`\n ],\n image: msg.containerSpec.commit.image\n};\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 760, + "y": 1300, + "wires": [ + [ + "af1330eccccb509f", + "93f20029ca3784d0" + ] + ] + }, + { + "id": "af1330eccccb509f", + "type": "subflow:b9a9b43a3594c357", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "env": [ + { + "name": "Container Name", + "value": "execute-script", + "type": "str" + }, + { + "name": "Image", + "value": "", + "type": "str" + }, + { + "name": "Command", + "value": "", + "type": "str" + }, + { + "name": "Output Mode", + "value": "full", + "type": "str" + }, + { + "name": "Commit", + "value": "true", + "type": "bool" + } + ], + "x": 750, + "y": 1340, + "wires": [ + [ + "8c0e8b561fb58e4c" + ] + ] + }, + { + "id": "8c0e8b561fb58e4c", + "type": "switch", + "z": "3b5c9ca1fb9ebf48", + "name": "Docker output", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "docker-stdout", + "vt": "str" + }, + { + "t": "eq", + "v": "docker-stderr", + "vt": "str" + }, + { + "t": "eq", + "v": "docker-done", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 3, + "x": 760, + "y": 1400, + "wires": [ + [ + "93f20029ca3784d0" + ], + [ + "93f20029ca3784d0" + ], + [ + "dd6437290fd336e7" + ] + ] + }, + { + "id": "8249b529648a77f1", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "Get current code", + "rules": [ + { + "t": "set", + "p": "content", + "pt": "msg", + "to": "msg.contentCodes[$$.msg.index]", + "tot": "jsonata" + }, + { + "t": "set", + "p": "lastImage", + "pt": "msg", + "to": "msg.containerSpec.commit.image", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 770, + "y": 820, + "wires": [ + [ + "544de36198caadba" + ] + ] + }, + { + "id": "dd6437290fd336e7", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "g": "d20e17ae1f88e910", + "name": "Iterate loop", + "rules": [ + { + "t": "set", + "p": "index", + "pt": "msg", + "to": "msg.containerSpec.index + 1", + "tot": "jsonata" + }, + { + "t": "set", + "p": "history", + "pt": "msg", + "to": "msg.containerSpec.history", + "tot": "jsonata" + }, + { + "t": "set", + "p": "historyId", + "pt": "msg", + "to": "msg.containerSpec.historyId", + "tot": "jsonata" + }, + { + "t": "set", + "p": "contentCodes", + "pt": "msg", + "to": "msg.containerSpec.contentCodes", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 750, + "y": 1460, + "wires": [ + [ + "7ab56a5e25543ac8", + "5952b16f0c8023f3" + ] + ] + }, + { + "id": "940cc0ae14188d1c", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Get environment", + "func": "const environments = context.get(\"Environments\") || {};\nconst queues = context.get(\"Queues\") || {};\n\n// if docker done\nif (msg.action === \"docker-done\") {\n // get our queue\n const execQueue = queues[msg.containerSpec.historyId] || [];\n // store our environment\n environments[msg.containerSpec.historyId] = msg.containerSpec;\n context.set(\"Environments\", environments);\n // add our environment to each queue message and send them\n return [\n execQueue.map(it => ({\n ...it,\n containerSpec: msg.containerSpec\n }))\n ];\n}\n\n// else, this is a message for executing in an environment\n// get our environment\nconst execEnv = environments[msg.historyId];\n// if we don't have one yet\nif (!execEnv) {\n // get our queue\n const execQueue = queues[msg.historyId] || [];\n // queue our message\n execQueue.push(msg);\n context.set(\"Queues\", queues);\n // don't send any messages\n return;\n}\n// add our environment to our message\nmsg.containerSpec = execEnv;\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 730, + "y": 740, + "wires": [ + [ + "1a70750cb8a22229" + ] + ] + }, + { + "id": "5ae745cf98b55950", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "g": "d20e17ae1f88e910", + "name": "Update environment", + "rules": [ + { + "t": "set", + "p": "containerSpec", + "pt": "msg", + "to": "$merge([msg.containerSpec, { historyId: msg.history.id }])", + "tot": "jsonata" + }, + { + "t": "set", + "p": "action", + "pt": "msg", + "to": "docker-done", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 740, + "y": 1500, + "wires": [ + [ + "35a1e0a9c30682f6", + "93f20029ca3784d0", + "e874a9f9c957d07f" + ] + ] + }, + { + "id": "93f20029ca3784d0", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Get Aggregate Script Outputs", + "func": "const outputs = context.get(\"Outputs\") || [];\n\n// if this is the beginning of a loop\nif ([\"loop-codes\", \"reset-codes\"].includes(msg.action)) {\n // reset our outputs\n context.set(\"Outputs\", []);\n // don't return any messages\n return;\n}\n\n// if this is an output to aggregate\nif ([\"docker-stdout\", \"docker-stderr\"].includes(msg.action)) {\n outputs.push(msg);\n context.set(\"Outputs\", outputs);\n // don't return any messages\n return;\n}\n\n// else, return our aggregated outputs\nmsg.scriptOutputs = outputs;\ncontext.set(\"Outputs\", []);\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1160, + "y": 1460, + "wires": [ + [ + "6634abddc36c6662" + ] + ] + }, + { + "id": "c8668175271219a7", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "Reset codes", + "rules": [ + { + "t": "set", + "p": "action", + "pt": "msg", + "to": "reset-codes", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1110, + "y": 1320, + "wires": [ + [ + "93f20029ca3784d0" + ] + ] + }, + { + "id": "cf5d7ad2b913deed", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Chrome unavailable prompt template", + "func": "msg.createPrompt = () => {\n return 'Chrome is not available, please use a different method.';\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1190, + "y": 1000, + "wires": [ + [ + "8c491b44c49379ec" + ] + ] + }, + { + "id": "8c491b44c49379ec", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Add Exec Message", + "func": "msg = {\n action: \"prog-history-add-entry\",\n entry: {\n role: \"user\",\n content: msg.createPrompt()\n },\n id: msg.historyId\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1490, + "y": 1080, + "wires": [ + [ + "c8668175271219a7", + "824ad7c29ee4fd68", + "d1688f392dbffd37" + ] + ] + }, + { + "id": "1e8f78c5c7e72bca", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Script exists prompt template", + "func": "msg.createPrompt = () => {\n return \"We've already tried that script.\";\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1160, + "y": 1180, + "wires": [ + [ + "8c491b44c49379ec" + ] + ] + }, + { + "id": "6634abddc36c6662", + "type": "function", + "z": "3b5c9ca1fb9ebf48", + "name": "Script output prompt template", + "func": "const outputs = msg.scriptOutputs;\n\nconst streamMaxLength = 1350;\n\nmsg.createPrompt = () => {\n return outputs.map(outMsg => {\n const tag = outMsg.action === \"docker-stdout\" ? \"stdout\" : \"stderr\";\n return `<${tag} beginningTruncated=\"${outMsg.content.length > streamMaxLength ? 'true' : 'false'}\">\n${outMsg.content.slice(-streamMaxLength)}\n\n\n`\n }).join('');\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1170, + "y": 1500, + "wires": [ + [ + "8c491b44c49379ec" + ] + ] + }, + { + "id": "16406d3e5582a1a4", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "name": "Begin code loop", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 980, + "y": 800, + "wires": [] + }, + { + "id": "d1688f392dbffd37", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "name": "Executor Message", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1490, + "y": 1120, + "wires": [] + }, + { + "id": "5952b16f0c8023f3", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "name": "Iterate loop", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 750, + "y": 1560, + "wires": [] + }, + { + "id": "e874a9f9c957d07f", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "name": "End loop", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 700, + "y": 1600, + "wires": [] + }, + { + "id": "053e11fd5e2f4c95", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "name": "Current code", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 970, + "y": 920, + "wires": [] + }, + { + "id": "544de36198caadba", + "type": "subflow:d5c98b48f9d2d77f", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "x": 780, + "y": 860, + "wires": [ + [ + "d51dc15e41460eed" + ] + ] + }, + { + "id": "d51dc15e41460eed", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "Get decode", + "rules": [ + { + "t": "set", + "p": "currentCode", + "pt": "msg", + "to": "decodedContent", + "tot": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 750, + "y": 900, + "wires": [ + [ + "f92c3f86107e5f1a", + "053e11fd5e2f4c95" + ] + ] + }, + { + "id": "b3f008f8f6712c97", + "type": "debug", + "z": "3b5c9ca1fb9ebf48", + "name": "Create script stderr", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 990, + "y": 1040, + "wires": [] + }, + { + "id": "61627dea12b6773b", + "type": "change", + "z": "3b5c9ca1fb9ebf48", + "name": "Get history", + "rules": [ + { + "t": "set", + "p": "historyId", + "pt": "msg", + "to": "msg.containerSpec.historyId", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1110, + "y": 1140, + "wires": [ + [ + "1e8f78c5c7e72bca" + ] + ] + }, + { + "id": "fb44317b333bd1ce", + "type": "subflow:2b3efcc977e88d91", + "z": "3b5c9ca1fb9ebf48", + "name": "", + "env": [ + { + "name": "Url", + "value": "bash-executor-view", + "type": "str" + } + ], + "x": 950, + "y": 340, + "wires": [ + [] + ] + }, + { + "id": "b2e03950e248b5e7", + "type": "comment", + "z": "3b5c9ca1fb9ebf48", + "name": "TODO", + "info": "1. Parse \"command not found\" and prompt to remember to install dependencies.\n2. Identify the AI getting stuck (cross threshold of scripts/messages) and prompt it to identify the problems it is having and recommend solutions\n - try and do this before the context window is exhausted.\n", + "x": 130, + "y": 140, + "wires": [] + }, + { + "id": "fe160cbe0df384e5", + "type": "template", + "z": "191694dad2850f37", + "name": "System Prompt", + "field": "prompt", + "fieldType": "msg", + "format": "handlebars", + "syntax": "mustache", + "template": "You are a helpful chat bot that will perform any requested tasks to the best of your ability.", + "output": "str", + "x": 200, + "y": 520, + "wires": [ + [ + "81b98c3380c57334" + ] + ] + }, + { + "id": "34fa053e9707e425", + "type": "subflow:74bd10ee8e354d0a", + "z": "191694dad2850f37", + "g": "b1dd9777ee396bd7", + "name": "Solution History", + "env": [ + { + "name": "Id", + "value": "solution-01", + "type": "str" + } + ], + "x": 480, + "y": 380, + "wires": [ + [ + "8565c4a9a8c13312", + "88802dbd1e8b0c57", + "b38cd518b824c20d" + ] + ] + }, + { + "id": "9d0d59cbd0342094", + "type": "inject", + "z": "191694dad2850f37", + "g": "0e31504694a6eb0c", + "name": "Start Loop", + "props": [ + { + "p": "action", + "v": "step-go-to", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 500, + "y": 80, + "wires": [ + [ + "b67aacc8e54e5106" + ] + ] + }, + { + "id": "c85c2df7d79465a0", + "type": "subflow:a59054999730c251", + "z": "191694dad2850f37", + "d": true, + "g": "83fd8826b0ec3bf4", + "name": "Model - dummy sse", + "env": [ + { + "name": "Id", + "value": "dummy-sse", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal:8091", + "type": "str" + }, + { + "name": "Batch", + "value": "10", + "type": "num" + } + ], + "x": 330, + "y": 680, + "wires": [ + [ + "d48b052e253b43c3" + ] + ] + }, + { + "id": "73516493eccdfd9d", + "type": "subflow:a59054999730c251", + "z": "191694dad2850f37", + "g": "83fd8826b0ec3bf4", + "name": "Model - genai - llama-cpp-llava", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "Batch", + "value": "10", + "type": "num" + } + ], + "x": 370, + "y": 760, + "wires": [ + [ + "d48b052e253b43c3" + ] + ] + }, + { + "id": "f762ec936046e78f", + "type": "comment", + "z": "191694dad2850f37", + "g": "83fd8826b0ec3bf4", + "name": "Models", + "info": "", + "x": 290, + "y": 620, + "wires": [] + }, + { + "id": "e451712bc8b52b18", + "type": "debug", + "z": "191694dad2850f37", + "g": "ce1b28a464e3b3b3", + "name": "Model Errors", + "active": true, + "tosidebar": true, + "console": true, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 460, + "y": 880, + "wires": [] + }, + { + "id": "e2dd14f8d37e7a72", + "type": "debug", + "z": "191694dad2850f37", + "g": "ce1b28a464e3b3b3", + "name": "Model Output", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 460, + "y": 840, + "wires": [] + }, + { + "id": "bb6dc487db2ce156", + "type": "switch", + "z": "191694dad2850f37", + "g": "ce1b28a464e3b3b3", + "name": "Action", + "property": "action", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "model-streaming-content", + "vt": "str" + }, + { + "t": "eq", + "v": "model-error", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 290, + "y": 860, + "wires": [ + [ + "e2dd14f8d37e7a72" + ], + [ + "e451712bc8b52b18" + ] + ] + }, + { + "id": "42cede20c9456a92", + "type": "subflow:74bd10ee8e354d0a", + "z": "191694dad2850f37", + "g": "5dbdaf47523ce33a", + "name": "Eval History", + "env": [ + { + "name": "Id", + "value": "eval-01", + "type": "str" + } + ], + "x": 1270, + "y": 640, + "wires": [ + [ + "1f999e727d7bdcbd", + "f79210375a125e74", + "c9ba32537f7bc133", + "6b036e58872195a7" + ] + ] + }, + { + "id": "b67aacc8e54e5106", + "type": "function", + "z": "191694dad2850f37", + "g": "0e31504694a6eb0c", + "name": "Prompt: Problem statement", + "func": "msg.createUserPrompt = () =>\n `I have 10K in savings currently in an investment account. My goal is to earn a passive income of $10K every month. Create a plan for me that will meet this goal. I'm looking for single tailored plan, not options to choose from. Give specific, brief instructions for carrying out this plan.`;\n\nflow.set(\"originalProblemStatement\", msg.createUserPrompt());\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 220, + "y": 160, + "wires": [ + [ + "8565c4a9a8c13312" + ] + ] + }, + { + "id": "81b98c3380c57334", + "type": "function", + "z": "191694dad2850f37", + "g": "83fd8826b0ec3bf4", + "name": "In", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 150, + "y": 700, + "wires": [ + [ + "c85c2df7d79465a0", + "73516493eccdfd9d", + "93859b35073996c8" + ] + ], + "icon": "font-awesome/fa-address-card-o" + }, + { + "id": "d48b052e253b43c3", + "type": "function", + "z": "191694dad2850f37", + "g": "83fd8826b0ec3bf4", + "name": "Out", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 590, + "y": 700, + "wires": [ + [ + "bb6dc487db2ce156", + "4135e1850bf3099c", + "fe0f3fe28e08e2f0", + "0800060d86e1ca55", + "079bf5373fe5d58f", + "b38cd518b824c20d" + ] + ], + "icon": "font-awesome/fa-address-card-o" + }, + { + "id": "c533acab9a1bba89", + "type": "comment", + "z": "191694dad2850f37", + "g": "0e31504694a6eb0c", + "name": "Step 1: Problem Statement and Solution", + "info": "", + "x": 250, + "y": 80, + "wires": [] + }, + { + "id": "8516a2d5188e142d", + "type": "comment", + "z": "191694dad2850f37", + "g": "17a2a4d88505d1b2", + "name": "Step 2: Evaluate Solution", + "info": "", + "x": 990, + "y": 340, + "wires": [] + }, + { + "id": "5dd26b4eb51f86a8", + "type": "comment", + "z": "191694dad2850f37", + "g": "3334e9dd5bf3557d", + "name": "Step 3: Propose New Prompt", + "info": "", + "x": 1000, + "y": 820, + "wires": [] + }, + { + "id": "0800060d86e1ca55", + "type": "function", + "z": "191694dad2850f37", + "g": "0df36a8be0d76989", + "name": "Prompt: Use proposed prompt", + "func": "msg.createUserPrompt = (history) => {\n const promptProposal = history.entries.slice(-1)[0].content;\n let newPrompt;\n try {\n // don't search for full ending tag, since sometimes the last token gets cutoff\n newPrompt = promptProposal.match(/([\\s\\S]*?)<\\/pro/)[1].trim();\n if (newPrompt.length < 1) {\n throw new Error(\"Empty prompt extracted from proposal\")\n }\n }\n catch (e) {\n throw new Error(`Error extracting prompt from: \\`${promptProposal}\\``);\n }\n\n return newPrompt;\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1010, + "y": 160, + "wires": [ + [ + "a33731f7d26ff1d8" + ] + ] + }, + { + "id": "32fd036f241606a1", + "type": "comment", + "z": "191694dad2850f37", + "g": "0df36a8be0d76989", + "name": "Step 4: Restart w/ New Prompt", + "info": "", + "x": 1010, + "y": 80, + "wires": [] + }, + { + "id": "0ad9554c20eb8dd0", + "type": "switch", + "z": "191694dad2850f37", + "g": "b1dd9777ee396bd7", + "name": "If Step 1", + "property": "step", + "propertyType": "flow", + "rules": [ + { + "t": "eq", + "v": "1", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 460, + "y": 340, + "wires": [ + [ + "34fa053e9707e425" + ] + ] + }, + { + "id": "4135e1850bf3099c", + "type": "switch", + "z": "191694dad2850f37", + "g": "5dbdaf47523ce33a", + "name": "If Step 2 or 3", + "property": "step", + "propertyType": "flow", + "rules": [ + { + "t": "btwn", + "v": "2", + "vt": "num", + "v2": "3", + "v2t": "num" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 1270, + "y": 600, + "wires": [ + [ + "42cede20c9456a92" + ] + ] + }, + { + "id": "93859b35073996c8", + "type": "subflow:a59054999730c251", + "z": "191694dad2850f37", + "d": true, + "g": "83fd8826b0ec3bf4", + "name": "Model - openai - localhost", + "env": [ + { + "name": "Id", + "value": "openai-localhost", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal:8080", + "type": "str" + } + ], + "x": 350, + "y": 720, + "wires": [ + [ + "d48b052e253b43c3" + ] + ] + }, + { + "id": "8565c4a9a8c13312", + "type": "subflow:fe8f70709279ea90", + "z": "191694dad2850f37", + "g": "0e31504694a6eb0c", + "name": "Step 1", + "env": [ + { + "name": "Step", + "value": "1", + "type": "num" + }, + { + "name": "InitHistoryId", + "value": "solution-01", + "type": "str" + }, + { + "name": "Wait", + "value": "false", + "type": "bool" + } + ], + "x": 510, + "y": 160, + "wires": [ + [ + "0ad9554c20eb8dd0" + ] + ] + }, + { + "id": "1322aa4137d1056e", + "type": "function", + "z": "191694dad2850f37", + "d": true, + "g": "17a2a4d88505d1b2", + "name": "Prompt: Evalutate Solution", + "func": "msg.createUserPrompt = (history) => {\n const problemStatement = history.entries[0].content;\n\n const solution = history.entries.slice(-1)[0].content;\n\n return `I'm going to give you a prompt that a user named Lilly gave to an LLM model named BigStar-13B. Then, I will give you the response BigStar gave to Lilly. I want you to rate BigStar's response on a scale from 1-10. Then, give 2-3 specific improvements to BigStar's response that would have increased it's rating.\n\nHere is Lilly's prompt:\n\n${problemStatement}\n\nHere is BigStar's response:\n\n${solution}\n\nWhat would you rate BigStar's response?`;\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1020, + "y": 420, + "wires": [ + [ + "1f999e727d7bdcbd" + ] + ] + }, + { + "id": "1f999e727d7bdcbd", + "type": "subflow:fe8f70709279ea90", + "z": "191694dad2850f37", + "g": "17a2a4d88505d1b2", + "name": "Step 2", + "env": [ + { + "name": "Step", + "value": "2", + "type": "num" + }, + { + "name": "InitHistoryId", + "value": "eval-01", + "type": "str" + } + ], + "x": 1290, + "y": 420, + "wires": [ + [ + "4135e1850bf3099c" + ] + ] + }, + { + "id": "833eaf27d6837495", + "type": "subflow:fe8f70709279ea90", + "z": "191694dad2850f37", + "g": "3334e9dd5bf3557d", + "name": "Step 3", + "env": [ + { + "name": "Step", + "value": "3", + "type": "num" + }, + { + "name": "InitHistory", + "value": "false", + "type": "bool" + } + ], + "x": 1290, + "y": 900, + "wires": [ + [ + "909642bb1b9261ea" + ] + ] + }, + { + "id": "fe0f3fe28e08e2f0", + "type": "function", + "z": "191694dad2850f37", + "g": "3334e9dd5bf3557d", + "name": "Prompt: Propose New Prompt", + "func": "msg.createUserPrompt = () => \n `How could Lilly's prompt be altered to get BigStar to respond with your suggested improvements? Please provide the new prompt wrapped in tags.`;\n\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1010, + "y": 900, + "wires": [ + [ + "833eaf27d6837495" + ] + ] + }, + { + "id": "a33731f7d26ff1d8", + "type": "subflow:fe8f70709279ea90", + "z": "191694dad2850f37", + "g": "0df36a8be0d76989", + "name": "Step 4", + "env": [ + { + "name": "Step", + "value": "4", + "type": "num" + }, + { + "name": "InitHistory", + "value": "false", + "type": "bool" + } + ], + "x": 930, + "y": 220, + "wires": [ + [ + "85c126ddb6ae9692" + ] + ] + }, + { + "id": "36217d16d71a4c30", + "type": "inject", + "z": "191694dad2850f37", + "g": "17a2a4d88505d1b2", + "name": "Start @ Step 2", + "props": [ + { + "p": "historyId", + "v": "solution-01", + "vt": "str" + }, + { + "p": "historySourceFilename", + "v": "/data/db/history-1706503270302.json", + "vt": "str" + }, + { + "p": "action", + "v": "step-start-at", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 1260, + "y": 340, + "wires": [ + [ + "b38cd518b824c20d" + ] + ] + }, + { + "id": "7b60dc37c59dc80f", + "type": "inject", + "z": "191694dad2850f37", + "g": "0df36a8be0d76989", + "name": "Start @ Step 4", + "props": [ + { + "p": "historyId", + "v": "eval-01", + "vt": "str" + }, + { + "p": "historySourceFilename", + "v": "/data/db/history-1706169633523.json", + "vt": "str" + }, + { + "p": "action", + "v": "step-start-at", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 1260, + "y": 80, + "wires": [ + [ + "0800060d86e1ca55" + ] + ] + }, + { + "id": "36f73b6e3236c721", + "type": "inject", + "z": "191694dad2850f37", + "g": "3334e9dd5bf3557d", + "name": "Start @ Step 3", + "props": [ + { + "p": "historyId", + "v": "eval-01", + "vt": "str" + }, + { + "p": "historySourceFilename", + "v": "/data/db/history-1706169407261.json", + "vt": "str" + }, + { + "p": "action", + "v": "step-start-at", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 1260, + "y": 820, + "wires": [ + [ + "fe0f3fe28e08e2f0" + ] + ] + }, + { + "id": "bd8902942d9f30bc", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 795, + "y": 780, + "wires": [ + [ + "fe0f3fe28e08e2f0" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "f79210375a125e74", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1435, + "y": 660, + "wires": [ + [ + "bd8902942d9f30bc" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "909642bb1b9261ea", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1435, + "y": 820, + "wires": [ + [ + "246801bf115544b3" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "246801bf115544b3", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1125, + "y": 640, + "wires": [ + [ + "4135e1850bf3099c" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "c9ba32537f7bc133", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1435, + "y": 320, + "wires": [ + [ + "322d52b49ebe2f42" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "88802dbd1e8b0c57", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 645, + "y": 420, + "wires": [ + [ + "fe160cbe0df384e5" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "85c126ddb6ae9692", + "type": "subflow:3bb38f582155f29d", + "z": "191694dad2850f37", + "g": "0df36a8be0d76989", + "name": "", + "x": 1050, + "y": 220, + "wires": [ + [ + "a8aa5ac1df416d41" + ] + ] + }, + { + "id": "a8aa5ac1df416d41", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 345, + "y": 280, + "wires": [ + [ + "8565c4a9a8c13312" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "322d52b49ebe2f42", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 755, + "y": 260, + "wires": [ + [ + "0800060d86e1ca55" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "6b036e58872195a7", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1435, + "y": 560, + "wires": [ + [ + "fe160cbe0df384e5" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "079bf5373fe5d58f", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 775, + "y": 640, + "wires": [ + [ + "c8bf1c9a8fe80c37" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "c8bf1c9a8fe80c37", + "type": "function", + "z": "191694dad2850f37", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 305, + "y": 380, + "wires": [ + [ + "0ad9554c20eb8dd0" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "b38cd518b824c20d", + "type": "function", + "z": "191694dad2850f37", + "g": "17a2a4d88505d1b2", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 855, + "y": 420, + "wires": [ + [ + "1322aa4137d1056e", + "9240a0389d51445c" + ] + ], + "icon": "font-awesome/fa-arrows", + "l": false + }, + { + "id": "9240a0389d51445c", + "type": "function", + "z": "191694dad2850f37", + "g": "17a2a4d88505d1b2", + "name": "Prompt: Evalutate Against Original", + "func": "msg.createUserPrompt = (history) => {\n const problemStatement = flow.get(\"originalProblemStatement\");\n\n const solution = history.entries.slice(-1)[0].content;\n\n return `I'm going to give you a prompt that a user named Lilly gave to an LLM model named BigStar-13B. Then, I will give you the response BigStar gave to Lilly. I want you to rate BigStar's response on a scale from 1-10. Then, give 2-3 specific improvements to BigStar's response that would have increased it's rating.\n\nHere is Lilly's prompt:\n\n${problemStatement}\n\nHere is BigStar's response:\n\n${solution}\n\nWhat would you rate BigStar's response?`;\n};\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1040, + "y": 460, + "wires": [ + [ + "1f999e727d7bdcbd" + ] + ] + }, + { + "id": "3e349487bb31edf5", + "type": "inject", + "z": "8518392b3e041cfe", + "name": "", + "props": [ + { + "p": "payload" }, { - "name": "BaseUrl", - "value": "http://host.docker.internal:8080", - "type": "str" + "p": "topic", + "vt": "str" } ], - "x": 310, - "y": 540, + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 420, + "y": 320, "wires": [ [ - "0bdfb9335b655b7b" + "ec9ee8ba595e12ca" ] ] }, { - "id": "5b1ba49c624f1633", - "type": "subflow:a59054999730c251", - "z": "4d258c7de41d3e07", - "d": true, - "g": "a6665159eabf55ba", - "name": "Model - genai - llama-cpp-llava", - "env": [ - { - "name": "Id", - "value": "genai-llama-cpp-llava", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", - "type": "str" - } - ], - "x": 330, - "y": 580, + "id": "ec9ee8ba595e12ca", + "type": "function", + "z": "8518392b3e041cfe", + "name": "function 13", + "func": "flow.set(\"prop\", 14);\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 670, + "y": 320, "wires": [ [ - "0bdfb9335b655b7b" + "9827779f81d25fee", + "513f707299db2bac" ] ] }, { - "id": "4289f12402c6ede9", - "type": "comment", - "z": "4d258c7de41d3e07", - "g": "a6665159eabf55ba", - "name": "Models", - "info": "", - "x": 250, - "y": 480, - "wires": [] + "id": "9827779f81d25fee", + "type": "function", + "z": "8518392b3e041cfe", + "name": "function 14", + "func": "msg.root = flow.get(\"prop\");\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 950, + "y": 340, + "wires": [ + [ + "1ae2ee3010712831" + ] + ] }, { - "id": "9abd1089c5b967cc", + "id": "3fe3f4f66c1086bc", "type": "debug", - "z": "4d258c7de41d3e07", - "g": "57d76b98327ee84c", - "name": "Model Errors", + "z": "8518392b3e041cfe", + "name": "debug 27", "active": true, "tosidebar": true, "console": false, @@ -8737,68 +14364,69 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 410, - "y": 740, + "x": 1360, + "y": 340, "wires": [] }, { - "id": "41c6b6041924578c", - "type": "debug", - "z": "4d258c7de41d3e07", - "g": "57d76b98327ee84c", - "name": "Model Output", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 420, - "y": 700, - "wires": [] + "id": "1ae2ee3010712831", + "type": "subflow:95c38d96d861b4c4", + "z": "8518392b3e041cfe", + "name": "", + "x": 1180, + "y": 340, + "wires": [ + [ + "3fe3f4f66c1086bc" + ] + ] }, { - "id": "388b8948292a6e42", + "id": "513f707299db2bac", "type": "switch", - "z": "4d258c7de41d3e07", - "g": "57d76b98327ee84c", - "name": "Action", - "property": "action", + "z": "8518392b3e041cfe", + "name": "MySwitch", + "property": "payload", "propertyType": "msg", "rules": [ { "t": "eq", - "v": "model-streaming-content", + "v": "one", "vt": "str" }, { "t": "eq", - "v": "model-error", + "v": "two", + "vt": "str" + }, + { + "t": "eq", + "v": "three", "vt": "str" } ], "checkall": "true", "repair": false, - "outputs": 2, - "x": 250, - "y": 720, + "outputs": 3, + "x": 840, + "y": 460, "wires": [ [ - "41c6b6041924578c" + "faeb427526c15c85" ], [ - "9abd1089c5b967cc" + "aafa6c5af0929a27" + ], + [ + "4649802dd53440e4" ] ] }, { - "id": "0bdfb9335b655b7b", + "id": "faeb427526c15c85", "type": "function", - "z": "4d258c7de41d3e07", - "g": "a6665159eabf55ba", - "name": " ", + "z": "8518392b3e041cfe", + "name": "function 17", "func": "\nreturn msg;", "outputs": 1, "timeout": 0, @@ -8806,120 +14434,233 @@ "initialize": "", "finalize": "", "libs": [], - "x": 535, - "y": 600, + "x": 1030, + "y": 420, + "wires": [ + [] + ] + }, + { + "id": "aafa6c5af0929a27", + "type": "function", + "z": "8518392b3e041cfe", + "name": "function 18", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1050, + "y": 480, + "wires": [ + [] + ] + }, + { + "id": "4649802dd53440e4", + "type": "function", + "z": "8518392b3e041cfe", + "name": "function 19", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1030, + "y": 580, + "wires": [ + [] + ] + }, + { + "id": "07b22b0dc0d11143", + "type": "rbe", + "z": "8518392b3e041cfe", + "name": "", + "func": "rbe", + "gap": "", + "start": "", + "inout": "out", + "septopics": true, + "property": "payload", + "topi": "topic", + "x": 710, + "y": 720, + "wires": [ + [] + ] + }, + { + "id": "a55573e0a503cd32", + "type": "delay", + "z": "8518392b3e041cfe", + "name": "", + "pauseType": "delay", + "timeout": "5", + "timeoutUnits": "seconds", + "rate": "1", + "nbRateUnits": "1", + "rateUnits": "second", + "randomFirst": "1", + "randomLast": "5", + "randomUnits": "seconds", + "drop": false, + "allowrate": false, + "outputs": 1, + "x": 1040, + "y": 660, + "wires": [ + [] + ] + }, + { + "id": "e9f8ed38bd8d02c0", + "type": "http request", + "z": "8518392b3e041cfe", + "name": "TEST-HTTP-REQ", + "method": "GET", + "ret": "txt", + "paytoqs": "ignore", + "url": "http://example.com", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "basic", + "senderr": false, + "headers": [], + "x": 670, + "y": 480, "wires": [ - [ - "388b8948292a6e42", - "e89cf8812605d88f" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + [] + ] }, { - "id": "083cd95ebe479e4c", - "type": "subflow:2ec5ed7947d505dd", - "z": "4d258c7de41d3e07", - "g": "41a1b6b6b5db2dc0", - "name": "", - "env": [ + "id": "8bfdab680b95f8bb", + "type": "switch", + "z": "8518392b3e041cfe", + "name": "If not null, else", + "property": "payload", + "propertyType": "msg", + "rules": [ { - "name": "Id", - "value": "simple-rag", - "type": "str" + "t": "nnull" }, { - "name": "BaseUrl", - "value": "http://host.docker.internal:6333", - "type": "str" + "t": "else" } ], - "x": 990, - "y": 280, + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 780, + "y": 200, "wires": [ [ - "87918d4b1691fe73", - "62ff4025db27f69b", - "e89cf8812605d88f" + "df7672b738a32382" + ], + [ + "aa9403ce7147f75f" ] ] }, { - "id": "ac073e3ad1964190", - "type": "subflow:9eb27f011bcf9a83", - "z": "4d258c7de41d3e07", - "d": true, - "g": "132bac76be391419", - "name": "Embeddings - Llama.cpp - localhost", - "env": [ - { - "name": "Id", - "value": "llama-cpp-localhost", - "type": "str" - }, + "id": "df7672b738a32382", + "type": "debug", + "z": "8518392b3e041cfe", + "name": "debug 28", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "\"Not empty\"", + "targetType": "jsonata", + "statusVal": "", + "statusType": "auto", + "x": 980, + "y": 160, + "wires": [] + }, + { + "id": "aa9403ce7147f75f", + "type": "debug", + "z": "8518392b3e041cfe", + "name": "debug 29", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "\"Empty\"", + "targetType": "jsonata", + "statusVal": "", + "statusType": "auto", + "x": 980, + "y": 220, + "wires": [] + }, + { + "id": "a949b1fe09dd6896", + "type": "inject", + "z": "8518392b3e041cfe", + "name": "", + "props": [ { - "name": "BaseUrl", - "value": "http://host.docker.internal:8080", - "type": "str" + "p": "payload" } ], - "x": 1540, - "y": 460, + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "undefined", + "payloadType": "jsonata", + "x": 530, + "y": 200, "wires": [ [ - "4d5a8d1e8ff6d660" + "8bfdab680b95f8bb" ] ] }, { - "id": "c714a08872d8c5e7", - "type": "function", + "id": "c595413a72a78b1b", + "type": "subflow:2b3efcc977e88d91", "z": "4d258c7de41d3e07", - "g": "d89f22418de07fba", - "name": "Load files", - "func": "const { DocxLoader } = langchainDocumentLoadersFsDocx;\nconst { DirectoryLoader } = langchainDocumentLoadersFsDirectory;\nconst { RecursiveCharacterTextSplitter } = langchainTextSplitter;\n\nconst loader = new DirectoryLoader(\n msg.directory,\n {\n \".docx\": (path) => new DocxLoader(path)\n }\n);\n\nconst splitter = new RecursiveCharacterTextSplitter();\n\n(async () => {\n try {\n let docs = await loader.load();\n docs = await splitter.splitDocuments(docs);\n node.send({\n action: \"vector-store-update-index\",\n docs\n });\n }\n catch (e) {\n node.error(e.stack);\n }\n})();\n", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [ - { - "var": "langchainDocumentLoadersFsDirectory", - "module": "langchain/document_loaders/fs/directory" - }, - { - "var": "langchainDocumentLoadersFsDocx", - "module": "langchain/document_loaders/fs/docx" - }, - { - "var": "langchainTextSplitter", - "module": "langchain/text_splitter" - }, + "name": "", + "env": [ { - "var": "mammoth", - "module": "mammoth" + "name": "Url", + "value": "simple-rag", + "type": "str" } ], - "x": 1420, - "y": 220, + "x": 510, + "y": 320, "wires": [ [ - "083cd95ebe479e4c" + "e89cf8812605d88f" ] ] }, { - "id": "9602172f379d6949", + "id": "fb6acbac6e2d9fc4", "type": "inject", "z": "4d258c7de41d3e07", - "g": "d89f22418de07fba", - "name": "Index directory", + "name": "Start App", "props": [ { - "p": "directory", - "v": "/data/rag/simple-rag/new", + "p": "timestamp", + "v": "", + "vt": "date" + }, + { + "p": "action", + "v": "history-init", "vt": "str" } ], @@ -8928,97 +14669,85 @@ "once": false, "onceDelay": 0.1, "topic": "", - "x": 1440, - "y": 160, + "x": 120, + "y": 120, "wires": [ [ - "c714a08872d8c5e7" + "e89cf8812605d88f" ] ] }, { - "id": "f6ee8199578688d0", - "type": "subflow:9eb27f011bcf9a83", + "id": "1525d739279d5422", + "type": "subflow:a59054999730c251", "z": "4d258c7de41d3e07", "d": true, - "g": "132bac76be391419", - "name": "Embeddings - dummy - localhost", + "g": "a6665159eabf55ba", + "name": "Model - openai - localhost", "env": [ { "name": "Id", - "value": "dummy-localhost", + "value": "openai-localhost", "type": "str" }, { "name": "BaseUrl", - "value": "http://host.docker.internal:8091", + "value": "http://host.docker.internal:8080", "type": "str" } ], - "x": 1540, - "y": 420, + "x": 310, + "y": 540, "wires": [ [ - "4d5a8d1e8ff6d660" + "0bdfb9335b655b7b" ] ] }, { - "id": "87918d4b1691fe73", - "type": "function", + "id": "5b1ba49c624f1633", + "type": "subflow:a59054999730c251", "z": "4d258c7de41d3e07", - "g": "132bac76be391419", - "name": " ", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1355, - "y": 360, - "wires": [ - [ - "f6ee8199578688d0", - "ac073e3ad1964190", - "a9572ffa926d1edc", - "1648a58fa167dcbd" - ] + "d": true, + "g": "a6665159eabf55ba", + "name": "Model - genai - llama-cpp-llava", + "env": [ + { + "name": "Id", + "value": "genai-llama-cpp-llava", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", + "type": "str" + } ], - "icon": "font-awesome/fa-arrows", - "l": false - }, - { - "id": "4d5a8d1e8ff6d660", - "type": "function", - "z": "4d258c7de41d3e07", - "g": "132bac76be391419", - "name": " ", - "func": "\nreturn msg;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1765, - "y": 520, + "x": 330, + "y": 580, "wires": [ [ - "b3466cd08378ae07", - "1c99cd2039cfe650" + "0bdfb9335b655b7b" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] + }, + { + "id": "4289f12402c6ede9", + "type": "comment", + "z": "4d258c7de41d3e07", + "g": "a6665159eabf55ba", + "name": "Models", + "info": "", + "x": 250, + "y": 480, + "wires": [] }, { - "id": "92142139591ba63d", + "id": "9abd1089c5b967cc", "type": "debug", "z": "4d258c7de41d3e07", - "g": "a4c668896ae9d468", - "name": "Embeddings Errors", + "g": "57d76b98327ee84c", + "name": "Model Errors", "active": true, "tosidebar": true, "console": false, @@ -9027,17 +14756,17 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 1630, - "y": 660, + "x": 410, + "y": 740, "wires": [] }, { - "id": "419f2ab4efdbabd3", + "id": "41c6b6041924578c", "type": "debug", "z": "4d258c7de41d3e07", - "g": "a4c668896ae9d468", - "name": "Embeddings Output", - "active": true, + "g": "57d76b98327ee84c", + "name": "Model Output", + "active": false, "tosidebar": true, "console": false, "tostatus": false, @@ -9045,15 +14774,15 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 1640, - "y": 620, + "x": 420, + "y": 700, "wires": [] }, { - "id": "b3466cd08378ae07", + "id": "388b8948292a6e42", "type": "switch", "z": "4d258c7de41d3e07", - "g": "a4c668896ae9d468", + "g": "57d76b98327ee84c", "name": "Action", "property": "action", "propertyType": "msg", @@ -9072,113 +14801,22 @@ "checkall": "true", "repair": false, "outputs": 2, - "x": 1450, - "y": 640, + "x": 250, + "y": 720, "wires": [ [ - "419f2ab4efdbabd3" + "41c6b6041924578c" ], [ - "92142139591ba63d" - ] - ] - }, - { - "id": "f68cbbc22164d634", - "type": "comment", - "z": "4d258c7de41d3e07", - "g": "132bac76be391419", - "name": "Embeddings Models", - "info": "", - "x": 1490, - "y": 360, - "wires": [] - }, - { - "id": "62ff4025db27f69b", - "type": "switch", - "z": "4d258c7de41d3e07", - "g": "41a1b6b6b5db2dc0", - "name": "Action", - "property": "action", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "vector-store-error", - "vt": "str" - } - ], - "checkall": "true", - "repair": false, - "outputs": 1, - "x": 950, - "y": 360, - "wires": [ - [ - "e3090e8b70f84526" - ] - ] - }, - { - "id": "e3090e8b70f84526", - "type": "debug", - "z": "4d258c7de41d3e07", - "g": "41a1b6b6b5db2dc0", - "name": "VectorStore Errors", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 1130, - "y": 360, - "wires": [] - }, - { - "id": "2989cf7eca1cfaaa", - "type": "comment", - "z": "4d258c7de41d3e07", - "g": "41a1b6b6b5db2dc0", - "name": "Vector Store", - "info": "", - "x": 970, - "y": 220, - "wires": [] - }, - { - "id": "8e8a149c1cc8ba68", - "type": "comment", - "z": "4d258c7de41d3e07", - "g": "d89f22418de07fba", - "name": "Index", - "info": "", - "x": 1410, - "y": 100, - "wires": [] - }, - { - "id": "e89cf8812605d88f", - "type": "subflow:a4137713471da6c4", - "z": "4d258c7de41d3e07", - "name": "", - "x": 330, - "y": 200, - "wires": [ - [ - "c595413a72a78b1b", - "7f0d19a15b573605", - "acd0680bb6e69b51" + "9abd1089c5b967cc" ] ] }, { - "id": "1c99cd2039cfe650", + "id": "0bdfb9335b655b7b", "type": "function", "z": "4d258c7de41d3e07", + "g": "a6665159eabf55ba", "name": " ", "func": "\nreturn msg;", "outputs": 1, @@ -9187,59 +14825,66 @@ "initialize": "", "finalize": "", "libs": [], - "x": 1835, - "y": 340, + "x": 535, + "y": 600, "wires": [ [ - "083cd95ebe479e4c" + "388b8948292a6e42", + "e89cf8812605d88f" ] ], "icon": "font-awesome/fa-arrows", "l": false }, { - "id": "7f0d19a15b573605", - "type": "function", + "id": "083cd95ebe479e4c", + "type": "subflow:2ec5ed7947d505dd", "z": "4d258c7de41d3e07", - "name": "Prompts", - "func": "msg.systemPrompt = `You are a helpful chat bot that will perform any requested tasks to the best of your ability.`;\n\nmsg.contextPrompt = (context) => `The following documents will provide you useful context when performing your task: \n${\n context.map(doc => {\n return `\n----- BEGIN DOCUMENT: ${doc.metadata.source} -----\n\n${doc.pageContent}\n\n----- END DOCUMENT -----\n`;\n })\n}\n`\n\nreturn msg;\n", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 180, - "y": 360, + "g": "41a1b6b6b5db2dc0", + "name": "", + "env": [ + { + "name": "Id", + "value": "simple-rag", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://host.docker.internal:6333", + "type": "str" + } + ], + "x": 990, + "y": 280, "wires": [ [ - "1525d739279d5422", - "5b1ba49c624f1633", - "1a8be604e1fb0f60" + "87918d4b1691fe73", + "62ff4025db27f69b", + "e89cf8812605d88f" ] ] }, { - "id": "a9572ffa926d1edc", + "id": "ac073e3ad1964190", "type": "subflow:9eb27f011bcf9a83", "z": "4d258c7de41d3e07", "d": true, "g": "132bac76be391419", - "name": "Embeddings - genai - llama-cpp-llava", + "name": "Embeddings - Llama.cpp - localhost", "env": [ { "name": "Id", - "value": "genai-llama-cpp-llava-embeddings", + "value": "llama-cpp-localhost", "type": "str" }, { "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", + "value": "http://host.docker.internal:8080", "type": "str" } ], - "x": 1550, - "y": 500, + "x": 1540, + "y": 460, "wires": [ [ "4d5a8d1e8ff6d660" @@ -9247,154 +14892,101 @@ ] }, { - "id": "acd0680bb6e69b51", + "id": "c714a08872d8c5e7", "type": "function", "z": "4d258c7de41d3e07", - "name": "Vector Search Params", - "func": "msg.vectorSearchParams = {\n top: 4\n};\n\nreturn msg;", + "g": "d89f22418de07fba", + "name": "Load files", + "func": "const { DocxLoader } = langchainDocumentLoadersFsDocx;\nconst { DirectoryLoader } = langchainDocumentLoadersFsDirectory;\nconst { RecursiveCharacterTextSplitter } = langchainTextSplitter;\n\nconst loader = new DirectoryLoader(\n msg.directory,\n {\n \".docx\": (path) => new DocxLoader(path)\n }\n);\n\nconst splitter = new RecursiveCharacterTextSplitter();\n\n(async () => {\n try {\n let docs = await loader.load();\n docs = await splitter.splitDocuments(docs);\n node.send({\n action: \"vector-store-update-index\",\n docs\n });\n }\n catch (e) {\n node.error(e.stack);\n }\n})();\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", - "libs": [], - "x": 740, - "y": 280, - "wires": [ - [ - "083cd95ebe479e4c" - ] - ] - }, - { - "id": "1a8be604e1fb0f60", - "type": "subflow:a59054999730c251", - "z": "4d258c7de41d3e07", - "g": "a6665159eabf55ba", - "name": "Model - genai - llama-cpp-mistral-8x", - "env": [ + "libs": [ { - "name": "Id", - "value": "genai-llama-cpp-mistral-8x", - "type": "str" + "var": "langchainDocumentLoadersFsDirectory", + "module": "langchain/document_loaders/fs/directory" }, { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", - "type": "str" - } - ], - "x": 340, - "y": 620, - "wires": [ - [ - "0bdfb9335b655b7b" - ] - ] - }, - { - "id": "1648a58fa167dcbd", - "type": "subflow:9eb27f011bcf9a83", - "z": "4d258c7de41d3e07", - "g": "132bac76be391419", - "name": "Embeddings - genai - llama-cpp-mistral-8x", - "env": [ + "var": "langchainDocumentLoadersFsDocx", + "module": "langchain/document_loaders/fs/docx" + }, { - "name": "Id", - "value": "genai-llama-cpp-mistral-8x-embeddings", - "type": "str" + "var": "langchainTextSplitter", + "module": "langchain/text_splitter" }, { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", - "type": "str" + "var": "mammoth", + "module": "mammoth" } ], - "x": 1560, - "y": 540, + "x": 1420, + "y": 220, "wires": [ [ - "4d5a8d1e8ff6d660" + "083cd95ebe479e4c" ] ] }, { - "id": "6b73ef72bb7e4b87", - "type": "subflow:2b3efcc977e88d91", - "z": "ec55121054ad7072", - "name": "", - "env": [ + "id": "9602172f379d6949", + "type": "inject", + "z": "4d258c7de41d3e07", + "g": "d89f22418de07fba", + "name": "Index directory", + "props": [ { - "name": "Url", - "value": "admin-operator", - "type": "str" + "p": "directory", + "v": "/data/rag/simple-rag/new", + "vt": "str" } ], - "x": 310, - "y": 280, + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 1440, + "y": 160, "wires": [ [ - "e77e6ed92b6eba12" + "c714a08872d8c5e7" ] ] }, { - "id": "e77e6ed92b6eba12", - "type": "subflow:74bd10ee8e354d0a", - "z": "ec55121054ad7072", - "name": "Admin History", + "id": "f6ee8199578688d0", + "type": "subflow:9eb27f011bcf9a83", + "z": "4d258c7de41d3e07", + "d": true, + "g": "132bac76be391419", + "name": "Embeddings - dummy - localhost", "env": [ { - "name": "SourceFilename", - "value": "/data/db/history-1711926907124.json", + "name": "Id", + "value": "dummy-localhost", "type": "str" - } - ], - "x": 600, - "y": 280, - "wires": [ - [ - "6b73ef72bb7e4b87", - "0a39bb73f010efd7", - "8ad28cb311d8a5c0" - ] - ] - }, - { - "id": "cd5e2c4e51717c0f", - "type": "inject", - "z": "ec55121054ad7072", - "name": "Start App", - "props": [ - { - "p": "timestamp", - "v": "", - "vt": "date" }, { - "p": "action", - "v": "history-init", - "vt": "str" + "name": "BaseUrl", + "value": "http://host.docker.internal:8091", + "type": "str" } ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "x": 140, - "y": 80, + "x": 1540, + "y": 420, "wires": [ [ - "e77e6ed92b6eba12", - "d7625ef95dd891b8" + "4d5a8d1e8ff6d660" ] ] }, { - "id": "0a34e1dce381f16b", + "id": "87918d4b1691fe73", "type": "function", - "z": "ec55121054ad7072", + "z": "4d258c7de41d3e07", + "g": "132bac76be391419", "name": " ", "func": "\nreturn msg;", "outputs": 1, @@ -9403,89 +14995,49 @@ "initialize": "", "finalize": "", "libs": [], - "x": 205, - "y": 440, + "x": 1355, + "y": 360, "wires": [ [ - "21debbaed5b57fd5", - "75d06bae12a047f9", - "a61cd1dd9aeb1256", - "9d4dbbbd2defb7fb" + "f6ee8199578688d0", + "ac073e3ad1964190", + "a9572ffa926d1edc", + "1648a58fa167dcbd" ] ], "icon": "font-awesome/fa-arrows", "l": false }, { - "id": "75d06bae12a047f9", - "type": "subflow:a59054999730c251", - "z": "ec55121054ad7072", - "d": true, - "g": "0bd29a38bd7fd7ee", - "name": "Model - openai - localhost", - "env": [ - { - "name": "Id", - "value": "openai-localhost", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://host.docker.internal:8080", - "type": "str" - } - ], - "x": 410, - "y": 500, + "id": "4d5a8d1e8ff6d660", + "type": "function", + "z": "4d258c7de41d3e07", + "g": "132bac76be391419", + "name": " ", + "func": "\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1765, + "y": 520, "wires": [ [ - "a98ec39f0f7f2c84" + "b3466cd08378ae07", + "1c99cd2039cfe650" ] - ] - }, - { - "id": "a61cd1dd9aeb1256", - "type": "subflow:a59054999730c251", - "z": "ec55121054ad7072", - "g": "0bd29a38bd7fd7ee", - "name": "Model - genai - llama-cpp-llava", - "env": [ - { - "name": "Id", - "value": "genai-llama-cpp-llava", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", - "type": "str" - } ], - "x": 430, - "y": 540, - "wires": [ - [ - "a98ec39f0f7f2c84" - ] - ] - }, - { - "id": "12901237f1ea6884", - "type": "comment", - "z": "ec55121054ad7072", - "g": "0bd29a38bd7fd7ee", - "name": "Models", - "info": "", - "x": 350, - "y": 400, - "wires": [] + "icon": "font-awesome/fa-arrows", + "l": false }, { - "id": "d9e0c9a3cf18f405", + "id": "92142139591ba63d", "type": "debug", - "z": "ec55121054ad7072", - "g": "7aad90c5be36eb0a", - "name": "Model Errors", + "z": "4d258c7de41d3e07", + "g": "a4c668896ae9d468", + "name": "Embeddings Errors", "active": true, "tosidebar": true, "console": false, @@ -9494,17 +15046,16 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 510, - "y": 700, + "x": 1630, + "y": 660, "wires": [] }, { - "id": "4b7f0d34fcfa313d", + "id": "419f2ab4efdbabd3", "type": "debug", - "z": "ec55121054ad7072", - "d": true, - "g": "7aad90c5be36eb0a", - "name": "Model Output", + "z": "4d258c7de41d3e07", + "g": "a4c668896ae9d468", + "name": "Embeddings Output", "active": true, "tosidebar": true, "console": false, @@ -9513,22 +15064,22 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 520, - "y": 660, + "x": 1640, + "y": 620, "wires": [] }, { - "id": "bbeaa9f159afdfaf", + "id": "b3466cd08378ae07", "type": "switch", - "z": "ec55121054ad7072", - "g": "7aad90c5be36eb0a", + "z": "4d258c7de41d3e07", + "g": "a4c668896ae9d468", "name": "Action", "property": "action", "propertyType": "msg", "rules": [ { "t": "eq", - "v": "model-content", + "v": "model-streaming-content", "vt": "str" }, { @@ -9540,54 +15091,113 @@ "checkall": "true", "repair": false, "outputs": 2, - "x": 350, - "y": 680, + "x": 1450, + "y": 640, "wires": [ [ - "4b7f0d34fcfa313d" + "419f2ab4efdbabd3" ], [ - "d9e0c9a3cf18f405" + "92142139591ba63d" ] ] }, { - "id": "21debbaed5b57fd5", - "type": "subflow:a59054999730c251", - "z": "ec55121054ad7072", - "d": true, - "g": "0bd29a38bd7fd7ee", - "name": "Model - dummy sse", - "env": [ - { - "name": "Id", - "value": "dummy-sse", - "type": "str" - }, - { - "name": "BaseUrl", - "value": "http://host.docker.internal.local:8091", - "type": "str" - }, + "id": "f68cbbc22164d634", + "type": "comment", + "z": "4d258c7de41d3e07", + "g": "132bac76be391419", + "name": "Embeddings Models", + "info": "", + "x": 1490, + "y": 360, + "wires": [] + }, + { + "id": "62ff4025db27f69b", + "type": "switch", + "z": "4d258c7de41d3e07", + "g": "41a1b6b6b5db2dc0", + "name": "Action", + "property": "action", + "propertyType": "msg", + "rules": [ { - "name": "Batch", - "value": "10", - "type": "num" + "t": "eq", + "v": "vector-store-error", + "vt": "str" } ], - "x": 390, - "y": 460, + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 950, + "y": 360, "wires": [ [ - "a98ec39f0f7f2c84" + "e3090e8b70f84526" ] ] }, { - "id": "a98ec39f0f7f2c84", + "id": "e3090e8b70f84526", + "type": "debug", + "z": "4d258c7de41d3e07", + "g": "41a1b6b6b5db2dc0", + "name": "VectorStore Errors", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1130, + "y": 360, + "wires": [] + }, + { + "id": "2989cf7eca1cfaaa", + "type": "comment", + "z": "4d258c7de41d3e07", + "g": "41a1b6b6b5db2dc0", + "name": "Vector Store", + "info": "", + "x": 970, + "y": 220, + "wires": [] + }, + { + "id": "8e8a149c1cc8ba68", + "type": "comment", + "z": "4d258c7de41d3e07", + "g": "d89f22418de07fba", + "name": "Index", + "info": "", + "x": 1410, + "y": 100, + "wires": [] + }, + { + "id": "e89cf8812605d88f", + "type": "subflow:a4137713471da6c4", + "z": "4d258c7de41d3e07", + "name": "", + "x": 330, + "y": 200, + "wires": [ + [ + "c595413a72a78b1b", + "7f0d19a15b573605", + "acd0680bb6e69b51" + ] + ] + }, + { + "id": "1c99cd2039cfe650", "type": "function", - "z": "ec55121054ad7072", - "g": "0bd29a38bd7fd7ee", + "z": "4d258c7de41d3e07", "name": " ", "func": "\nreturn msg;", "outputs": 1, @@ -9596,536 +15206,788 @@ "initialize": "", "finalize": "", "libs": [], - "x": 645, - "y": 560, + "x": 1835, + "y": 340, "wires": [ [ - "e77e6ed92b6eba12", - "bbeaa9f159afdfaf", - "4de07154c6644063" + "083cd95ebe479e4c" ] ], "icon": "font-awesome/fa-arrows", "l": false }, { - "id": "9d4dbbbd2defb7fb", - "type": "subflow:a59054999730c251", - "z": "ec55121054ad7072", + "id": "7f0d19a15b573605", + "type": "function", + "z": "4d258c7de41d3e07", + "name": "Prompts", + "func": "msg.systemPrompt = `You are a helpful chat bot that will perform any requested tasks to the best of your ability.`;\n\nmsg.contextPrompt = (context) => `The following documents will provide you useful context when performing your task: \n${\n context.map(doc => {\n return `\n----- BEGIN DOCUMENT: ${doc.metadata.source} -----\n\n${doc.pageContent}\n\n----- END DOCUMENT -----\n`;\n })\n}\n`\n\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 180, + "y": 360, + "wires": [ + [ + "1525d739279d5422", + "5b1ba49c624f1633", + "1a8be604e1fb0f60" + ] + ] + }, + { + "id": "a9572ffa926d1edc", + "type": "subflow:9eb27f011bcf9a83", + "z": "4d258c7de41d3e07", "d": true, - "g": "0bd29a38bd7fd7ee", - "name": "Model - genai - llama-cpp-mistral-8x", + "g": "132bac76be391419", + "name": "Embeddings - genai - llama-cpp-llava", "env": [ { "name": "Id", - "value": "genai-llama-cpp-mistral-8x", + "value": "genai-llama-cpp-llava-embeddings", "type": "str" }, { "name": "BaseUrl", - "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-llava", "type": "str" } ], - "x": 440, - "y": 580, + "x": 1550, + "y": 500, "wires": [ [ - "a98ec39f0f7f2c84" + "4d5a8d1e8ff6d660" ] ] }, { - "id": "0a39bb73f010efd7", + "id": "acd0680bb6e69b51", "type": "function", - "z": "ec55121054ad7072", - "name": "Admin Prompt", - "func": "msg.systemPrompt = `## Mandate\n\nYou are an AI Administrator.\n\nYour mandate is to manage a collective of AI Operators in order to accomplish the goal of any requests from the User.\n\nWhen a goal is too complex or you lack the requisite abilities for you to accomplish it on your own, break the goal down into one or more smaller tasks and assign each task to an Operator.\n\nIn addition to requests from the User, Operators may also send you messages or requests. Unlike requests from the User, you may choose whether and how to respond to messages and requests from Operators.\n\nEvery response must conclude with an tag.\n\n## Commands\n\nManage the collective of Operators using the Operator API. Send commands to the API as a JSON object wrapped in tags. Messages from operators will be given to you wrapped in tags.\n\n## Operator API Docs\n\n### Create an Operator\n\n\\`\\`\\`\n\n{\n \"method\": \"POST\",\n \"path\": \"/operators\",\n \"body\": {\n \"id\": \"06f86c9a-1fe6-4c74-8939-30e64cb1edbb\",\n \"name\": \"My First Operator\"\n }\n}\n\n\\`\\`\\`\n\n### Message an Operator\n\n\\`\\`\\`\n\n{\n \"method\": \"POST\",\n \"path\": \"/operators/06f86c9a-1fe6-4c74-8939-30e64cb1edbb/messages\",\n \"body\": {\n \"content\": \"Sign up for an account at the following website: https://www.example.com\"\n }\n}\n\n\\`\\`\\`\n\n### Delete an Operator\n\n\\`\\`\\`\n\n{\n \"method\": \"DELETE\",\n \"path\": \"/operators/06f86c9a-1fe6-4c74-8939-30e64cb1edbb\",\n \"body\": {}\n}\n\n\\`\\`\\`\n\n\n`;\n\nreturn msg;\n", + "z": "4d258c7de41d3e07", + "name": "Vector Search Params", + "func": "msg.vectorSearchParams = {\n top: 4\n};\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 140, - "y": 400, + "x": 740, + "y": 280, "wires": [ [ - "0a34e1dce381f16b" + "083cd95ebe479e4c" ] ] }, { - "id": "4de07154c6644063", - "type": "subflow:f19bc65164444615", - "z": "ec55121054ad7072", - "name": "Operator Histories", + "id": "1a8be604e1fb0f60", + "type": "subflow:a59054999730c251", + "z": "4d258c7de41d3e07", + "g": "a6665159eabf55ba", + "name": "Model - genai - llama-cpp-mistral-8x", "env": [ { - "name": "Factory Id", - "value": "operators", + "name": "Id", + "value": "genai-llama-cpp-mistral-8x", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", "type": "str" } ], - "x": 890, - "y": 600, + "x": 340, + "y": 620, "wires": [ [ - "94206e52b6f654bd", - "941ab8d26359e8b3" + "0bdfb9335b655b7b" ] ] }, { - "id": "3f33490320859b09", - "type": "switch", - "z": "ec55121054ad7072", - "name": "Response tag", - "property": "tag", - "propertyType": "msg", - "rules": [ + "id": "1648a58fa167dcbd", + "type": "subflow:9eb27f011bcf9a83", + "z": "4d258c7de41d3e07", + "g": "132bac76be391419", + "name": "Embeddings - genai - llama-cpp-mistral-8x", + "env": [ { - "t": "eq", - "v": "operator-api", - "vt": "str" + "name": "Id", + "value": "genai-llama-cpp-mistral-8x-embeddings", + "type": "str" + }, + { + "name": "BaseUrl", + "value": "http://d2u7t6ixyjqeq5.cloudfront.net/genai-llama-cpp-mistral-8x", + "type": "str" } ], - "checkall": "true", - "repair": false, - "outputs": 1, - "x": 880, - "y": 240, + "x": 1560, + "y": 540, "wires": [ [ - "1ec42373eea9f5ff" + "4d5a8d1e8ff6d660" ] ] }, { - "id": "1ec42373eea9f5ff", - "type": "function", - "z": "ec55121054ad7072", - "name": "Parse operator API", - "func": "let apiMsg;\ntry {\n apiMsg = JSON.parse(msg.content);\n}\ncatch (e) {\n throw new Error(`Error parsing operator AI call: ${msg.content} - ${e}`);\n}\n\nreturn {\n ...msg,\n ...apiMsg\n};\n", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 890, - "y": 340, + "id": "0dd8b704b63c96a1", + "type": "inject", + "z": "f6f2187d.f17ca8", + "g": "f1bf7ba3b4088527", + "name": "Authorize", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": true, + "onceDelay": 0.1, + "topic": "", + "payload": "{ \"password\": \"\", \"username\": \"admin\" }", + "payloadType": "json", + "x": 160, + "y": 120, "wires": [ [ - "17e432a11037e949" + "bd7eb8ec2a8e0da9" ] ] }, { - "id": "17e432a11037e949", - "type": "switch", - "z": "ec55121054ad7072", - "name": "Operator API - Path", - "property": "path", - "propertyType": "msg", + "id": "3b853d53f8b1fb4d", + "type": "change", + "z": "f6f2187d.f17ca8", + "g": "f1bf7ba3b4088527", + "name": "SaveToken", "rules": [ { - "t": "regex", - "v": "^/operators(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})?$", - "vt": "str", - "case": true - }, + "t": "set", + "p": "portainer_jwt", + "pt": "flow", + "to": "payload", + "tot": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 770, + "y": 120, + "wires": [ + [] + ] + }, + { + "id": "46b306f2e48bb850", + "type": "http request", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "", + "method": "GET", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "41aad7d8f71cd6e6", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [ { - "t": "regex", - "v": "^/operators/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/messages$", - "vt": "str", - "case": true + "keyType": "other", + "keyValue": "X-API-Key", + "valueType": "msg", + "valueValue": "token" } ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 890, - "y": 440, + "x": 570, + "y": 280, "wires": [ [ - "1e437fb36b5c0ea1" - ], - [ - "da042c7a27dcbd9f" + "7887225ee569137c" ] - ], - "outputLabels": [ - "Operators", - "Operators/Messages" ] }, { - "id": "1e437fb36b5c0ea1", - "type": "switch", - "z": "ec55121054ad7072", - "name": "Operators Method", - "property": "method", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "POST", - "vt": "str" - }, - { - "t": "eq", - "v": "DELETE", - "vt": "str" - } - ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 1110, - "y": 420, + "id": "733507b741691f58", + "type": "inject", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Fetch", + "props": [], + "repeat": "", + "crontab": "", + "once": true, + "onceDelay": "0.5", + "topic": "", + "x": 150, + "y": 280, "wires": [ [ - "2c04b0bb076a5230" - ], - [] + "6fc0878730035324", + "4534e2dfa3d348df" + ] ] }, { - "id": "2c04b0bb076a5230", + "id": "7887225ee569137c", "type": "function", - "z": "ec55121054ad7072", - "name": "Create operator", - "func": "msg = {\n action: \"prog-history-init\",\n historyId: msg.body?.id\n};\n\nreturn msg;\n", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Save Endpoints", + "func": "var instances = [];\nmsg.payload.forEach(function(endpoint) {\n var obj = {};\n obj[endpoint.Name] = endpoint.Id;\n instances.push(obj)\n});\nflow.set('portainer_endpoints', instances);\nmsg.payload = instances[0];\nmsg.options = instances;\nreturn msg;", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1380, - "y": 360, + "x": 780, + "y": 280, "wires": [ - [ - "40557c67b6ce1c09", - "1554a43a221611d6" - ] + [] ] }, { - "id": "da042c7a27dcbd9f", - "type": "switch", - "z": "ec55121054ad7072", - "name": "Operators/Messages Method", - "property": "method", - "propertyType": "msg", - "rules": [ + "id": "9f7f53505a88dbb1", + "type": "http request", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "", + "method": "GET", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "41aad7d8f71cd6e6", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [ { - "t": "eq", - "v": "POST", - "vt": "str" + "keyType": "other", + "keyValue": "X-API-Key", + "valueType": "msg", + "valueValue": "token" } ], - "checkall": "true", - "repair": false, - "outputs": 1, - "x": 1140, - "y": 460, + "x": 570, + "y": 340, "wires": [ [ - "2d1212f366ac2dec" + "374c4ab5a3ae97c7" ] ] }, { - "id": "a2eae6bb6671163b", + "id": "fdb9b09540cd5ba6", "type": "function", - "z": "ec55121054ad7072", - "name": "Add Admin Message", - "func": "msg = {\n action: \"prog-history-add-entry\",\n entry: {\n role: \"user\",\n content: msg.createAdminMessagePrompt(msg.body?.content)\n },\n id: msg.path.split('/')[2]\n};\n\nreturn msg;\n", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Endpoint", + "func": "\nmsg.url = flow.get('server_url')+'/api/endpoints/'+msg.payload+'/docker/containers/json?all=true';\nmsg.token = flow.get('portainer_jwt');\nreturn msg;", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1400, - "y": 540, + "x": 390, + "y": 340, "wires": [ [ - "4de07154c6644063", - "dd64967ec7cb7b3d" + "9f7f53505a88dbb1" ] ] }, { - "id": "2d1212f366ac2dec", + "id": "374c4ab5a3ae97c7", "type": "function", - "z": "ec55121054ad7072", - "name": "Admin message prompt template", - "func": "msg.createAdminMessagePrompt = message => {\n return `${message}`;\n};\n\nreturn msg;\n", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Options", + "func": "msg.options = msg.payload.map((item)=>{\n let obj = {};\n obj[item.Names[0]] = item.Id;\n return obj;\n})\nreturn msg;", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1440, - "y": 500, + "x": 770, + "y": 340, + "wires": [ + [] + ] + }, + { + "id": "75a002efe0c1f011", + "type": "change", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Save Container", + "rules": [ + { + "t": "set", + "p": "portainer_container", + "pt": "flow", + "to": "payload", + "tot": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1240, + "y": 340, "wires": [ [ - "a2eae6bb6671163b" + "df970663c1614b1d" ] ] }, { - "id": "ef526c2a80f31eb3", + "id": "84cb3dac9b9f5d39", "type": "function", - "z": "ec55121054ad7072", - "name": "Operator Prompt", - "func": "msg.systemPrompt = `## Mandate\n\nYou are an AI Operator.\n\nYour mandate is to perform any tasks requested of you by your AI Administrator to the best of your ability in order to accomplish the overarching goal of the User.\n\nWhen a task is too complex or you lack the requisite abilities for you to accomplish it on your own, you may ask the Administrator to break the task down into one or more smaller tasks and assign them to Operators.\n\nThis conversation is a complete record of every action you took in performing the task.\n\nEnd all responses with an tag.\n\n## Commands\n\nYou may message the Administrator by wrapping your message in tags. Messages from the Administrator will be given to you wrapped in tags.\n`;\n\nreturn msg;\n", - "outputs": 1, - "timeout": 0, + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Url", + "func": "let endpoint = flow.get('portainer_endpoint');\nlet container = flow.get('portainer_container');\nlet startOrStop = msg.payload ? 'start' : 'stop';\nif(!endpoint || !container){\n return [null, { payload: \"Either endpoint or container not selected\", status: !msg.payload}]\n}else{\n msg.url = flow.get('server_url') +'/api/endpoints/' + endpoint + '/docker/containers/'+container+'/'+startOrStop;\n msg.token = flow.get('portainer_jwt');\n return [msg,null]\n}", + "outputs": 2, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 130, + "x": 750, "y": 480, "wires": [ [ - "0a34e1dce381f16b" - ] + "b56089ef7ebdddf2" + ], + [] ] }, { - "id": "87b70bd29575e8b4", + "id": "909a59dbc05a2fad", + "type": "change", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Save Container", + "rules": [ + { + "t": "set", + "p": "portainer_endpoint", + "pt": "flow", + "to": "payload", + "tot": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1240, + "y": 280, + "wires": [ + [] + ] + }, + { + "id": "14dab9180b245706", "type": "function", - "z": "ec55121054ad7072", - "name": " ", - "func": "\nreturn msg;", + "z": "f6f2187d.f17ca8", + "g": "d3ea6600f7f1c7d6", + "name": "Reset", + "func": "flow.set('portainer_endpoint', null);\nflow.set('portainer_container',null);\nreturn msg;", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 265, - "y": 920, + "x": 1090, + "y": 120, + "wires": [ + [] + ] + }, + { + "id": "1ed0f9b52a08f533", + "type": "link in", + "z": "f6f2187d.f17ca8", + "g": "d3ea6600f7f1c7d6", + "name": "Reset Link", + "links": [ + "6fc0878730035324" + ], + "x": 955, + "y": 120, "wires": [ [ - "ef526c2a80f31eb3" + "14dab9180b245706" ] + ] + }, + { + "id": "6fc0878730035324", + "type": "link out", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Fetch Link", + "mode": "link", + "links": [ + "0c165bf98f40b598", + "1ed0f9b52a08f533" ], - "icon": "font-awesome/fa-arrows", - "l": false + "x": 265, + "y": 320, + "wires": [] }, { - "id": "40557c67b6ce1c09", + "id": "b56089ef7ebdddf2", + "type": "http request", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "", + "method": "POST", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "41aad7d8f71cd6e6", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [ + { + "keyType": "other", + "keyValue": "X-API-Key", + "valueType": "msg", + "valueValue": "token" + } + ], + "x": 970, + "y": 480, + "wires": [ + [] + ] + }, + { + "id": "60e45a11ede888cb", "type": "function", - "z": "ec55121054ad7072", - "name": " ", - "func": "\nreturn msg;", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Button", + "func": "msg.enabled = !!flow.get('portainer_container');\nreturn msg;", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1695, - "y": 540, + "x": 390, + "y": 480, "wires": [ - [ - "4de07154c6644063" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + [] + ] }, { - "id": "a073258f226718b6", - "type": "switch", - "z": "ec55121054ad7072", - "name": "Response tag", - "property": "tag", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "operator-message", - "vt": "str" - } + "id": "df970663c1614b1d", + "type": "link out", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Button", + "mode": "link", + "links": [ + "49c1d79c39f3c0a4" + ], + "x": 1385, + "y": 340, + "wires": [] + }, + { + "id": "0c165bf98f40b598", + "type": "link in", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Button Status", + "links": [ + "35aa7e2f151f726c", + "6fc0878730035324" ], - "checkall": "true", - "repair": false, - "outputs": 1, - "x": 880, - "y": 760, + "x": 95, + "y": 480, "wires": [ [ - "2d730859f47f1ceb" + "60e45a11ede888cb" ] ] }, { - "id": "94206e52b6f654bd", + "id": "a86d84649831b0fc", "type": "function", - "z": "ec55121054ad7072", - "name": " ", - "func": "\nreturn msg;", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Url", + "func": "let endpoint = flow.get('portainer_endpoint');\nlet container = flow.get('portainer_container');\nif (!!endpoint && !!container){\n msg.url = flow.get('server_url') +'/api/endpoints/' + endpoint + '/docker/containers/'+container+'/json';\n msg.token = flow.get('portainer_jwt');\n return msg\n}\nelse\n return null;\n", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 715, - "y": 680, + "x": 370, + "y": 400, "wires": [ [ - "87b70bd29575e8b4" + "0b6e18ac2c03166b" ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + ] }, { - "id": "8ad28cb311d8a5c0", - "type": "subflow:240cc03734c17fa7", - "z": "ec55121054ad7072", - "name": "Parse Admin Response", - "x": 900, - "y": 160, + "id": "49c1d79c39f3c0a4", + "type": "link in", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Container Selected", + "links": [ + "df970663c1614b1d" + ], + "x": 95, + "y": 400, "wires": [ [ - "3f33490320859b09" + "a86d84649831b0fc" ] ] }, { - "id": "941ab8d26359e8b3", - "type": "subflow:240cc03734c17fa7", - "z": "ec55121054ad7072", - "name": "Parse Operator Response", - "x": 910, - "y": 680, + "id": "0b6e18ac2c03166b", + "type": "http request", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "", + "method": "GET", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "41aad7d8f71cd6e6", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [ + { + "keyType": "other", + "keyValue": "X-API-Key", + "valueType": "msg", + "valueValue": "token" + } + ], + "x": 570, + "y": 400, "wires": [ [ - "a073258f226718b6" + "e6f08d657cfa77a9" ] ] }, { - "id": "2d730859f47f1ceb", + "id": "e6f08d657cfa77a9", "type": "function", - "z": "ec55121054ad7072", - "name": "Operator message prompt template", - "func": "msg.createOperatorMessagePrompt = (id, message) => {\n return `${message}`;\n};\n\nreturn msg;\n", - "outputs": 1, - "timeout": 0, + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Get Status", + "func": "//msg.payload = msg.payload.State.Running;\nreturn [\n { payload: msg.payload.State.Running},\n { payload: msg.payload.State.Status},\n { payload: msg.payload.State.Health.Status },\n { payload: msg.payload.State.StartedAt}\n];", + "outputs": 4, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1420, - "y": 700, + "x": 770, + "y": 400, "wires": [ [ - "134cfbd5d2b56837" - ] + "35aa7e2f151f726c" + ], + [], + [], + [] ] }, { - "id": "134cfbd5d2b56837", - "type": "function", - "z": "ec55121054ad7072", - "name": "Add Operator Message", - "func": "msg = {\n action: \"history-add-entry\",\n entry: {\n role: \"user\",\n content: msg.createOperatorMessagePrompt(msg.agentId, msg.content)\n }\n};\n\nreturn msg;\n", + "id": "72d2e05a0acd3fa8", + "type": "delay", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "", + "pauseType": "delay", + "timeout": "0.1", + "timeoutUnits": "seconds", + "rate": "1", + "nbRateUnits": "1", + "rateUnits": "second", + "randomFirst": "1", + "randomLast": "5", + "randomUnits": "seconds", + "drop": false, + "allowrate": false, "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1390, - "y": 740, + "x": 570, + "y": 540, + "wires": [ + [] + ] + }, + { + "id": "35aa7e2f151f726c", + "type": "link out", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Button", + "mode": "link", + "links": [ + "0c165bf98f40b598" + ], + "x": 915, + "y": 380, + "wires": [] + }, + { + "id": "f1c8fbcb6c326e46", + "type": "inject", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Update Status", + "props": [], + "repeat": "5", + "crontab": "", + "once": true, + "onceDelay": "0.5", + "topic": "", + "x": 180, + "y": 360, "wires": [ [ - "13c990f21a453c5a", - "e7f4585c8ca44732" + "a86d84649831b0fc", + "bfb495bb4ca9ae6f" ] ] }, { - "id": "d2c9ca4a42af3ba9", + "id": "bfb495bb4ca9ae6f", "type": "function", - "z": "ec55121054ad7072", - "name": " ", - "func": "\nreturn msg;", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set Url", + "func": "let endpoint = flow.get('portainer_endpoint');\nlet container = flow.get('portainer_container');\nif (!!endpoint && !!container){\n msg.url = flow.get('server_url') +'/api/endpoints/' + endpoint + '/docker/containers/' + container +'/stats?stream=false&one-shot=false';\n msg.token = flow.get('portainer_jwt');\n return msg\n}\nelse\n return null;\n", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 725, - "y": 400, + "x": 370, + "y": 580, "wires": [ [ - "e77e6ed92b6eba12" + "6026847cd96ce18c" ] + ] + }, + { + "id": "6026847cd96ce18c", + "type": "http request", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "", + "method": "GET", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "41aad7d8f71cd6e6", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [ + { + "keyType": "other", + "keyValue": "X-API-Key", + "valueType": "msg", + "valueValue": "token" + } ], - "icon": "font-awesome/fa-arrows", - "l": false + "x": 590, + "y": 580, + "wires": [ + [ + "12ca61074a76e5dd", + "d8c78c08e407231e" + ] + ] }, { - "id": "13c990f21a453c5a", + "id": "12ca61074a76e5dd", "type": "function", - "z": "ec55121054ad7072", - "name": " ", - "func": "\nreturn msg;", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "CPU Usage", + "func": "var stats = msg.payload;\nif(!!stats){\n var cpu_delta = stats.cpu_stats.cpu_usage.total_usage - stats.precpu_stats.cpu_usage.total_usage;\n var system_cpu_delta = stats.cpu_stats.system_cpu_usage - stats.precpu_stats.system_cpu_usage;\n var number_cpus = stats.cpu_stats.online_cpus;\n // msg.payload = { data: [stats, cpu_delta, system_cpu_delta, number_cpus]}\n msg.payload = Number((cpu_delta === 0? 0 : (cpu_delta / system_cpu_delta) * number_cpus * 100.0).toFixed(2));\n return msg;\n}\nelse\n return null", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1615, - "y": 740, + "x": 770, + "y": 580, "wires": [ - [ - "d2c9ca4a42af3ba9" - ] - ], - "icon": "font-awesome/fa-arrows", - "l": false + [] + ] }, { - "id": "d7625ef95dd891b8", + "id": "d8c78c08e407231e", "type": "function", - "z": "ec55121054ad7072", - "name": "Init Operator Histories", - "func": "\nreturn {\n action: \"prog-factory-init\"\n};\n", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Memory Usage", + "func": "var stats = msg.payload;\nif(!!stats){\n if (!!stats.memory_stats.stats.cache)\n var used_memory = stats.memory_stats.usage - stats.memory_stats.stats.cache;\n else\n var used_memory = stats.memory_stats.usage - stats.memory_stats.stats.inactive_file\n var available_memory =stats.memory_stats.limit\n // msg.payload = { data: [stats, used_memory, available_memory]}\n msg.payload = Number(((used_memory / available_memory) * 100.000).toFixed(2));\n return msg;\n}\nelse\nreturn null", "outputs": 1, - "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 420, - "y": 100, + "x": 780, + "y": 640, "wires": [ [ - "b6cc1b3167117b16" + "d75002a1564c11aa" ] ] }, { - "id": "1554a43a221611d6", + "id": "d75002a1564c11aa", "type": "debug", - "z": "ec55121054ad7072", - "name": "Creating Operator", - "active": true, + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "debug 1", + "active": false, "tosidebar": true, "console": false, "tostatus": false, @@ -10133,42 +15995,75 @@ "targetType": "full", "statusVal": "", "statusType": "auto", - "x": 1650, - "y": 320, + "x": 960, + "y": 700, "wires": [] }, { - "id": "dd64967ec7cb7b3d", - "type": "debug", - "z": "ec55121054ad7072", - "name": "Sending Admin Message", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 1670, - "y": 600, - "wires": [] + "id": "bd7eb8ec2a8e0da9", + "type": "function", + "z": "f6f2187d.f17ca8", + "g": "f1bf7ba3b4088527", + "name": "Configuration", + "func": "msg.payload = \"ptr_3Wql5OXTh3bhXGW18Bzrk8SjVcr2xmBFXmpciFzR7zI=\"\nmsg.serverUrl = \"https://192.168.0.103:9443\"\nreturn msg;", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 390, + "y": 120, + "wires": [ + [ + "3b853d53f8b1fb4d", + "d3e4f8597b868498" + ] + ] }, { - "id": "e7f4585c8ca44732", - "type": "debug", - "z": "ec55121054ad7072", - "name": "Sending Operator Message", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 1680, - "y": 800, - "wires": [] + "id": "d3e4f8597b868498", + "type": "change", + "z": "f6f2187d.f17ca8", + "g": "f1bf7ba3b4088527", + "name": "Save URL", + "rules": [ + { + "t": "set", + "p": "server_url", + "pt": "flow", + "to": "serverUrl", + "tot": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 770, + "y": 160, + "wires": [ + [] + ] + }, + { + "id": "4534e2dfa3d348df", + "type": "function", + "z": "f6f2187d.f17ca8", + "g": "856e8d2dc2416b46", + "name": "Set URL", + "func": "msg.url = flow.get('server_url') + '/api/endpoints'\nmsg.token = flow.get('portainer_jwt');\nreturn msg;", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 380, + "y": 280, + "wires": [ + [ + "46b306f2e48bb850" + ] + ] } ] \ No newline at end of file diff --git a/packages/node-red-data/flows_cred.json b/packages/node-red-data/flows_cred.json index a6b6e47..5cf3a94 100644 --- a/packages/node-red-data/flows_cred.json +++ b/packages/node-red-data/flows_cred.json @@ -1,3 +1,3 @@ { - "$": "49c64eb96adb81080dbf3c94bc1777b9KNttumDFW7FaPVlT0o8WiY+Bjgp3hR9aduqZ+bepP5dgwbFfE5IdmscI+ZoMuwourqJnK3rtEoeOEzXGLUHHEGOWGRBNOEdNCuxROWCdPsN8W3KQ+sGJ6uAAN5eNtwc=" + "$": "a1536422ef621fdc688fbb13518047a1dJ6ykBIUAG1csJgtM+ZgQkbkNUvekEclmNTwkKvmCkfusvtNQ1G8rHTHpjmNQgDd3DqLm5cJPeKCSa0aaaE4Sb0uifOLf7NSb2yp60Zt9AUecgrSl0osOzS4cpTuq7sCP1nIkdnoMzpm8/kiULniDHQxAIVeSS+L5WWUI3U2tG8sFR9ReRoBYuJFBv2a6JnZl9sJjyFbl+4Bp5Wq2kkcYT6cSct1hIXOoxcYljfCf8PlmzZ1Tj4vPR4eC7kxGy0ZmqBTozeNBrcYPhucEw==" } \ No newline at end of file diff --git a/packages/node-red-data/package-lock.json b/packages/node-red-data/package-lock.json index b5b5cfe..b6a1b02 100644 --- a/packages/node-red-data/package-lock.json +++ b/packages/node-red-data/package-lock.json @@ -13,20 +13,25 @@ "@langchain/openai": "^0.0.13", "acorn": "^8.11.3", "async": "^3.2.5", + "change-case": "^5.4.4", "classnames": "^2.5.1", "color-name": "^2.0.0", + "colors": "^1.4.0", "date-fns": "^3.3.0", "dompurify": "^3.0.8", + "html-entities": "^2.5.2", + "is-sorted": "^1.0.5", "jsdom": "^24.0.0", + "jssoup": "^0.0.15", "langchain": "^0.1.12", "mammoth": "^1.6.0", "marked": "^9.1.6", "node-fetch": "^3.3.2", - "node-red-contrib-jsonpath": "~0.1.1", - "node-red-contrib-llm-nodes": "file:nodes/node-red-contrib-llm-nodes-0.2.11.tgz", + "node-red-contrib-llm-nodes": "file:nodes/node-red-contrib-llm-nodes-0.2.12.tgz", "pkginfo": "^0.3.1", "sse.js": "^2.2.0", - "timestore": "^1.2.0" + "timestore": "^1.2.0", + "yargs": "^17.7.2" } }, "node_modules/@alwatr/dedupe": { @@ -728,6 +733,14 @@ "node": ">= 8.0.0" } }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -917,6 +930,11 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==" + }, "node_modules/charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", @@ -930,6 +948,19 @@ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -954,6 +985,14 @@ "node": ">=12.20" } }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1219,6 +1258,11 @@ "node": ">=0.10.0" } }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -1387,6 +1431,14 @@ "node": ">= 0.4" } }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1728,6 +1780,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -1847,6 +1907,29 @@ "node": ">=18" } }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/htmlparser": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/htmlparser/-/htmlparser-1.7.7.tgz", + "integrity": "sha512-zpK66ifkT0fauyFh2Mulrq4AqGTucxGtOhZ8OjkbSfcCpkqQEI8qRkY0tSQSJNAQ4HUZkgWaU4fK4EH6SVH9PQ==", + "engines": { + "node": ">=0.1.33" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -1991,6 +2074,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2015,6 +2106,11 @@ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" }, + "node_modules/is-sorted": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-sorted/-/is-sorted-1.0.5.tgz", + "integrity": "sha512-KZJvKDrI+Kg3ixeDaZQIt7RIwcGnm07+NSipyj1r9MtjDrLG678ETy4yO6dBJLUjejPdge9fLCGxsWkQO/3PJg==" + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2122,11 +2218,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/JSONPath": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/JSONPath/-/JSONPath-0.11.2.tgz", - "integrity": "sha512-rb/B7XKD/stAMqhao/DKEveRkFkYNOr8S/YjTjfisIrYvzcFdnQl0nlg32AHAws++Avv7AdiDHRyP9yZM6Lscw==" - }, "node_modules/jsonpointer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", @@ -2135,6 +2226,14 @@ "node": ">=0.10.0" } }, + "node_modules/jssoup": { + "version": "0.0.15", + "resolved": "https://registry.npmjs.org/jssoup/-/jssoup-0.0.15.tgz", + "integrity": "sha512-9/7qzZQ878Jey0JyNTuy1NYE8Y4G5PbpWQ5hS8vlBD2Ar4MKJNMQ0239yjb+WExRNLiYPSgZSVLyFUwQNWa1ag==", + "dependencies": { + "htmlparser": "^1.7.7" + } + }, "node_modules/jszip": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", @@ -2675,18 +2774,10 @@ "url": "https://opencollective.com/node-fetch" } }, - "node_modules/node-red-contrib-jsonpath": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/node-red-contrib-jsonpath/-/node-red-contrib-jsonpath-0.1.1.tgz", - "integrity": "sha512-0E3Q3Ixd/LuzfbCrv779l1UMaGjCMHxQqnNjxFAjDxcbuDsz1oU84UW8J4bS1bPLhkzud9IB0WIZk6/+PSsGcw==", - "dependencies": { - "JSONPath": ">=0.10.0" - } - }, "node_modules/node-red-contrib-llm-nodes": { - "version": "0.2.11", - "resolved": "file:nodes/node-red-contrib-llm-nodes-0.2.11.tgz", - "integrity": "sha512-3uXEeEzHZEANM54on88ZuIsAdmYDUzhLoGjsc1E6FRrHw6PwLf0suVI6pyMaQ00ec2Jx9sZ7tq4pC/u157MILA==", + "version": "0.2.12", + "resolved": "file:nodes/node-red-contrib-llm-nodes-0.2.12.tgz", + "integrity": "sha512-/v+q0twoRK/d2nr03A2RXqEjKzV6ZX4qZOgXKfOy9At6dg4tjrbJUbJB+Pi+5Wed73+2ZKeRMIf5B4tK5ZyRYg==", "license": "MIT", "dependencies": { "@totallyinformation/ti-common-event-handler": "^1.0.0", @@ -3273,6 +3364,14 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -3719,6 +3818,30 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -3963,6 +4086,22 @@ "node": ">= 8" } }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/ws": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", @@ -4012,6 +4151,14 @@ "node": ">=0.4.0" } }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, "node_modules/yaml": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", @@ -4020,6 +4167,31 @@ "node": ">= 14" } }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, "node_modules/zod": { "version": "3.22.4", "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", @@ -4341,6 +4513,11 @@ "humanize-ms": "^1.2.1" } }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -4476,6 +4653,11 @@ "supports-color": "^7.1.0" } }, + "change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==" + }, "charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", @@ -4486,6 +4668,16 @@ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4506,6 +4698,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.0.tgz", "integrity": "sha512-SbtvAMWvASO5TE2QP07jHBMXKafgdZz8Vrsrn96fiL+O92/FN/PLARzUW5sKt013fjAprK2d2iCn2hk2Xb5oow==" }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -4699,6 +4896,11 @@ "jake": "^10.8.5" } }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -4803,6 +5005,11 @@ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" }, + "escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==" + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -5059,6 +5266,11 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, "get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -5136,6 +5348,16 @@ "whatwg-encoding": "^3.1.1" } }, + "html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==" + }, + "htmlparser": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/htmlparser/-/htmlparser-1.7.7.tgz", + "integrity": "sha512-zpK66ifkT0fauyFh2Mulrq4AqGTucxGtOhZ8OjkbSfcCpkqQEI8qRkY0tSQSJNAQ4HUZkgWaU4fK4EH6SVH9PQ==" + }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -5247,6 +5469,11 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -5265,6 +5492,11 @@ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" }, + "is-sorted": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-sorted/-/is-sorted-1.0.5.tgz", + "integrity": "sha512-KZJvKDrI+Kg3ixeDaZQIt7RIwcGnm07+NSipyj1r9MtjDrLG678ETy4yO6dBJLUjejPdge9fLCGxsWkQO/3PJg==" + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -5344,16 +5576,19 @@ "universalify": "^2.0.0" } }, - "JSONPath": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/JSONPath/-/JSONPath-0.11.2.tgz", - "integrity": "sha512-rb/B7XKD/stAMqhao/DKEveRkFkYNOr8S/YjTjfisIrYvzcFdnQl0nlg32AHAws++Avv7AdiDHRyP9yZM6Lscw==" - }, "jsonpointer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==" }, + "jssoup": { + "version": "0.0.15", + "resolved": "https://registry.npmjs.org/jssoup/-/jssoup-0.0.15.tgz", + "integrity": "sha512-9/7qzZQ878Jey0JyNTuy1NYE8Y4G5PbpWQ5hS8vlBD2Ar4MKJNMQ0239yjb+WExRNLiYPSgZSVLyFUwQNWa1ag==", + "requires": { + "htmlparser": "^1.7.7" + } + }, "jszip": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", @@ -5602,17 +5837,9 @@ "formdata-polyfill": "^4.0.10" } }, - "node-red-contrib-jsonpath": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/node-red-contrib-jsonpath/-/node-red-contrib-jsonpath-0.1.1.tgz", - "integrity": "sha512-0E3Q3Ixd/LuzfbCrv779l1UMaGjCMHxQqnNjxFAjDxcbuDsz1oU84UW8J4bS1bPLhkzud9IB0WIZk6/+PSsGcw==", - "requires": { - "JSONPath": ">=0.10.0" - } - }, "node-red-contrib-llm-nodes": { - "version": "file:nodes/node-red-contrib-llm-nodes-0.2.11.tgz", - "integrity": "sha512-3uXEeEzHZEANM54on88ZuIsAdmYDUzhLoGjsc1E6FRrHw6PwLf0suVI6pyMaQ00ec2Jx9sZ7tq4pC/u157MILA==", + "version": "file:nodes/node-red-contrib-llm-nodes-0.2.12.tgz", + "integrity": "sha512-/v+q0twoRK/d2nr03A2RXqEjKzV6ZX4qZOgXKfOy9At6dg4tjrbJUbJB+Pi+5Wed73+2ZKeRMIf5B4tK5ZyRYg==", "requires": { "@totallyinformation/ti-common-event-handler": "^1.0.0", "degit": "^2.8.4", @@ -6040,6 +6267,11 @@ } } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -6368,6 +6600,24 @@ } } }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -6546,6 +6796,16 @@ "isexe": "^2.0.0" } }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "ws": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", @@ -6572,11 +6832,35 @@ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, "yaml": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==" }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + }, "zod": { "version": "3.22.4", "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", diff --git a/packages/node-red-data/package.json b/packages/node-red-data/package.json index 926c9db..8f29e0c 100644 --- a/packages/node-red-data/package.json +++ b/packages/node-red-data/package.json @@ -9,19 +9,24 @@ "@langchain/openai": "^0.0.13", "acorn": "^8.11.3", "async": "^3.2.5", + "change-case": "^5.4.4", "classnames": "^2.5.1", "color-name": "^2.0.0", + "colors": "^1.4.0", "date-fns": "^3.3.0", "dompurify": "^3.0.8", + "html-entities": "^2.5.2", + "is-sorted": "^1.0.5", "jsdom": "^24.0.0", + "jssoup": "^0.0.15", "langchain": "^0.1.12", "mammoth": "^1.6.0", "marked": "^9.1.6", "node-fetch": "^3.3.2", - "node-red-contrib-jsonpath": "~0.1.1", - "node-red-contrib-llm-nodes": "file:nodes/node-red-contrib-llm-nodes-0.2.11.tgz", + "node-red-contrib-llm-nodes": "file:nodes/node-red-contrib-llm-nodes-0.2.12.tgz", "pkginfo": "^0.3.1", "sse.js": "^2.2.0", - "timestore": "^1.2.0" + "timestore": "^1.2.0", + "yargs": "^17.7.2" } -} \ No newline at end of file +} diff --git a/packages/node-red-data/ui-builder/bash-executor-view/.eslintrc.js b/packages/node-red-data/ui-builder/bash-executor-view/.eslintrc.js new file mode 100644 index 0000000..7ed4de2 --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor-view/.eslintrc.js @@ -0,0 +1,80 @@ +/** JavaScript Versions + * 5 is minimum -> Last IE11 + * 6 = 2015 -> Node >8.10, iOS12+ + * 7 = 2016 -> FF78+, + * 8 = 2017 -> Node 10.9+ + * 9 = 2018 -> Node 12.11+ + * 10 = 2019 + * 11 = 2020 + * 12 = 2021 + */ +module.exports = { // eslint-disable-line no-undef + env: { + browser: true, + node: false, + 'shared-node-browser': false, + }, + parserOptions: { + ecmaVersion: 2015, + sourceType: 'script', + }, + root: true, + globals: { + uibuilder: true, + $: true, + }, + overrides: [ + { + files: ['*.esm.js', '*.module.js', '*.mod.js', '*.mjs'], + parserOptions: { sourceType: 'module' }, + } + ], + plugins: [ + 'html', // Check scripts in HTML. https://www.npmjs.com/package/eslint-plugin-html + 'es', // Help avoid js that is too new. https://eslint-plugin-es.mysticatea.dev/ + 'jsdoc', // JSDoc. https://www.npmjs.com/package/eslint-plugin-jsdoc + 'promise', // Better promises. https://www.npmjs.com/package/eslint-plugin-promise + 'sonarjs', // Detect bugs and suspicious patterns. https://github.com/SonarSource/eslint-plugin-sonarjs + ], + extends: [ + 'standard', + // 'eslint:recommended', + 'plugin:es/restrict-to-es2015', + 'plugin:jsdoc/recommended', + 'plugin:promise/recommended', + 'plugin:sonarjs/recommended', + ], + rules: { + // TODO remove once min engines moves to node.js v15+ + 'es/no-logical-assignment-operators': 'error', + 'es/no-promise-any': 'error', + 'es/no-numeric-separators': 'error', + + 'sonarjs/no-duplicate-string': ['warn', { 'threshold': 6 }], // Default is 3 + // 'sonarjs/cognitive-complexity': ['error', 15], // Default is 15 + 'sonarjs/no-nested-template-literals': 0, + + // Tidy up some jsdoc oddities + 'jsdoc/multiline-blocks': 0, + 'jsdoc/newline-after-description': 0, + 'jsdoc/no-multi-asterisks': 0, + 'jsdoc/tag-lines': 0, + 'jsdoc/valid-types': 0, // Rubbish, fails on common type configs + 'jsdoc/no-undefined-types': 0, // ['error'|'warn', {'definedTypes':['Promise']}], + + // Make Standard less annoying + 'brace-style': 'off', // You should only use one-true-brace style but sometimes we want to compress things a bit. + 'comma-dangle': 'off', // Lack of dangles wastes soo much time correcting lists + 'dot-notation': 'off', // Turn off to allow for tslint's brain-dead treatment of expando objects in JS + 'indent': ['error', 4, { 'SwitchCase': 1 }], // Standard wants 2, I like 4 + 'space-before-function-paren': 'off', // No, don't need space between fn and arg! + 'no-multi-spaces': 'off', // Readability is more important than size (reduce size using uglify) + 'object-shorthand': ['error', 'consistent'], + 'padded-blocks': 'off', // Sometimes you just need some space! See above. + 'space-in-parens': 'off', // Sometimes you just need some space! + 'spaced-comment': ['error', 'always', { + 'markers': ['html', '#region', '#endregion'] + }], + 'quote-props': 'off', // Sometimes it is necessary and then much nicer to be able to quote things that don't need it. + }, +} diff --git a/packages/node-red-data/ui-builder/bash-executor-view/LICENSE b/packages/node-red-data/ui-builder/bash-executor-view/LICENSE new file mode 100644 index 0000000..a16c46a --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor-view/LICENSE @@ -0,0 +1,178 @@ + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/packages/node-red-data/ui-builder/bash-executor-view/README.md b/packages/node-red-data/ui-builder/bash-executor-view/README.md new file mode 100644 index 0000000..642720c --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor-view/README.md @@ -0,0 +1,57 @@ +# uibuilder Template: Blank + +> NOTE: You can replace the contents of this README with text that describes your UI. + +This is about the simplest template you can get for uibuilder. Is is also (as of uibuilder v5+), the default template. + +It does not use any frameworks and has no other dependencies. + +It demonstrates that you can use uibuilder purely with HTML/JavaScript or even just HTML and still easily build a simple, dynamic, data-driven user interface with the help of Node-RED. + +All it does is start up uibuilder. + +From uibuilder v6.1.0+, it uses the IIFE client library. + +## Folders + +* `/` - The root folder contains this file. It can be used for other things **but** it will not be served up in the Node-RED web server. +* `/src/` - the default folder that serves files as web resources. However, this can be changed to a different folder if desired. +* `/dist/` - the default folder for serving files as web resources where a build step is used. In that case, the `/src` folder is the source used by the build tool and `/dist` is the destination for the build (the "distribution" folder). +* `/routes/` - This folder can contain `.js` files defining routing middleware for uibuilder's ExpressJS web server. +* `/api/` - This folder can contain `.js` files defining REST API's specific to this uibuilder instance. + +The above folders will all pre-exist for the built-in uibuilder templates. The folders can safely be removed if not needed but one folder must exist to serve the web resources from (this cannot be the root folder). + +The template only has files in the root and `src` folders. The `src` folder is the default used by uibuilder to serve up files to clients. + +One reserved item in the root folder however will be a `package.json` file. This will be used in the future to help with build/compile steps. You can still use it yourself, just bear in mind that a future version of uibuilder will make use it as well. If you need to have any development packages installed to build your UI, don't forget to tell `npm` to save them as development dependencies not normal dependencies. + +The `dist` folder should be used if you have a build step to convert your source code to something that browsers understand. So if you are using a build (compile) step to produce your production code, ensure that it is configured to use the `dist` folder as the output folder and that it creates at least an `index.html` file. + +You can switch between the `src` and `dist` (or other) folders using the matching setting in the Editor. See uibuilder's advanced settings tab. + +Also note that you can use **linked** folders and files in this folder structure. This can be handy if you want to maintain your code in a different folder somewhere or if your default build process needs to use sub-folders other than `src` and `dist`.(Though as of v6, you can specify any sub-folder to be served) + +## Files in this template + +* `package.json`: REQUIRED. Defines the basic structure, name, description of the project and defines any local development dependencies if any. Also works with `npm` allowing the installation of dev packages (such as build or linting tools). +* `README.md`: This file. Change this to describe your web app and provide documentation for it. +* `.eslintrc.js`: A pre-configured configuration for the ESLINT tool. Helps when writing front-end code. +* `LICENSE`: A copy of the Apache 2.0 license. Replace with a different license if needed. Always license your code. Apache 2.0 matches the licensing of uibuilder. +* `src/index.html`: REQUIRED. Contains your basic HTML and will be the file loaded and displayed in the browser when going to the uibuilder defined URL. +* `src/index.js`: Contains all of the logic for your UI. It must be linked to in the html file. Optional. +* `src/index.css`: Contains your custom CSS for styling. It must be linked to in the html file. Optional. + +Note that only the `package.json` and `index.html` files are actually _required_. uibuilder will not function as expected without them. + +It is possible to use the index.html file simply as a link to other files but it must be present. + +The other files are all optional. However, you will need to change the index.html file accordingly if you rename or remove them. + +## Multiple HTML pages + +uibuilder will happily serve up any number of web pages from a single instance. It will also make use of sub-folders. However, each folder should have an `index.html` file so that a URL that ends with the folder name will still work without error. + +Note that each html file is a separate page and requires its own JavaScript and uibuilder library reference. When moving between pages, remember that every page is stand-alone, a new environment. You can share one `index.js` file between multiple pages if you prefer but each page will run a separate instance. + +If multiple pages are connected to the same uibuilder instance, they will all get the same broadcast messages from Node-RED. So if you want to handle different messages on different pages, remember to filter them in your front-end JavaScript in `uibuilder.onChange('msg', ....)` function. Turn on the advanced flag for including a `msg._uib` property in output if you need to differentiate between pages and/or clients in Node-RED. diff --git a/packages/node-red-data/ui-builder/bash-executor-view/api/.keep b/packages/node-red-data/ui-builder/bash-executor-view/api/.keep new file mode 100644 index 0000000..e69de29 diff --git a/packages/node-red-data/ui-builder/bash-executor-view/dist/.keep b/packages/node-red-data/ui-builder/bash-executor-view/dist/.keep new file mode 100644 index 0000000..e69de29 diff --git a/packages/node-red-data/ui-builder/bash-executor-view/package.json b/packages/node-red-data/ui-builder/bash-executor-view/package.json new file mode 100644 index 0000000..869b149 --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor-view/package.json @@ -0,0 +1,26 @@ +{ + "name": "uib-blank", + "version": "6.1.0", + "private": true, + "description": "This is about the simplest template you can get for uibuilder.", + "browser": "./src/index.js", + "scripts": { + "build": "echo \"Error: no build process specified\" && exit 1" + }, + "keywords": ["uibuilder", "node-red", "node-red-contrib-uibuilder"], + "author": "Julian Knight (Totally Information)", + "license": "Apache-2.0", + "homepage": "https://github.com/TotallyInformation/node-red-contrib-uibuilder", + "bugs": "https://github.com/TotallyInformation/node-red-contrib-uibuilder/issues", + "repository": { + "type": "git", + "url": "https://github.com/TotallyInformation/node-red-contrib-uibuilder.git" + }, + "browserslist": [ + "> 0.5%", + "maintained versions", + "last 2 versions", + "not dead", + "not ie > 0" + ] +} diff --git a/packages/node-red-data/ui-builder/bash-executor-view/routes/.keep b/packages/node-red-data/ui-builder/bash-executor-view/routes/.keep new file mode 100644 index 0000000..e69de29 diff --git a/packages/node-red-data/ui-builder/bash-executor-view/src/index.css b/packages/node-red-data/ui-builder/bash-executor-view/src/index.css new file mode 100644 index 0000000..a2a47be --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor-view/src/index.css @@ -0,0 +1,7 @@ +/* Load defaults from `/node_modules/node-red-contrib-uibuilder/front-end/uib-brand.min.css` + * This version auto-adjusts for light/dark browser settings but might not be as complete. + */ +@import url("../uibuilder/uib-brand.min.css"); + +/* OR, load the defaults from the older `/node_modules/node-red-contrib-uibuilder/front-end/uib-styles.css` */ +/* @import url("../uibuilder/uib-styles.css"); */ diff --git a/packages/node-red-data/ui-builder/bash-executor-view/src/index.html b/packages/node-red-data/ui-builder/bash-executor-view/src/index.html new file mode 100644 index 0000000..51e21c6 --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor-view/src/index.html @@ -0,0 +1,26 @@ + + + + + + + + Blank template - Node-RED uibuilder + + + + + + + + + + + + +

uibuilder Blank Template

+
Using the IIFE library.
+ +
+ + diff --git a/packages/node-red-data/ui-builder/bash-executor-view/src/index.js b/packages/node-red-data/ui-builder/bash-executor-view/src/index.js new file mode 100644 index 0000000..64b683a --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor-view/src/index.js @@ -0,0 +1,8 @@ +/** The simplest use of uibuilder client library + * See the docs if the client doesn't start on its own. + */ + +// Listen for incoming messages from Node-RED and action +// uibuilder.onChange('msg', (msg) => { +// // do stuff with the incoming msg +// }) diff --git a/packages/node-red-data/ui-builder/bash-executor/.eslintrc.js b/packages/node-red-data/ui-builder/bash-executor/.eslintrc.js new file mode 100644 index 0000000..7ed4de2 --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor/.eslintrc.js @@ -0,0 +1,80 @@ +/** JavaScript Versions + * 5 is minimum -> Last IE11 + * 6 = 2015 -> Node >8.10, iOS12+ + * 7 = 2016 -> FF78+, + * 8 = 2017 -> Node 10.9+ + * 9 = 2018 -> Node 12.11+ + * 10 = 2019 + * 11 = 2020 + * 12 = 2021 + */ +module.exports = { // eslint-disable-line no-undef + env: { + browser: true, + node: false, + 'shared-node-browser': false, + }, + parserOptions: { + ecmaVersion: 2015, + sourceType: 'script', + }, + root: true, + globals: { + uibuilder: true, + $: true, + }, + overrides: [ + { + files: ['*.esm.js', '*.module.js', '*.mod.js', '*.mjs'], + parserOptions: { sourceType: 'module' }, + } + ], + plugins: [ + 'html', // Check scripts in HTML. https://www.npmjs.com/package/eslint-plugin-html + 'es', // Help avoid js that is too new. https://eslint-plugin-es.mysticatea.dev/ + 'jsdoc', // JSDoc. https://www.npmjs.com/package/eslint-plugin-jsdoc + 'promise', // Better promises. https://www.npmjs.com/package/eslint-plugin-promise + 'sonarjs', // Detect bugs and suspicious patterns. https://github.com/SonarSource/eslint-plugin-sonarjs + ], + extends: [ + 'standard', + // 'eslint:recommended', + 'plugin:es/restrict-to-es2015', + 'plugin:jsdoc/recommended', + 'plugin:promise/recommended', + 'plugin:sonarjs/recommended', + ], + rules: { + // TODO remove once min engines moves to node.js v15+ + 'es/no-logical-assignment-operators': 'error', + 'es/no-promise-any': 'error', + 'es/no-numeric-separators': 'error', + + 'sonarjs/no-duplicate-string': ['warn', { 'threshold': 6 }], // Default is 3 + // 'sonarjs/cognitive-complexity': ['error', 15], // Default is 15 + 'sonarjs/no-nested-template-literals': 0, + + // Tidy up some jsdoc oddities + 'jsdoc/multiline-blocks': 0, + 'jsdoc/newline-after-description': 0, + 'jsdoc/no-multi-asterisks': 0, + 'jsdoc/tag-lines': 0, + 'jsdoc/valid-types': 0, // Rubbish, fails on common type configs + 'jsdoc/no-undefined-types': 0, // ['error'|'warn', {'definedTypes':['Promise']}], + + // Make Standard less annoying + 'brace-style': 'off', // You should only use one-true-brace style but sometimes we want to compress things a bit. + 'comma-dangle': 'off', // Lack of dangles wastes soo much time correcting lists + 'dot-notation': 'off', // Turn off to allow for tslint's brain-dead treatment of expando objects in JS + 'indent': ['error', 4, { 'SwitchCase': 1 }], // Standard wants 2, I like 4 + 'space-before-function-paren': 'off', // No, don't need space between fn and arg! + 'no-multi-spaces': 'off', // Readability is more important than size (reduce size using uglify) + 'object-shorthand': ['error', 'consistent'], + 'padded-blocks': 'off', // Sometimes you just need some space! See above. + 'space-in-parens': 'off', // Sometimes you just need some space! + 'spaced-comment': ['error', 'always', { + 'markers': ['html', '#region', '#endregion'] + }], + 'quote-props': 'off', // Sometimes it is necessary and then much nicer to be able to quote things that don't need it. + }, +} diff --git a/packages/node-red-data/ui-builder/bash-executor/LICENSE b/packages/node-red-data/ui-builder/bash-executor/LICENSE new file mode 100644 index 0000000..a16c46a --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor/LICENSE @@ -0,0 +1,178 @@ + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/packages/node-red-data/ui-builder/bash-executor/README.md b/packages/node-red-data/ui-builder/bash-executor/README.md new file mode 100644 index 0000000..642720c --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor/README.md @@ -0,0 +1,57 @@ +# uibuilder Template: Blank + +> NOTE: You can replace the contents of this README with text that describes your UI. + +This is about the simplest template you can get for uibuilder. Is is also (as of uibuilder v5+), the default template. + +It does not use any frameworks and has no other dependencies. + +It demonstrates that you can use uibuilder purely with HTML/JavaScript or even just HTML and still easily build a simple, dynamic, data-driven user interface with the help of Node-RED. + +All it does is start up uibuilder. + +From uibuilder v6.1.0+, it uses the IIFE client library. + +## Folders + +* `/` - The root folder contains this file. It can be used for other things **but** it will not be served up in the Node-RED web server. +* `/src/` - the default folder that serves files as web resources. However, this can be changed to a different folder if desired. +* `/dist/` - the default folder for serving files as web resources where a build step is used. In that case, the `/src` folder is the source used by the build tool and `/dist` is the destination for the build (the "distribution" folder). +* `/routes/` - This folder can contain `.js` files defining routing middleware for uibuilder's ExpressJS web server. +* `/api/` - This folder can contain `.js` files defining REST API's specific to this uibuilder instance. + +The above folders will all pre-exist for the built-in uibuilder templates. The folders can safely be removed if not needed but one folder must exist to serve the web resources from (this cannot be the root folder). + +The template only has files in the root and `src` folders. The `src` folder is the default used by uibuilder to serve up files to clients. + +One reserved item in the root folder however will be a `package.json` file. This will be used in the future to help with build/compile steps. You can still use it yourself, just bear in mind that a future version of uibuilder will make use it as well. If you need to have any development packages installed to build your UI, don't forget to tell `npm` to save them as development dependencies not normal dependencies. + +The `dist` folder should be used if you have a build step to convert your source code to something that browsers understand. So if you are using a build (compile) step to produce your production code, ensure that it is configured to use the `dist` folder as the output folder and that it creates at least an `index.html` file. + +You can switch between the `src` and `dist` (or other) folders using the matching setting in the Editor. See uibuilder's advanced settings tab. + +Also note that you can use **linked** folders and files in this folder structure. This can be handy if you want to maintain your code in a different folder somewhere or if your default build process needs to use sub-folders other than `src` and `dist`.(Though as of v6, you can specify any sub-folder to be served) + +## Files in this template + +* `package.json`: REQUIRED. Defines the basic structure, name, description of the project and defines any local development dependencies if any. Also works with `npm` allowing the installation of dev packages (such as build or linting tools). +* `README.md`: This file. Change this to describe your web app and provide documentation for it. +* `.eslintrc.js`: A pre-configured configuration for the ESLINT tool. Helps when writing front-end code. +* `LICENSE`: A copy of the Apache 2.0 license. Replace with a different license if needed. Always license your code. Apache 2.0 matches the licensing of uibuilder. +* `src/index.html`: REQUIRED. Contains your basic HTML and will be the file loaded and displayed in the browser when going to the uibuilder defined URL. +* `src/index.js`: Contains all of the logic for your UI. It must be linked to in the html file. Optional. +* `src/index.css`: Contains your custom CSS for styling. It must be linked to in the html file. Optional. + +Note that only the `package.json` and `index.html` files are actually _required_. uibuilder will not function as expected without them. + +It is possible to use the index.html file simply as a link to other files but it must be present. + +The other files are all optional. However, you will need to change the index.html file accordingly if you rename or remove them. + +## Multiple HTML pages + +uibuilder will happily serve up any number of web pages from a single instance. It will also make use of sub-folders. However, each folder should have an `index.html` file so that a URL that ends with the folder name will still work without error. + +Note that each html file is a separate page and requires its own JavaScript and uibuilder library reference. When moving between pages, remember that every page is stand-alone, a new environment. You can share one `index.js` file between multiple pages if you prefer but each page will run a separate instance. + +If multiple pages are connected to the same uibuilder instance, they will all get the same broadcast messages from Node-RED. So if you want to handle different messages on different pages, remember to filter them in your front-end JavaScript in `uibuilder.onChange('msg', ....)` function. Turn on the advanced flag for including a `msg._uib` property in output if you need to differentiate between pages and/or clients in Node-RED. diff --git a/packages/node-red-data/ui-builder/bash-executor/api/.keep b/packages/node-red-data/ui-builder/bash-executor/api/.keep new file mode 100644 index 0000000..e69de29 diff --git a/packages/node-red-data/ui-builder/bash-executor/dist/.keep b/packages/node-red-data/ui-builder/bash-executor/dist/.keep new file mode 100644 index 0000000..e69de29 diff --git a/packages/node-red-data/ui-builder/bash-executor/package.json b/packages/node-red-data/ui-builder/bash-executor/package.json new file mode 100644 index 0000000..869b149 --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor/package.json @@ -0,0 +1,26 @@ +{ + "name": "uib-blank", + "version": "6.1.0", + "private": true, + "description": "This is about the simplest template you can get for uibuilder.", + "browser": "./src/index.js", + "scripts": { + "build": "echo \"Error: no build process specified\" && exit 1" + }, + "keywords": ["uibuilder", "node-red", "node-red-contrib-uibuilder"], + "author": "Julian Knight (Totally Information)", + "license": "Apache-2.0", + "homepage": "https://github.com/TotallyInformation/node-red-contrib-uibuilder", + "bugs": "https://github.com/TotallyInformation/node-red-contrib-uibuilder/issues", + "repository": { + "type": "git", + "url": "https://github.com/TotallyInformation/node-red-contrib-uibuilder.git" + }, + "browserslist": [ + "> 0.5%", + "maintained versions", + "last 2 versions", + "not dead", + "not ie > 0" + ] +} diff --git a/packages/node-red-data/ui-builder/bash-executor/routes/.keep b/packages/node-red-data/ui-builder/bash-executor/routes/.keep new file mode 100644 index 0000000..e69de29 diff --git a/packages/node-red-data/ui-builder/bash-executor/src/index.css b/packages/node-red-data/ui-builder/bash-executor/src/index.css new file mode 100644 index 0000000..a2a47be --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor/src/index.css @@ -0,0 +1,7 @@ +/* Load defaults from `/node_modules/node-red-contrib-uibuilder/front-end/uib-brand.min.css` + * This version auto-adjusts for light/dark browser settings but might not be as complete. + */ +@import url("../uibuilder/uib-brand.min.css"); + +/* OR, load the defaults from the older `/node_modules/node-red-contrib-uibuilder/front-end/uib-styles.css` */ +/* @import url("../uibuilder/uib-styles.css"); */ diff --git a/packages/node-red-data/ui-builder/bash-executor/src/index.html b/packages/node-red-data/ui-builder/bash-executor/src/index.html new file mode 100644 index 0000000..51e21c6 --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor/src/index.html @@ -0,0 +1,26 @@ + + + + + + + + Blank template - Node-RED uibuilder + + + + + + + + + + + + +

uibuilder Blank Template

+
Using the IIFE library.
+ +
+ + diff --git a/packages/node-red-data/ui-builder/bash-executor/src/index.js b/packages/node-red-data/ui-builder/bash-executor/src/index.js new file mode 100644 index 0000000..64b683a --- /dev/null +++ b/packages/node-red-data/ui-builder/bash-executor/src/index.js @@ -0,0 +1,8 @@ +/** The simplest use of uibuilder client library + * See the docs if the client doesn't start on its own. + */ + +// Listen for incoming messages from Node-RED and action +// uibuilder.onChange('msg', (msg) => { +// // do stuff with the incoming msg +// }) diff --git a/packages/node-red-data/ui-builder/package.json b/packages/node-red-data/ui-builder/package.json index c7ade14..8b126aa 100644 --- a/packages/node-red-data/ui-builder/package.json +++ b/packages/node-red-data/ui-builder/package.json @@ -1,6 +1,6 @@ { "name": "uib_root", - "version": "0.2.11", + "version": "0.2.12", "description": "Root configuration and data folder for uibuilder", "scripts": {}, "dependencies": {}, diff --git a/packages/node-red-data/ui-builder/package.json.bak b/packages/node-red-data/ui-builder/package.json.bak index c7ade14..8b126aa 100644 --- a/packages/node-red-data/ui-builder/package.json.bak +++ b/packages/node-red-data/ui-builder/package.json.bak @@ -1,6 +1,6 @@ { "name": "uib_root", - "version": "0.2.11", + "version": "0.2.12", "description": "Root configuration and data folder for uibuilder", "scripts": {}, "dependencies": {},