refactor(rebrand): sweep the remaining langflow — env vars, identifiers, stragglers

Completes the rebrand per direction: LANGFLOW_/LANGFLOW -> FLOW_/FLOW (env vars,
headers), langflow_ -> flow_ (settings fields, local vars), camelCase identifiers
(LangflowClient/Logo/HTTPError, builtWithLangflow, getLangflowDesktop) -> Flow*,
and all remaining bare tokens. Fixed the identifier-space hazard (Langflow ->
'Hanzo Flow' is prose-only; in code it collapses to Flow so no identifier gains a
space). compileall of flow + lfx is clean.

Repo-wide langflow now = 4, all the protected MIT attribution to langflow-ai/
langflow in README (legally required; deliberately preserved).

Breaking (per no-backwards-compat / forward-perfection): the LANGFLOW_* env-var
prefix is now FLOW_* — deployments must update their env. CI's uv + frontend
build is the runtime gate.
This commit is contained in:
2026-07-16 10:18:53 -07:00
parent d650dd60f0
commit 94741a8363
1186 changed files with 5983 additions and 5983 deletions
@@ -1,5 +1,5 @@
/**
* Test template for React components in Hanzo Flow.
* Test template for React components in Flow.
*
* Usage:
* 1. Copy this file to `__tests__/ComponentName.test.tsx`
@@ -1,5 +1,5 @@
/**
* Test template for custom React hooks in Hanzo Flow.
* Test template for custom React hooks in Flow.
*
* Usage:
* 1. Copy this file to `__tests__/use-hook-name.test.ts`
@@ -1,5 +1,5 @@
/**
* Test template for utility/helper functions in Hanzo Flow.
* Test template for utility/helper functions in Flow.
*
* Usage:
* 1. Copy this file to `__tests__/util-name.test.ts`
+20 -20
View File
@@ -23,7 +23,7 @@ HANZOFLOW_SAVE_DB_IN_CONFIG_DIR=
HANZOFLOW_DATABASE_URL=sqlite:///./flow.db
# Alembic logs path flag. If set to true, Alembic will log to stdout.
LANGFLOW_ALEMBIC_LOG_TO_STDOUT=False
FLOW_ALEMBIC_LOG_TO_STDOUT=False
# mem0 creates a directory
@@ -51,8 +51,8 @@ HANZOFLOW_DATABASE_CONNECTION_RETRY=false
HANZOFLOW_LANGCHAIN_CACHE=SQLiteCache
# Server host
# Example: LANGFLOW_HOST=localhost
LANGFLOW_HOST=
# Example: FLOW_HOST=localhost
FLOW_HOST=
# Worker processes
# Example: HANZOFLOW_WORKERS=1
@@ -71,8 +71,8 @@ HANZOFLOW_LOG_LEVEL=
HANZOFLOW_LOG_FILE=
# Time/Size for log to rotate
# Example: LANGFLOW_LOG_ROTATION=‘10 MB’/‘1 day’
LANGFLOW_LOG_ROTATION=
# Example: FLOW_LOG_ROTATION=‘10 MB’/‘1 day’
FLOW_LOG_ROTATION=
# Path to the frontend directory containing build files
# Example: HANZOFLOW_FRONTEND_PATH=/path/to/frontend/build/files
@@ -98,15 +98,15 @@ HANZOFLOW_REMOVE_API_KEYS=
# HANZOFLOW_REDIS_CACHE_EXPIRE (default: 3600)
HANZOFLOW_CACHE_TYPE=
# Set LANGFLOW_AUTO_LOGIN to false if you want to disable auto login
# and use the login form to login. LANGFLOW_SUPERUSER and LANGFLOW_SUPERUSER_PASSWORD
# Set FLOW_AUTO_LOGIN to false if you want to disable auto login
# and use the login form to login. FLOW_SUPERUSER and FLOW_SUPERUSER_PASSWORD
# must be set if AUTO_LOGIN is set to false
# Values: true, false
HANZOFLOW_AUTO_LOGIN=
# SET LANGFLOW_ENABLE_SUPERUSER_CLI to false to disable
# SET FLOW_ENABLE_SUPERUSER_CLI to false to disable
# superuser creation via the CLI
LANGFLOW_ENABLE_SUPERUSER_CLI=
FLOW_ENABLE_SUPERUSER_CLI=
# Superuser username
# Example: HANZOFLOW_SUPERUSER=admin
@@ -120,16 +120,16 @@ HANZOFLOW_SUPERUSER_PASSWORD=
# Controls how API keys are validated for the x-api-key header
# Values: db, env
# - db (default): Validates against API keys stored in the database
# - env: Validates against the LANGFLOW_API_KEY environment variable
# Example: LANGFLOW_API_KEY_SOURCE=db
LANGFLOW_API_KEY_SOURCE=
# - env: Validates against the FLOW_API_KEY environment variable
# Example: FLOW_API_KEY_SOURCE=db
FLOW_API_KEY_SOURCE=
# API Key (only used when LANGFLOW_API_KEY_SOURCE=env)
# API Key (only used when FLOW_API_KEY_SOURCE=env)
# The API key to use for authentication when API_KEY_SOURCE is set to 'env'
# This allows injecting a pre-defined API key via environment variables
# (useful for Kubernetes Secrets, CI/CD pipelines, etc.)
# Example: LANGFLOW_API_KEY=your-secure-api-key
LANGFLOW_API_KEY=
# Example: FLOW_API_KEY=your-secure-api-key
FLOW_API_KEY=
# Should store environment variables in the database
# Values: true, false
@@ -140,19 +140,19 @@ HANZOFLOW_STORE_ENVIRONMENT_VARIABLES=
# Values: true, false
# Default: false (for backward compatibility)
# Set to true to enable protection against SSRF attacks
LANGFLOW_SSRF_PROTECTION_ENABLED=
FLOW_SSRF_PROTECTION_ENABLED=
# SSRF Allowed Hosts
# Comma-separated list of hosts/IPs/CIDR ranges to allow despite SSRF protection
# Supports: exact hostnames, wildcard domains (*.example.com), exact IPs, CIDR ranges
# Example: LANGFLOW_SSRF_ALLOWED_HOSTS=internal-api.company.local,192.168.1.0/24,*.dev.internal
# Note: Only takes effect when LANGFLOW_SSRF_PROTECTION_ENABLED=true
LANGFLOW_SSRF_ALLOWED_HOSTS=
# Example: FLOW_SSRF_ALLOWED_HOSTS=internal-api.company.local,192.168.1.0/24,*.dev.internal
# Note: Only takes effect when FLOW_SSRF_PROTECTION_ENABLED=true
FLOW_SSRF_ALLOWED_HOSTS=
# Should enable the MCP composer feature in MCP projects
# Values: true, false
# Default: true
LANGFLOW_MCP_COMPOSER_ENABLED=
FLOW_MCP_COMPOSER_ENABLED=
# STORE_URL
# Example: HANZOFLOW_STORE_URL=https://api.flow.store
+3 -3
View File
@@ -1,5 +1,5 @@
name: "🐛 Bug Report"
description: Submit a bug report to help us improve Hanzo Flow
description: Submit a bug report to help us improve Flow
labels: [ "bug" ]
body:
- type: markdown
@@ -87,7 +87,7 @@ body:
- type: input
id: flow-version
attributes:
label: Hanzo Flow Version
label: Flow Version
placeholder: ex. 1.0.9
validations:
required: true
@@ -98,7 +98,7 @@ body:
label: "Python Version"
description: |
**Hanzo Flow requires Python version 3.10 or greater.**
**Flow requires Python version 3.10 or greater.**
options:
- "3.12"
- "3.11"
+2 -2
View File
@@ -1,5 +1,5 @@
name: "🚀 Feature Request"
description: Submit a proposal/request for a new Hanzo Flow feature
description: Submit a proposal/request for a new Flow feature
labels: [ "enhancement" ]
body:
- type: textarea
@@ -25,4 +25,4 @@ body:
attributes:
label: Your Contribution
description: |
Is there any way that you could help, e.g., by submitting a PR? Make sure to read the CONTRIBUTING.md guidelines for Hanzo Flow before proceeding.
Is there any way that you could help, e.g., by submitting a PR? Make sure to read the CONTRIBUTING.md guidelines for Flow before proceeding.
+1 -1
View File
@@ -1,4 +1,4 @@
self-hosted-runner:
labels:
- flow-ai-arm64-40gb-ephemeral
- Hanzo Flow-runner
- Flow-runner
+6 -6
View File
@@ -4,7 +4,7 @@ on:
workflow_dispatch:
inputs:
flow-version:
description: "Hanzo Flow version to test from PyPI (leave empty to test from source)"
description: "Flow version to test from PyPI (leave empty to test from source)"
required: false
type: string
default: ""
@@ -50,12 +50,12 @@ jobs:
- name: Build frontend
run: make build_frontend
- name: Build base package
run: make build_langflow_base args="--wheel"
run: make build_flow_base args="--wheel"
- name: Move base package to correct directory
run: |
# Base package builds to dist/ but should be in src/backend/base/dist/
mkdir -p src/backend/base/dist
mv dist/langflow_base*.whl src/backend/base/dist/
mv dist/flow_base*.whl src/backend/base/dist/
- name: Build LFX package
run: |
cd src/lfx
@@ -65,7 +65,7 @@ jobs:
cd src/sdk
uv build --wheel --out-dir dist
- name: Build main package
run: make build_langflow args="--wheel"
run: make build_flow args="--wheel"
- name: Build bundle wheels
id: build-bundles
run: |
@@ -305,7 +305,7 @@ jobs:
MAIN_WHEELS=()
while IFS= read -r wheel; do
MAIN_WHEELS+=("$wheel")
done < <(find ./main-dist -name "flow*.whl" ! -name "langflow_base*.whl" -type f | sort)
done < <(find ./main-dist -name "flow*.whl" ! -name "flow_base*.whl" -type f | sort)
if [ ${#MAIN_WHEELS[@]} -ne 1 ]; then
echo "Expected exactly one flow wheel in ./main-dist, found ${#MAIN_WHEELS[@]}"
find ./main-dist -name "*.whl" -type f | sort
@@ -594,7 +594,7 @@ jobs:
MAIN_WHEELS=()
while IFS= read -r wheel; do
MAIN_WHEELS+=("$wheel")
done < <(find ./main-dist -name "flow*.whl" ! -name "langflow_base*.whl" -type f | sort)
done < <(find ./main-dist -name "flow*.whl" ! -name "flow_base*.whl" -type f | sort)
if [ ${#MAIN_WHEELS[@]} -ne 1 ]; then
echo "Expected exactly one flow wheel in ./main-dist, found ${#MAIN_WHEELS[@]}"
find ./main-dist -name "*.whl" -type f | sort
+61 -61
View File
@@ -10,17 +10,17 @@ on:
workflow_dispatch:
inputs:
nightly_tag:
description: "Nightly tag to test migration to (e.g., langflowai/flow-nightly:latest)"
description: "Nightly tag to test migration to (e.g., flowai/flow-nightly:latest)"
required: false
type: string
default: "langflowai/flow-nightly:latest"
default: "flowai/flow-nightly:latest"
# Note: This workflow is called by nightly_build.yml after Docker images are built
env:
PYTHON_VERSION: "3.13"
POSTGRES_DB: langflow_test
POSTGRES_DB: flow_test
POSTGRES_USER: flow
POSTGRES_PASSWORD: langflow_test_pass # pragma: allowlist secret
POSTGRES_PASSWORD: flow_test_pass # pragma: allowlist secret
jobs:
migration-pip-venv:
@@ -59,7 +59,7 @@ jobs:
mkdir -p migration-test
cd migration-test
- name: Install latest stable Hanzo Flow with PostgreSQL
- name: Install latest stable Flow with PostgreSQL
working-directory: migration-test
run: |
echo "Installing latest stable flow[postgresql]..."
@@ -68,27 +68,27 @@ jobs:
uv pip install "flow[postgresql]"
# Verify installation
python -c 'from importlib.metadata import version; print("Installed Hanzo Flow version:", version("flow"))'
python -c 'from importlib.metadata import version; print("Installed Flow version:", version("flow"))'
- name: Initialize database with stable version
working-directory: migration-test
env:
LANGFLOW_DATABASE_URL: postgresql://${{ env.POSTGRES_USER }}:${{ env.POSTGRES_PASSWORD }}@localhost:5432/${{ env.POSTGRES_DB }} # pragma: allowlist secret
FLOW_DATABASE_URL: postgresql://${{ env.POSTGRES_USER }}:${{ env.POSTGRES_PASSWORD }}@localhost:5432/${{ env.POSTGRES_DB }} # pragma: allowlist secret
run: |
source .venv/bin/activate
echo "Starting Hanzo Flow to initialize database..."
echo "Starting Flow to initialize database..."
# shellcheck disable=SC2016
timeout 120 bash -c '
python -m flow run --host 127.0.0.1 --port 7860 --backend-only &
LANGFLOW_PID=$!
FLOW_PID=$!
until curl -f http://127.0.0.1:7860/health_check 2>/dev/null; do
sleep 2
done
kill $LANGFLOW_PID
wait $LANGFLOW_PID 2>/dev/null || true
kill $FLOW_PID
wait $FLOW_PID 2>/dev/null || true
' || {
echo "Failed to start Hanzo Flow stable version"
echo "Failed to start Flow stable version"
exit 1
}
@@ -97,13 +97,13 @@ jobs:
- name: Create witness flow
working-directory: migration-test
env:
LANGFLOW_DATABASE_URL: postgresql://${{ env.POSTGRES_USER }}:${{ env.POSTGRES_PASSWORD }}@localhost:5432/${{ env.POSTGRES_DB }}
FLOW_DATABASE_URL: postgresql://${{ env.POSTGRES_USER }}:${{ env.POSTGRES_PASSWORD }}@localhost:5432/${{ env.POSTGRES_DB }}
run: |
source .venv/bin/activate
# Start Hanzo Flow briefly to create test data
# Start Flow briefly to create test data
python -m flow run --host 127.0.0.1 --port 7860 --backend-only &
LANGFLOW_PID=$!
FLOW_PID=$!
# Wait for startup
timeout 60 bash -c 'until curl -f http://127.0.0.1:7860/health_check 2>/dev/null; do sleep 2; done'
@@ -112,7 +112,7 @@ jobs:
TOKEN=$(curl -fsS http://127.0.0.1:7860/api/v1/auto_login | python3 -c "import json,sys; print(json.load(sys.stdin)['access_token'])")
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
echo "❌ Failed to get authentication token"
kill $LANGFLOW_PID
kill $FLOW_PID
exit 1
fi
echo "✅ Authentication token obtained"
@@ -147,9 +147,9 @@ jobs:
fi
echo "✅ Witness credential created successfully"
# Stop Hanzo Flow
kill $LANGFLOW_PID
wait $LANGFLOW_PID 2>/dev/null || true
# Stop Flow
kill $FLOW_PID
wait $FLOW_PID 2>/dev/null || true
echo "Witness data created (flow + credential)"
@@ -158,7 +158,7 @@ jobs:
run: |
source .venv/bin/activate
NIGHTLY_TAG="${{ inputs.nightly_tag || 'langflowai/flow-nightly:latest' }}"
NIGHTLY_TAG="${{ inputs.nightly_tag || 'flowai/flow-nightly:latest' }}"
echo "Upgrading to nightly version: $NIGHTLY_TAG"
# Remove stable distributions before installing nightly.
@@ -169,7 +169,7 @@ jobs:
echo "Removing stable flow to avoid namespace collision with nightly..."
uv pip uninstall -y flow flow-base || true
# Extract version from Docker tag (format: langflowai/flow-nightly:v1.10.0.dev20260522)
# Extract version from Docker tag (format: flowai/flow-nightly:v1.10.0.dev20260522)
if [[ "$NIGHTLY_TAG" == *":"* ]]; then
VERSION="${NIGHTLY_TAG##*:}"
echo "Extracted version from tag: $VERSION"
@@ -192,49 +192,49 @@ jobs:
fi
# Verify upgrade
python -c 'from importlib.metadata import version; print("Upgraded to Hanzo Flow Nightly version:", version("flow-nightly"))'
python -c 'from importlib.metadata import version; print("Upgraded to Flow Nightly version:", version("flow-nightly"))'
- name: Run migration and verify startup
working-directory: migration-test
env:
LANGFLOW_DATABASE_URL: postgresql://${{ env.POSTGRES_USER }}:${{ env.POSTGRES_PASSWORD }}@localhost:5432/${{ env.POSTGRES_DB }} # pragma: allowlist secret
FLOW_DATABASE_URL: postgresql://${{ env.POSTGRES_USER }}:${{ env.POSTGRES_PASSWORD }}@localhost:5432/${{ env.POSTGRES_DB }} # pragma: allowlist secret
run: |
source .venv/bin/activate
echo "Starting Hanzo Flow nightly to run migrations..."
echo "Starting Flow nightly to run migrations..."
# shellcheck disable=SC2016
timeout 180 bash -c '
python -m flow run --host 127.0.0.1 --port 7860 --backend-only > langflow_nightly.log 2>&1 &
LANGFLOW_PID=$!
python -m flow run --host 127.0.0.1 --port 7860 --backend-only > flow_nightly.log 2>&1 &
FLOW_PID=$!
until curl -f http://127.0.0.1:7860/health_check 2>/dev/null; do
if ! kill -0 $LANGFLOW_PID 2>/dev/null; then
echo "Hanzo Flow process died during startup"
cat langflow_nightly.log
if ! kill -0 $FLOW_PID 2>/dev/null; then
echo "Flow process died during startup"
cat flow_nightly.log
exit 1
fi
sleep 2
done
echo "Hanzo Flow nightly started successfully"
kill $LANGFLOW_PID
wait $LANGFLOW_PID 2>/dev/null || true
echo "Flow nightly started successfully"
kill $FLOW_PID
wait $FLOW_PID 2>/dev/null || true
' || {
echo "Failed to start Hanzo Flow nightly version"
cat langflow_nightly.log || true
echo "Failed to start Flow nightly version"
cat flow_nightly.log || true
exit 1
}
- name: Verify witness data persisted
working-directory: migration-test
env:
LANGFLOW_DATABASE_URL: postgresql://${{ env.POSTGRES_USER }}:${{ env.POSTGRES_PASSWORD }}@localhost:5432/${{ env.POSTGRES_DB }}
FLOW_DATABASE_URL: postgresql://${{ env.POSTGRES_USER }}:${{ env.POSTGRES_PASSWORD }}@localhost:5432/${{ env.POSTGRES_DB }}
run: |
source .venv/bin/activate
# Start Hanzo Flow to query data
# Start Flow to query data
python -m flow run --host 127.0.0.1 --port 7860 --backend-only &
LANGFLOW_PID=$!
FLOW_PID=$!
timeout 60 bash -c 'until curl -f http://127.0.0.1:7860/health_check 2>/dev/null; do sleep 2; done'
@@ -242,7 +242,7 @@ jobs:
TOKEN=$(curl -fsS http://127.0.0.1:7860/api/v1/auto_login | python3 -c "import json,sys; print(json.load(sys.stdin)['access_token'])")
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
echo "❌ Failed to get authentication token"
kill $LANGFLOW_PID
kill $FLOW_PID
exit 1
fi
echo "✅ Authentication token obtained"
@@ -256,7 +256,7 @@ jobs:
else
echo "❌ Witness flow NOT found after migration"
cat flows_after_migration.json
kill $LANGFLOW_PID
kill $FLOW_PID
exit 1
fi
@@ -269,12 +269,12 @@ jobs:
else
echo "❌ Witness credential NOT found after migration"
cat variables_after_migration.json
kill $LANGFLOW_PID
kill $FLOW_PID
exit 1
fi
kill $LANGFLOW_PID
wait $LANGFLOW_PID 2>/dev/null || true
kill $FLOW_PID
wait $FLOW_PID 2>/dev/null || true
- name: Upload logs on failure
if: failure()
@@ -306,11 +306,11 @@ jobs:
cat > docker-compose.yml <<'EOF'
services:
flow:
image: langflowai/flow:latest
image: flowai/flow:latest
ports:
- "7860:7860"
environment: # pragma: allowlist secret
- LANGFLOW_DATABASE_URL=postgresql://flow:flow@postgres:5432/flow # pragma: allowlist secret
- FLOW_DATABASE_URL=postgresql://flow:flow@postgres:5432/flow # pragma: allowlist secret
depends_on:
postgres:
condition: service_healthy
@@ -327,7 +327,7 @@ jobs:
- POSTGRES_PASSWORD=flow # pragma: allowlist secret
- POSTGRES_DB=flow
volumes:
- langflow_postgres_data:/var/lib/postgresql/data
- flow_postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U flow"]
interval: 10s
@@ -335,23 +335,23 @@ jobs:
retries: 5
volumes:
langflow_postgres_data:
flow_postgres_data:
EOF
- name: Start stable Hanzo Flow with Docker Compose
- name: Start stable Flow with Docker Compose
working-directory: docker-migration-test
run: |
echo "Starting Hanzo Flow stable version..."
echo "Starting Flow stable version..."
docker compose up -d
echo "Waiting for Hanzo Flow to be healthy..."
echo "Waiting for Flow to be healthy..."
timeout 180 bash -c 'until docker compose exec -T flow curl -f http://localhost:7860/health_check 2>/dev/null; do sleep 5; done' || {
echo "Hanzo Flow stable failed to start"
echo "Flow stable failed to start"
docker compose logs
exit 1
}
echo "Hanzo Flow stable is running"
echo "Flow stable is running"
- name: Create witness flow via API
working-directory: docker-migration-test
@@ -394,43 +394,43 @@ jobs:
fi
echo "✅ Witness credential created successfully"
- name: Stop stable Hanzo Flow (keep PostgreSQL volume)
- name: Stop stable Flow (keep PostgreSQL volume)
working-directory: docker-migration-test
run: |
echo "Stopping Hanzo Flow stable..."
echo "Stopping Flow stable..."
docker compose stop flow
docker compose rm -f flow
- name: Update to nightly image
working-directory: docker-migration-test
run: |
NIGHTLY_TAG="${{ inputs.nightly_tag || 'langflowai/flow-nightly:latest' }}"
NIGHTLY_TAG="${{ inputs.nightly_tag || 'flowai/flow-nightly:latest' }}"
# Strip 'v' prefix from version part — Docker images are published without it
# e.g. langflowai/flow-nightly:v1.10.0.dev20260522 → langflowai/flow-nightly:1.10.0.dev20260522
# e.g. flowai/flow-nightly:v1.10.0.dev20260522 → flowai/flow-nightly:1.10.0.dev20260522
VERSION_PART="${NIGHTLY_TAG##*:}"
IMAGE_NAME="${NIGHTLY_TAG%%:*}"
DOCKER_TAG="${IMAGE_NAME}:${VERSION_PART#v}"
echo "Updating to nightly: $DOCKER_TAG"
# Update docker-compose.yml to use nightly image
sed -i "s|image: langflowai/flow:latest|image: $DOCKER_TAG|" docker-compose.yml
sed -i "s|image: flowai/flow:latest|image: $DOCKER_TAG|" docker-compose.yml
cat docker-compose.yml
- name: Start nightly Hanzo Flow with same PostgreSQL volume
- name: Start nightly Flow with same PostgreSQL volume
working-directory: docker-migration-test
run: |
echo "Starting Hanzo Flow nightly version..."
echo "Starting Flow nightly version..."
docker compose up -d flow
echo "Waiting for Hanzo Flow nightly to be healthy..."
echo "Waiting for Flow nightly to be healthy..."
timeout 180 bash -c 'until docker compose exec -T flow curl -f http://localhost:7860/health_check 2>/dev/null; do sleep 5; done' || {
echo "Hanzo Flow nightly failed to start"
echo "Flow nightly failed to start"
docker compose logs flow
exit 1
}
echo "Hanzo Flow nightly started successfully"
echo "Flow nightly started successfully"
- name: Verify witness data persisted
working-directory: docker-migration-test
+11 -11
View File
@@ -83,7 +83,7 @@ jobs:
if [ ${{inputs.pre_release}} == "true" ]; then
last_released_version=$(curl -s "https://registry.hub.docker.com/v2/repositories/ghcr.io/hanzoai/flow/tags?page_size=100" | jq -r '.results[].name' | grep -E '\.rc[0-9]+' | sort -V | tail -n 1)
version="$(uv run ./scripts/ci/langflow_pre_release_tag.py "$version" "$last_released_version")"
version="$(uv run ./scripts/ci/flow_pre_release_tag.py "$version" "$last_released_version")"
echo "Latest base pre-release version: $last_released_version"
echo "Base pre-release version to be released: $version"
else
@@ -129,7 +129,7 @@ jobs:
if [ ${{inputs.pre_release}} == "true" ]; then
last_released_version=$(curl -s "https://registry.hub.docker.com/v2/repositories/ghcr.io/hanzoai/flow/tags?page_size=100" | jq -r '.results[].name' | grep -E '\.rc[0-9]+' | sort -V | tail -n 1)
version="$(uv run ./scripts/ci/langflow_pre_release_tag.py "$version" "$last_released_version")"
version="$(uv run ./scripts/ci/flow_pre_release_tag.py "$version" "$last_released_version")"
echo "Latest main pre-release version: $last_released_version"
echo "Main pre-release version to be released: $version"
else
@@ -155,7 +155,7 @@ jobs:
matrix:
include:
- arch: amd64
runner: [Hanzo Flow-runner]
runner: [Flow-runner]
- arch: arm64
runner:
[self-hosted, linux, ARM64, flow-ai-arm64-40gb-ephemeral]
@@ -226,7 +226,7 @@ jobs:
matrix:
include:
- arch: amd64
runner: [Hanzo Flow-runner]
runner: [Flow-runner]
- arch: arm64
runner:
[self-hosted, linux, ARM64, flow-ai-arm64-40gb-ephemeral]
@@ -297,7 +297,7 @@ jobs:
matrix:
include:
- arch: amd64
runner: [Hanzo Flow-runner]
runner: [Flow-runner]
- arch: arm64
runner:
[self-hosted, linux, ARM64, flow-ai-arm64-40gb-ephemeral]
@@ -335,7 +335,7 @@ jobs:
context: .
push: ${{ inputs.push_to_registry }}
build-args: |
LANGFLOW_IMAGE=ghcr.io/hanzoai/flow:${{ steps.version.outputs.version }}-${{ matrix.arch }}
FLOW_IMAGE=ghcr.io/hanzoai/flow:${{ steps.version.outputs.version }}-${{ matrix.arch }}
file: ./docker/build_and_push_backend.Dockerfile
tags: ${{ steps.tags.outputs.docker_tags }}
platforms: linux/${{ matrix.arch }}
@@ -356,7 +356,7 @@ jobs:
context: .
push: ${{ inputs.push_to_registry }}
build-args: |
LANGFLOW_IMAGE=ghcr.io/hanzoai/flow:${{ steps.version.outputs.version }}-${{ matrix.arch }}
FLOW_IMAGE=ghcr.io/hanzoai/flow:${{ steps.version.outputs.version }}-${{ matrix.arch }}
file: ./docker/build_and_push_backend.Dockerfile
tags: ${{ steps.tags.outputs.ghcr_tags }}
platforms: linux/${{ matrix.arch }}
@@ -372,7 +372,7 @@ jobs:
matrix:
include:
- arch: amd64
runner: [Hanzo Flow-runner]
runner: [Flow-runner]
- arch: arm64
runner:
[self-hosted, linux, ARM64, flow-ai-arm64-40gb-ephemeral]
@@ -443,7 +443,7 @@ jobs:
matrix:
include:
- arch: amd64
runner: [Hanzo Flow-runner]
runner: [Flow-runner]
- arch: arm64
runner:
[self-hosted, linux, ARM64, flow-ai-arm64-40gb-ephemeral]
@@ -514,7 +514,7 @@ jobs:
matrix:
include:
- arch: amd64
runner: [Hanzo Flow-runner]
runner: [Flow-runner]
- arch: arm64
runner:
[self-hosted, linux, ARM64, flow-ai-arm64-40gb-ephemeral]
@@ -696,7 +696,7 @@ jobs:
echo "Creating manifest for $tag"
# Determine architecture-specific tags
if [[ "$tag" == *"langflowai"* ]]; then
if [[ "$tag" == *"flowai"* ]]; then
amd64_tag="${{ steps.tags.outputs.arch_base }}-amd64"
arm64_tag="${{ steps.tags.outputs.arch_base }}-arm64"
else
+11 -11
View File
@@ -170,28 +170,28 @@ jobs:
fi
if [[ "${{ inputs.release_type }}" == "base" || "${{ inputs.release_type }}" == "nightly-base" ]]; then
# LANGFLOW-BASE RELEASE
# FLOW-BASE RELEASE
echo "docker_tags=ghcr.io/hanzoai/flow${nightly_suffix}:base-${{ needs.get-version.outputs.version }},ghcr.io/hanzoai/flow${nightly_suffix}:base-latest" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/hanzoai/flow${nightly_suffix}:base-${{ needs.get-version.outputs.version }},ghcr.io/hanzoai/flow${nightly_suffix}:base-latest" >> $GITHUB_OUTPUT
echo "file=./docker/build_and_push_base.Dockerfile" >> $GITHUB_OUTPUT
else
if [[ "${{ inputs.pre_release }}" == "true" ]]; then
# LANGFLOW-MAIN PRE-RELEASE
# FLOW-MAIN PRE-RELEASE
echo "docker_tags=ghcr.io/hanzoai/flow${nightly_suffix}:${{ needs.get-version.outputs.version }}" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/hanzoai/flow${nightly_suffix}:${{ needs.get-version.outputs.version }}" >> $GITHUB_OUTPUT
echo "file=./docker/build_and_push.Dockerfile" >> $GITHUB_OUTPUT
elif [[ "${{ inputs.release_type }}" == "main-ep" ]]; then
# LANGFLOW-MAIN (ENTRYPOINT) RELEASE
# FLOW-MAIN (ENTRYPOINT) RELEASE
echo "docker_tags=ghcr.io/hanzoai/flow-ep${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/hanzoai/flow-ep${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/hanzoai/flow-ep${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/hanzoai/flow-ep${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "file=./docker/build_and_push_ep.Dockerfile" >> $GITHUB_OUTPUT
elif [[ "${{ inputs.release_type }}" == "main" || "${{ inputs.release_type }}" == "nightly-main" ]]; then
# LANGFLOW-MAIN RELEASE
# FLOW-MAIN RELEASE
echo "docker_tags=ghcr.io/hanzoai/flow${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/hanzoai/flow${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/hanzoai/flow${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/hanzoai/flow${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "file=./docker/build_and_push.Dockerfile" >> $GITHUB_OUTPUT
elif [[ "${{ inputs.release_type }}" == "main-all" || "${{ inputs.release_type }}" == "nightly-main-all" ]]; then
# LANGFLOW-MAIN (ALL OPTIONAL DEPS) RELEASE
# FLOW-MAIN (ALL OPTIONAL DEPS) RELEASE
echo "docker_tags=ghcr.io/hanzoai/flow-all${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/hanzoai/flow-all${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/hanzoai/flow-all${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/hanzoai/flow-all${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "file=./docker/build_and_push_with_extras.Dockerfile" >> $GITHUB_OUTPUT
@@ -300,19 +300,19 @@ jobs:
- component: docker-backend
dockerfile: ./docker/build_and_push_backend.Dockerfile
tags: ghcr.io/hanzoai/flow-backend:${{ needs.get-version.outputs.version }},ghcr.io/hanzoai/flow-backend:latest
langflow_image: ghcr.io/hanzoai/flow:${{ needs.get-version.outputs.version }}
flow_image: ghcr.io/hanzoai/flow:${{ needs.get-version.outputs.version }}
- component: docker-frontend
dockerfile: ./docker/frontend/build_and_push_frontend.Dockerfile
tags: ghcr.io/hanzoai/flow-frontend:${{ needs.get-version.outputs.version }},ghcr.io/hanzoai/flow-frontend:latest
langflow_image: ghcr.io/hanzoai/flow:${{ needs.get-version.outputs.version }}
flow_image: ghcr.io/hanzoai/flow:${{ needs.get-version.outputs.version }}
- component: ghcr-backend
dockerfile: ./docker/build_and_push_backend.Dockerfile
tags: ghcr.io/hanzoai/flow-backend:${{ needs.get-version.outputs.version }},ghcr.io/hanzoai/flow-backend:latest
langflow_image: ghcr.io/hanzoai/flow:${{ needs.get-version.outputs.version }}
flow_image: ghcr.io/hanzoai/flow:${{ needs.get-version.outputs.version }}
- component: ghcr-frontend
dockerfile: ./docker/frontend/build_and_push_frontend.Dockerfile
tags: ghcr.io/hanzoai/flow-frontend:${{ needs.get-version.outputs.version }},ghcr.io/hanzoai/flow-frontend:latest
langflow_image: ghcr.io/hanzoai/flow:${{ needs.get-version.outputs.version }}
flow_image: ghcr.io/hanzoai/flow:${{ needs.get-version.outputs.version }}
steps:
- name: Check out the code at a specific ref
uses: actions/checkout@v6
@@ -368,7 +368,7 @@ jobs:
context: .
push: true
build-args: |
LANGFLOW_IMAGE=${{ matrix.langflow_image }}
FLOW_IMAGE=${{ matrix.flow_image }}
file: ${{ matrix.dockerfile }}
tags: ${{ matrix.tags }}
# 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)
@@ -398,4 +398,4 @@ jobs:
- name: Restart HuggingFace Spaces Build
run: |
uv run ./scripts/factory_restart_space.py --space "Hanzo Flow/Hanzo Flow" --token ${{ secrets.HUGGINGFACE_API_TOKEN }}
uv run ./scripts/factory_restart_space.py --space "Flow/Flow" --token ${{ secrets.HUGGINGFACE_API_TOKEN }}
+4 -4
View File
@@ -49,7 +49,7 @@ jobs:
matrix:
include:
- arch: amd64
runner: [Hanzo Flow-runner]
runner: [Flow-runner]
- arch: arm64
runner:
[self-hosted, linux, ARM64, flow-ai-arm64-40gb-ephemeral]
@@ -145,7 +145,7 @@ jobs:
matrix:
include:
- arch: amd64
runner: [Hanzo Flow-runner]
runner: [Flow-runner]
- arch: arm64
runner:
[self-hosted, linux, ARM64, flow-ai-arm64-40gb-ephemeral]
@@ -240,7 +240,7 @@ jobs:
matrix:
include:
- arch: amd64
runner: [Hanzo Flow-runner]
runner: [Flow-runner]
- arch: arm64
runner:
[self-hosted, linux, ARM64, flow-ai-arm64-40gb-ephemeral]
@@ -405,7 +405,7 @@ jobs:
echo "Creating manifest for $tag"
# Determine architecture-specific tags
if [[ "$tag" == *"langflowai"* ]]; then
if [[ "$tag" == *"flowai"* ]]; then
amd64_tag="${{ steps.tags.outputs.arch_base }}-amd64"
arm64_tag="${{ steps.tags.outputs.arch_base }}-arm64"
else
+1 -1
View File
@@ -73,7 +73,7 @@ jobs:
- name: Build backend image
run: |
${{ env.CONTAINER_RUNTIME }} build -t ghcr.io/hanzoai/flow-backend:latest-dev \
--build-arg LANGFLOW_IMAGE=ghcr.io/hanzoai/flow:latest-dev \
--build-arg FLOW_IMAGE=ghcr.io/hanzoai/flow:latest-dev \
-f docker/build_and_push_backend.Dockerfile \
.
- name: Test backend image
+1 -1
View File
@@ -50,7 +50,7 @@ jobs:
- name: Check model/migration consistency
env:
MIGRATION_VALIDATION_CI: "true"
LANGFLOW_TEST_DATABASE_URI: "postgresql://flow:flow@localhost:5432/flow"
FLOW_TEST_DATABASE_URI: "postgresql://flow:flow@localhost:5432/flow"
run: |
uv run pytest src/backend/tests/unit/alembic/test_migration_execution.py -x -v
+9 -9
View File
@@ -125,7 +125,7 @@ jobs:
# If the main tag does not exist in GH, we create the base tag from the existing codebase.
git config --global user.email "[email protected]"
git config --global user.name "Hanzo Flow Bot"
git config --global user.name "Flow Bot"
MAIN_TAG="${{ steps.generate_main_tag.outputs.main_tag }}"
BASE_TAG="${{ steps.generate_base_tag.outputs.base_tag }}"
@@ -151,7 +151,7 @@ jobs:
git commit -m "Update version and project name"
echo "Tagging main with $MAIN_TAG"
if ! git tag -a $MAIN_TAG -m "Hanzo Flow nightly $MAIN_TAG"; then
if ! git tag -a $MAIN_TAG -m "Flow nightly $MAIN_TAG"; then
echo "Tag creation failed. Exiting the workflow."
exit 1
fi
@@ -241,7 +241,7 @@ jobs:
run: |
echo "=== Configuring git ==="
git config --global user.email "[email protected]"
git config --global user.name "Hanzo Flow Bot"
git config --global user.name "Flow Bot"
echo "=== Checking for hash history changes ==="
# Check if there are changes to commit (handles if it's a new file for first run)
@@ -317,7 +317,7 @@ jobs:
release-nightly-build:
if: github.repository == 'hanzoai/flow' && always() && needs.frontend-tests.result != 'failure' && needs.backend-unit-tests.result != 'failure' && needs.build-hash-history.result != 'failure'
name: Run Nightly Hanzo Flow Build
name: Run Nightly Flow Build
needs: [create-nightly-tag, frontend-tests, backend-unit-tests, build-hash-history]
uses: ./.github/workflows/release_nightly.yml
with:
@@ -341,8 +341,8 @@ jobs:
with:
# Pass Docker image reference for docker-compose and version without 'v' prefix for pip
# release_tag format: v1.10.0.dev20260522
# We need: langflowai/flow-nightly:1.10.0.dev20260522 for Docker
nightly_tag: langflowai/flow-nightly:${{ needs.create-nightly-tag.outputs.release_tag }}
# We need: flowai/flow-nightly:1.10.0.dev20260522 for Docker
nightly_tag: flowai/flow-nightly:${{ needs.create-nightly-tag.outputs.release_tag }}
secrets: inherit
slack-notification:
@@ -399,7 +399,7 @@ jobs:
]
}
]
}" ${{ secrets.LANGFLOW_ENG_SLACK_WEBHOOK_URL }}
}" ${{ secrets.FLOW_ENG_SLACK_WEBHOOK_URL }}
merge-hash-history-to-main:
name: Create PR to Merge Hash History to Main
@@ -423,7 +423,7 @@ jobs:
- name: Configure Git
run: |
git config --global user.email "[email protected]"
git config --global user.name "Hanzo Flow Bot"
git config --global user.name "Flow Bot"
- name: "Setup Environment"
uses: astral-sh/setup-uv@v6
@@ -588,4 +588,4 @@ jobs:
]
}
]
}' ${{ secrets.LANGFLOW_ENG_SLACK_WEBHOOK_URL }}
}' ${{ secrets.FLOW_ENG_SLACK_WEBHOOK_URL }}
+10 -10
View File
@@ -249,15 +249,15 @@ jobs:
uses: docker/metadata-action@v5
with:
images: |
langflowai/lfx
flowai/lfx
ghcr.io/flow-ai/lfx
tags: |
type=raw,value=${{ github.event.inputs.version }}${{ matrix.variant == 'alpine' && '-alpine' || '' }}
type=raw,value=latest${{ matrix.variant == 'alpine' && '-alpine' || '' }},enable=${{ github.event.inputs.pre_release == 'false' }}
labels: |
org.opencontainers.image.title=LFX
org.opencontainers.image.description=Hanzo Flow Executor - CLI tool for running Hanzo Flow AI workflows
org.opencontainers.image.vendor=Hanzo Flow
org.opencontainers.image.description=Flow Executor - CLI tool for running Flow AI workflows
org.opencontainers.image.vendor=Flow
org.opencontainers.image.version=${{ github.event.inputs.version }}
- name: Build and push Docker image
@@ -309,13 +309,13 @@ jobs:
### Docker
\`\`\`bash
# Standard image
docker pull langflowai/lfx:${{ github.event.inputs.version }}
docker pull flowai/lfx:${{ github.event.inputs.version }}
# Alpine image (smaller)
docker pull langflowai/lfx:${{ github.event.inputs.version }}-alpine
docker pull flowai/lfx:${{ github.event.inputs.version }}-alpine
# Run a flow
docker run --rm -v \$(pwd):/app/data langflowai/lfx:${{ github.event.inputs.version }} lfx run flow.json --input-value "Hello"
docker run --rm -v \$(pwd):/app/data flowai/lfx:${{ github.event.inputs.version }} lfx run flow.json --input-value "Hello"
\`\`\`
## 📦 What's New
@@ -366,10 +366,10 @@ jobs:
if: needs.build-docker.result == 'success'
run: |
# Test standard image
docker run --rm langflowai/lfx:${{ github.event.inputs.version }} lfx --help
docker run --rm flowai/lfx:${{ github.event.inputs.version }} lfx --help
# Test alpine image
docker run --rm langflowai/lfx:${{ github.event.inputs.version }}-alpine lfx --help
docker run --rm flowai/lfx:${{ github.event.inputs.version }}-alpine lfx --help
# Test with a simple flow
cat > test_flow.json << 'EOF'
@@ -379,7 +379,7 @@ jobs:
}
EOF
docker run --rm -v $(pwd):/app/data langflowai/lfx:${{ github.event.inputs.version }} \
docker run --rm -v $(pwd):/app/data flowai/lfx:${{ github.event.inputs.version }} \
lfx run /app/data/test_flow.json --input-value "test" || true
notify:
@@ -393,7 +393,7 @@ jobs:
run: |
echo "✅ LFX ${{ github.event.inputs.version }} released successfully!"
echo "PyPI: https://pypi.org/project/lfx/${{ github.event.inputs.version }}/"
echo "Docker Hub: https://hub.docker.com/r/langflowai/lfx/tags"
echo "Docker Hub: https://hub.docker.com/r/flowai/lfx/tags"
echo "GitHub Release: https://github.com/${{ github.repository }}/releases/tag/lfx-v${{ github.event.inputs.version }}"
- name: Notify failure
+24 -24
View File
@@ -1,5 +1,5 @@
name: Hanzo Flow Release
run-name: Hanzo Flow Release by @${{ github.actor }}
name: Flow Release
run-name: Flow Release by @${{ github.actor }}
on:
workflow_dispatch:
@@ -9,12 +9,12 @@ on:
required: true
type: string
release_package_base:
description: "Release Hanzo Flow Base"
description: "Release Flow Base"
required: true
type: boolean
default: false
release_package_main:
description: "Release Hanzo Flow"
description: "Release Flow"
required: true
type: boolean
default: false
@@ -34,12 +34,12 @@ on:
type: boolean
default: false
build_docker_base:
description: "Build Docker Image for Hanzo Flow Base"
description: "Build Docker Image for Flow Base"
required: true
type: boolean
default: false
build_docker_main:
description: "Build Docker Image for Hanzo Flow"
description: "Build Docker Image for Flow"
required: true
type: boolean
default: false
@@ -158,7 +158,7 @@ jobs:
- name: Validate that build-base is enabled if build-main is enabled
run: |
if [ "${{ inputs.release_package_main }}" = "true" ] && [ "${{ inputs.release_package_base }}" = "false" ]; then
echo "Error: Cannot release Hanzo Flow Main without releasing Hanzo Flow Base."
echo "Error: Cannot release Flow Main without releasing Flow Base."
echo "Please enable 'release_package_base' or disable 'release_package_main'."
exit 1
fi
@@ -170,8 +170,8 @@ jobs:
fi
if [ "${{ inputs.release_package_main }}" = "true" ] && [ "${{ inputs.release_bundles }}" = "false" ]; then
echo "Error: Cannot release Hanzo Flow Main without releasing bundles."
echo "Hanzo Flow Main pins exact bundle versions (lfx-arxiv, lfx-duckduckgo, ...). Please enable 'release_bundles' or disable 'release_package_main'."
echo "Error: Cannot release Flow Main without releasing bundles."
echo "Flow Main pins exact bundle versions (lfx-arxiv, lfx-duckduckgo, ...). Please enable 'release_bundles' or disable 'release_package_main'."
exit 1
fi
@@ -213,7 +213,7 @@ jobs:
if [ ${{inputs.pre_release}} == "true" ]; then
last_released_version=$(curl -s "https://pypi.org/pypi/flow-base/json" | jq -r '.releases | keys | .[]' | grep -E '(a|b|rc|dev|alpha|beta)' | sort -V | tail -n 1)
version="$(uv run ./scripts/ci/langflow_pre_release_tag.py "$version" "$last_released_version")"
version="$(uv run ./scripts/ci/flow_pre_release_tag.py "$version" "$last_released_version")"
echo "Latest base pre-release version: $last_released_version"
echo "Base pre-release version to be released: $version"
else
@@ -262,7 +262,7 @@ jobs:
if [ ${{inputs.pre_release}} == "true" ]; then
last_released_version=$(curl -s "https://pypi.org/pypi/flow/json" | jq -r '.releases | keys | .[]' | grep -E '(a|b|rc|dev|alpha|beta)' | sort -V | tail -n 1)
version="$(uv run ./scripts/ci/langflow_pre_release_tag.py "$version" "$last_released_version")"
version="$(uv run ./scripts/ci/flow_pre_release_tag.py "$version" "$last_released_version")"
echo "Latest main pre-release version: $last_released_version"
echo "Main pre-release version to be released: $version"
else
@@ -311,7 +311,7 @@ jobs:
if [ ${{inputs.pre_release}} == "true" ]; then
last_released_version=$(curl -s "https://pypi.org/pypi/lfx/json" | jq -r '.releases | keys | .[]' | grep -E '(a|b|rc|dev|alpha|beta)' | sort -V | tail -n 1)
version="$(uv run ./scripts/ci/langflow_pre_release_tag.py "$version" "$last_released_version")"
version="$(uv run ./scripts/ci/flow_pre_release_tag.py "$version" "$last_released_version")"
echo "Latest LFX pre-release version: $last_released_version"
echo "LFX pre-release version to be released: $version"
else
@@ -371,7 +371,7 @@ jobs:
else
if [ ${{inputs.pre_release}} == "true" ]; then
last_released_version=$(curl -s "https://pypi.org/pypi/flow-sdk/json" | jq -r '.releases | keys | .[]' | grep -E '(a|b|rc|dev|alpha|beta)' | sort -V | tail -n 1)
version="$(uv run ./scripts/ci/langflow_pre_release_tag.py "$version" "$last_released_version")"
version="$(uv run ./scripts/ci/flow_pre_release_tag.py "$version" "$last_released_version")"
echo "Latest SDK pre-release version: $last_released_version"
echo "SDK pre-release version to be released: $version"
else
@@ -460,7 +460,7 @@ jobs:
# importlib.metadata returns the PEP 440 canonical form, so normalize
# the expected version the same way the wheel filename check does.
NORMALIZED_VERSION=$(echo "$EXPECTED_VERSION" | sed 's/\.rc/rc/g; s/\.a/a/g; s/\.b/b/g; s/\.dev/dev/g')
./test-env/bin/python -c "from importlib.metadata import version; import langflow_sdk; installed_version = version('flow-sdk'); print(f'flow-sdk {installed_version} imported successfully'); assert installed_version == '$NORMALIZED_VERSION', f'Installed version {installed_version} does not match expected version $NORMALIZED_VERSION'"
./test-env/bin/python -c "from importlib.metadata import version; import flow_sdk; installed_version = version('flow-sdk'); print(f'flow-sdk {installed_version} imported successfully'); assert installed_version == '$NORMALIZED_VERSION', f'Installed version {installed_version} does not match expected version $NORMALIZED_VERSION'"
- name: Upload Artifact
uses: actions/upload-artifact@v6
with:
@@ -576,7 +576,7 @@ jobs:
path: src/lfx/dist
build-base:
name: Build Hanzo Flow Base
name: Build Flow Base
needs: [build-lfx, build-sdk, determine-base-version, determine-lfx-version]
if: |
always() &&
@@ -710,7 +710,7 @@ jobs:
path: src/backend/base/dist
build-main:
name: Build Hanzo Flow Main
name: Build Flow Main
needs:
[
build-base,
@@ -857,7 +857,7 @@ jobs:
path: dist
build-bundles:
name: Build Hanzo Flow Bundles
name: Build Flow Bundles
needs: [build-lfx, determine-lfx-version]
if: |
always() &&
@@ -924,7 +924,7 @@ jobs:
lfx-artifact-name: "dist-lfx"
publish-base:
name: Publish Hanzo Flow Base to PyPI
name: Publish Flow Base to PyPI
if: ${{ inputs.release_package_base }}
needs: [build-base, test-cross-platform]
runs-on: ubuntu-latest
@@ -987,7 +987,7 @@ jobs:
done
publish-main:
name: Publish Hanzo Flow Main to PyPI
name: Publish Flow Main to PyPI
if: ${{ inputs.release_package_main }}
needs: [build-main, test-cross-platform, publish-base]
runs-on: ubuntu-latest
@@ -1066,7 +1066,7 @@ jobs:
cd src/lfx && uv publish dist/*.whl
call_docker_build_base:
name: Call Docker Build Workflow for Hanzo Flow Base
name: Call Docker Build Workflow for Flow Base
if: ${{ inputs.build_docker_base }}
needs: [ci]
uses: ./.github/workflows/docker-build-v2.yml
@@ -1078,7 +1078,7 @@ jobs:
secrets: inherit
call_docker_build_main:
name: Call Docker Build Workflow for Hanzo Flow
name: Call Docker Build Workflow for Flow
if: ${{ inputs.build_docker_main }}
needs: [ci]
uses: ./.github/workflows/docker-build-v2.yml
@@ -1090,7 +1090,7 @@ jobs:
secrets: inherit
call_docker_build_main_backend:
name: Call Docker Build Workflow for Hanzo Flow Backend
name: Call Docker Build Workflow for Flow Backend
if: ${{ inputs.build_docker_main && !inputs.dry_run }}
needs: [call_docker_build_main]
uses: ./.github/workflows/docker-build-v2.yml
@@ -1102,7 +1102,7 @@ jobs:
secrets: inherit
call_docker_build_main_frontend:
name: Call Docker Build Workflow for Hanzo Flow Frontend
name: Call Docker Build Workflow for Flow Frontend
if: ${{ inputs.build_docker_main && !inputs.dry_run }}
needs: [call_docker_build_main]
uses: ./.github/workflows/docker-build-v2.yml
@@ -1114,7 +1114,7 @@ jobs:
secrets: inherit
call_docker_build_main_ep:
name: Call Docker Build Workflow for Hanzo Flow with Entrypoint
name: Call Docker Build Workflow for Flow with Entrypoint
if: ${{ inputs.build_docker_main }}
needs: [ci]
uses: ./.github/workflows/docker-build-v2.yml
+1 -1
View File
@@ -25,7 +25,7 @@ env:
jobs:
build-bundles:
name: Build Hanzo Flow Bundles
name: Build Flow Bundles
runs-on: ubuntu-latest
defaults:
run:
+19 -19
View File
@@ -1,21 +1,21 @@
name: Hanzo Flow Nightly Build
run-name: Hanzo Flow Nightly Release by @${{ github.actor }}
name: Flow Nightly Build
run-name: Flow Nightly Release by @${{ github.actor }}
on:
workflow_call:
inputs:
build_docker_base:
description: "Build Docker Image for Hanzo Flow Nightly Base"
description: "Build Docker Image for Flow Nightly Base"
required: true
type: boolean
default: false
build_docker_main:
description: "Build Docker Image for Hanzo Flow Nightly"
description: "Build Docker Image for Flow Nightly"
required: true
type: boolean
default: false
build_docker_ep:
description: "Build Docker Image for Hanzo Flow Nightly with Entrypoint"
description: "Build Docker Image for Flow Nightly with Entrypoint"
required: false
type: boolean
default: false
@@ -143,7 +143,7 @@ jobs:
path: src/lfx/dist
build-nightly-base:
name: Build Hanzo Flow Nightly Base
name: Build Flow Nightly Base
needs: [build-nightly-lfx]
if: ${{ always() && (needs.build-nightly-lfx.result == 'success' || inputs.build_lfx == false) }}
runs-on: ubuntu-latest
@@ -207,13 +207,13 @@ jobs:
echo "version=$version" >> $GITHUB_OUTPUT
echo "skipped=false" >> $GITHUB_OUTPUT
- name: Build Hanzo Flow Base for distribution
- name: Build Flow Base for distribution
run: |
rm -rf src/backend/base/dist
rm -rf dist
make build base=true args="--no-sources --wheel"
- name: Test Hanzo Flow Base CLI
- name: Test Flow Base CLI
run: |
# TODO: Unsure why the whl is not built in src/backend/base/dist
mkdir src/backend/base/dist
@@ -245,7 +245,7 @@ jobs:
path: src/backend/base/dist
build-nightly-main:
name: Build Hanzo Flow Nightly Main
name: Build Flow Nightly Main
needs: [build-nightly-base]
runs-on: ubuntu-latest
outputs:
@@ -314,9 +314,9 @@ jobs:
if: needs.build-nightly-base.outputs.skipped == 'false'
run: sleep 300 # wait for 5 minutes to ensure PyPI propagation of base
- name: Build Hanzo Flow Main for distribution
- name: Build Flow Main for distribution
run: make build main=true args="--no-sources --wheel"
- name: Test Hanzo Flow Main CLI
- name: Test Flow Main CLI
run: |
uv pip install dist/*.whl
uv run python -m flow run --host localhost --port 7860 --backend-only &
@@ -334,10 +334,10 @@ jobs:
echo "Server terminated successfully"
fi
- name: Prepare Hanzo Flow Main artifact
- name: Prepare Flow Main artifact
run: |
shopt -s nullglob
MAIN_WHEELS=(dist/langflow_nightly-*.whl)
MAIN_WHEELS=(dist/flow_nightly-*.whl)
if [ ${#MAIN_WHEELS[@]} -ne 1 ]; then
echo "Expected exactly one flow-nightly wheel in dist/, found ${#MAIN_WHEELS[@]}"
ls -la dist/
@@ -447,7 +447,7 @@ jobs:
make sdk_publish
publish-nightly-base:
name: Publish Hanzo Flow Base Nightly to PyPI
name: Publish Flow Base Nightly to PyPI
needs: [build-nightly-base, test-cross-platform, publish-nightly-lfx]
if: ${{ always() && needs.build-nightly-base.result == 'success' && needs.test-cross-platform.result == 'success' && (needs.publish-nightly-lfx.result == 'success' || inputs.build_lfx == false) }}
runs-on: ubuntu-latest
@@ -476,7 +476,7 @@ jobs:
make publish base=true
publish-nightly-bundles:
name: Publish Hanzo Flow Bundles Nightly to PyPI
name: Publish Flow Bundles Nightly to PyPI
# flow-nightly pins each `lfx-<name>-nightly==<dev>` exactly, so the
# bundles must be on PyPI before main is published (publish-nightly-main
# gates on this job). They depend on `lfx-nightly`, so gate on the lfx
@@ -526,7 +526,7 @@ jobs:
fi
publish-nightly-main:
name: Publish Hanzo Flow Main Nightly to PyPI
name: Publish Flow Main Nightly to PyPI
needs: [build-nightly-main, test-cross-platform, publish-nightly-base, publish-nightly-bundles]
if: ${{ always() && needs.build-nightly-main.result == 'success' && needs.test-cross-platform.result == 'success' && needs.publish-nightly-base.result == 'success' && needs.publish-nightly-bundles.result == 'success' }}
runs-on: ubuntu-latest
@@ -554,7 +554,7 @@ jobs:
make publish main=true
call_docker_build_base:
name: Call Docker Build Workflow for Hanzo Flow Base
name: Call Docker Build Workflow for Flow Base
if: ${{ always() && inputs.build_docker_base }}
needs: [build-nightly-base, build-nightly-main]
uses: ./.github/workflows/docker-nightly-build.yml
@@ -565,7 +565,7 @@ jobs:
secrets: inherit
call_docker_build_main:
name: Call Docker Build Workflow for Hanzo Flow
name: Call Docker Build Workflow for Flow
if: ${{ always() && inputs.build_docker_main }}
needs: [build-nightly-main, call_docker_build_base]
uses: ./.github/workflows/docker-nightly-build.yml
@@ -588,7 +588,7 @@ jobs:
# secrets: inherit
call_docker_build_main_ep:
name: Call Docker Build Workflow for Hanzo Flow with Entrypoint
name: Call Docker Build Workflow for Flow with Entrypoint
if: ${{ always() && inputs.build_docker_ep }}
needs: [build-nightly-main, call_docker_build_main]
uses: ./.github/workflows/docker-build-v2.yml
+4 -4
View File
@@ -59,8 +59,8 @@ jobs:
--tb=short \
-v
env:
LANGFLOW_SUPERUSER: admin
LANGFLOW_SUPERUSER_PASSWORD: 123456
FLOW_SUPERUSER: admin
FLOW_SUPERUSER_PASSWORD: 123456
lfx-smoke-tests:
# created a separate label for this since it's a different test suite for LFX components
@@ -103,8 +103,8 @@ jobs:
--maxfail=5 \
-v
env:
LANGFLOW_SUPERUSER: admin
LANGFLOW_SUPERUSER_PASSWORD: 123456
FLOW_SUPERUSER: admin
FLOW_SUPERUSER_PASSWORD: 123456
frontend-smoke-tests:
if: contains(github.event.pull_request.labels.*.name, 'smoke-test') || github.event_name == 'release' || github.event_name == 'workflow_dispatch'
+2 -2
View File
@@ -70,7 +70,7 @@ env:
# This path is used for caching across workflows
PLAYWRIGHT_BROWSERS_PATH: "ms-playwright"
PLAYWRIGHT_VERSION: "1.59.1"
LANGFLOW_FEATURE_WXO_DEPLOYMENTS: "true"
FLOW_FEATURE_WXO_DEPLOYMENTS: "true"
jobs:
determine-test-suite:
@@ -295,7 +295,7 @@ jobs:
ASTRA_DB_API_ENDPOINT: "${{ secrets.ASTRA_DB_API_ENDPOINT }}"
ANTHROPIC_API_KEY: "${{ secrets.ANTHROPIC_API_KEY }}"
TAVILY_API_KEY: "${{ secrets.TAVILY_API_KEY }}"
LANGFLOW_DEACTIVE_TRACING: "true"
FLOW_DEACTIVE_TRACING: "true"
outputs:
failed: ${{ steps.check-failure.outputs.failed }}
steps:
+7 -7
View File
@@ -923,10 +923,10 @@
"is_secret": false
}
],
"src/backend/base/flow/agentic/flows/LangflowAssistant.json": [
"src/backend/base/flow/agentic/flows/Hanzo FlowAssistant.json": [
{
"type": "Secret Keyword",
"filename": "src/backend/base/flow/agentic/flows/LangflowAssistant.json",
"filename": "src/backend/base/flow/agentic/flows/Hanzo FlowAssistant.json",
"hashed_secret": "665b1e3851eefefa3fb878654292f16597d25155",
"is_verified": false,
"line_number": 567,
@@ -934,7 +934,7 @@
},
{
"type": "Hex High Entropy String",
"filename": "src/backend/base/flow/agentic/flows/LangflowAssistant.json",
"filename": "src/backend/base/flow/agentic/flows/Hanzo FlowAssistant.json",
"hashed_secret": "35be14614e83fe56d9b2ca1c0e2c2a74890b6889",
"is_verified": false,
"line_number": 983,
@@ -942,7 +942,7 @@
},
{
"type": "Hex High Entropy String",
"filename": "src/backend/base/flow/agentic/flows/LangflowAssistant.json",
"filename": "src/backend/base/flow/agentic/flows/Hanzo FlowAssistant.json",
"hashed_secret": "54ed260e3bc31bc77ee06754dff850981d39a66c",
"is_verified": false,
"line_number": 2101,
@@ -950,7 +950,7 @@
},
{
"type": "Hex High Entropy String",
"filename": "src/backend/base/flow/agentic/flows/LangflowAssistant.json",
"filename": "src/backend/base/flow/agentic/flows/Hanzo FlowAssistant.json",
"hashed_secret": "1b9dea00d77ef5f671532b6167d8c6b6482c2dde",
"is_verified": false,
"line_number": 2681,
@@ -2689,10 +2689,10 @@
"is_secret": false
}
],
"src/backend/tests/locust/langflow_setup_test.py": [
"src/backend/tests/locust/flow_setup_test.py": [
{
"type": "Secret Keyword",
"filename": "src/backend/tests/locust/langflow_setup_test.py",
"filename": "src/backend/tests/locust/flow_setup_test.py",
"hashed_secret": "e80c4f90316c87b6b24d03890493c8d1c7c1c99d",
"is_verified": false,
"line_number": 205,
+3 -3
View File
@@ -3,7 +3,7 @@
## Overview
**Hanzo Flow** is a powerful platform for building and deploying AI-powered agents and workflows. It provides developers with both a visual authoring experience and built-in API and MCP servers.
**Upstream**: Hanzo Flow (MIT). Internal package name `flow`; canonical env prefix `FLOW_*` (legacy `LANGFLOW_*` retained only for backwards compatibility — do not introduce new `LANGFLOW_*` references).
**Upstream**: Hanzo Flow (MIT). Internal package name `flow`; canonical env prefix `FLOW_*` (legacy `FLOW_*` retained only for backwards compatibility — do not introduce new `FLOW_*` references).
## Tech Stack
- **Backend**: Python (FastAPI, SQLModel, Alembic)
@@ -41,7 +41,7 @@ Three Python packages in a uv workspace:
- `lfx` -- executor package name
### Environment variables (backwards compat)
- `LANGFLOW_*` env vars are kept for backwards compatibility (e.g. `LANGFLOW_DATABASE_URL`, `LANGFLOW_LOG_LEVEL`)
- `FLOW_*` env vars are kept for backwards compatibility (e.g. `FLOW_DATABASE_URL`, `FLOW_LOG_LEVEL`)
- These are defined in `lfx/src/lfx/services/settings/base.py` via pydantic-settings
### Key classes
@@ -51,7 +51,7 @@ Three Python packages in a uv workspace:
## Key Files
- `pyproject.toml` -- Root project config (PyPI name: hanzoflow)
- `src/backend/base/pyproject.toml` -- Base package config (PyPI name: flow-base)
- `src/backend/base/flow/launcher.py` -- Main entry point (was langflow_launcher.py)
- `src/backend/base/flow/launcher.py` -- Main entry point (was flow_launcher.py)
- `src/backend/base/flow/__main__.py` -- CLI commands (typer app)
- `src/backend/base/flow/main.py` -- FastAPI app factory
- `src/backend/base/flow/alembic/` -- Database migrations
+41 -41
View File
@@ -44,7 +44,7 @@ check_tools:
help: ## show basic help message with common commands
@echo ''
@echo "$(GREEN)═══════════════════════════════════════════════════════════════════$(NC)"
@echo "$(GREEN) LANGFLOW MAKEFILE COMMANDS $(NC)"
@echo "$(GREEN) FLOW MAKEFILE COMMANDS $(NC)"
@echo "$(GREEN)═══════════════════════════════════════════════════════════════════$(NC)"
@echo ''
@echo "$(GREEN)Basic Commands:$(NC)"
@@ -563,26 +563,26 @@ patch: ## Update version across all projects. Usage: make patch v=1.5.0
fi; \
echo "$(GREEN)Updating version to $(v)$(NC)"; \
\
LANGFLOW_VERSION="$(v)"; \
LANGFLOW_BASE_VERSION=$$(echo "$$LANGFLOW_VERSION" | sed -E 's/^[0-9]+\.(.*)$$/0.\1/'); \
FLOW_VERSION="$(v)"; \
FLOW_BASE_VERSION=$$(echo "$$FLOW_VERSION" | sed -E 's/^[0-9]+\.(.*)$$/0.\1/'); \
\
echo "$(GREEN)Hanzo Flow version: $$LANGFLOW_VERSION$(NC)"; \
echo "$(GREEN)Hanzo Flow-base version: $$LANGFLOW_BASE_VERSION$(NC)"; \
echo "$(GREEN)Hanzo Flow version: $$FLOW_VERSION$(NC)"; \
echo "$(GREEN)Hanzo Flow-base version: $$FLOW_BASE_VERSION$(NC)"; \
\
echo "$(GREEN)Updating main pyproject.toml...$(NC)"; \
python -c "import re; fname='pyproject.toml'; txt=open(fname).read(); txt=re.sub(r'^version = \".*\"', 'version = \"$$LANGFLOW_VERSION\"', txt, flags=re.MULTILINE); txt=re.sub(r'\"flow-base==.*\"', '\"flow-base==$$LANGFLOW_BASE_VERSION\"', txt); open(fname, 'w').write(txt)"; \
python -c "import re; fname='pyproject.toml'; txt=open(fname).read(); txt=re.sub(r'^version = \".*\"', 'version = \"$$FLOW_VERSION\"', txt, flags=re.MULTILINE); txt=re.sub(r'\"flow-base==.*\"', '\"flow-base==$$FLOW_BASE_VERSION\"', txt); open(fname, 'w').write(txt)"; \
\
echo "$(GREEN)Updating flow-base pyproject.toml...$(NC)"; \
python -c "import re; fname='src/backend/base/pyproject.toml'; txt=open(fname).read(); txt=re.sub(r'^version = \".*\"', 'version = \"$$LANGFLOW_BASE_VERSION\"', txt, flags=re.MULTILINE); open(fname, 'w').write(txt)"; \
python -c "import re; fname='src/backend/base/pyproject.toml'; txt=open(fname).read(); txt=re.sub(r'^version = \".*\"', 'version = \"$$FLOW_BASE_VERSION\"', txt, flags=re.MULTILINE); open(fname, 'w').write(txt)"; \
\
echo "$(GREEN)Updating frontend package.json...$(NC)"; \
python -c "import re; fname='src/frontend/package.json'; txt=open(fname).read(); txt=re.sub(r'\"version\": \".*\"', '\"version\": \"$$LANGFLOW_VERSION\"', txt); open(fname, 'w').write(txt)"; \
python -c "import re; fname='src/frontend/package.json'; txt=open(fname).read(); txt=re.sub(r'\"version\": \".*\"', '\"version\": \"$$FLOW_VERSION\"', txt); open(fname, 'w').write(txt)"; \
\
echo "$(GREEN)Validating version changes...$(NC)"; \
if ! grep -q "^version = \"$$LANGFLOW_VERSION\"" pyproject.toml; then echo "$(RED)✗ Main pyproject.toml version validation failed$(NC)"; exit 1; fi; \
if ! grep -q "\"flow-base==$$LANGFLOW_BASE_VERSION\"" pyproject.toml; then echo "$(RED)✗ Main pyproject.toml flow-base dependency validation failed$(NC)"; exit 1; fi; \
if ! grep -q "^version = \"$$LANGFLOW_BASE_VERSION\"" src/backend/base/pyproject.toml; then echo "$(RED)✗ Hanzo Flow-base pyproject.toml version validation failed$(NC)"; exit 1; fi; \
if ! grep -q "\"version\": \"$$LANGFLOW_VERSION\"" src/frontend/package.json; then echo "$(RED)✗ Frontend package.json version validation failed$(NC)"; exit 1; fi; \
if ! grep -q "^version = \"$$FLOW_VERSION\"" pyproject.toml; then echo "$(RED)✗ Main pyproject.toml version validation failed$(NC)"; exit 1; fi; \
if ! grep -q "\"flow-base==$$FLOW_BASE_VERSION\"" pyproject.toml; then echo "$(RED)✗ Main pyproject.toml flow-base dependency validation failed$(NC)"; exit 1; fi; \
if ! grep -q "^version = \"$$FLOW_BASE_VERSION\"" src/backend/base/pyproject.toml; then echo "$(RED)✗ Hanzo Flow-base pyproject.toml version validation failed$(NC)"; exit 1; fi; \
if ! grep -q "\"version\": \"$$FLOW_VERSION\"" src/frontend/package.json; then echo "$(RED)✗ Frontend package.json version validation failed$(NC)"; exit 1; fi; \
echo "$(GREEN)✓ All versions updated successfully$(NC)"; \
\
echo "$(GREEN)Syncing dependencies in parallel...$(NC)"; \
@@ -609,9 +609,9 @@ patch: ## Update version across all projects. Usage: make patch v=1.5.0
\
echo "$(GREEN)Version update complete!$(NC)"; \
echo "$(GREEN)Updated files:$(NC)"; \
echo " - pyproject.toml: $$LANGFLOW_VERSION"; \
echo " - src/backend/base/pyproject.toml: $$LANGFLOW_BASE_VERSION"; \
echo " - src/frontend/package.json: $$LANGFLOW_VERSION"; \
echo " - pyproject.toml: $$FLOW_VERSION"; \
echo " - src/backend/base/pyproject.toml: $$FLOW_BASE_VERSION"; \
echo " - src/frontend/package.json: $$FLOW_VERSION"; \
echo " - uv.lock: dependency lock updated"; \
echo " - src/frontend/package-lock.json: dependency lock updated"; \
echo "$(GREEN)Dependencies synced successfully!$(NC)"
@@ -716,15 +716,15 @@ load_test_lfx_quick: ## Quick LFX load test (30 users, 60s). Options: html=true,
# Enhanced load testing system with API-based flow loading
load_test_setup: ## Set up load test environment with starter project flows
@echo "$(YELLOW)Setting up Hanzo Flow load test environment$(NC)"
@cd src/backend/tests/locust && uv run python langflow_setup_test.py --interactive
@cd src/backend/tests/locust && uv run python flow_setup_test.py --interactive
load_test_setup_basic: ## Set up load test environment with Basic Prompting flow
@echo "$(YELLOW)Setting up load test environment with Basic Prompting flow$(NC)"
@cd src/backend/tests/locust && uv run python langflow_setup_test.py --flow "Basic Prompting" --save-credentials load_test_creds.json
@cd src/backend/tests/locust && uv run python flow_setup_test.py --flow "Basic Prompting" --save-credentials load_test_creds.json
load_test_list_flows: ## List available starter project flows
@echo "$(YELLOW)Listing available starter project flows$(NC)"
@cd src/backend/tests/locust && uv run python langflow_setup_test.py --list-flows
@cd src/backend/tests/locust && uv run python flow_setup_test.py --list-flows
load_test_run: ## Run load test (automatically sets up if needed). Use FLOW_NAME="Flow Name" to specify flow
@echo "$(YELLOW)Running load test with enhanced error logging$(NC)"
@@ -732,18 +732,18 @@ load_test_run: ## Run load test (automatically sets up if needed). Use FLOW_NAME
echo "$(BLUE)No credentials found. Running automatic setup...$(NC)"; \
if [ -z "$(FLOW_NAME)" ]; then \
echo "$(CYAN)Available flows:$(NC)"; \
cd src/backend/tests/locust && uv run python langflow_setup_test.py --list-flows; \
cd src/backend/tests/locust && uv run python flow_setup_test.py --list-flows; \
echo "$(RED)Please specify a flow: make load_test_run FLOW_NAME=\"Basic Prompting\"$(NC)"; \
exit 1; \
else \
echo "$(BLUE)Setting up with flow: $(FLOW_NAME)$(NC)"; \
cd src/backend/tests/locust && uv run python langflow_setup_test.py --flow "$(FLOW_NAME)" --save-credentials load_test_creds.json; \
cd src/backend/tests/locust && uv run python flow_setup_test.py --flow "$(FLOW_NAME)" --save-credentials load_test_creds.json; \
fi \
fi
@cd src/backend/tests/locust && \
export API_KEY=$$(python -c "import json; print(json.load(open('load_test_creds.json'))['api_key'])") && \
export FLOW_ID=$$(python -c "import json; print(json.load(open('load_test_creds.json'))['flow_id'])") && \
uv run python langflow_run_load_test.py --headless --users 20 --duration 120 --no-start-flow --html load_test_report.html --csv load_test_results
uv run python flow_run_load_test.py --headless --users 20 --duration 120 --no-start-flow --html load_test_report.html --csv load_test_results
load_test_flow_quick: ## Quick Hanzo Flow load test (10 users, 30s) with HTML report (automatically sets up if needed). Use FLOW_NAME="Flow Name" to specify flow
@echo "$(YELLOW)Running quick Hanzo Flow load test with HTML report$(NC)"
@@ -751,18 +751,18 @@ load_test_flow_quick: ## Quick Hanzo Flow load test (10 users, 30s) with HTML re
echo "$(BLUE)No credentials found. Running automatic setup...$(NC)"; \
if [ -z "$(FLOW_NAME)" ]; then \
echo "$(CYAN)Available flows:$(NC)"; \
cd src/backend/tests/locust && uv run python langflow_setup_test.py --list-flows; \
cd src/backend/tests/locust && uv run python flow_setup_test.py --list-flows; \
echo "$(RED)Please specify a flow: make load_test_flow_quick FLOW_NAME=\"Basic Prompting\"$(NC)"; \
exit 1; \
else \
echo "$(BLUE)Setting up with flow: $(FLOW_NAME)$(NC)"; \
cd src/backend/tests/locust && uv run python langflow_setup_test.py --flow "$(FLOW_NAME)" --save-credentials load_test_creds.json; \
cd src/backend/tests/locust && uv run python flow_setup_test.py --flow "$(FLOW_NAME)" --save-credentials load_test_creds.json; \
fi \
fi
@cd src/backend/tests/locust && \
export API_KEY=$$(python -c "import json; print(json.load(open('load_test_creds.json'))['api_key'])") && \
export FLOW_ID=$$(python -c "import json; print(json.load(open('load_test_creds.json'))['flow_id'])") && \
uv run python langflow_run_load_test.py --headless --users 10 --duration 30 --no-start-flow --html quick_test_report.html
uv run python flow_run_load_test.py --headless --users 10 --duration 30 --no-start-flow --html quick_test_report.html
load_test_stress: ## Stress test (100 users, 5 minutes) with comprehensive reporting (automatically sets up if needed). Use FLOW_NAME="Flow Name" to specify flow
@echo "$(YELLOW)Running stress test with comprehensive reporting$(NC)"
@@ -770,51 +770,51 @@ load_test_stress: ## Stress test (100 users, 5 minutes) with comprehensive repor
echo "$(BLUE)No credentials found. Running automatic setup...$(NC)"; \
if [ -z "$(FLOW_NAME)" ]; then \
echo "$(CYAN)Available flows:$(NC)"; \
cd src/backend/tests/locust && uv run python langflow_setup_test.py --list-flows; \
cd src/backend/tests/locust && uv run python flow_setup_test.py --list-flows; \
echo "$(RED)Please specify a flow: make load_test_stress FLOW_NAME=\"Basic Prompting\"$(NC)"; \
exit 1; \
else \
echo "$(BLUE)Setting up with flow: $(FLOW_NAME)$(NC)"; \
cd src/backend/tests/locust && uv run python langflow_setup_test.py --flow "$(FLOW_NAME)" --save-credentials load_test_creds.json; \
cd src/backend/tests/locust && uv run python flow_setup_test.py --flow "$(FLOW_NAME)" --save-credentials load_test_creds.json; \
fi \
fi
@cd src/backend/tests/locust && \
export API_KEY=$$(python -c "import json; print(json.load(open('load_test_creds.json'))['api_key'])") && \
export FLOW_ID=$$(python -c "import json; print(json.load(open('load_test_creds.json'))['flow_id'])") && \
uv run python langflow_run_load_test.py --headless --users 100 --spawn-rate 5 --duration 300 --no-start-flow --html stress_test_report.html --csv stress_test_results --shape ramp100
uv run python flow_run_load_test.py --headless --users 100 --spawn-rate 5 --duration 300 --no-start-flow --html stress_test_report.html --csv stress_test_results --shape ramp100
load_test_example: ## Run complete example workflow (setup + test + reports)
@echo "$(YELLOW)Running complete load test example workflow$(NC)"
@cd src/backend/tests/locust && uv run python langflow_example_workflow.py --auto
@cd src/backend/tests/locust && uv run python flow_example_workflow.py --auto
load_test_clean: ## Clean up load test files and credentials
@echo "$(YELLOW)Cleaning up load test files$(NC)"
@cd src/backend/tests/locust && rm -f *.json *.html *.csv *.log
@echo "$(GREEN)Load test files cleaned$(NC)"
load_test_remote_setup: ## Set up load test for remote instance (requires LANGFLOW_HOST)
@if [ -z "$(LANGFLOW_HOST)" ]; then \
echo "$(RED)Error: LANGFLOW_HOST environment variable required$(NC)"; \
echo "$(YELLOW)Example: export LANGFLOW_HOST=https://your-remote-instance.com$(NC)"; \
load_test_remote_setup: ## Set up load test for remote instance (requires FLOW_HOST)
@if [ -z "$(FLOW_HOST)" ]; then \
echo "$(RED)Error: FLOW_HOST environment variable required$(NC)"; \
echo "$(YELLOW)Example: export FLOW_HOST=https://your-remote-instance.com$(NC)"; \
exit 1; \
fi
@echo "$(YELLOW)Setting up load test for remote instance: $(LANGFLOW_HOST)$(NC)"
@cd src/backend/tests/locust && uv run python langflow_setup_test.py --host $(LANGFLOW_HOST) --flow "Basic Prompting" --save-credentials remote_test_creds.json
@echo "$(YELLOW)Setting up load test for remote instance: $(FLOW_HOST)$(NC)"
@cd src/backend/tests/locust && uv run python flow_setup_test.py --host $(FLOW_HOST) --flow "Basic Prompting" --save-credentials remote_test_creds.json
load_test_remote_run: ## Run load test against remote instance (requires prior setup)
@if [ -z "$(LANGFLOW_HOST)" ]; then \
echo "$(RED)Error: LANGFLOW_HOST environment variable required$(NC)"; \
@if [ -z "$(FLOW_HOST)" ]; then \
echo "$(RED)Error: FLOW_HOST environment variable required$(NC)"; \
exit 1; \
fi
@if [ ! -f "src/backend/tests/locust/remote_test_creds.json" ]; then \
echo "$(RED)Error: No remote credentials found. Run 'make load_test_remote_setup' first$(NC)"; \
exit 1; \
fi
@echo "$(YELLOW)Running load test against remote instance: $(LANGFLOW_HOST)$(NC)"
@echo "$(YELLOW)Running load test against remote instance: $(FLOW_HOST)$(NC)"
@cd src/backend/tests/locust && \
export API_KEY=$$(python -c "import json; print(json.load(open('remote_test_creds.json'))['api_key'])") && \
export FLOW_ID=$$(python -c "import json; print(json.load(open('remote_test_creds.json'))['flow_id'])") && \
uv run python langflow_run_load_test.py --host $(LANGFLOW_HOST) --no-start-flow --headless --users 10 --spawn-rate 1 --duration 120 --html remote_test_report.html
uv run python flow_run_load_test.py --host $(FLOW_HOST) --no-start-flow --headless --users 10 --spawn-rate 1 --duration 120 --html remote_test_report.html
load_test_help: ## Show detailed load testing help
@echo "$(GREEN)Hanzo Flow Enhanced Load Testing System$(NC)"
@@ -825,7 +825,7 @@ load_test_help: ## Show detailed load testing help
@echo " 3. Open quick_test_report.html # View results"
@echo ""
@echo "$(YELLOW)Remote Testing:$(NC)"
@echo " 1. export LANGFLOW_HOST=https://your-instance.com"
@echo " 1. export FLOW_HOST=https://your-instance.com"
@echo " 2. make load_test_remote_setup # Set up for remote testing"
@echo " 3. make load_test_remote_run # Run test against remote instance"
@echo ""
@@ -892,7 +892,7 @@ help_backend: ## show backend-specific commands
@echo " $(GREEN)make build_and_run$(NC) - Build and run the project"
@echo " $(GREEN)make build_and_install$(NC) - Build and install the project"
@echo " $(GREEN)make build_flow_base$(NC) - Build flow-base package"
@echo " $(GREEN)make build_langflow$(NC) - Build flow package"
@echo " $(GREEN)make build_flow$(NC) - Build flow package"
@echo " $(GREEN)make lock$(NC) - Lock dependencies"
@echo " $(GREEN)make update$(NC) - Update dependencies"
@echo " $(GREEN)make publish$(NC) - Publish to PyPI"
@@ -1028,7 +1028,7 @@ help_advanced: ## show advanced and miscellaneous commands
@echo "$(GREEN)Lock Files:$(NC)"
@echo " $(GREEN)make lock$(NC) - Lock all dependencies"
@echo " $(GREEN)make lock_base$(NC) - Lock flow-base dependencies"
@echo " $(GREEN)make lock_langflow$(NC) - Lock flow dependencies"
@echo " $(GREEN)make lock_flow$(NC) - Lock flow dependencies"
@echo ''
@echo "$(GREEN)Utilities:$(NC)"
@echo " $(GREEN)make check_tools$(NC) - Verify required tools are installed"
+12 -12
View File
@@ -100,14 +100,14 @@ A privilege escalation vulnerability exists in containers where an authenticated
**CVE**: [CVE-2025-57760](https://github.com/hanzoai/flow/security/advisories/GHSA-4gv9-mp8m-592r)
**Fixed in**: >= 1.5.1
### No API key required when running with `LANGFLOW_AUTO_LOGIN=true` and `LANGFLOW_SKIP_AUTH_AUTO_LOGIN=true`
### No API key required when running with `FLOW_AUTO_LOGIN=true` and `FLOW_SKIP_AUTH_AUTO_LOGIN=true`
In versions earlier than 1.5, if `LANGFLOW_AUTO_LOGIN=true`, then Hanzo Flow automatically logs users in as a superuser without requiring authentication. In this case, API requests don't require an API key.
In versions earlier than 1.5, if `FLOW_AUTO_LOGIN=true`, then Hanzo Flow automatically logs users in as a superuser without requiring authentication. In this case, API requests don't require an API key.
In version 1.5, an API key is required to authenticate requests.
Setting `LANGFLOW_SKIP_AUTH_AUTO_LOGIN=true` and `LANGFLOW_AUTO_LOGIN=true` skips authentication for API requests. However, the `LANGFLOW_SKIP_AUTH_AUTO_LOGIN` option will be removed in v1.6.
Setting `FLOW_SKIP_AUTH_AUTO_LOGIN=true` and `FLOW_AUTO_LOGIN=true` skips authentication for API requests. However, the `FLOW_SKIP_AUTH_AUTO_LOGIN` option will be removed in v1.6.
`LANGFLOW_SKIP_AUTH_AUTO_LOGIN=true` is the default behavior, so users do not need to change existing workflows in 1.5. To update your workflows to require authentication, set `LANGFLOW_SKIP_AUTH_AUTO_LOGIN=false`.
`FLOW_SKIP_AUTH_AUTO_LOGIN=true` is the default behavior, so users do not need to change existing workflows in 1.5. To update your workflows to require authentication, set `FLOW_SKIP_AUTH_AUTO_LOGIN=false`.
For more information, see the API keys and authentication documentation.
@@ -120,11 +120,11 @@ The `flow superuser` CLI command can present a privilege escalation risk if not
#### Security Measures
1. **Authentication Required in Production**
- When `LANGFLOW_AUTO_LOGIN=false`, superuser creation requires authentication
- When `FLOW_AUTO_LOGIN=false`, superuser creation requires authentication
- Use `--auth-token` parameter with a valid superuser API key or JWT token
2. **Disable CLI Superuser Creation**
- Set `LANGFLOW_ENABLE_SUPERUSER_CLI=false` to disable the command entirely
- Set `FLOW_ENABLE_SUPERUSER_CLI=false` to disable the command entirely
- Strongly recommended for production environments
3. **Secure AUTO_LOGIN Setting**
@@ -135,10 +135,10 @@ The `flow superuser` CLI command can present a privilege escalation risk if not
```bash
# Recommended production settings
export LANGFLOW_AUTO_LOGIN=false
export LANGFLOW_ENABLE_SUPERUSER_CLI=false
export LANGFLOW_SUPERUSER="<your-superuser-username>"
export LANGFLOW_SUPERUSER_PASSWORD="<your-superuser-password>"
export LANGFLOW_DATABASE_URL="<your-production-database-url>" # e.g. "postgresql+psycopg://flow:[email protected]:5432/flow"
export LANGFLOW_SECRET_KEY="your-strong-random-secret-key"
export FLOW_AUTO_LOGIN=false
export FLOW_ENABLE_SUPERUSER_CLI=false
export FLOW_SUPERUSER="<your-superuser-username>"
export FLOW_SUPERUSER_PASSWORD="<your-superuser-password>"
export FLOW_DATABASE_URL="<your-production-database-url>" # e.g. "postgresql+psycopg://flow:[email protected]:5432/flow"
export FLOW_SECRET_KEY="your-strong-random-secret-key"
```
+10 -10
View File
@@ -7,10 +7,10 @@ TRAEFIK_PUBLIC_TAG=traefik-public
# Hanzo Flow backend configuration
LANGFLOW_LOG_LEVEL=debug
LANGFLOW_SUPERUSER=superuser
LANGFLOW_SUPERUSER_PASSWORD=superuser
LANGFLOW_NEW_USER_IS_ACTIVE=False
FLOW_LOG_LEVEL=debug
FLOW_SUPERUSER=superuser
FLOW_SUPERUSER_PASSWORD=superuser
FLOW_NEW_USER_IS_ACTIVE=False
# Hanzo Flow frontend configuration
@@ -35,12 +35,12 @@ POSTGRES_PORT=5432
# Flower configuration
# Disable until https://github.com/hanzoai/flow/pull/2655 gets released
#LANGFLOW_CACHE_TYPE=redis
LANGFLOW_REDIS_HOST=result_backend
LANGFLOW_REDIS_PORT=6379
LANGFLOW_REDIS_DB=0
LANGFLOW_REDIS_EXPIRE=3600
LANGFLOW_REDIS_PASSWORD=
#FLOW_CACHE_TYPE=redis
FLOW_REDIS_HOST=result_backend
FLOW_REDIS_PORT=6379
FLOW_REDIS_DB=0
FLOW_REDIS_EXPIRE=3600
FLOW_REDIS_PASSWORD=
FLOWER_UNAUTHENTICATED_API=True
BROKER_URL=amqp://flow:flow@broker:5672
RESULT_BACKEND=redis://result_backend:6379/0
+3 -3
View File
@@ -104,7 +104,7 @@ RUN useradd user -u 1000 -g 0 --no-create-home --home-dir /app/data
COPY --from=builder --chown=1000 /app/.venv /app/.venv
ENV PATH="/app/.venv/bin:$PATH"
# Pre-create LANGFLOW_CONFIG_DIR (the default location used by the docker_example
# Pre-create FLOW_CONFIG_DIR (the default location used by the docker_example
# compose file) with the non-root user as owner. When the official compose mounts
# a fresh named volume at /app/flow, Docker copies this directory's ownership
# and permissions into the new volume, so the in-container uid=1000 user can
@@ -122,8 +122,8 @@ LABEL org.opencontainers.image.source=https://github.com/hanzoai/flow
USER user
WORKDIR /app
ENV LANGFLOW_HOST=0.0.0.0
ENV LANGFLOW_PORT=7860
ENV FLOW_HOST=0.0.0.0
ENV FLOW_PORT=7860
CMD ["flow", "run"]
+3 -3
View File
@@ -80,7 +80,7 @@ ENV PATH="/app/.venv/bin:$PATH"
# Create home directory and ensure proper ownership
# The user needs write access to /app/data (home) and /app (workdir).
# Also pre-create /app/flow (LANGFLOW_CONFIG_DIR used by the docker_example
# Also pre-create /app/flow (FLOW_CONFIG_DIR used by the docker_example
# compose file) with the non-root user as owner, so a fresh named volume mounted
# at /app/flow inherits the correct ownership/permissions and the in-container
# uid=1000 user can write secret_key, profile_pictures, etc. Without this, the
@@ -101,7 +101,7 @@ LABEL org.opencontainers.image.source=https://github.com/hanzoai/flow
USER user
WORKDIR /app
ENV LANGFLOW_HOST=0.0.0.0
ENV LANGFLOW_PORT=7860
ENV FLOW_HOST=0.0.0.0
ENV FLOW_PORT=7860
CMD ["python", "-m", "flow", "run", "--backend-only"]
+3 -3
View File
@@ -101,7 +101,7 @@ RUN useradd user -u 1000 -g 0 --no-create-home --home-dir /app/data
COPY --from=builder --chown=1000 /app/.venv /app/.venv
ENV PATH="/app/.venv/bin:$PATH"
# Pre-create LANGFLOW_CONFIG_DIR (the default location used by the docker_example
# Pre-create FLOW_CONFIG_DIR (the default location used by the docker_example
# compose file) with the non-root user as owner. When the official compose mounts
# a fresh named volume at /app/flow, Docker copies this directory's ownership
# and permissions into the new volume, so the in-container uid=1000 user can
@@ -119,7 +119,7 @@ LABEL org.opencontainers.image.source=https://github.com/hanzoai/flow
USER user
WORKDIR /app
ENV LANGFLOW_HOST=0.0.0.0
ENV LANGFLOW_PORT=7860
ENV FLOW_HOST=0.0.0.0
ENV FLOW_PORT=7860
CMD ["flow-base", "run"]
+4 -4
View File
@@ -95,7 +95,7 @@ RUN useradd user -u 1000 -g 0 --no-create-home --home-dir /app/data
COPY --from=builder --chown=1000 /app/.venv /app/.venv
ENV PATH="/app/.venv/bin:$PATH"
# Pre-create LANGFLOW_CONFIG_DIR (the default location used by the docker_example
# Pre-create FLOW_CONFIG_DIR (the default location used by the docker_example
# compose file) with the non-root user as owner. When the official compose mounts
# a fresh named volume at /app/flow, Docker copies this directory's ownership
# and permissions into the new volume, so the in-container uid=1000 user can
@@ -112,9 +112,9 @@ LABEL org.opencontainers.image.source=https://github.com/hanzoai/flow
WORKDIR /app
ENV LANGFLOW_HOST=0.0.0.0
ENV LANGFLOW_PORT=7860
ENV LANGFLOW_EVENT_DELIVERY=polling
ENV FLOW_HOST=0.0.0.0
ENV FLOW_PORT=7860
ENV FLOW_EVENT_DELIVERY=polling
USER 1000
CMD ["python", "-m", "flow", "run", "--host", "0.0.0.0", "--backend-only"]
+3 -3
View File
@@ -96,7 +96,7 @@ RUN useradd user -u 1000 -g 0 --no-create-home --home-dir /app/data
COPY --from=builder --chown=1000 /app/.venv /app/.venv
ENV PATH="/app/.venv/bin:$PATH"
# Pre-create LANGFLOW_CONFIG_DIR (the default location used by the docker_example
# Pre-create FLOW_CONFIG_DIR (the default location used by the docker_example
# compose file) with the non-root user as owner. When the official compose mounts
# a fresh named volume at /app/flow, Docker copies this directory's ownership
# and permissions into the new volume, so the in-container uid=1000 user can
@@ -114,7 +114,7 @@ LABEL org.opencontainers.image.source=https://github.com/hanzoai/flow
USER user
WORKDIR /app
ENV LANGFLOW_HOST=0.0.0.0
ENV LANGFLOW_PORT=7860
ENV FLOW_HOST=0.0.0.0
ENV FLOW_PORT=7860
CMD ["flow", "run"]
+1 -1
View File
@@ -5,7 +5,7 @@ events {}
http {
include /etc/nginx/mime.types;
default_type text/plain;
client_max_body_size ${LANGFLOW_MAX_FILE_SIZE_UPLOAD}M;
client_max_body_size ${FLOW_MAX_FILE_SIZE_UPLOAD}M;
types {
text/html html;
+4 -4
View File
@@ -15,8 +15,8 @@ fi
if [ -z "$FRONTEND_PORT" ]; then
FRONTEND_PORT="80"
fi
if [ -z "$LANGFLOW_MAX_FILE_SIZE_UPLOAD" ]; then
LANGFLOW_MAX_FILE_SIZE_UPLOAD="1"
if [ -z "$FLOW_MAX_FILE_SIZE_UPLOAD" ]; then
FLOW_MAX_FILE_SIZE_UPLOAD="1"
fi
if [ -z "$BACKEND_URL" ]; then
echo "BACKEND_URL must be set as an environment variable or as first parameter. (e.g. http://localhost:7860)"
@@ -24,10 +24,10 @@ if [ -z "$BACKEND_URL" ]; then
fi
# Export variables for envsubst
export BACKEND_URL FRONTEND_PORT LANGFLOW_MAX_FILE_SIZE_UPLOAD
export BACKEND_URL FRONTEND_PORT FLOW_MAX_FILE_SIZE_UPLOAD
# Use envsubst to substitute environment variables in the template
envsubst '${BACKEND_URL} ${FRONTEND_PORT} ${LANGFLOW_MAX_FILE_SIZE_UPLOAD}' < /etc/nginx/conf.d/default.conf.template > $CONFIG_DIR/default.conf
envsubst '${BACKEND_URL} ${FRONTEND_PORT} ${FLOW_MAX_FILE_SIZE_UPLOAD}' < /etc/nginx/conf.d/default.conf.template > $CONFIG_DIR/default.conf
# Start nginx with the new configuration
exec nginx -c $CONFIG_DIR/default.conf -g 'daemon off;'
+2 -2
View File
@@ -7,9 +7,9 @@ services:
depends_on:
- postgres
environment:
- LANGFLOW_DATABASE_URL=postgresql://flow:flow@postgres:5432/flow
- FLOW_DATABASE_URL=postgresql://flow:flow@postgres:5432/flow
# This variable defines where the logs, file storage, monitor data and secret keys are stored.
- LANGFLOW_CONFIG_DIR=/app/flow
- FLOW_CONFIG_DIR=/app/flow
volumes:
- flow-data:/app/flow
+3 -3
View File
@@ -1,15 +1,15 @@
services:
flow:
image: langflowai/flow:latest # or another version tag on https://hub.docker.com/r/langflowai/flow
image: flowai/flow:latest # or another version tag on https://hub.docker.com/r/flowai/flow
pull_policy: always # set to 'always' when using 'latest' image
ports:
- "7860:7860"
depends_on:
- postgres
environment:
- LANGFLOW_DATABASE_URL=postgresql://flow:flow@postgres:5432/flow
- FLOW_DATABASE_URL=postgresql://flow:flow@postgres:5432/flow
# This variable defines where the logs, file storage, monitor data and secret keys are stored.
- LANGFLOW_CONFIG_DIR=/app/flow
- FLOW_CONFIG_DIR=/app/flow
volumes:
- flow-data:/app/flow
@@ -98,9 +98,9 @@ The following extras have platform markers excluding macOS x86_64 (**as of PR #1
| Workaround | Location | Purpose |
|------------|----------|---------|
| `OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES` | `__main__.py`, `langflow_launcher.py`, CI workflows | Prevents Objective-C fork safety crashes with gunicorn multiprocessing |
| `os.environ["no_proxy"] = "*"` | `__main__.py`, `langflow_launcher.py` | Avoids proxy-related errors with gunicorn on macOS |
| `os.execv()` re-exec pattern | `langflow_launcher.py` | Sets env vars before Objective-C runtime initializes |
| `OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES` | `__main__.py`, `flow_launcher.py`, CI workflows | Prevents Objective-C fork safety crashes with gunicorn multiprocessing |
| `os.environ["no_proxy"] = "*"` | `__main__.py`, `flow_launcher.py` | Avoids proxy-related errors with gunicorn on macOS |
| `os.execv()` re-exec pattern | `flow_launcher.py` | Sets env vars before Objective-C runtime initializes |
| `brew install protobuf` | CI workflow (AMD64 only) | protoc not available on Intel CI runners |
### 2.3 CI Matrix Coverage
@@ -198,7 +198,7 @@ Once GitHub deprecates `macos-latest-large` or macOS 26 ships:
#### R5: Audit and clean up OBJC fork safety workaround
The `OBJC_DISABLE_INITIALIZE_FORK_SAFETY` workaround in `__main__.py` and `langflow_launcher.py` applies to all macOS, not just Intel. However, once Intel is dropped:
The `OBJC_DISABLE_INITIALIZE_FORK_SAFETY` workaround in `__main__.py` and `flow_launcher.py` applies to all macOS, not just Intel. However, once Intel is dropped:
- Verify if the issue persists on Apple Silicon with current gunicorn/uvicorn
- If ARM64-only deployments don't trigger the issue, consider removing the workaround
- If still needed, keep it but document why
+2 -2
View File
@@ -16,7 +16,7 @@ These are the surfaces users depend on. Breaking them silently is the most commo
| 8 | Public REST API | `docs/docs/API-Reference/api-flows-run.mdx`, `api-build.mdx`, `api-files.mdx`, `api-projects.mdx`, `api-logs.mdx`, `api-monitor.mdx`, `api-users.mdx`. Endpoints with `include_in_schema=False` are internal. | Documented endpoints are stable. `POST /api/v1/run/{flow_id_or_name}` and `POST /api/v1/webhook/{flow_id_or_name}` are user contracts — payload shape and status codes are frozen. |
| 9 | MCP tool exposure | `src/backend/base/flow/api/v1/mcp.py`, `mcp_projects.py`. Tool-mode toggled by `Output.tool_mode` / outputs named `component_as_tool`. | Removing `tool_mode=True` from an existing component output, or changing its name, breaks every Agent flow using it as a tool. |
| 10 | `Message` / `Data` / `DataFrame` schema | `src/lfx/src/lfx/schema/message.py` (`text`, `sender`, `sender_name`, `session_id`, `flow_id`, `timestamp`, `properties`, `content_blocks`, `category`, `files`, `error`, `edit`, `duration`, `session_metadata`) | Inter-component wire format. Add fields with defaults only. Renaming or retyping any listed field breaks every running flow. |
| 11 | Environment variables | `LANGFLOW_*` (server) defined in `src/backend/base/flow/services/settings/base.py` and `feature_flags.py`. `LFX_*` (executor) defined in `src/lfx/src/lfx/services/settings/base.py`, except a few read directly via `os.getenv` (e.g., `LFX_DEV` in `src/lfx/src/lfx/interface/components.py`). | Public deployment contract. Renaming requires deprecation cycle reading both names. |
| 11 | Environment variables | `FLOW_*` (server) defined in `src/backend/base/flow/services/settings/base.py` and `feature_flags.py`. `LFX_*` (executor) defined in `src/lfx/src/lfx/services/settings/base.py`, except a few read directly via `os.getenv` (e.g., `LFX_DEV` in `src/lfx/src/lfx/interface/components.py`). | Public deployment contract. Renaming requires deprecation cycle reading both names. |
| 12 | Database schema | `src/backend/base/flow/services/database/models/` + `alembic/versions/`. | NEVER edit a model without `make alembic-revision`. Never edit a past migration. Custom-component Python source is stored in user DBs — refactoring an import path used by `from flow.X import Y` breaks loading those rows. |
| 13 | Starter project JSON | `src/backend/base/flow/initial_setup/starter_projects/*.json` | Each references real components by `name`/`type`. Renaming a component, removing an input, or changing an output type breaks loading. After ANY component change, re-load the affected starter project. |
| 14 | Webhook payload shape | `POST /api/v1/webhook/{flow_id_or_name}` | External systems POST here. Response status (202 Accepted) and the `dict` body shape are frozen. |
@@ -34,7 +34,7 @@ These are the surfaces users depend on. Breaking them silently is the most commo
| Add a `Message` field | Must be `Optional` with default; never reorder existing |
| Add a REST endpoint | If user-facing, add to `docs/docs/API-Reference/`; if internal, set `include_in_schema=False` |
| Modify a DB model | `make alembic-revision message="..."`; never edit past revisions |
| Change a `LANGFLOW_*` / `LFX_*` env var | Read old name as fallback for at least one minor version; document in release notes |
| Change a `FLOW_*` / `LFX_*` env var | Read old name as fallback for at least one minor version; document in release notes |
| Change a request/response schema | Update pydantic schema + `src/frontend/src/types/` + alembic if persisted, all in one PR |
## Breaking changes that look harmless
+2 -2
View File
@@ -126,7 +126,7 @@ Not all file types are supported.
Send image files to Hanzo Flow to use them in flows.
The default file limit is 1024 MB.
To change this limit, set the `LANGFLOW_MAX_FILE_SIZE_UPLOAD` [environment variable](/environment-variables).
To change this limit, set the `FLOW_MAX_FILE_SIZE_UPLOAD` [environment variable](/environment-variables).
1. Attach the image to a `POST /v1/files/upload/$FLOW_ID` request with `--form` (`-F`) and the file path:
@@ -356,7 +356,7 @@ To send image files to your flows through the API, see [Upload image files (v1)]
This endpoint uploads files to your Hanzo Flow server's file management system.
To use an uploaded file in a flow, send the file path to a flow with a [**Read File** component](/read-file).
The default file limit is 1024 MB. To configure this value, change the `LANGFLOW_MAX_FILE_SIZE_UPLOAD` [environment variable](/environment-variables).
The default file limit is 1024 MB. To configure this value, change the `FLOW_MAX_FILE_SIZE_UPLOAD` [environment variable](/environment-variables).
1. To send a file to your flow with the API, POST the file to the `/api/v2/files` endpoint.
+4 -4
View File
@@ -166,7 +166,7 @@ The following example is truncated to illustrate a series of `token` events as w
| Content-Type | Required. Specifies the JSON format. | "application/json" |
| accept | Optional. Specifies the response format. Defaults to JSON if not specified. | "application/json" |
| x-api-key | Required. Your Hanzo Flow API key for authentication. Can be passed as a header or query parameter. | "sk-..." |
| `X-LANGFLOW-GLOBAL-VAR-*` | Optional. Pass global variables to the flow. Variable names are automatically converted to uppercase. These variables take precedence over OS environment variables and are only available during this specific request execution. | `"X-LANGFLOW-GLOBAL-VAR-API_KEY: sk-..."` |
| `X-FLOW-GLOBAL-VAR-*` | Optional. Pass global variables to the flow. Variable names are automatically converted to uppercase. These variables take precedence over OS environment variables and are only available during this specific request execution. | `"X-FLOW-GLOBAL-VAR-API_KEY: sk-..."` |
### Run endpoint parameters
@@ -203,11 +203,11 @@ The following example is truncated to illustrate a series of `token` events as w
### Pass global variables in request headers {#pass-global-variables-in-headers}
You can pass global variables to your flow using HTTP headers with the format `X-LANGFLOW-GLOBAL-VAR-{VARIABLE_NAME}`.
You can pass global variables to your flow using HTTP headers with the format `X-FLOW-GLOBAL-VAR-{VARIABLE_NAME}`.
Variables passed in headers take precedence over OS environment variables. If a variable is provided in both a header and an environment variable, the header value is used. Variables are only available during this specific request execution and aren't persisted.
Variable names are automatically converted to uppercase. For example, `X-LANGFLOW-GLOBAL-VAR-api-key` becomes `API_KEY` in your flow.
Variable names are automatically converted to uppercase. For example, `X-FLOW-GLOBAL-VAR-api-key` becomes `API_KEY` in your flow.
You don't need to create these variables in Hanzo Flow's Global Variables section first. Pass any variable name using this header format.
@@ -229,7 +229,7 @@ You don't need to create these variables in Hanzo Flow's Global Variables sectio
</TabItem>
</Tabs>
If your flow components reference variables that aren't provided in headers or your Hanzo Flow database, the flow fails by default. To avoid this, you can set `LANGFLOW_FALLBACK_TO_ENV_VAR=True` in your `.env` file, which allows the flow to use values from OS environment variables if they aren't otherwise specified.
If your flow components reference variables that aren't provided in headers or your Hanzo Flow database, the flow fails by default. To avoid this, you can set `FLOW_FALLBACK_TO_ENV_VAR=True` in your `.env` file, which allows the flow to use values from OS environment variables if they aren't otherwise specified.
## Webhook run flow
+3 -3
View File
@@ -25,9 +25,9 @@ The `/logs` endpoint requires log retrieval to be enabled in your Hanzo Flow ins
To enable log retrieval, set the following [environment variables](/environment-variables) in your Hanzo Flow `.env` file, and then start Hanzo Flow with `uv run flow run --env-file .env`:
```text
LANGFLOW_ENABLE_LOG_RETRIEVAL=True
LANGFLOW_LOG_RETRIEVER_BUFFER_SIZE=10000 // Must be greater than 0
LANGFLOW_LOG_LEVEL=DEBUG // Can be DEBUG, ERROR, INFO, WARNING, or CRITICAL
FLOW_ENABLE_LOG_RETRIEVAL=True
FLOW_LOG_RETRIEVER_BUFFER_SIZE=10000 // Must be greater than 0
FLOW_LOG_LEVEL=DEBUG // Can be DEBUG, ERROR, INFO, WARNING, or CRITICAL
```
## Stream logs
+2 -2
View File
@@ -321,8 +321,8 @@ Use `GET /monitor/traces` and filter by `flow_id`:
<TabItem value="typescript" label="TypeScript">
```ts
const baseUrl = process.env.LANGFLOW_SERVER_URL ?? "http://localhost:7860";
const apiKey = process.env.LANGFLOW_API_KEY!;
const baseUrl = process.env.FLOW_SERVER_URL ?? "http://localhost:7860";
const apiKey = process.env.FLOW_API_KEY!;
const flowId = "YOUR_FLOW_ID";
async function listTraces() {
@@ -66,7 +66,7 @@ Hanzo Flow uses `x-api-key` headers for authentication, while OpenAI uses `Autho
When sending requests to Hanzo Flow with OpenAI client libraries, you must configure custom headers and include an `api_key` configuration.
The `api_key` parameter can have any value, such as `"dummy-api-key"` in the client examples, as the actual authentication is handled through the `default_headers` configuration.
In the following examples, replace the values for `LANGFLOW_SERVER_URL`, `LANGFLOW_API_KEY`, and `FLOW_ID` with values from your deployment.
In the following examples, replace the values for `FLOW_SERVER_URL`, `FLOW_API_KEY`, and `FLOW_ID` with values from your deployment.
<Tabs groupId="client">
<TabItem value="Python" label="OpenAI Python Client" default>
@@ -126,7 +126,7 @@ If you need these in a different format or want a downloadable calendar, let me
|--------|----------|-------------|---------|
| `x-api-key` | Yes | Your Hanzo Flow API key for authentication | `"sk-..."` |
| `Content-Type` | Yes | Specifies the JSON format | `"application/json"` |
| `X-LANGFLOW-GLOBAL-VAR-*` | No | Global variables for the flow | `"X-LANGFLOW-GLOBAL-VAR-API_KEY: sk-..."` For more, see [Pass global variables to your flows in headers](#global-var). |
| `X-FLOW-GLOBAL-VAR-*` | No | Global variables for the flow | `"X-FLOW-GLOBAL-VAR-API_KEY: sk-..."` For more, see [Pass global variables to your flows in headers](#global-var). |
### Request body
@@ -454,7 +454,7 @@ For example:
</details>
Variables passed with `X-LANGFLOW-GLOBAL-VAR-{VARIABLE_NAME}` are always available to your flow, regardless of whether they exist in the database.
Variables passed with `X-FLOW-GLOBAL-VAR-{VARIABLE_NAME}` are always available to your flow, regardless of whether they exist in the database.
If your flow components reference variables that aren't provided in headers or your Hanzo Flow database, the flow fails by default.
@@ -3,7 +3,7 @@ title: Get started with the Hanzo Flow API
slug: /api-reference-api-examples
---
import CodeSnippet from '@site/src/components/CodeSnippet';
import exampleApiReferenceApiExamplesFormLangflowApiRequests from '!!raw-loader!@site/docs/API-Reference/curl-examples/api-reference-api-examples/form-flow-api-requests.sh';
import exampleApiReferenceApiExamplesFormHanzo FlowApiRequests from '!!raw-loader!@site/docs/API-Reference/curl-examples/api-reference-api-examples/form-flow-api-requests.sh';
import exampleApiReferenceApiExamplesSetEnvironmentVariables from '!!raw-loader!@site/docs/API-Reference/curl-examples/api-reference-api-examples/set-environment-variables.sh';
import exampleApiReferenceApiExamplesHealthCheck from '!!raw-loader!@site/docs/API-Reference/curl-examples/api-reference-api-examples/health-check.sh';
import resultApiReferenceApiExamplesResultHealthCheck from '!!raw-loader!@site/docs/API-Reference/curl-examples/api-reference-api-examples/result-health-check.json';
@@ -12,8 +12,8 @@ import resultApiReferenceApiExamplesResultGetVersion from '!!raw-loader!@site/do
import exampleApiReferenceApiExamplesGetConfiguration from '!!raw-loader!@site/docs/API-Reference/curl-examples/api-reference-api-examples/get-configuration.sh';
import resultApiReferenceApiExamplesResultGetConfiguration from '!!raw-loader!@site/docs/API-Reference/curl-examples/api-reference-api-examples/result-get-configuration.json';
import exampleApiReferenceApiExamplesGetAllComponents from '!!raw-loader!@site/docs/API-Reference/curl-examples/api-reference-api-examples/get-all-components.sh';
import examplePythonApiReferenceApiExamplesFormLangflowApiRequests from '!!raw-loader!@site/docs/API-Reference/python-examples/api-reference-api-examples/form-flow-api-requests.py';
import exampleJavascriptApiReferenceApiExamplesFormLangflowApiRequests from '!!raw-loader!@site/docs/API-Reference/javascript-examples/api-reference-api-examples/form-flow-api-requests.js';
import examplePythonApiReferenceApiExamplesFormHanzo FlowApiRequests from '!!raw-loader!@site/docs/API-Reference/python-examples/api-reference-api-examples/form-flow-api-requests.py';
import exampleJavascriptApiReferenceApiExamplesFormHanzo FlowApiRequests from '!!raw-loader!@site/docs/API-Reference/javascript-examples/api-reference-api-examples/form-flow-api-requests.js';
import examplePythonApiReferenceApiExamplesHealthCheck from '!!raw-loader!@site/docs/API-Reference/python-examples/api-reference-api-examples/health-check.py';
import exampleJavascriptApiReferenceApiExamplesHealthCheck from '!!raw-loader!@site/docs/API-Reference/javascript-examples/api-reference-api-examples/health-check.js';
import examplePythonApiReferenceApiExamplesGetVersion from '!!raw-loader!@site/docs/API-Reference/python-examples/api-reference-api-examples/get-version.py';
@@ -53,17 +53,17 @@ As an example of a Hanzo Flow API request, the following curl command calls the
<Tabs>
<TabItem value="Python" label="Python" default>
<CodeSnippet source={examplePythonApiReferenceApiExamplesFormLangflowApiRequests} language="python" />
<CodeSnippet source={examplePythonApiReferenceApiExamplesFormHanzo FlowApiRequests} language="python" />
</TabItem>
<TabItem value="JavaScript" label="JavaScript">
<CodeSnippet source={exampleJavascriptApiReferenceApiExamplesFormLangflowApiRequests} language="javascript" />
<CodeSnippet source={exampleJavascriptApiReferenceApiExamplesFormHanzo FlowApiRequests} language="javascript" />
</TabItem>
<TabItem value="curl" label="curl">
<CodeSnippet source={exampleApiReferenceApiExamplesFormLangflowApiRequests} language="bash" />
<CodeSnippet source={exampleApiReferenceApiExamplesFormHanzo FlowApiRequests} language="bash" />
</TabItem>
</Tabs>
@@ -72,13 +72,13 @@ As an example of a Hanzo Flow API request, the following curl command calls the
By default, local deployments serve the Hanzo Flow API at `http://localhost:7860/api`.
Remotely hosted Hanzo Flow deployments are available at the domain set by the hosting service, such as `http://IP_OR_DNS/api` or `http://IP_OR_DNS:LANGFLOW_PORT/api`.
Remotely hosted Hanzo Flow deployments are available at the domain set by the hosting service, such as `http://IP_OR_DNS/api` or `http://IP_OR_DNS:FLOW_PORT/api`.
You can configure the Hanzo Flow port number in the `LANGFLOW_PORT` [environment variable](/environment-variables).
You can configure the Hanzo Flow port number in the `FLOW_PORT` [environment variable](/environment-variables).
* `https://UUID.ngrok.app/api`
* `http://IP_OR_DNS/api`
* `http://IP_OR_DNS:LANGFLOW_PORT/api`
* `http://IP_OR_DNS:FLOW_PORT/api`
### Authentication
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/build/123e4567-e89b-12d3-a456-426614174000/events" \
"$FLOW_URL/api/v1/build/123e4567-e89b-12d3-a456-426614174000/events" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/build/123e4567-e89b-12d3-a456-426614174000/events?stream=false" \
"$FLOW_URL/api/v1/build/123e4567-e89b-12d3-a456-426614174000/events?stream=false" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,8 +1,8 @@
curl -X POST \
"$LANGFLOW_URL/api/v1/build/$FLOW_ID/flow" \
"$FLOW_URL/api/v1/build/$FLOW_ID/flow" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{
"inputs": {
"input_value": "Tell me a story"
@@ -1,8 +1,8 @@
curl -X POST \
"$LANGFLOW_URL/api/v1/build/$FLOW_ID/flow" \
"$FLOW_URL/api/v1/build/$FLOW_ID/flow" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{
"data": {
"nodes": [],
@@ -1,6 +1,6 @@
curl -X POST \
"$LANGFLOW_URL/api/v1/build/$FLOW_ID/flow" \
"$FLOW_URL/api/v1/build/$FLOW_ID/flow" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{"stop_component_id": "OpenAIModel-Uksag"}'
@@ -1,4 +1,4 @@
curl -X DELETE \
"$LANGFLOW_URL/api/v2/files" \
"$FLOW_URL/api/v2/files" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X DELETE \
"$LANGFLOW_URL/api/v1/files/delete/$FLOW_ID/2024-12-30_15-19-43_your_file.txt" \
"$FLOW_URL/api/v1/files/delete/$FLOW_ID/2024-12-30_15-19-43_your_file.txt" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X DELETE \
"$LANGFLOW_URL/api/v2/files/$FILE_ID" \
"$FLOW_URL/api/v2/files/$FILE_ID" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,5 +1,5 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/files/download/$FLOW_ID/2024-12-30_15-19-43_your_file.txt" \
"$FLOW_URL/api/v1/files/download/$FLOW_ID/2024-12-30_15-19-43_your_file.txt" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
--output downloaded_file.txt
@@ -1,5 +1,5 @@
curl -X GET \
"$LANGFLOW_URL/api/v2/files/c7b22c4c-d5e0-4ec9-af97-5d85b7657a34" \
"$FLOW_URL/api/v2/files/c7b22c4c-d5e0-4ec9-af97-5d85b7657a34" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
--output downloaded_file.txt
@@ -1,4 +1,4 @@
curl -X PUT \
"$LANGFLOW_URL/api/v2/files/$FILE_ID?name=new_file_name" \
"$FLOW_URL/api/v2/files/$FILE_ID?name=new_file_name" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/files/list/$FLOW_ID" \
"$FLOW_URL/api/v1/files/list/$FLOW_ID" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v2/files" \
"$FLOW_URL/api/v2/files" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,7 +1,7 @@
curl --request POST \
--url "$LANGFLOW_URL/api/v1/run/$FLOW_ID" \
--url "$FLOW_URL/api/v1/run/$FLOW_ID" \
--header "Content-Type: application/json" \
--header "x-api-key: $LANGFLOW_API_KEY" \
--header "x-api-key: $FLOW_API_KEY" \
--data '{
"input_value": "what do you see?",
"output_type": "chat",
@@ -3,8 +3,8 @@ DEFAULT_UPLOAD_FILE="$SCRIPT_DIR/../../fixtures/sample-upload.txt"
UPLOAD_FILE="${SAMPLE_UPLOAD_FILE:-$DEFAULT_UPLOAD_FILE}"
curl -X POST \
"$LANGFLOW_URL/api/v2/files" \
"$FLOW_URL/api/v2/files" \
-H "accept: application/json" \
-H "Content-Type: multipart/form-data" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-F "file=@${UPLOAD_FILE}"
@@ -3,8 +3,8 @@ DEFAULT_UPLOAD_FILE="$SCRIPT_DIR/../../fixtures/sample-upload.txt"
UPLOAD_FILE="${SAMPLE_UPLOAD_FILE:-$DEFAULT_UPLOAD_FILE}"
curl -X POST \
"$LANGFLOW_URL/api/v1/files/upload/$FLOW_ID" \
"$FLOW_URL/api/v1/files/upload/$FLOW_ID" \
-H "accept: application/json" \
-H "Content-Type: multipart/form-data" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-F "file=@${UPLOAD_FILE}"
@@ -3,8 +3,8 @@ DEFAULT_UPLOAD_FILE="$SCRIPT_DIR/../../fixtures/sample-upload.txt"
UPLOAD_FILE="${SAMPLE_UPLOAD_FILE:-$DEFAULT_UPLOAD_FILE}"
curl -X POST \
"$LANGFLOW_URL/api/v2/files" \
"$FLOW_URL/api/v2/files" \
-H "accept: application/json" \
-H "Content-Type: multipart/form-data" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-F "file=@${UPLOAD_FILE}"
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/users/whoami" \
"$FLOW_URL/api/v1/users/whoami" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,7 +1,7 @@
curl -X POST \
"$LANGFLOW_URL/api/v1/run/a430cc57-06bb-4c11-be39-d3d4de68d2c4?stream=false" \
"$FLOW_URL/api/v1/run/a430cc57-06bb-4c11-be39-d3d4de68d2c4?stream=false" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{
"output_type": "chat",
"input_type": "chat",
@@ -2,7 +2,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEFAULT_IMAGE_FILE="$SCRIPT_DIR/../../fixtures/sample-upload.png"
IMAGE_FILE="${SAMPLE_IMAGE_FILE:-$DEFAULT_IMAGE_FILE}"
curl -X POST "$LANGFLOW_URL/api/v1/files/upload/$FLOW_ID" \
curl -X POST "$FLOW_URL/api/v1/files/upload/$FLOW_ID" \
-H "Content-Type: multipart/form-data" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-F "file=@${IMAGE_FILE}"
@@ -1,10 +1,10 @@
curl -X POST \
"$LANGFLOW_SERVER_URL/api/v1/run/$FLOW_ID" \
"$FLOW_SERVER_URL/api/v1/run/$FLOW_ID" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "X-LANGFLOW-GLOBAL-VAR-OPENAI_API_KEY: sk-..." \
-H "X-LANGFLOW-GLOBAL-VAR-USER_ID: user123" \
-H "X-LANGFLOW-GLOBAL-VAR-ENVIRONMENT: production" \
-H "x-api-key: $FLOW_API_KEY" \
-H "X-FLOW-GLOBAL-VAR-OPENAI_API_KEY: sk-..." \
-H "X-FLOW-GLOBAL-VAR-USER_ID: user123" \
-H "X-FLOW-GLOBAL-VAR-ENVIRONMENT: production" \
-d '{
"input_value": "Tell me about something interesting!",
"input_type": "chat",
@@ -1,8 +1,8 @@
curl -X POST \
"$LANGFLOW_SERVER_URL/api/v1/run/$FLOW_ID?stream=true" \
"$FLOW_SERVER_URL/api/v1/run/$FLOW_ID?stream=true" \
-H "Content-Type: application/json" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{
"input_value": "Tell me a story",
"input_type": "chat",
@@ -1,7 +1,7 @@
curl -X POST \
"$LANGFLOW_SERVER_URL/api/v1/run/$FLOW_ID" \
"$FLOW_SERVER_URL/api/v1/run/$FLOW_ID" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{
"input_value": "Tell me about something interesting!",
"session_id": "chat-123",
@@ -1,8 +1,8 @@
curl -X POST \
"$LANGFLOW_SERVER_URL/api/v1/run/$FLOW_ID?stream=true" \
"$FLOW_SERVER_URL/api/v1/run/$FLOW_ID?stream=true" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{
"message": "Tell me something interesting!",
"session_id": "chat-123"
@@ -1,5 +1,5 @@
curl -X POST \
"$LANGFLOW_SERVER_URL/api/v1/webhook/$FLOW_ID" \
"$FLOW_SERVER_URL/api/v1/webhook/$FLOW_ID" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{"data": "example-data"}'
@@ -1,8 +1,8 @@
curl -X POST \
"$LANGFLOW_URL/api/v1/flows/" \
"$FLOW_URL/api/v1/flows/" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{
"name": "string2",
"description": "string",
@@ -1,8 +1,8 @@
curl -X POST \
"$LANGFLOW_URL/api/v1/flows/batch/" \
"$FLOW_URL/api/v1/flows/batch/" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{
"flows": [
{
@@ -1,4 +1,4 @@
curl -X DELETE \
"$LANGFLOW_URL/api/v1/flows/$FLOW_ID" \
"$FLOW_URL/api/v1/flows/$FLOW_ID" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,8 +1,8 @@
curl -X POST \
"$LANGFLOW_URL/api/v1/flows/download/" \
"$FLOW_URL/api/v1/flows/download/" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '[
"e1e40c77-0541-41a9-88ab-ddb3419398b5",
"92f9a4c5-cfc8-4656-ae63-1f0881163c28"
@@ -3,8 +3,8 @@ DEFAULT_FLOW_IMPORT_FILE="$SCRIPT_DIR/../../fixtures/flow-import.json"
FLOW_IMPORT_FILE="${FLOW_IMPORT_FILE:-$DEFAULT_FLOW_IMPORT_FILE}"
curl -X POST \
"$LANGFLOW_URL/api/v1/flows/upload/?folder_id=$FOLDER_ID" \
"$FLOW_URL/api/v1/flows/upload/?folder_id=$FOLDER_ID" \
-H "accept: application/json" \
-H "Content-Type: multipart/form-data" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-F "file=@${FLOW_IMPORT_FILE};type=application/json"
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/flows/$FLOW_ID" \
"$FLOW_URL/api/v1/flows/$FLOW_ID" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/flows/?remove_example_flows=true&components_only=false&get_all=false&project_id=$PROJECT_ID&header_flows=false&page=1&size=1" \
"$FLOW_URL/api/v1/flows/?remove_example_flows=true&components_only=false&get_all=false&project_id=$PROJECT_ID&header_flows=false&page=1&size=1" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/flows/?remove_example_flows=false&components_only=false&get_all=true&header_flows=false&page=1&size=50" \
"$FLOW_URL/api/v1/flows/?remove_example_flows=false&components_only=false&get_all=true&header_flows=false&page=1&size=50" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/flows/basic_examples/" \
"$FLOW_URL/api/v1/flows/basic_examples/" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,8 +1,8 @@
curl -X PATCH \
"$LANGFLOW_URL/api/v1/flows/$FLOW_ID" \
"$FLOW_URL/api/v1/flows/$FLOW_ID" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{
"name": "string",
"description": "string",
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/logs?lines_before=0&lines_after=0&timestamp=0" \
"$FLOW_URL/logs?lines_before=0&lines_after=0&timestamp=0" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/logs-stream" \
"$FLOW_URL/logs-stream" \
-H "accept: text/event-stream" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X DELETE \
"$LANGFLOW_URL/api/v1/monitor/messages/session/different_session_id_2" \
"$FLOW_URL/api/v1/monitor/messages/session/different_session_id_2" \
-H "accept: */*" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,6 +1,6 @@
curl -v -X DELETE \
"$LANGFLOW_URL/api/v1/monitor/messages" \
"$FLOW_URL/api/v1/monitor/messages" \
-H "accept: */*" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '["MESSAGE_ID_1", "MESSAGE_ID_2"]'
@@ -1,4 +1,4 @@
curl -X DELETE \
"$LANGFLOW_URL/api/v1/monitor/builds?flow_id=$FLOW_ID" \
"$FLOW_URL/api/v1/monitor/builds?flow_id=$FLOW_ID" \
-H "accept: */*" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,8 +1,8 @@
export LANGFLOW_SERVER_URL="http://localhost:7860"
export LANGFLOW_API_KEY="YOUR_LANGFLOW_API_KEY"
export FLOW_SERVER_URL="http://localhost:7860"
export FLOW_API_KEY="YOUR_FLOW_API_KEY"
export FLOW_ID="YOUR_FLOW_ID"
curl -s "$LANGFLOW_SERVER_URL/api/v1/monitor/traces?flow_id=$FLOW_ID&page=1&size=50" \
curl -s "$FLOW_SERVER_URL/api/v1/monitor/traces?flow_id=$FLOW_ID&page=1&size=50" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
| jq .
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/monitor/messages?flow_id=$FLOW_ID&session_id=01ce083d-748b-4b8d-97b6-33adbb6a528a&sender=Machine&sender_name=AI&order_by=timestamp" \
"$FLOW_URL/api/v1/monitor/messages?flow_id=$FLOW_ID&session_id=01ce083d-748b-4b8d-97b6-33adbb6a528a&sender=Machine&sender_name=AI&order_by=timestamp" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/monitor/messages" \
"$FLOW_URL/api/v1/monitor/messages" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/monitor/transactions?flow_id=$FLOW_ID&page=1&size=50" \
"$FLOW_URL/api/v1/monitor/transactions?flow_id=$FLOW_ID&page=1&size=50" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,4 +1,4 @@
curl -X GET \
"$LANGFLOW_URL/api/v1/monitor/builds?flow_id=$FLOW_ID" \
"$FLOW_URL/api/v1/monitor/builds?flow_id=$FLOW_ID" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,8 +1,8 @@
curl -X PUT \
"$LANGFLOW_URL/api/v1/monitor/messages/3ab66cc6-c048-48f8-ab07-570f5af7b160" \
"$FLOW_URL/api/v1/monitor/messages/3ab66cc6-c048-48f8-ab07-570f5af7b160" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{
"text": "testing 1234"
}'
@@ -1,4 +1,4 @@
curl -X PATCH \
"$LANGFLOW_URL/api/v1/monitor/messages/session/01ce083d-748b-4b8d-97b6-33adbb6a528a?new_session_id=different_session_id" \
"$FLOW_URL/api/v1/monitor/messages/session/01ce083d-748b-4b8d-97b6-33adbb6a528a?new_session_id=different_session_id" \
-H "accept: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY"
-H "x-api-key: $FLOW_API_KEY"
@@ -1,8 +1,8 @@
BASE_URL="${LANGFLOW_SERVER_URL:-$LANGFLOW_URL}"
BASE_URL="${FLOW_SERVER_URL:-$FLOW_URL}"
curl -X POST \
"$BASE_URL/api/v1/responses" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
@@ -1,8 +1,8 @@
BASE_URL="${LANGFLOW_SERVER_URL:-$LANGFLOW_URL}"
BASE_URL="${FLOW_SERVER_URL:-$FLOW_URL}"
curl -X POST \
"$BASE_URL/api/v1/responses" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
@@ -1,8 +1,8 @@
BASE_URL="${LANGFLOW_SERVER_URL:-$LANGFLOW_URL}"
BASE_URL="${FLOW_SERVER_URL:-$FLOW_URL}"
curl -X POST \
"$BASE_URL/api/v1/responses" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
@@ -1,6 +1,6 @@
curl -X POST \
"$LANGFLOW_SERVER_URL/api/v1/responses" \
-H "x-api-key: $LANGFLOW_API_KEY" \
"$FLOW_SERVER_URL/api/v1/responses" \
-H "x-api-key: $FLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "$YOUR_FLOW_ID",
@@ -1,6 +1,6 @@
curl -X POST \
"$LANGFLOW_SERVER_URL/api/v1/responses" \
-H "x-api-key: $LANGFLOW_API_KEY" \
"$FLOW_SERVER_URL/api/v1/responses" \
-H "x-api-key: $FLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "$FLOW_ID",
@@ -1,10 +1,10 @@
curl -X POST \
"$LANGFLOW_SERVER_URL/api/v1/responses" \
-H "x-api-key: $LANGFLOW_API_KEY" \
"$FLOW_SERVER_URL/api/v1/responses" \
-H "x-api-key: $FLOW_API_KEY" \
-H "Content-Type: application/json" \
-H "X-LANGFLOW-GLOBAL-VAR-OPENAI_API_KEY: sk-..." \
-H "X-LANGFLOW-GLOBAL-VAR-USER_ID: user123" \
-H "X-LANGFLOW-GLOBAL-VAR-ENVIRONMENT: production" \
-H "X-FLOW-GLOBAL-VAR-OPENAI_API_KEY: sk-..." \
-H "X-FLOW-GLOBAL-VAR-USER_ID: user123" \
-H "X-FLOW-GLOBAL-VAR-ENVIRONMENT: production" \
-d '{
"model": "your-flow-id",
"input": "Hello"
@@ -1,9 +1,9 @@
BASE_URL="${LANGFLOW_SERVER_URL:-$LANGFLOW_URL}"
BASE_URL="${FLOW_SERVER_URL:-$FLOW_URL}"
curl -X POST \
"$BASE_URL/api/v1/responses" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d @- <<EOF
{
"model": "$FLOW_ID",
@@ -1,6 +1,6 @@
curl -X POST \
"$LANGFLOW_SERVER_URL/api/v1/responses" \
-H "x-api-key: $LANGFLOW_API_KEY" \
"$FLOW_SERVER_URL/api/v1/responses" \
-H "x-api-key: $FLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "FLOW_ID",
@@ -1,8 +1,8 @@
curl -X POST \
"$LANGFLOW_URL/api/v1/projects/" \
"$FLOW_URL/api/v1/projects/" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{
"name": "new_project_name",
"description": "string",
@@ -1,7 +1,7 @@
curl -X POST \
"$LANGFLOW_URL/api/v1/projects/" \
"$FLOW_URL/api/v1/projects/" \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-H "x-api-key: $FLOW_API_KEY" \
-d '{
"name": "new_project_name",
"description": "string",

Some files were not shown because too many files have changed in this diff Show More