From 32112ff33b3f7560f683124a76b3e4cee90c5ec3 Mon Sep 17 00:00:00 2001 From: nrvo <151435968+nrvo@users.noreply.github.com> Date: Wed, 24 Jan 2024 10:34:04 +0100 Subject: [PATCH] [App] Flowise AI (#2290) * Add Flowise app * Update apps/flowise/metadata/description.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/flowise/metadata/description.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/flowise/metadata/description.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * update after review * update config.json * fix(flowise): remove unused config * fix(flowise): remove required from random --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Stavros --- apps/flowise/config.json | 76 +++++++++++++++++++++++++++ apps/flowise/docker-compose.yml | 53 +++++++++++++++++++ apps/flowise/metadata/description.md | 50 ++++++++++++++++++ apps/flowise/metadata/logo.jpg | Bin 0 -> 30708 bytes 4 files changed, 179 insertions(+) create mode 100644 apps/flowise/config.json create mode 100644 apps/flowise/docker-compose.yml create mode 100644 apps/flowise/metadata/description.md create mode 100644 apps/flowise/metadata/logo.jpg diff --git a/apps/flowise/config.json b/apps/flowise/config.json new file mode 100644 index 00000000..1fd2f08d --- /dev/null +++ b/apps/flowise/config.json @@ -0,0 +1,76 @@ +{ + "$schema": "../schema.json", + "name": "Flowise AI", + "available": true, + "exposable": true, + "port": 8009, + "id": "flowise", + "tipi_version": 1, + "version": "1.4.10", + "categories": ["ai", "automation"], + "description": "Flowise AI is an Open source UI visual tool to build your customized LLM ochestration flow & AI agents. Developing LLM apps takes countless iterations. With low code approach, Flowise AI enable quick iterations to go from testing to production.", + "short_desc": "Build LLM Apps Easily", + "author": "flowise.ai", + "source": "https://github.com/FlowiseAI/Flowise", + "website": "https://flowiseai.com/", + "form_fields": [ + { + "type": "text", + "label": "Flowise Username", + "max": 50, + "min": 3, + "required": true, + "env_variable": "FLOWISE_USERNAME" + }, + { + "type": "password", + "label": "Flowise Password", + "max": 50, + "min": 12, + "required": true, + "env_variable": "FLOWISE_PASSWORD" + }, + { + "type": "random", + "label": "Flowise Secret", + "min": 16, + "env_variable": "FLOWISE_SECRETKEY_OVERWRITE" + }, + { + "type": "url", + "label": "(Optional) Langchain Endpoint", + "hint": "URL of your langhchain endpoint", + "required": false, + "env_variable": "LANGCHAIN_ENDPOINT" + }, + { + "type": "password", + "label": "(Optional) Langchain API Key", + "max": 50, + "min": 3, + "required": false, + "env_variable": "LANGCHAIN_API_KEY" + }, + { + "type": "text", + "label": "(Optional) Langchain Project", + "max": 50, + "min": 3, + "required": false, + "env_variable": "LANGCHAIN_PROJECT" + }, + { + "type": "boolean", + "label": "Enable Langchain Tracing v2", + "required": false, + "env_variable": "LANGCHAIN_TRACING_V2" + }, + { + "type": "boolean", + "label": "Disable Flowise telemetry", + "required": false, + "env_variable": "DISABLE_FLOWISE_TELEMETRY" + } + ], + "supported_architectures": ["arm64", "amd64"] +} diff --git a/apps/flowise/docker-compose.yml b/apps/flowise/docker-compose.yml new file mode 100644 index 00000000..2b4937c7 --- /dev/null +++ b/apps/flowise/docker-compose.yml @@ -0,0 +1,53 @@ +version: '3.7' + +services: + flowise: + image: flowiseai/flowise:1.4.10 + restart: unless-stopped + command: /bin/sh -c "sleep 3; flowise start" + container_name: flowise + environment: + - PORT=8009 + - FLOWISE_USERNAME=${FLOWISE_USERNAME} + - FLOWISE_PASSWORD=${FLOWISE_PASSWORD} + - FLOWISE_SECRETKEY_OVERWRITE=${FLOWISE_SECRETKEY_OVERWRITE} + - LANGCHAIN_ENDPOINT=${LANGCHAIN_ENDPOINT} + - LANGCHAIN_API_KEY=${LANGCHAIN_API_KEY} + - LANGCHAIN_PROJECT=${LANGCHAIN_PROJECT} + - LANGCHAIN_TRACING_V2=${LANGCHAIN_TRACING_V2} + - DISABLE_FLOWISE_TELEMETRY=${DISABLE_FLOWISE_TELEMETRY} + - DATABASE_PATH=/root/.flowise + - APIKEY_PATH=/root/.flowise + - SECRETKEY_PATH=/root/.flowise/logs + - LOG_PATH=/root/.flowise + ports: + - "${APP_PORT}:8009" + volumes: + - ${APP_DATA_DIR}/data/flowise:/root/.flowise + networks: + - tipi_main_network + labels: + # Main + traefik.enable: true + traefik.http.middlewares.flowise-web-redirect.redirectscheme.scheme: https + traefik.http.services.flowise.loadbalancer.server.port: 8009 + # Web + traefik.http.routers.flowise-insecure.rule: Host(`${APP_DOMAIN}`) + traefik.http.routers.flowise-insecure.entrypoints: web + traefik.http.routers.flowise-insecure.service: flowise + traefik.http.routers.flowise-insecure.middlewares: flowise-web-redirect + # Websecure + traefik.http.routers.flowise.rule: Host(`${APP_DOMAIN}`) + traefik.http.routers.flowise.entrypoints: websecure + traefik.http.routers.flowise.service: flowise + traefik.http.routers.flowise.tls.certresolver: myresolver + # Local domain + traefik.http.routers.flowise-local-insecure.rule: Host(`flowise.${LOCAL_DOMAIN}`) + traefik.http.routers.flowise-local-insecure.entrypoints: web + traefik.http.routers.flowise-local-insecure.service: flowise + traefik.http.routers.flowise-local-insecure.middlewares: flowise-web-redirect + # Local domain secure + traefik.http.routers.flowise-local.rule: Host(`flowise.${LOCAL_DOMAIN}`) + traefik.http.routers.flowise-local.entrypoints: websecure + traefik.http.routers.flowise-local.service: flowise + traefik.http.routers.flowise-local.tls: true diff --git a/apps/flowise/metadata/description.md b/apps/flowise/metadata/description.md new file mode 100644 index 00000000..34928d4a --- /dev/null +++ b/apps/flowise/metadata/description.md @@ -0,0 +1,50 @@ +# Flowise - Build LLM Apps Easily + +[Flowise AI](https://github.com/FlowiseAI/Flowise) is an Open source UI visual tool to build your customized LLM orchestration flow & AI agents. Developing LLM apps takes countless iterations. With low code approach, Flowise AI enable quick iterations to go from testing to production. + +--- + +![](https://github.com/FlowiseAI/Flowise/blob/main/images/flowise.png?raw=true) + +![](https://github.com/FlowiseAI/Flowise/blob/main/images/flowise.gif?raw=true) + +--- + +## ⭐ Features +Developing LLM apps takes countless iterations. With low code approach, we enable quick iterations to go from testing to production + +### LLM Ochestration +Connect LLMs with memory, data loaders, cache, moderation and many more +- Langchain +- LlamaIndex +- 100+ integrations + +--- + +### Agents & Assistants +Create an autonomous agent that can use tools to execute different tasks +- Custom Tools +- OpenAI Assistant +- Function Agent + +--- + +### API, SDK, Embed +Extend and integrate to your applications using APIs, SDK and Embedded Chat +- APIs +- Embedded Widget +- React SDK + +--- + +### Open source LLMs +Run in an air-gapped environment with local LLMs, embeddings, and vector databases +- HuggingFace, Ollama, LocalAI, Replicate +- Llama2, Mistral, Vicuna, Orca, Llava +- Self host on AWS, Azure, GCP + +--- + +### 📖 Website & Docs +[Flowise Docs](https://docs.flowiseai.com/) +[Website](https://flowiseai.com/) diff --git a/apps/flowise/metadata/logo.jpg b/apps/flowise/metadata/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..25ec801df67a1feffdfdd7b042ed52e5c15c7ba8 GIT binary patch literal 30708 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