mirror of
https://github.com/hanzoai/flow.git
synced 2026-10-17 01:29:18 +00:00
refactor(rebrand): langflow->flow package names + product strings (app code)
Stage 2 of the rebrand, on top of the module migration: - Workspace distribution names langflow-base/langflow-sdk -> hanzo-flow-base/ hanzo-flow-sdk across all pyproject.toml (matches root hanzo-flow). - App-code product strings: "Langflow" -> "Hanzo Flow", bare "langflow" -> "flow" across src/backend/base/flow + src/lfx/src (207 files) — MCP server names, docstrings, user-facing labels. compileall of the flow package + lfx parses clean. DELIBERATELY NOT swept (the delicate config-boundary layer — needs the running app + a compat decision, not a blind sed): - LANGFLOW_* env vars (LANGFLOW_DATABASE_URL, LANGFLOW_SERVER_URL, LANGFLOW_SSRF_PROTECTION_ENABLED, ...) — renaming breaks every deployment's config; needs a FLOW_/HANZO_ alias with fallback, coordinated with deploy env. - pydantic settings fields that map to those env vars. - internal identifiers (LangflowHTTPError, *_langflow_connections_binding) — safe to global-rename but want the uv suite green to confirm no reference is missed.
This commit is contained in:
@@ -1 +1 @@
|
||||
"""Agentic experience module for Langflow."""
|
||||
"""Agentic experience module for Hanzo Flow."""
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Langflow Assistant API module."""
|
||||
"""Hanzo Flow Assistant API module."""
|
||||
|
||||
# Note: router is imported directly via flow.agentic.api.router to avoid circular imports
|
||||
# Use: from flow.agentic.api.router import router
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Langflow Assistant API router.
|
||||
"""Hanzo Flow Assistant API router.
|
||||
|
||||
This module provides the HTTP endpoints for the Langflow Assistant.
|
||||
This module provides the HTTP endpoints for the Hanzo Flow Assistant.
|
||||
All business logic is delegated to service modules.
|
||||
"""
|
||||
|
||||
@@ -171,7 +171,7 @@ async def check_assistant_config(
|
||||
current_user: CurrentActiveUser,
|
||||
session: DbSession,
|
||||
) -> dict:
|
||||
"""Check if the Langflow Assistant is properly configured.
|
||||
"""Check if the Hanzo Flow Assistant is properly configured.
|
||||
|
||||
Returns available providers with their configured status and available models.
|
||||
"""
|
||||
@@ -256,7 +256,7 @@ async def assist(
|
||||
current_user: CurrentActiveUser,
|
||||
session: DbSession,
|
||||
) -> dict:
|
||||
"""Chat with the Langflow Assistant."""
|
||||
"""Chat with the Hanzo Flow Assistant."""
|
||||
ctx = await _resolve_assistant_context(request, current_user.id, session)
|
||||
|
||||
logger.info(f"Executing {FLOW_ASSISTANT_FLOW} with {ctx.provider}/{ctx.model_name}")
|
||||
@@ -281,7 +281,7 @@ async def assist_stream(
|
||||
current_user: CurrentActiveUser,
|
||||
session: DbSession,
|
||||
) -> StreamingResponse:
|
||||
"""Chat with the Langflow Assistant with streaming progress updates."""
|
||||
"""Chat with the Hanzo Flow Assistant with streaming progress updates."""
|
||||
ctx = await _resolve_assistant_context(request, current_user.id, session)
|
||||
|
||||
return StreamingResponse(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Langflow Agentic Flows.
|
||||
"""Hanzo Flow Agentic Flows.
|
||||
|
||||
This package contains flow definitions for the Langflow Assistant feature.
|
||||
This package contains flow definitions for the Hanzo Flow Assistant feature.
|
||||
|
||||
Available flows:
|
||||
- translation_flow: Intent classification and translation flow (Python)
|
||||
|
||||
@@ -14,42 +14,42 @@ from lfx.components.models import LanguageModelComponent
|
||||
from lfx.graph import Graph
|
||||
|
||||
TRANSLATION_PROMPT = """You are a Language Detection, Translation, and Intent Classification \
|
||||
Agent for Langflow Assistant.
|
||||
Agent for Hanzo Flow Assistant.
|
||||
|
||||
Your responsibilities are:
|
||||
1. Translate the input text to English (if not already in English)
|
||||
2. Classify the user's intent
|
||||
|
||||
Intent Classification:
|
||||
- "generate_component": User wants you to CREATE/BUILD/GENERATE/MODIFY a custom Langflow component.
|
||||
- "generate_component": User wants you to CREATE/BUILD/GENERATE/MODIFY a custom Hanzo Flow component.
|
||||
This includes both new component requests AND follow-up modifications to a previous component.
|
||||
Examples: "Create a component that calls an API", "Build me a custom component for...",
|
||||
"can you use dataframe output instead?", "add error handling", "make it also support CSV",
|
||||
"change the output to return a list", "use requests instead of urllib", "add a timeout parameter"
|
||||
- "question": User is ASKING A QUESTION about Langflow, seeking help with Langflow, or wants \
|
||||
information about Langflow features, components, flows, or how to use Langflow.
|
||||
- "question": User is ASKING A QUESTION about Hanzo Flow, seeking help with Hanzo Flow, or wants \
|
||||
information about Hanzo Flow features, components, flows, or how to use Hanzo Flow.
|
||||
Examples: "How do I create a component?", "What is a component?", "Can you explain flows?", \
|
||||
"How to connect two components?"
|
||||
- "off_topic": The question is NOT about Langflow. It is about other tools, platforms, general \
|
||||
knowledge, or anything unrelated to Langflow.
|
||||
- "off_topic": The question is NOT about Hanzo Flow. It is about other tools, platforms, general \
|
||||
knowledge, or anything unrelated to Hanzo Flow.
|
||||
Examples: "How does n8n work?", "What is Python?", "Tell me about React", "How to cook pasta", \
|
||||
"Explain Docker", "What is AutoGen?", "How does Make.com work?", "Write me a poem"
|
||||
|
||||
IMPORTANT rules:
|
||||
- "How to create a component" = question (asking for Langflow guidance)
|
||||
- "How to create a component" = question (asking for Hanzo Flow guidance)
|
||||
- "Create a component that does X" = generate_component (requesting creation)
|
||||
- Short follow-up requests that imply changes to something previously generated = generate_component
|
||||
(e.g., "use X instead", "add Y", "change Z", "make it do W", "can you also...", "what about using...")
|
||||
- Questions about OTHER tools or platforms (n8n, Make, Zapier, AutoGen, CrewAI, etc.) = off_topic
|
||||
- General knowledge questions NOT related to Langflow = off_topic
|
||||
- If unsure whether it's about Langflow, classify as "question" (not off_topic)
|
||||
- General knowledge questions NOT related to Hanzo Flow = off_topic
|
||||
- If unsure whether it's about Hanzo Flow, classify as "question" (not off_topic)
|
||||
|
||||
Output format (JSON only, no markdown):
|
||||
{{"translation": "<english text>", "intent": "<generate_component|question|off_topic>"}}
|
||||
|
||||
Examples:
|
||||
Input: "como criar um componente no langflow"
|
||||
Output: {{"translation": "how to create a component in langflow", "intent": "question"}}
|
||||
Input: "como criar um componente no flow"
|
||||
Output: {{"translation": "how to create a component in flow", "intent": "question"}}
|
||||
|
||||
Input: "crie um componente que chama uma API"
|
||||
Output: {{"translation": "create a component that calls an API", "intent": "generate_component"}}
|
||||
|
||||
@@ -1 +1 @@
|
||||
"""Helper utilities for the Langflow Assistant."""
|
||||
"""Helper utilities for the Hanzo Flow Assistant."""
|
||||
|
||||
@@ -12,7 +12,7 @@ def extract_python_code(text: str) -> str | None:
|
||||
"""Extract Python code from markdown code blocks.
|
||||
|
||||
Handles both closed (```python ... ```) and unclosed blocks.
|
||||
Returns the first code block that appears to be a Langflow component.
|
||||
Returns the first code block that appears to be a Hanzo Flow component.
|
||||
"""
|
||||
matches = _find_code_blocks(text)
|
||||
if not matches:
|
||||
@@ -46,7 +46,7 @@ def _find_unclosed_code_block(text: str) -> list[str]:
|
||||
|
||||
|
||||
def _find_component_code(matches: list[str]) -> str | None:
|
||||
"""Find the first match that looks like a Langflow component."""
|
||||
"""Find the first match that looks like a Hanzo Flow component."""
|
||||
for match in matches:
|
||||
if "class " in match and "Component" in match:
|
||||
return match.strip()
|
||||
|
||||
@@ -18,7 +18,7 @@ DANGEROUS_CALLS: dict[str, str] = {
|
||||
|
||||
# Dangerous attribute calls: (module, method, violation_message)
|
||||
DANGEROUS_ATTR_CALLS: list[tuple[str, str, str]] = [
|
||||
("os", "system", "os.system() is forbidden — use Langflow's built-in integrations"),
|
||||
("os", "system", "os.system() is forbidden — use Hanzo Flow's built-in integrations"),
|
||||
("os", "popen", "os.popen() is forbidden"),
|
||||
("os", "execl", "os.execl() is forbidden"),
|
||||
("os", "execle", "os.execle() is forbidden"),
|
||||
|
||||
@@ -11,15 +11,15 @@ MAX_INPUT_LENGTH = 2000
|
||||
|
||||
REFUSAL_MESSAGE = (
|
||||
"I'm sorry, but I can't process that request. "
|
||||
"I'm the Langflow Assistant and I can help you with "
|
||||
"Langflow components, flows, and technical questions. "
|
||||
"Please rephrase your question about Langflow."
|
||||
"I'm the Hanzo Flow Assistant and I can help you with "
|
||||
"Hanzo Flow components, flows, and technical questions. "
|
||||
"Please rephrase your question about Hanzo Flow."
|
||||
)
|
||||
|
||||
# Prompt injection patterns: (compiled_regex, violation_description)
|
||||
# Each pattern targets a specific injection technique.
|
||||
# Patterns are intentionally specific to avoid false positives on
|
||||
# legitimate Langflow questions (e.g., "how do I ignore errors").
|
||||
# legitimate Hanzo Flow questions (e.g., "how do I ignore errors").
|
||||
INJECTION_PATTERNS: list[tuple[re.Pattern[str], str]] = [
|
||||
# Instruction override attempts
|
||||
(
|
||||
|
||||
@@ -30,7 +30,7 @@ class _ReturnChecker(ast.NodeVisitor):
|
||||
break
|
||||
self.generic_visit(node)
|
||||
|
||||
# Langflow components commonly use async output methods
|
||||
# Hanzo Flow components commonly use async output methods
|
||||
visit_AsyncFunctionDef = visit_FunctionDef # noqa: N815
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""MCP (Model Context Protocol) server for Langflow Agentic tools."""
|
||||
"""MCP (Model Context Protocol) server for Hanzo Flow Agentic tools."""
|
||||
|
||||
from flow.agentic.mcp.server import mcp
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Entry point for running the Langflow Agentic MCP server.
|
||||
"""Entry point for running the Hanzo Flow Agentic MCP server.
|
||||
|
||||
This allows running the server with:
|
||||
python -m flow.agentic.mcp
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""FastMCP server for Langflow Agentic tools.
|
||||
"""FastMCP server for Hanzo Flow Agentic tools.
|
||||
|
||||
This module exposes template search and creation functions as MCP tools using FastMCP decorators.
|
||||
"""
|
||||
@@ -40,7 +40,7 @@ from flow.agentic.utils.template_search import (
|
||||
from flow.services.deps import get_settings_service, session_scope
|
||||
|
||||
# Initialize FastMCP server
|
||||
mcp = FastMCP("langflow-agentic")
|
||||
mcp = FastMCP("flow-agentic")
|
||||
|
||||
DEFAULT_TEMPLATE_FIELDS = ["id", "name", "description", "tags", "endpoint_name", "icon"]
|
||||
DEFAULT_COMPONENT_FIELDS = ["name", "type", "display_name", "description"]
|
||||
|
||||
@@ -1 +1 @@
|
||||
"""Services for the Langflow Assistant."""
|
||||
"""Services for the Hanzo Flow Assistant."""
|
||||
|
||||
@@ -407,7 +407,7 @@ async def execute_flow_with_validation_streaming(
|
||||
current_input = VALIDATION_RETRY_TEMPLATE.format(
|
||||
error=f"Security violations: {violations_str}. "
|
||||
"Do NOT use dangerous functions like os.system, subprocess, exec, eval. "
|
||||
"Use Langflow's built-in integrations instead.",
|
||||
"Use Hanzo Flow's built-in integrations instead.",
|
||||
code=code,
|
||||
)
|
||||
continue
|
||||
|
||||
@@ -10,7 +10,7 @@ import lfx
|
||||
# Relative path embedded in the bundled LangflowAssistant.json flow for the
|
||||
# Directory component that scans built-in lfx components. It only resolves
|
||||
# correctly when the process CWD is the monorepo root, which is never the
|
||||
# case for a packaged install (Langflow Desktop, `pip install langflow`,
|
||||
# case for a packaged install (Hanzo Flow Desktop, `pip install flow`,
|
||||
# Docker, etc.). inject_lfx_components_path rewrites it to an absolute path
|
||||
# derived from the installed lfx package at runtime.
|
||||
LFX_COMPONENTS_PATH_SENTINEL = "./src/lfx/src/lfx/components/"
|
||||
@@ -113,7 +113,7 @@ def inject_lfx_components_path(flow_data: dict) -> dict:
|
||||
The bundled LangflowAssistant flow hardcodes a relative path that only
|
||||
resolves from the monorepo root. In any packaged install the process CWD
|
||||
is different and the Directory component raises "Path ... must exist and
|
||||
be a directory.", causing the Langflow Assistant to fail with
|
||||
be a directory.", causing the Hanzo Flow Assistant to fail with
|
||||
"An internal error occurred while executing the flow." on first use.
|
||||
|
||||
This function walks the flow nodes and, for each Directory node whose
|
||||
|
||||
@@ -41,7 +41,7 @@ ERROR:
|
||||
ORIGINAL REQUEST:
|
||||
{original_input}
|
||||
|
||||
Respond with a complete, valid Langflow component as a Python class extending Component, \
|
||||
Respond with a complete, valid Hanzo Flow component as a Python class extending Component, \
|
||||
inside a single ```python code block. Do not emit raw tool calls or partial JSON."""
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Utilities for agentic features in Langflow."""
|
||||
"""Utilities for agentic features in Hanzo Flow."""
|
||||
|
||||
from flow.agentic.utils.template_search import (
|
||||
get_all_tags,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Component search and metadata utilities for Langflow."""
|
||||
"""Component search and metadata utilities for Hanzo Flow."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Flow component operations utilities for Langflow."""
|
||||
"""Flow component operations utilities for Hanzo Flow."""
|
||||
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Flow graph visualization utilities for Langflow."""
|
||||
"""Flow graph visualization utilities for Hanzo Flow."""
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from uuid import UUID
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Template search and loading utilities for Langflow."""
|
||||
"""Template search and loading utilities for Hanzo Flow."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""API utilities for Langflow.
|
||||
"""API utilities for Hanzo Flow.
|
||||
|
||||
This module provides backward compatibility by re-exporting all utilities
|
||||
from the core module. This ensures existing imports continue to work while
|
||||
|
||||
@@ -275,10 +275,10 @@ async def check_flow_version(component: StoreComponentCreate) -> None:
|
||||
|
||||
langflow_version = await get_lf_version_from_pypi()
|
||||
if langflow_version is None:
|
||||
raise HTTPException(status_code=500, detail="Unable to verify the latest version of Langflow")
|
||||
raise HTTPException(status_code=500, detail="Unable to verify the latest version of Hanzo Flow")
|
||||
if langflow_version != component.last_tested_version:
|
||||
await logger.awarning(
|
||||
f"Your version of Langflow ({component.last_tested_version}) is outdated. "
|
||||
f"Your version of Hanzo Flow ({component.last_tested_version}) is outdated. "
|
||||
f"Please update to the latest version ({langflow_version}) and try again."
|
||||
)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""MCP utilities for Langflow."""
|
||||
"""MCP utilities for Hanzo Flow."""
|
||||
|
||||
from flow.api.utils.mcp.config_utils import (
|
||||
auto_configure_starter_projects_mcp,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Utilities for auto-configuring the Langflow Agentic MCP server."""
|
||||
"""Utilities for auto-configuring the Hanzo Flow Agentic MCP server."""
|
||||
|
||||
import sys
|
||||
from uuid import UUID
|
||||
@@ -18,9 +18,9 @@ from flow.services.variable.constants import CREDENTIAL_TYPE, GENERIC_TYPE
|
||||
|
||||
|
||||
async def auto_configure_agentic_mcp_server(session: AsyncSession) -> None:
|
||||
"""Auto-configure the Langflow Agentic MCP server for all users.
|
||||
"""Auto-configure the Hanzo Flow Agentic MCP server for all users.
|
||||
|
||||
This function adds the langflow-agentic MCP server to each user's MCP
|
||||
This function adds the flow-agentic MCP server to each user's MCP
|
||||
configuration, making the agentic tools available in their MCP clients
|
||||
(like Claude Desktop).
|
||||
|
||||
@@ -34,7 +34,7 @@ async def auto_configure_agentic_mcp_server(session: AsyncSession) -> None:
|
||||
await logger.adebug("Agentic experience disabled, skipping agentic MCP server configuration")
|
||||
return
|
||||
|
||||
await logger.ainfo("Auto-configuring Langflow Agentic MCP server for all users...")
|
||||
await logger.ainfo("Auto-configuring Hanzo Flow Agentic MCP server for all users...")
|
||||
|
||||
try:
|
||||
# Get all users in the system
|
||||
@@ -49,13 +49,13 @@ async def auto_configure_agentic_mcp_server(session: AsyncSession) -> None:
|
||||
storage_service = get_service(ServiceType.STORAGE_SERVICE)
|
||||
|
||||
# Server configuration
|
||||
server_name = "langflow-agentic"
|
||||
server_name = "flow-agentic"
|
||||
python_executable = sys.executable
|
||||
server_config = {
|
||||
"command": python_executable,
|
||||
"args": ["-m", "flow.agentic.mcp"],
|
||||
"metadata": {
|
||||
"description": "Langflow Agentic MCP server providing tools for flow/component operations, "
|
||||
"description": "Hanzo Flow Agentic MCP server providing tools for flow/component operations, "
|
||||
"template search, and graph visualization",
|
||||
"auto_configured": True,
|
||||
"langflow_internal": True,
|
||||
@@ -124,15 +124,15 @@ async def auto_configure_agentic_mcp_server(session: AsyncSession) -> None:
|
||||
|
||||
|
||||
async def remove_agentic_mcp_server(session: AsyncSession) -> None:
|
||||
"""Remove the Langflow Agentic MCP server from all users.
|
||||
"""Remove the Hanzo Flow Agentic MCP server from all users.
|
||||
|
||||
This function removes the langflow-agentic MCP server from each user's MCP
|
||||
This function removes the flow-agentic MCP server from each user's MCP
|
||||
configuration. Used when agentic experience is disabled.
|
||||
|
||||
Args:
|
||||
session: Database session for querying users.
|
||||
"""
|
||||
await logger.ainfo("Removing Langflow Agentic MCP server from all users...")
|
||||
await logger.ainfo("Removing Hanzo Flow Agentic MCP server from all users...")
|
||||
|
||||
try:
|
||||
# Get all users
|
||||
@@ -146,7 +146,7 @@ async def remove_agentic_mcp_server(session: AsyncSession) -> None:
|
||||
storage_service = get_service(ServiceType.STORAGE_SERVICE)
|
||||
settings_service = get_settings_service()
|
||||
|
||||
server_name = "langflow-agentic"
|
||||
server_name = "flow-agentic"
|
||||
servers_removed = 0
|
||||
|
||||
for user in users:
|
||||
|
||||
@@ -143,15 +143,15 @@ router = APIRouter(prefix="/deployments", tags=["Deployments"], include_in_schem
|
||||
|
||||
DeploymentProviderAccountIdQuery = Annotated[
|
||||
UUID,
|
||||
Query(description="Langflow DB provider-account UUID (`deployment_provider_account.id`)."),
|
||||
Query(description="Hanzo Flow DB provider-account UUID (`deployment_provider_account.id`)."),
|
||||
]
|
||||
DeploymentProviderAccountIdPath = Annotated[
|
||||
UUID,
|
||||
Path(description="Langflow DB provider-account UUID (`deployment_provider_account.id`)."),
|
||||
Path(description="Hanzo Flow DB provider-account UUID (`deployment_provider_account.id`)."),
|
||||
]
|
||||
DeploymentIdPath = Annotated[
|
||||
UUID,
|
||||
Path(description="Langflow DB deployment UUID (`deployment.id`)."),
|
||||
Path(description="Hanzo Flow DB deployment UUID (`deployment.id`)."),
|
||||
]
|
||||
ProjectIdQuery = Annotated[
|
||||
UUID | None,
|
||||
@@ -159,7 +159,7 @@ ProjectIdQuery = Annotated[
|
||||
]
|
||||
DeploymentIdQuery = Annotated[
|
||||
UUID,
|
||||
Query(description="Langflow DB deployment UUID (`deployment.id`)."),
|
||||
Query(description="Hanzo Flow DB deployment UUID (`deployment.id`)."),
|
||||
]
|
||||
SnapshotNameQueryItem = Annotated[str, StringConstraints(strip_whitespace=True, min_length=1)]
|
||||
|
||||
@@ -178,7 +178,7 @@ IncludeProviderDeleteQuery = Annotated[
|
||||
"When true (default), deletes the deployment resource (e.g., agent) on the provider, "
|
||||
"then removes the local DB row. Other provider-managed resources "
|
||||
"(for example, tools and connections) are NOT deleted. "
|
||||
"When false, only the local Langflow DB row is removed; "
|
||||
"When false, only the local Hanzo Flow DB row is removed; "
|
||||
"nothing is changed on the provider."
|
||||
),
|
||||
),
|
||||
@@ -256,7 +256,7 @@ async def _delete_local_deployment_row_with_commit_retry(
|
||||
Delete is provider-first, so by the time this helper runs the provider
|
||||
resource is already gone (or was already missing). If the first DB commit
|
||||
fails, retry the local delete once after a rollback so we do not strand a
|
||||
stale Langflow row that still blocks later reads or provider-account
|
||||
stale Hanzo Flow row that still blocks later reads or provider-account
|
||||
deletion.
|
||||
"""
|
||||
try:
|
||||
@@ -497,7 +497,7 @@ async def create_deployment(
|
||||
if existing_deployment is not None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail=f"The agent '{existing_resource_key}' is already managed by Langflow. "
|
||||
detail=f"The agent '{existing_resource_key}' is already managed by Hanzo Flow. "
|
||||
"Update it to make changes, or delete the existing deployment first.",
|
||||
)
|
||||
should_mutate_existing_resource = (
|
||||
@@ -636,14 +636,14 @@ async def list_deployments(
|
||||
load_from_provider: Annotated[
|
||||
bool,
|
||||
Query(
|
||||
description=("When true, list deployments directly from the provider (bypassing Langflow deployment rows).")
|
||||
description=("When true, list deployments directly from the provider (bypassing Hanzo Flow deployment rows).")
|
||||
),
|
||||
] = False,
|
||||
flow_version_ids: Annotated[
|
||||
FlowVersionIdsQuery,
|
||||
Query(
|
||||
description=(
|
||||
"Optional Langflow flow version ids (pass as repeated query params, "
|
||||
"Optional Hanzo Flow flow version ids (pass as repeated query params, "
|
||||
"e.g. ?flow_version_ids=id1&flow_version_ids=id2). When provided, "
|
||||
"deployments are filtered to those with at least one matching "
|
||||
"attachment (OR semantics across ids). "
|
||||
@@ -1012,7 +1012,7 @@ async def update_snapshot(
|
||||
"""Replace an existing provider snapshot's content with a new flow version.
|
||||
|
||||
Resolves the deployment context from the attachment record linked to
|
||||
``provider_snapshot_id``. Only Langflow-tracked snapshots (those with
|
||||
``provider_snapshot_id``. Only Hanzo Flow-tracked snapshots (those with
|
||||
a ``flow_version_deployment_attachment`` row) can be updated.
|
||||
"""
|
||||
from flow.services.database.models.deployment.crud import get_deployment as get_deployment_row
|
||||
|
||||
@@ -32,7 +32,7 @@ def _get_allowed_profile_picture_folders(settings_service: SettingsService) -> s
|
||||
base directory and validate path containment below.
|
||||
|
||||
If no directories can be found (unexpected), fall back to the curated
|
||||
defaults {"People", "Space"} shipped with Langflow.
|
||||
defaults {"People", "Space"} shipped with Hanzo Flow.
|
||||
"""
|
||||
allowed: set[str] = set()
|
||||
try:
|
||||
|
||||
@@ -105,8 +105,8 @@ class DeploymentApiPayloads(DeploymentPayloadFields):
|
||||
"""API-side payload schema registry for deployment providers.
|
||||
|
||||
Ownership boundary:
|
||||
Langflow owns API slot population here because API payloads may include
|
||||
Langflow-specific references and reshaping requirements. Adapter-side
|
||||
Hanzo Flow owns API slot population here because API payloads may include
|
||||
Hanzo Flow-specific references and reshaping requirements. Adapter-side
|
||||
slot population is defined separately via ``DeploymentPayloadSchemas``.
|
||||
"""
|
||||
|
||||
@@ -119,7 +119,7 @@ class BaseDeploymentMapper:
|
||||
"""Per-provider mapper for deployment API payloads.
|
||||
|
||||
Mapper vs adapter responsibilities:
|
||||
- Mapper: API-boundary translation/validation (Langflow schemas <-> adapter payloads).
|
||||
- Mapper: API-boundary translation/validation (Hanzo Flow schemas <-> adapter payloads).
|
||||
- Adapter: provider execution (network calls, provider semantics, side effects).
|
||||
|
||||
Selection contract:
|
||||
@@ -136,7 +136,7 @@ class BaseDeploymentMapper:
|
||||
responses), while payload-only shapers return provider dicts unchanged.
|
||||
|
||||
Provider-specific mappers override only the methods that need
|
||||
Langflow-aware resolution or payload reshaping.
|
||||
Hanzo Flow-aware resolution or payload reshaping.
|
||||
"""
|
||||
|
||||
api_payloads: ClassVar[DeploymentApiPayloads] = DeploymentApiPayloads()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Relationship to adapter registries:
|
||||
- Adapters execute provider operations (create/update/delete/list/status).
|
||||
- Mappers reshape Langflow API payloads/results into adapter-facing contracts.
|
||||
- Mappers reshape Hanzo Flow API payloads/results into adapter-facing contracts.
|
||||
|
||||
Why ``AdapterType`` is used here:
|
||||
- Mapper lookup must follow the same provider categorization as adapters.
|
||||
|
||||
@@ -366,7 +366,7 @@ class WatsonxApiDeploymentCreatePayload(BaseModel):
|
||||
|
||||
|
||||
class WatsonxApiCreatedTool(BaseModel):
|
||||
"""API response shape for a tool created from a Langflow flow version."""
|
||||
"""API response shape for a tool created from a Hanzo Flow flow version."""
|
||||
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
@@ -611,8 +611,8 @@ class _WatsonxApiAgentExecutionResultBase(BaseModel):
|
||||
"""Shared fields for API-facing agent execution result payloads.
|
||||
|
||||
All provider-owned identifiers and metadata live here inside
|
||||
``provider_data``. The enclosing response only carries Langflow-owned
|
||||
fields (``deployment_id``). ``deployment_id`` (Langflow DB UUID) is
|
||||
``provider_data``. The enclosing response only carries Hanzo Flow-owned
|
||||
fields (``deployment_id``). ``deployment_id`` (Hanzo Flow DB UUID) is
|
||||
intentionally omitted from this schema to avoid ownership confusion.
|
||||
"""
|
||||
|
||||
|
||||
@@ -786,10 +786,10 @@ async def install_mcp_config(
|
||||
legacy_sse_url = await get_project_sse_url(project_id)
|
||||
command = "uvx"
|
||||
args = ["mcp-proxy"]
|
||||
# Check if we need to add Langflow API key headers
|
||||
# Check if we need to add Hanzo Flow API key headers
|
||||
# Necessary only when Project API Key Authentication is enabled
|
||||
|
||||
# Generate a Langflow API key for auto-install if needed
|
||||
# Generate a Hanzo Flow API key for auto-install if needed
|
||||
# Only add API key headers for projects with "apikey" auth type (not "none" or OAuth)
|
||||
|
||||
if should_generate_api_key:
|
||||
@@ -856,7 +856,7 @@ async def install_mcp_config(
|
||||
if "mcpServers" not in existing_config:
|
||||
existing_config["mcpServers"] = {}
|
||||
|
||||
# Remove stale entries that point to the same Langflow URLs (e.g. after the project is renamed)
|
||||
# Remove stale entries that point to the same Hanzo Flow URLs (e.g. after the project is renamed)
|
||||
existing_config, removed_servers = remove_server_by_urls(existing_config, connection_urls)
|
||||
|
||||
if removed_servers:
|
||||
@@ -1221,7 +1221,7 @@ async def _get_mcp_composer_auth_config(project) -> dict:
|
||||
class ProjectMCPServer:
|
||||
def __init__(self, project_id: UUID):
|
||||
self.project_id = project_id
|
||||
self.server = Server(f"langflow-mcp-project-{project_id}")
|
||||
self.server = Server(f"flow-mcp-project-{project_id}")
|
||||
# TODO: implement an environment variable to enable/disable stateless mode
|
||||
self.session_manager = StreamableHTTPSessionManager(self.server, stateless=True)
|
||||
# since we lazily initialize the session manager's lifecycle
|
||||
@@ -1414,7 +1414,7 @@ async def register_project_with_composer(project: Folder):
|
||||
|
||||
settings = get_settings_service().settings
|
||||
if not settings.host or not settings.port:
|
||||
error_msg = "Langflow host and port must be set in settings to register project with MCP Composer"
|
||||
error_msg = "Hanzo Flow host and port must be set in settings to register project with MCP Composer"
|
||||
raise ValueError(error_msg)
|
||||
|
||||
if not project.id:
|
||||
@@ -1549,7 +1549,7 @@ async def get_or_start_mcp_composer(auth_config: dict, project_name: str, projec
|
||||
# Prepare current auth config for comparison
|
||||
settings = get_settings_service().settings
|
||||
if not settings.host or not settings.port:
|
||||
error_msg = "Langflow host and port must be set in settings to register project with MCP Composer"
|
||||
error_msg = "Hanzo Flow host and port must be set in settings to register project with MCP Composer"
|
||||
raise ValueError(error_msg)
|
||||
|
||||
streamable_http_url = await get_project_streamable_http_url(project_id)
|
||||
|
||||
@@ -157,7 +157,7 @@ async def handle_list_resources(project_id=None):
|
||||
stored_filename = Path(stored_path).name if stored_path else user_file.name
|
||||
safe_filename = quote(stored_filename)
|
||||
if stored_filename.startswith(f"{MCP_SERVERS_FILE}_{current_user.id}"):
|
||||
# reserved file name for langflow MCP server config file(s)
|
||||
# reserved file name for flow MCP server config file(s)
|
||||
continue
|
||||
description = getattr(user_file, "provider", None) or "User file uploaded via File Manager"
|
||||
resource = types.Resource(
|
||||
@@ -210,7 +210,7 @@ async def handle_read_resource(uri: str, project_id: UUID | str | None = None) -
|
||||
raise ValueError(msg)
|
||||
|
||||
# SECURITY: authorise the caller before reading. The storage layer alone is
|
||||
# not enough because the filesystem doesn't know about Langflow users, and
|
||||
# not enough because the filesystem doesn't know about Hanzo Flow users, and
|
||||
# previously any authenticated user could request any flow_id.
|
||||
try:
|
||||
current_user = current_user_ctx.get()
|
||||
|
||||
@@ -102,7 +102,7 @@ async def run_flow_for_openai_responses(
|
||||
event_manager = create_stream_tokens_event_manager(queue=asyncio_queue)
|
||||
|
||||
async def openai_stream_generator() -> AsyncGenerator[str, None]:
|
||||
"""Convert Langflow events to OpenAI Responses API streaming format."""
|
||||
"""Convert Hanzo Flow events to OpenAI Responses API streaming format."""
|
||||
main_task = asyncio.create_task(
|
||||
run_flow_generator(
|
||||
flow=flow,
|
||||
@@ -598,7 +598,7 @@ async def create_response(
|
||||
"""Create a response using OpenAI Responses API format.
|
||||
|
||||
This endpoint accepts a flow_id in the model parameter and processes
|
||||
the input through the specified Langflow flow.
|
||||
the input through the specified Hanzo Flow flow.
|
||||
|
||||
Args:
|
||||
request: OpenAI Responses API request with model (flow_id) and input
|
||||
|
||||
@@ -444,7 +444,7 @@ async def delete_project(
|
||||
if not project:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
|
||||
# Prevent deletion of the Langflow Assistant folder
|
||||
# Prevent deletion of the Hanzo Flow Assistant folder
|
||||
if project.name == ASSISTANT_FOLDER_NAME:
|
||||
msg = f"Cannot delete the '{ASSISTANT_FOLDER_NAME}' folder, that contains pre-built flows."
|
||||
await logger.adebug("Cannot delete the '%s' folder, that contains pre-built flows.", ASSISTANT_FOLDER_NAME)
|
||||
|
||||
@@ -11,12 +11,12 @@ Two identifier domains coexist in these schemas:
|
||||
* **Provider-owned (str)** -- ``reference_id``, ``config_id``,
|
||||
``run_id``.
|
||||
Opaque values assigned or consumed by the external deployment provider.
|
||||
``provider_key`` is Langflow-owned adapter vocabulary.
|
||||
``provider_key`` is Hanzo Flow-owned adapter vocabulary.
|
||||
Provider-specific metadata (for example URL and tenant/account identifiers)
|
||||
belongs inside ``provider_data``.
|
||||
|
||||
* **Provider-originated but Langflow-owned once persisted** -- ``resource_key``.
|
||||
Langflow stores and indexes this as part of its own deployment record.
|
||||
* **Provider-originated but Hanzo Flow-owned once persisted** -- ``resource_key``.
|
||||
Hanzo Flow stores and indexes this as part of its own deployment record.
|
||||
|
||||
``provider_data`` dicts are opaque pass-through containers whose contents
|
||||
are defined by the provider adapter. Flow forwards them without
|
||||
@@ -265,7 +265,7 @@ class DeploymentGetResponse(_DeploymentResponseWithProviderData):
|
||||
list item stays lean.
|
||||
"""
|
||||
|
||||
resource_key: str = Field(description="Langflow-persisted stable provider resource identifier.")
|
||||
resource_key: str = Field(description="Hanzo Flow-persisted stable provider resource identifier.")
|
||||
attached_count: int = Field(default=0, ge=0, description="Number of flow versions attached to this deployment.")
|
||||
|
||||
|
||||
@@ -275,7 +275,7 @@ class DeploymentListItem(_DeploymentResponseCommon):
|
||||
See ``DeploymentGetResponse`` docstring for rationale on the separate class.
|
||||
"""
|
||||
|
||||
resource_key: str = Field(description="Langflow-persisted stable provider resource identifier.")
|
||||
resource_key: str = Field(description="Hanzo Flow-persisted stable provider resource identifier.")
|
||||
attached_count: int = Field(default=0, ge=0, description="Number of flow versions attached to this deployment.")
|
||||
flow_version_ids: list[UUID] | None = Field(
|
||||
default=None,
|
||||
@@ -333,25 +333,25 @@ class DeploymentSnapshotListResponse(_PaginatedResponse):
|
||||
class DeploymentFlowVersionListItem(BaseModel):
|
||||
"""Flow version metadata attached to a deployment.
|
||||
|
||||
**Identity model:** Langflow tracks provider tools by their immutable
|
||||
**Identity model:** Hanzo Flow tracks provider tools by their immutable
|
||||
``provider_snapshot_id`` (the wxO tool_id), never by name. This
|
||||
distinguishes the following cases:
|
||||
|
||||
* **Tool renamed in provider** — Same ``provider_snapshot_id``, different
|
||||
``provider_data.tool_name``. Langflow picks up the new name on the next fetch.
|
||||
``provider_data.tool_name``. Hanzo Flow picks up the new name on the next fetch.
|
||||
* **Tool deleted in provider** — ``provider_snapshot_id`` no longer
|
||||
resolves. ``provider_data.tool_name`` may be missing/``None``.
|
||||
* **Tool deleted + new tool created with same name** — The new tool has
|
||||
a different ID. Langflow's attachment still points to the old
|
||||
(missing) ID. The new tool is invisible to Langflow until explicitly
|
||||
a different ID. Hanzo Flow's attachment still points to the old
|
||||
(missing) ID. The new tool is invisible to Hanzo Flow until explicitly
|
||||
attached via an update operation.
|
||||
|
||||
Frontends should use ``provider_data.tool_name`` for display and
|
||||
``provider_snapshot_id`` for identity / operations.
|
||||
"""
|
||||
|
||||
id: UUID = Field(description="Langflow flow version UUID (`flow_version.id`).")
|
||||
flow_id: UUID = Field(description="Langflow flow UUID (`flow.id`) for this version.")
|
||||
id: UUID = Field(description="Hanzo Flow flow version UUID (`flow_version.id`).")
|
||||
flow_id: UUID = Field(description="Hanzo Flow flow UUID (`flow.id`) for this version.")
|
||||
flow_name: str | None = Field(
|
||||
default=None,
|
||||
description="Name of the flow owning this version (`flow.name`).",
|
||||
@@ -378,13 +378,13 @@ class DeploymentFlowVersionListResponse(_PaginatedResponse):
|
||||
class DeploymentCreateResponse(_DeploymentResponseWithProviderData):
|
||||
"""API response for deployment creation."""
|
||||
|
||||
resource_key: str = Field(description="Langflow-persisted stable provider resource identifier.")
|
||||
resource_key: str = Field(description="Hanzo Flow-persisted stable provider resource identifier.")
|
||||
|
||||
|
||||
class DeploymentUpdateResponse(_DeploymentResponseWithProviderData):
|
||||
"""API response for deployment update."""
|
||||
|
||||
resource_key: str = Field(description="Langflow-persisted stable provider resource identifier.")
|
||||
resource_key: str = Field(description="Hanzo Flow-persisted stable provider resource identifier.")
|
||||
|
||||
|
||||
class DeploymentStatusResponse(_DeploymentResponseWithProviderData):
|
||||
@@ -661,7 +661,7 @@ class SnapshotUpdateRequest(BaseModel):
|
||||
model_config = {"extra": "forbid"}
|
||||
|
||||
flow_version_id: UUID = Field(
|
||||
description="Langflow flow version whose artifact will replace the snapshot content.",
|
||||
description="Hanzo Flow flow version whose artifact will replace the snapshot content.",
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ async def authenticate_and_get_openai_key(session: DbSession, user: User, websoc
|
||||
{
|
||||
"type": "error",
|
||||
"code": "langflow_auth",
|
||||
"message": "You must pass a valid Langflow token or cookie.",
|
||||
"message": "You must pass a valid Hanzo Flow token or cookie.",
|
||||
}
|
||||
)
|
||||
return None, None
|
||||
|
||||
@@ -180,18 +180,18 @@ class ProgressIndicator:
|
||||
|
||||
|
||||
def create_flow_progress(*, verbose: bool = False) -> ProgressIndicator:
|
||||
"""Create a progress indicator with predefined Langflow initialization steps."""
|
||||
"""Create a progress indicator with predefined Hanzo Flow initialization steps."""
|
||||
progress = ProgressIndicator(verbose=verbose)
|
||||
|
||||
# Define the initialization steps matching the order in main.py
|
||||
steps = [
|
||||
("Initializing Langflow", "Setting up basic configuration"),
|
||||
("Initializing Hanzo Flow", "Setting up basic configuration"),
|
||||
("Checking Environment", "Loading environment variables and settings"),
|
||||
("Starting Core Services", "Initializing database and core services"),
|
||||
("Connecting Database", "Setting up database connection and migrations"),
|
||||
("Loading Components", "Caching component types and custom components"),
|
||||
("Adding Starter Projects", "Creating or updating starter project templates"),
|
||||
("Launching Langflow", "Starting server and final setup"),
|
||||
("Launching Hanzo Flow", "Starting server and final setup"),
|
||||
]
|
||||
|
||||
for title, description in steps:
|
||||
@@ -201,7 +201,7 @@ def create_flow_progress(*, verbose: bool = False) -> ProgressIndicator:
|
||||
|
||||
|
||||
def create_langflow_shutdown_progress(*, verbose: bool = False, multiple_workers: bool = False) -> ProgressIndicator:
|
||||
"""Create a progress indicator with predefined Langflow shutdown steps."""
|
||||
"""Create a progress indicator with predefined Hanzo Flow shutdown steps."""
|
||||
progress = ProgressIndicator(verbose=verbose)
|
||||
|
||||
# Define the shutdown steps in reverse order of initialization
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Langflow knowledge bases module - forwards to lfx.components.files_and_knowledge.
|
||||
"""Hanzo Flow knowledge bases module - forwards to lfx.components.files_and_knowledge.
|
||||
|
||||
This module provides backwards compatibility by forwarding all imports
|
||||
to files_and_knowledge where the actual knowledge base components are located.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Component module for langflow - imports from lfx.
|
||||
"""Component module for flow - imports from lfx.
|
||||
|
||||
This maintains backward compatibility while using the lfx implementation.
|
||||
"""
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
STARTER_FOLDER_NAME = "Starter Projects"
|
||||
STARTER_FOLDER_DESCRIPTION = "Starter projects to help you get started in Langflow."
|
||||
STARTER_FOLDER_DESCRIPTION = "Starter projects to help you get started in Hanzo Flow."
|
||||
|
||||
ASSISTANT_FOLDER_NAME = "Langflow Assistant"
|
||||
ASSISTANT_FOLDER_DESCRIPTION = "Pre-built flows from Langflow Assistant to enhance your workflow."
|
||||
ASSISTANT_FOLDER_NAME = "Hanzo Flow Assistant"
|
||||
ASSISTANT_FOLDER_DESCRIPTION = "Pre-built flows from Hanzo Flow Assistant to enhance your workflow."
|
||||
|
||||
@@ -780,7 +780,7 @@ async def get_or_create_starter_folder(session):
|
||||
|
||||
|
||||
async def get_or_create_assistant_folder(session, user_id: UUID):
|
||||
"""Create or get the Langflow Assistant folder for a specific user.
|
||||
"""Create or get the Hanzo Flow Assistant folder for a specific user.
|
||||
|
||||
This folder contains agentic flows and cannot be deleted.
|
||||
|
||||
@@ -789,7 +789,7 @@ async def get_or_create_assistant_folder(session, user_id: UUID):
|
||||
user_id: The ID of the user who owns the folder
|
||||
|
||||
Returns:
|
||||
The Langflow Assistant folder
|
||||
The Hanzo Flow Assistant folder
|
||||
"""
|
||||
stmt = select(Folder).where(Folder.user_id == user_id, Folder.name == ASSISTANT_FOLDER_NAME)
|
||||
result = await session.exec(stmt)
|
||||
@@ -836,10 +836,10 @@ async def load_agentic_flows() -> list[tuple[anyio.Path, dict]]:
|
||||
|
||||
|
||||
async def create_or_update_agentic_flows(session: AsyncSession, user_id: UUID) -> None:
|
||||
"""Create or update agentic flows in the Langflow Assistant folder for a user.
|
||||
"""Create or update agentic flows in the Hanzo Flow Assistant folder for a user.
|
||||
|
||||
This function is called on user login to ensure that all agentic flows
|
||||
are present and up-to-date in the user's Langflow Assistant folder.
|
||||
are present and up-to-date in the user's Hanzo Flow Assistant folder.
|
||||
|
||||
The function will:
|
||||
- Extract flow_id and endpoint_name from the JSON
|
||||
@@ -859,7 +859,7 @@ async def create_or_update_agentic_flows(session: AsyncSession, user_id: UUID) -
|
||||
return
|
||||
|
||||
try:
|
||||
# Get or create the Langflow Assistant folder
|
||||
# Get or create the Hanzo Flow Assistant folder
|
||||
assistant_folder = await get_or_create_assistant_folder(session, user_id)
|
||||
|
||||
# Load all agentic flows from the directory
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Interface components module for langflow - imports from lfx."""
|
||||
"""Interface components module for flow - imports from lfx."""
|
||||
|
||||
# Import everything from lfx.interface.components
|
||||
from lfx.interface.components import * # noqa: F403
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Interface listing module for langflow - imports from lfx."""
|
||||
"""Interface listing module for flow - imports from lfx."""
|
||||
|
||||
# Import everything from lfx.interface.listing
|
||||
from lfx.interface.listing import * # noqa: F403
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Interface utils module for langflow - imports from lfx."""
|
||||
"""Interface utils module for flow - imports from lfx."""
|
||||
|
||||
# Import everything from lfx.interface.utils
|
||||
from lfx.interface.utils import * # noqa: F403
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Expand compact flow format to full flow format.
|
||||
|
||||
This module provides functionality to expand a minimal/compact flow format
|
||||
(used by AI agents) into the full flow format expected by Langflow.
|
||||
(used by AI agents) into the full flow format expected by Hanzo Flow.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -256,7 +256,7 @@ def expand_compact_flow(
|
||||
all_types_dict: The component types dictionary from component_cache
|
||||
|
||||
Returns:
|
||||
Full flow data structure ready for Langflow UI
|
||||
Full flow data structure ready for Hanzo Flow UI
|
||||
|
||||
Example compact input:
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""JSON and Data classes for langflow - imports from lfx.
|
||||
"""JSON and Data classes for flow - imports from lfx.
|
||||
|
||||
This maintains backward compatibility while using the lfx implementation.
|
||||
JSON is the new base type; Data is an alias for backwards compatibility.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Message class for langflow - imports from lfx.
|
||||
"""Message class for flow - imports from lfx.
|
||||
|
||||
This maintains backward compatibility while using the lfx implementation.
|
||||
"""
|
||||
|
||||
@@ -1 +1 @@
|
||||
"""Adapter namespaces for Langflow service-scoped plugin registries."""
|
||||
"""Adapter namespaces for Hanzo Flow service-scoped plugin registries."""
|
||||
|
||||
@@ -1 +1 @@
|
||||
"""Langflow deployment adapter implementations."""
|
||||
"""Hanzo Flow deployment adapter implementations."""
|
||||
|
||||
@@ -47,10 +47,10 @@ class WxOAuthURL(str, Enum):
|
||||
Please note:
|
||||
- The stated environment variables are solely for
|
||||
internal testing and development purposes,
|
||||
and must be left unset when shipping Langflow
|
||||
and must be left unset when shipping Hanzo Flow
|
||||
for general availability.
|
||||
- The IAM URLs cannot be changed during runtime,
|
||||
and Langflow does not dynamically resolve the IAM URL based on
|
||||
and Hanzo Flow does not dynamically resolve the IAM URL based on
|
||||
the environment of a given wxO tenant. It simply uses the
|
||||
default production IAM URLs, or the environment variable
|
||||
overrides if set.
|
||||
|
||||
+1
-1
@@ -461,7 +461,7 @@ async def validate_connection(connections_client: ConnectionsClient, *, app_id:
|
||||
raise InvalidContentError(message=msg)
|
||||
|
||||
if config.security_scheme != ConnectionSecurityScheme.KEY_VALUE:
|
||||
msg = f"Connection '{app_id}' must use key-value credentials for Langflow flows."
|
||||
msg = f"Connection '{app_id}' must use key-value credentials for Hanzo Flow flows."
|
||||
raise InvalidContentError(message=msg)
|
||||
|
||||
runtime_credentials = await asyncio.to_thread(
|
||||
|
||||
+14
-14
@@ -106,20 +106,20 @@ def ensure_langflow_connections_binding(tool_payload: dict[str, Any]) -> dict[st
|
||||
to prevent a stubbornly failing update.
|
||||
"""
|
||||
binding = _ensure_dict(tool_payload, "binding")
|
||||
langflow = _ensure_dict(binding, "langflow")
|
||||
return _ensure_dict(langflow, "connections")
|
||||
flow = _ensure_dict(binding, "flow")
|
||||
return _ensure_dict(flow, "connections")
|
||||
|
||||
|
||||
def verify_langflow_owned(tool: dict[str, Any], *, tool_id: str) -> None:
|
||||
"""Raise ``InvalidContentError`` if the tool lacks ``binding.langflow``.
|
||||
"""Raise ``InvalidContentError`` if the tool lacks ``binding.flow``.
|
||||
|
||||
Call before any mutating operation on an existing tool to ensure
|
||||
Langflow created it. Tools created manually in the wxO console or
|
||||
Hanzo Flow created it. Tools created manually in the wxO console or
|
||||
by other integrations will not have this marker.
|
||||
"""
|
||||
binding = tool.get("binding")
|
||||
if not isinstance(binding, dict) or "langflow" not in binding:
|
||||
msg = f"Cannot modify tool '{tool_id}': it does not have a Langflow binding and may not be managed by Langflow."
|
||||
if not isinstance(binding, dict) or "flow" not in binding:
|
||||
msg = f"Cannot modify tool '{tool_id}': it does not have a Hanzo Flow binding and may not be managed by Hanzo Flow."
|
||||
raise InvalidContentError(message=msg)
|
||||
|
||||
|
||||
@@ -132,8 +132,8 @@ def extract_langflow_connections_binding(tool_payload: dict[str, Any]) -> dict[s
|
||||
binding = tool_payload.get("binding")
|
||||
if not isinstance(binding, dict):
|
||||
return {}
|
||||
langflow = binding.get("langflow")
|
||||
if not isinstance(langflow, dict):
|
||||
flow = binding.get("flow")
|
||||
if not isinstance(flow, dict):
|
||||
return {}
|
||||
connections = flow.get("connections")
|
||||
return connections if isinstance(connections, dict) else {}
|
||||
@@ -183,7 +183,7 @@ async def update_existing_tool_connection_bindings(
|
||||
|
||||
|
||||
def extract_langflow_artifact_from_zip(artifact_zip_bytes: bytes, *, snapshot_id: str) -> dict[str, Any]:
|
||||
"""Read and parse the Langflow flow JSON from a wxO snapshot artifact zip."""
|
||||
"""Read and parse the Hanzo Flow flow JSON from a wxO snapshot artifact zip."""
|
||||
try:
|
||||
with zipfile.ZipFile(io.BytesIO(artifact_zip_bytes), "r") as zip_artifact:
|
||||
json_members = [name for name in zip_artifact.namelist() if name.lower().endswith(".json")]
|
||||
@@ -299,7 +299,7 @@ def create_wxo_flow_tool(
|
||||
if not flow_definition.get("last_tested_version"):
|
||||
detected_version = (get_version_info() or {}).get("version")
|
||||
if not detected_version:
|
||||
msg = "Unable to determine running Langflow version for snapshot creation."
|
||||
msg = "Unable to determine running Hanzo Flow version for snapshot creation."
|
||||
raise InvalidContentError(message=msg)
|
||||
flow_definition["last_tested_version"] = detected_version
|
||||
|
||||
@@ -320,12 +320,12 @@ def create_wxo_flow_tool(
|
||||
if current_name:
|
||||
tool_payload["name"] = normalize_wxo_name(current_name)
|
||||
|
||||
(tool_payload.setdefault("binding", {}).setdefault("langflow", {})["project_id"]) = project_id
|
||||
(tool_payload.setdefault("binding", {}).setdefault("flow", {})["project_id"]) = project_id
|
||||
logger.debug(
|
||||
"create_wxo_flow_tool: tool name='%s', project_id='%s', binding=%s",
|
||||
tool_payload.get("name"),
|
||||
project_id,
|
||||
tool_payload.get("binding", {}).get("langflow"),
|
||||
tool_payload.get("binding", {}).get("flow"),
|
||||
)
|
||||
|
||||
artifacts: bytes = build_langflow_artifact_bytes(
|
||||
@@ -462,7 +462,7 @@ async def process_raw_flows_with_app_id(
|
||||
app_id: str,
|
||||
flows: list[BaseFlowArtifact[WatsonxFlowArtifactProviderData]],
|
||||
) -> list[WatsonxToolRefBinding]:
|
||||
"""Create langflow tools in wxO and connect them to the given app_id."""
|
||||
"""Create flow tools in wxO and connect them to the given app_id."""
|
||||
from flow.services.adapters.deployment.watsonx_orchestrate.core.config import validate_connection
|
||||
|
||||
connection = await validate_connection(clients.connections, app_id=app_id)
|
||||
@@ -558,7 +558,7 @@ async def verify_tools_by_ids(
|
||||
|
||||
if len(normalized_connections) < len(connections):
|
||||
logger.warning(
|
||||
"Tool %s returned malformed langflow connection bindings; defaulting to empty mapping",
|
||||
"Tool %s returned malformed flow connection bindings; defaulting to empty mapping",
|
||||
tool["id"],
|
||||
)
|
||||
provider_data: dict[str, dict[str, str]] = {"connections": {}}
|
||||
|
||||
+1
-1
@@ -335,7 +335,7 @@ async def _apply_tool_renames(
|
||||
|
||||
Guards against destructive operations on tools we don't own:
|
||||
1. Tool must be attached to this agent (tool_id in agent_tool_ids).
|
||||
2. Tool must be a Langflow-managed tool (has ``binding.langflow``).
|
||||
2. Tool must be a Hanzo Flow-managed tool (has ``binding.flow``).
|
||||
3. Tool must exist on the provider.
|
||||
|
||||
Captures original tool payloads in ``original_tools`` for rollback.
|
||||
|
||||
@@ -19,7 +19,7 @@ class WatsonxFlowArtifactProviderData(BaseModel):
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
project_id: NormalizedId = Field(description="Langflow project id carried for watsonx snapshot creation.")
|
||||
project_id: NormalizedId = Field(description="Hanzo Flow project id carried for watsonx snapshot creation.")
|
||||
source_ref: Annotated[str, StringConstraints(strip_whitespace=True, min_length=1)] = Field(
|
||||
description="Adapter-neutral source reference used for create/update snapshot correlation.",
|
||||
)
|
||||
@@ -241,7 +241,7 @@ class WatsonxUnbindOperation(BaseModel):
|
||||
|
||||
|
||||
class WatsonxRenameToolOperation(BaseModel):
|
||||
"""Rename a Langflow-managed tool on the provider."""
|
||||
"""Rename a Hanzo Flow-managed tool on the provider."""
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
@@ -550,7 +550,7 @@ class WatsonxAgentExecutionResultData(BaseModel):
|
||||
execution_id: NormalizedId | None = None
|
||||
agent_id: NormalizedId | None = Field(
|
||||
default=None,
|
||||
description="WXO agent identifier (resource_key in Langflow DB).",
|
||||
description="WXO agent identifier (resource_key in Hanzo Flow DB).",
|
||||
)
|
||||
thread_id: NormalizedId | None = None
|
||||
status: str | None = None
|
||||
|
||||
@@ -982,7 +982,7 @@ class WatsonxOrchestrateDeploymentService(BaseDeploymentService):
|
||||
without touching the tool's name, metadata, or connection bindings.
|
||||
|
||||
The tool name is fetched from wxO at call time, not derived from the
|
||||
Langflow flow name. This is intentional: the user may have set a
|
||||
Hanzo Flow flow name. This is intentional: the user may have set a
|
||||
custom tool name during initial deployment, or renamed the tool
|
||||
directly in the wxO console. Either way, the provider is the source
|
||||
of truth for the tool name.
|
||||
@@ -991,7 +991,7 @@ class WatsonxOrchestrateDeploymentService(BaseDeploymentService):
|
||||
|
||||
* **Tool renamed in wxO console** — The new name is picked up
|
||||
automatically on the next update since we always fetch it fresh.
|
||||
Langflow never stores the tool name locally.
|
||||
Hanzo Flow never stores the tool name locally.
|
||||
* **Tool deleted in wxO** — ``get_drafts_by_ids`` returns empty
|
||||
and we raise ``InvalidContentError`` before any mutation.
|
||||
* **Tool exists but name is empty/null** — Defensive check raises
|
||||
@@ -1012,7 +1012,7 @@ class WatsonxOrchestrateDeploymentService(BaseDeploymentService):
|
||||
by name. A rename preserves identity; a delete+recreate does not.
|
||||
|
||||
**Blast-radius boundary:** callers must verify that ``snapshot_id``
|
||||
is tracked by a Langflow attachment record before calling this
|
||||
is tracked by a Hanzo Flow attachment record before calling this
|
||||
method; this prevents accidental overwrites of externally managed
|
||||
WXO tools.
|
||||
"""
|
||||
@@ -1021,7 +1021,7 @@ class WatsonxOrchestrateDeploymentService(BaseDeploymentService):
|
||||
clients = await self._get_provider_clients(user_id=user_id, db=db)
|
||||
|
||||
# Fetch the existing tool to preserve its wxO name — the tool may have
|
||||
# been deployed with a custom name that differs from the Langflow flow
|
||||
# been deployed with a custom name that differs from the Hanzo Flow flow
|
||||
# name, and we must not overwrite it with the flow name.
|
||||
existing_tools = await asyncio.to_thread(clients.tool.get_drafts_by_ids, [snapshot_id])
|
||||
if not existing_tools or not isinstance(existing_tools[0], dict):
|
||||
|
||||
@@ -177,7 +177,7 @@ def build_agent_payload_from_values(
|
||||
return {
|
||||
"name": agent_name,
|
||||
"display_name": agent_display_name,
|
||||
"description": str(description).strip() or f"Langflow deployment {deployment_name}",
|
||||
"description": str(description).strip() or f"Hanzo Flow deployment {deployment_name}",
|
||||
"tools": list(tool_ids),
|
||||
"style": "default",
|
||||
"llm": str(llm).strip(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Authentication service factory.
|
||||
|
||||
Builds the Langflow auth implementation (JWT, DB users, etc.)
|
||||
Builds the Hanzo Flow auth implementation (JWT, DB users, etc.)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -18,7 +18,7 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class AuthServiceFactory(ServiceFactory):
|
||||
"""Factory that creates the Langflow auth service (implements LFX BaseAuthService)."""
|
||||
"""Factory that creates the Hanzo Flow auth service (implements LFX BaseAuthService)."""
|
||||
|
||||
name = ServiceType.AUTH_SERVICE.value
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Hanzo IAM Organization extraction for Flow (Langflow fork).
|
||||
Hanzo IAM Organization extraction for Flow (Hanzo Flow fork).
|
||||
|
||||
Extracts the IAM organization slug from:
|
||||
1. X-IAM-Org-Id request header (set by gateway)
|
||||
|
||||
@@ -43,7 +43,7 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class AuthService(BaseAuthService):
|
||||
"""Default Langflow authentication service (implements LFX BaseAuthService)."""
|
||||
"""Default Hanzo Flow authentication service (implements LFX BaseAuthService)."""
|
||||
|
||||
name = ServiceType.AUTH_SERVICE.value
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ async def ws_api_key_security(api_key: str | None) -> UserRead:
|
||||
def _auth_error_to_http(e: AuthenticationError) -> HTTPException:
|
||||
"""Map auth exceptions to 401 Unauthorized or 403 Forbidden.
|
||||
|
||||
Langflow returns 403 for missing/invalid credentials; 401 for invalid/expired tokens.
|
||||
Hanzo Flow returns 403 for missing/invalid credentials; 401 for invalid/expired tokens.
|
||||
"""
|
||||
if isinstance(
|
||||
e,
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"""Database service constants."""
|
||||
|
||||
# Minimum PostgreSQL major version required by Langflow.
|
||||
# Minimum PostgreSQL major version required by Hanzo Flow.
|
||||
# The schema uses UNIQUE NULLS DISTINCT, which is only supported in PostgreSQL 15+.
|
||||
MIN_POSTGRESQL_MAJOR_VERSION = 15
|
||||
|
||||
# User-facing message when migrations fail due to PostgreSQL < 15 (e.g. UNIQUE NULLS DISTINCT).
|
||||
POSTGRESQL_VERSION_REQUIRED_MESSAGE = (
|
||||
f"Langflow requires PostgreSQL {MIN_POSTGRESQL_MAJOR_VERSION} or higher when using PostgreSQL as the database. "
|
||||
"The current PostgreSQL version does not support the syntax used by Langflow's schema. "
|
||||
f"Hanzo Flow requires PostgreSQL {MIN_POSTGRESQL_MAJOR_VERSION} or higher when using PostgreSQL as the database. "
|
||||
"The current PostgreSQL version does not support the syntax used by Hanzo Flow's schema. "
|
||||
f"Please upgrade your PostgreSQL instance to version {MIN_POSTGRESQL_MAJOR_VERSION} or higher. "
|
||||
"See: https://docs.flow.org/configuration-custom-database"
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""SSO plugin tables.
|
||||
|
||||
These tables are used by the SSO plugin for identity and provider configuration.
|
||||
Migrations are managed by Langflow (OSS); the plugin must not create or
|
||||
Migrations are managed by Hanzo Flow (OSS); the plugin must not create or
|
||||
migrate these tables.
|
||||
|
||||
Plugins must use these tables via the models exported from
|
||||
|
||||
@@ -48,12 +48,12 @@ class Deployment(SQLModel, table=True): # type: ignore[call-arg]
|
||||
)
|
||||
# ``DeploymentType`` is imported from LFX
|
||||
# (``lfx.services.adapters.deployment.schema``). The DB-level
|
||||
# ``deployment_type_enum`` constraint is defined by a Langflow alembic
|
||||
# ``deployment_type_enum`` constraint is defined by a Hanzo Flow alembic
|
||||
# migration, **not** by LFX code. This decoupling is intentional:
|
||||
#
|
||||
# LFX adds a new member -> INSERT/UPDATE with the new value is rejected
|
||||
# by the DB until a Langflow migration adds it
|
||||
# to the enum type. Langflow explicitly opts
|
||||
# by the DB until a Hanzo Flow migration adds it
|
||||
# to the enum type. Hanzo Flow explicitly opts
|
||||
# in to new deployment types.
|
||||
#
|
||||
# LFX renames a value -> Existing rows are unaffected (the DB stores
|
||||
@@ -72,7 +72,7 @@ class Deployment(SQLModel, table=True): # type: ignore[call-arg]
|
||||
#
|
||||
# To add a new value to ``deployment_type_enum``:
|
||||
# 1. Add the member to ``DeploymentType`` in LFX (or confirm it exists).
|
||||
# 2. Create a Langflow alembic migration that runs:
|
||||
# 2. Create a Hanzo Flow alembic migration that runs:
|
||||
# op.execute("ALTER TYPE deployment_type_enum ADD VALUE '<new>'")
|
||||
# For SQLite (dev/test) this is a no-op; the CHECK constraint is
|
||||
# recreated automatically by ``batch_alter_table``.
|
||||
|
||||
@@ -48,14 +48,14 @@ class DeploymentProviderAccount(SQLModel, table=True): # type: ignore[call-arg]
|
||||
# may not require a tenant/organization identifier.
|
||||
provider_tenant_id: str | None = Field(default=None, index=True)
|
||||
# The DB-level ``deployment_provider_key_enum`` constraint is defined
|
||||
# by a Langflow alembic migration. The enum is Langflow-owned (see
|
||||
# by a Hanzo Flow alembic migration. The enum is Hanzo Flow-owned (see
|
||||
# ``DeploymentProviderKey`` above); LFX uses plain strings for adapter
|
||||
# registry keys and does not reference this enum.
|
||||
#
|
||||
# To add a new value to ``deployment_provider_key_enum``:
|
||||
# 1. Add the member to ``DeploymentProviderKey`` in this module.
|
||||
# 2. Register the corresponding adapter in LFX and mapper in Langflow.
|
||||
# 3. Create a Langflow alembic migration that runs:
|
||||
# 2. Register the corresponding adapter in LFX and mapper in Hanzo Flow.
|
||||
# 3. Create a Hanzo Flow alembic migration that runs:
|
||||
# op.execute(
|
||||
# "ALTER TYPE deployment_provider_key_enum ADD VALUE '<new>'"
|
||||
# )
|
||||
|
||||
+2
-2
@@ -9,11 +9,11 @@ from enum import Enum
|
||||
|
||||
|
||||
class DeploymentProviderKey(str, Enum):
|
||||
"""Deployment provider identifiers recognised by Langflow.
|
||||
"""Deployment provider identifiers recognised by Hanzo Flow.
|
||||
|
||||
Each member value must match the adapter registry key used by
|
||||
``get_deployment_adapter(adapter_key)`` in LFX and the corresponding
|
||||
mapper registration in the Langflow mapper registry.
|
||||
mapper registration in the Hanzo Flow mapper registry.
|
||||
"""
|
||||
|
||||
WATSONX_ORCHESTRATE = "watsonx-orchestrate"
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ class FlowVersionDeploymentAttachment(SQLModel, table=True): # type: ignore[cal
|
||||
description=(
|
||||
"Opaque provider-assigned identifier for the materialized snapshot "
|
||||
"(e.g. a wxO tool ID, a K8s ConfigMap name, an S3 key). "
|
||||
"Links this Langflow flow version to its provider-side resource."
|
||||
"Links this Hanzo Flow flow version to its provider-side resource."
|
||||
),
|
||||
)
|
||||
created_at: datetime | None = Field(
|
||||
|
||||
@@ -277,7 +277,7 @@ class DatabaseService(Service):
|
||||
async def ensure_postgresql_version(self) -> None:
|
||||
"""If the database is PostgreSQL, ensure it is version 15 or higher.
|
||||
|
||||
Langflow's schema uses UNIQUE NULLS DISTINCT, which is only supported in PostgreSQL 15+.
|
||||
Hanzo Flow's schema uses UNIQUE NULLS DISTINCT, which is only supported in PostgreSQL 15+.
|
||||
Logs the message and raises UnsupportedPostgreSQLVersionError if the version is too old.
|
||||
"""
|
||||
if not self.database_url.startswith(("postgresql", "postgres")):
|
||||
|
||||
@@ -150,7 +150,7 @@ class WebhookEventManager:
|
||||
|
||||
|
||||
# Module-level instance (can be replaced in tests via dependency injection)
|
||||
# TODO: Consider migrating to langflow's service manager pattern for better DI
|
||||
# TODO: Consider migrating to flow's service manager pattern for better DI
|
||||
_webhook_event_manager: WebhookEventManager | None = None
|
||||
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ def import_all_services_into_a_dict():
|
||||
logger.exception(exc)
|
||||
msg = "Could not initialize services. Please check your settings."
|
||||
raise RuntimeError(msg) from exc
|
||||
# Import settings and auth base from lfx (used in type hints but not langflow Service subclasses)
|
||||
# Import settings and auth base from lfx (used in type hints but not flow Service subclasses)
|
||||
from lfx.services.auth.base import BaseAuthService
|
||||
from lfx.services.settings.service import SettingsService
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Langflow ServiceManager - re-exports from lfx for backwards compatibility."""
|
||||
"""Hanzo Flow ServiceManager - re-exports from lfx for backwards compatibility."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Storage service for langflow - redirects to lfx implementation."""
|
||||
"""Storage service for flow - redirects to lfx implementation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ async def get_lf_version_from_pypi():
|
||||
return None
|
||||
return response.json()["info"]["version"]
|
||||
except Exception: # noqa: BLE001
|
||||
logger.debug("Error getting the latest version of langflow from PyPI", exc_info=True)
|
||||
logger.debug("Error getting the latest version of flow from PyPI", exc_info=True)
|
||||
return None
|
||||
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ class CollectingSpanProcessor(SpanProcessor):
|
||||
self.correlation_id = str(uuid.uuid4())
|
||||
|
||||
# Inject into the CHAIN & LLM spans
|
||||
if span.name in ("Langflow", "Language Model"):
|
||||
if span.name in ("Hanzo Flow", "Language Model"):
|
||||
span.set_attribute("flow.correlation_id", self.correlation_id)
|
||||
|
||||
def on_end(self, span):
|
||||
@@ -94,7 +94,7 @@ class ArizePhoenixTracer(BaseTracer):
|
||||
self.carrier: dict[Any, CarrierT] = {}
|
||||
|
||||
self.root_span = self.tracer.start_span(
|
||||
name="Langflow",
|
||||
name="Hanzo Flow",
|
||||
start_time=self._get_current_timestamp(),
|
||||
)
|
||||
self.root_span.set_attribute(SpanAttributes.SESSION_ID, self.session_id or self.flow_id)
|
||||
|
||||
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
||||
_UTC_MIN = datetime.min.replace(tzinfo=timezone.utc)
|
||||
|
||||
# Name substring used to identify the user-facing input span.
|
||||
# Langflow's native tracer names this span "Chat Input" by convention.
|
||||
# Hanzo Flow's native tracer names this span "Chat Input" by convention.
|
||||
# If the span naming convention changes, update this constant.
|
||||
_CHAT_INPUT_SPAN_NAME = "Chat Input"
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ class LangWatchTracer(BaseTracer):
|
||||
api_key = os.environ["LANGWATCH_API_KEY"]
|
||||
endpoint = os.environ.get("LANGWATCH_ENDPOINT", "https://app.langwatch.ai")
|
||||
|
||||
resource = Resource.create(attributes={"service.name": "langflow"})
|
||||
resource = Resource.create(attributes={"service.name": "flow"})
|
||||
exporter = OTLPSpanExporter(
|
||||
endpoint=f"{endpoint}/api/otel/v1/traces", headers={"Authorization": f"Bearer {api_key}"}
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Native tracer for storing execution traces in the database.
|
||||
|
||||
This module provides a tracer that stores component-level and LangChain-level
|
||||
execution traces directly in Langflow's database, enabling the Trace View
|
||||
execution traces directly in Hanzo Flow's database, enabling the Trace View
|
||||
without requiring external services like LangSmith or LangFuse.
|
||||
"""
|
||||
|
||||
@@ -43,7 +43,7 @@ TYPE_MAP = {
|
||||
|
||||
|
||||
class NativeTracer(BaseTracer):
|
||||
"""Tracer that stores execution traces in Langflow's database.
|
||||
"""Tracer that stores execution traces in Hanzo Flow's database.
|
||||
|
||||
This tracer captures:
|
||||
- Component-level traces (via add_trace/end_trace)
|
||||
@@ -477,7 +477,7 @@ class NativeTracer(BaseTracer):
|
||||
lc_attributes["gen_ai.response.model"] = span_info["model_name"]
|
||||
if span_info.get("provider"):
|
||||
lc_attributes["gen_ai.provider.name"] = span_info["provider"]
|
||||
# Default to chat since most LLM usage in Langflow is conversational
|
||||
# Default to chat since most LLM usage in Hanzo Flow is conversational
|
||||
if span_info.get("span_type") == "llm":
|
||||
lc_attributes["gen_ai.operation.name"] = "chat"
|
||||
if prompt_tokens:
|
||||
@@ -554,5 +554,5 @@ class NativeTracer(BaseTracer):
|
||||
|
||||
@staticmethod
|
||||
def _map_trace_type(trace_type: str) -> SpanType:
|
||||
"""Normalise Langflow's string trace types to the SpanType enum, defaulting to CHAIN for unknown values."""
|
||||
"""Normalise Hanzo Flow's string trace types to the SpanType enum, defaulting to CHAIN for unknown values."""
|
||||
return TYPE_MAP.get(trace_type.lower(), SpanType.CHAIN)
|
||||
|
||||
@@ -31,7 +31,7 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class TraceloopTracer(BaseTracer):
|
||||
"""Traceloop tracer for Langflow."""
|
||||
"""Traceloop tracer for Hanzo Flow."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -64,7 +64,7 @@ class TraceloopTracer(BaseTracer):
|
||||
api_endpoint=os.getenv("TRACELOOP_BASE_URL", "https://api.traceloop.com"),
|
||||
)
|
||||
self._ready = True
|
||||
self._tracer = trace.get_tracer("langflow")
|
||||
self._tracer = trace.get_tracer("flow")
|
||||
self.propagator = TraceContextTextMapPropagator()
|
||||
self.carrier: CarrierT = {}
|
||||
|
||||
|
||||
@@ -262,7 +262,7 @@ def register_all_service_factories() -> None:
|
||||
service_manager.register_factory(task_factory.TaskServiceFactory())
|
||||
service_manager.register_factory(store_factory.StoreServiceFactory())
|
||||
service_manager.register_factory(shared_component_cache_factory.SharedComponentCacheServiceFactory())
|
||||
# Override LFX's no-op auth service with Langflow's full JWT implementation
|
||||
# Override LFX's no-op auth service with Hanzo Flow's full JWT implementation
|
||||
service_manager.register_service_class(ServiceType.AUTH_SERVICE, AuthService, override=True)
|
||||
service_manager.register_factory(auth_factory.AuthServiceFactory())
|
||||
service_manager.register_factory(mcp_composer_factory.MCPComposerServiceFactory())
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Lazy load utilities for langflow - imports from lfx."""
|
||||
"""Lazy load utilities for flow - imports from lfx."""
|
||||
|
||||
# Import everything from lfx.utils.lazy_load
|
||||
from lfx.utils.lazy_load import * # noqa: F403
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""MCP subprocess cleanup utilities for graceful shutdown.
|
||||
|
||||
This module provides functions to properly terminate MCP server subprocesses
|
||||
spawned by stdio_client during Langflow shutdown.
|
||||
spawned by stdio_client during Hanzo Flow shutdown.
|
||||
|
||||
Works on macOS and Linux only.
|
||||
"""
|
||||
@@ -42,7 +42,7 @@ async def cleanup_mcp_sessions() -> None:
|
||||
|
||||
|
||||
async def _kill_mcp_processes() -> None:
|
||||
"""Kill MCP server subprocesses spawned by this Langflow process.
|
||||
"""Kill MCP server subprocesses spawned by this Hanzo Flow process.
|
||||
|
||||
This is a fallback for when the normal cleanup doesn't properly terminate
|
||||
subprocesses spawned by stdio_client.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Template validation utilities for Langflow starter projects.
|
||||
"""Template validation utilities for Hanzo Flow starter projects.
|
||||
|
||||
This module provides validation functions to ensure template integrity and prevent
|
||||
unexpected breakage in starter project templates.
|
||||
|
||||
+103
-103
@@ -1,5 +1,5 @@
|
||||
[project]
|
||||
name = "langflow-base"
|
||||
name = "hanzo-flow-base"
|
||||
version = "0.9.6"
|
||||
description = "A Python package with a built-in web application"
|
||||
requires-python = ">=3.12,<3.14"
|
||||
@@ -371,124 +371,124 @@ ibm-watsonx-clients = [
|
||||
]
|
||||
|
||||
complete = [
|
||||
"langflow-base[couchbase]",
|
||||
"langflow-base[cassandra]",
|
||||
"langflow-base[clickhouse]",
|
||||
"langflow-base[mongodb]",
|
||||
"langflow-base[supabase]",
|
||||
"langflow-base[redis]",
|
||||
"langflow-base[elasticsearch]",
|
||||
"langflow-base[faiss]",
|
||||
"langflow-base[qdrant]",
|
||||
"langflow-base[qdrant-vectors]",
|
||||
"langflow-base[weaviate]",
|
||||
"langflow-base[chroma]",
|
||||
"langflow-base[upstash]",
|
||||
"langflow-base[pinecone]",
|
||||
"langflow-base[milvus]",
|
||||
"langflow-base[mongodb-vectors]",
|
||||
"langflow-base[astradb]",
|
||||
"langflow-base[openai]",
|
||||
"langflow-base[anthropic]",
|
||||
"langflow-base[cohere]",
|
||||
"langflow-base[google]",
|
||||
"langflow-base[ollama]",
|
||||
"langflow-base[nvidia]",
|
||||
"langflow-base[mistral]",
|
||||
"langflow-base[sambanova]",
|
||||
"langflow-base[groq]",
|
||||
"langflow-base[langfuse]",
|
||||
"langflow-base[langwatch]",
|
||||
"langflow-base[langsmith]",
|
||||
"langflow-base[arize]",
|
||||
"langflow-base[pypdf]",
|
||||
"langflow-base[docx]",
|
||||
"langflow-base[pytube]",
|
||||
# "langflow-base[crewai]", # commented out due to httpx version conflict
|
||||
"langflow-base[smolagents]",
|
||||
"langflow-base[beautifulsoup]",
|
||||
"langflow-base[serpapi]",
|
||||
"langflow-base[google-api]",
|
||||
"langflow-base[wikipedia]",
|
||||
"langflow-base[fake-useragent]",
|
||||
"langflow-base[duckduckgo]",
|
||||
"langflow-base[yfinance]",
|
||||
"langflow-base[wolframalpha]",
|
||||
"langflow-base[pyarrow]",
|
||||
"langflow-base[fastavro]",
|
||||
"langflow-base[gitpython]",
|
||||
"langflow-base[nltk]",
|
||||
"langflow-base[lark]",
|
||||
"langflow-base[huggingface]",
|
||||
"langflow-base[metaphor]",
|
||||
"langflow-base[metal]",
|
||||
"langflow-base[markup]",
|
||||
"langflow-base[aws]",
|
||||
"langflow-base[numexpr]",
|
||||
"langflow-base[qianfan]",
|
||||
"langflow-base[pgvector]",
|
||||
"langflow-base[litellm]",
|
||||
"langflow-base[zep]",
|
||||
"langflow-base[youtube]",
|
||||
"langflow-base[markdown]",
|
||||
"langflow-base[kubernetes]",
|
||||
"langflow-base[json-repair]",
|
||||
"langflow-base[composio]",
|
||||
"langflow-base[ragstack]",
|
||||
"langflow-base[opensearch]",
|
||||
"langflow-base[atlassian]",
|
||||
"langflow-base[mem0]",
|
||||
"langflow-base[needle]",
|
||||
"langflow-base[sseclient]",
|
||||
"langflow-base[openinference]",
|
||||
"langflow-base[mcp]",
|
||||
"langflow-base[ag2]",
|
||||
"langflow-base[scrapegraph]",
|
||||
"langflow-base[apify]",
|
||||
"langflow-base[spider]",
|
||||
"hanzo-flow-base[couchbase]",
|
||||
"hanzo-flow-base[cassandra]",
|
||||
"hanzo-flow-base[clickhouse]",
|
||||
"hanzo-flow-base[mongodb]",
|
||||
"hanzo-flow-base[supabase]",
|
||||
"hanzo-flow-base[redis]",
|
||||
"hanzo-flow-base[elasticsearch]",
|
||||
"hanzo-flow-base[faiss]",
|
||||
"hanzo-flow-base[qdrant]",
|
||||
"hanzo-flow-base[qdrant-vectors]",
|
||||
"hanzo-flow-base[weaviate]",
|
||||
"hanzo-flow-base[chroma]",
|
||||
"hanzo-flow-base[upstash]",
|
||||
"hanzo-flow-base[pinecone]",
|
||||
"hanzo-flow-base[milvus]",
|
||||
"hanzo-flow-base[mongodb-vectors]",
|
||||
"hanzo-flow-base[astradb]",
|
||||
"hanzo-flow-base[openai]",
|
||||
"hanzo-flow-base[anthropic]",
|
||||
"hanzo-flow-base[cohere]",
|
||||
"hanzo-flow-base[google]",
|
||||
"hanzo-flow-base[ollama]",
|
||||
"hanzo-flow-base[nvidia]",
|
||||
"hanzo-flow-base[mistral]",
|
||||
"hanzo-flow-base[sambanova]",
|
||||
"hanzo-flow-base[groq]",
|
||||
"hanzo-flow-base[langfuse]",
|
||||
"hanzo-flow-base[langwatch]",
|
||||
"hanzo-flow-base[langsmith]",
|
||||
"hanzo-flow-base[arize]",
|
||||
"hanzo-flow-base[pypdf]",
|
||||
"hanzo-flow-base[docx]",
|
||||
"hanzo-flow-base[pytube]",
|
||||
# "hanzo-flow-base[crewai]", # commented out due to httpx version conflict
|
||||
"hanzo-flow-base[smolagents]",
|
||||
"hanzo-flow-base[beautifulsoup]",
|
||||
"hanzo-flow-base[serpapi]",
|
||||
"hanzo-flow-base[google-api]",
|
||||
"hanzo-flow-base[wikipedia]",
|
||||
"hanzo-flow-base[fake-useragent]",
|
||||
"hanzo-flow-base[duckduckgo]",
|
||||
"hanzo-flow-base[yfinance]",
|
||||
"hanzo-flow-base[wolframalpha]",
|
||||
"hanzo-flow-base[pyarrow]",
|
||||
"hanzo-flow-base[fastavro]",
|
||||
"hanzo-flow-base[gitpython]",
|
||||
"hanzo-flow-base[nltk]",
|
||||
"hanzo-flow-base[lark]",
|
||||
"hanzo-flow-base[huggingface]",
|
||||
"hanzo-flow-base[metaphor]",
|
||||
"hanzo-flow-base[metal]",
|
||||
"hanzo-flow-base[markup]",
|
||||
"hanzo-flow-base[aws]",
|
||||
"hanzo-flow-base[numexpr]",
|
||||
"hanzo-flow-base[qianfan]",
|
||||
"hanzo-flow-base[pgvector]",
|
||||
"hanzo-flow-base[litellm]",
|
||||
"hanzo-flow-base[zep]",
|
||||
"hanzo-flow-base[youtube]",
|
||||
"hanzo-flow-base[markdown]",
|
||||
"hanzo-flow-base[kubernetes]",
|
||||
"hanzo-flow-base[json-repair]",
|
||||
"hanzo-flow-base[composio]",
|
||||
"hanzo-flow-base[ragstack]",
|
||||
"hanzo-flow-base[opensearch]",
|
||||
"hanzo-flow-base[atlassian]",
|
||||
"hanzo-flow-base[mem0]",
|
||||
"hanzo-flow-base[needle]",
|
||||
"hanzo-flow-base[sseclient]",
|
||||
"hanzo-flow-base[openinference]",
|
||||
"hanzo-flow-base[mcp]",
|
||||
"hanzo-flow-base[ag2]",
|
||||
"hanzo-flow-base[scrapegraph]",
|
||||
"hanzo-flow-base[apify]",
|
||||
"hanzo-flow-base[spider]",
|
||||
# ALTK
|
||||
"langflow-base[altk]",
|
||||
"hanzo-flow-base[altk]",
|
||||
# Toolguard
|
||||
"langflow-base[toolguard]",
|
||||
"hanzo-flow-base[toolguard]",
|
||||
# Additional LangChain integrations
|
||||
"langflow-base[langchain-huggingface]",
|
||||
"langflow-base[langchain-unstructured]",
|
||||
"langflow-base[graph-retriever]",
|
||||
"langflow-base[langchain-mcp-adapters]",
|
||||
"hanzo-flow-base[langchain-huggingface]",
|
||||
"hanzo-flow-base[langchain-unstructured]",
|
||||
"hanzo-flow-base[graph-retriever]",
|
||||
"hanzo-flow-base[langchain-mcp-adapters]",
|
||||
# Additional monitoring
|
||||
"langflow-base[opik]",
|
||||
"langflow-base[traceloop]",
|
||||
"langflow-base[openlayer]",
|
||||
"hanzo-flow-base[opik]",
|
||||
"hanzo-flow-base[traceloop]",
|
||||
"hanzo-flow-base[openlayer]",
|
||||
# Document processing / OCR
|
||||
"langflow-base[docling]",
|
||||
"langflow-base[easyocr]",
|
||||
"hanzo-flow-base[docling]",
|
||||
"hanzo-flow-base[easyocr]",
|
||||
# Additional tools
|
||||
"langflow-base[cleanlab]",
|
||||
"langflow-base[twelvelabs]",
|
||||
"langflow-base[jigsawstack]",
|
||||
"langflow-base[assemblyai]",
|
||||
"hanzo-flow-base[cleanlab]",
|
||||
"hanzo-flow-base[twelvelabs]",
|
||||
"hanzo-flow-base[jigsawstack]",
|
||||
"hanzo-flow-base[assemblyai]",
|
||||
# Data processing
|
||||
"langflow-base[datasets]",
|
||||
"langflow-base[fastparquet]",
|
||||
"hanzo-flow-base[datasets]",
|
||||
"hanzo-flow-base[fastparquet]",
|
||||
# Vision / ML
|
||||
"langflow-base[vlmrun]",
|
||||
"langflow-base[cuga]",
|
||||
"langflow-base[mlx]",
|
||||
"hanzo-flow-base[vlmrun]",
|
||||
"hanzo-flow-base[cuga]",
|
||||
"hanzo-flow-base[mlx]",
|
||||
# MCP
|
||||
"langflow-base[fastmcp]",
|
||||
"hanzo-flow-base[fastmcp]",
|
||||
# AWS extras
|
||||
"langflow-base[aioboto3]",
|
||||
"hanzo-flow-base[aioboto3]",
|
||||
# Astra
|
||||
"langflow-base[astrapy]",
|
||||
"hanzo-flow-base[astrapy]",
|
||||
# Windows-specific
|
||||
"langflow-base[gassist]",
|
||||
"hanzo-flow-base[gassist]",
|
||||
# wxO deployment adapter,
|
||||
"langflow-base[ibm-watsonx-clients]"
|
||||
"hanzo-flow-base[ibm-watsonx-clients]"
|
||||
]
|
||||
|
||||
all = [
|
||||
"langflow-base[complete]",
|
||||
"hanzo-flow-base[complete]",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
langflow-base = "flow.launcher:main"
|
||||
hanzo-flow-base = "flow.launcher:main"
|
||||
|
||||
@@ -45,7 +45,7 @@ dependencies = [
|
||||
"pypdf>=6.10.0,<7.0.0",
|
||||
"cryptography>=46.0.7",
|
||||
"ag-ui-protocol>=0.1.10",
|
||||
"langflow-sdk>=0.1.0",
|
||||
"hanzo-flow-sdk>=0.1.0",
|
||||
"markitdown>=0.1.4,<2.0.0",
|
||||
"setuptools>=80.0.0,<81.0.0",
|
||||
"wheel>=0.46.2,<1.0.0",
|
||||
|
||||
@@ -18,7 +18,7 @@ def _version_callback(value: bool) -> None:
|
||||
|
||||
app = typer.Typer(
|
||||
name="lfx",
|
||||
help="lfx - Langflow Executor",
|
||||
help="lfx - Hanzo Flow Executor",
|
||||
add_completion=False,
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ def _app_callback(
|
||||
callback=_version_callback,
|
||||
),
|
||||
) -> None:
|
||||
"""Lfx - Langflow Executor."""
|
||||
"""Lfx - Hanzo Flow Executor."""
|
||||
|
||||
|
||||
# Register command groups (order determines help-panel ordering)
|
||||
|
||||
@@ -152,7 +152,7 @@ class ALTKBaseTool(BaseTool):
|
||||
llm_client = get_llm(llm_client_type)
|
||||
llm_client_obj = llm_client(model=model_name, api_key=api_key)
|
||||
else:
|
||||
logger.info("ALTK currently only supports OpenAI and Anthropic models through Langflow.")
|
||||
logger.info("ALTK currently only supports OpenAI and Anthropic models through Hanzo Flow.")
|
||||
llm_client_obj = None
|
||||
|
||||
return llm_client_obj
|
||||
|
||||
@@ -746,7 +746,7 @@ class ComposioBaseComponent(Component):
|
||||
logger.debug(f"Could not populate Composio actions for {self.app_name}: {e}")
|
||||
|
||||
def _validate_schema_inputs(self, action_key: str) -> list[InputTypes]:
|
||||
"""Convert the JSON schema for *action_key* into Langflow input objects."""
|
||||
"""Convert the JSON schema for *action_key* into Hanzo Flow input objects."""
|
||||
# Skip validation for default/placeholder values
|
||||
if action_key in ("disabled", "placeholder", ""):
|
||||
logger.debug(f"Skipping schema validation for placeholder value: {action_key}")
|
||||
|
||||
@@ -299,8 +299,8 @@ def docling_worker(
|
||||
|
||||
except ModuleNotFoundError:
|
||||
msg = (
|
||||
"Docling is an optional dependency of Langflow. "
|
||||
"Install with `uv pip install 'langflow[docling]'` "
|
||||
"Docling is an optional dependency of Hanzo Flow. "
|
||||
"Install with `uv pip install 'flow[docling]'` "
|
||||
"or refer to the documentation"
|
||||
)
|
||||
queue.put({"error": msg})
|
||||
@@ -345,7 +345,7 @@ def docling_worker(
|
||||
except ImportError as e:
|
||||
msg = (
|
||||
"langchain-docling is not installed. Please install it with `pip install langchain-docling` "
|
||||
"or `pip install 'langflow[docling-image-description]'`."
|
||||
"or `pip install 'flow[docling-image-description]'`."
|
||||
)
|
||||
raise ImportError(msg) from e
|
||||
pic_desc_llm = _deserialize_pydantic_model(pic_desc_config)
|
||||
|
||||
@@ -621,7 +621,7 @@ async def get_flow_snake_case(flow_name: str, user_id: str, session, *, is_actio
|
||||
from flow.services.database.models.flow.model import Flow
|
||||
from sqlmodel import select
|
||||
except ImportError as e:
|
||||
msg = "Langflow Flow model is not available. This feature requires the full Langflow installation."
|
||||
msg = "Hanzo Flow Flow model is not available. This feature requires the full Hanzo Flow installation."
|
||||
raise ImportError(msg) from e
|
||||
|
||||
uuid_user_id = UUID(user_id) if isinstance(user_id, str) else user_id
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"""Safe defaults for Langflow-created Chroma collections.
|
||||
"""Safe defaults for Hanzo Flow-created Chroma collections.
|
||||
|
||||
Chroma collection configuration can persist server-side embedding functions.
|
||||
Some embedding functions accept model-loading kwargs such as trust_remote_code.
|
||||
Langflow embeds client-side, so built-in collection creation should not register
|
||||
Hanzo Flow embeds client-side, so built-in collection creation should not register
|
||||
server-side embedding code.
|
||||
"""
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ def register(app: typer.Typer) -> None:
|
||||
help="Overwrite the destination file if it already exists.",
|
||||
),
|
||||
) -> None:
|
||||
"""Scaffold a new Langflow flow JSON from a built-in template (lazy-loaded)."""
|
||||
"""Scaffold a new Hanzo Flow flow JSON from a built-in template (lazy-loaded)."""
|
||||
from pathlib import Path
|
||||
|
||||
from lfx.cli.create import create_command, print_templates
|
||||
@@ -58,7 +58,7 @@ def register(app: typer.Typer) -> None:
|
||||
rich_help_panel="Authoring",
|
||||
)
|
||||
def requirements_command_wrapper(
|
||||
flow_path: str = typer.Argument(help="Path to the Langflow flow JSON file"),
|
||||
flow_path: str = typer.Argument(help="Path to the Hanzo Flow flow JSON file"),
|
||||
output: str | None = typer.Option(
|
||||
None,
|
||||
"--output",
|
||||
@@ -82,7 +82,7 @@ def register(app: typer.Typer) -> None:
|
||||
help="Do not pin package versions (default: pin to currently installed versions)",
|
||||
),
|
||||
) -> None:
|
||||
"""Generate requirements.txt from a Langflow flow JSON (lazy-loaded)."""
|
||||
"""Generate requirements.txt from a Hanzo Flow flow JSON (lazy-loaded)."""
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
@@ -120,7 +120,7 @@ def register(app: typer.Typer) -> None:
|
||||
def validate_command_wrapper(
|
||||
flow_paths: list[str] = typer.Argument(
|
||||
default=None,
|
||||
help="Path(s) to Langflow flow JSON file(s) or directories to validate. Defaults to flows/.",
|
||||
help="Path(s) to Hanzo Flow flow JSON file(s) or directories to validate. Defaults to flows/.",
|
||||
),
|
||||
dir_path: str | None = typer.Option(
|
||||
None,
|
||||
@@ -185,7 +185,7 @@ def register(app: typer.Typer) -> None:
|
||||
help="Output format: text (default) or json",
|
||||
),
|
||||
) -> None:
|
||||
"""Validate Langflow flow JSON files without executing them (lazy-loaded)."""
|
||||
"""Validate Hanzo Flow flow JSON files without executing them (lazy-loaded)."""
|
||||
from lfx.cli.validate import validate_command
|
||||
|
||||
# Merge --dir into positional paths for a consistent interface with push
|
||||
|
||||
@@ -7,7 +7,7 @@ def register(app: typer.Typer) -> None:
|
||||
"""Register remote-stage commands on *app*."""
|
||||
|
||||
@app.command(
|
||||
name="status", help="Compare local flow files against a remote Langflow instance", rich_help_panel="Remote"
|
||||
name="status", help="Compare local flow files against a remote Hanzo Flow instance", rich_help_panel="Remote"
|
||||
)
|
||||
def status_command_wrapper(
|
||||
flow_paths: list[str] = typer.Argument(
|
||||
@@ -34,12 +34,12 @@ def register(app: typer.Typer) -> None:
|
||||
target: str | None = typer.Option(
|
||||
None,
|
||||
"--target",
|
||||
help="Langflow instance URL (inline override — skips config file lookup).",
|
||||
help="Hanzo Flow instance URL (inline override — skips config file lookup).",
|
||||
),
|
||||
api_key: str | None = typer.Option(
|
||||
None,
|
||||
"--api-key",
|
||||
help="API key for the Langflow instance (used with --target or to override config).",
|
||||
help="API key for the Hanzo Flow instance (used with --target or to override config).",
|
||||
),
|
||||
show_remote_only: bool = typer.Option(
|
||||
False,
|
||||
@@ -62,7 +62,7 @@ def register(app: typer.Typer) -> None:
|
||||
|
||||
@app.command(
|
||||
name="push",
|
||||
help="Push flow JSON to a remote Langflow instance (upsert by stable ID)",
|
||||
help="Push flow JSON to a remote Hanzo Flow instance (upsert by stable ID)",
|
||||
rich_help_panel="Remote",
|
||||
)
|
||||
def push_command_wrapper(
|
||||
@@ -101,12 +101,12 @@ def register(app: typer.Typer) -> None:
|
||||
target: str | None = typer.Option(
|
||||
None,
|
||||
"--target",
|
||||
help="Langflow instance URL (inline override — skips config file lookup).",
|
||||
help="Hanzo Flow instance URL (inline override — skips config file lookup).",
|
||||
),
|
||||
api_key: str | None = typer.Option(
|
||||
None,
|
||||
"--api-key",
|
||||
help="API key for the Langflow instance (used with --target or to override config).",
|
||||
help="API key for the Hanzo Flow instance (used with --target or to override config).",
|
||||
),
|
||||
dry_run: bool = typer.Option(
|
||||
False,
|
||||
@@ -124,7 +124,7 @@ def register(app: typer.Typer) -> None:
|
||||
help="Clear password/load_from_db field values before pushing.",
|
||||
),
|
||||
) -> None:
|
||||
"""Push Langflow flows to a remote instance using stable IDs for upsert (lazy-loaded)."""
|
||||
"""Push Hanzo Flow flows to a remote instance using stable IDs for upsert (lazy-loaded)."""
|
||||
from lfx.cli.push import push_command
|
||||
|
||||
push_command(
|
||||
@@ -142,7 +142,7 @@ def register(app: typer.Typer) -> None:
|
||||
)
|
||||
|
||||
@app.command(
|
||||
name="pull", help="Pull flows from a remote Langflow instance to local files", rich_help_panel="Remote"
|
||||
name="pull", help="Pull flows from a remote Hanzo Flow instance to local files", rich_help_panel="Remote"
|
||||
)
|
||||
def pull_command_wrapper(
|
||||
env: str | None = typer.Option(
|
||||
@@ -181,12 +181,12 @@ def register(app: typer.Typer) -> None:
|
||||
target: str | None = typer.Option(
|
||||
None,
|
||||
"--target",
|
||||
help="Langflow instance URL (inline override — skips config file lookup).",
|
||||
help="Hanzo Flow instance URL (inline override — skips config file lookup).",
|
||||
),
|
||||
api_key: str | None = typer.Option(
|
||||
None,
|
||||
"--api-key",
|
||||
help="API key for the Langflow instance (used with --target or to override config).",
|
||||
help="API key for the Hanzo Flow instance (used with --target or to override config).",
|
||||
),
|
||||
strip_secrets: bool = typer.Option(
|
||||
True,
|
||||
@@ -199,7 +199,7 @@ def register(app: typer.Typer) -> None:
|
||||
help="JSON indentation level.",
|
||||
),
|
||||
) -> None:
|
||||
"""Pull and normalize flows from a remote Langflow instance (lazy-loaded)."""
|
||||
"""Pull and normalize flows from a remote Hanzo Flow instance (lazy-loaded)."""
|
||||
from lfx.cli.pull import pull_command
|
||||
|
||||
pull_command(
|
||||
@@ -261,12 +261,12 @@ def register(app: typer.Typer) -> None:
|
||||
target: str | None = typer.Option(
|
||||
None,
|
||||
"--target",
|
||||
help="Langflow instance URL (inline override — skips config file lookup).",
|
||||
help="Hanzo Flow instance URL (inline override — skips config file lookup).",
|
||||
),
|
||||
api_key: str | None = typer.Option(
|
||||
None,
|
||||
"--api-key",
|
||||
help="API key for the Langflow instance (used with --target or to override config).",
|
||||
help="API key for the Hanzo Flow instance (used with --target or to override config).",
|
||||
),
|
||||
in_place: bool = typer.Option(
|
||||
False,
|
||||
@@ -300,7 +300,7 @@ def register(app: typer.Typer) -> None:
|
||||
help="JSON indentation level.",
|
||||
),
|
||||
) -> None:
|
||||
"""Export and normalize Langflow flow JSON for version control (lazy-loaded)."""
|
||||
"""Export and normalize Hanzo Flow flow JSON for version control (lazy-loaded)."""
|
||||
from lfx.cli.export import export_command
|
||||
|
||||
export_command(
|
||||
|
||||
@@ -40,7 +40,7 @@ def register(app: typer.Typer) -> None:
|
||||
example=example,
|
||||
)
|
||||
|
||||
@app.command(name="login", help="Validate credentials against a remote Langflow instance", rich_help_panel="Setup")
|
||||
@app.command(name="login", help="Validate credentials against a remote Hanzo Flow instance", rich_help_panel="Setup")
|
||||
def login_command_wrapper(
|
||||
env: str | None = typer.Option(
|
||||
None,
|
||||
@@ -56,15 +56,15 @@ def register(app: typer.Typer) -> None:
|
||||
target: str | None = typer.Option(
|
||||
None,
|
||||
"--target",
|
||||
help="Langflow instance URL (inline override — skips config file lookup).",
|
||||
help="Hanzo Flow instance URL (inline override — skips config file lookup).",
|
||||
),
|
||||
api_key: str | None = typer.Option(
|
||||
None,
|
||||
"--api-key",
|
||||
help="API key for the Langflow instance (used with --target or to override config).",
|
||||
help="API key for the Hanzo Flow instance (used with --target or to override config).",
|
||||
),
|
||||
) -> None:
|
||||
"""Test connectivity and authentication for a Langflow environment (lazy-loaded)."""
|
||||
"""Test connectivity and authentication for a Hanzo Flow environment (lazy-loaded)."""
|
||||
from lfx.cli.login import login_command
|
||||
|
||||
login_command(
|
||||
|
||||
@@ -638,7 +638,7 @@ def load_sdk(command_name: str) -> Any:
|
||||
try:
|
||||
import flow_sdk # type: ignore[import-untyped]
|
||||
except ImportError as exc:
|
||||
msg = f"langflow-sdk is required for lfx {command_name}. Install it with: pip install langflow-sdk"
|
||||
msg = f"flow-sdk is required for lfx {command_name}. Install it with: pip install flow-sdk"
|
||||
raise typer.BadParameter(msg) from exc
|
||||
else:
|
||||
return langflow_sdk
|
||||
|
||||
@@ -7,8 +7,8 @@ Local (default)
|
||||
result back to disk (or stdout). No network connection required.
|
||||
|
||||
Remote (--env / --flow-id / --project-id)
|
||||
Pull flows directly from a running Langflow instance using the
|
||||
``langflow-sdk`` HTTP client, normalize them, and write to disk.
|
||||
Pull flows directly from a running Hanzo Flow instance using the
|
||||
``flow-sdk`` HTTP client, normalize them, and write to disk.
|
||||
|
||||
Examples:
|
||||
--------
|
||||
@@ -101,7 +101,7 @@ def export_command(
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Remote mode: pull from a live Langflow instance
|
||||
# Remote mode: pull from a live Hanzo Flow instance
|
||||
# ------------------------------------------------------------------
|
||||
if flow_id or project_id:
|
||||
if not env and not target:
|
||||
|
||||
+13
-13
@@ -29,13 +29,13 @@ console = Console()
|
||||
_ENVIRONMENTS_YAML = """\
|
||||
# .lfx/environments.yaml
|
||||
#
|
||||
# Configure your Langflow instances here.
|
||||
# Configure your Hanzo Flow instances here.
|
||||
# Safe to commit — API keys are NEVER stored in this file.
|
||||
# The api_key_env value is the NAME of an environment variable that holds
|
||||
# the actual API key; set that variable in your shell or CI secrets.
|
||||
#
|
||||
# Quick start:
|
||||
# 1. Open Langflow → Settings → API Keys → Create a new key
|
||||
# 1. Open Hanzo Flow → Settings → API Keys → Create a new key
|
||||
# 2. export LANGFLOW_LOCAL_API_KEY=<your key>
|
||||
# 3. lfx export --env local --flow-id <uuid> --output-dir flows/
|
||||
|
||||
@@ -57,15 +57,15 @@ defaults:
|
||||
"""
|
||||
|
||||
_TEST_FLOWS_PY = '''\
|
||||
"""Integration tests for Langflow flows.
|
||||
"""Integration tests for Hanzo Flow flows.
|
||||
|
||||
Run against a local instance (started with ``lfx serve``):
|
||||
|
||||
pytest tests/ --langflow-url http://localhost:8000
|
||||
pytest tests/ --flow-url http://localhost:8000
|
||||
|
||||
Run against a named environment (staging, production, etc.):
|
||||
|
||||
pytest tests/ --langflow-env staging -m integration
|
||||
pytest tests/ --flow-env staging -m integration
|
||||
|
||||
The flow_runner fixture auto-skips when no connection is configured,
|
||||
so these tests are safe to include in any CI pipeline.
|
||||
@@ -85,16 +85,16 @@ def test_flow_responds(flow_runner):
|
||||
@pytest.mark.integration
|
||||
def test_flow_output_quality(flow_runner):
|
||||
"""Example: assert on the content of the response."""
|
||||
result = flow_runner("my-flow-endpoint", "What is Langflow?")
|
||||
result = flow_runner("my-flow-endpoint", "What is Hanzo Flow?")
|
||||
text = result.first_text_output()
|
||||
assert text is not None
|
||||
assert len(text) > 20, f"Response seems too short: {text!r}"
|
||||
'''
|
||||
|
||||
_GITIGNORE = """\
|
||||
# Langflow credentials -- never commit API keys
|
||||
# (langflow-environments.toml may contain literal keys; .lfx/environments.yaml is safe to commit)
|
||||
langflow-environments.toml
|
||||
# Hanzo Flow credentials -- never commit API keys
|
||||
# (flow-environments.toml may contain literal keys; .lfx/environments.yaml is safe to commit)
|
||||
flow-environments.toml
|
||||
"""
|
||||
|
||||
# Templates bundled inside the Python package
|
||||
@@ -210,11 +210,11 @@ def init_command(
|
||||
**kw,
|
||||
)
|
||||
|
||||
# .gitignore — keep langflow-environments.toml ignored for backward compat
|
||||
# .gitignore — keep flow-environments.toml ignored for backward compat
|
||||
gitignore = target / ".gitignore"
|
||||
if gitignore.exists():
|
||||
existing_content = gitignore.read_text(encoding="utf-8")
|
||||
if "langflow-environments.toml" not in existing_content:
|
||||
if "flow-environments.toml" not in existing_content:
|
||||
gitignore.write_text(existing_content.rstrip() + "\n\n" + _GITIGNORE, encoding="utf-8")
|
||||
created.append((".gitignore", "appended credentials ignore rule"))
|
||||
else:
|
||||
@@ -249,9 +249,9 @@ def init_command(
|
||||
if example:
|
||||
console.print(" 3. [bold]lfx validate flows/hello-world.json[/bold] (check the starter flow)")
|
||||
console.print(" 4. [bold]lfx serve flows/hello-world.json[/bold] (run it locally)")
|
||||
console.print(" 5. [bold]lfx push --dir flows/ --env local[/bold] (deploy to Langflow)")
|
||||
console.print(" 5. [bold]lfx push --dir flows/ --env local[/bold] (deploy to Hanzo Flow)")
|
||||
else:
|
||||
console.print(" 3. [bold]lfx create my-flow --template hello-world[/bold]")
|
||||
console.print(" 4. [bold]lfx push --dir flows/ --env local[/bold]")
|
||||
console.print(f" {'6' if example else '5'}. [bold]pytest tests/ --langflow-env local[/bold]")
|
||||
console.print(f" {'6' if example else '5'}. [bold]pytest tests/ --flow-env local[/bold]")
|
||||
console.print()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""lfx login -- validate credentials against a remote Langflow instance.
|
||||
"""lfx login -- validate credentials against a remote Hanzo Flow instance.
|
||||
|
||||
Tests whether the configured URL and API key are reachable and accepted,
|
||||
then prints a summary with guidance on how to fix any problems.
|
||||
@@ -82,7 +82,7 @@ def _probe_connection(client: Any, sdk: Any) -> tuple[bool, str, int]:
|
||||
except Exception as exc: # noqa: BLE001
|
||||
# A Pydantic ValidationError means the HTTP request completed and was
|
||||
# authenticated (auth is fine) but the SDK's schema doesn't match the
|
||||
# local Langflow version exactly. Treat this as a successful probe.
|
||||
# local Hanzo Flow version exactly. Treat this as a successful probe.
|
||||
if "ValidationError" in type(exc).__qualname__:
|
||||
return True, "OK", 0
|
||||
return False, f"error:{exc}", 0
|
||||
@@ -150,13 +150,13 @@ def login_command(
|
||||
err_console.print()
|
||||
err_console.print("[bold]How to fix:[/bold]")
|
||||
if key_env_name:
|
||||
err_console.print(" 1. Open Langflow → Settings → API Keys → Create a new key")
|
||||
err_console.print(" 1. Open Hanzo Flow → Settings → API Keys → Create a new key")
|
||||
err_console.print(f" 2. [bold]export {key_env_name}=<your-new-key>[/bold]")
|
||||
elif env_cfg.name not in ("__inline__", "__env__"):
|
||||
err_console.print(" 1. Open Langflow → Settings → API Keys → Create a new key")
|
||||
err_console.print(" 1. Open Hanzo Flow → Settings → API Keys → Create a new key")
|
||||
err_console.print(" 2. Pass [bold]--api-key <key>[/bold] or configure api_key_env in your YAML")
|
||||
else:
|
||||
err_console.print(" 1. Open Langflow → Settings → API Keys → Create a new key")
|
||||
err_console.print(" 1. Open Hanzo Flow → Settings → API Keys → Create a new key")
|
||||
err_console.print(" 2. Pass [bold]--api-key <key>[/bold]")
|
||||
raise typer.Exit(1)
|
||||
|
||||
@@ -166,9 +166,9 @@ def login_command(
|
||||
err_console.print(f" URL: {env_cfg.url}")
|
||||
err_console.print()
|
||||
err_console.print("[bold]How to fix:[/bold]")
|
||||
err_console.print(" • Make sure your Langflow instance is running")
|
||||
err_console.print(" • Make sure your Hanzo Flow instance is running")
|
||||
err_console.print(" • Check the URL in your .lfx/environments.yaml")
|
||||
err_console.print(" • If running locally: [bold]langflow run[/bold] or [bold]lfx serve <flow.json>[/bold]")
|
||||
err_console.print(" • If running locally: [bold]flow run[/bold] or [bold]lfx serve <flow.json>[/bold]")
|
||||
raise typer.Exit(1)
|
||||
|
||||
# Generic HTTP or other error
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""lfx pull -- fetch flows from a remote Langflow instance to local files.
|
||||
"""lfx pull -- fetch flows from a remote Hanzo Flow instance to local files.
|
||||
|
||||
Downloads flows from a live Langflow instance, normalizes them for version
|
||||
Downloads flows from a live Hanzo Flow instance, normalizes them for version
|
||||
control, and writes them to a local directory. Repeated pulls are safe:
|
||||
existing files are overwritten with the latest remote state.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""lfx push -- push normalized flow JSON to a remote Langflow instance.
|
||||
"""lfx push -- push normalized flow JSON to a remote Hanzo Flow instance.
|
||||
|
||||
Uses stable flow IDs for upsert (PUT /api/v1/flows/{id}), so repeated pushes
|
||||
are idempotent: the first push creates the flow, subsequent ones update it in
|
||||
|
||||
@@ -110,9 +110,9 @@ async def run(
|
||||
),
|
||||
),
|
||||
) -> None:
|
||||
"""Execute a Langflow graph script or JSON flow and return the result.
|
||||
"""Execute a Hanzo Flow graph script or JSON flow and return the result.
|
||||
|
||||
This command analyzes and executes either a Python script containing a Langflow graph,
|
||||
This command analyzes and executes either a Python script containing a Hanzo Flow graph,
|
||||
a JSON flow file, inline JSON, or JSON from stdin, returning the result in the specified format.
|
||||
By default, output is minimal for use in containers and serverless environments.
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user