mirror of
https://github.com/hanzoai/flow.git
synced 2026-10-17 01:29:18 +00:00
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:
@@ -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
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
self-hosted-runner:
|
||||
labels:
|
||||
- flow-ai-arm64-40gb-ephemeral
|
||||
- Hanzo Flow-runner
|
||||
- Flow-runner
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -25,7 +25,7 @@ env:
|
||||
|
||||
jobs:
|
||||
build-bundles:
|
||||
name: Build Hanzo Flow Bundles
|
||||
name: Build Flow Bundles
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
@@ -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,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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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"]
|
||||
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;'
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}"
|
||||
|
||||
+5
-5
@@ -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",
|
||||
|
||||
+2
-2
@@ -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",
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
curl -X GET \
|
||||
"$LANGFLOW_URL/logs?lines_before=0&lines_after=0×tamp=0" \
|
||||
"$FLOW_URL/logs?lines_before=0&lines_after=0×tamp=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"
|
||||
|
||||
+2
-2
@@ -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
|
||||
{
|
||||
|
||||
+2
-2
@@ -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
|
||||
{
|
||||
|
||||
+2
-2
@@ -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",
|
||||
|
||||
+2
-2
@@ -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",
|
||||
|
||||
+5
-5
@@ -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"
|
||||
|
||||
+2
-2
@@ -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
Reference in New Issue
Block a user