Tai Truong commited on
Commit
d202ada
·
1 Parent(s): 40131fc

fix readme

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .devcontainer/Dockerfile +29 -0
  2. .devcontainer/demo/README.md +15 -0
  3. .devcontainer/demo/devcontainer.json +33 -0
  4. .devcontainer/devcontainer.json +51 -0
  5. .env.example +104 -0
  6. .eslintrc.json +90 -0
  7. .gitattributes +32 -35
  8. .github/ISSUE_TEMPLATE/bug-report.yaml +120 -0
  9. .github/ISSUE_TEMPLATE/feature-request.yaml +28 -0
  10. .github/ISSUE_TEMPLATE/work-in-progress.yaml +58 -0
  11. .github/actions/install-playwright/action.yml +76 -0
  12. .github/actions/poetry_caching/action.yml +99 -0
  13. .github/actions/setup-uv/action.yml +25 -0
  14. .github/changes-filter.yaml +71 -0
  15. .github/dependabot.yml +11 -0
  16. .github/release.yml +35 -0
  17. .github/semantic.yml +2 -0
  18. .github/workflows/auto-update.yml +13 -0
  19. .github/workflows/ci.yml +140 -0
  20. .github/workflows/codeql.yml +66 -0
  21. .github/workflows/codspeed.yml +45 -0
  22. .github/workflows/conventional-labels.yml +28 -0
  23. .github/workflows/create-release.yml +36 -0
  24. .github/workflows/deploy_gh-pages.yml +41 -0
  25. .github/workflows/docker-build.yml +323 -0
  26. .github/workflows/docker_test.yml +64 -0
  27. .github/workflows/docs_test.yml +49 -0
  28. .github/workflows/fetch_docs_notion.yml +61 -0
  29. .github/workflows/integration_tests.yml +50 -0
  30. .github/workflows/js_autofix.yml +45 -0
  31. .github/workflows/lint-js.yml +53 -0
  32. .github/workflows/lint-py.yml +41 -0
  33. .github/workflows/matchers/ruff.json +14 -0
  34. .github/workflows/nightly_build.yml +204 -0
  35. .github/workflows/py_autofix.yml +21 -0
  36. .github/workflows/python_test.yml +175 -0
  37. .github/workflows/release.yml +243 -0
  38. .github/workflows/release_nightly.yml +233 -0
  39. .github/workflows/store_pytest_durations.yml +65 -0
  40. .github/workflows/style-check-py.yml +31 -0
  41. .github/workflows/typescript_test.yml +348 -0
  42. .gitignore +279 -0
  43. .pre-commit-config.yaml +25 -0
  44. .vscode/launch.json +80 -0
  45. .vscode/tasks.json +54 -0
  46. CODE_OF_CONDUCT.md +128 -0
  47. CONTRIBUTING.md +102 -0
  48. LICENSE +21 -0
  49. Makefile +446 -0
  50. README.md +0 -11
.devcontainer/Dockerfile ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Source: https://github.com/a5chin/python-uv
2
+ FROM debian:bookworm-slim AS builder
3
+
4
+ ENV CARGO_HOME="/opt/.cargo"
5
+
6
+ SHELL [ "/bin/bash", "-o", "pipefail", "-c" ]
7
+
8
+ WORKDIR /opt
9
+
10
+ # The installer requires curl (and certificates) to download the release archive
11
+ # hadolint ignore=DL3008
12
+ RUN apt-get update && \
13
+ apt-get install -y --no-install-recommends ca-certificates curl
14
+
15
+ # Run uv installer
16
+ RUN curl -LsSf https://astral.sh/uv/install.sh | sh
17
+
18
+
19
+ FROM mcr.microsoft.com/vscode/devcontainers/base:bookworm
20
+
21
+
22
+ ENV CARGO_HOME="/opt/.cargo"
23
+ ENV PATH="$CARGO_HOME/bin/:$PATH"
24
+ ENV PYTHONUNBUFFERED=True
25
+ ENV UV_LINK_MODE=copy
26
+
27
+ WORKDIR /opt
28
+
29
+ COPY --from=builder --chown=vscode: $CARGO_HOME $CARGO_HOME
.devcontainer/demo/README.md ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Langflow Demo Codespace Readme
2
+
3
+ These instructions will walk you through the process of running a Langflow demo via GitHub Codespaces.
4
+
5
+ ## Setup
6
+
7
+ ### Create a Codespace in GitHub
8
+
9
+ To setup the demo, simply navigate to the Langflow repo, click the "+" button, and select "Create new Codespace". This will automatically create a new codespace in your browser, which you can use for the demo.
10
+
11
+ ### Wait for everything to install
12
+
13
+ After the codespace is opened, you should see a new Terminal window in VS Code where langflow is installed. Once the install completes, `langflow` will launch the webserver and your application will be available via devcontainer port.
14
+
15
+ Note: VS Code should prompt you with a button to push once the port is available.
.devcontainer/demo/devcontainer.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2
+ // README at: https://github.com/devcontainers/templates/tree/main/src/universal
3
+ {
4
+ "name": "Langflow Demo Container",
5
+ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6
+ "image": "mcr.microsoft.com/devcontainers/python:3.10",
7
+ "features": {
8
+ "ghcr.io/devcontainers/features/aws-cli:1": {},
9
+ "ghcr.io/devcontainers/features/docker-in-docker": {},
10
+ "ghcr.io/devcontainers/features/node": {}
11
+ },
12
+ "customizations": {
13
+ "vscode": {
14
+ "extensions": [
15
+ "actboy168.tasks",
16
+ "GitHub.copilot",
17
+ "ms-python.python",
18
+ "eamodio.gitlens",
19
+ "GitHub.vscode-pull-request-github"
20
+ ]
21
+ }
22
+ },
23
+ // Features to add to the dev container. More info: https://containers.dev/features.
24
+ // "features": {},
25
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
26
+ // "forwardPorts": [],
27
+ // Use 'postCreateCommand' to run commands after the container is created.
28
+ "postCreateCommand": "pipx install 'langflow>=0.0.33' && langflow --host 0.0.0.0"
29
+ // Configure tool-specific properties.
30
+ // "customizations": {},
31
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
32
+ // "remoteUser": "root"
33
+ }
.devcontainer/devcontainer.json ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2
+ // README at: https://github.com/devcontainers/templates/tree/main/src/universal
3
+ {
4
+ "name": "Langflow Dev Container",
5
+ "build": {
6
+ "context": "..",
7
+ "dockerfile": "Dockerfile"
8
+ },
9
+ // Features to add to the dev container. More info: https://containers.dev/features.
10
+ "features": {
11
+ "ghcr.io/devcontainers/features/node": {},
12
+ "ghcr.io/dhoeric/features/hadolint:1": {}
13
+ },
14
+
15
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
16
+ // "forwardPorts": [],
17
+
18
+ // Use 'postCreateCommand' to run commands after the container is created.
19
+ "postCreateCommand": "make install_frontend && make install_backend",
20
+ "postStartCommand": "make init",
21
+
22
+ // Configure tool-specific properties.
23
+ "customizations": {
24
+ "vscode": {
25
+ "extensions": [
26
+ "charliermarsh.ruff",
27
+ "njpwerner.autodocstring",
28
+ "oderwat.indent-rainbow",
29
+ "exiasr.hadolint",
30
+ "actboy168.tasks",
31
+ "GitHub.copilot",
32
+ "ms-python.python",
33
+ "eamodio.gitlens",
34
+ "ms-vscode.makefile-tools",
35
+ "GitHub.vscode-pull-request-github"
36
+ ],
37
+ "settings": {
38
+ "terminal.integrated.defaultProfile.linux": "zsh",
39
+ "terminal.integrated.profiles.linux": {
40
+ "zsh": {
41
+ "path": "/bin/zsh"
42
+ }
43
+ }
44
+ }
45
+ }
46
+ },
47
+
48
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
49
+ // "remoteUser": "root"
50
+ "remoteUser": "vscode"
51
+ }
.env.example ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Description: Example of .env file
2
+ # Usage: Copy this file to .env and change the values
3
+ # according to your needs
4
+ # Do not commit .env file to git
5
+ # Do not change .env.example file
6
+
7
+ # Config directory
8
+ # Directory where files, logs and database will be stored
9
+ # Example: LANGFLOW_CONFIG_DIR=~/.langflow
10
+ LANGFLOW_CONFIG_DIR=
11
+
12
+ # Save database in the config directory
13
+ # Values: true, false
14
+ # If false, the database will be saved in Langflow's root directory
15
+ # This means that the database will be deleted when Langflow is uninstalled
16
+ # and that the database will not be shared between different virtual environments
17
+ # Example: LANGFLOW_SAVE_DB_IN_CONFIG_DIR=true
18
+ LANGFLOW_SAVE_DB_IN_CONFIG_DIR=
19
+
20
+ # Database URL
21
+ # Postgres example: LANGFLOW_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/langflow
22
+ # SQLite example:
23
+ LANGFLOW_DATABASE_URL=sqlite:///./langflow.db
24
+
25
+ # Cache type
26
+ LANGFLOW_LANGCHAIN_CACHE=SQLiteCache
27
+
28
+ # Server host
29
+ # Example: LANGFLOW_HOST=127.0.0.1
30
+ LANGFLOW_HOST=
31
+
32
+ # Worker processes
33
+ # Example: LANGFLOW_WORKERS=1
34
+ LANGFLOW_WORKERS=
35
+
36
+ # Server port
37
+ # Example: LANGFLOW_PORT=7860
38
+ LANGFLOW_PORT=
39
+
40
+ # Logging level
41
+ # Example: LANGFLOW_LOG_LEVEL=critical
42
+ LANGFLOW_LOG_LEVEL=
43
+
44
+ # Path to the log file
45
+ # Example: LANGFLOW_LOG_FILE=logs/langflow.log
46
+ LANGFLOW_LOG_FILE=
47
+
48
+ # Path to the frontend directory containing build files
49
+ # Example: LANGFLOW_FRONTEND_PATH=/path/to/frontend/build/files
50
+ LANGFLOW_FRONTEND_PATH=
51
+
52
+ # Whether to open the browser after starting the server
53
+ # Values: true, false
54
+ # Example: LANGFLOW_OPEN_BROWSER=true
55
+ LANGFLOW_OPEN_BROWSER=
56
+
57
+ # Whether to remove API keys from the projects saved in the database
58
+ # Values: true, false
59
+ # Example: LANGFLOW_REMOVE_API_KEYS=false
60
+ LANGFLOW_REMOVE_API_KEYS=
61
+
62
+ # Whether to use RedisCache or ThreadingInMemoryCache or AsyncInMemoryCache
63
+ # Values: async, memory, redis
64
+ # Example: LANGFLOW_CACHE_TYPE=memory
65
+ # If you want to use redis then the following environment variables must be set:
66
+ # LANGFLOW_REDIS_HOST (default: localhost)
67
+ # LANGFLOW_REDIS_PORT (default: 6379)
68
+ # LANGFLOW_REDIS_DB (default: 0)
69
+ # LANGFLOW_REDIS_CACHE_EXPIRE (default: 3600)
70
+ LANGFLOW_CACHE_TYPE=
71
+
72
+ # Set AUTO_LOGIN to false if you want to disable auto login
73
+ # and use the login form to login. LANGFLOW_SUPERUSER and LANGFLOW_SUPERUSER_PASSWORD
74
+ # must be set if AUTO_LOGIN is set to false
75
+ # Values: true, false
76
+ LANGFLOW_AUTO_LOGIN=
77
+
78
+ # Superuser username
79
+ # Example: LANGFLOW_SUPERUSER=admin
80
+ LANGFLOW_SUPERUSER=
81
+
82
+ # Superuser password
83
+ # Example: LANGFLOW_SUPERUSER_PASSWORD=123456
84
+ LANGFLOW_SUPERUSER_PASSWORD=
85
+
86
+ # Should store environment variables in the database
87
+ # Values: true, false
88
+ LANGFLOW_STORE_ENVIRONMENT_VARIABLES=
89
+
90
+ # STORE_URL
91
+ # Example: LANGFLOW_STORE_URL=https://api.langflow.store
92
+ # LANGFLOW_STORE_URL=
93
+
94
+ # DOWNLOAD_WEBHOOK_URL
95
+ #
96
+ # LANGFLOW_DOWNLOAD_WEBHOOK_URL=
97
+
98
+ # LIKE_WEBHOOK_URL
99
+ #
100
+ # LANGFLOW_LIKE_WEBHOOK_URL=
101
+
102
+ # Value must finish with slash /
103
+ #BACKEND_URL=http://localhost:7860/
104
+ BACKEND_URL=
.eslintrc.json ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "extends": [
3
+ "eslint:recommended",
4
+ "plugin:react/recommended",
5
+ "plugin:prettier/recommended"
6
+ ],
7
+ "plugins": [
8
+ "react",
9
+ "import-helpers",
10
+ "prettier"
11
+ ],
12
+ "parser": "@typescript-eslint/parser",
13
+ "parserOptions": {
14
+ "project": [
15
+ "./tsconfig.node.json",
16
+ "./tsconfig.json"
17
+ ],
18
+ "extraFileExtensions:": [
19
+ ".mdx"
20
+ ],
21
+ "extensions:": [
22
+ ".mdx"
23
+ ]
24
+ },
25
+ "env": {
26
+ "browser": true,
27
+ "es2021": true
28
+ },
29
+ "settings": {
30
+ "react": {
31
+ "version": "detect"
32
+ }
33
+ },
34
+ "rules": {
35
+ "no-console": "warn",
36
+ "no-self-assign": "warn",
37
+ "no-self-compare": "warn",
38
+ "complexity": [
39
+ "error",
40
+ {
41
+ "max": 15
42
+ }
43
+ ],
44
+ "indent": [
45
+ "error",
46
+ 2,
47
+ {
48
+ "SwitchCase": 1
49
+ }
50
+ ],
51
+ "no-dupe-keys": "error",
52
+ "no-invalid-regexp": "error",
53
+ "no-undef": "error",
54
+ "no-return-assign": "error",
55
+ "no-redeclare": "error",
56
+ "no-empty": "error",
57
+ "no-await-in-loop": "error",
58
+ "react/react-in-jsx-scope": 0,
59
+ "node/exports-style": [
60
+ "error",
61
+ "module.exports"
62
+ ],
63
+ "node/file-extension-in-import": [
64
+ "error",
65
+ "always"
66
+ ],
67
+ "node/prefer-global/buffer": [
68
+ "error",
69
+ "always"
70
+ ],
71
+ "node/prefer-global/console": [
72
+ "error",
73
+ "always"
74
+ ],
75
+ "node/prefer-global/process": [
76
+ "error",
77
+ "always"
78
+ ],
79
+ "node/prefer-global/url-search-params": [
80
+ "error",
81
+ "always"
82
+ ],
83
+ "node/prefer-global/url": [
84
+ "error",
85
+ "always"
86
+ ],
87
+ "node/prefer-promises/dns": "error",
88
+ "node/prefer-promises/fs": "error"
89
+ }
90
+ }
.gitattributes CHANGED
@@ -1,35 +1,32 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ # Set the default behavior, in case people don't have core.autocrlf set.
2
+ * text eol=lf
3
+ # Explicitly declare text files you want to always be normalized and converted
4
+ # to native line endings on checkout.
5
+ *.c text
6
+ *.h text
7
+ *.py text
8
+ *.js text
9
+ *.jsx text
10
+ *.ts text
11
+ *.tsx text
12
+ *.md text
13
+ *.mdx text
14
+ *.yml text
15
+ *.yaml text
16
+ *.xml text
17
+ *.csv text
18
+ *.json text
19
+ *.sh text
20
+ *.Dockerfile text
21
+ Dockerfile text
22
+ # Declare files that will always have CRLF line endings on checkout.
23
+ *.sln text eol=crlf
24
+ # Denote all files that are truly binary and should not be modified.
25
+ *.png filter=lfs diff=lfs merge=lfs -text
26
+ *.jpg filter=lfs diff=lfs merge=lfs -text
27
+ *.ico binary
28
+ *.gif binary
29
+ *.mp4 binary
30
+ *.svg binary
31
+ *.csv binary
32
+ *.gif filter=lfs diff=lfs merge=lfs -text
 
 
 
.github/ISSUE_TEMPLATE/bug-report.yaml ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "🐛 Bug Report"
2
+ description: Submit a bug report to help us improve Langflow
3
+ labels: [ "bug" ]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thanks for taking the time to fill out this bug report!
9
+
10
+ - type: textarea
11
+ id: description
12
+ attributes:
13
+ label: Bug Description
14
+ description: A clear and concise description of what the bug is
15
+ placeholder: Tell us what you see!
16
+ validations:
17
+ required: true
18
+
19
+ - type: textarea
20
+ id: reproduction
21
+ validations:
22
+ required: true
23
+ attributes:
24
+ label: Reproduction
25
+ description: |
26
+ Please provide a code sample that reproduces the problem you ran into. It can be a Colab link or just a code snippet.
27
+ If you have code snippets, error messages, or stack traces please provide them here as well.
28
+ Important! Use code tags to format your code correctly. See https://help.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks#syntax-highlighting
29
+ Do not use screenshots, as they are hard to read, and (more importantly) don't allow others to copy-and-paste your code.
30
+ placeholder: |
31
+ Steps to reproduce the behavior:
32
+
33
+ 1.
34
+ 2.
35
+ 3.
36
+
37
+ - type: textarea
38
+ id: expected-behavior
39
+ validations:
40
+ required: true
41
+ attributes:
42
+ label: Expected behavior
43
+ description: "A clear and concise description of what you would expect to happen."
44
+
45
+ - type: textarea
46
+ id: who-can-help
47
+ attributes:
48
+ label: Who can help?
49
+ description: |
50
+ Your issue will be replied to more quickly if you can figure out the right person to tag with @.
51
+ If you know the relevant code owner, please tag them. Otherwise, leave this blank and a core maintainer will direct the issue accordingly.
52
+
53
+ Please tag fewer than 3 people.
54
+
55
+ Specific Areas:
56
+
57
+ Frontend:
58
+ - @anovazzi1
59
+ - @Cristhianzl
60
+ - @lucaseduoli
61
+ - @igorrCarvalho
62
+
63
+ Backend:
64
+ - @italojohnny
65
+
66
+ Full Stack:
67
+ - @ogabrielluiz
68
+ - @nicoloboschi
69
+ - @zzzming
70
+ - @jordanrfrazier
71
+ - @mfortman11
72
+ - @NadirJ
73
+
74
+ placeholder: "@Username ..."
75
+
76
+ - type: markdown
77
+ attributes:
78
+ value: '## Environment'
79
+
80
+ - type: input
81
+ id: os
82
+ attributes:
83
+ label: Operating System
84
+ placeholder: ex. Ubuntu Linux 22.04
85
+ validations:
86
+ required: true
87
+
88
+ - type: input
89
+ id: langflow-version
90
+ attributes:
91
+ label: Langflow Version
92
+ placeholder: ex. 1.0.9
93
+ validations:
94
+ required: true
95
+
96
+ - type: dropdown
97
+ id: python-version
98
+ attributes:
99
+ label: "Python Version"
100
+ description: |
101
+
102
+ **Langflow requires Python version 3.10 or greater.**
103
+ options:
104
+ - "3.12"
105
+ - "3.11"
106
+ - "3.10"
107
+
108
+ - type: textarea
109
+ id: screenshot
110
+ attributes:
111
+ label: Screenshot
112
+ description: "If applicable, add screenshots to help explain your problem."
113
+ placeholder: "Paste your screenshot here."
114
+
115
+ - type: textarea
116
+ id: flow-file
117
+ attributes:
118
+ label: Flow File
119
+ description: "Add your flow if applicable to help replicate the problem."
120
+ placeholder: "Add your flow link here."
.github/ISSUE_TEMPLATE/feature-request.yaml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "🚀 Feature Request"
2
+ description: Submit a proposal/request for a new Langflow feature
3
+ labels: [ "enhancement" ]
4
+ body:
5
+ - type: textarea
6
+ id: feature-request
7
+ validations:
8
+ required: true
9
+ attributes:
10
+ label: Feature Request
11
+ description: |
12
+ A clear and concise description of the feature proposal. Please provide any relevant links to papers, code, or other resources that support your proposal.
13
+
14
+ - type: textarea
15
+ id: motivation
16
+ validations:
17
+ required: true
18
+ attributes:
19
+ label: Motivation
20
+ description: |
21
+ Please outline the motivation for the proposal. Is your feature request related to a problem? e.g., I'm always frustrated when [...]. If this is related to another GitHub issue, please link it here as well.
22
+
23
+ - type: textarea
24
+ id: contribution
25
+ attributes:
26
+ label: Your Contribution
27
+ description: |
28
+ Is there any way that you could help, e.g., by submitting a PR? Make sure to read the CONTRIBUTING.md guidelines for Langflow before proceeding.
.github/ISSUE_TEMPLATE/work-in-progress.yaml ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Work in Progress
2
+ description: Use this template to describe the new feature or improvement you are currently working on.
3
+ labels: [enhancement]
4
+
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ ## Work in Progress
10
+
11
+ Thank you for contributing to our project! Please fill out the sections below to describe the new feature or improvement you are currently working on.
12
+
13
+ - type: input
14
+ id: title
15
+ attributes:
16
+ label: Title
17
+ description: Provide a concise title for your feature or improvement.
18
+ placeholder: "Short and descriptive title"
19
+ validations:
20
+ required: true
21
+
22
+ - type: dropdown
23
+ id: type
24
+ attributes:
25
+ label: Type
26
+ description: Is this a new feature or an improvement?
27
+ options:
28
+ - New Feature
29
+ - Improvement
30
+ validations:
31
+ required: true
32
+
33
+ - type: textarea
34
+ id: description
35
+ attributes:
36
+ label: Description
37
+ description: Provide a detailed description of the feature or improvement.
38
+ placeholder: "Explain the feature or improvement in detail"
39
+ validations:
40
+ required: true
41
+
42
+ - type: textarea
43
+ id: use-case
44
+ attributes:
45
+ label: Use Case
46
+ description: Describe the use case or user story that this feature or improvement addresses.
47
+ placeholder: "As a [user], I want to [do something] so that [benefit]."
48
+ validations:
49
+ required: false
50
+
51
+ - type: textarea
52
+ id: implementation
53
+ attributes:
54
+ label: Implementation Plan
55
+ description: Outline your plan for implementing this feature or improvement.
56
+ placeholder: "Describe how you plan to implement this feature or improvement."
57
+ validations:
58
+ required: false
.github/actions/install-playwright/action.yml ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Install Playwright
2
+ description: Install Playwright and dependencies with cache
3
+
4
+ # https://github.com/microsoft/playwright/issues/7249
5
+
6
+ inputs:
7
+ working-directory:
8
+ description: Where to install Playwright
9
+ default: ./
10
+ browsers:
11
+ description: Browsers to install
12
+ default: chromium webkit firefox
13
+
14
+ outputs:
15
+ version:
16
+ description: Installed version of Playwright
17
+ value: ${{ steps.version.outputs.version }}
18
+ cache-hit:
19
+ description: Whether cache for Playwright was found
20
+ value: ${{ steps.cache.outputs.cache-hit }}
21
+
22
+ runs:
23
+ using: composite
24
+ steps:
25
+ - name: Get Playwright version
26
+ uses: actions/github-script@v7
27
+ id: version
28
+ with:
29
+ script: |
30
+ const fs = require('fs');
31
+ const path = require('path');
32
+
33
+ // Get working directory
34
+ const workingDirectory = "${{ inputs.working-directory }}";
35
+ console.debug("Specified working directory:", workingDirectory);
36
+ if (workingDirectory) process.chdir(workingDirectory);
37
+ console.debug("Actual working directory:", process.cwd());
38
+
39
+ // Read package.json
40
+ let version = "";
41
+ try {
42
+ const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
43
+ version = (
44
+ packageJson.devDependencies?.['@playwright/test'] ||
45
+ packageJson.dependencies?.['@playwright/test'] ||
46
+ packageJson.dependencies?.['playwright'] ||
47
+ packageJson.devDependencies?.['playwright']
48
+ )?.replace(/[\^~]/g, '');
49
+ } catch (error) {
50
+ console.log(error.message);
51
+ }
52
+
53
+ console.debug("Version:", version);
54
+ if (version) {
55
+ core.exportVariable("PLAYWRIGHT_VERSION", version);
56
+ core.setOutput("version", version);
57
+ } else core.setFailed("Couldn't get Playwright version");
58
+
59
+ - name: Cache Playwright
60
+ id: cache
61
+ uses: actions/cache@v4
62
+ with:
63
+ path: ~/.cache/ms-playwright
64
+ key: playwright-${{ env.PLAYWRIGHT_VERSION }}
65
+
66
+ - name: Install Playwright and its dependencies
67
+ shell: bash
68
+ if: steps.cache.outputs.cache-hit != 'true'
69
+ working-directory: ${{ inputs.working-directory }}
70
+ run: npx playwright install ${{ inputs.browsers }} --with-deps
71
+
72
+ - name: Install just Playwright's dependencies
73
+ shell: bash
74
+ if: steps.cache.outputs.cache-hit == 'true'
75
+ working-directory: ${{ inputs.working-directory }}
76
+ run: npx playwright install-deps
.github/actions/poetry_caching/action.yml ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # An action for setting up poetry install with caching.
2
+ # Using a custom action since the default action does not
3
+ # take poetry install groups into account.
4
+ # Action code from:
5
+ # https://github.com/actions/setup-python/issues/505#issuecomment-1273013236
6
+ # Copy of https://github.com/langchain-ai/langchain/blob/2f8dd1a1619f25daa4737df4d378b1acd6ff83c4/.github/actions/poetry_setup/action.yml
7
+ name: poetry-install-with-caching
8
+ description: Poetry install with support for caching of dependency groups.
9
+
10
+ inputs:
11
+ python-version:
12
+ description: Python version, supporting MAJOR.MINOR only
13
+ required: true
14
+
15
+ poetry-version:
16
+ description: Poetry version
17
+ required: true
18
+
19
+ cache-key:
20
+ description: Cache key to use for manual handling of caching
21
+ required: true
22
+
23
+ working-directory:
24
+ description: Directory whose poetry.lock file should be cached
25
+ required: true
26
+
27
+ runs:
28
+ using: composite
29
+ steps:
30
+ - uses: actions/setup-python@v5
31
+ name: Setup python ${{ inputs.python-version }}
32
+ id: setup-python
33
+ with:
34
+ python-version: ${{ inputs.python-version }}
35
+
36
+ - uses: actions/cache@v4
37
+ id: cache-bin-poetry
38
+ name: Cache Poetry binary - Python ${{ inputs.python-version }}
39
+ env:
40
+ SEGMENT_DOWNLOAD_TIMEOUT_MIN: "1"
41
+ with:
42
+ path: |
43
+ /opt/pipx/venvs/poetry
44
+ # This step caches the poetry installation, so make sure it's keyed on the poetry version as well.
45
+ key: bin-poetry-${{ runner.os }}-${{ runner.arch }}-py-${{ inputs.python-version }}-${{ inputs.poetry-version }}
46
+
47
+ - name: Refresh shell hashtable and fixup softlinks
48
+ if: steps.cache-bin-poetry.outputs.cache-hit == 'true'
49
+ shell: bash
50
+ env:
51
+ POETRY_VERSION: ${{ inputs.poetry-version }}
52
+ PYTHON_VERSION: ${{ inputs.python-version }}
53
+ run: |
54
+ set -eux
55
+
56
+ # Refresh the shell hashtable, to ensure correct `which` output.
57
+ hash -r
58
+
59
+ # `actions/cache@v3` doesn't always seem able to correctly unpack softlinks.
60
+ # Delete and recreate the softlinks pipx expects to have.
61
+ rm /opt/pipx/venvs/poetry/bin/python
62
+ cd /opt/pipx/venvs/poetry/bin
63
+ ln -s "$(which "python$PYTHON_VERSION")" python
64
+ chmod +x python
65
+ cd /opt/pipx_bin/
66
+ ln -s /opt/pipx/venvs/poetry/bin/poetry poetry
67
+ chmod +x poetry
68
+
69
+ # Ensure everything got set up correctly.
70
+ /opt/pipx/venvs/poetry/bin/python --version
71
+ /opt/pipx_bin/poetry --version
72
+
73
+ - name: Install poetry
74
+ if: steps.cache-bin-poetry.outputs.cache-hit != 'true'
75
+ shell: bash
76
+ env:
77
+ POETRY_VERSION: ${{ inputs.poetry-version || env.POETRY_VERSION }}
78
+ PYTHON_VERSION: ${{ inputs.python-version }}
79
+ # Install poetry using the python version installed by setup-python step.
80
+ run: |
81
+ pipx install "poetry==$POETRY_VERSION" --python '${{ steps.setup-python.outputs.python-path }}' --verbose
82
+ pipx ensurepath
83
+ # Ensure the poetry binary is available in the PATH.
84
+ # Test that the poetry binary is available.
85
+ poetry --version
86
+
87
+ - name: Restore pip and poetry cached dependencies
88
+ uses: actions/cache@v4
89
+ env:
90
+ SEGMENT_DOWNLOAD_TIMEOUT_MIN: "4"
91
+ WORKDIR: ${{ inputs.working-directory == '' && '.' || inputs.working-directory }}
92
+ with:
93
+ path: |
94
+ ~/.cache/pip
95
+ ~/.cache/pypoetry/virtualenvs
96
+ ~/.cache/pypoetry/cache
97
+ ~/.cache/pypoetry/artifacts
98
+ ${{ env.WORKDIR }}/.venv
99
+ key: py-deps-${{ runner.os }}-${{ runner.arch }}-py-${{ inputs.python-version }}-poetry-${{ inputs.poetry-version }}-${{ inputs.cache-key }}-${{ hashFiles(format('{0}/**/poetry.lock', env.WORKDIR)) }}
.github/actions/setup-uv/action.yml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "Setup uv"
2
+ description: "Checks out code, installs uv, and sets up Python environment"
3
+
4
+ runs:
5
+ using: "composite"
6
+ steps:
7
+ - name: Install uv
8
+ uses: astral-sh/setup-uv@v3
9
+ with:
10
+ enable-cache: true
11
+ cache-dependency-glob: "uv.lock"
12
+
13
+ - name: "Set up Python"
14
+ uses: actions/setup-python@v5
15
+ with:
16
+ python-version-file: "pyproject.toml"
17
+
18
+ - name: Restore uv cache
19
+ uses: actions/cache@v4
20
+ with:
21
+ path: /tmp/.uv-cache
22
+ key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
23
+ restore-keys: |
24
+ uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
25
+ uv-${{ runner.os }}
.github/changes-filter.yaml ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # https://github.com/dorny/paths-filter
2
+ python:
3
+ - "src/backend/**"
4
+ - "src/backend/**.py"
5
+ - "pyproject.toml"
6
+ - "poetry.lock"
7
+ - "**/python_test.yml"
8
+ components-changes:
9
+ - "src/backend/base/langflow/components/**"
10
+ starter-projects-changes:
11
+ - "src/backend/base/langflow/initial_setup/**"
12
+ frontend-tests:
13
+ - "src/frontend/tests/**"
14
+ frontend:
15
+ - "src/frontend/**"
16
+ - "**/typescript_test.yml"
17
+ docs:
18
+ - "docs/**"
19
+
20
+ # Test categories and their associated paths
21
+ starter-projects:
22
+ - "src/backend/base/langflow/initial_setup/**"
23
+ - "src/backend/base/langflow/components/**"
24
+ - "src/frontend/src/pages/MainPage/**"
25
+ - "src/frontend/src/utils/reactflowUtils.ts"
26
+ - "src/frontend/tests/extended/features/**"
27
+
28
+ components:
29
+ - "src/frontend/src/components/**"
30
+ - "src/frontend/src/modals/**"
31
+ - "src/frontend/src/pages/FlowPage/**"
32
+ - "src/frontend/src/shared/**"
33
+ - "src/frontend/src/hooks/**"
34
+ - "src/frontend/src/CustomNodes/**"
35
+ - "src/frontend/src/style/**"
36
+ - "src/frontend/src/utils/styleUtils.ts"
37
+ - "src/backend/base/langflow/components/**"
38
+ - "src/frontend/tests/core/features/**"
39
+ - "src/frontend/tests/core/integrations/**"
40
+ - "src/frontend/tests/core/regression/**"
41
+ - "src/frontend/tests/extended/integrations/**"
42
+ - "src/frontend/tests/extended/features/**"
43
+ - "src/frontend/tests/extended/regression/**"
44
+
45
+ workspace:
46
+ - "src/backend/base/langflow/inputs/**"
47
+ - "src/frontend/src/components/core/parameterRenderComponent/**"
48
+ - "src/frontend/src/CustomNodes/**"
49
+ - "src/frontend/src/modals/**"
50
+ - "src/frontend/src/style/**"
51
+ - "src/frontend/src/CustomEdges/**"
52
+ - "src/frontend/src/utils/reactflowUtils.ts"
53
+ - "src/frontend/src/utils/buildUtils.ts"
54
+ - "src/frontend/tests/core/features/**"
55
+ - "src/frontend/tests/core/unit/**"
56
+ - "src/frontend/tests/extended/features/**"
57
+ - "src/frontend/tests/core/regression/**"
58
+
59
+ api:
60
+ - "src/backend/base/langflow/api/**"
61
+ - "src/frontend/src/controllers/**"
62
+ - "src/frontend/tests/core/features/**"
63
+ - "src/frontend/tests/extended/features/**"
64
+ - "src/frontend/tests/extended/regression/**"
65
+
66
+ database:
67
+ - "src/backend/base/langflow/services/database/**"
68
+ - "src/backend/base/langflow/alembic/**"
69
+ - "src/frontend/src/controllers/**"
70
+ - "src/frontend/tests/core/features/**"
71
+ - "src/frontend/tests/extended/features/**"
.github/dependabot.yml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Set update schedule for GitHub Actions
2
+
3
+ version: 2
4
+ updates:
5
+ - package-ecosystem: "github-actions"
6
+ directory: "/"
7
+ schedule:
8
+ interval: "monthly"
9
+ commit-message:
10
+ prefix: "build(deps):"
11
+ include: scope
.github/release.yml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ changelog:
2
+ categories:
3
+ - title: 🚨 Breaking Changes
4
+ description: Changes that break existing functionality
5
+ labels:
6
+ - breaking
7
+ - title: ✨ New Features
8
+ description: New features and enhancements
9
+ labels:
10
+ - enhancement
11
+ - title: 🐛 Bug Fixes
12
+ description: Bug fixes and patches
13
+ labels:
14
+ - fix
15
+ - bug
16
+ - title: 📝 Documentation Updates
17
+ description: Changes to documentation
18
+ labels:
19
+ - documentation
20
+ - title: 🛠 Maintenance Tasks
21
+ description: Maintenance tasks and housekeeping
22
+ labels:
23
+ - chore
24
+ - refactor
25
+ - style
26
+ - performance
27
+ - build
28
+ - title: ✅ Tests
29
+ description: Changes to tests
30
+ labels:
31
+ - test
32
+ - title: Others
33
+ description: Other changes
34
+ labels:
35
+ - "*"
.github/semantic.yml ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ titleOnly: true
2
+ targetUrl: https://www.conventionalcommits.org/en/v1.0.0/#summary
.github/workflows/auto-update.yml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Auto-update
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ Auto:
10
+ name: Auto-update
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: tibdex/auto-update@v2
.github/workflows/ci.yml ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: CI
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ python-versions:
7
+ description: "Python Versions"
8
+ required: false
9
+ type: string
10
+ default: "['3.10']"
11
+ frontend-tests-folder:
12
+ description: "Frontend Tests Folder"
13
+ required: false
14
+ type: string
15
+ default: "tests/core"
16
+ release:
17
+ description: "Release"
18
+ required: false
19
+ type: boolean
20
+ default: false
21
+ workflow_dispatch:
22
+ inputs:
23
+ branch:
24
+ description: "(Optional) Branch to checkout"
25
+ required: false
26
+ type: string
27
+ openai_api_key:
28
+ description: "OpenAI API Key"
29
+ required: false
30
+ type: string
31
+ store_api_key:
32
+ description: "Store API Key"
33
+ required: false
34
+ type: string
35
+ python-versions:
36
+ description: "Python Versions"
37
+ required: false
38
+ type: string
39
+ default: "['3.10']"
40
+ pull_request:
41
+ types: [synchronize, labeled]
42
+
43
+ concurrency:
44
+ group: ${{ github.workflow }}-${{ github.ref }}
45
+ cancel-in-progress: true
46
+
47
+ jobs:
48
+ set-ci-condition:
49
+ name: Should Run CI
50
+ runs-on: ubuntu-latest
51
+ outputs:
52
+ should-run-ci: ${{ (contains( github.event.pull_request.labels.*.name, 'lgtm') && github.event.pull_request.draft == false) || (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') }}
53
+ steps:
54
+ # Do anything just to make the job run
55
+ - run: echo "Debug CI Condition"
56
+ - run: echo "Labels -> ${{ join(github.event.pull_request.labels.*.name, ',') }}"
57
+ - run: echo "IsDraft -> ${{ github.event.pull_request.draft }}"
58
+ - run: echo "Event name -> ${{ github.event_name }}"
59
+ path-filter:
60
+ needs: set-ci-condition
61
+ if: ${{ needs.set-ci-condition.outputs.should-run-ci == 'true' }}
62
+ name: Filter Paths
63
+ runs-on: ubuntu-latest
64
+ outputs:
65
+ python: ${{ steps.filter.outputs.python }}
66
+ frontend: ${{ steps.filter.outputs.frontend }}
67
+ docs: ${{ steps.filter.outputs.docs }}
68
+ frontend-tests: ${{ steps.filter.outputs.frontend-tests }}
69
+ components-changes: ${{ steps.filter.outputs.components-changes }}
70
+ starter-projects-changes: ${{ steps.filter.outputs.starter-projects-changes }}
71
+ steps:
72
+ - name: Checkout code
73
+ uses: actions/checkout@v4
74
+ with:
75
+ ref: ${{ inputs.branch || github.ref }}
76
+ - name: Filter Paths
77
+ id: filter
78
+ uses: dorny/paths-filter@v3
79
+ with:
80
+ filters: ./.github/changes-filter.yaml
81
+
82
+ test-backend:
83
+ needs: path-filter
84
+ name: Run Backend Tests
85
+ if: ${{ needs.path-filter.outputs.python == 'true'}}
86
+ uses: ./.github/workflows/python_test.yml
87
+ with:
88
+ python-versions: ${{ inputs.python-versions || '["3.10"]' }}
89
+
90
+ test-frontend:
91
+ needs: path-filter
92
+ name: Run Frontend Tests
93
+ if: ${{ needs.path-filter.outputs.frontend == 'true' || needs.path-filter.outputs.frontend-tests == 'true' || needs.path-filter.outputs.components-changes == 'true' || needs.path-filter.outputs.starter-projects-changes == 'true' }}
94
+ uses: ./.github/workflows/typescript_test.yml
95
+ with:
96
+ tests_folder: ${{ inputs.frontend-tests-folder }}
97
+ release: ${{ inputs.release || false }}
98
+ secrets:
99
+ OPENAI_API_KEY: "${{ secrets.OPENAI_API_KEY }}"
100
+ STORE_API_KEY: "${{ secrets.STORE_API_KEY }}"
101
+ ANTHROPIC_API_KEY: "${{ secrets.ANTHROPIC_API_KEY }}"
102
+ TAVILY_API_KEY: "${{ secrets.TAVILY_API_KEY }}"
103
+
104
+ lint-backend:
105
+ needs: path-filter
106
+ if: ${{ needs.path-filter.outputs.python == 'true'}}
107
+ name: Lint Backend
108
+ uses: ./.github/workflows/lint-py.yml
109
+
110
+ test-docs-build:
111
+ needs: path-filter
112
+ if: ${{ needs.path-filter.outputs.docs == 'true' }}
113
+ name: Test Docs Build
114
+ uses: ./.github/workflows/docs_test.yml
115
+
116
+ # https://github.com/langchain-ai/langchain/blob/master/.github/workflows/check_diffs.yml
117
+ ci_success:
118
+ name: "CI Success"
119
+ needs:
120
+ [
121
+ test-backend,
122
+ test-frontend,
123
+ lint-backend,
124
+ test-docs-build,
125
+ set-ci-condition,
126
+ ]
127
+
128
+ if: always()
129
+ runs-on: ubuntu-latest
130
+ env:
131
+ JOBS_JSON: ${{ toJSON(needs) }}
132
+ RESULTS_JSON: ${{ toJSON(needs.*.result) }}
133
+ EXIT_CODE: ${{!contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && needs.set-ci-condition.outputs.should-run-ci == 'true' && '0' || '1'}}
134
+ steps:
135
+ - name: "CI Success"
136
+ run: |
137
+ echo $JOBS_JSON
138
+ echo $RESULTS_JSON
139
+ echo "Exiting with $EXIT_CODE"
140
+ exit $EXIT_CODE
.github/workflows/codeql.yml ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: "CodeQL"
2
+
3
+ on:
4
+ push:
5
+ branches: [ 'dev', 'main' ]
6
+ pull_request:
7
+ # The branches below must be a subset of the branches above
8
+ branches: [ 'dev' ]
9
+ schedule:
10
+ - cron: '17 2 * * 1'
11
+
12
+ jobs:
13
+ analyze:
14
+ name: Analyze
15
+ runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
16
+ timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
17
+ permissions:
18
+ actions: read
19
+ contents: read
20
+ security-events: write
21
+
22
+ strategy:
23
+ fail-fast: false
24
+ matrix:
25
+ language: [ 'python', 'javascript' ]
26
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
27
+ # Use only 'java' to analyze code written in Java, Kotlin or both
28
+ # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
29
+ # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
30
+
31
+ steps:
32
+ - name: Checkout repository
33
+ uses: actions/checkout@v4
34
+
35
+ # Initializes the CodeQL tools for scanning.
36
+ - name: Initialize CodeQL
37
+ uses: github/codeql-action/init@v3
38
+ with:
39
+ languages: ${{ matrix.language }}
40
+ # If you wish to specify custom queries, you can do so here or in a config file.
41
+ # By default, queries listed here will override any specified in a config file.
42
+ # Prefix the list here with "+" to use these queries and those in the config file.
43
+
44
+ # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
45
+ # queries: security-extended,security-and-quality
46
+
47
+
48
+ # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
49
+ # If this step fails, then you should remove it and run the build manually (see below)
50
+ - name: Autobuild
51
+ uses: github/codeql-action/autobuild@v3
52
+
53
+ # ℹ️ Command-line programs to run using the OS shell.
54
+ # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
55
+
56
+ # If the Autobuild fails above, remove it and uncomment the following three lines.
57
+ # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
58
+
59
+ # - run: |
60
+ # echo "Run, Build Application using script"
61
+ # ./location_of_script_within_repo/buildscript.sh
62
+
63
+ - name: Perform CodeQL Analysis
64
+ uses: github/codeql-action/analyze@v3
65
+ with:
66
+ category: "/language:${{matrix.language}}"
.github/workflows/codspeed.yml ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Run benchmarks
2
+
3
+ on:
4
+ push:
5
+ paths:
6
+ - "src/backend/base/**"
7
+ - "src/backend/tests/performance/**"
8
+ branches:
9
+ - "main" # or "master"
10
+ pull_request:
11
+ paths:
12
+ - "src/backend/base/**"
13
+ - "src/backend/tests/performance/**"
14
+ - "!src/backend/base/langflow/components/**"
15
+ workflow_dispatch:
16
+
17
+ concurrency:
18
+ group: ${{ github.workflow }}-${{ github.ref }}
19
+ cancel-in-progress: true
20
+
21
+ jobs:
22
+ codspeed:
23
+ name: Run benchmarks
24
+ runs-on: ubuntu-latest
25
+ strategy:
26
+ matrix:
27
+ python-version:
28
+ - "3.12"
29
+ steps:
30
+ - name: Check out the code at a specific ref
31
+ uses: actions/checkout@v4
32
+ - name: "Setup Environment"
33
+ uses: ./.github/actions/setup-uv
34
+ - name: Run benchmarks
35
+ uses: CodSpeedHQ/action@v3
36
+ with:
37
+ token: ${{ secrets.CODSPEED_TOKEN }}
38
+ run: |
39
+ uv run pytest src/backend/tests \
40
+ --ignore=src/backend/tests/integration \
41
+ --codspeed \
42
+ -m "not api_key_required" \
43
+ -n auto
44
+ - name: Minimize uv cache
45
+ run: uv cache prune --ci
.github/workflows/conventional-labels.yml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Warning, do not check out untrusted code with
2
+ # the pull_request_target event.
3
+ name: Label PRs with Conventional Commits
4
+ on:
5
+ pull_request_target:
6
+ types: [opened, edited]
7
+
8
+ jobs:
9
+ validate-pr:
10
+ name: Validate PR
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Validate the pull request
14
+ id: validate
15
+ uses: Namchee/conventional-pr@v0.15.5
16
+ with:
17
+ access_token: ${{ secrets.GITHUB_TOKEN }}
18
+ issue: false
19
+
20
+ label:
21
+ needs: validate-pr
22
+ name: Label PR
23
+ runs-on: ubuntu-latest
24
+ if: ${{ github.event.pull_request.user.type != 'Bot'}}
25
+ steps:
26
+ - uses: bcoe/conventional-release-labels@v1
27
+ with:
28
+ type_labels: '{"feat": "enhancement","fix": "bug","docs": "documentation","style": "style","refactor": "refactor","perf": "performance","test": "test","chore": "chore","build": "build"}'
.github/workflows/create-release.yml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Create Release
2
+ on:
3
+ workflow_dispatch:
4
+ inputs:
5
+ version:
6
+ description: "Version to release"
7
+ required: true
8
+ type: string
9
+ ref:
10
+ description: "Commit to tag the release"
11
+ required: true
12
+ type: string
13
+ pre_release:
14
+ description: "Pre-release tag"
15
+ required: true
16
+ type: boolean
17
+
18
+ jobs:
19
+ create_release:
20
+ name: Create Release Job
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/download-artifact@v4
24
+ with:
25
+ name: dist-main
26
+ path: dist
27
+ - name: Create Release Notes
28
+ uses: ncipollo/release-action@v1
29
+ with:
30
+ artifacts: "dist/*"
31
+ token: ${{ secrets.GITHUB_TOKEN }}
32
+ draft: false
33
+ generateReleaseNotes: true
34
+ prerelease: ${{ inputs.pre_release }}
35
+ tag: v${{ inputs.version }}
36
+ commit: ${{ inputs.ref }}
.github/workflows/deploy_gh-pages.yml ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Deploy to GitHub Pages
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - 'docs/**'
9
+ # Review gh actions docs if you want to further define triggers, paths, etc
10
+ # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
11
+
12
+ jobs:
13
+ deploy:
14
+ name: Deploy to GitHub Pages
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: 18
21
+ cache: npm
22
+ cache-dependency-path: ./docs/package-lock.json
23
+
24
+ - name: Install dependencies
25
+ run: cd docs && npm install --legacy-peer-deps
26
+ - name: Build website
27
+ run: cd docs && npm run build
28
+
29
+ # Popular action to deploy to GitHub Pages:
30
+ # Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus
31
+ - name: Deploy to GitHub Pages
32
+ uses: peaceiris/actions-gh-pages@v4
33
+ with:
34
+ github_token: ${{ secrets.GITHUB_TOKEN }}
35
+ # Build output to publish to the `gh-pages` branch:
36
+ publish_dir: ./docs/build
37
+ # The following lines assign commit authorship to the official
38
+ # GH-Actions bot for deploys to `gh-pages` branch:
39
+ # https://github.com/actions/checkout/issues/13#issuecomment-724415212
40
+ # The GH actions bot is used by default if you didn't specify the two fields.
41
+ # You can swap them out with your own user credentials.
.github/workflows/docker-build.yml ADDED
@@ -0,0 +1,323 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Docker Build and Push
2
+ run-name: Docker Build and Push @${{ inputs.release_type }} by @${{ github.actor }}
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ main_version:
7
+ required: true
8
+ type: string
9
+ description: "Main version to tag images with. Required for both main and base releases."
10
+ base_version:
11
+ required: false
12
+ type: string
13
+ description: "Base version to tag images with. Required for base release type."
14
+ release_type:
15
+ required: true
16
+ type: string
17
+ description: "Release type. One of 'main', 'main-ep', 'base', 'nightly-main', 'nightly-base'."
18
+ pre_release:
19
+ required: false
20
+ type: boolean
21
+ default: false
22
+ ref:
23
+ required: false
24
+ type: string
25
+ description: "Ref to check out. If not specified, will default to the main version or current branch."
26
+
27
+ workflow_dispatch:
28
+ inputs:
29
+ main_version:
30
+ description: "Main version to tag images with. Required for both main and base releases."
31
+ required: false
32
+ type: string
33
+ base_version:
34
+ description: "Base version to tag images with. Required for base release type."
35
+ required: false
36
+ type: string
37
+ release_type:
38
+ description: "Type of release. One of 'main', 'main-ep', 'base', 'nightly-main', 'nightly-base'."
39
+ required: true
40
+ type: string
41
+ pre_release:
42
+ required: false
43
+ type: boolean
44
+ default: false
45
+ ref:
46
+ required: false
47
+ type: string
48
+ description: "Ref to check out. If not specified, will default to the main version or current branch."
49
+
50
+
51
+ env:
52
+ POETRY_VERSION: "1.8.2"
53
+ TEST_TAG: "langflowai/langflow:test"
54
+
55
+ jobs:
56
+ get-version:
57
+ name: Get Version
58
+ runs-on: ubuntu-latest
59
+ outputs:
60
+ version: ${{ steps.get-version-input.outputs.version || steps.get-version-base.outputs.version || steps.get-version-main.outputs.version }}
61
+ steps:
62
+ - name: Verify a main version exists
63
+ if: ${{ inputs.main_version == '' }}
64
+ run: |
65
+ # due to our how we split packages, we need to have a main version to check out.
66
+ echo "Must specify a main version to check out."
67
+ exit 1
68
+
69
+ - name: Check out the code at a specific ref
70
+ uses: actions/checkout@v4
71
+ with:
72
+ ref: ${{ inputs.ref || inputs.main_version || github.ref }}
73
+ persist-credentials: true
74
+
75
+ - name: Get Version to Tag
76
+ if: ${{ inputs.main_version != '' }}
77
+ id: get-version-input
78
+ run: |
79
+ # Produces the versions we will use to tag the docker images with.
80
+
81
+ if [[ "${{ inputs.release_type }}" == "base" && "${{ inputs.base_version }}" == '' ]]; then
82
+ echo "Must specify a base version for base release type."
83
+ exit 1
84
+ fi
85
+
86
+ if [[ "${{ inputs.release_type }}" == "nightly-base" && "${{ inputs.base_version }}" == '' ]]; then
87
+ echo "Must specify a base version for nightly-base release type."
88
+ exit 1
89
+ fi
90
+
91
+ if [[ "${{ inputs.release_type }}" == "main" && "${{ inputs.main_version }}" == '' ]]; then
92
+ echo "Must specify a main version for main release type."
93
+ exit 1
94
+ fi
95
+
96
+ if [[ "${{ inputs.release_type }}" == "main-ep" && "${{ inputs.main_version }}" == '' ]]; then
97
+ echo "Must specify a main version for main-ep release type."
98
+ exit 1
99
+ fi
100
+
101
+ if [[ "${{ inputs.release_type }}" == "nightly-main" && "${{ inputs.main_version }}" == '' ]]; then
102
+ echo "Must specify a main version for nightly-main release type."
103
+ exit 1
104
+ fi
105
+
106
+ if [[ "${{ inputs.release_type }}" == "base" || "${{ inputs.release_type }}" == "nightly-base" ]]; then
107
+ version=${{ inputs.base_version }}
108
+ echo "base version=${{ inputs.base_version }}"
109
+ echo version=$version
110
+ echo version=$version >> $GITHUB_OUTPUT
111
+ elif [[ "${{ inputs.release_type }}" == "main" || "${{ inputs.release_type }}" == "main-ep" || "${{ inputs.release_type }}" == "nightly-main" ]]; then
112
+ version=${{ inputs.main_version }}
113
+ echo version=$version
114
+ echo version=$version >> $GITHUB_OUTPUT
115
+ else
116
+ echo "No version or ref specified. Exiting the workflow."
117
+ exit 1
118
+ fi
119
+ - name: Get Version Base
120
+ if: ${{ inputs.base_version == '' && (inputs.release_type == 'base' || inputs.release_type == 'nightly-base') }}
121
+ id: get-version-base
122
+ run: |
123
+ version=$(uv tree | grep 'langflow-base' | awk '{print $3}' | sed 's/^v//')
124
+ if [ -z "$version" ]; then
125
+ echo "Failed to extract version from uv tree output"
126
+ exit 1
127
+ fi
128
+ echo version=$version
129
+ echo version=$version >> $GITHUB_OUTPUT
130
+ - name: Get Version Main
131
+ if: ${{ inputs.main_version == '' && (inputs.release_type == 'main' || inputs.release_type == 'main-ep' || inputs.release_type == 'nightly-main') }}
132
+ id: get-version-main
133
+ run: |
134
+ version=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | awk '{print $2}' | sed 's/^v//')
135
+ echo version=$version
136
+ echo version=$version >> $GITHUB_OUTPUT
137
+ setup:
138
+ runs-on: ubuntu-latest
139
+ needs: get-version
140
+ outputs:
141
+ docker_tags: ${{ steps.set-vars.outputs.docker_tags }}
142
+ ghcr_tags: ${{ steps.set-vars.outputs.ghcr_tags }}
143
+ file: ${{ steps.set-vars.outputs.file }}
144
+ steps:
145
+ - name: Set Dockerfile and Tags
146
+ id: set-vars
147
+ run: |
148
+ nightly_suffix=''
149
+ if [[ "${{ inputs.release_type }}" == "nightly-base" || "${{ inputs.release_type }}" == "nightly-main" ]]; then
150
+ nightly_suffix="-nightly"
151
+ fi
152
+
153
+ if [[ "${{ inputs.release_type }}" == "base" || "${{ inputs.release_type }}" == "nightly-base" ]]; then
154
+ # LANGFLOW-BASE RELEASE
155
+ echo "docker_tags=langflowai/langflow${nightly_suffix}:base-${{ needs.get-version.outputs.version }},langflowai/langflow${nightly_suffix}:base-latest" >> $GITHUB_OUTPUT
156
+ echo "ghcr_tags=ghcr.io/langflow-ai/langflow${nightly_suffix}:base-${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow${nightly_suffix}:base-latest" >> $GITHUB_OUTPUT
157
+ echo "file=./docker/build_and_push_base.Dockerfile" >> $GITHUB_OUTPUT
158
+ else
159
+ if [[ "${{ inputs.pre_release }}" == "true" ]]; then
160
+ # LANGFLOW-MAIN PRE-RELEASE
161
+ echo "docker_tags=langflowai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }}" >> $GITHUB_OUTPUT
162
+ echo "ghcr_tags=ghcr.io/langflow-ai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }}" >> $GITHUB_OUTPUT
163
+ echo "file=./docker/build_and_push.Dockerfile" >> $GITHUB_OUTPUT
164
+ elif [[ "${{ inputs.release_type }}" == "main-ep" ]]; then
165
+ # LANGFLOW-MAIN (ENTRYPOINT) RELEASE
166
+ echo "docker_tags=langflowai/langflow-ep${nightly_suffix}:${{ needs.get-version.outputs.version }},langflowai/langflow-ep${nightly_suffix}:latest" >> $GITHUB_OUTPUT
167
+ echo "ghcr_tags=ghcr.io/langflow-ai/langflow-ep${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow-ep${nightly_suffix}:latest" >> $GITHUB_OUTPUT
168
+ echo "file=./docker/build_and_push_ep.Dockerfile" >> $GITHUB_OUTPUT
169
+ elif [[ "${{ inputs.release_type }}" == "main" || "${{ inputs.release_type }}" == "nightly-main" ]]; then
170
+ # LANGFLOW-MAIN RELEASE
171
+ echo "docker_tags=langflowai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }},langflowai/langflow${nightly_suffix}:latest" >> $GITHUB_OUTPUT
172
+ echo "ghcr_tags=ghcr.io/langflow-ai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow${nightly_suffix}:latest" >> $GITHUB_OUTPUT
173
+ echo "file=./docker/build_and_push.Dockerfile" >> $GITHUB_OUTPUT
174
+ else
175
+ echo "Invalid release type. Exiting the workflow."
176
+ exit 1
177
+ fi
178
+ fi
179
+ build:
180
+ runs-on: ubuntu-latest
181
+ needs: [get-version, setup]
182
+ steps:
183
+ - name: Check out the code at a specific ref
184
+ uses: actions/checkout@v4
185
+ with:
186
+ ref: ${{ inputs.ref || inputs.main_version || github.ref }}
187
+ persist-credentials: true
188
+ - name: "Setup Environment"
189
+ uses: ./.github/actions/setup-uv
190
+ - name: Install the project
191
+ run: |
192
+ if [[ "${{ inputs.release_type }}" == "base" || "${{ inputs.release_type }}" == "nightly-base" ]]; then
193
+ uv sync --directory src/backend/base --no-dev --no-sources
194
+ else
195
+ uv sync --no-dev --no-sources
196
+ fi
197
+
198
+ - name: Set up Docker Buildx
199
+ uses: docker/setup-buildx-action@v3
200
+
201
+ - name: Login to Docker Hub
202
+ uses: docker/login-action@v3
203
+ with:
204
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
205
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
206
+
207
+ - name: Build and Push to Docker Hub
208
+ uses: docker/build-push-action@v6
209
+ with:
210
+ context: .
211
+ push: true
212
+ file: ${{ needs.setup.outputs.file }}
213
+ tags: ${{ needs.setup.outputs.docker_tags }}
214
+ platforms: linux/amd64,linux/arm64
215
+ cache-from: type=gha
216
+ cache-to: type=gha,mode=max
217
+
218
+ - name: Login to Github Container Registry
219
+ uses: docker/login-action@v3
220
+ with:
221
+ registry: ghcr.io
222
+ username: ${{ github.actor }}
223
+ password: ${{ secrets.TEMP_GHCR_TOKEN}}
224
+
225
+ - name: Build and push to Github Container Registry
226
+ uses: docker/build-push-action@v6
227
+ with:
228
+ context: .
229
+ push: true
230
+ file: ${{ needs.setup.outputs.file }}
231
+ tags: ${{ needs.setup.outputs.ghcr_tags }}
232
+ platforms: linux/amd64,linux/arm64
233
+ cache-from: type=gha
234
+ cache-to: type=gha,mode=max
235
+
236
+ build_components:
237
+ if: ${{ inputs.release_type == 'main' }}
238
+ runs-on: ubuntu-latest
239
+ permissions:
240
+ packages: write
241
+ needs: [build, get-version]
242
+ strategy:
243
+ matrix:
244
+ component: [docker-backend, docker-frontend, ghcr-backend, ghcr-frontend]
245
+ include:
246
+ - component: docker-backend
247
+ dockerfile: ./docker/build_and_push_backend.Dockerfile
248
+ tags: langflowai/langflow-backend:${{ needs.get-version.outputs.version }},langflowai/langflow-backend:latest
249
+ langflow_image: langflowai/langflow:${{ needs.get-version.outputs.version }}
250
+ - component: docker-frontend
251
+ dockerfile: ./docker/frontend/build_and_push_frontend.Dockerfile
252
+ tags: langflowai/langflow-frontend:${{ needs.get-version.outputs.version }},langflowai/langflow-frontend:latest
253
+ langflow_image: langflowai/langflow:${{ needs.get-version.outputs.version }}
254
+ - component: ghcr-backend
255
+ dockerfile: ./docker/build_and_push_backend.Dockerfile
256
+ tags: ghcr.io/langflow-ai/langflow-backend:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow-backend:latest
257
+ langflow_image: ghcr.io/langflow-ai/langflow:${{ needs.get-version.outputs.version }}
258
+ - component: ghcr-frontend
259
+ dockerfile: ./docker/frontend/build_and_push_frontend.Dockerfile
260
+ tags: ghcr.io/langflow-ai/langflow-frontend:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow-frontend:latest
261
+ langflow_image: ghcr.io/langflow-ai/langflow:${{ needs.get-version.outputs.version }}
262
+ steps:
263
+ - name: Check out the code at a specific ref
264
+ uses: actions/checkout@v4
265
+ with:
266
+ ref: ${{ inputs.ref || inputs.main_version || github.ref }}
267
+
268
+ - name: Set up Docker Buildx
269
+ uses: docker/setup-buildx-action@v3
270
+
271
+ - name: Login to Docker Hub
272
+ if: ${{ matrix.component == 'docker-backend' }} || ${{ matrix.component == 'docker-frontend' }}
273
+ uses: docker/login-action@v3
274
+ with:
275
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
276
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
277
+
278
+ - name: Login to Github Container Registry
279
+ if: ${{ matrix.component == 'ghcr-backend' }} || ${{ matrix.component == 'ghcr-frontend' }}
280
+ uses: docker/login-action@v3
281
+ with:
282
+ registry: ghcr.io
283
+ username: ${{ github.actor }}
284
+ password: ${{ secrets.TEMP_GHCR_TOKEN}}
285
+
286
+ - name: Wait for propagation (for backend)
287
+ run: sleep 120
288
+
289
+ - name: Build and push ${{ matrix.component }}
290
+ uses: docker/build-push-action@v6
291
+ with:
292
+ context: .
293
+ push: true
294
+ build-args: |
295
+ LANGFLOW_IMAGE=${{ matrix.langflow_image }}
296
+ file: ${{ matrix.dockerfile }}
297
+ tags: ${{ matrix.tags }}
298
+ # provenance: false will result in a single manifest for all platforms which makes the image pullable from arm64 machines via the emulation (e.g. Apple Silicon machines)
299
+ provenance: false
300
+
301
+ restart-space:
302
+ name: Restart HuggingFace Spaces
303
+ if: ${{ inputs.release_type == 'main' }}
304
+ runs-on: ubuntu-latest
305
+ needs: [build, get-version]
306
+ strategy:
307
+ matrix:
308
+ python-version:
309
+ - "3.12"
310
+ steps:
311
+ - name: Check out the code at a specific ref
312
+ uses: actions/checkout@v4
313
+ with:
314
+ ref: ${{ inputs.ref || inputs.main_version || github.ref }}
315
+ - name: "Setup Environment"
316
+ uses: ./.github/actions/setup-uv
317
+
318
+ - name: Restart HuggingFace Spaces Build
319
+ run: |
320
+ uv run ./scripts/factory_restart_space.py --space "Langflow/Langflow" --token ${{ secrets.HUGGINGFACE_API_TOKEN }}
321
+
322
+
323
+
.github/workflows/docker_test.yml ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Test Docker images
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - "docker/**"
8
+ - "poetry.lock"
9
+ - "pyproject.toml"
10
+ - "src/backend/**"
11
+ - ".github/workflows/docker_test.yml"
12
+ pull_request:
13
+ branches: [dev]
14
+ paths:
15
+ - "docker/**"
16
+ - "poetry.lock"
17
+ - "pyproject.toml"
18
+ - "src/**"
19
+ - ".github/workflows/docker_test.yml"
20
+
21
+ env:
22
+ POETRY_VERSION: "1.8.2"
23
+
24
+ jobs:
25
+ test-docker:
26
+ runs-on: ubuntu-latest
27
+ name: Test docker images
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ - name: Build image
31
+ run: |
32
+ docker build -t langflowai/langflow:latest-dev \
33
+ -f docker/build_and_push.Dockerfile \
34
+ .
35
+ - name: Test image
36
+ run: |
37
+ expected_version=$(cat pyproject.toml | grep version | head -n 1 | cut -d '"' -f 2)
38
+ version=$(docker run --rm --entrypoint bash langflowai/langflow:latest-dev -c "python -c 'from langflow.utils.version import get_version_info; print(get_version_info()[\"version\"])'")
39
+ if [ "$expected_version" != "$version" ]; then
40
+ echo "Expected version: $expected_version"
41
+ echo "Actual version: $version"
42
+ exit 1
43
+ fi
44
+
45
+ - name: Build backend image
46
+ run: |
47
+ docker build -t langflowai/langflow-backend:latest-dev \
48
+ --build-arg LANGFLOW_IMAGE=langflowai/langflow:latest-dev \
49
+ -f docker/build_and_push_backend.Dockerfile \
50
+ .
51
+ - name: Test backend image
52
+ run: |
53
+ expected_version=$(cat pyproject.toml | grep version | head -n 1 | cut -d '"' -f 2)
54
+ version=$(docker run --rm --entrypoint bash langflowai/langflow-backend:latest-dev -c "python -c 'from langflow.utils.version import get_version_info; print(get_version_info()[\"version\"])'")
55
+ if [ "$expected_version" != "$version" ]; then
56
+ echo "Expected version: $expected_version"
57
+ echo "Actual version: $version"
58
+ exit 1
59
+ fi
60
+ - name: Build frontend image
61
+ run: |
62
+ docker build -t langflowai/langflow-frontend:latest-dev \
63
+ -f docker/frontend/build_and_push_frontend.Dockerfile \
64
+ .
.github/workflows/docs_test.yml ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Test Docs Build
2
+
3
+ on:
4
+ workflow_call:
5
+ workflow_dispatch:
6
+ inputs:
7
+ branch:
8
+ description: "(Optional) Branch to checkout"
9
+ required: false
10
+ type: string
11
+
12
+ env:
13
+ NODE_VERSION: "21"
14
+
15
+ jobs:
16
+ test-docs-build:
17
+ name: Test Docs Build
18
+ runs-on: ubuntu-latest
19
+
20
+ steps:
21
+ - name: Checkout code
22
+ uses: actions/checkout@v4
23
+ with:
24
+ ref: ${{ inputs.branch || github.ref }}
25
+ - name: Setup Node.js
26
+ uses: actions/setup-node@v4
27
+ id: setup-node
28
+ with:
29
+ node-version: ${{ env.NODE_VERSION }}
30
+
31
+ - name: Cache Node.js dependencies
32
+ uses: actions/cache@v4
33
+ id: npm-cache
34
+ with:
35
+ path: ~/.npm
36
+ key: ${{ runner.os }}-node-${{ hashFiles('docs/package-lock.json') }}
37
+ restore-keys: |
38
+ ${{ runner.os }}-node-
39
+
40
+ - name: Install Node.js dependencies
41
+ run: |
42
+ cd docs
43
+ npm install --legacy-peer-deps
44
+ if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
45
+
46
+ - name: Build Docs
47
+ run: |
48
+ cd docs
49
+ npm run build
.github/workflows/fetch_docs_notion.yml ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Fetch Docs from Notion
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ env:
7
+ NODE_VERSION: "21"
8
+
9
+ jobs:
10
+ fetch-docs:
11
+ name: Fetch Docs from Notion
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - name: Get current date
16
+ id: date
17
+ run: echo "DATE=$(date +'%Y%m%d%H%M%S')" >> "$GITHUB_OUTPUT"
18
+
19
+ - name: Checkout code
20
+ uses: actions/checkout@v4
21
+
22
+ - name: Setup Node.js
23
+ uses: actions/setup-node@v4
24
+ id: setup-node
25
+ with:
26
+ node-version: ${{ env.NODE_VERSION }}
27
+
28
+ - name: Cache Node.js dependencies
29
+ uses: actions/cache@v4
30
+ id: npm-cache
31
+ with:
32
+ path: ~/.npm
33
+ key: ${{ runner.os }}-node-${{ hashFiles('docs/package-lock.json') }}
34
+ restore-keys: |
35
+ ${{ runner.os }}-node-
36
+
37
+ - name: Install Node.js dependencies
38
+ run: |
39
+ cd docs
40
+ npm install --legacy-peer-deps
41
+ if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
42
+
43
+ - name: Fetch Docs from Notion
44
+ run: |
45
+ cd docs
46
+ npm run pull
47
+ env:
48
+ NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
49
+ NOTION_DOCS_ROOT_PAGE_ID: ${{ secrets.NOTION_DOCS_ROOT_PAGE_ID }}
50
+
51
+ - name: Create Pull Request
52
+ id: create_pr
53
+ uses: peter-evans/create-pull-request@v7
54
+ with:
55
+ token: ${{ secrets.GITHUB_TOKEN }}
56
+ commit-message: Update docs from Notion
57
+ branch: update-docs-${{ steps.date.outputs.DATE }}
58
+ base: main
59
+ title: "docs: update docs from notion"
60
+ body: This PR updates the documentation from Notion.
61
+ labels: documentation
.github/workflows/integration_tests.yml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Integration Tests
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ ref:
7
+ description: "(Optional) ref to checkout"
8
+ required: false
9
+ type: string
10
+ workflow_call:
11
+ inputs:
12
+ python-versions:
13
+ description: "(Optional) Python versions to test"
14
+ required: true
15
+ type: string
16
+ default: "['3.10', '3.11', '3.12']"
17
+ ref:
18
+ description: "(Optional) ref to checkout"
19
+ required: false
20
+ type: string
21
+
22
+ env:
23
+ POETRY_VERSION: "1.8.2"
24
+
25
+ jobs:
26
+ integration-tests:
27
+ name: Run Integration Tests
28
+ runs-on: ubuntu-latest
29
+ strategy:
30
+ max-parallel: 1 # Currently, we can only run at a time for collection-per-db-constraints
31
+ matrix:
32
+ python-version:
33
+ - "3.12"
34
+ - "3.11"
35
+ - "3.10"
36
+ env:
37
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
38
+ ASTRA_DB_API_ENDPOINT: ${{ secrets.ASTRA_DB_API_ENDPOINT }}
39
+ ASTRA_DB_APPLICATION_TOKEN: ${{ secrets.ASTRA_DB_APPLICATION_TOKEN }}
40
+ steps:
41
+ - name: Checkout code
42
+ uses: actions/checkout@v4
43
+ with:
44
+ ref: ${{ inputs.ref || github.ref }}
45
+ - name: "Setup Environment"
46
+ uses: ./.github/actions/setup-uv
47
+ - name: Run integration tests with api keys
48
+ timeout-minutes: 20
49
+ run: |
50
+ make integration_tests_api_keys
.github/workflows/js_autofix.yml ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: autofix.ci
2
+
3
+ on:
4
+ pull_request:
5
+ paths:
6
+ - "src/frontend/**"
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ env:
12
+ NODE_VERSION: "21"
13
+ jobs:
14
+ autofix:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Setup Node.js
21
+ uses: actions/setup-node@v4
22
+ id: setup-node
23
+ with:
24
+ node-version: ${{ env.NODE_VERSION }}
25
+
26
+ - name: Cache Node.js dependencies
27
+ uses: actions/cache@v4
28
+ id: npm-cache
29
+ with:
30
+ path: ~/.npm
31
+ key: ${{ runner.os }}-node-${{ hashFiles('src/frontend/package-lock.json') }}
32
+ restore-keys: |
33
+ ${{ runner.os }}-node-
34
+
35
+ - name: Install Node.js dependencies
36
+ run: |
37
+ cd src/frontend
38
+ npm ci
39
+ if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
40
+ - name: Run Prettier
41
+ run: |
42
+ cd src/frontend
43
+ npm run format
44
+
45
+ - uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c
.github/workflows/lint-js.yml ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Lint Frontend
2
+
3
+ on:
4
+ workflow_call:
5
+ workflow_dispatch:
6
+ inputs:
7
+ branch:
8
+ description: "(Optional) Branch to checkout"
9
+ required: false
10
+ type: string
11
+
12
+
13
+ env:
14
+ NODE_VERSION: "21"
15
+
16
+ jobs:
17
+ run-linters:
18
+ name: Run Prettier
19
+ runs-on: ubuntu-latest
20
+ permissions:
21
+ contents: write
22
+
23
+ steps:
24
+ - name: Checkout code
25
+ uses: actions/checkout@v4
26
+ with:
27
+ ref: ${{ inputs.branch || github.ref }}
28
+
29
+ - name: Setup Node.js
30
+ uses: actions/setup-node@v4
31
+ id: setup-node
32
+ with:
33
+ node-version: ${{ env.NODE_VERSION }}
34
+
35
+ - name: Cache Node.js dependencies
36
+ uses: actions/cache@v4
37
+ id: npm-cache
38
+ with:
39
+ path: ~/.npm
40
+ key: ${{ runner.os }}-node-${{ hashFiles('src/frontend/package-lock.json') }}
41
+ restore-keys: |
42
+ ${{ runner.os }}-node-
43
+
44
+ - name: Install Node.js dependencies
45
+ run: |
46
+ cd src/frontend
47
+ npm install
48
+ if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
49
+
50
+ - name: Run Prettier
51
+ run: |
52
+ cd src/frontend
53
+ npm run check-format
.github/workflows/lint-py.yml ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Lint Python
2
+
3
+ on:
4
+ workflow_call:
5
+ workflow_dispatch:
6
+ inputs:
7
+ branch:
8
+ description: "(Optional) Branch to checkout"
9
+ required: false
10
+ type: string
11
+ env:
12
+ POETRY_VERSION: "1.8.2"
13
+
14
+
15
+ jobs:
16
+ lint:
17
+ name: Run Mypy
18
+ runs-on: ubuntu-latest
19
+ strategy:
20
+ matrix:
21
+ python-version:
22
+ - "3.12"
23
+ - "3.11"
24
+ - "3.10"
25
+ steps:
26
+ - name: Check out the code at a specific ref
27
+ uses: actions/checkout@v4
28
+ with:
29
+ ref: ${{ inputs.branch || github.ref }}
30
+ persist-credentials: true
31
+ - name: "Setup Environment"
32
+ uses: ./.github/actions/setup-uv
33
+ - name: Install the project
34
+ run: uv sync --dev
35
+ - name: Run Mypy
36
+ run: |
37
+ uv run mypy --namespace-packages -p "langflow"
38
+ env:
39
+ GITHUB_TOKEN: ${{ secrets.github_token }}
40
+ - name: Minimize uv cache
41
+ run: uv cache prune --ci
.github/workflows/matchers/ruff.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "problemMatcher": [
3
+ {
4
+ "owner": "ruff",
5
+ "pattern": [
6
+ {
7
+ "regexp": "^(Would reformat): (.+)$",
8
+ "message": 1,
9
+ "file": 2
10
+ }
11
+ ]
12
+ }
13
+ ]
14
+ }
.github/workflows/nightly_build.yml ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Nightly Build
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ schedule:
6
+ # Run job at 6:30 UTC, 10.30pm PST, or 11.30pm PDT
7
+ - cron: "30 6 * * *"
8
+
9
+ env:
10
+ POETRY_VERSION: "1.8.3"
11
+ PYTHON_VERSION: "3.12"
12
+
13
+ jobs:
14
+ create-nightly-tag:
15
+ if: github.repository == 'langflow-ai/langflow'
16
+ runs-on: ubuntu-latest
17
+ defaults:
18
+ run:
19
+ shell: bash -ex -o pipefail {0}
20
+ permissions:
21
+ # Required to create tag
22
+ contents: write
23
+ outputs:
24
+ main_tag: ${{ steps.generate_main_tag.outputs.main_tag }}
25
+ base_tag: ${{ steps.set_base_tag.outputs.base_tag }}
26
+ steps:
27
+ - name: Checkout code
28
+ uses: actions/checkout@v4
29
+ with:
30
+ persist-credentials: true
31
+ - name: "Setup Environment"
32
+ uses: ./.github/actions/setup-uv
33
+ - name: Install the project
34
+ run: uv sync --dev
35
+
36
+ - name: Generate main nightly tag
37
+ id: generate_main_tag
38
+ run: |
39
+ # NOTE: This outputs the tag with the `v` prefix.
40
+ MAIN_TAG="$(uv run ./scripts/ci/pypi_nightly_tag.py main)"
41
+ echo "main_tag=$MAIN_TAG" >> $GITHUB_OUTPUT
42
+ echo "main_tag=$MAIN_TAG"
43
+
44
+ - name: Check if main tag already exists
45
+ id: check_main_tag
46
+ run: |
47
+ git fetch --tags
48
+ if git rev-parse -q --verify "refs/tags/${{ steps.generate_main_tag.outputs.main_tag }}" >/dev/null; then
49
+ echo "main_tag_exists=true" >> $GITHUB_OUTPUT
50
+ else
51
+ echo "main_tag_exists=false" >> $GITHUB_OUTPUT
52
+ fi
53
+
54
+ - name: Generate base nightly tag
55
+ id: generate_base_tag
56
+ if: ${{ steps.check_main_tag.outputs.main_tag_exists == 'false' }}
57
+ run: |
58
+ # NOTE: This outputs the tag with the `v` prefix.
59
+ BASE_TAG="$(uv run ./scripts/ci/pypi_nightly_tag.py base)"
60
+ echo "base_tag=$BASE_TAG" >> $GITHUB_OUTPUT
61
+ echo "base_tag=$BASE_TAG"
62
+
63
+ - name: Commit tag
64
+ id: commit_tag
65
+ if: ${{ steps.check_main_tag.outputs.main_tag_exists == 'false' }}
66
+ run: |
67
+ # If the main tag does not exist in GH, we create the base tag from the existing codebase.
68
+
69
+ git config --global user.email "bot-nightly-builds@langflow.org"
70
+ git config --global user.name "Langflow Bot"
71
+
72
+ MAIN_TAG="${{ steps.generate_main_tag.outputs.main_tag }}"
73
+ BASE_TAG="${{ steps.generate_base_tag.outputs.base_tag }}"
74
+ echo "Updating base project version to $BASE_TAG and updating main project version to $MAIN_TAG"
75
+ uv run ./scripts/ci/update_pyproject_combined.py main $MAIN_TAG $BASE_TAG
76
+
77
+ uv lock
78
+ cd src/backend/base && uv lock && cd ../../..
79
+
80
+ git add pyproject.toml src/backend/base/pyproject.toml uv.lock src/backend/base/uv.lock
81
+ git commit -m "Update version and project name"
82
+
83
+ echo "Tagging main with $MAIN_TAG"
84
+ if ! git tag -a $MAIN_TAG -m "Langflow nightly $MAIN_TAG"; then
85
+ echo "Tag creation failed. Exiting the workflow."
86
+ exit 1
87
+ fi
88
+
89
+ echo "Pushing main tag $MAIN_TAG"
90
+ if ! git push origin $MAIN_TAG; then
91
+ echo "Tag push failed. Check if the tag already exists. Exiting the workflow."
92
+ exit 1
93
+ fi
94
+ # TODO: notify on failure
95
+
96
+ - name: Checkout main nightly tag
97
+ uses: actions/checkout@v4
98
+ if: ${{ steps.check_main_tag.outputs.main_tag_exists == 'true' }}
99
+ with:
100
+ ref: ${{ steps.generate_main_tag.outputs.main_tag }}
101
+
102
+ - name: Retrieve Base Tag
103
+ id: retrieve_base_tag
104
+ if: ${{ steps.check_main_tag.outputs.main_tag_exists == 'true' }}
105
+ working-directory: src/backend/base
106
+ run: |
107
+ # If the main tag already exists, we need to retrieve the base version from the main tag codebase.
108
+ version=$(uv tree | grep 'langflow-base' | awk '{print $3}')
109
+ echo "base_tag=$version" >> $GITHUB_OUTPUT
110
+ echo "base_tag=$version"
111
+
112
+ - name: Set Base Tag
113
+ id: set_base_tag
114
+ run: |
115
+ if [ "${{ steps.retrieve_base_tag.conclusion }}" != "skipped" ] && [ "${{ steps.retrieve_base_tag.outputs.base_tag }}" ]; then
116
+ BASE_TAG="${{ steps.retrieve_base_tag.outputs.base_tag }}"
117
+ echo "base_tag=$BASE_TAG" >> $GITHUB_OUTPUT
118
+ echo "base_tag=$BASE_TAG"
119
+ elif [ "${{ steps.commit_tag.conclusion }}" != "skipped" ] && [ "${{ steps.generate_base_tag.outputs.base_tag }}" ]; then
120
+ BASE_TAG="${{ steps.generate_base_tag.outputs.base_tag }}"
121
+ echo "base_tag=$BASE_TAG" >> $GITHUB_OUTPUT
122
+ echo "base_tag=$BASE_TAG"
123
+ else
124
+ echo "No base tag found. Exiting the workflow."
125
+ exit 1
126
+ fi
127
+
128
+ frontend-tests:
129
+ if: github.repository == 'langflow-ai/langflow'
130
+ name: Run Frontend Tests
131
+ needs: create-nightly-tag
132
+ uses: ./.github/workflows/typescript_test.yml
133
+ with:
134
+ tests_folder: "tests"
135
+ release: true
136
+ secrets:
137
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
138
+ STORE_API_KEY: ${{ secrets.STORE_API_KEY }}
139
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
140
+ TAVILY_API_KEY: ${{ secrets.TAVILY_API_KEY }}
141
+
142
+ backend-unit-tests:
143
+ if: github.repository == 'langflow-ai/langflow'
144
+ name: Run Backend Unit Tests
145
+ needs: create-nightly-tag
146
+ uses: ./.github/workflows/python_test.yml
147
+ with:
148
+ python-versions: '["3.10", "3.11", "3.12"]'
149
+
150
+ # Not making nightly builds dependent on integration test success
151
+ # due to inherent flakiness of 3rd party integrations
152
+ # Revisit when https://github.com/langflow-ai/langflow/pull/3607 is merged.
153
+ # backend-integration-tests:
154
+ # name: Run Backend Integration Tests
155
+ # needs: create-nightly-tag
156
+ # uses: ./.github/workflows/integration_tests.yml
157
+ # with:
158
+ # python-versions: '["3.10", "3.11", "3.12"]'
159
+ # ref: ${{ needs.create-nightly-tag.outputs.tag }}
160
+
161
+ release-nightly-build:
162
+ if: github.repository == 'langflow-ai/langflow'
163
+ name: Run Nightly Langflow Build
164
+ needs: [frontend-tests, backend-unit-tests, create-nightly-tag]
165
+ uses: ./.github/workflows/release_nightly.yml
166
+ with:
167
+ build_docker_base: true
168
+ build_docker_main: true
169
+ nightly_tag_main: ${{ needs.create-nightly-tag.outputs.main_tag }}
170
+ nightly_tag_base: ${{ needs.create-nightly-tag.outputs.base_tag }}
171
+ secrets: inherit
172
+
173
+ # slack-notification:
174
+ # name: Send Slack Notification
175
+ # needs: run-nightly-build
176
+ # runs-on: ubuntu-latest
177
+ # steps:
178
+ # - name: Send success notification to Slack
179
+ # if: success()
180
+ # uses: slackapi/slack-github-action@v1.26.0
181
+ # with:
182
+ # payload: |
183
+ # {
184
+ # "channel": "#langflow-nightly-builds",
185
+ # "username": "GitHub Actions",
186
+ # "text": "Nightly Build Successful :white_check_mark:",
187
+ # "icon_emoji": ":rocket:"
188
+ # }
189
+ # env:
190
+ # SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
191
+
192
+ # - name: Send failure notification to Slack
193
+ # if: failure()
194
+ # uses: slackapi/slack-github-action@v1.26.0
195
+ # with:
196
+ # payload: |
197
+ # {
198
+ # "channel": "#langflow-nightly-builds",
199
+ # "username": "GitHub Actions",
200
+ # "text": "Nightly Build Failed :x:",
201
+ # "icon_emoji": ":warning:"
202
+ # }
203
+ # env:
204
+ # SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
.github/workflows/py_autofix.yml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: autofix.ci
2
+ on:
3
+ pull_request:
4
+ paths:
5
+ - "**/*.py"
6
+ env:
7
+ POETRY_VERSION: "1.8.2"
8
+
9
+ jobs:
10
+ lint:
11
+ name: Run Ruff Check and Format
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - name: "Setup Environment"
16
+ uses: ./.github/actions/setup-uv
17
+ - run: uv run ruff check --fix-only .
18
+ - run: uv run ruff format .
19
+ - uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c
20
+ - name: Minimize uv cache
21
+ run: uv cache prune --ci
.github/workflows/python_test.yml ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Python tests
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ python-versions:
7
+ description: "(Optional) Python versions to test"
8
+ required: true
9
+ type: string
10
+ default: "['3.10', '3.11', '3.12']"
11
+ ref:
12
+ description: "(Optional) ref to checkout"
13
+ required: false
14
+ type: string
15
+ nightly:
16
+ description: "Whether run is from the nightly build"
17
+ required: false
18
+ type: boolean
19
+ default: false
20
+ workflow_dispatch:
21
+ inputs:
22
+ python-versions:
23
+ description: "(Optional) Python versions to test"
24
+ required: true
25
+ type: string
26
+ default: "['3.10', '3.11', '3.12']"
27
+ env:
28
+ POETRY_VERSION: "1.8.2"
29
+ NODE_VERSION: "21"
30
+ PYTEST_RUN_PATH: "src/backend/tests"
31
+
32
+ jobs:
33
+ build:
34
+ name: Unit Tests - Python ${{ matrix.python-version }} - Group ${{ matrix.group }}
35
+ runs-on: ubuntu-latest
36
+ env:
37
+ UV_CACHE_DIR: /tmp/.uv-cache
38
+ strategy:
39
+ matrix:
40
+ python-version: ${{ fromJson(inputs.python-versions || '["3.10", "3.11", "3.12"]' ) }}
41
+ splitCount: [5]
42
+ group: [1, 2, 3, 4, 5]
43
+ steps:
44
+ - uses: actions/checkout@v4
45
+ with:
46
+ ref: ${{ inputs.ref || github.ref }}
47
+ - name: Setup Node.js
48
+ uses: actions/setup-node@v4
49
+ id: setup-node
50
+ with:
51
+ node-version: ${{ env.NODE_VERSION }}
52
+ - name: Install uv
53
+ uses: astral-sh/setup-uv@v4
54
+ with:
55
+ enable-cache: true
56
+ cache-dependency-glob: "uv.lock"
57
+ - name: "Set up Python"
58
+ uses: actions/setup-python@v5
59
+ with:
60
+ python-version-file: "pyproject.toml"
61
+ - name: Restore uv cache
62
+ uses: actions/cache@v4
63
+ with:
64
+ path: /tmp/.uv-cache
65
+ key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
66
+ restore-keys: |
67
+ uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
68
+ uv-${{ runner.os }}
69
+ - name: Install the project
70
+ run: uv sync --dev
71
+ - name: Run unit tests
72
+ uses: nick-fields/retry@v3
73
+ with:
74
+ timeout_minutes: 12
75
+ max_attempts: 2
76
+ command: make unit_tests async=false args="-x --splits ${{ matrix.splitCount }} --group ${{ matrix.group }}"
77
+ - name: Minimize uv cache
78
+ run: uv cache prune --ci
79
+ integration-tests:
80
+ name: Integration Tests - Python ${{ matrix.python-version }}
81
+ runs-on: ubuntu-latest
82
+ strategy:
83
+ matrix:
84
+ python-version: ${{ fromJson(inputs.python-versions || '["3.10", "3.11", "3.12"]' ) }}
85
+ steps:
86
+ - uses: actions/checkout@v4
87
+ with:
88
+ ref: ${{ inputs.ref || github.ref }}
89
+ - name: Install uv
90
+ uses: astral-sh/setup-uv@v4
91
+ with:
92
+ enable-cache: true
93
+ cache-dependency-glob: "uv.lock"
94
+ - name: "Set up Python"
95
+ uses: actions/setup-python@v5
96
+ with:
97
+ python-version-file: "pyproject.toml"
98
+ - name: Restore uv cache
99
+ uses: actions/cache@v4
100
+ with:
101
+ path: /tmp/.uv-cache
102
+ key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
103
+ restore-keys: |
104
+ uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
105
+ uv-${{ runner.os }}
106
+ - name: Install the project
107
+ run: uv sync --dev
108
+ - name: Run integration tests
109
+ run: make integration_tests_no_api_keys
110
+ - name: Minimize uv cache
111
+ run: uv cache prune --ci
112
+ test-cli:
113
+ name: Test CLI - Python ${{ matrix.python-version }}
114
+ runs-on: ubuntu-latest
115
+ strategy:
116
+ matrix:
117
+ python-version: ${{ fromJson(inputs.python-versions || '["3.10", "3.11", "3.12"]') }}
118
+ steps:
119
+ - name: Check out the code at a specific ref
120
+ uses: actions/checkout@v4
121
+ with:
122
+ ref: ${{ inputs.ref || github.ref }}
123
+ - name: "Setup Environment"
124
+ uses: ./.github/actions/setup-uv
125
+
126
+ - name: Check Version
127
+ id: check-version
128
+ # We need to print $3 because langflow-base is a dependency of langflow
129
+ # For langlow we'd use print $2
130
+ run: |
131
+ version=$(uv tree | grep 'langflow-base' | awk '{print $3}' | sed 's/^v//')
132
+ url="https://pypi.org/pypi/langflow-base/json"
133
+ if [ ${{ inputs.nightly }} == true ]; then
134
+ url="https://pypi.org/pypi/langflow-base-nightly/json"
135
+ fi
136
+
137
+ last_released_version=$(curl -s $url | jq -r '.releases | keys | .[]' | sort -V | tail -n 1)
138
+ if [ "$version" != "$last_released_version" ]; then
139
+ echo "Version $version has not been released yet. Skipping the rest of the job."
140
+ echo skipped=true >> $GITHUB_OUTPUT
141
+ exit 0
142
+ else
143
+ echo version=$version >> $GITHUB_OUTPUT
144
+ echo skipped=false >> $GITHUB_OUTPUT
145
+ fi
146
+ - name: Build wheel
147
+ if: steps.check-version.outputs.skipped == 'false'
148
+ run: |
149
+ make build main=true
150
+ - name: Install wheel and Test CLI
151
+ if: steps.check-version.outputs.skipped == 'false'
152
+ run: |
153
+ uv venv new-venv
154
+ source new-venv/bin/activate
155
+ uv pip install dist/*.whl
156
+ - name: Test CLI
157
+ if: steps.check-version.outputs.skipped == 'false'
158
+ run: |
159
+ source new-venv/bin/activate
160
+ python -m langflow run --host 127.0.0.1 --port 7860 --backend-only &
161
+ SERVER_PID=$!
162
+ # Wait for the server to start
163
+ timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/api/v1/auto_login; do sleep 5; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
164
+ # Terminate the server
165
+ kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
166
+ sleep 20 # give the server some time to terminate
167
+ # Check if the server is still running
168
+ if kill -0 $SERVER_PID 2>/dev/null; then
169
+ echo "Failed to terminate the server"
170
+ exit 0
171
+ else
172
+ echo "Server terminated successfully"
173
+ fi
174
+ - name: Minimize uv cache
175
+ run: uv cache prune --ci
.github/workflows/release.yml ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Langflow Release
2
+ run-name: Langflow Release by @${{ github.actor }}
3
+
4
+ on:
5
+ workflow_dispatch:
6
+ inputs:
7
+ release_package_base:
8
+ description: "Release Langflow Base"
9
+ required: true
10
+ type: boolean
11
+ default: false
12
+ release_package_main:
13
+ description: "Release Langflow"
14
+ required: true
15
+ type: boolean
16
+ default: false
17
+ build_docker_base:
18
+ description: "Build Docker Image for Langflow Base"
19
+ required: true
20
+ type: boolean
21
+ default: false
22
+ build_docker_main:
23
+ description: "Build Docker Image for Langflow"
24
+ required: true
25
+ type: boolean
26
+ default: false
27
+ build_docker_ep:
28
+ description: "Build Docker Image for Langflow with Entrypoint"
29
+ required: false
30
+ type: boolean
31
+ default: false
32
+ pre_release:
33
+ description: "Pre-release"
34
+ required: false
35
+ type: boolean
36
+ default: false
37
+ create_release:
38
+ description: "Whether to create a gh release"
39
+ required: false
40
+ type: boolean
41
+ default: true
42
+
43
+
44
+ jobs:
45
+ ci:
46
+ if: ${{ github.event.inputs.release_package_base == 'true' || github.event.inputs.release_package_main == 'true' }}
47
+ name: CI
48
+ uses: ./.github/workflows/ci.yml
49
+ with:
50
+ python-versions: "['3.10', '3.11', '3.12']"
51
+ frontend-tests-folder: "tests"
52
+ release: true
53
+
54
+ release-base:
55
+ name: Release Langflow Base
56
+ needs: [ci]
57
+ if: inputs.release_package_base == true
58
+ runs-on: ubuntu-latest
59
+ outputs:
60
+ version: ${{ steps.check-version.outputs.version }}
61
+ skipped: ${{ steps.check-version.outputs.skipped }}
62
+ steps:
63
+ - name: Checkout code
64
+ uses: actions/checkout@v4
65
+ - name: Setup Environment
66
+ uses: ./.github/actions/setup-uv
67
+ - name: Install the project
68
+ run: uv sync --dev
69
+ - name: Check Version
70
+ id: check-version
71
+ run: |
72
+ version=$(uv tree | grep 'langflow-base' | awk '{print $3}' | sed 's/^v//')
73
+ last_released_version=$(curl -s "https://pypi.org/pypi/langflow-base/json" | jq -r '.releases | keys | .[]' | sort -V | tail -n 1)
74
+ if [ "$version" = "$last_released_version" ]; then
75
+ echo "Version $version is already released. Skipping release."
76
+ echo skipped=true >> $GITHUB_OUTPUT
77
+ exit 0
78
+ else
79
+ echo version=$version >> $GITHUB_OUTPUT
80
+ echo skipped=false >> $GITHUB_OUTPUT
81
+ fi
82
+ - name: Build project for distribution
83
+ if: steps.check-version.outputs.skipped == 'false'
84
+ run: make build base=true args="--wheel"
85
+ - name: Test CLI
86
+ if: steps.check-version.outputs.skipped == 'false'
87
+ run: |
88
+ # TODO: Unsure why the whl is not built in src/backend/base/dist
89
+ mkdir src/backend/base/dist
90
+ mv dist/*.whl src/backend/base/dist
91
+ uv pip install src/backend/base/dist/*.whl
92
+ uv run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only &
93
+ SERVER_PID=$!
94
+ # Wait for the server to start
95
+ timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/api/v1/auto_login; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
96
+ # Terminate the server
97
+ kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
98
+ sleep 20 # give the server some time to terminate
99
+ # Check if the server is still running
100
+ if kill -0 $SERVER_PID 2>/dev/null; then
101
+ echo "Failed to terminate the server"
102
+ exit 0
103
+ else
104
+ echo "Server terminated successfully"
105
+ fi
106
+ - name: Publish to PyPI
107
+ if: steps.check-version.outputs.skipped == 'false'
108
+ env:
109
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
110
+ run: |
111
+ make publish base=true
112
+ - name: Upload Artifact
113
+ if: steps.check-version.outputs.skipped == 'false'
114
+ uses: actions/upload-artifact@v4
115
+ with:
116
+ name: dist-base
117
+ path: src/backend/base/dist
118
+
119
+ release-main:
120
+ name: Release Langflow Main
121
+ if: inputs.release_package_main == true
122
+ needs: [release-base]
123
+ runs-on: ubuntu-latest
124
+ outputs:
125
+ version: ${{ steps.check-version.outputs.version }}
126
+ steps:
127
+ - name: Checkout code
128
+ uses: actions/checkout@v4
129
+ - name: Setup Environment
130
+ uses: ./.github/actions/setup-uv
131
+ - name: Install the project
132
+ run: uv sync --dev
133
+
134
+ # If pre-release is true, we need to check if ["a", "b", "rc", "dev", "post"] is in the version string
135
+ # if the version string is incorrect, we need to exit the workflow
136
+ - name: Check if pre-release
137
+ if: inputs.pre_release == 'true'
138
+ run: |
139
+ version=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | awk '{print $2}' | sed 's/^v//')
140
+ if [[ "${version}" =~ ^([0-9]+\.)?([0-9]+\.)?[0-9]+((a|b|rc|dev|post)([0-9]+))$ ]]; then
141
+ echo "Pre-release version detected. Continuing with the release."
142
+ else
143
+ echo "Invalid pre-release version detected. Exiting the workflow."
144
+ exit 1
145
+ fi
146
+ - name: Check Version
147
+ id: check-version
148
+ run: |
149
+ version=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | awk '{print $2}' | sed 's/^v//')
150
+ last_released_version=$(curl -s "https://pypi.org/pypi/langflow/json" | jq -r '.releases | keys | .[]' | sort -V | tail -n 1)
151
+ if [ "$version" = "$last_released_version" ]; then
152
+ echo "Version $version is already released. Skipping release."
153
+ exit 1
154
+ else
155
+ echo version=$version >> $GITHUB_OUTPUT
156
+ fi
157
+ - name: Wait for PyPI Propagation
158
+ if: needs.release-base.outputs.skipped == 'false'
159
+ run: sleep 300 # wait for 5 minutes to ensure PyPI propagation
160
+
161
+ - name: Build project for distribution
162
+ run: make build main=true args="--no-sources --wheel"
163
+ - name: Test CLI
164
+ run: |
165
+ uv pip install dist/*.whl
166
+ uv run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only &
167
+ SERVER_PID=$!
168
+ # Wait for the server to start
169
+ timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/health_check; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
170
+ # Terminate the server
171
+ kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
172
+ sleep 20 # give the server some time to terminate
173
+ # Check if the server is still running
174
+ if kill -0 $SERVER_PID 2>/dev/null; then
175
+ echo "Failed to terminate the server"
176
+ exit 0
177
+ else
178
+ echo "Server terminated successfully"
179
+ fi
180
+ - name: Publish to PyPI
181
+ env:
182
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
183
+ run: |
184
+ make publish main=true
185
+ - name: Upload Artifact
186
+ uses: actions/upload-artifact@v4
187
+ with:
188
+ name: dist-main
189
+ path: dist
190
+
191
+ call_docker_build_base:
192
+ name: Call Docker Build Workflow for Langflow Base
193
+ if: inputs.build_docker_base == true
194
+ needs: [release-base, release-main]
195
+ uses: ./.github/workflows/docker-build.yml
196
+ with:
197
+ base_version: ${{ needs.release-base.outputs.version }}
198
+ main_version: ${{ needs.release-main.outputs.version }}
199
+ release_type: base
200
+ pre_release: ${{ inputs.pre_release }}
201
+ secrets: inherit
202
+
203
+ call_docker_build_main:
204
+ name: Call Docker Build Workflow for Langflow
205
+ if: inputs.build_docker_main == true
206
+ needs: [release-main]
207
+ uses: ./.github/workflows/docker-build.yml
208
+ with:
209
+ main_version: ${{ needs.release-main.outputs.version }}
210
+ release_type: main
211
+ pre_release: ${{ inputs.pre_release }}
212
+ secrets: inherit
213
+
214
+ call_docker_build_main_ep:
215
+ name: Call Docker Build Workflow for Langflow with Entrypoint
216
+ if: inputs.build_docker_ep == true
217
+ needs: [release-main]
218
+ uses: ./.github/workflows/docker-build.yml
219
+ with:
220
+ main_version: ${{ needs.release-main.outputs.version }}
221
+ release_type: main-ep
222
+ pre_release: False
223
+ secrets: inherit
224
+
225
+ create_release:
226
+ name: Create Release
227
+ runs-on: ubuntu-latest
228
+ needs: release-main
229
+ steps:
230
+ - uses: actions/download-artifact@v4
231
+ with:
232
+ name: dist-main
233
+ path: dist
234
+ - name: Create Release
235
+ uses: ncipollo/release-action@v1
236
+ with:
237
+ artifacts: "dist/*"
238
+ token: ${{ secrets.GITHUB_TOKEN }}
239
+ draft: false
240
+ generateReleaseNotes: true
241
+ prerelease: ${{ inputs.pre_release }}
242
+ tag: ${{ needs.release-main.outputs.version }}
243
+ commit: ${{ github.ref }}
.github/workflows/release_nightly.yml ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Langflow Nightly Build
2
+ run-name: Langflow Nightly Release by @${{ github.actor }}
3
+
4
+ on:
5
+ workflow_dispatch:
6
+ inputs:
7
+ build_docker_base:
8
+ description: "Build Docker Image for Langflow Nightly Base"
9
+ required: true
10
+ type: boolean
11
+ default: false
12
+ build_docker_main:
13
+ description: "Build Docker Image for Langflow Nightly"
14
+ required: true
15
+ type: boolean
16
+ default: false
17
+ build_docker_ep:
18
+ description: "Build Docker Image for Langflow Nightly with Entrypoint"
19
+ required: false
20
+ type: boolean
21
+ default: false
22
+ nightly_tag_main:
23
+ description: "Tag for the nightly main build"
24
+ required: true
25
+ type: string
26
+ nightly_tag_base:
27
+ description: "Tag for the nightly base build"
28
+ required: true
29
+ type: string
30
+ workflow_call:
31
+ inputs:
32
+ build_docker_base:
33
+ description: "Build Docker Image for Langflow Nightly Base"
34
+ required: true
35
+ type: boolean
36
+ default: false
37
+ build_docker_main:
38
+ description: "Build Docker Image for Langflow Nightly"
39
+ required: true
40
+ type: boolean
41
+ default: false
42
+ build_docker_ep:
43
+ description: "Build Docker Image for Langflow Nightly with Entrypoint"
44
+ required: false
45
+ type: boolean
46
+ default: false
47
+ nightly_tag_main:
48
+ description: "Tag for the nightly main build"
49
+ required: true
50
+ type: string
51
+ nightly_tag_base:
52
+ description: "Tag for the nightly base build"
53
+ required: true
54
+ type: string
55
+
56
+ env:
57
+ POETRY_VERSION: "1.8.3"
58
+ PYTHON_VERSION: "3.12"
59
+
60
+ jobs:
61
+ release-nightly-base:
62
+ name: Release Langflow Nightly Base
63
+ runs-on: ubuntu-latest
64
+ defaults:
65
+ run:
66
+ shell: bash
67
+ outputs:
68
+ version: ${{ steps.verify.outputs.version }}
69
+ steps:
70
+ - name: Check out the code at a specific ref
71
+ uses: actions/checkout@v4
72
+ with:
73
+ ref: ${{ inputs.nightly_tag_main }}
74
+ persist-credentials: true
75
+ - name: "Setup Environment"
76
+ uses: ./.github/actions/setup-uv
77
+ - name: Install the project
78
+ run: uv sync --dev
79
+
80
+ - name: Verify Nightly Name and Version
81
+ id: verify
82
+ run: |
83
+ name=$(uv tree | grep 'langflow-base' | awk '{print $2}')
84
+ version=$(uv tree | grep 'langflow-base' | awk '{print $3}')
85
+ if [ "$name" != "langflow-base-nightly" ]; then
86
+ echo "Name $name does not match langflow-base-nightly. Exiting the workflow."
87
+ exit 1
88
+ fi
89
+ if [ "$version" != "${{ inputs.nightly_tag_base }}" ]; then
90
+ echo "Version $version does not match nightly tag ${{ inputs.nightly_tag_base }}. Exiting the workflow."
91
+ exit 1
92
+ fi
93
+ # Strip the leading `v` from the version
94
+ version=$(echo $version | sed 's/^v//')
95
+ echo "version=$version" >> $GITHUB_OUTPUT
96
+
97
+ - name: Build project for distribution
98
+ run: make build base=true args="--wheel"
99
+
100
+ - name: Test CLI
101
+ run: |
102
+ # TODO: Unsure why the whl is not built in src/backend/base/dist
103
+ mkdir src/backend/base/dist
104
+ mv dist/*.whl src/backend/base/dist/
105
+ uv pip install src/backend/base/dist/*.whl
106
+ uv run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only &
107
+ SERVER_PID=$!
108
+ # Wait for the server to start
109
+ timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/api/v1/auto_login; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
110
+ # Terminate the server
111
+ kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
112
+ sleep 20 # give the server some time to terminate
113
+ # Check if the server is still running
114
+ if kill -0 $SERVER_PID 2>/dev/null; then
115
+ echo "Failed to terminate the server"
116
+ exit 0
117
+ else
118
+ echo "Server terminated successfully"
119
+ fi
120
+
121
+ - name: Publish to PyPI
122
+ env:
123
+ POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
124
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
125
+ run: |
126
+ make publish base=true
127
+
128
+ - name: Upload Artifact
129
+ uses: actions/upload-artifact@v4
130
+ with:
131
+ name: dist-base
132
+ path: src/backend/base/dist
133
+
134
+ release-nightly-main:
135
+ name: Release Langflow Nightly Main
136
+ needs: [release-nightly-base]
137
+ runs-on: ubuntu-latest
138
+ outputs:
139
+ version: ${{ steps.verify.outputs.version }}
140
+ defaults:
141
+ run:
142
+ shell: bash
143
+ steps:
144
+ - name: Check out the code at a specific ref
145
+ uses: actions/checkout@v4
146
+ with:
147
+ ref: ${{ inputs.nightly_tag_main}}
148
+ persist-credentials: true
149
+ - name: "Setup Environment"
150
+ uses: ./.github/actions/setup-uv
151
+ - name: Install the project
152
+ run: uv sync --dev
153
+
154
+ - name: Verify Nightly Name and Version
155
+ id: verify
156
+ run: |
157
+ name=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | awk '{print $1}')
158
+ version=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | awk '{print $2}')
159
+ if [ "$name" != "langflow-nightly" ]; then
160
+ echo "Name $name does not match langflow-nightly. Exiting the workflow."
161
+ exit 1
162
+ fi
163
+ if [ "$version" != "${{ inputs.nightly_tag_main }}" ]; then
164
+ echo "Version $version does not match nightly tag ${{ inputs.nightly_tag_main }}. Exiting the workflow."
165
+ exit 1
166
+ fi
167
+ # Strip the leading `v` from the version
168
+ version=$(echo $version | sed 's/^v//')
169
+ echo "version=$version" >> $GITHUB_OUTPUT
170
+ - name: Wait for PyPI Propagation
171
+ run: sleep 300 # wait for 5 minutes to ensure PyPI propagation of base
172
+
173
+ - name: Build project for distribution
174
+ run: make build main=true args="--no-sources --wheel"
175
+ - name: Test CLI
176
+ run: |
177
+ uv pip install dist/*.whl
178
+ uv run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only &
179
+ SERVER_PID=$!
180
+ # Wait for the server to start
181
+ timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/health_check; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
182
+ # Terminate the server
183
+ kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
184
+ sleep 20 # give the server some time to terminate
185
+ # Check if the server is still running
186
+ if kill -0 $SERVER_PID 2>/dev/null; then
187
+ echo "Failed to terminate the server"
188
+ exit 0
189
+ else
190
+ echo "Server terminated successfully"
191
+ fi
192
+ - name: Publish to PyPI
193
+ env:
194
+ POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
195
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
196
+ run: |
197
+ make publish main=true
198
+ - name: Upload Artifact
199
+ uses: actions/upload-artifact@v4
200
+ with:
201
+ name: dist-main
202
+ path: dist
203
+
204
+ call_docker_build_base:
205
+ name: Call Docker Build Workflow for Langflow Base
206
+ if: always() && ${{ inputs.build_docker_base == 'true' }}
207
+ needs: [release-nightly-base, release-nightly-main]
208
+ uses: ./.github/workflows/docker-build.yml
209
+ with:
210
+ release_type: nightly-base
211
+ base_version: ${{ inputs.nightly_tag_base }}
212
+ main_version: ${{ inputs.nightly_tag_main }}
213
+ secrets: inherit
214
+
215
+ call_docker_build_main:
216
+ name: Call Docker Build Workflow for Langflow
217
+ if: always() && ${{ inputs.build_docker_main == 'true' }}
218
+ needs: [release-nightly-main]
219
+ uses: ./.github/workflows/docker-build.yml
220
+ with:
221
+ release_type: nightly-main
222
+ main_version: ${{ inputs.nightly_tag_main }}
223
+ secrets: inherit
224
+
225
+ call_docker_build_main_ep:
226
+ name: Call Docker Build Workflow for Langflow with Entrypoint
227
+ if: always() && ${{ inputs.build_docker_ep == 'true' }}
228
+ needs: [release-nightly-main]
229
+ uses: ./.github/workflows/docker-build.yml
230
+ with:
231
+ release_type: main-ep
232
+ main_version: ${{ inputs.nightly_tag_main }}
233
+ secrets: inherit
.github/workflows/store_pytest_durations.yml ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Store pytest durations
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ schedule:
6
+ # Run job at 6:30 UTC, 10.30pm PST, or 11.30pm PDT
7
+ - cron: "30 6 * * *"
8
+
9
+ env:
10
+ PYTEST_RUN_PATH: "src/backend/tests"
11
+
12
+ jobs:
13
+ build:
14
+ name: Run pytest and store durations
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ contents: write
18
+ pull-requests: write
19
+ env:
20
+ UV_CACHE_DIR: /tmp/.uv-cache
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ - name: Install uv
24
+ uses: astral-sh/setup-uv@v4
25
+ with:
26
+ enable-cache: true
27
+ cache-dependency-glob: "uv.lock"
28
+ - name: "Set up Python"
29
+ uses: actions/setup-python@v5
30
+ with:
31
+ python-version-file: "pyproject.toml"
32
+ - name: Restore uv cache
33
+ uses: actions/cache@v4
34
+ with:
35
+ path: /tmp/.uv-cache
36
+ key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
37
+ restore-keys: |
38
+ uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
39
+ uv-${{ runner.os }}
40
+ - name: Install the project
41
+ run: uv sync --dev
42
+ - name: Run unit tests
43
+ uses: nick-fields/retry@v3
44
+ with:
45
+ timeout_minutes: 12
46
+ max_attempts: 2
47
+ command: uv run pytest src/backend/tests --durations-path src/backend/tests/.test_durations --splitting-algorithm least_duration --store-durations
48
+ - name: Minimize uv cache
49
+ run: uv cache prune --ci
50
+
51
+ - name: Create Pull Request
52
+ uses: peter-evans/create-pull-request@v7
53
+ with:
54
+ token: ${{ secrets.GITHUB_TOKEN }}
55
+ branch-token: ${{ secrets.GITHUB_TOKEN }}
56
+ commit-message: "chore: update test durations"
57
+ title: "chore: update test durations"
58
+ body: |
59
+ Automated PR to update test durations file.
60
+
61
+ This PR was automatically created by the store_pytest_durations workflow.
62
+ branch: update-test-durations
63
+ branch-suffix: timestamp
64
+ delete-branch: true
65
+ maintainer-can-modify: true
.github/workflows/style-check-py.yml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Ruff Style Check
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize, reopened, auto_merge_enabled]
6
+ paths:
7
+ - "**/*.py"
8
+
9
+
10
+
11
+
12
+
13
+ jobs:
14
+ lint:
15
+ name: Ruff Style Check
16
+ runs-on: ubuntu-latest
17
+ strategy:
18
+ matrix:
19
+ python-version:
20
+ - "3.12"
21
+ steps:
22
+ - name: Check out the code at a specific ref
23
+ uses: actions/checkout@v4
24
+ - name: "Setup Environment"
25
+ uses: ./.github/actions/setup-uv
26
+ - name: Register problem matcher
27
+ run: echo "::add-matcher::.github/workflows/matchers/ruff.json"
28
+ - name: Run Ruff Check
29
+ run: uv run --only-dev ruff check --output-format=github .
30
+ - name: Minimize uv cache
31
+ run: uv cache prune --ci
.github/workflows/typescript_test.yml ADDED
@@ -0,0 +1,348 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Run Frontend Tests
2
+
3
+ on:
4
+ workflow_call:
5
+ secrets:
6
+ OPENAI_API_KEY:
7
+ required: true
8
+ STORE_API_KEY:
9
+ required: true
10
+ ANTHROPIC_API_KEY:
11
+ required: true
12
+ TAVILY_API_KEY:
13
+ required: true
14
+ inputs:
15
+ suites:
16
+ description: "Test suites to run (JSON array)"
17
+ required: false
18
+ type: string
19
+ default: '[]'
20
+ release:
21
+ description: "Whether this is a release build"
22
+ required: false
23
+ type: boolean
24
+ default: false
25
+ tests_folder:
26
+ description: "(Optional) Tests to run"
27
+ required: false
28
+ type: string
29
+ default: "tests"
30
+ ref:
31
+ description: "(Optional) ref to checkout"
32
+ required: false
33
+ type: string
34
+ workflow_dispatch:
35
+ inputs:
36
+ suites:
37
+ description: "Test suites to run (JSON array)"
38
+ required: false
39
+ type: string
40
+ default: '[]'
41
+ release:
42
+ description: "Whether this is a release build"
43
+ required: false
44
+ type: boolean
45
+ default: false
46
+ tests_folder:
47
+ description: "(Optional) Tests to run"
48
+ required: false
49
+ type: string
50
+ default: "tests"
51
+
52
+ env:
53
+ NODE_VERSION: "21"
54
+ PYTHON_VERSION: "3.12"
55
+ # Define the directory where Playwright browsers will be installed.
56
+ # Adjust if your project uses a different path.
57
+ PLAYWRIGHT_BROWSERS_PATH: "ms-playwright"
58
+
59
+ jobs:
60
+ determine-test-suite:
61
+ name: Determine Test Suites and Shard Distribution
62
+ runs-on: ubuntu-latest
63
+ outputs:
64
+ matrix: ${{ steps.setup-matrix.outputs.matrix }}
65
+ test_grep: ${{ steps.set-matrix.outputs.test_grep }}
66
+ suites: ${{ steps.set-matrix.outputs.suites }}
67
+ steps:
68
+ - uses: actions/checkout@v4
69
+ with:
70
+ ref: ${{ inputs.ref || github.ref }}
71
+ fetch-depth: 0
72
+
73
+ - name: Paths Filter
74
+ id: filter
75
+ uses: dorny/paths-filter@v3
76
+ with:
77
+ filters: .github/changes-filter.yaml
78
+
79
+ - name: Determine Test Suites from Changes
80
+ id: set-matrix
81
+ run: |
82
+ # Start with input suites if provided, otherwise empty array
83
+ echo "Changes filter output: ${{ steps.filter.outputs }}"
84
+ SUITES='${{ inputs.suites }}'
85
+ echo "Initial suites: $SUITES"
86
+ TEST_GREP=""
87
+
88
+ RELEASE="${{ inputs.release || 'false' }}"
89
+ echo "Release build: $RELEASE"
90
+
91
+ # Only set to release if it's explicitly a release build
92
+ if [[ "$RELEASE" == "true" ]]; then
93
+ SUITES='["release"]'
94
+ echo "Release build detected - setting suites to: $SUITES"
95
+ # grep pattern for release is the @release tag - run all tests
96
+ TEST_GREP="--grep=\"@release\""
97
+ else
98
+ # If input suites were not provided, determine based on changes
99
+ if [[ "$SUITES" == "[]" ]]; then
100
+ echo "No input suites provided - determining from changes"
101
+ TAGS=()
102
+ # Add suites and tags based on changed files
103
+ if [[ "${{ steps.filter.outputs.components }}" == "true" ]]; then
104
+ SUITES=$(echo $SUITES | jq -c '. += ["components"]')
105
+ TAGS+=("@components")
106
+ echo "Added components suite"
107
+ fi
108
+ if [[ "${{ steps.filter.outputs.starter-projects }}" == "true" ]]; then
109
+ SUITES=$(echo $SUITES | jq -c '. += ["starter-projects"]')
110
+ TAGS+=("@starter-projects")
111
+ echo "Added starter-projects suite"
112
+ fi
113
+ if [[ "${{ steps.filter.outputs.workspace }}" == "true" ]]; then
114
+ SUITES=$(echo $SUITES | jq -c '. += ["workspace"]')
115
+ TAGS+=("@workspace")
116
+ echo "Added workspace suite"
117
+ fi
118
+ if [[ "${{ steps.filter.outputs.api }}" == "true" ]]; then
119
+ SUITES=$(echo $SUITES | jq -c '. += ["api"]')
120
+ TAGS+=("@api")
121
+ echo "Added api suite"
122
+ fi
123
+ if [[ "${{ steps.filter.outputs.database }}" == "true" ]]; then
124
+ SUITES=$(echo $SUITES | jq -c '. += ["database"]')
125
+ TAGS+=("@database")
126
+ echo "Added database suite"
127
+ fi
128
+
129
+ # Create grep pattern if we have tags
130
+ if [ ${#TAGS[@]} -gt 0 ]; then
131
+ # Join tags with | for OR logic
132
+ REGEX_PATTERN=$(IFS='|'; echo "${TAGS[*]}")
133
+ TEST_GREP="--grep=\"${REGEX_PATTERN}\""
134
+ fi
135
+ else
136
+ # Process input suites to tags
137
+ TAGS=()
138
+ if echo "$SUITES" | jq -e 'contains(["components"])' > /dev/null; then
139
+ TAGS+=("@components")
140
+ fi
141
+ if echo "$SUITES" | jq -e 'contains(["starter-projects"])' > /dev/null; then
142
+ TAGS+=("@starter-projects")
143
+ fi
144
+ if echo "$SUITES" | jq -e 'contains(["workspace"])' > /dev/null; then
145
+ TAGS+=("@workspace")
146
+ fi
147
+ if echo "$SUITES" | jq -e 'contains(["api"])' > /dev/null; then
148
+ TAGS+=("@api")
149
+ fi
150
+ if echo "$SUITES" | jq -e 'contains(["database"])' > /dev/null; then
151
+ TAGS+=("@database")
152
+ fi
153
+
154
+ if [ ${#TAGS[@]} -gt 0 ]; then
155
+ # Join tags with | for OR logic
156
+ REGEX_PATTERN=$(IFS='|'; echo "${TAGS[*]}")
157
+ TEST_GREP="--grep \"${REGEX_PATTERN}\""
158
+ fi
159
+ fi
160
+ fi
161
+
162
+ # Ensure compact JSON output
163
+ SUITES=$(echo "$SUITES" | jq -c '.')
164
+
165
+ echo "Final test suites to run: $SUITES"
166
+ echo "Test grep pattern: $TEST_GREP"
167
+ # Ensure proper JSON formatting for matrix output
168
+ echo "matrix=$(echo $SUITES | jq -c .)" >> $GITHUB_OUTPUT
169
+ echo "test_grep=$TEST_GREP" >> $GITHUB_OUTPUT
170
+
171
+ - name: Setup Node ${{ env.NODE_VERSION }}
172
+ uses: actions/setup-node@v4
173
+ id: setup-node
174
+ with:
175
+ node-version: ${{ env.NODE_VERSION }}
176
+ cache: "npm"
177
+ cache-dependency-path: ./src/frontend/package-lock.json
178
+
179
+ - name: Install Frontend Dependencies
180
+ run: npm ci
181
+ working-directory: ./src/frontend
182
+
183
+ - name: Calculate Test Shards Distribution
184
+ id: setup-matrix
185
+ run: |
186
+ cd src/frontend
187
+
188
+ # Get the test count using playwright's built-in grep
189
+ if [ -n "${{ steps.set-matrix.outputs.test_grep }}" ]; then
190
+ TEST_COUNT=$(npx playwright test ${{ inputs.tests_folder }} ${{ steps.set-matrix.outputs.test_grep }} --list | wc -l)
191
+ else
192
+ TEST_COUNT=$(npx playwright test ${{ inputs.tests_folder }} --list | wc -l)
193
+ fi
194
+
195
+ echo "Total tests to run: $TEST_COUNT"
196
+
197
+ # Calculate optimal shard count - 1 shard per 5 tests, min 1, max 10
198
+ SHARD_COUNT=$(( (TEST_COUNT + 4) / 5 ))
199
+ if [ $SHARD_COUNT -lt 1 ]; then
200
+ SHARD_COUNT=1
201
+ elif [ $SHARD_COUNT -gt 10 ]; then
202
+ SHARD_COUNT=10
203
+ fi
204
+
205
+ # Create the matrix combinations string
206
+ MATRIX_COMBINATIONS=""
207
+ for i in $(seq 1 $SHARD_COUNT); do
208
+ if [ $i -gt 1 ]; then
209
+ MATRIX_COMBINATIONS="$MATRIX_COMBINATIONS,"
210
+ fi
211
+ MATRIX_COMBINATIONS="$MATRIX_COMBINATIONS{\"shardIndex\": $i, \"shardTotal\": $SHARD_COUNT}"
212
+ done
213
+
214
+ echo "matrix={\"include\":[$MATRIX_COMBINATIONS]}" >> "$GITHUB_OUTPUT"
215
+
216
+ setup-and-test:
217
+ name: Playwright Tests - Shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
218
+ runs-on: ubuntu-latest
219
+ if: ${{ needs.determine-test-suite.outputs.test_grep != '' }}
220
+ needs: determine-test-suite
221
+ strategy:
222
+ fail-fast: false
223
+ matrix: ${{ fromJson(needs.determine-test-suite.outputs.matrix) }}
224
+ env:
225
+ OPENAI_API_KEY: ${{ inputs.openai_api_key || secrets.OPENAI_API_KEY }}
226
+ STORE_API_KEY: ${{ inputs.store_api_key || secrets.STORE_API_KEY }}
227
+ SEARCH_API_KEY: "${{ secrets.SEARCH_API_KEY }}"
228
+ ASTRA_DB_APPLICATION_TOKEN: "${{ secrets.ASTRA_DB_APPLICATION_TOKEN }}"
229
+ ASTRA_DB_API_ENDPOINT: "${{ secrets.ASTRA_DB_API_ENDPOINT }}"
230
+ ANTHROPIC_API_KEY: "${{ secrets.ANTHROPIC_API_KEY }}"
231
+ TAVILY_API_KEY: "${{ secrets.TAVILY_API_KEY }}"
232
+ UV_CACHE_DIR: /tmp/.uv-cache
233
+ outputs:
234
+ failed: ${{ steps.check-failure.outputs.failed }}
235
+ steps:
236
+ - name: Checkout Repository
237
+ uses: actions/checkout@v4
238
+ with:
239
+ ref: ${{ inputs.ref || github.ref }}
240
+
241
+ - name: Setup Node.js Environment
242
+ uses: actions/setup-node@v4
243
+ id: setup-node
244
+ with:
245
+ node-version: ${{ env.NODE_VERSION }}
246
+ cache: "npm"
247
+ cache-dependency-path: ./src/frontend/package-lock.json
248
+
249
+ - name: Install Frontend Dependencies
250
+ run: npm ci
251
+ working-directory: ./src/frontend
252
+
253
+ - name: Install Playwright Browser Dependencies
254
+ id: install-playwright
255
+ uses: ./.github/actions/install-playwright
256
+ with:
257
+ working-directory: ./src/frontend
258
+ browsers: chromium
259
+
260
+ - name: Setup Python Environment with UV
261
+ uses: ./.github/actions/setup-uv
262
+
263
+ - name: Install Python Dependencies
264
+ run: uv sync --dev
265
+
266
+ - name: Configure Environment Variables
267
+ run: |
268
+ touch .env
269
+ echo "${{ secrets.ENV_VARS }}" > .env
270
+
271
+ - name: Execute Playwright Tests
272
+ uses: nick-fields/retry@v3
273
+ with:
274
+ timeout_minutes: 12
275
+ max_attempts: 2
276
+ command: |
277
+ cd src/frontend
278
+ echo 'Running tests with pattern: ${{ needs.determine-test-suite.outputs.test_grep }}'
279
+ npx playwright test ${{ inputs.tests_folder }} ${{ needs.determine-test-suite.outputs.test_grep }} --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --list
280
+ # echo command before running
281
+ echo "npx playwright test ${{ inputs.tests_folder }} ${{ needs.determine-test-suite.outputs.test_grep }} --trace on --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers 2"
282
+
283
+ npx playwright test ${{ inputs.tests_folder }} ${{ needs.determine-test-suite.outputs.test_grep }} --trace on --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers 2
284
+
285
+ - name: Upload Test Results
286
+ if: always()
287
+ uses: actions/upload-artifact@v4
288
+ with:
289
+ name: blob-report-${{ matrix.shardIndex }}
290
+ path: src/frontend/blob-report
291
+ retention-days: 1
292
+
293
+ - name: Cleanup UV Cache
294
+ run: uv cache prune --ci
295
+
296
+ merge-reports:
297
+ # We need to repeat the condition at every step
298
+ # https://github.com/actions/runner/issues/662
299
+ needs: setup-and-test
300
+ runs-on: ubuntu-latest
301
+ if: always()
302
+ env:
303
+ EXIT_CODE: ${{!contains(needs.setup-and-test.result, 'failure') && !contains(needs.setup-and-test.result, 'cancelled') && '0' || '1'}}
304
+ steps:
305
+ - name: "Should Merge Reports"
306
+ # If the CI was successful, we don't need to merge the reports
307
+ # so we can skip all the steps below
308
+ id: should_merge_reports
309
+ run: |
310
+ if [ "$EXIT_CODE" == "0" ]; then
311
+ echo "should_merge_reports=false" >> $GITHUB_OUTPUT
312
+ else
313
+ echo "should_merge_reports=true" >> $GITHUB_OUTPUT
314
+ fi
315
+ - name: Checkout code
316
+ if: ${{ steps.should_merge_reports.outputs.should_merge_reports == 'true' }}
317
+ uses: actions/checkout@v4
318
+
319
+ - name: Setup Node.js
320
+
321
+ if: ${{ steps.should_merge_reports.outputs.should_merge_reports == 'true' }}
322
+ uses: actions/setup-node@v4
323
+ with:
324
+ node-version: ${{ env.NODE_VERSION }}
325
+
326
+ - name: Download blob reports from GitHub Actions Artifacts
327
+
328
+ if: ${{ steps.should_merge_reports.outputs.should_merge_reports == 'true' }}
329
+ uses: actions/download-artifact@v4
330
+ with:
331
+ path: all-blob-reports
332
+ pattern: blob-report-*
333
+ merge-multiple: true
334
+
335
+ - name: Merge into HTML Report
336
+
337
+ if: ${{ steps.should_merge_reports.outputs.should_merge_reports == 'true' }}
338
+ run: |
339
+ npx playwright merge-reports --reporter html ./all-blob-reports
340
+
341
+ - name: Upload HTML report
342
+
343
+ if: ${{ steps.should_merge_reports.outputs.should_merge_reports == 'true' }}
344
+ uses: actions/upload-artifact@v4
345
+ with:
346
+ name: html-report--attempt-${{ github.run_attempt }}
347
+ path: playwright-report
348
+ retention-days: 14
.gitignore ADDED
@@ -0,0 +1,279 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This is to avoid Opencommit hook from getting pushed
2
+ prepare-commit-msg
3
+ # Logs
4
+ logs
5
+ *.log
6
+ npm-debug.log*
7
+ yarn-debug.log*
8
+ yarn-error.log*
9
+ lerna-debug.log*
10
+ qdrant_storage
11
+
12
+ .dspy_cache
13
+ # Mac
14
+ .DS_Store
15
+
16
+ # VSCode
17
+ .vscode/settings.json
18
+ .chroma
19
+ .ruff_cache
20
+
21
+ # PyCharm
22
+ .idea/
23
+
24
+ # Diagnostic reports (https://nodejs.org/api/report.html)
25
+ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
26
+
27
+ # Runtime data
28
+ pids
29
+ *.pid
30
+ *.seed
31
+ *.pid.lock
32
+
33
+ # Directory for instrumented libs generated by jscoverage/JSCover
34
+ lib-cov
35
+
36
+ # Coverage directory used by tools like istanbul
37
+ coverage
38
+ *.lcov
39
+
40
+ # nyc test coverage
41
+ .nyc_output
42
+
43
+ # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
44
+ .grunt
45
+
46
+ # Bower dependency directory (https://bower.io/)
47
+ bower_components
48
+
49
+ # node-waf configuration
50
+ .lock-wscript
51
+
52
+ # Compiled binary addons (https://nodejs.org/api/addons.html)
53
+ build/Release
54
+
55
+ # Dependency directories
56
+ node_modules/
57
+ jspm_packages/
58
+
59
+ # TypeScript v1 declaration files
60
+ typings/
61
+
62
+ # TypeScript cache
63
+ *.tsbuildinfo
64
+
65
+ # Optional npm cache directory
66
+ .npm
67
+
68
+ # Optional eslint cache
69
+ .eslintcache
70
+
71
+ # Microbundle cache
72
+ .rpt2_cache/
73
+ .rts2_cache_cjs/
74
+ .rts2_cache_es/
75
+ .rts2_cache_umd/
76
+
77
+ # Optional REPL history
78
+ .node_repl_history
79
+
80
+ # Output of 'npm pack'
81
+ *.tgz
82
+
83
+ # Yarn Integrity file
84
+ .yarn-integrity
85
+
86
+ # dotenv environment variables file
87
+ .env
88
+ .env.test
89
+
90
+ # parcel-bundler cache (https://parceljs.org/)
91
+ .cache
92
+
93
+ # Next.js build output
94
+ .next
95
+
96
+ # Nuxt.js build / generate output
97
+ .nuxt
98
+ dist
99
+
100
+ # Gatsby files
101
+ .cache/
102
+ # Comment in the public line in if your project uses Gatsby and *not* Next.js
103
+ # https://nextjs.org/blog/next-9-1#public-directory-support
104
+ # public
105
+
106
+ # vuepress build output
107
+ .vuepress/dist
108
+
109
+ # Serverless directories
110
+ .serverless/
111
+
112
+ # FuseBox cache
113
+ .fusebox/
114
+
115
+ # DynamoDB Local files
116
+ .dynamodb/
117
+
118
+ # TernJS port file
119
+ .tern-port
120
+ # Byte-compiled / optimized / DLL files
121
+ __pycache__/
122
+ *.py[cod]
123
+ *$py.class
124
+ notebooks
125
+
126
+ # C extensions
127
+ *.so
128
+
129
+ # Distribution / packaging
130
+ .Python
131
+ build/
132
+ develop-eggs/
133
+ dist/
134
+ downloads/
135
+ eggs/
136
+ .eggs/
137
+ lib/
138
+ lib64/
139
+ parts/
140
+ sdist/
141
+ var/
142
+ wheels/
143
+ pip-wheel-metadata/
144
+ share/python-wheels/
145
+ *.egg-info/
146
+ .installed.cfg
147
+ *.egg
148
+ MANIFEST
149
+
150
+ # PyInstaller
151
+ # Usually these files are written by a python script from a template
152
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
153
+ *.manifest
154
+ *.spec
155
+
156
+ # Installer logs
157
+ pip-log.txt
158
+ pip-delete-this-directory.txt
159
+
160
+ # Unit test / coverage reports
161
+ htmlcov/
162
+ .tox/
163
+ .nox/
164
+ .coverage
165
+ .coverage.*
166
+ .cache
167
+ nosetests.xml
168
+ coverage.xml
169
+ *.cover
170
+ *.py,cover
171
+ .hypothesis/
172
+ .pytest_cache/
173
+ .testmondata*
174
+
175
+ # Translations
176
+ *.mo
177
+ *.pot
178
+
179
+ # Django stuff:
180
+ *.log
181
+ local_settings.py
182
+ db.sqlite3
183
+ db.sqlite3-journal
184
+ *.db-shm
185
+ *.db-wal
186
+
187
+ # Flask stuff:
188
+ instance/
189
+ .webassets-cache
190
+
191
+ # Scrapy stuff:
192
+ .scrapy
193
+
194
+ # Sphinx documentation
195
+ docs/_build/
196
+
197
+ # PyBuilder
198
+ target/
199
+
200
+ # Jupyter Notebook
201
+ .ipynb_checkpoints
202
+
203
+ # IPython
204
+ profile_default/
205
+ ipython_config.py
206
+
207
+ # pyenv
208
+ .python-version
209
+
210
+ # pipenv
211
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
212
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
213
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
214
+ # install all needed dependencies.
215
+ #Pipfile.lock
216
+
217
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
218
+ __pypackages__/
219
+
220
+ # Celery stuff
221
+ celerybeat-schedule
222
+ celerybeat.pid
223
+
224
+ # SageMath parsed files
225
+ *.sage.py
226
+
227
+ # Environments
228
+ .env
229
+ .venv
230
+ env/
231
+ venv/
232
+ ENV/
233
+ env.bak/
234
+ venv.bak/
235
+
236
+ # Spyder project settings
237
+ .spyderproject
238
+ .spyproject
239
+
240
+ # Rope project settings
241
+ .ropeproject
242
+
243
+ # mkdocs documentation
244
+ /site
245
+
246
+ # mypy
247
+ .mypy_cache/
248
+ .dmypy.json
249
+ dmypy.json
250
+
251
+ # Poetry
252
+ .testenv/*
253
+ langflow.db
254
+
255
+
256
+ .githooks/prepare-commit-msg
257
+ .langchain.db
258
+
259
+ # docusaurus
260
+ .docusaurus/
261
+
262
+ /tmp/*
263
+ src/backend/langflow/frontend/
264
+ src/backend/base/langflow/frontend/
265
+ .docker
266
+ scratchpad*
267
+ chroma*/*
268
+ stuff/*
269
+ src/frontend/playwright-report/index.html
270
+ *.bak
271
+ prof/*
272
+
273
+ src/frontend/temp
274
+ *-shm
275
+ *-wal
276
+ .history
277
+
278
+ .dspy_cache/
279
+ *.db
.pre-commit-config.yaml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v4.1.0
4
+ hooks:
5
+ - id: check-case-conflict
6
+ - id: end-of-file-fixer
7
+ # python, js and ts only
8
+ files: \.(py|js|ts)$
9
+ - id: mixed-line-ending
10
+ files: \.(py|js|ts)$
11
+ args:
12
+ - --fix=lf
13
+ - id: trailing-whitespace
14
+ - repo: local
15
+ hooks:
16
+ - id: ruff-check
17
+ name: ruff check
18
+ language: system
19
+ entry: bash -c "uv run ruff check"
20
+ types: [file, python]
21
+ - id: ruff-format
22
+ name: ruff format
23
+ language: system
24
+ entry: bash -c "uv run ruff format"
25
+ types: [file, python]
.vscode/launch.json ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "Debug Backend",
6
+ "type": "debugpy",
7
+ "request": "launch",
8
+ "module": "uvicorn",
9
+ "preLaunchTask": "Install Backend",
10
+
11
+ "args": [
12
+ "--factory",
13
+ "langflow.main:create_app",
14
+ "--port",
15
+ "7860",
16
+ "--reload",
17
+ "--log-level",
18
+ "debug",
19
+ "--loop",
20
+ "asyncio",
21
+ "--reload-include",
22
+ "./src/backend/*"
23
+ ],
24
+ "jinja": true,
25
+ "justMyCode": false,
26
+ "env": {
27
+ "LANGFLOW_LOG_LEVEL": "debug",
28
+ "LANGFLOW_PROMETHEUS_PORT": "9090"
29
+ },
30
+ "envFile": "${workspaceFolder}/.env"
31
+ },
32
+ {
33
+ "name": "Debug CLI",
34
+ "type": "debugpy",
35
+ "request": "launch",
36
+ "module": "langflow",
37
+ "args": [
38
+ "run",
39
+ "--path",
40
+ "${workspaceFolder}/src/backend/base/langflow/frontend",
41
+ "--env-file",
42
+ "${workspaceFolder}/.env"
43
+ ],
44
+ // "python": "/path/to/your/python_env/python", // Replace with the path to your Python executable
45
+ "jinja": true,
46
+ "justMyCode": false
47
+ },
48
+ {
49
+ "name": "Python: Remote Attach",
50
+ "type": "debugpy",
51
+ "request": "attach",
52
+ "justMyCode": true,
53
+ "connect": {
54
+ "port": 5678
55
+ },
56
+ "pathMappings": [
57
+ {
58
+ "localRoot": "${workspaceFolder}",
59
+ "remoteRoot": "."
60
+ }
61
+ ]
62
+ },
63
+ {
64
+ "name": "Debug Frontend",
65
+ "type": "chrome",
66
+ "request": "launch",
67
+ "url": "http://localhost:3000/",
68
+ "webRoot": "${workspaceRoot}/src/frontend"
69
+ },
70
+ {
71
+ "name": "Python: Debug Tests",
72
+ "type": "debugpy",
73
+ "request": "launch",
74
+ "program": "${file}",
75
+ "purpose": ["debug-test"],
76
+ "console": "integratedTerminal",
77
+ "justMyCode": false
78
+ }
79
+ ]
80
+ }
.vscode/tasks.json ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ // See https://go.microsoft.com/fwlink/?LinkId=733558
3
+ // for the documentation about the tasks.json format
4
+ "version": "2.0.0",
5
+ "tasks": [
6
+ {
7
+ "label": "Init",
8
+ "type": "shell",
9
+ "command": "make init"
10
+ },
11
+ // make backend
12
+ {
13
+ "label": "Backend",
14
+ "type": "shell",
15
+ "command": "make backend"
16
+ },
17
+ // make frontend
18
+ {
19
+ "label": "Frontend",
20
+ "type": "shell",
21
+ "command": "make frontend"
22
+ },
23
+ // make test
24
+ {
25
+ "label": "Test",
26
+ "type": "shell",
27
+ "command": "make unit_tests"
28
+ },
29
+ // make lint
30
+ {
31
+ "label": "Lint",
32
+ "type": "shell",
33
+ "command": "make lint"
34
+ },
35
+ // make format
36
+ {
37
+ "label": "Format",
38
+ "type": "shell",
39
+ "command": "make format"
40
+ },
41
+ // make install
42
+ {
43
+ "label": "Install",
44
+ "type": "shell",
45
+ "command": "make install_backend && make install_frontend"
46
+ },
47
+ // install backend
48
+ {
49
+ "label": "Install Backend",
50
+ "type": "shell",
51
+ "command": "make install_backend"
52
+ }
53
+ ]
54
+ }
CODE_OF_CONDUCT.md ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socioeconomic status,
9
+ nationality, personal appearance, race, religion, or sexual identity
10
+ and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment for our
18
+ community include:
19
+
20
+ - Demonstrating empathy and kindness toward other people
21
+ - Being respectful of differing opinions, viewpoints, and experiences
22
+ - Giving and gracefully accepting constructive feedback
23
+ - Accepting responsibility and apologizing to those affected by our mistakes,
24
+ and learning from the experience
25
+ - Focusing on what is best not just for us as individuals, but for the
26
+ overall community
27
+
28
+ Examples of unacceptable behavior include:
29
+
30
+ - The use of sexualized language or imagery, and sexual attention or
31
+ advances of any kind
32
+ - Trolling, insulting or derogatory comments, and personal or political attacks
33
+ - Public or private harassment
34
+ - Publishing others' private information, such as a physical or email
35
+ address, without their explicit permission
36
+ - Other conduct which could reasonably be considered inappropriate in a
37
+ professional setting
38
+
39
+ ## Enforcement Responsibilities
40
+
41
+ Community leaders are responsible for clarifying and enforcing our standards of
42
+ acceptable behavior and will take appropriate and fair corrective action in
43
+ response to any behavior that they deem inappropriate, threatening, offensive,
44
+ or harmful.
45
+
46
+ Community leaders have the right and responsibility to remove, edit, or reject
47
+ comments, commits, code, wiki edits, issues, and other contributions that are
48
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
49
+ decisions when appropriate.
50
+
51
+ ## Scope
52
+
53
+ This Code of Conduct applies within all community spaces, and also applies when
54
+ an individual is officially representing the community in public spaces.
55
+ Examples of representing our community include using an official e-mail address,
56
+ posting via an official social media account, or acting as an appointed
57
+ representative at an online or offline event.
58
+
59
+ ## Enforcement
60
+
61
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
+ reported to the community leaders responsible for enforcement at
63
+ contact@langflow.org.
64
+ All complaints will be reviewed and investigated promptly and fairly.
65
+
66
+ All community leaders are obligated to respect the privacy and security of the
67
+ reporter of any incident.
68
+
69
+ ## Enforcement Guidelines
70
+
71
+ Community leaders will follow these Community Impact Guidelines in determining
72
+ the consequences for any action they deem in violation of this Code of Conduct:
73
+
74
+ ### 1. Correction
75
+
76
+ **Community Impact**: Use of inappropriate language or other behavior deemed
77
+ unprofessional or unwelcome in the community.
78
+
79
+ **Consequence**: A private, written warning from community leaders, providing
80
+ clarity around the nature of the violation and an explanation of why the
81
+ behavior was inappropriate. A public apology may be requested.
82
+
83
+ ### 2. Warning
84
+
85
+ **Community Impact**: A violation through a single incident or series
86
+ of actions.
87
+
88
+ **Consequence**: A warning with consequences for continued behavior. No
89
+ interaction with the people involved, including unsolicited interaction with
90
+ those enforcing the Code of Conduct, for a specified period of time. This
91
+ includes avoiding interactions in community spaces as well as external channels
92
+ like social media. Violating these terms may lead to a temporary or
93
+ permanent ban.
94
+
95
+ ### 3. Temporary Ban
96
+
97
+ **Community Impact**: A serious violation of community standards, including
98
+ sustained inappropriate behavior.
99
+
100
+ **Consequence**: A temporary ban from any sort of interaction or public
101
+ communication with the community for a specified period of time. No public or
102
+ private interaction with the people involved, including unsolicited interaction
103
+ with those enforcing the Code of Conduct, is allowed during this period.
104
+ Violating these terms may lead to a permanent ban.
105
+
106
+ ### 4. Permanent Ban
107
+
108
+ **Community Impact**: Demonstrating a pattern of violation of community
109
+ standards, including sustained inappropriate behavior, harassment of an
110
+ individual, or aggression toward or disparagement of classes of individuals.
111
+
112
+ **Consequence**: A permanent ban from any sort of public interaction within
113
+ the community.
114
+
115
+ ## Attribution
116
+
117
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118
+ version 2.0, available at
119
+ https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120
+
121
+ Community Impact Guidelines were inspired by [Mozilla's code of conduct
122
+ enforcement ladder](https://github.com/mozilla/diversity).
123
+
124
+ [homepage]: https://www.contributor-covenant.org
125
+
126
+ For answers to common questions about this code of conduct, see the FAQ at
127
+ https://www.contributor-covenant.org/faq. Translations are available at
128
+ https://www.contributor-covenant.org/translations.
CONTRIBUTING.md ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Contributing to Langflow
2
+
3
+ This guide is intended to help you get started contributing to Langflow.
4
+ As an open-source project in a rapidly developing field, we are extremely open
5
+ to contributions, whether it be in the form of a new feature, improved infra, or better documentation.
6
+
7
+ To contribute to this project, please follow the [fork and pull request](https://docs.github.com/en/get-started/quickstart/contributing-to-projects) workflow.
8
+
9
+ ## Reporting bugs or suggesting improvements
10
+
11
+ Our [GitHub issues](https://github.com/langflow-ai/langflow/issues) page is kept up to date
12
+ with bugs, improvements, and feature requests. There is a taxonomy of labels to help
13
+ with sorting and discovery of issues of interest. [See this page](https://github.com/langflow-ai/langflow/labels) for an overview of
14
+ the system we use to tag our issues and pull requests.
15
+
16
+ If you're looking for help with your code, consider posting a question on the
17
+ [GitHub Discussions board](https://github.com/langflow-ai/langflow/discussions). Please
18
+ understand that we won't be able to provide individual support via email. We
19
+ also believe that help is much more valuable if it's **shared publicly**,
20
+ so that more people can benefit from it.
21
+
22
+ - **Describing your issue:** Try to provide as many details as possible. What
23
+ exactly goes wrong? _How_ is it failing? Is there an error?
24
+ "XY doesn't work" usually isn't that helpful for tracking down problems. Always
25
+ remember to include the code you ran and if possible, extract only the relevant
26
+ parts and don't just dump your entire script. This will make it easier for us to
27
+ reproduce the error.
28
+
29
+ - **Sharing long blocks of code or logs:** If you need to include long code,
30
+ logs or tracebacks, you can wrap them in `<details>` and `</details>`. This
31
+ [collapses the content](https://developer.mozilla.org/en/docs/Web/HTML/Element/details)
32
+ so it only becomes visible on click, making the issue easier to read and follow.
33
+
34
+ ## Contributing code and documentation
35
+
36
+ You can develop Langflow locally via uv + NodeJS.
37
+
38
+ ### Clone the Langflow Repository
39
+
40
+ Navigate to the [Langflow GitHub repository](https://github.com/langflow-ai/langflow) and press "Fork" in the upper right-hand corner.
41
+
42
+ Add the new remote to your local repository on your local machine:
43
+
44
+ ```bash
45
+ git remote add fork https://github.com/<your username>/langflow.git
46
+ ```
47
+
48
+ We also provide a .vscode/launch.json file for debugging the backend in VSCode, which is a lot faster than using docker compose.
49
+
50
+ ### Prepare the environment
51
+
52
+ Setting up hooks:
53
+
54
+ ```bash
55
+ make init
56
+ ```
57
+
58
+ This will set up the development environment by installing backend and frontend dependencies, building the frontend static files, and initializing the project. It runs `make install_backend`, `make install_frontend`, `make build_frontend`, and finally `uv run langflow run` to start the application.
59
+
60
+ It is advised to run `make lint`, `make format`, and `make unit_tests` before pushing to the repository.
61
+
62
+ ### Run locally (uv and Node.js)
63
+
64
+ Langflow can run locally by cloning the repository and installing the dependencies. We recommend using a virtual environment to isolate the dependencies from your system.
65
+
66
+ Before you start, make sure you have the following installed:
67
+
68
+ - uv (>=0.4)
69
+ - Node.js
70
+
71
+ Then, in the root folder, install the dependencies and start the development server for the backend:
72
+
73
+ ```bash
74
+ make backend
75
+ ```
76
+
77
+ And the frontend:
78
+
79
+ ```bash
80
+ make frontend
81
+ ```
82
+
83
+ ### Run documentation
84
+
85
+ The documentation is built using [Docusaurus](https://docusaurus.io/). To run the documentation locally, run the following commands:
86
+
87
+ ```bash
88
+ cd docs
89
+ npm install
90
+ npm run start
91
+ ```
92
+
93
+ The documentation will be available at `localhost:3000` and all the files are located in the `docs/docs` folder.
94
+
95
+ ## Opening a pull request
96
+
97
+ Once you wrote and manually tested your change, you can start sending the patch to the main repository.
98
+
99
+ - Open a new GitHub pull request with the patch against the `main` branch.
100
+ - Ensure the PR title follows semantic commits conventions.
101
+ - For example, `feat: add new feature`, `fix: correct issue with X`.
102
+ - Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Langflow
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
Makefile ADDED
@@ -0,0 +1,446 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .PHONY: all init format lint build build_frontend install_frontend run_frontend run_backend dev help tests coverage clean_python_cache clean_npm_cache clean_all
2
+
3
+ # Configurations
4
+ VERSION=$(shell grep "^version" pyproject.toml | sed 's/.*\"\(.*\)\"$$/\1/')
5
+ DOCKERFILE=docker/build_and_push.Dockerfile
6
+ DOCKERFILE_BACKEND=docker/build_and_push_backend.Dockerfile
7
+ DOCKERFILE_FRONTEND=docker/frontend/build_and_push_frontend.Dockerfile
8
+ DOCKER_COMPOSE=docker_example/docker-compose.yml
9
+ PYTHON_REQUIRED=$(shell grep '^requires-python[[:space:]]*=' pyproject.toml | sed -n 's/.*"\([^"]*\)".*/\1/p')
10
+ RED=\033[0;31m
11
+ NC=\033[0m # No Color
12
+ GREEN=\033[0;32m
13
+
14
+ log_level ?= debug
15
+ host ?= 0.0.0.0
16
+ port ?= 7860
17
+ env ?= .env
18
+ open_browser ?= true
19
+ path = src/backend/base/langflow/frontend
20
+ workers ?= 1
21
+ async ?= true
22
+ lf ?= false
23
+ ff ?= true
24
+ all: help
25
+
26
+ ######################
27
+ # UTILITIES
28
+ ######################
29
+
30
+ # increment the patch version of the current package
31
+ patch: ## bump the version in langflow and langflow-base
32
+ @echo 'Patching the version'
33
+ @poetry version patch
34
+ @echo 'Patching the version in langflow-base'
35
+ @cd src/backend/base && poetry version patch
36
+ @make lock
37
+
38
+ # check for required tools
39
+ check_tools:
40
+ @command -v uv >/dev/null 2>&1 || { echo >&2 "$(RED)uv is not installed. Aborting.$(NC)"; exit 1; }
41
+ @command -v npm >/dev/null 2>&1 || { echo >&2 "$(RED)NPM is not installed. Aborting.$(NC)"; exit 1; }
42
+ @echo "$(GREEN)All required tools are installed.$(NC)"
43
+
44
+
45
+ help: ## show this help message
46
+ @echo '----'
47
+ @grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | \
48
+ awk -F ':.*##' '{printf "\033[36mmake %s\033[0m: %s\n", $$1, $$2}' | \
49
+ column -c2 -t -s :
50
+ @echo '----'
51
+
52
+ ######################
53
+ # INSTALL PROJECT
54
+ ######################
55
+
56
+ reinstall_backend: ## forces reinstall all dependencies (no caching)
57
+ @echo 'Installing backend dependencies'
58
+ @uv sync -n --reinstall --frozen
59
+
60
+ install_backend: ## install the backend dependencies
61
+ @echo 'Installing backend dependencies'
62
+ @uv sync --frozen
63
+
64
+ install_frontend: ## install the frontend dependencies
65
+ @echo 'Installing frontend dependencies'
66
+ @cd src/frontend && npm install > /dev/null 2>&1
67
+
68
+ build_frontend: ## build the frontend static files
69
+ @echo 'Building frontend static files'
70
+ @cd src/frontend && CI='' npm run build > /dev/null 2>&1
71
+ @rm -rf src/backend/base/langflow/frontend
72
+ @cp -r src/frontend/build src/backend/base/langflow/frontend
73
+
74
+ init: check_tools clean_python_cache clean_npm_cache ## initialize the project
75
+ @make install_backend
76
+ @make install_frontend
77
+ @make build_frontend
78
+ @echo "$(GREEN)All requirements are installed.$(NC)"
79
+ @uv run langflow run
80
+
81
+ ######################
82
+ # CLEAN PROJECT
83
+ ######################
84
+
85
+ clean_python_cache:
86
+ @echo "Cleaning Python cache..."
87
+ find . -type d -name '__pycache__' -exec rm -r {} +
88
+ find . -type f -name '*.py[cod]' -exec rm -f {} +
89
+ find . -type f -name '*~' -exec rm -f {} +
90
+ find . -type f -name '.*~' -exec rm -f {} +
91
+ find . -type d -empty -delete
92
+ @echo "$(GREEN)Python cache cleaned.$(NC)"
93
+
94
+ clean_npm_cache:
95
+ @echo "Cleaning npm cache..."
96
+ cd src/frontend && npm cache clean --force
97
+ rm -rf src/frontend/node_modules src/frontend/build src/backend/base/langflow/frontend src/frontend/package-lock.json
98
+ @echo "$(GREEN)NPM cache and frontend directories cleaned.$(NC)"
99
+
100
+ clean_all: clean_python_cache clean_npm_cache # clean all caches and temporary directories
101
+ @echo "$(GREEN)All caches and temporary directories cleaned.$(NC)"
102
+
103
+ setup_uv: ## install poetry using pipx
104
+ pipx install uv
105
+
106
+ add:
107
+ @echo 'Adding dependencies'
108
+ ifdef devel
109
+ @cd src/backend/base && uv add --group dev $(devel)
110
+ endif
111
+
112
+ ifdef main
113
+ @uv add $(main)
114
+ endif
115
+
116
+ ifdef base
117
+ @cd src/backend/base && uv add $(base)
118
+ endif
119
+
120
+
121
+
122
+ ######################
123
+ # CODE TESTS
124
+ ######################
125
+
126
+ coverage: ## run the tests and generate a coverage report
127
+ @uv run coverage run
128
+ @uv run coverage erase
129
+
130
+ unit_tests: ## run unit tests
131
+ @uv sync --extra dev --frozen
132
+ @EXTRA_ARGS=""
133
+ @if [ "$(async)" = "true" ]; then \
134
+ EXTRA_ARGS="$$EXTRA_ARGS --instafail -n auto"; \
135
+ fi; \
136
+ if [ "$(lf)" = "true" ]; then \
137
+ EXTRA_ARGS="$$EXTRA_ARGS --lf"; \
138
+ fi; \
139
+ if [ "$(ff)" = "true" ]; then \
140
+ EXTRA_ARGS="$$EXTRA_ARGS --ff"; \
141
+ fi; \
142
+ uv run pytest src/backend/tests --ignore=src/backend/tests/integration $$EXTRA_ARGS --instafail -ra -m 'not api_key_required' --durations-path src/backend/tests/.test_durations --splitting-algorithm least_duration $(args)
143
+
144
+ unit_tests_looponfail:
145
+ @make unit_tests args="-f"
146
+
147
+ integration_tests:
148
+ uv run pytest src/backend/tests/integration \
149
+ --instafail -ra \
150
+ $(args)
151
+
152
+ integration_tests_no_api_keys:
153
+ uv run pytest src/backend/tests/integration \
154
+ --instafail -ra -m "not api_key_required" \
155
+ $(args)
156
+
157
+ integration_tests_api_keys:
158
+ uv run pytest src/backend/tests/integration \
159
+ --instafail -ra -m "api_key_required" \
160
+ $(args)
161
+
162
+ tests: ## run unit, integration, coverage tests
163
+ @echo 'Running Unit Tests...'
164
+ make unit_tests
165
+ @echo 'Running Integration Tests...'
166
+ make integration_tests
167
+ @echo 'Running Coverage Tests...'
168
+ make coverage
169
+
170
+ ######################
171
+ # CODE QUALITY
172
+ ######################
173
+
174
+ codespell: ## run codespell to check spelling
175
+ @poetry install --with spelling
176
+ poetry run codespell --toml pyproject.toml
177
+
178
+ fix_codespell: ## run codespell to fix spelling errors
179
+ @poetry install --with spelling
180
+ poetry run codespell --toml pyproject.toml --write
181
+
182
+ format: ## run code formatters
183
+ @uv run ruff check . --fix
184
+ @uv run ruff format . --config pyproject.toml
185
+ @cd src/frontend && npm run format
186
+
187
+ unsafe_fix:
188
+ @uv run ruff check . --fix --unsafe-fixes
189
+
190
+ lint: install_backend ## run linters
191
+ @uv run mypy --namespace-packages -p "langflow"
192
+
193
+ install_frontendci:
194
+ @cd src/frontend && npm ci > /dev/null 2>&1
195
+
196
+ install_frontendc:
197
+ @cd src/frontend && rm -rf node_modules package-lock.json && npm install > /dev/null 2>&1
198
+
199
+ run_frontend: ## run the frontend
200
+ @-kill -9 `lsof -t -i:3000`
201
+ @cd src/frontend && npm start
202
+
203
+ tests_frontend: ## run frontend tests
204
+ ifeq ($(UI), true)
205
+ @cd src/frontend && npx playwright test --ui --project=chromium
206
+ else
207
+ @cd src/frontend && npx playwright test --project=chromium
208
+ endif
209
+
210
+ run_cli: install_frontend install_backend build_frontend ## run the CLI
211
+ @echo 'Running the CLI'
212
+ @uv run langflow run \
213
+ --frontend-path $(path) \
214
+ --log-level $(log_level) \
215
+ --host $(host) \
216
+ --port $(port) \
217
+ $(if $(env),--env-file $(env),) \
218
+ $(if $(filter false,$(open_browser)),--no-open-browser)
219
+
220
+ run_cli_debug:
221
+ @echo 'Running the CLI in debug mode'
222
+ @make install_frontend > /dev/null
223
+ @echo 'Building the frontend'
224
+ @make build_frontend > /dev/null
225
+ @echo 'Install backend dependencies'
226
+ @make install_backend > /dev/null
227
+ ifdef env
228
+ @make start env=$(env) host=$(host) port=$(port) log_level=debug
229
+ else
230
+ @make start host=$(host) port=$(port) log_level=debug
231
+ endif
232
+
233
+
234
+ setup_devcontainer: ## set up the development container
235
+ make install_backend
236
+ make install_frontend
237
+ make build_frontend
238
+ uv run langflow --frontend-path src/frontend/build
239
+
240
+ setup_env: ## set up the environment
241
+ @sh ./scripts/setup/setup_env.sh
242
+
243
+ frontend: install_frontend ## run the frontend in development mode
244
+ make run_frontend
245
+
246
+ frontendc: install_frontendc
247
+ make run_frontend
248
+
249
+
250
+ backend: setup_env install_backend ## run the backend in development mode
251
+ @-kill -9 $$(lsof -t -i:7860) || true
252
+ ifdef login
253
+ @echo "Running backend autologin is $(login)";
254
+ LANGFLOW_AUTO_LOGIN=$(login) uv run uvicorn \
255
+ --factory langflow.main:create_app \
256
+ --host 0.0.0.0 \
257
+ --port $(port) \
258
+ $(if $(filter-out 1,$(workers)),, --reload) \
259
+ --env-file $(env) \
260
+ --loop asyncio \
261
+ $(if $(workers),--workers $(workers),)
262
+ else
263
+ @echo "Running backend respecting the $(env) file";
264
+ uv run uvicorn \
265
+ --factory langflow.main:create_app \
266
+ --host 0.0.0.0 \
267
+ --port $(port) \
268
+ $(if $(filter-out 1,$(workers)),, --reload) \
269
+ --env-file $(env) \
270
+ --loop asyncio \
271
+ $(if $(workers),--workers $(workers),)
272
+ endif
273
+
274
+ build_and_run: setup_env ## build the project and run it
275
+ rm -rf dist
276
+ rm -rf src/backend/base/dist
277
+ make build
278
+ uv run pip install dist/*.tar.gz
279
+ uv run langflow run
280
+
281
+ build_and_install: ## build the project and install it
282
+ @echo 'Removing dist folder'
283
+ rm -rf dist
284
+ rm -rf src/backend/base/dist
285
+ make build && uv run pip install dist/*.whl && pip install src/backend/base/dist/*.whl --force-reinstall
286
+
287
+ build: setup_env ## build the frontend static files and package the project
288
+ ifdef base
289
+ make install_frontendci
290
+ make build_frontend
291
+ make build_langflow_base args="$(args)"
292
+ endif
293
+
294
+ ifdef main
295
+ make install_frontendci
296
+ make build_frontend
297
+ make build_langflow_base args="$(args)"
298
+ make build_langflow args="$(args)"
299
+ endif
300
+
301
+ build_langflow_base:
302
+ cd src/backend/base && uv build $(args)
303
+ rm -rf src/backend/base/langflow/frontend
304
+
305
+ build_langflow_backup:
306
+ uv lock && uv build
307
+
308
+ build_langflow:
309
+ uv lock --no-upgrade
310
+ uv build $(args)
311
+ ifdef restore
312
+ mv pyproject.toml.bak pyproject.toml
313
+ mv uv.lock.bak uv.lock
314
+ endif
315
+
316
+
317
+ docker_build: dockerfile_build clear_dockerimage ## build DockerFile
318
+
319
+ docker_build_backend: dockerfile_build_be clear_dockerimage ## build Backend DockerFile
320
+
321
+ docker_build_frontend: dockerfile_build_fe clear_dockerimage ## build Frontend Dockerfile
322
+
323
+ dockerfile_build:
324
+ @echo 'BUILDING DOCKER IMAGE: ${DOCKERFILE}'
325
+ @docker build --rm \
326
+ -f ${DOCKERFILE} \
327
+ -t langflow:${VERSION} .
328
+
329
+ dockerfile_build_be: dockerfile_build
330
+ @echo 'BUILDING DOCKER IMAGE BACKEND: ${DOCKERFILE_BACKEND}'
331
+ @docker build --rm \
332
+ --build-arg LANGFLOW_IMAGE=langflow:${VERSION} \
333
+ -f ${DOCKERFILE_BACKEND} \
334
+ -t langflow_backend:${VERSION} .
335
+
336
+ dockerfile_build_fe: dockerfile_build
337
+ @echo 'BUILDING DOCKER IMAGE FRONTEND: ${DOCKERFILE_FRONTEND}'
338
+ @docker build --rm \
339
+ --build-arg LANGFLOW_IMAGE=langflow:${VERSION} \
340
+ -f ${DOCKERFILE_FRONTEND} \
341
+ -t langflow_frontend:${VERSION} .
342
+
343
+ clear_dockerimage:
344
+ @echo 'Clearing the docker build'
345
+ @if docker images -f "dangling=true" -q | grep -q '.*'; then \
346
+ docker rmi $$(docker images -f "dangling=true" -q); \
347
+ fi
348
+
349
+ docker_compose_up: docker_build docker_compose_down
350
+ @echo 'Running docker compose up'
351
+ docker compose -f $(DOCKER_COMPOSE) up --remove-orphans
352
+
353
+ docker_compose_down:
354
+ @echo 'Running docker compose down'
355
+ docker compose -f $(DOCKER_COMPOSE) down || true
356
+
357
+ dcdev_up:
358
+ @echo 'Running docker compose up'
359
+ docker compose -f docker/dev.docker-compose.yml down || true
360
+ docker compose -f docker/dev.docker-compose.yml up --remove-orphans
361
+
362
+ lock_base:
363
+ cd src/backend/base && uv lock
364
+
365
+ lock_langflow:
366
+ uv lock
367
+
368
+ lock: ## lock dependencies
369
+ @echo 'Locking dependencies'
370
+ cd src/backend/base && uv lock
371
+ uv lock
372
+
373
+ update: ## update dependencies
374
+ @echo 'Updating dependencies'
375
+ cd src/backend/base && uv sync --upgrade
376
+ uv sync --upgrade
377
+
378
+ publish_base:
379
+ cd src/backend/base && uv publish
380
+
381
+ publish_langflow:
382
+ uv publish
383
+
384
+ publish_base_testpypi:
385
+ # TODO: update this to use the test-pypi repository
386
+ cd src/backend/base && uv publish -r test-pypi
387
+
388
+ publish_langflow_testpypi:
389
+ # TODO: update this to use the test-pypi repository
390
+ uv publish -r test-pypi
391
+
392
+ publish: ## build the frontend static files and package the project and publish it to PyPI
393
+ @echo 'Publishing the project'
394
+ ifdef base
395
+ make publish_base
396
+ endif
397
+
398
+ ifdef main
399
+ make publish_langflow
400
+ endif
401
+
402
+ publish_testpypi: ## build the frontend static files and package the project and publish it to PyPI
403
+ @echo 'Publishing the project'
404
+
405
+ ifdef base
406
+ #TODO: replace with uvx twine upload dist/*
407
+ poetry config repositories.test-pypi https://test.pypi.org/legacy/
408
+ make publish_base_testpypi
409
+ endif
410
+
411
+ ifdef main
412
+ #TODO: replace with uvx twine upload dist/*
413
+ poetry config repositories.test-pypi https://test.pypi.org/legacy/
414
+ make publish_langflow_testpypi
415
+ endif
416
+
417
+
418
+ # example make alembic-revision message="Add user table"
419
+ alembic-revision: ## generate a new migration
420
+ @echo 'Generating a new Alembic revision'
421
+ cd src/backend/base/langflow/ && uv run alembic revision --autogenerate -m "$(message)"
422
+
423
+
424
+ alembic-upgrade: ## upgrade database to the latest version
425
+ @echo 'Upgrading database to the latest version'
426
+ cd src/backend/base/langflow/ && uv run alembic upgrade head
427
+
428
+ alembic-downgrade: ## downgrade database by one version
429
+ @echo 'Downgrading database by one version'
430
+ cd src/backend/base/langflow/ && uv run alembic downgrade -1
431
+
432
+ alembic-current: ## show current revision
433
+ @echo 'Showing current Alembic revision'
434
+ cd src/backend/base/langflow/ && uv run alembic current
435
+
436
+ alembic-history: ## show migration history
437
+ @echo 'Showing Alembic migration history'
438
+ cd src/backend/base/langflow/ && uv run alembic history --verbose
439
+
440
+ alembic-check: ## check migration status
441
+ @echo 'Running alembic check'
442
+ cd src/backend/base/langflow/ && uv run alembic check
443
+
444
+ alembic-stamp: ## stamp the database with a specific revision
445
+ @echo 'Stamping the database with revision $(revision)'
446
+ cd src/backend/base/langflow/ && uv run alembic stamp $(revision)
README.md CHANGED
@@ -1,11 +0,0 @@
1
- ---
2
- title: Agent Flow
3
- emoji: 🐠
4
- colorFrom: indigo
5
- colorTo: purple
6
- sdk: static
7
- pinned: false
8
- license: mit
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference