Commit Graph

17889 Commits

Author SHA1 Message Date
eb5f83f950 fix: pin postgres image to bookworm in docker_example (#13027)
* fix: pin postgres image to bookworm in docker_example to prevent collation mismatch

The postgres:16 tag silently moved its base from Debian Bookworm
(glibc 2.36) to Trixie (glibc 2.41), causing a recurring collation
version mismatch warning on existing langflow-postgres volumes.

Pin to postgres:16-bookworm in both docker-compose files and update
the README so existing data volumes keep matching the OS locale data.

Refs: https://github.com/langflow-ai/langflow/issues/9608

* docs: pin postgres image to bookworm in current docs compose snippets

Mirror the docker_example pin in the four current docs that publish
copyable Compose snippets pairing postgres:16 with a persistent
langflow-postgres volume. Prevents the same Bookworm-to-Trixie
collation version mismatch warning when users follow docs instead
of docker_example.

Versioned historical docs are left as-is.

Refs: https://github.com/langflow-ai/langflow/issues/9608

* fix: switch postgres pin from bookworm to trixie for OS consistency

Aligns the pinned postgres base with the langflow runtime image, which
moved to Debian Trixie in #12990. Keeping postgres on bookworm would
have diverged the stack and locked the database to an aging glibc that
will receive fewer security backports as bookworm ages into oldstable.

The pin itself still solves the original bug — postgres:16 cannot
silently roll its OS underneath an existing volume.

Document the one-time REFRESH COLLATION VERSION step for users
upgrading from a bookworm-initialized volume in docker_example/README.md.

Refs: https://github.com/langflow-ai/langflow/issues/9608
(cherry picked from commit 7504eb4c72)
2026-05-07 19:39:49 +00:00
cd4aa718e7 fix: stabilize model toggle and refresh Agent dropdown after provider changes (#13113)
* fix: stabilize model toggle and refresh Agent dropdown after provider changes

Two related regressions in the Model Provider management flow on
release-1.9.3:

1. Toggle bounce — rapid clicks on a model Switch flickered between on
   and off before settling. ``handleModelToggle`` performed an
   optimistic ``setQueryData`` on ``useGetEnabledModels`` but never
   cancelled in-flight refetches. With React Query defaults
   (``staleTime: 0``, ``refetchOnWindowFocus: true``), a background
   refetch could land mid-debounce and overwrite the optimistic state
   with stale server data, then the deferred mutation eventually
   corrected it. Fix: ``cancelQueries`` before each optimistic update,
   per the canonical TanStack Query optimistic-updates pattern.

2. Agent dropdown stayed stale after the provider modal closed —
   disabled models remained listed in the Agent's Language Model
   dropdown. The post-close ``isRefreshingAfterClose`` loading gate
   only waited for ``useGetModelProviders`` to settle, not
   ``useGetEnabledModels``. When the providers refetch finished first,
   the loading state cleared and ``groupedOptions`` ran against the
   still-stale enabled-models cache. Fix: track both queries'
   ``isFetching`` flags in the gate's effect.

No behavioral change to the sticky-default UX — the user's previously
selected model continues to show in the dropdown with the wrench
affordance when globally disabled, as designed.

Also narrows the pre-existing ``catch (error: any)`` patterns in the
edited hook file to ``unknown`` with a small shared ``getErrorMessage``
helper, satisfying the staged-file no-explicit-any pre-commit lint.

Tests:
- New ``useProviderConfiguration`` unit test asserts
  ``cancelQueries`` runs before ``setQueryData`` on toggle.
- Extended ``ModelInputComponent`` test covers the dual-query loading
  gate (providers settles first, enabled-models still in flight →
  loading persists; then enabled-models settles → loading clears).

* fix: re-apply pending overlay through entire mutation lifecycle

Addresses review feedback on #13113: ``cancelQueries`` only cancels
refetches that are already in flight at click time. A new
``useGetEnabledModels`` refetch can still start during the 1s
debounce window (or while the mutation is in flight) and overwrite
the optimistic cache with stale server state, producing the same
bounce we just fixed.

Two coordinated changes keep the optimistic state protected for the
entire pending-toggle window:

1. ``pendingModelToggles`` is no longer cleared upfront when the
   debounced flush sends a mutation. Instead, ``clearSentToggles``
   removes only the entries whose value still matches what we sent
   on ``onSettled`` / ``onError``. This preserves the overlay across
   the in-flight mutation window AND correctly handles the case
   where the user re-toggled the same model mid-flight (now a fresh
   intent that survives clearing).

2. A new ``useEffect`` subscribes to ``useGetEnabledModels`` and
   re-applies the pending overlay whenever the data emission drifts
   from the user's pending intent. This catches any refetch
   (window focus, mount, reconnect, stale-time expiry) that lands
   between click and ``onSettled``, regardless of when it started.

Tests:
- New ``re-applies the pending overlay when a refetch surfaces
  stale data`` test simulates a stale refetch and asserts the
  effect re-applies the optimistic overlay.
- New ``does not re-overlay when no toggles are pending`` test
  guards against spurious overlay calls on mount.

* fix: split overlay vs unsent buffers to prevent duplicate model toggle mutations

Addresses a follow-up race introduced by the previous commit: keeping
``pendingModelToggles`` populated through ``onSettled`` (so the
re-overlay effect could repel mid-flight refetches) also caused the
next flush to snapshot the in-flight entries again, sending duplicate
requests with non-deterministic success/failure ordering. The same
risk applied to ``flushPendingChanges`` on modal close.

Split the single buffer into two refs with single responsibilities:

  - ``overlayToggles``: the union of every toggle still protecting the
    UI. The re-overlay effect re-applies this whenever
    ``useGetEnabledModels`` emits new data. Drained per-key on
    ``onSettled``/``onError`` only when the overlay value still matches
    what we sent (a user re-toggle mid-flight becomes a fresh intent
    and must survive the clear).

  - ``unsentToggles``: the strict subset that has NOT been sent in a
    mutation yet, or was re-toggled since the last send. Drained
    immediately at flush time so subsequent flushes never resend an
    in-flight payload.

``handleModelToggle`` populates both buffers; flushes drain only
``unsentToggles`` and use ``overlayToggles`` for cache protection.

Two new unit tests:
- ``does not resend in-flight toggles when a new toggle is flushed``
  asserts that after toggling A then B (with A's mutation in flight),
  the second flush carries ONLY B.
- ``re-sends a model when the user re-toggles it after the previous
  flush fired`` asserts that re-toggling the same model produces a
  second mutation (the re-toggle is a fresh intent, not a duplicate).

* fix: drop sticky-default UX, treat disabled-selected model like any other

Removes the sticky-default carve-out so a globally-disabled model is
never shown in the Agent's Language Model dropdown, regardless of
whether it's the node's saved selection. Drops the Wrench/Configure
affordance — there's no per-trigger "this model isn't enabled for
your user" UX anymore; the dropdown is the single source of truth.

Changes in ``modelInputComponent``:

  - ``groupedOptions``: drop the ``isStickyNotEnabled`` filter
    bypass and the zero-provider import fallback. Disabled models
    never pass the filter, even when tagged ``not_enabled_locally``.

  - ``selectedModel``: drop the saved-value preservation branch.
    If the saved name isn't in ``flatOptions``, fall through to the
    first available option (or ``null`` if nothing is available).

  - Auto-select effect: fires whenever the saved value isn't in
    ``flatOptions``, not just when the value is empty. This
    realigns the node's stored value with the trigger so the
    rendered selection and the run-time selection don't diverge.

  - ``hasEnabledProviders``: redefined as "at least one model of
    this component's type is enabled across any provider"
    (derived from ``groupedOptions``). Routes a configured-but-
    all-disabled provider to the Setup Provider CTA — same UX as
    the never-configured case.

  - Remove the Wrench JSX, the ``showConfigureAffordance``
    derivation, and the now-orphaned ``hasProcessedEmptyRef``.

Tests:
  - ``renders the Setup Provider CTA when no models are enabled``
    (replaces the old disabled-combobox expectation).
  - ``auto-selects an available model when the saved value is
    globally disabled``.
  - ``renders the Setup Provider CTA when a provider is configured
    but all its models are disabled``.
  - ``never renders the Configure wrench affordance``.

* refactor: extract toggle queue into useModelToggleQueue hook

Addresses review I1 (file size + mixed responsibilities) and R1, R2,
R3, R4 in one pass.

I1 — Extract toggle-queue logic out of useProviderConfiguration. The
parent hook drops from 821 lines to 601 and now owns a single
responsibility (variable CRUD + provider lifecycle). The toggle queue
— overlay/unsent buffers, debounced flush, awaitable flush, optimistic
cache management, re-overlay effect — lives in a new 292-line
useModelToggleQueue.ts with one clear responsibility.

R1 — Inside the new hook, DRY the two flush variants behind shared
helpers:
  - ``buildAndConsumeToggleBatch()`` snapshots unsentToggles into the
    mutation payload, captures the pre-toggle cache for rollback, and
    drains unsentToggles atomically.
  - ``rollbackToggleBatch()`` drains overlay BEFORE restoring
    previousData (load-bearing order — otherwise the re-overlay effect
    would re-apply the stale overlay over the rollback).
The two flush callers now differ only in ``mutate`` vs awaitable
``mutateAsync`` plumbing.

R2 — Explicit loop-guard comment on the drift check inside the
re-overlay effect. Names the ``drifted`` short-circuit as the
termination condition so a future refactor that "simplifies" to an
unconditional re-apply doesn't silently introduce a render loop.

R3 — Adversarial coverage for the mutation error path:
  - ``rolls back to previousData when the toggle mutation fails``
  - ``does not re-apply the overlay after a failed mutation drains it``
    (asserts the drain-before-rollback ordering)
  - ``preserves a mid-flight re-toggle when the original mutation
    fails`` (asserts a user re-toggle survives the originating
    mutation's failure)

R4 — ``flushPendingChanges`` now invalidates the affected queries
inline on success, instead of relying on the caller's
``refreshAllModelInputs`` for the load-bearing invalidation. The
caller's refresh remains as an additive per-node template refresh.

Test infra: moved toggle-queue tests from
``useProviderConfiguration.test.tsx`` to a dedicated
``useModelToggleQueue.test.tsx`` that exercises the extracted hook
directly. Debounce mock changed from synchronous pass-through to
explicit ``runDebounced()`` so individual tests can choose whether to
exercise the debounced path or the awaitable ``flushPendingChanges``
path.

95/95 tests pass (87 prior + new R3 coverage + R4 success-path
invalidation).
2026-05-13 14:17:31 -07:00
00bc383f86 docs: SSRF protection enabled by default (#13106)
docs-ssrf-protection-enabled-by-default
2026-05-13 11:30:37 -04:00
b54bdf318d fix: update security dependencies (#13053)
* chore: update security dependencies

- Update brace-expansion to ^5.0.5 in docs
- Update picomatch to ^4.0.4 in docs
- Update ip-address to ^10.1.1 in frontend
- Update GitPython to >=3.1.48 in backend
- Add protobuf constraint >=6.33.6,<7.0.0 in backend

* chore: address additional CVEs and add security documentation

- Update lodash from deprecated 4.18.0 to 4.17.21
- Add docs/SECURITY_OVERRIDES.md documenting all CVEs
- Revert mem0ai 2.x upgrade due to compatibility issues

* fix: update dependencies to address CVE vulnerabilities

- Update langchain-core to >=1.3.3 (fixes CVE-2026-44843)
- Update GitPython to >=3.1.50 (partially fixes CVE-2026-44243, CVE-2026-44244, GHSA-mv93-w799-cj2w)
- Update pyarrow constraint to >=23.0.1,<24.0.0 (fixes CVE-2026-25087)
- Add override-dependencies for transitive packages:
  - lxml >=6.1.0 (fixes CVE-2026-41066)
  - mako >=1.3.12 (fixes CVE-2026-44307)
  - urllib3 >=2.7.0 (fixes CVE-2026-44431, CVE-2026-44432)
  - python-liquid >=2.2.0 (fixes CVE-2026-45017)

Total: 9 CVEs addressed
Smoke tests: All imports successful, no breaking changes detected

---------

Co-authored-by: Janardan S Kavia <janardanskavia@Janardans-MacBook-Pro.local>
2026-05-12 13:09:53 -04:00
6993a19bbe feat: Add SSRF protection with DNS rebinding prevention (#13016)
* feat: Add SSRF protection with DNS rebinding prevention

- Implement DNS pinning to prevent DNS rebinding attacks
- Enable SSRF protection by default (ssrf_protection_enabled = True)
- Add validate_and_resolve_url() function for DNS pinning
- Create SSRFProtectedTransport for custom HTTP transport
- Add comprehensive test suite for DNS rebinding protection
- Change from warn_only=True to warn_only=False for enforcement

This fixes a HIGH severity SSRF vulnerability (CVSS 8.6) that could allow
attackers to bypass SSRF protection using DNS rebinding attacks to access:
- Internal services and private networks
- Cloud metadata endpoints (AWS, GCP, Azure)
- Localhost services

The DNS pinning implementation ensures that the IP address validated during
security checks is the same IP used for the actual HTTP request, eliminating
the TOCTOU (Time-of-Check to Time-of-Use) vulnerability.

Changes:
- src/lfx/src/lfx/components/data_source/api_request.py: Integrate DNS pinning
- src/lfx/src/lfx/utils/ssrf_protection.py: Add validate_and_resolve_url()
- src/lfx/src/lfx/utils/ssrf_transport.py: Custom transport with DNS pinning
- src/lfx/src/lfx/services/settings/base.py: Enable SSRF protection by default
- src/backend/tests/unit/components/data_source/test_dns_rebinding.py: Test suite

Tested and verified working in GUI with DNS pinning logs visible.

* fix(security): implement network-level DNS pinning for SSRF protection with HTTPS support

This commit implements proper DNS rebinding protection that works with both HTTP and HTTPS by using network-level DNS pinning instead of URL rewriting.

## Changes

### Security Fixes
- **ssrf_protection.py**: Fixed critical vulnerability where IP validation returned early on first allowlisted IP, skipping validation of remaining IPs. Now validates ALL resolved IPs before making decisions.
- Blocks hostname if ANY resolved IP is blocked (even if others are allowlisted)
- Supports partial allowlisting (uses only allowlisted IPs for DNS pinning)
- Updated documentation to reflect that SSRF protection is now enabled by default
- Changed warn_only default from True to False for stricter security

### DNS Pinning Implementation
- **ssrf_transport.py**: Created DNSPinningNetworkBackend class that implements network-level DNS pinning
  - Extends httpcore.AsyncNetworkBackend to intercept TCP connections
  - Connects to pinned IP at network layer while preserving hostname for TLS
  - Works with both HTTP and HTTPS (fixes HTTPS regression from URL rewriting approach)
  - Properly handles TLS SNI and certificate verification

### Testing
- **test_dns_rebinding.py**: Updated all DNS rebinding tests to verify network-level behavior
  - Tests now patch AutoBackend.connect_tcp to capture actual IP connections
  - Verifies DNS pinning prevents rebinding attacks
  - Verifies hostname preservation for TLS
  - Tests IPv6 support
  - All 7 tests passing

## Technical Details

The previous URL rewriting approach (replacing hostname with IP in URL) broke HTTPS because:
1. TLS certificate is issued for hostname, not IP address
2. Certificate verification fails when connecting to IP
3. This was a regression - HTTPS worked before but was vulnerable

The new network-level approach:
1. Resolves DNS during validation and pins IPs
2. Uses custom AsyncNetworkBackend to intercept TCP connections
3. Connects to pinned IP at network layer
4. Preserves original hostname for TLS SNI and certificate verification
5. Works transparently with both HTTP and HTTPS

## Function Clarification

Two validation functions exist for different purposes:
- validate_url_for_ssrf(): Simple validation for URL component (no HTTP requests)
- validate_and_resolve_url(): Validation + DNS pinning for API Request component (makes HTTP requests)

Fixes DNS rebinding vulnerability while maintaining HTTPS compatibility.

* fix(security): support multiple IPs for dual-stack and load-balanced hosts

This commit fixes DNS pinning to properly handle hosts that resolve to multiple
IP addresses (dual-stack IPv4/IPv6, load balancing, etc.).

## Changes

### DNS Pinning Enhancement
- **ssrf_transport.py**: Updated to accept and use list of validated IPs
  - Changed pinned_ips from dict[str, str] to dict[str, list[str]]
  - DNSPinningNetworkBackend now tries IPs in order with fallback
  - Supports dual-stack (IPv4+IPv6) and load-balanced hosts
  - Falls back to next IP if connection fails

- **api_request.py**: Pass all validated IPs instead of just first one
  - Changed from validated_ips[0] to validated_ips
  - Enables proper failover for unreachable IPs

### Testing
- **test_dns_rebinding.py**: Added test_dns_pinning_with_multiple_ips_fallback
  - Verifies system tries multiple IPs when first fails
  - Tests dual-stack scenario (IPv4 fails, IPv6 succeeds)
  - Confirms IPs are tried in order
  - All 8 tests passing

## Technical Details

**Previous behavior:**
- Only used first validated IP (validated_ips[0])
- Failed if that single IP was unreachable
- Broke dual-stack and load-balanced hosts

**New behavior:**
- Accepts full list of validated IPs
- Tries each IP in order until one succeeds
- Properly supports:
  - Dual-stack hosts (IPv4 + IPv6)
  - Load-balanced hosts (multiple IPs)
  - Failover scenarios

This maintains security (all IPs validated during SSRF check) while improving
reliability and compatibility with modern networking configurations.

* fix: improve SSRF protection with DNS pinning and fix resource leak

- Implement network-level DNS pinning to prevent DNS rebinding attacks
- Fix resource leak in SSRFProtectedTransport by not calling super().__init__()
- Simplify error messages in SSRF protection (remove verbose explanations)
- Restore warn_only parameter in validate_url_for_ssrf() for backward compatibility
- Remove warn_only from validate_and_resolve_url() (not needed in API Request)
- Switch from private AutoBackend to public httpcore.AnyIOBackend() API
- Add noqa comments for unavoidable FBT and B008 warnings (matching parent class signature)
- Support dual-stack (IPv4/IPv6) and load-balanced hosts with multiple IPs
- Move imports to top of file for better code organization

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* test: fix SSRF protection test mocks to use validate_and_resolve_url

- Updated test mocks from validate_url_for_ssrf to validate_and_resolve_url
- Fixed test_ssrf_protection_disabled_by_default to explicitly disable protection
- All 12 SSRF protection tests now passing

* fix: read SSRF allowlist directly from environment for test compatibility

- Modified get_allowed_hosts() to read from os.getenv() first
- Fixes test isolation issue where settings service cached old values
- Ensures patch.dict() in tests properly overrides allowlist
- Maintains backward compatibility with settings service fallback

* test: fix test_ssrf_protection_enforcement_mode to properly mock validation

The test was failing because it wasn't mocking validate_and_resolve_url,
so the actual SSRF protection wasn't being triggered. Updated the test to:
- Mock validate_and_resolve_url to raise SSRFProtectionError
- Follow the same pattern as other SSRF protection tests
- Properly test that API Request component enforces blocking (no warn-only mode)

* refactor: rewrite SSRF protection tests to test real implementation

BREAKING CHANGE: Completely rewrote SSRF protection tests to properly test
actual security behavior instead of mocking core functions.

Changes:
- Removed all mocks of validate_and_resolve_url() - tests now verify real SSRF blocking
- Added tests that verify DNS pinning actually prevents rebinding attacks
- Test real blocking of private IPs (127.0.0.1, 192.168.x.x, 10.x.x.x, 172.16.x.x)
- Test real blocking of cloud metadata endpoints (169.254.169.254)
- Verify allowlist functionality with actual hostnames, IPs, and CIDR ranges
- Test that custom DNS pinning transport is used when protection is enabled
- Test that normal httpx client is used when protection is disabled
- Fixed environment variable caching in is_ssrf_protection_enabled()

Why this matters:
The old tests were mocking validate_and_resolve_url(), which meant they weren't
actually testing if SSRF protection works. They were just testing error handling.
Real SSRF vulnerabilities could have slipped through.

The new tests:
1. Let the real SSRF protection code run
2. Verify actual private IPs are blocked
3. Verify public URLs are allowed
4. Verify allowlist bypasses work correctly
5. Verify DNS pinning transport is actually used

All 41 tests pass (37 passed, 4 skipped for version checks).

---------

Co-authored-by: Janardan S Kavia <janardanskavia@Janardans-MacBook-Pro.local>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-09 18:58:15 -04:00
7504eb4c72 fix: pin postgres image to bookworm in docker_example (#13027)
* fix: pin postgres image to bookworm in docker_example to prevent collation mismatch

The postgres:16 tag silently moved its base from Debian Bookworm
(glibc 2.36) to Trixie (glibc 2.41), causing a recurring collation
version mismatch warning on existing langflow-postgres volumes.

Pin to postgres:16-bookworm in both docker-compose files and update
the README so existing data volumes keep matching the OS locale data.

Refs: https://github.com/langflow-ai/langflow/issues/9608

* docs: pin postgres image to bookworm in current docs compose snippets

Mirror the docker_example pin in the four current docs that publish
copyable Compose snippets pairing postgres:16 with a persistent
langflow-postgres volume. Prevents the same Bookworm-to-Trixie
collation version mismatch warning when users follow docs instead
of docker_example.

Versioned historical docs are left as-is.

Refs: https://github.com/langflow-ai/langflow/issues/9608

* fix: switch postgres pin from bookworm to trixie for OS consistency

Aligns the pinned postgres base with the langflow runtime image, which
moved to Debian Trixie in #12990. Keeping postgres on bookworm would
have diverged the stack and locked the database to an aging glibc that
will receive fewer security backports as bookworm ages into oldstable.

The pin itself still solves the original bug — postgres:16 cannot
silently roll its OS underneath an existing volume.

Document the one-time REFRESH COLLATION VERSION step for users
upgrading from a bookworm-initialized volume in docker_example/README.md.

Refs: https://github.com/langflow-ai/langflow/issues/9608
2026-05-07 19:39:49 +00:00
bc927abef2 chore: improve AI-agent context (CLAUDE.md auto-load + AGENTS.md tweaks) (#13028)
* chore: import AGENTS.md from CLAUDE.md so Claude Code loads project instructions

Claude Code does not yet natively support AGENTS.md. The previous CLAUDE.md
was a human-readable redirect, but the agent never followed it. Using the
@AGENTS.md import directive (which Claude Code does support) makes the
project instructions auto-load.

* chore: clarify dev-deps sync and pre-commit workflow in AGENTS.md

- Note that running tests inside a sub-package needs uv sync --group dev
  --package <name>; the default sync skips sub-package dev deps and leaves
  things like fakeredis uninstalled.
- Tighten the pre-commit workflow section: pre-commit hooks already run
  ruff/biome on commit, so the previous 5-step manual sequence overstated
  what's needed.
2026-05-07 19:12:12 +00:00
b707c9a41d docs: opensearch connector feature (#12998)
* docs-add-opensearch-provider-and-adjust-kb-docs

* docs-combine-kb-config-sections-and-update-partial

* add-release-note

* Apply suggestions from code review

Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: April I. Murphy <36110273+aimurphy@users.noreply.github.com>

* docs-clarify-embedding-model-step

---------

Co-authored-by: April I. Murphy <36110273+aimurphy@users.noreply.github.com>
2026-05-07 18:28:04 +00:00
406b372d7a chore(starter-projects): new Vector Store RAG template (#13018)
* chore(starter-projects): new Vector Store RAG template

Update the RAG starter flow to align with the new knowledge base
paradigm: removes the inline knowledge base creation sub-flow and
points users to the dedicated Knowledge Ingestion UI for loading
content into their vector store.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(starter-projects): tweak Vector Store RAG README description

Drop the outdated reference to two sub-flows in the in-template
README and refresh the saved metadata.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: autofix of starter project json

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>
2026-05-07 15:27:41 +00:00
abbe917811 test: fix flow state clean test on windows (#13013) 2026-05-07 10:01:24 -03:00
94981c443d fix: update Docker base images to Trixie and force pull latest images in nightly builds (#13015)
- Update builder stage: bookworm-slim → trixie-slim (5 Dockerfiles)
- Update runtime stage: python:3.12.13-slim-trixie → python:3.12-slim-trixie
- Add pull: true to 6 Docker build steps in nightly workflow
- Forces pulling latest base images instead of using cached layers

This resolves CVE vulnerabilities in Docker images by ensuring we use
the latest Debian Trixie base images instead of cached Bookworm layers.
2026-05-06 23:26:11 +00:00
1217ced9e1 Fix: Migration 1.9.2 to 1.10.0 back to 1.9.2 idempotency issue (#12991)
* Fixing migration 1.9.2 -> 1.10.0 -> 1.9.2 idempotent.

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-06 21:55:17 +00:00
af8871cf61 fix: force pull latest base images in Docker nightly builds (#13014)
- Add pull: true to all docker build steps in nightly workflow
- Forces Docker to pull latest python:3.12-slim-trixie instead of using cached layers
- Ensures Debian Trixie base images are used instead of cached Bookworm layers
- Resolves issue where Docker layer caching prevented CVE fixes from taking effect
2026-05-06 21:26:57 +00:00
f08885f20c ci: block PR titles ending in ellipsis (#13004)
Adds a validate-pr-title job to ci.yml that fails on PRs whose title
ends with '...' or '…'. Wired into the CI Success aggregate so it acts
as a merge gate. Skipped on merge_group, workflow_dispatch, and
workflow_call where no PR title is available.
2026-05-06 18:04:37 +00:00
30ac789ca1 fix(frontend): default event_delivery to streaming to match server config (#12978)
Frontend was forcing event_delivery=polling in the build query, overriding
LANGFLOW_EVENT_DELIVERY=streaming on the server. Token-by-token streaming
in the Playground never worked because the frontend always took the polling
code path (customPollBuildEvents) instead of SSE (performStreamingRequest).

Aligns three default fallbacks with the server doc default (STREAMING):
- buildUtils.buildFlowVertices: query-param default
- utilityStore.eventDelivery: initial store value (race window before /config)
- use-get-config: fallback when /config omits event_delivery

buildFlowVerticesWithFallback already retries with POLLING on
STREAMING_NOT_SUPPORTED / ENDPOINT_NOT_AVAILABLE, so streaming-first is safe.

Fixes #12291
2026-05-06 17:56:34 +00:00
7c347a56ea docs: release note refactor (#12987)
* docs-1.10-release-notes-and-link-out-to-previous-versions

* docs-remove-outdated-windows-upgrade-note
2026-05-06 15:44:07 +00:00
92e21615c6 fix(tests): Stabilize traces and user-flow-cleanup e2e on Windows CI (#12997) 2026-05-06 12:09:04 -03:00
0aea910dac fix(frontend): paginator empty state shows "0 items" instead of "1-0 of 0 items" (#12965)
* fix(frontend): paginator empty state shows "0 items" instead of "1-0 of 0 items"

When totalRowsCount is 0 the paginator rendered "1-0 of 0 items" and
"of 0 pages", with the next button enabled because pageIndex (1) was
not equal to maxIndex (0). Hide the range when empty, floor maxIndex
to 1, and disable both navigation buttons when there is nowhere to go.

* Update legacy paginator tests to assert new empty-state copy
2026-05-06 14:03:57 +00:00
deecfc68fa fix(mcp): make run_tool wait_for timeout configurable, raise floor to… (#12996)
fix(mcp): make run_tool wait_for timeout configurable, raise floor to 180s

The hardcoded `timeout=30.0` on `asyncio.wait_for(session.call_tool(...))`
in both `MCPSseClient.run_tool` and `MCPStreamableHttpClient.run_tool` was
truncating in-flight tool calls whose servers needed longer than 30s to
respond — most visibly large MCP composers whose tool responses include
sizeable catalogs.

Failure mode:

  LLM → AgentExecutor → run_tool   (1 call from the LLM)
    ├── attempt 1: get_session (probe ..._1 fails → swap ..._2)
    │             → call_tool → 30s wait_for fires, TimeoutError raised
    │             (server is still working — response ignored on arrival)
    └── attempt 2: get_session (probe ..._2 fails → swap ..._3)
                  → call_tool → 30s wait_for fires again
                  → util.py dedup ("Repeated TimeoutError, not retrying")
                  → ValueError("Maximum retries exceeded ...")
  ← AgentExecutor surfaces error → flow fails

The retry loop's TimeoutError dedup correctly stops looping once it sees
the same error twice, but every call against a slow server hit the same
ceiling and never had a chance to succeed. The session swaps between
attempts also produced excess HTTP churn against the server.

Both `run_tool` methods now resolve the timeout from
`get_settings_service().settings.mcp_server_timeout` (already used for
connection setup at lines 1617 / 1887, env: `LANGFLOW_MCP_SERVER_TIMEOUT`)
with a `max(setting, 180.0)` floor so default deployments don't end up
*shorter* than the previous hardcoded 30s — the Pydantic default for
`mcp_server_timeout` is 20.

Touched:
  src/lfx/src/lfx/base/mcp/util.py
    - L1677, L1689 (stdio run_tool)
    - L1960, L1972 (streamable HTTP run_tool)

Unchanged on purpose:
  - L1217, L1381  session-creation `timeout=30.0` (separate concern).
  - L1060        `_validate_session_connectivity` 3.0s probe (separate
                  concern; addressed in follow-up if probe thrash persists).

Tuning:
  - LANGFLOW_MCP_SERVER_TIMEOUT now governs both connection setup and
    tool-call wait_for. The 180s floor clamps low values; raise the env
    var above 180 to take effect.

Repro / verification:
  - Trace run that previously failed at 67.08s with "Maximum retries
    exceeded with repeated TimeoutError errors" against
    `mcp-guardium_get_service_info` (47KB response payload) now
    completes on attempt 1.

Co-authored-by: MANSURA HABIBA <MANSURAH@ie.ibm.com>
2026-05-06 07:33:47 -07:00
4b46b57e5c fix: Ensure direct-uvicorn startup in macOS 2026-05-05 21:50:01 -07:00
78f82cae32 perf: Enhance Gunicorn preload functionality for Langflow (#12778)
* perf: Enhance Gunicorn preload functionality for Langflow

- Introduced a new preload module to optimize memory usage by running fork-safe initialization in the Gunicorn master process.
- Updated the lifespan management in `main.py` to check if the master has preloaded resources, allowing workers to inherit state and skip redundant setup.
- Adjusted the server loading process to accommodate the new preload logic, ensuring efficient resource management across worker processes.

* feat(cache): Implement teardown method for RedisCache to prevent socket leaks

- Added a `teardown` method to the `RedisCache` class to close the Redis connection, addressing potential socket leaks during process forking.
- Introduced unit tests to verify the functionality of the `teardown` method, ensuring it handles client closure and errors gracefully.
- Tests cover scenarios including normal closure, error handling during closure, and teardown with URL-based connections.

* feat(cache): Implement teardown method in RedisCache to prevent socket leaks

- Added a `teardown` method to the `RedisCache` class, ensuring proper closure of the Redis client connection before forking to avoid socket leaks.
- Created comprehensive unit tests to validate the functionality of the `teardown` method, covering various scenarios including normal operation and error handling.
- Updated existing tests to reflect the new teardown functionality and ensure RedisCache is recognized as an instance of `ExternalAsyncBaseCacheService`.

* refactor(preload): Simplify DB engine disposal logic in master preload

- Removed exception handling around the DB engine disposal to streamline the process, ensuring that the engine is disposed of without unnecessary error logging. This change enhances code clarity and maintains the intended functionality of resource management during the preload phase.

* refactor(preload): Streamline cache service teardown logic

- Simplified the cache service socket closure process in the master preload function to prevent sharing across forks. This change enhances code clarity by removing unnecessary exception handling while maintaining the intended functionality of resource management during the preload phase.

* feat(preload): Introduce per-step completion flags for improved state management

- Added completion flags in the preload state to track the status of various initialization steps, including profile picture copying, starter project creation, agentic global variable initialization, MCP server configuration, and flow loading.
- Updated the lifespan management in `main.py` to utilize these flags, allowing the system to skip redundant setup tasks if they have already been completed during the preload phase.
- This enhancement improves resource management and ensures that the application behaves correctly in a multi-worker environment.

* refactor(lifespan): Replace temp dir management with get_owned_temp_dirs function

- Updated the lifespan management in `main.py` to utilize the new `get_owned_temp_dirs` function, which encapsulates the logic for determining temp directory ownership based on the process type (master or worker).
- Removed the `is_master` check from the lifespan function, simplifying the code and enhancing clarity regarding temp directory cleanup responsibilities.
- Added the `get_owned_temp_dirs` function in `preload.py` to centralize temp directory ownership logic, ensuring that workers do not attempt to clean up directories owned by the master process.

* refactor(lifespan): Enhance initialization flow with conditional gates

- Introduced conditional gates in the `get_lifespan` function to manage the initialization of profile pictures, super users, bundles, component types, and starter projects based on their completion status.
- Improved logging to provide clearer insights into which steps are being skipped or executed, enhancing the overall clarity of the initialization process.
- Updated the preload logic in `preload.py` to ensure that agentic global variables and MCP server configuration are only initialized when necessary, maintaining efficient resource management in a multi-worker environment.

* fix: resolve double-call of initialize_auto_login_default_superuser and add preload tests

- Fix double-call issue: setup_superuser() now handles AUTO_LOGIN completely with file lock
- Add comprehensive unit tests for preload.py covering failure-fallback contract
- Simplify code by doing superuser initialization in initialize_services() (called early in both preload and worker startup)
- File lock protects multi-worker race conditions when preload is disabled
- Tests verify critical step failures propagate, best-effort steps continue on failure

Made-with: Cursor

* fix(preload): resolve missing import and agentic initialization conflicts

Fixed critical bugs introduced in c0e81a5401 that caused preload failures:

1. Missing import: Added DEFAULT_SUPERUSER_PASSWORD to module-level imports
   - Was only imported inside AUTO_LOGIN block but used when AUTO_LOGIN=false
   - Caused NameError that crashed preload with "session scope error"

2. Removed agentic variable initialization from setup_superuser()
   - Prevents double-initialization conflict with preload's dedicated step
   - initialize_agentic_global_variables() in preload handles all users

3. Made teardown_superuser() more robust
   - Now skips deletion instead of raising errors on FK constraints
   - Prevents startup failures when default superuser has associated flows

Resolves: "An error occurred during the session scope" preload error
Resolves: Ghost thread warnings from incomplete initialization
Made-with: Cursor

* refactor(preload): Enhance state management and initialization logic

- Updated the `_PreloadState` class to include `bundles_loaded` and `types_cached` flags for better tracking of initialization steps.
- Modified the `get_lifespan` function to utilize the new state flags, improving the conditional logic for loading bundles and caching component types.
- Implemented a `reset` method in `_PreloadState` to ensure consistent state restoration after preload failures, enhancing reliability in multi-worker environments.
- Simplified the teardown process in `ExternalAsyncBaseCacheService` by making `teardown` an abstract method, allowing direct calls without fallback checks.

This refactor improves clarity and efficiency in the preload and lifespan management processes.

* refactor(lifespan): Improve component types caching and starter project creation logic

- Enhanced the `get_lifespan` function to utilize a local handle for component types when the cache is inherited, ensuring consistency in multi-worker environments.
- Added logging for scenarios where the component types cache is empty, allowing for cache rebuilding instead of skipping starter project creation.
- Streamlined the starter project creation process with improved error handling and logging, ensuring clarity on failures and skipped operations.

This refactor enhances the reliability and clarity of the initialization process in the application.

* fix(tests): Update teardown_superuser test to preserve default superuser if never logged

- Renamed the test function to clarify its purpose.
- Modified the test logic to ensure that the default superuser is not removed during teardown if it has never been logged in, preventing foreign key errors.
- Added assertions to verify that the superuser remains intact and its properties are correctly set after teardown.

This change enhances the reliability of the superuser management in the test suite.

* feat: Implement orphaned MCP server config migration and add unit tests

- Introduced `migrate_orphaned_mcp_servers_config` function to recover MCP server config files that become orphaned after a database reset while preserving the config directory.
- Added logic to handle scenarios with multiple orphaned files, ensuring safe migration and logging for manual recovery.
- Created comprehensive unit tests to validate the migration functionality, covering cases for single orphan recovery, multiple orphans, and scenarios with no orphans.
- Enhanced the setup of the superuser to include the migration process, improving the robustness of user configuration management.

This update enhances the application's ability to recover user configurations in containerized environments.

* fix(teardown): Improve superuser removal logic and error handling

- Updated the `teardown_superuser` function to remove the default superuser when AUTO_LOGIN is disabled and the user has never logged in, enhancing user management.
- Improved error handling to raise a `RuntimeError` if the removal fails, ensuring that issues are logged and not silently ignored.
- Adjusted the `DatabaseService` teardown process to reflect the updated superuser removal logic and ensure proper resource disposal.

This change enhances the reliability of the superuser management during application shutdown.

* fix(setup_superuser): Enhance error handling for AUTO_LOGIN timeout scenario

- Updated the `setup_superuser` function to provide clearer logging and error messages when the AUTO_LOGIN lock times out and no default superuser exists.
- Introduced a check to verify the existence of the default superuser in the database, raising a `RuntimeError` with a descriptive message if it is not found.
- Added unit tests to validate the behavior of the setup process under timeout conditions, ensuring that the application fails gracefully when required superuser credentials are missing.

This change improves the robustness of the superuser initialization process and enhances error visibility during startup.

* fix(preload): Update error handling to log exceptions with traceback for best-effort steps

- Modified the error handling in the `_run_master_preload` function to log exceptions with traceback instead of warnings for best-effort steps, ensuring better visibility into failures.
- Updated unit tests to reflect the change in logging behavior, verifying that exceptions are correctly logged during preload operations.

This change enhances the clarity of error reporting during the preload process, aiding in debugging and monitoring.

* fix(preload): Ensure cleanup of temporary directories during reset

- Updated the `reset` method in the `_PreloadState` class to call `cleanup()` on each `TemporaryDirectory` before clearing the `temp_dirs` list, preventing on-disk directory leaks during failed preloads.
- Added a unit test to verify that `cleanup()` is called for all temporary directories during the reset process, ensuring proper resource management.

This change enhances the reliability of the preload process by ensuring that temporary resources are properly cleaned up.

* refactor(preload): Introduce PreloadStep enumeration and streamline step completion logic

- Added a `PreloadStep` enumeration to define ordered preload phases, enhancing clarity and maintainability of the preload process.
- Replaced direct state attribute checks with the `is_step_complete` function to improve readability and encapsulate step completion logic.
- Updated the `_run_master_preload` function to utilize `mark_step_complete` for recording successful completion of preload steps, enforcing prerequisite ordering.
- Enhanced unit tests to validate the new step completion logic and ensure proper functionality of the preload process.

This refactor improves the structure and reliability of the preload mechanism, making it easier to manage and understand the initialization flow.

* refactor(superuser): Remove redundant checks for superuser credentials in setup functions

- Eliminated unnecessary validation for `DEFAULT_SUPERUSER` and `DEFAULT_SUPERUSER_PASSWORD` in both `initialize_auto_login_default_superuser` and `setup_superuser` functions, simplifying the initialization logic.
- This change streamlines the superuser setup process, assuming that the necessary credentials are managed externally, thus enhancing code clarity and maintainability.

* refactor(preload): Streamline error handling and step completion in preload process

- Introduced a `_best_effort` function to encapsulate error handling for preload steps, improving code readability and maintainability.
- Updated the `_run_master_preload` function to utilize the new error handling mechanism for various steps, ensuring consistent logging and state management.
- Enhanced the documentation in the preload module to clarify the handling of fork-unsafe resources and the overall preload process.

This refactor enhances the robustness and clarity of the preload mechanism, making it easier to manage and understand the initialization flow.

* refactor(preload): Enhance error handling and resource cleanup in preload process

- Wrapped post-initialization work in a try/finally block to ensure the DB engine and cache service are always disposed of, preventing resource leaks in forked workers.
- Updated logging to provide clearer visibility into the preload steps, including error handling for best-effort operations.
- Improved the structure of the `_run_master_preload` function by consolidating related operations and ensuring consistent cleanup.

This refactor enhances the robustness and clarity of the preload mechanism, ensuring safe resource management during initialization.

* [autofix.ci] apply automated fixes

* test(setup_superuser): remove default superuser before lock-timeout no-superuser case

The `initialized_services` fixture starts with `AUTO_LOGIN=false`, which
runs `setup_superuser` through the credentials-fallback path and creates
the default superuser. The "raises_when_no_superuser" test then mocked
the lock to time out, but the existence check found that pre-created
user and returned `AUTO_LOGIN_LOCK_TIMEOUT_SUPERUSER_PRESENT` instead of
raising `RuntimeError`. Delete the default superuser before mocking the
lock so the no-superuser branch is actually exercised.

---------

Co-authored-by: Jordan Frazier <jordan.frazier@datastax.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>
2026-05-05 21:49:11 +00:00
fae08ab66a feat: Added API support for BE endpoints (#12423)
* add memories

* add memories

* accessibility and bug fixes

* fix types

* fix types

* [autofix.ci] apply automated fixes

* add new testcases

* [autofix.ci] apply automated fixes

* remove auto capture

* [autofix.ci] apply automated fixes

* coderabbit fixes and remove KB from FE

* added enpoint support

* coderabbit fix

* [autofix.ci] apply automated fixes

* added session and memory messages endpoint

* code rabbit fixes

* [autofix.ci] apply automated fixes

* merge session id fix

* [autofix.ci] apply automated fixes

* fix testcases

* [autofix.ci] apply automated fixes

* fix testcases

* fix traces sidebar

* memory query rewrite and testcase improvement

* [autofix.ci] apply automated fixes

* Improve seperation of concern for memory hook

* [autofix.ci] apply automated fixes

* handleToggleActive Signature Breaking Change

* improve testcase

* [autofix.ci] apply automated fixes

* fix testcases

* fix mcp testcase

* disable embedded option trigger causing user to to be able to switch provider when option is zero

* Peer review updates

* [autofix.ci] apply automated fixes

* added refresh logic and fixed prior issues from CR

* [autofix.ci] apply automated fixes

---------

Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local>
2026-05-05 21:27:47 +00:00
596e98b9b7 fix: Respect proxy environment variables in URL Component (#12989)
* fix: URLComponent ignores proxy in async mode (#12285)

The URLComponent fails to connect for users behind corporate proxies
because its asynchronous mode does not recognize standard system proxy
environment variables. The component defaults to use_async=True, which
initializes the RecursiveUrlLoader; the underlying async loader does
not natively respect system proxy environment variables, so the
component attempts a direct connection and fails in restricted network
environments.

Detect standard proxy environment variables (http_proxy, HTTP_PROXY,
https_proxy, HTTPS_PROXY) in URLComponent._create_loader. If a proxy
is detected and use_async is enabled, override use_async to False so
the loader uses its synchronous implementation, which natively
respects system proxies. Empty and whitespace-only values are
correctly evaluated as no-proxy and do not trigger the fallback.

Closes #10297

* fix(URLComponent): broaden proxy detection and harden tests

Address review findings on the proxy fix:

- Add ALL_PROXY and all_proxy to the detected env vars. ALL_PROXY is
  commonly set in corporate and container environments (curl, git,
  many Unix tools honour it), and is sometimes the only proxy var
  configured.
- Replace the unused proxy_url string with a single boolean any() over
  the env var keys, since only the presence of a proxy is consulted.
- Reorganize the proxy tests under TestURLComponentProxyHandling with
  a shared default-attributes helper, parametrize over all six env var
  spellings, and add coverage for multiple-simultaneous-proxies and
  the use_async=False path (which should not log a warning).

* [autofix.ci] apply automated fixes

* fix: remove no_proxy="*" macOS startup hack so corporate proxies work

Two startup paths set `os.environ["no_proxy"] = "*"` on macOS, which
disables proxy use for every HTTP client in the process and every child
gunicorn worker (httpx, requests, urllib3 — and therefore the OpenAI,
Anthropic, Groq, etc. SDKs that wrap them). For users behind corporate
proxies on macOS this made every external LLM call unroutable, even with
HTTPS_PROXY properly set.

The override traces to commit history with no concrete justification —
the only artifact is a Stack Overflow link about a uWSGI segfault, but
Langflow uses gunicorn, not uWSGI. Bench-verified that gunicorn boots
cleanly and serves requests on macOS without it (1 worker via
LangflowApplication, OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES retained,
HTTPS_PROXY survives intact in parent and child).

Verification:
  - gunicorn worker spawns and serves /health (200 OK), exits cleanly
  - httpx, urllib, requests all resolve HTTPS_PROXY after the macOS init
    (previously: all three returned empty proxy maps because of no_proxy=*)
  - OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES still set — the actual
    fork-safety fix is preserved

Closes the macOS half of #10297. Companion fix for the async URLComponent
half is in #12285 / branch pr-12285-rebased.

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* [autofix.ci] apply automated fixes (attempt 3/3)

* Orjson update

---------

Co-authored-by: Diogo Veiga <diogo.veiga@tecnico.ulisboa.pt>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-05 13:55:39 -07:00
c4d7a247f4 fix: update Docker base images to latest Python 3.12 and Debian Trixie to resolve CVEs (#12990)
* fix: update Docker base images to latest Python 3.12 to resolve CVEs

- Update all Dockerfiles from python:3.12.13-slim-trixie to python:3.12-slim-trixie
- This ensures automatic security patches for Debian base image CVEs
- Affects nightly builds (base, main, main-all) and release builds (backend, ep)
- Using unpinned patch version (3.12 vs 3.12.13) follows security best practices

* fix: update builder stage to Debian Trixie for consistency

- Update all Dockerfiles from bookworm-slim to trixie-slim in builder stage
- Ensures consistency between builder and runtime Debian versions
- Eliminates CVEs in both build and runtime environments
- Uses ghcr.io/astral-sh/uv:python3.12-trixie-slim for all builders
2026-05-05 20:25:20 +00:00
364fd5dd9a fix: Notifications overlap the bottom-center menubar (#12946)
fix: raise CanvasBanner above bottom-center menubar to prevent overlap

Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local>
2026-05-05 19:44:24 +00:00
32308507e8 feat: Frontend memory (#12293)
* add memories

* add memories

* accessibility and bug fixes

* fix types

* fix types

* [autofix.ci] apply automated fixes

* add new testcases

* [autofix.ci] apply automated fixes

* remove auto capture

* [autofix.ci] apply automated fixes

* coderabbit fixes and remove KB from FE

* fix testcases

* [autofix.ci] apply automated fixes

* fix testcases

* fix mcp testcase

---------

Co-authored-by: Olayinka Adelakun <olayinkaadelakun@mac.war.can.ibm.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local>
2026-05-05 19:36:41 +00:00
017cb1f93c feat(assistant): Add Refresh List and Manage Model Providers to model selector (#12985)
* add model provider config on model selection

* [autofix.ci] apply automated fixes

* fix fe tests playwright

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-05 19:26:27 +00:00
60627bec3a chore: Add DESIGN.md for Langflow's visual design system (#12830)
* docs: Add DESIGN.md specification for Langflow's visual design system

Machine-readable design tokens (YAML frontmatter) paired with
human-readable design rationale following the open-source DESIGN.md
format from Google Labs. Intended for AI agents generating UI that
must match Langflow's visual identity.

Covers 129 color tokens, 15 typography scales, 50 component
definitions, spacing/rounding/elevation systems, dark mode strategy,
and the 14-hue data type color system used for node port encoding.

* ci: Add DESIGN.md lint workflow

Runs `@google/design.md lint` against DESIGN.md on pull requests that
modify the file. Catches spec violations, broken token references, and
WCAG AA contrast failures before merge. CLI version is pinned via env
var so format spec changes require a deliberate bump.

* ci: Integrate DESIGN.md lint into CI Success pipeline

Replaces the standalone workflow with a job inside ci.yml so it gates
the "CI Success" aggregate check. Path-filter skips the job on PRs
that don't touch DESIGN.md, so cost is near-zero for normal PRs.
2026-05-05 18:51:04 +00:00
d04debcb2e feat: native structured output on AgentComponent with prompt fallback (#12935)
* initial commit for structural response

* add schema preprocessing tests

* fix agent duplication message

* add playwright tests

* [autofix.ci] apply automated fixes

* chore: auto-bake note keys and regenerate backend locales/en.json [skip ci]

* ruff fixes

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-05-05 18:34:29 +00:00
b8a2b126ca feat(lfx): extension manifest schema, validate CLI, and error formatter (LE-1014) (#12952)
* feat(lfx): add extension manifest schema, validate CLI, and error formatter (LE-1014)

Foundation for the Bundle Separation iteration. Defines what a valid
extension.json looks like (Pydantic models + Draft 2020-12 JSON Schema),
ships the offline `lfx extension validate` command, and ships the single
`format_extension_error` function that every other extension-system module
will use to render structured errors.

What's in lfx.extension:

- `ExtensionManifest` / `BundleRef` / `LangflowCompat` Pydantic models with
  `extra="forbid"` so unknown fields fail loudly. Deferred fields (`services`,
  `routes`, `hooks`, `starter_projects`, `userConfig`) are reserved as
  None-only so non-null values produce a dedicated
  `field-deferred-in-this-milestone` error instead of a generic schema wall.
  `bundles` accepts a list but rejects length > 1 with
  `multi-bundle-deferred-in-this-milestone` (validator-enforced; the loader
  re-checks at install time in LE-1015).
- `schema.build_schema()` + `build_schema_json()` produce the publishable
  artifact at schemas.langflow.org/extension/v1.json.
- `ExtensionError` typed envelope and `format_extension_error` -- one branch
  per discriminant. Codes are registered in `ERROR_CODES`; an
  `ExtensionError` constructed with an unknown code raises at construction
  time, preventing producers from shipping without a matching renderer.
- `validate_extension` runs four passes: manifest discovery + schema,
  path-safety (no `..`, no absolute paths, no symlink escape), AST
  inspection of every `.py` (syntax, Component subclass present, build()
  declared, top-level `import *`, top-level I/O primitives), and an opt-in
  `--execute-imports` that runs each module in a subprocess with a
  temporary HOME / TMPDIR / LANGFLOW_CONFIG_DIR and LANGFLOW_*/LFX_* env
  vars stripped.
- `lfx extension validate` and `lfx extension schema` typer subcommands.

Acceptance-criteria coverage in tests/unit/extension/:

- Round-trips every v0 manifest field; deferred fields rejected; multi-bundle
  rejected with the dedicated discriminant.
- JSON Schema validates the v0 example and rejects 12 malformed manifests
  with distinct error paths (>= 10 required by the ticket).
- Median default-validate runtime < 100ms on the basic template.
- Crafted side-effect bundle: default validate does NOT execute it (canary
  file is never written); `--execute-imports` DOES execute it and the canary
  appears, while LANGFLOW_* env vars are NOT inherited by the subprocess.
- Snapshot tests for every code in ERROR_CODES; a guard test verifies
  ERROR_CODES and the snapshot table are in lockstep so future additions
  cannot ship without a format branch and a snapshot.

Wiring: `lfx extension` is a sub-app under the Authoring help panel so
future tickets (LE-1016 init/dev, LE-1018 reload) can attach without
colliding with the existing `lfx validate` (which validates flow JSON, not
extensions).

* fix(lfx): fall back to tomli on Python 3.10 in extension manifest loader

tomllib is stdlib only on 3.11+, but lfx supports 3.10-3.13. Use the
existing tomli runtime dependency as the 3.10 fallback (same API, so the
import alias keeps the rest of the module unchanged).

Fixes ModuleNotFoundError seen in CI on the 3.10 job.

* Update src/lfx/tests/unit/extension/test_schema.py

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update src/lfx/src/lfx/extension/schema.py

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update src/lfx/src/lfx/cli/_extension_commands.py

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: LangflowCompat -> LfxCompat

* fix: Remove references to ticket

* fix: encode maxItems constraint in schema

* fix: deferred fields and schema version

* Fix ruff errors

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-05-05 18:28:01 +00:00
10745ac3a5 fix: encode non-ASCII filenames in Content-Disposition headers (RFC 5987) (#12918)
* fix: encode non-ASCII filenames in Content-Disposition headers

HTTP headers only support ASCII/latin-1. Placing Chinese or other
non-ASCII characters directly in filename="..." caused a latin-1
serialization error (500) on download.

Fix all four download routes to use an ASCII-safe fallback in
filename= and the URL-encoded form in filename*=UTF-8'':
- api/v1/files: /download/{flow_id}/{file_name}
- api/v1/flows_helpers: /flows/download/ (ZIP)
- api/v2/files: /files/{file_id} and /files/batch/

Also fix the frontend filename extraction regex in both
use-get-download-flows.ts and use-get-download-files.ts to parse
RFC 5987 (filename*=UTF-8''<encoded>) with decodeURIComponent,
falling back to plain filename= for older responses.

Closes #8105

* test: add non-ASCII filename encoding tests for file download routes

Cover the RFC 5987 Content-Disposition encoding fix across all
affected download endpoints:
- api/v1/files: parametrized test with Chinese, Japanese, accented
  Latin, and ASCII filenames verifying filename*=UTF-8'' encoding
- api/v2/files: same parametrized test for single-file download plus
  a batch download test verifying the ZIP Content-Disposition header
- flows download: test with Chinese flow names verifying the ZIP
  response uses a decodable RFC 5987 filename

Reproduces the regression from issue #8105 where downloading files
with non-ASCII names returned HTTP 500.

* fix: use safe="" in quote() for RFC 5987 filename encoding and tighten test assertion

Ensures forward slashes and other special characters are percent-encoded
in Content-Disposition filename* values. Also fixes weak in-operator
assertion in v2 test to check the correct direction.

* fix: centralize RFC 5987 Content-Disposition encoding and patch header injection

Extract build_content_disposition() helper in api/utils/core.py that:
- Escapes double-quotes in the ASCII fallback (prevents parameter smuggling
  via filenames like evil"; x=injected)
- Uses quote(safe="") to percent-encode forward slashes
- Returns the dual-param format (filename= + filename*=) for broad client
  compatibility

Replace the duplicated 3-line encoding blocks in v1/files.py, v2/files.py,
flows_helpers.py, and projects_files.py with a single call to the helper.

projects_files.py was missing from the original fix: it used quote() without
safe="" and emitted only filename*= with no ASCII fallback.

* test: strengthen Content-Disposition header assertions

- v2/test_files.py: expected_rfc5987 now includes the file extension so a
  regression that strips the extension from the RFC 5987 value is detected
- test_database.py: strengthen the dual-flow download assertion to verify
  both filename= and filename*= params are present, not just the prefix
- test_database.py: rename test_download_flows_non_ascii_content_disposition
  to test_download_flows_content_disposition_dual_param and update the
  docstring to accurately reflect that the ZIP filename is always ASCII
  (timestamp-based); the test now verifies the dual-param format

* fix: sanitize control chars and escape backslash in build_content_disposition

Strip ASCII control characters (CR/LF/NUL and others in 0x00-0x1f/0x7f range)
from filename before encoding to prevent header injection. Also escape backslash
before double-quote in the ASCII fallback per RFC 6266 §4.1 quoted-pair grammar.

* test: add adversarial tests for build_content_disposition and strengthen v2 assertion

Add direct unit tests for the helper covering: quote escaping, backslash escaping,
CRLF/NUL/control char stripping, empty filename, and very long names. Replace
weak substring assertions in the v2 single-file download test with exact equality
against the stored filename returned by the upload response.

* refactor: extract Content-Disposition parser to shared frontend util

Extract the duplicated 14-line RFC 5987 parsing block from use-get-download-files
and use-get-download-flows into a single parseContentDispositionFilename util.
Wraps decodeURIComponent in try/catch to gracefully fall back to the legacy
filename= param on malformed percent-sequences. Adds Jest tests covering all
branches: RFC 5987 priority, legacy fallback, CJK decode, null header, and
malformed input.

* test: replace Portuguese test filename with English equivalent

Rename the accented Latin test case from the Portuguese
arquivo_com_acentuação.txt to naïve_résumé.txt so all test
data uses English while still exercising the same ï/é encoding path.
2026-05-05 15:12:44 +00:00
52ae55b20a docs: deprecate voice to voice websocket endpoint (#12970)
* docs-deprecate-voice-to-voice-endpoint

* docs-explain-voice-mode-vs-speech-to-text
2026-05-05 14:30:31 +00:00
73b30f588b fix(frontend): render node dropdowns above build/notification overlays (#12973)
* fix(frontend): render node dropdowns above build/notification overlays

ReactFlow nodes apply `transform` which creates a local stacking context.
The model selector and generic node dropdown previously rendered without
a Portal, so their `z-50` popover content was trapped inside that
context and got covered by the build status / error notification panel
(also `z-50`, sibling of the canvas).

Switch both `dropdownComponent` and `modelInputComponent` to always use
the portalled `PopoverContent` and bump the popover layer to `z-[60]`.
Mounting the popover into `document.body` escapes the node's stacking
context, and the higher z-index keeps it above the build panel
regardless of portal mount order.

* fix(frontend): flip node dropdowns above build/notification overlays

Prior commit moved the dropdown popovers to a Portal so they could
escape the node's stacking context, which fixed the overlap with the
build status / error notification panel but also pulled the popovers
out of the React Flow viewport's CSS scale transform — the dropdowns
no longer scaled with canvas zoom and looked oversized when zoomed out
and too small when zoomed in.

Switch to a non-portal-based fix: keep the popovers inline in the node
(so they continue to scale with canvas zoom like the rest of the node)
and let Radix flip them above the trigger when the build panel is on
screen.

- Subscribe to `useFlowStore` for `isBuilding` and `buildInfo` and
  derive a `showingBuildPanel` flag in `dropdownComponent` and
  `modelInputComponent`.
- Restore the original `PopoverContentWithoutPortal` selector in both
  files (children / editNode / inspectionPanel keep portaled content).
- Always pass `avoidCollisions` and a dynamic
  `collisionPadding.bottom` equal to `BUILD_PANEL_COLLISION_PADDING_PX`
  (160) when the panel is visible, otherwise `0`. Radix then auto-flips
  the popover above the trigger whenever the bottom region is reserved.
- Move `BUILD_PANEL_COLLISION_PADDING_PX` into
  `constants/constants.ts` with a comment so the magic number is
  defined once and documented.
2026-05-05 14:10:47 +00:00
41083413c0 fix: Duplicate lines rendered in the tracing view (#12944)
flush border top

Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local>
2026-05-05 13:57:20 +00:00
539316bb67 docs: troubleshoot desktop errors from telemetry (#11282)
* add-troubleshooting-items-from-scarf

* sort-desktop-errors-by-os

* include-err-strings

* casing

* remove-placeholders

* python-version

* Apply suggestions from code review

Co-authored-by: April I. Murphy <36110273+aimurphy@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: April I. Murphy <36110273+aimurphy@users.noreply.github.com>

* peer-review

* Apply suggestions from code review

Co-authored-by: April I. Murphy <36110273+aimurphy@users.noreply.github.com>

* docs-update-some-error-messages-that-have-changed

* docs-check-desktop-errors-against-error-constants-file

---------

Co-authored-by: April I. Murphy <36110273+aimurphy@users.noreply.github.com>
2026-05-05 13:44:21 +00:00
00251c4d04 fix: MCP connection refresh state (#12931)
* fix: refresh MCP connection state

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* Update mcp_component.py

* Update mcp_component.py

* Update Nvidia Remix.json

* Update component_index.json

* Update component_index.json

* Update component_index.json

* fix: tool list doesnt refresh after error

* Update use-patch-mcp-server.test.ts

* Update component_index.json

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-04 19:16:11 -07:00
54066c35c7 fix(model-input): hide wrench when saved model's provider is configured (#12971)
* fix(model-input): hide wrench when saved model's provider is configured

When a user deactivates all models from a configured provider, the backend
still injects the saved selection into options as a sticky-default with
not_enabled_locally:true, causing the trigger to surface the Configure
wrench. The wrench is intended for imported flows that reference providers
the user hasn't set up — not for models the user has actively deactivated.

This change scopes the sticky-default affordance to providers that are not
configured locally:

- groupedOptions filters out sticky options whose provider is configured.
- selectedModel falls through to the first available option instead of
  preserving the saved selection with the wrench flag in that case.
- The auto-default useEffect resets the persisted value when the saved
  model is missing AND its provider is configured, so the flow no longer
  references a model the user can't run.

Also tightens the value-prop type from `any` to `ModelOption[] | undefined`
on the component's BaseInputProps generic so the file passes the staged
biome no-any check (pre-existing violation that blocked the surgical edit).

* fix: Don't refresh list if no changes made
2026-05-05 00:13:59 +00:00
c2a5c73628 feat: add sandboxed File System component for agents (#12901)
* add file system component

* add file system validations and tests

* [autofix.ci] apply automated fixes

* ruff style and fix

* ruff fix

* address gh suggestions

* aditional tests to cover gaps

* fix QA issues

* message ordering regression fix

* Update component_index.json

* Update component_index.json

* chore: auto-bake note keys and regenerate backend locales/en.json [skip ci]

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-05-04 14:01:08 -07:00
49a758c771 fix: Pagination shows "-19-0 of 0 items" in traces view when empty (#12941)
* fix empty pagination component

* add testcase

* [autofix.ci] apply automated fixes

---------

Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-04 19:41:25 +00:00
0b0c7dc1a7 fix(ui): Hide native Edge password reveal icon on desktop (#12972)
fix eye input desktop
2026-05-04 19:15:38 +00:00
6b74589e46 fix: prevents credential types vars from being used as inputs/outputs unless specifically typed as secretstr (#12908)
* just prevents credentials typed vars from use

* fix: Cleanup from the review

* Update .secrets.baseline

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* cleanup from code review

* one more cleanup

* [autofix.ci] apply automated fixes

* Update test_credential_variable_leakage.py

* fix: tests

* Update credentials.py

* fix: Mask secret value in custom component

* Update component_index.json

* Update test_credential_resolution.py

* Update cloud_storage_utils.py

* Update test_cometapi_component.py

* compatibility preserve

* fix: Refactor some duplicate routines

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* feat(ui): Disable sensitive global var selection

* fix: Make sure dynamic forms also reject

* [autofix.ci] apply automated fixes

* Update templates

* One more template update

* Update component_index.json

* Update test_credential_resolution.py

---------

Co-authored-by: Eric Hare <ericrhare@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-05-04 18:07:56 +00:00
a556005e40 fix(deployments): rename env labels (#12949) 2026-05-04 13:03:52 +00:00
f8468389d1 fix(tests): Stabilize Playwright e2e suite on Windows CI (#12964) 2026-05-04 09:08:24 -03:00
6d2e255f5d Merge remote-tracking branch 'origin/release-1.9.2' into release-1.10.0
# Conflicts:
#	.secrets.baseline
#	pyproject.toml
#	src/backend/base/langflow/initial_setup/starter_projects/Knowledge Retrieval.json
#	src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json
#	src/backend/base/pyproject.toml
#	src/frontend/package-lock.json
#	src/frontend/package.json
#	src/lfx/pyproject.toml
#	src/lfx/src/lfx/_assets/component_index.json
#	src/sdk/pyproject.toml
#	uv.lock
2026-05-01 14:22:58 -07:00
ea3eae8b9e chore: update deps (#12951)
* chore: update deps

update deps

* chore: update uv.lock
2026-05-01 16:20:53 +00:00
5bf73714e3 chore: Remove the diskcache dependency (#12953) 2026-05-01 15:42:32 +00:00
61c1d18245 feat: Add draft version CTA in deployment modal (#12925)
* feat(deployments): add draft version CTA

* fix(deployments): hide name success on error
2026-04-30 20:50:50 +00:00
d68b312421 fix: route custom Loguru logs through Langflow logger (#12926)
fix: route custom loguru logs through langflow logger
2026-04-30 12:10:29 -07:00
9d94f9b7d0 fix: update playwright to 1.59.0 (#12947)
chore: update playwright to 1.59.0

- Update playwright dependency from 1.58.0 to 1.59.0
- Sync uv.lock with updated dependencies

Co-authored-by: Janardan S Kavia <janardanskavia@Janardans-MacBook-Pro.local>
2026-04-30 17:22:34 +00:00
cb06a666d0 fix(security): reject symlinks/hardlinks in BaseFileComponent TAR extraction (GHSA-ccv6-r384-xp75) (#12945)
`BaseFileComponent._unpack_bundle._safe_extract_tar` accepted any TAR member
type and only checked that `output_dir / member.name` did not escape the
extract dir. That check was performed before extraction, so a symlink whose
*target* was an absolute path (or `../` escape) was extracted untouched.
Once on disk the link was iterated by `temp_dir_path.iterdir()` and handed
to `process_files()`, whose concrete implementations (FileComponent,
DoclingInline/Remote, NvidiaIngest, VideoFile, Unstructured) call
`path.read_bytes()` and follow the link to read arbitrary host files.

The reporter's exploit chain leaks `~/.langflow/secret_key`, forges a JWT
for an admin user, and then runs arbitrary code through the Python
interpreter node, achieving RCE.

Python's `tarfile` only defaults to the safe `data` filter on Python 3.14,
which langflow's `requires-python = ">=3.10,<3.14"` excludes — so every
supported interpreter was vulnerable.

Fix:
- `_safe_extract_tar` now rejects symbolic-link, hard-link, FIFO, and
  device-node members with a `ValueError` and only extracts regular files
  and directories.
- `_unpack_and_collect_files` skips any `is_symlink()` entries from the
  extracted bundle directory and from recursive directory walks as
  defense-in-depth in case a future bundle format slips a link through.
- New `tests/unit/base/data/test_base_file_unpack.py` covers symlink (abs
  + relative escape), hardlink, FIFO rejection, benign tar/zip extraction,
  the post-extraction symlink filter, and an end-to-end repro mirroring
  the advisory PoC (real filesystem symlink → tarfile.add).

Refs: https://github.com/langflow-ai/langflow/security/advisories/GHSA-ccv6-r384-xp75
2026-04-30 17:22:27 +00:00